@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.
Files changed (291) hide show
  1. package/.eslintignore +2 -0
  2. package/.eslintrc.js +73 -0
  3. package/.stylelintrc +12 -0
  4. package/CHANGELOG.md +72 -0
  5. package/LICENSE +21 -0
  6. package/README.md +71 -0
  7. package/demo/index.html +582 -0
  8. package/demo/live-demo.js +471 -0
  9. package/dist/DateRangePicker.cjs.js +2996 -0
  10. package/dist/DateRangePicker.esm.js +2994 -0
  11. package/dist/DateRangePicker.umd.js +3002 -0
  12. package/dist/Datepicker.cjs.js +2778 -0
  13. package/dist/Datepicker.esm.js +2776 -0
  14. package/dist/Datepicker.umd.js +2784 -0
  15. package/dist/css/datepicker-bs4.css +276 -0
  16. package/dist/css/datepicker-bs4.min.css +1 -0
  17. package/dist/css/datepicker-bs5.css +276 -0
  18. package/dist/css/datepicker-bs5.min.css +1 -0
  19. package/dist/css/datepicker-bulma.css +258 -0
  20. package/dist/css/datepicker-bulma.min.css +1 -0
  21. package/dist/css/datepicker-foundation.css +262 -0
  22. package/dist/css/datepicker-foundation.min.css +1 -0
  23. package/dist/css/datepicker.css +306 -0
  24. package/dist/css/datepicker.min.css +1403 -0
  25. package/dist/js/datepicker-full.js +2777 -0
  26. package/dist/js/datepicker-full.min.js +1 -0
  27. package/dist/js/datepicker.js +2569 -0
  28. package/dist/js/datepicker.min.js +1 -0
  29. package/dist/js/locales/ar-tn.js +15 -0
  30. package/dist/js/locales/ar.js +15 -0
  31. package/dist/js/locales/az.js +14 -0
  32. package/dist/js/locales/bg.js +14 -0
  33. package/dist/js/locales/bm.js +18 -0
  34. package/dist/js/locales/bn.js +19 -0
  35. package/dist/js/locales/br.js +18 -0
  36. package/dist/js/locales/bs.js +15 -0
  37. package/dist/js/locales/ca.js +18 -0
  38. package/dist/js/locales/cs.js +19 -0
  39. package/dist/js/locales/cy.js +14 -0
  40. package/dist/js/locales/da.js +19 -0
  41. package/dist/js/locales/de.js +18 -0
  42. package/dist/js/locales/el.js +16 -0
  43. package/dist/js/locales/en-AU.js +18 -0
  44. package/dist/js/locales/en-CA.js +18 -0
  45. package/dist/js/locales/en-GB.js +18 -0
  46. package/dist/js/locales/en-IE.js +17 -0
  47. package/dist/js/locales/en-NZ.js +17 -0
  48. package/dist/js/locales/en-ZA.js +17 -0
  49. package/dist/js/locales/eo.js +17 -0
  50. package/dist/js/locales/es.js +18 -0
  51. package/dist/js/locales/et.js +18 -0
  52. package/dist/js/locales/eu.js +18 -0
  53. package/dist/js/locales/fa.js +17 -0
  54. package/dist/js/locales/fi.js +17 -0
  55. package/dist/js/locales/fo.js +15 -0
  56. package/dist/js/locales/fr-CH.js +21 -0
  57. package/dist/js/locales/fr.js +18 -0
  58. package/dist/js/locales/gl.js +16 -0
  59. package/dist/js/locales/he.js +15 -0
  60. package/dist/js/locales/hi.js +18 -0
  61. package/dist/js/locales/hr.js +13 -0
  62. package/dist/js/locales/hu.js +18 -0
  63. package/dist/js/locales/hy.js +18 -0
  64. package/dist/js/locales/id.js +15 -0
  65. package/dist/js/locales/is.js +14 -0
  66. package/dist/js/locales/it-CH.js +20 -0
  67. package/dist/js/locales/it.js +18 -0
  68. package/dist/js/locales/ja.js +17 -0
  69. package/dist/js/locales/ka.js +17 -0
  70. package/dist/js/locales/kk.js +15 -0
  71. package/dist/js/locales/km.js +15 -0
  72. package/dist/js/locales/ko.js +18 -0
  73. package/dist/js/locales/lt.js +19 -0
  74. package/dist/js/locales/lv.js +18 -0
  75. package/dist/js/locales/me.js +17 -0
  76. package/dist/js/locales/mk.js +15 -0
  77. package/dist/js/locales/mn.js +17 -0
  78. package/dist/js/locales/mr.js +18 -0
  79. package/dist/js/locales/ms.js +15 -0
  80. package/dist/js/locales/nl-BE.js +18 -0
  81. package/dist/js/locales/nl.js +18 -0
  82. package/dist/js/locales/no.js +18 -0
  83. package/dist/js/locales/oc.js +17 -0
  84. package/dist/js/locales/pl.js +17 -0
  85. package/dist/js/locales/pt-BR.js +17 -0
  86. package/dist/js/locales/pt.js +18 -0
  87. package/dist/js/locales/ro.js +17 -0
  88. package/dist/js/locales/ru.js +18 -0
  89. package/dist/js/locales/si.js +18 -0
  90. package/dist/js/locales/sk.js +18 -0
  91. package/dist/js/locales/sl.js +15 -0
  92. package/dist/js/locales/sq.js +18 -0
  93. package/dist/js/locales/sr-latn.js +16 -0
  94. package/dist/js/locales/sr.js +16 -0
  95. package/dist/js/locales/sv.js +17 -0
  96. package/dist/js/locales/sw.js +15 -0
  97. package/dist/js/locales/ta.js +18 -0
  98. package/dist/js/locales/tg.js +19 -0
  99. package/dist/js/locales/th.js +14 -0
  100. package/dist/js/locales/tk.js +18 -0
  101. package/dist/js/locales/tr.js +17 -0
  102. package/dist/js/locales/uk.js +17 -0
  103. package/dist/js/locales/uz-cyrl.js +18 -0
  104. package/dist/js/locales/uz-latn.js +18 -0
  105. package/dist/js/locales/vi.js +16 -0
  106. package/dist/js/locales/zh-CN.js +19 -0
  107. package/dist/js/locales/zh-TW.js +18 -0
  108. package/dist/locales/index.cjs.js +1028 -0
  109. package/dist/locales/index.esm.js +1028 -0
  110. package/dist/main.cjs.js +2999 -0
  111. package/dist/main.esm.js +2994 -0
  112. package/dist/main.umd.js +3005 -0
  113. package/docs/.nojekyll +0 -0
  114. package/docs/README.md +266 -0
  115. package/docs/_sidebar.md +6 -0
  116. package/docs/api.md +284 -0
  117. package/docs/date-string+format.md +90 -0
  118. package/docs/i18n.md +99 -0
  119. package/docs/images/datepicker-inline.jpg +0 -0
  120. package/docs/images/datepicker.jpg +0 -0
  121. package/docs/images/multidate.jpg +0 -0
  122. package/docs/images/picker-structure.jpg +0 -0
  123. package/docs/images/rangepicker.jpg +0 -0
  124. package/docs/images/view-days.jpg +0 -0
  125. package/docs/images/view-decades.jpg +0 -0
  126. package/docs/images/view-months.jpg +0 -0
  127. package/docs/images/view-years.jpg +0 -0
  128. package/docs/index.html +26 -0
  129. package/docs/options.md +354 -0
  130. package/docs/overview.md +174 -0
  131. package/extras/twoDigitToFullYear/test/twoDigitToFullYear.js +58 -0
  132. package/extras/twoDigitToFullYear/twoDigitToFullYear.js +26 -0
  133. package/js/DateRangePicker.js +210 -0
  134. package/js/Datepicker.js +487 -0
  135. package/js/datepicker-full.js +5 -0
  136. package/js/events/functions.js +48 -0
  137. package/js/events/inputFieldListeners.js +206 -0
  138. package/js/events/otherListeners.js +15 -0
  139. package/js/events/pickerListeners.js +70 -0
  140. package/js/i18n/base-locales.js +13 -0
  141. package/js/i18n/locales/ar-tn.js +15 -0
  142. package/js/i18n/locales/ar.js +15 -0
  143. package/js/i18n/locales/az.js +14 -0
  144. package/js/i18n/locales/bg.js +14 -0
  145. package/js/i18n/locales/bm.js +18 -0
  146. package/js/i18n/locales/bn.js +19 -0
  147. package/js/i18n/locales/br.js +18 -0
  148. package/js/i18n/locales/bs.js +15 -0
  149. package/js/i18n/locales/ca.js +18 -0
  150. package/js/i18n/locales/cs.js +19 -0
  151. package/js/i18n/locales/cy.js +14 -0
  152. package/js/i18n/locales/da.js +19 -0
  153. package/js/i18n/locales/de.js +18 -0
  154. package/js/i18n/locales/el.js +16 -0
  155. package/js/i18n/locales/en-AU.js +18 -0
  156. package/js/i18n/locales/en-CA.js +18 -0
  157. package/js/i18n/locales/en-GB.js +18 -0
  158. package/js/i18n/locales/en-IE.js +17 -0
  159. package/js/i18n/locales/en-NZ.js +17 -0
  160. package/js/i18n/locales/en-ZA.js +17 -0
  161. package/js/i18n/locales/eo.js +17 -0
  162. package/js/i18n/locales/es.js +18 -0
  163. package/js/i18n/locales/et.js +18 -0
  164. package/js/i18n/locales/eu.js +18 -0
  165. package/js/i18n/locales/fa.js +17 -0
  166. package/js/i18n/locales/fi.js +17 -0
  167. package/js/i18n/locales/fo.js +15 -0
  168. package/js/i18n/locales/fr-CH.js +21 -0
  169. package/js/i18n/locales/fr.js +18 -0
  170. package/js/i18n/locales/gl.js +16 -0
  171. package/js/i18n/locales/he.js +15 -0
  172. package/js/i18n/locales/hi.js +18 -0
  173. package/js/i18n/locales/hr.js +13 -0
  174. package/js/i18n/locales/hu.js +18 -0
  175. package/js/i18n/locales/hy.js +18 -0
  176. package/js/i18n/locales/id.js +15 -0
  177. package/js/i18n/locales/is.js +14 -0
  178. package/js/i18n/locales/it-CH.js +20 -0
  179. package/js/i18n/locales/it.js +18 -0
  180. package/js/i18n/locales/ja.js +17 -0
  181. package/js/i18n/locales/ka.js +17 -0
  182. package/js/i18n/locales/kk.js +15 -0
  183. package/js/i18n/locales/km.js +15 -0
  184. package/js/i18n/locales/ko.js +18 -0
  185. package/js/i18n/locales/lt.js +19 -0
  186. package/js/i18n/locales/lv.js +18 -0
  187. package/js/i18n/locales/me.js +17 -0
  188. package/js/i18n/locales/mk.js +15 -0
  189. package/js/i18n/locales/mn.js +17 -0
  190. package/js/i18n/locales/mr.js +18 -0
  191. package/js/i18n/locales/ms.js +15 -0
  192. package/js/i18n/locales/nl-BE.js +18 -0
  193. package/js/i18n/locales/nl.js +18 -0
  194. package/js/i18n/locales/no.js +18 -0
  195. package/js/i18n/locales/oc.js +17 -0
  196. package/js/i18n/locales/pl.js +17 -0
  197. package/js/i18n/locales/pt-BR.js +17 -0
  198. package/js/i18n/locales/pt.js +18 -0
  199. package/js/i18n/locales/ro.js +17 -0
  200. package/js/i18n/locales/ru.js +18 -0
  201. package/js/i18n/locales/si.js +18 -0
  202. package/js/i18n/locales/sk.js +18 -0
  203. package/js/i18n/locales/sl.js +15 -0
  204. package/js/i18n/locales/sq.js +18 -0
  205. package/js/i18n/locales/sr-latn.js +16 -0
  206. package/js/i18n/locales/sr.js +16 -0
  207. package/js/i18n/locales/sv.js +17 -0
  208. package/js/i18n/locales/sw.js +15 -0
  209. package/js/i18n/locales/ta.js +18 -0
  210. package/js/i18n/locales/tg.js +19 -0
  211. package/js/i18n/locales/th.js +14 -0
  212. package/js/i18n/locales/tk.js +18 -0
  213. package/js/i18n/locales/tr.js +17 -0
  214. package/js/i18n/locales/uk.js +17 -0
  215. package/js/i18n/locales/uz-cyrl.js +18 -0
  216. package/js/i18n/locales/uz-latn.js +18 -0
  217. package/js/i18n/locales/vi.js +16 -0
  218. package/js/i18n/locales/zh-CN.js +19 -0
  219. package/js/i18n/locales/zh-TW.js +18 -0
  220. package/js/lib/date-format.js +185 -0
  221. package/js/lib/date.js +82 -0
  222. package/js/lib/dom.js +55 -0
  223. package/js/lib/event.js +68 -0
  224. package/js/lib/utils.js +61 -0
  225. package/js/main.js +4 -0
  226. package/js/options/defaultOptions.js +38 -0
  227. package/js/options/processOptions.js +263 -0
  228. package/js/picker/Picker.js +334 -0
  229. package/js/picker/templates/calendarWeeksTemplate.js +8 -0
  230. package/js/picker/templates/daysTemplate.js +8 -0
  231. package/js/picker/templates/pickerTemplate.js +23 -0
  232. package/js/picker/views/DaysView.js +250 -0
  233. package/js/picker/views/MonthsView.js +198 -0
  234. package/js/picker/views/View.js +55 -0
  235. package/js/picker/views/YearsView.js +170 -0
  236. package/package.json +81 -0
  237. package/postcss.config.js +5 -0
  238. package/rollup.config.js +75 -0
  239. package/sass/_mixins.scss +12 -0
  240. package/sass/datepicker-bs4.scss +91 -0
  241. package/sass/datepicker-bs5.scss +91 -0
  242. package/sass/datepicker-bulma.scss +69 -0
  243. package/sass/datepicker-foundation.scss +66 -0
  244. package/sass/datepicker.scss +436 -0
  245. package/sass/index-bs4.scss +5 -0
  246. package/sass/index-bs5.scss +5 -0
  247. package/sass/index-bulma.scss +6 -0
  248. package/sass/index-foundation.scss +3 -0
  249. package/scripts/build-css.js +39 -0
  250. package/scripts/build-locales.js +57 -0
  251. package/scripts/convert-bsdp-locales.js +65 -0
  252. package/scripts/minify-css.js +31 -0
  253. package/scripts/minify-js.js +17 -0
  254. package/style.css +10 -0
  255. package/tailwind.config.js +16 -0
  256. package/tailwind.css +1389 -0
  257. package/test/DateRangePicker/DateRangePicker.js +547 -0
  258. package/test/DateRangePicker/api-methods.js +415 -0
  259. package/test/DateRangePicker/date-selection.js +472 -0
  260. package/test/DateRangePicker/options.js +308 -0
  261. package/test/Datepicker/Datepicker-object.js +236 -0
  262. package/test/Datepicker/api-methods.js +328 -0
  263. package/test/_utils/date.js +102 -0
  264. package/test/_utils/dom.js +70 -0
  265. package/test/events.js +785 -0
  266. package/test/inline-mode.js +45 -0
  267. package/test/keyboard-operation/arrow-down.js +293 -0
  268. package/test/keyboard-operation/arrow-left.js +255 -0
  269. package/test/keyboard-operation/arrow-right.js +215 -0
  270. package/test/keyboard-operation/arrow-up.js +461 -0
  271. package/test/keyboard-operation/edit-mode.js +458 -0
  272. package/test/keyboard-operation/keyboard-operation.js +146 -0
  273. package/test/mouse-operation.js +580 -0
  274. package/test/options/before-show.js +635 -0
  275. package/test/options/bulma-datepicker.sublime-workspace +1280 -0
  276. package/test/options/buttons.js +383 -0
  277. package/test/options/date-restrictions.js +802 -0
  278. package/test/options/format.js +281 -0
  279. package/test/options/multidate.js +380 -0
  280. package/test/options/options.js +727 -0
  281. package/test/options/orientation.js +410 -0
  282. package/test/options/pick-levle+view.js +357 -0
  283. package/test/test.html +94 -0
  284. package/test/unit/DateRangePicker.js +192 -0
  285. package/test/unit/Datepicker.js +307 -0
  286. package/test/unit/_setup.js +28 -0
  287. package/test/unit/lib/date-format.js +310 -0
  288. package/test/unit/lib/date.js +211 -0
  289. package/test/unit/lib/dom.js +142 -0
  290. package/test/unit/lib/event.js +207 -0
  291. 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
+ }
@@ -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
+ }
@@ -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,4 @@
1
+ import Datepicker from './Datepicker.js';
2
+ import DateRangePicker from './DateRangePicker.js';
3
+
4
+ export {Datepicker, DateRangePicker};
@@ -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;