@ohos-ports/flowbite-datepicker 2.0.0-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintignore +2 -0
- package/.eslintrc.js +73 -0
- package/.stylelintrc +12 -0
- package/CHANGELOG.md +72 -0
- package/LICENSE +21 -0
- package/README.md +71 -0
- package/demo/index.html +582 -0
- package/demo/live-demo.js +471 -0
- package/dist/DateRangePicker.cjs.js +2996 -0
- package/dist/DateRangePicker.esm.js +2994 -0
- package/dist/DateRangePicker.umd.js +3002 -0
- package/dist/Datepicker.cjs.js +2778 -0
- package/dist/Datepicker.esm.js +2776 -0
- package/dist/Datepicker.umd.js +2784 -0
- package/dist/css/datepicker-bs4.css +276 -0
- package/dist/css/datepicker-bs4.min.css +1 -0
- package/dist/css/datepicker-bs5.css +276 -0
- package/dist/css/datepicker-bs5.min.css +1 -0
- package/dist/css/datepicker-bulma.css +258 -0
- package/dist/css/datepicker-bulma.min.css +1 -0
- package/dist/css/datepicker-foundation.css +262 -0
- package/dist/css/datepicker-foundation.min.css +1 -0
- package/dist/css/datepicker.css +306 -0
- package/dist/css/datepicker.min.css +1403 -0
- package/dist/js/datepicker-full.js +2777 -0
- package/dist/js/datepicker-full.min.js +1 -0
- package/dist/js/datepicker.js +2569 -0
- package/dist/js/datepicker.min.js +1 -0
- package/dist/js/locales/ar-tn.js +15 -0
- package/dist/js/locales/ar.js +15 -0
- package/dist/js/locales/az.js +14 -0
- package/dist/js/locales/bg.js +14 -0
- package/dist/js/locales/bm.js +18 -0
- package/dist/js/locales/bn.js +19 -0
- package/dist/js/locales/br.js +18 -0
- package/dist/js/locales/bs.js +15 -0
- package/dist/js/locales/ca.js +18 -0
- package/dist/js/locales/cs.js +19 -0
- package/dist/js/locales/cy.js +14 -0
- package/dist/js/locales/da.js +19 -0
- package/dist/js/locales/de.js +18 -0
- package/dist/js/locales/el.js +16 -0
- package/dist/js/locales/en-AU.js +18 -0
- package/dist/js/locales/en-CA.js +18 -0
- package/dist/js/locales/en-GB.js +18 -0
- package/dist/js/locales/en-IE.js +17 -0
- package/dist/js/locales/en-NZ.js +17 -0
- package/dist/js/locales/en-ZA.js +17 -0
- package/dist/js/locales/eo.js +17 -0
- package/dist/js/locales/es.js +18 -0
- package/dist/js/locales/et.js +18 -0
- package/dist/js/locales/eu.js +18 -0
- package/dist/js/locales/fa.js +17 -0
- package/dist/js/locales/fi.js +17 -0
- package/dist/js/locales/fo.js +15 -0
- package/dist/js/locales/fr-CH.js +21 -0
- package/dist/js/locales/fr.js +18 -0
- package/dist/js/locales/gl.js +16 -0
- package/dist/js/locales/he.js +15 -0
- package/dist/js/locales/hi.js +18 -0
- package/dist/js/locales/hr.js +13 -0
- package/dist/js/locales/hu.js +18 -0
- package/dist/js/locales/hy.js +18 -0
- package/dist/js/locales/id.js +15 -0
- package/dist/js/locales/is.js +14 -0
- package/dist/js/locales/it-CH.js +20 -0
- package/dist/js/locales/it.js +18 -0
- package/dist/js/locales/ja.js +17 -0
- package/dist/js/locales/ka.js +17 -0
- package/dist/js/locales/kk.js +15 -0
- package/dist/js/locales/km.js +15 -0
- package/dist/js/locales/ko.js +18 -0
- package/dist/js/locales/lt.js +19 -0
- package/dist/js/locales/lv.js +18 -0
- package/dist/js/locales/me.js +17 -0
- package/dist/js/locales/mk.js +15 -0
- package/dist/js/locales/mn.js +17 -0
- package/dist/js/locales/mr.js +18 -0
- package/dist/js/locales/ms.js +15 -0
- package/dist/js/locales/nl-BE.js +18 -0
- package/dist/js/locales/nl.js +18 -0
- package/dist/js/locales/no.js +18 -0
- package/dist/js/locales/oc.js +17 -0
- package/dist/js/locales/pl.js +17 -0
- package/dist/js/locales/pt-BR.js +17 -0
- package/dist/js/locales/pt.js +18 -0
- package/dist/js/locales/ro.js +17 -0
- package/dist/js/locales/ru.js +18 -0
- package/dist/js/locales/si.js +18 -0
- package/dist/js/locales/sk.js +18 -0
- package/dist/js/locales/sl.js +15 -0
- package/dist/js/locales/sq.js +18 -0
- package/dist/js/locales/sr-latn.js +16 -0
- package/dist/js/locales/sr.js +16 -0
- package/dist/js/locales/sv.js +17 -0
- package/dist/js/locales/sw.js +15 -0
- package/dist/js/locales/ta.js +18 -0
- package/dist/js/locales/tg.js +19 -0
- package/dist/js/locales/th.js +14 -0
- package/dist/js/locales/tk.js +18 -0
- package/dist/js/locales/tr.js +17 -0
- package/dist/js/locales/uk.js +17 -0
- package/dist/js/locales/uz-cyrl.js +18 -0
- package/dist/js/locales/uz-latn.js +18 -0
- package/dist/js/locales/vi.js +16 -0
- package/dist/js/locales/zh-CN.js +19 -0
- package/dist/js/locales/zh-TW.js +18 -0
- package/dist/locales/index.cjs.js +1028 -0
- package/dist/locales/index.esm.js +1028 -0
- package/dist/main.cjs.js +2999 -0
- package/dist/main.esm.js +2994 -0
- package/dist/main.umd.js +3005 -0
- package/docs/.nojekyll +0 -0
- package/docs/README.md +266 -0
- package/docs/_sidebar.md +6 -0
- package/docs/api.md +284 -0
- package/docs/date-string+format.md +90 -0
- package/docs/i18n.md +99 -0
- package/docs/images/datepicker-inline.jpg +0 -0
- package/docs/images/datepicker.jpg +0 -0
- package/docs/images/multidate.jpg +0 -0
- package/docs/images/picker-structure.jpg +0 -0
- package/docs/images/rangepicker.jpg +0 -0
- package/docs/images/view-days.jpg +0 -0
- package/docs/images/view-decades.jpg +0 -0
- package/docs/images/view-months.jpg +0 -0
- package/docs/images/view-years.jpg +0 -0
- package/docs/index.html +26 -0
- package/docs/options.md +354 -0
- package/docs/overview.md +174 -0
- package/extras/twoDigitToFullYear/test/twoDigitToFullYear.js +58 -0
- package/extras/twoDigitToFullYear/twoDigitToFullYear.js +26 -0
- package/js/DateRangePicker.js +210 -0
- package/js/Datepicker.js +487 -0
- package/js/datepicker-full.js +5 -0
- package/js/events/functions.js +48 -0
- package/js/events/inputFieldListeners.js +206 -0
- package/js/events/otherListeners.js +15 -0
- package/js/events/pickerListeners.js +70 -0
- package/js/i18n/base-locales.js +13 -0
- package/js/i18n/locales/ar-tn.js +15 -0
- package/js/i18n/locales/ar.js +15 -0
- package/js/i18n/locales/az.js +14 -0
- package/js/i18n/locales/bg.js +14 -0
- package/js/i18n/locales/bm.js +18 -0
- package/js/i18n/locales/bn.js +19 -0
- package/js/i18n/locales/br.js +18 -0
- package/js/i18n/locales/bs.js +15 -0
- package/js/i18n/locales/ca.js +18 -0
- package/js/i18n/locales/cs.js +19 -0
- package/js/i18n/locales/cy.js +14 -0
- package/js/i18n/locales/da.js +19 -0
- package/js/i18n/locales/de.js +18 -0
- package/js/i18n/locales/el.js +16 -0
- package/js/i18n/locales/en-AU.js +18 -0
- package/js/i18n/locales/en-CA.js +18 -0
- package/js/i18n/locales/en-GB.js +18 -0
- package/js/i18n/locales/en-IE.js +17 -0
- package/js/i18n/locales/en-NZ.js +17 -0
- package/js/i18n/locales/en-ZA.js +17 -0
- package/js/i18n/locales/eo.js +17 -0
- package/js/i18n/locales/es.js +18 -0
- package/js/i18n/locales/et.js +18 -0
- package/js/i18n/locales/eu.js +18 -0
- package/js/i18n/locales/fa.js +17 -0
- package/js/i18n/locales/fi.js +17 -0
- package/js/i18n/locales/fo.js +15 -0
- package/js/i18n/locales/fr-CH.js +21 -0
- package/js/i18n/locales/fr.js +18 -0
- package/js/i18n/locales/gl.js +16 -0
- package/js/i18n/locales/he.js +15 -0
- package/js/i18n/locales/hi.js +18 -0
- package/js/i18n/locales/hr.js +13 -0
- package/js/i18n/locales/hu.js +18 -0
- package/js/i18n/locales/hy.js +18 -0
- package/js/i18n/locales/id.js +15 -0
- package/js/i18n/locales/is.js +14 -0
- package/js/i18n/locales/it-CH.js +20 -0
- package/js/i18n/locales/it.js +18 -0
- package/js/i18n/locales/ja.js +17 -0
- package/js/i18n/locales/ka.js +17 -0
- package/js/i18n/locales/kk.js +15 -0
- package/js/i18n/locales/km.js +15 -0
- package/js/i18n/locales/ko.js +18 -0
- package/js/i18n/locales/lt.js +19 -0
- package/js/i18n/locales/lv.js +18 -0
- package/js/i18n/locales/me.js +17 -0
- package/js/i18n/locales/mk.js +15 -0
- package/js/i18n/locales/mn.js +17 -0
- package/js/i18n/locales/mr.js +18 -0
- package/js/i18n/locales/ms.js +15 -0
- package/js/i18n/locales/nl-BE.js +18 -0
- package/js/i18n/locales/nl.js +18 -0
- package/js/i18n/locales/no.js +18 -0
- package/js/i18n/locales/oc.js +17 -0
- package/js/i18n/locales/pl.js +17 -0
- package/js/i18n/locales/pt-BR.js +17 -0
- package/js/i18n/locales/pt.js +18 -0
- package/js/i18n/locales/ro.js +17 -0
- package/js/i18n/locales/ru.js +18 -0
- package/js/i18n/locales/si.js +18 -0
- package/js/i18n/locales/sk.js +18 -0
- package/js/i18n/locales/sl.js +15 -0
- package/js/i18n/locales/sq.js +18 -0
- package/js/i18n/locales/sr-latn.js +16 -0
- package/js/i18n/locales/sr.js +16 -0
- package/js/i18n/locales/sv.js +17 -0
- package/js/i18n/locales/sw.js +15 -0
- package/js/i18n/locales/ta.js +18 -0
- package/js/i18n/locales/tg.js +19 -0
- package/js/i18n/locales/th.js +14 -0
- package/js/i18n/locales/tk.js +18 -0
- package/js/i18n/locales/tr.js +17 -0
- package/js/i18n/locales/uk.js +17 -0
- package/js/i18n/locales/uz-cyrl.js +18 -0
- package/js/i18n/locales/uz-latn.js +18 -0
- package/js/i18n/locales/vi.js +16 -0
- package/js/i18n/locales/zh-CN.js +19 -0
- package/js/i18n/locales/zh-TW.js +18 -0
- package/js/lib/date-format.js +185 -0
- package/js/lib/date.js +82 -0
- package/js/lib/dom.js +55 -0
- package/js/lib/event.js +68 -0
- package/js/lib/utils.js +61 -0
- package/js/main.js +4 -0
- package/js/options/defaultOptions.js +38 -0
- package/js/options/processOptions.js +263 -0
- package/js/picker/Picker.js +334 -0
- package/js/picker/templates/calendarWeeksTemplate.js +8 -0
- package/js/picker/templates/daysTemplate.js +8 -0
- package/js/picker/templates/pickerTemplate.js +23 -0
- package/js/picker/views/DaysView.js +250 -0
- package/js/picker/views/MonthsView.js +198 -0
- package/js/picker/views/View.js +55 -0
- package/js/picker/views/YearsView.js +170 -0
- package/package.json +81 -0
- package/postcss.config.js +5 -0
- package/rollup.config.js +75 -0
- package/sass/_mixins.scss +12 -0
- package/sass/datepicker-bs4.scss +91 -0
- package/sass/datepicker-bs5.scss +91 -0
- package/sass/datepicker-bulma.scss +69 -0
- package/sass/datepicker-foundation.scss +66 -0
- package/sass/datepicker.scss +436 -0
- package/sass/index-bs4.scss +5 -0
- package/sass/index-bs5.scss +5 -0
- package/sass/index-bulma.scss +6 -0
- package/sass/index-foundation.scss +3 -0
- package/scripts/build-css.js +39 -0
- package/scripts/build-locales.js +57 -0
- package/scripts/convert-bsdp-locales.js +65 -0
- package/scripts/minify-css.js +31 -0
- package/scripts/minify-js.js +17 -0
- package/style.css +10 -0
- package/tailwind.config.js +16 -0
- package/tailwind.css +1389 -0
- package/test/DateRangePicker/DateRangePicker.js +547 -0
- package/test/DateRangePicker/api-methods.js +415 -0
- package/test/DateRangePicker/date-selection.js +472 -0
- package/test/DateRangePicker/options.js +308 -0
- package/test/Datepicker/Datepicker-object.js +236 -0
- package/test/Datepicker/api-methods.js +328 -0
- package/test/_utils/date.js +102 -0
- package/test/_utils/dom.js +70 -0
- package/test/events.js +785 -0
- package/test/inline-mode.js +45 -0
- package/test/keyboard-operation/arrow-down.js +293 -0
- package/test/keyboard-operation/arrow-left.js +255 -0
- package/test/keyboard-operation/arrow-right.js +215 -0
- package/test/keyboard-operation/arrow-up.js +461 -0
- package/test/keyboard-operation/edit-mode.js +458 -0
- package/test/keyboard-operation/keyboard-operation.js +146 -0
- package/test/mouse-operation.js +580 -0
- package/test/options/before-show.js +635 -0
- package/test/options/bulma-datepicker.sublime-workspace +1280 -0
- package/test/options/buttons.js +383 -0
- package/test/options/date-restrictions.js +802 -0
- package/test/options/format.js +281 -0
- package/test/options/multidate.js +380 -0
- package/test/options/options.js +727 -0
- package/test/options/orientation.js +410 -0
- package/test/options/pick-levle+view.js +357 -0
- package/test/test.html +94 -0
- package/test/unit/DateRangePicker.js +192 -0
- package/test/unit/Datepicker.js +307 -0
- package/test/unit/_setup.js +28 -0
- package/test/unit/lib/date-format.js +310 -0
- package/test/unit/lib/date.js +211 -0
- package/test/unit/lib/dom.js +142 -0
- package/test/unit/lib/event.js +207 -0
- package/test/unit/lib/utils.js +135 -0
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
import {stripTime, today} from './date.js';
|
|
2
|
+
import {lastItemOf} from './utils.js';
|
|
3
|
+
|
|
4
|
+
// pattern for format parts
|
|
5
|
+
export const reFormatTokens = /dd?|DD?|mm?|MM?|yy?(?:yy)?/;
|
|
6
|
+
// pattern for non date parts
|
|
7
|
+
export const reNonDateParts = /[\s!-/:-@[-`{-~年月日]+/;
|
|
8
|
+
// cache for persed formats
|
|
9
|
+
let knownFormats = {};
|
|
10
|
+
// parse funtions for date parts
|
|
11
|
+
const parseFns = {
|
|
12
|
+
y(date, year) {
|
|
13
|
+
return new Date(date).setFullYear(parseInt(year, 10));
|
|
14
|
+
},
|
|
15
|
+
m(date, month, locale) {
|
|
16
|
+
const newDate = new Date(date);
|
|
17
|
+
let monthIndex = parseInt(month, 10) - 1;
|
|
18
|
+
|
|
19
|
+
if (isNaN(monthIndex)) {
|
|
20
|
+
if (!month) {
|
|
21
|
+
return NaN;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const monthName = month.toLowerCase();
|
|
25
|
+
const compareNames = name => name.toLowerCase().startsWith(monthName);
|
|
26
|
+
// compare with both short and full names because some locales have periods
|
|
27
|
+
// in the short names (not equal to the first X letters of the full names)
|
|
28
|
+
monthIndex = locale.monthsShort.findIndex(compareNames);
|
|
29
|
+
if (monthIndex < 0) {
|
|
30
|
+
monthIndex = locale.months.findIndex(compareNames);
|
|
31
|
+
}
|
|
32
|
+
if (monthIndex < 0) {
|
|
33
|
+
return NaN;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
newDate.setMonth(monthIndex);
|
|
38
|
+
return newDate.getMonth() !== normalizeMonth(monthIndex)
|
|
39
|
+
? newDate.setDate(0)
|
|
40
|
+
: newDate.getTime();
|
|
41
|
+
},
|
|
42
|
+
d(date, day) {
|
|
43
|
+
return new Date(date).setDate(parseInt(day, 10));
|
|
44
|
+
},
|
|
45
|
+
};
|
|
46
|
+
// format functions for date parts
|
|
47
|
+
const formatFns = {
|
|
48
|
+
d(date) {
|
|
49
|
+
return date.getDate();
|
|
50
|
+
},
|
|
51
|
+
dd(date) {
|
|
52
|
+
return padZero(date.getDate(), 2);
|
|
53
|
+
},
|
|
54
|
+
D(date, locale) {
|
|
55
|
+
return locale.daysShort[date.getDay()];
|
|
56
|
+
},
|
|
57
|
+
DD(date, locale) {
|
|
58
|
+
return locale.days[date.getDay()];
|
|
59
|
+
},
|
|
60
|
+
m(date) {
|
|
61
|
+
return date.getMonth() + 1;
|
|
62
|
+
},
|
|
63
|
+
mm(date) {
|
|
64
|
+
return padZero(date.getMonth() + 1, 2);
|
|
65
|
+
},
|
|
66
|
+
M(date, locale) {
|
|
67
|
+
return locale.monthsShort[date.getMonth()];
|
|
68
|
+
},
|
|
69
|
+
MM(date, locale) {
|
|
70
|
+
return locale.months[date.getMonth()];
|
|
71
|
+
},
|
|
72
|
+
y(date) {
|
|
73
|
+
return date.getFullYear();
|
|
74
|
+
},
|
|
75
|
+
yy(date) {
|
|
76
|
+
return padZero(date.getFullYear(), 2).slice(-2);
|
|
77
|
+
},
|
|
78
|
+
yyyy(date) {
|
|
79
|
+
return padZero(date.getFullYear(), 4);
|
|
80
|
+
},
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
// get month index in normal range (0 - 11) from any number
|
|
84
|
+
function normalizeMonth(monthIndex) {
|
|
85
|
+
return monthIndex > -1 ? monthIndex % 12 : normalizeMonth(monthIndex + 12);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function padZero(num, length) {
|
|
89
|
+
return num.toString().padStart(length, '0');
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function parseFormatString(format) {
|
|
93
|
+
if (typeof format !== 'string') {
|
|
94
|
+
throw new Error("Invalid date format.");
|
|
95
|
+
}
|
|
96
|
+
if (format in knownFormats) {
|
|
97
|
+
return knownFormats[format];
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// sprit the format string into parts and seprators
|
|
101
|
+
const separators = format.split(reFormatTokens);
|
|
102
|
+
const parts = format.match(new RegExp(reFormatTokens, 'g'));
|
|
103
|
+
if (separators.length === 0 || !parts) {
|
|
104
|
+
throw new Error("Invalid date format.");
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// collect format functions used in the format
|
|
108
|
+
const partFormatters = parts.map(token => formatFns[token]);
|
|
109
|
+
|
|
110
|
+
// collect parse function keys used in the format
|
|
111
|
+
// iterate over parseFns' keys in order to keep the order of the keys.
|
|
112
|
+
const partParserKeys = Object.keys(parseFns).reduce((keys, key) => {
|
|
113
|
+
const token = parts.find(part => part[0] !== 'D' && part[0].toLowerCase() === key);
|
|
114
|
+
if (token) {
|
|
115
|
+
keys.push(key);
|
|
116
|
+
}
|
|
117
|
+
return keys;
|
|
118
|
+
}, []);
|
|
119
|
+
|
|
120
|
+
return knownFormats[format] = {
|
|
121
|
+
parser(dateStr, locale) {
|
|
122
|
+
const dateParts = dateStr.split(reNonDateParts).reduce((dtParts, part, index) => {
|
|
123
|
+
if (part.length > 0 && parts[index]) {
|
|
124
|
+
const token = parts[index][0];
|
|
125
|
+
if (token === 'M') {
|
|
126
|
+
dtParts.m = part;
|
|
127
|
+
} else if (token !== 'D') {
|
|
128
|
+
dtParts[token] = part;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
return dtParts;
|
|
132
|
+
}, {});
|
|
133
|
+
|
|
134
|
+
// iterate over partParserkeys so that the parsing is made in the oder
|
|
135
|
+
// of year, month and day to prevent the day parser from correcting last
|
|
136
|
+
// day of month wrongly
|
|
137
|
+
return partParserKeys.reduce((origDate, key) => {
|
|
138
|
+
const newDate = parseFns[key](origDate, dateParts[key], locale);
|
|
139
|
+
// ingnore the part failed to parse
|
|
140
|
+
return isNaN(newDate) ? origDate : newDate;
|
|
141
|
+
}, today());
|
|
142
|
+
},
|
|
143
|
+
formatter(date, locale) {
|
|
144
|
+
let dateStr = partFormatters.reduce((str, fn, index) => {
|
|
145
|
+
return str += `${separators[index]}${fn(date, locale)}`;
|
|
146
|
+
}, '');
|
|
147
|
+
// separators' length is always parts' length + 1,
|
|
148
|
+
return dateStr += lastItemOf(separators);
|
|
149
|
+
},
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
export function parseDate(dateStr, format, locale) {
|
|
154
|
+
if (dateStr instanceof Date || typeof dateStr === 'number') {
|
|
155
|
+
const date = stripTime(dateStr);
|
|
156
|
+
return isNaN(date) ? undefined : date;
|
|
157
|
+
}
|
|
158
|
+
if (!dateStr) {
|
|
159
|
+
return undefined;
|
|
160
|
+
}
|
|
161
|
+
if (dateStr === 'today') {
|
|
162
|
+
return today();
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
if (format && format.toValue) {
|
|
166
|
+
const date = format.toValue(dateStr, format, locale);
|
|
167
|
+
return isNaN(date) ? undefined : stripTime(date);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
return parseFormatString(format).parser(dateStr, locale);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
export function formatDate(date, format, locale) {
|
|
174
|
+
if (isNaN(date) || (!date && date !== 0)) {
|
|
175
|
+
return '';
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
const dateObj = typeof date === 'number' ? new Date(date) : date;
|
|
179
|
+
|
|
180
|
+
if (format.toDisplay) {
|
|
181
|
+
return format.toDisplay(dateObj, format, locale);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
return parseFormatString(format).formatter(dateObj, locale);
|
|
185
|
+
}
|
package/js/lib/date.js
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
export function stripTime(timeValue) {
|
|
2
|
+
return new Date(timeValue).setHours(0, 0, 0, 0);
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
export function today() {
|
|
6
|
+
return new Date().setHours(0, 0, 0, 0);
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
// Get the time value of the start of given date or year, month and day
|
|
10
|
+
export function dateValue(...args) {
|
|
11
|
+
switch (args.length) {
|
|
12
|
+
case 0:
|
|
13
|
+
return today();
|
|
14
|
+
case 1:
|
|
15
|
+
return stripTime(args[0]);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// use setFullYear() to keep 2-digit year from being mapped to 1900-1999
|
|
19
|
+
const newDate = new Date(0);
|
|
20
|
+
newDate.setFullYear(...args);
|
|
21
|
+
return newDate.setHours(0, 0, 0, 0);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export function addDays(date, amount) {
|
|
25
|
+
const newDate = new Date(date);
|
|
26
|
+
return newDate.setDate(newDate.getDate() + amount);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export function addWeeks(date, amount) {
|
|
30
|
+
return addDays(date, amount * 7);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export function addMonths(date, amount) {
|
|
34
|
+
// If the day of the date is not in the new month, the last day of the new
|
|
35
|
+
// month will be returned. e.g. Jan 31 + 1 month → Feb 28 (not Mar 03)
|
|
36
|
+
const newDate = new Date(date);
|
|
37
|
+
const monthsToSet = newDate.getMonth() + amount;
|
|
38
|
+
let expectedMonth = monthsToSet % 12;
|
|
39
|
+
if (expectedMonth < 0) {
|
|
40
|
+
expectedMonth += 12;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const time = newDate.setMonth(monthsToSet);
|
|
44
|
+
return newDate.getMonth() !== expectedMonth ? newDate.setDate(0) : time;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export function addYears(date, amount) {
|
|
48
|
+
// If the date is Feb 29 and the new year is not a leap year, Feb 28 of the
|
|
49
|
+
// new year will be returned.
|
|
50
|
+
const newDate = new Date(date);
|
|
51
|
+
const expectedMonth = newDate.getMonth();
|
|
52
|
+
const time = newDate.setFullYear(newDate.getFullYear() + amount);
|
|
53
|
+
return expectedMonth === 1 && newDate.getMonth() === 2 ? newDate.setDate(0) : time;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// Calculate the distance bettwen 2 days of the week
|
|
57
|
+
function dayDiff(day, from) {
|
|
58
|
+
return (day - from + 7) % 7;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// Get the date of the specified day of the week of given base date
|
|
62
|
+
export function dayOfTheWeekOf(baseDate, dayOfWeek, weekStart = 0) {
|
|
63
|
+
const baseDay = new Date(baseDate).getDay();
|
|
64
|
+
return addDays(baseDate, dayDiff(dayOfWeek, weekStart) - dayDiff(baseDay, weekStart));
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Get the ISO week of a date
|
|
68
|
+
export function getWeek(date) {
|
|
69
|
+
// start of ISO week is Monday
|
|
70
|
+
const thuOfTheWeek = dayOfTheWeekOf(date, 4, 1);
|
|
71
|
+
// 1st week == the week where the 4th of January is in
|
|
72
|
+
const firstThu = dayOfTheWeekOf(new Date(thuOfTheWeek).setMonth(0, 4), 4, 1);
|
|
73
|
+
return Math.round((thuOfTheWeek - firstThu) / 604800000) + 1;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// Get the start year of the period of years that includes given date
|
|
77
|
+
// years: length of the year period
|
|
78
|
+
export function startOfYearPeriod(date, years) {
|
|
79
|
+
/* @see https://en.wikipedia.org/wiki/Year_zero#ISO_8601 */
|
|
80
|
+
const year = new Date(date).getFullYear();
|
|
81
|
+
return Math.floor(year / years) * years;
|
|
82
|
+
}
|
package/js/lib/dom.js
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
let range = null;
|
|
2
|
+
|
|
3
|
+
export function parseHTML(html) {
|
|
4
|
+
if (range == null) { range = document.createRange() }
|
|
5
|
+
return range.createContextualFragment(html);
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
// equivalent to jQuery's :visble
|
|
9
|
+
export function isVisible(el) {
|
|
10
|
+
return !!(el.offsetWidth || el.offsetHeight || el.getClientRects().length);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export function hideElement(el) {
|
|
14
|
+
if (el.style.display === 'none') {
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
// back up the existing display setting in data-style-display
|
|
18
|
+
if (el.style.display) {
|
|
19
|
+
el.dataset.styleDisplay = el.style.display;
|
|
20
|
+
}
|
|
21
|
+
el.style.display = 'none';
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export function showElement(el) {
|
|
25
|
+
if (el.style.display !== 'none') {
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
if (el.dataset.styleDisplay) {
|
|
29
|
+
// restore backed-up dispay property
|
|
30
|
+
el.style.display = el.dataset.styleDisplay;
|
|
31
|
+
delete el.dataset.styleDisplay;
|
|
32
|
+
} else {
|
|
33
|
+
el.style.display = '';
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export function emptyChildNodes(el) {
|
|
38
|
+
if (el.firstChild) {
|
|
39
|
+
el.removeChild(el.firstChild);
|
|
40
|
+
emptyChildNodes(el);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export function replaceChildNodes(el, newChildNodes) {
|
|
45
|
+
emptyChildNodes(el);
|
|
46
|
+
if (newChildNodes instanceof DocumentFragment) {
|
|
47
|
+
el.appendChild(newChildNodes);
|
|
48
|
+
} else if (typeof newChildNodes === 'string') {
|
|
49
|
+
el.appendChild(parseHTML(newChildNodes));
|
|
50
|
+
} else if (typeof newChildNodes.forEach === 'function') {
|
|
51
|
+
newChildNodes.forEach((node) => {
|
|
52
|
+
el.appendChild(node);
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
}
|
package/js/lib/event.js
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
const listenerRegistry = new WeakMap();
|
|
2
|
+
const {addEventListener, removeEventListener} = EventTarget.prototype;
|
|
3
|
+
|
|
4
|
+
// Register event listeners to a key object
|
|
5
|
+
// listeners: array of listener definitions;
|
|
6
|
+
// - each definition must be a flat array of event target and the arguments
|
|
7
|
+
// used to call addEventListener() on the target
|
|
8
|
+
export function registerListeners(keyObj, listeners) {
|
|
9
|
+
let registered = listenerRegistry.get(keyObj);
|
|
10
|
+
if (!registered) {
|
|
11
|
+
registered = [];
|
|
12
|
+
listenerRegistry.set(keyObj, registered);
|
|
13
|
+
}
|
|
14
|
+
listeners.forEach((listener) => {
|
|
15
|
+
addEventListener.call(...listener);
|
|
16
|
+
registered.push(listener);
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export function unregisterListeners(keyObj) {
|
|
21
|
+
let listeners = listenerRegistry.get(keyObj);
|
|
22
|
+
if (!listeners) {
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
listeners.forEach((listener) => {
|
|
26
|
+
removeEventListener.call(...listener);
|
|
27
|
+
});
|
|
28
|
+
listenerRegistry.delete(keyObj);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// Event.composedPath() polyfill for Edge
|
|
32
|
+
// based on https://gist.github.com/kleinfreund/e9787d73776c0e3750dcfcdc89f100ec
|
|
33
|
+
if (!Event.prototype.composedPath) {
|
|
34
|
+
const getComposedPath = (node, path = []) => {
|
|
35
|
+
path.push(node);
|
|
36
|
+
|
|
37
|
+
let parent;
|
|
38
|
+
if (node.parentNode) {
|
|
39
|
+
parent = node.parentNode;
|
|
40
|
+
} else if (node.host) { // ShadowRoot
|
|
41
|
+
parent = node.host;
|
|
42
|
+
} else if (node.defaultView) { // Document
|
|
43
|
+
parent = node.defaultView;
|
|
44
|
+
}
|
|
45
|
+
return parent ? getComposedPath(parent, path) : path;
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
Event.prototype.composedPath = function () {
|
|
49
|
+
return getComposedPath(this.target);
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function findFromPath(path, criteria, currentTarget, index = 0) {
|
|
54
|
+
const el = path[index];
|
|
55
|
+
if (criteria(el)) {
|
|
56
|
+
return el;
|
|
57
|
+
} else if (el === currentTarget || !el.parentElement) {
|
|
58
|
+
// stop when reaching currentTarget or <html>
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
return findFromPath(path, criteria, currentTarget, index + 1);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// Search for the actual target of a delegated event
|
|
65
|
+
export function findElementInEventPath(ev, selector) {
|
|
66
|
+
const criteria = typeof selector === 'function' ? selector : el => el.matches(selector);
|
|
67
|
+
return findFromPath(ev.composedPath(), criteria, ev.currentTarget);
|
|
68
|
+
}
|
package/js/lib/utils.js
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
export function hasProperty(obj, prop) {
|
|
2
|
+
return Object.prototype.hasOwnProperty.call(obj, prop);
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
export function lastItemOf(arr) {
|
|
6
|
+
return arr[arr.length - 1];
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
// push only the items not included in the array
|
|
10
|
+
export function pushUnique(arr, ...items) {
|
|
11
|
+
items.forEach((item) => {
|
|
12
|
+
if (arr.includes(item)) {
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
arr.push(item);
|
|
16
|
+
});
|
|
17
|
+
return arr;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export function stringToArray(str, separator) {
|
|
21
|
+
// convert empty string to an empty array
|
|
22
|
+
return str ? str.split(separator) : [];
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export function isInRange(testVal, min, max) {
|
|
26
|
+
const minOK = min === undefined || testVal >= min;
|
|
27
|
+
const maxOK = max === undefined || testVal <= max;
|
|
28
|
+
return minOK && maxOK;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export function limitToRange(val, min, max) {
|
|
32
|
+
if (val < min) {
|
|
33
|
+
return min;
|
|
34
|
+
}
|
|
35
|
+
if (val > max) {
|
|
36
|
+
return max;
|
|
37
|
+
}
|
|
38
|
+
return val;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export function createTagRepeat(tagName, repeat, attributes = {}, index = 0, html = '') {
|
|
42
|
+
const openTagSrc = Object.keys(attributes).reduce((src, attr) => {
|
|
43
|
+
let val = attributes[attr];
|
|
44
|
+
if (typeof val === 'function') {
|
|
45
|
+
val = val(index);
|
|
46
|
+
}
|
|
47
|
+
return `${src} ${attr}="${val}"`;
|
|
48
|
+
}, tagName);
|
|
49
|
+
html += `<${openTagSrc}></${tagName}>`;
|
|
50
|
+
|
|
51
|
+
const next = index + 1;
|
|
52
|
+
return next < repeat
|
|
53
|
+
? createTagRepeat(tagName, repeat, attributes, next, html)
|
|
54
|
+
: html;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// Remove the spacing surrounding tags for HTML parser not to create text nodes
|
|
58
|
+
// before/after elements
|
|
59
|
+
export function optimizeTemplateHTML(html) {
|
|
60
|
+
return html.replace(/>\s+/g, '>').replace(/\s+</, '<');
|
|
61
|
+
}
|
package/js/main.js
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
// config options updatable by setOptions() and their default values
|
|
2
|
+
const defaultOptions = {
|
|
3
|
+
autohide: false,
|
|
4
|
+
beforeShowDay: null,
|
|
5
|
+
beforeShowDecade: null,
|
|
6
|
+
beforeShowMonth: null,
|
|
7
|
+
beforeShowYear: null,
|
|
8
|
+
calendarWeeks: false,
|
|
9
|
+
clearBtn: false,
|
|
10
|
+
dateDelimiter: ',',
|
|
11
|
+
datesDisabled: [],
|
|
12
|
+
daysOfWeekDisabled: [],
|
|
13
|
+
daysOfWeekHighlighted: [],
|
|
14
|
+
defaultViewDate: undefined, // placeholder, defaults to today() by the program
|
|
15
|
+
disableTouchKeyboard: false,
|
|
16
|
+
format: 'mm/dd/yyyy',
|
|
17
|
+
language: 'en',
|
|
18
|
+
maxDate: null,
|
|
19
|
+
maxNumberOfDates: 1,
|
|
20
|
+
maxView: 3,
|
|
21
|
+
minDate: null,
|
|
22
|
+
nextArrow: '<svg class="w-4 h-4 rtl:rotate-180" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 14 10"><path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M1 5h12m0 0L9 1m4 4L9 9"/></svg>',
|
|
23
|
+
orientation: 'auto',
|
|
24
|
+
pickLevel: 0,
|
|
25
|
+
prevArrow: '<svg class="w-4 h-4 rtl:rotate-180" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 14 10"><path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 5H1m0 0 4 4M1 5l4-4"/></svg>',
|
|
26
|
+
showDaysOfWeek: true,
|
|
27
|
+
showOnClick: true,
|
|
28
|
+
showOnFocus: true,
|
|
29
|
+
startView: 0,
|
|
30
|
+
title: '',
|
|
31
|
+
todayBtn: false,
|
|
32
|
+
todayBtnMode: 0,
|
|
33
|
+
todayHighlight: false,
|
|
34
|
+
updateOnBlur: true,
|
|
35
|
+
weekStart: 0,
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
export default defaultOptions;
|