mirror of
https://github.com/eitchtee/WYGIWYH.git
synced 2026-04-23 17:18:44 +02:00
feat(datepicker): drop native datepickers in favor of AirDatePicker for better compatibility
As Firefox (still) doesn't support month input type
This commit is contained in:
7
frontend/package-lock.json
generated
7
frontend/package-lock.json
generated
@@ -17,6 +17,7 @@
|
||||
"@babel/preset-env": "^7.16.8",
|
||||
"@fortawesome/fontawesome-free": "^6.6.0",
|
||||
"@popperjs/core": "^2.11.8",
|
||||
"air-datepicker": "^3.5.3",
|
||||
"alpinejs": "^3.14.1",
|
||||
"autoprefixer": "^10.4.14",
|
||||
"autosize": "^6.0.1",
|
||||
@@ -2703,6 +2704,12 @@
|
||||
"acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/air-datepicker": {
|
||||
"version": "3.5.3",
|
||||
"resolved": "https://registry.npmjs.org/air-datepicker/-/air-datepicker-3.5.3.tgz",
|
||||
"integrity": "sha512-Elf9gLhv/jidN1+TfeRJYMQRUfYx5apXw2dY5DuAMPRnNtQ4Iw9fTTJK772osmXSUB9xQ2Y8Q1Pt6pgBOQLPQw==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/ajv": {
|
||||
"version": "6.12.6",
|
||||
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
"@babel/preset-env": "^7.16.8",
|
||||
"@fortawesome/fontawesome-free": "^6.6.0",
|
||||
"@popperjs/core": "^2.11.8",
|
||||
"air-datepicker": "^3.5.3",
|
||||
"alpinejs": "^3.14.1",
|
||||
"autoprefixer": "^10.4.14",
|
||||
"autosize": "^6.0.1",
|
||||
|
||||
148
frontend/src/application/datepicker.js
Normal file
148
frontend/src/application/datepicker.js
Normal file
@@ -0,0 +1,148 @@
|
||||
import AirDatepicker from 'air-datepicker';
|
||||
import en from 'air-datepicker/locale/en';
|
||||
import ptBr from 'air-datepicker/locale/pt-BR';
|
||||
import {createPopper} from '@popperjs/core';
|
||||
|
||||
const locales = {
|
||||
'pt': ptBr,
|
||||
'en': en
|
||||
};
|
||||
|
||||
function isMobileDevice() {
|
||||
const mobileRegex = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i;
|
||||
return mobileRegex.test(navigator.userAgent);
|
||||
}
|
||||
|
||||
function isTouchDevice() {
|
||||
return ('ontouchstart' in window) || (navigator.maxTouchPoints > 0) || (navigator.msMaxTouchPoints > 0);
|
||||
}
|
||||
|
||||
function isMobile() {
|
||||
return isMobileDevice() || isTouchDevice();
|
||||
}
|
||||
|
||||
window.DatePicker = function createDynamicDatePicker(element) {
|
||||
let isOnMobile = isMobile();
|
||||
|
||||
let baseOpts = {
|
||||
isMobile: isOnMobile,
|
||||
timepicker: element.dataset.timepicker === 'true',
|
||||
autoClose: element.dataset.autoClose === 'true',
|
||||
buttons: element.dataset.clearButton === 'true' ? ['clear', 'today'] : ['today'],
|
||||
locale: locales[element.dataset.language],
|
||||
onSelect: ({date, formattedDate, datepicker}) => {
|
||||
const _event = new CustomEvent("change", {
|
||||
bubbles: true,
|
||||
});
|
||||
datepicker.$el.dispatchEvent(_event);
|
||||
}
|
||||
};
|
||||
|
||||
const positionConfig = !isOnMobile ? {
|
||||
position({$datepicker, $target, $pointer, done}) {
|
||||
let popper = createPopper($target, $datepicker, {
|
||||
placement: 'bottom',
|
||||
modifiers: [
|
||||
{
|
||||
name: 'flip',
|
||||
options: {
|
||||
padding: {
|
||||
top: 64
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'offset',
|
||||
options: {
|
||||
offset: [0, 20]
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'arrow',
|
||||
options: {
|
||||
element: $pointer
|
||||
}
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
return function completeHide() {
|
||||
popper.destroy();
|
||||
done();
|
||||
};
|
||||
}
|
||||
} : {};
|
||||
|
||||
let opts = {...baseOpts, ...positionConfig};
|
||||
|
||||
if (element.dataset.value) {
|
||||
opts["selectedDates"] = [element.dataset.value];
|
||||
opts["startDate"] = [element.dataset.value];
|
||||
}
|
||||
|
||||
return new AirDatepicker(element, opts);
|
||||
};
|
||||
|
||||
|
||||
window.MonthYearPicker = function createDynamicDatePicker(element) {
|
||||
let isOnMobile = isMobile();
|
||||
|
||||
let baseOpts = {
|
||||
isMobile: isOnMobile,
|
||||
view: 'months',
|
||||
minView: 'months',
|
||||
dateFormat: 'MMMM yyyy',
|
||||
autoClose: element.dataset.autoClose === 'true',
|
||||
buttons: element.dataset.clearButton === 'true' ? ['clear', 'today'] : ['today'],
|
||||
locale: locales[element.dataset.language],
|
||||
onSelect: ({date, formattedDate, datepicker}) => {
|
||||
const _event = new CustomEvent("change", {
|
||||
bubbles: true,
|
||||
});
|
||||
datepicker.$el.dispatchEvent(_event);
|
||||
}
|
||||
};
|
||||
|
||||
const positionConfig = !isOnMobile ? {
|
||||
position({$datepicker, $target, $pointer, done}) {
|
||||
let popper = createPopper($target, $datepicker, {
|
||||
placement: 'bottom',
|
||||
modifiers: [
|
||||
{
|
||||
name: 'flip',
|
||||
options: {
|
||||
padding: {
|
||||
top: 64
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'offset',
|
||||
options: {
|
||||
offset: [0, 20]
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'arrow',
|
||||
options: {
|
||||
element: $pointer
|
||||
}
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
return function completeHide() {
|
||||
popper.destroy();
|
||||
done();
|
||||
};
|
||||
}
|
||||
} : {};
|
||||
|
||||
let opts = {...baseOpts, ...positionConfig};
|
||||
|
||||
if (element.dataset.value) {
|
||||
opts["selectedDates"] = [element.dataset.value];
|
||||
opts["startDate"] = [element.dataset.value];
|
||||
}
|
||||
return new AirDatepicker(element, opts);
|
||||
};
|
||||
89
frontend/src/styles/_datepicker.scss
Normal file
89
frontend/src/styles/_datepicker.scss
Normal file
@@ -0,0 +1,89 @@
|
||||
@import 'air-datepicker/air-datepicker.css';
|
||||
|
||||
.air-datepicker-global-container {
|
||||
z-index: 2000; // Allows the datepicker to be shown on top of offcanvas
|
||||
}
|
||||
|
||||
.air-datepicker {
|
||||
--adp-accent-color: #fbb700;
|
||||
--adp-day-name-color: #fbb700;
|
||||
--adp-background-color: #303030; /* $gray-800 */
|
||||
--adp-color: #fff;
|
||||
--adb-color-other-month: #888; /* $gray-600 */
|
||||
--adp-cell-background-color-selected: #fbb700;
|
||||
|
||||
--adp-border-color-inline: #444;
|
||||
|
||||
--adp-background-color-selected-other-month-focused: #e6a600; /* Slightly darker than $yellow */
|
||||
--adp-background-color-selected-other-month: #fbb700;
|
||||
|
||||
--adp-color-secondary: #adb5bd; /* $gray-500 */
|
||||
--adp-background-color-hover: #444;
|
||||
--adp-background-color-active: #3c3c3c;
|
||||
--adp-cell-background-color-selected-hover: #e6a600;
|
||||
--adp-color-other-month: #888; /* $gray-600 */
|
||||
--adp-color-disabled: #444; /* $gray-700 */
|
||||
--adp-color-disabled-in-range: #666; /* Between $gray-600 and $gray-700 */
|
||||
--adp-color-other-month-hover: #ced4da; /* $gray-400 */
|
||||
--adp-time-track-color: #444; /* $gray-700 */
|
||||
--adp-time-track-color-hover: #888; /* $gray-600 */
|
||||
}
|
||||
|
||||
.air-datepicker-cell.-selected-,
|
||||
.air-datepicker-cell.-selected-.-current-,
|
||||
.-selected-.air-datepicker-cell.-year-.-other-decade-,
|
||||
.-selected-.air-datepicker-cell.-day-.-other-month-{
|
||||
color: #222; /* $gray-900 */
|
||||
}
|
||||
|
||||
/* Additional styles for better dark theme integration */
|
||||
.air-datepicker {
|
||||
border-color: #444; /* $gray-700 */
|
||||
}
|
||||
|
||||
.air-datepicker-body--day-names {
|
||||
color: #fbb700; /* $yellow */
|
||||
}
|
||||
|
||||
.air-datepicker-cell:hover {
|
||||
background-color: #444; /* $gray-700 */
|
||||
}
|
||||
|
||||
.air-datepicker-cell.-current- {
|
||||
color: #fbb700; /* $yellow */
|
||||
}
|
||||
|
||||
.air-datepicker-cell.-range-from-,
|
||||
.air-datepicker-cell.-range-to- {
|
||||
border: 1px solid #fbb700; /* $yellow */
|
||||
}
|
||||
|
||||
.air-datepicker-cell.-range-from-::before,
|
||||
.air-datepicker-cell.-range-to-::before {
|
||||
background-color: rgba(251, 183, 0, 0.1); /* $yellow with opacity */
|
||||
}
|
||||
|
||||
.air-datepicker-cell.-in-range- {
|
||||
background-color: rgba(251, 183, 0, 0.1); /* $yellow with opacity */
|
||||
}
|
||||
|
||||
.air-datepicker-time--row input[type='range']::-webkit-slider-thumb {
|
||||
background-color: #fbb700; /* $yellow */
|
||||
}
|
||||
|
||||
.air-datepicker-time--row input[type='range']::-moz-range-thumb {
|
||||
background-color: #fbb700; /* $yellow */
|
||||
}
|
||||
|
||||
.air-datepicker-button,
|
||||
.air-datepicker-button:hover {
|
||||
color: #fbb700; /* $yellow */
|
||||
}
|
||||
|
||||
.air-datepicker-button:hover {
|
||||
background-color: #444; /* $gray-700 */
|
||||
}
|
||||
|
||||
.air-datepicker--pointer:after {
|
||||
background: #303030
|
||||
}
|
||||
@@ -2,6 +2,7 @@
|
||||
@import "font-awesome.scss";
|
||||
@import "tailwind.scss";
|
||||
@import "bootstrap.scss";
|
||||
@import "datepicker.scss";
|
||||
@import "tom-select.scss";
|
||||
@import "animations.scss";
|
||||
@import "scrollbar.scss";
|
||||
|
||||
Reference in New Issue
Block a user