@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,727 @@
1
+ describe('options', function () {
2
+ let clock;
3
+ let input;
4
+
5
+ beforeEach(function () {
6
+ clock = sinon.useFakeTimers({now: new Date(2020, 1, 14)});
7
+ input = document.createElement('input');
8
+ testContainer.appendChild(input);
9
+ });
10
+
11
+ afterEach(function () {
12
+ testContainer.removeChild(input);
13
+ clock.restore();
14
+ });
15
+
16
+ describe('autohide', function () {
17
+ it('makes the picker hide automatically on selection when true', function () {
18
+ const {dp, picker} = createDP(input, {autohide: true});
19
+ dp.show();
20
+
21
+ // by satDate()
22
+ dp.setDate('2/4/2020');
23
+ expect(isVisible(picker), 'to be false');
24
+
25
+ dp.show();
26
+
27
+ // by click on day cell
28
+ getCells(picker)[25].click();
29
+ expect(isVisible(picker), 'to be false');
30
+
31
+ dp.show();
32
+
33
+ // by typing enter key in edit mode
34
+ dp.enterEditMode();
35
+ input.value = '2/14/2020';
36
+ simulant.fire(input, 'keydown', {key: 'Enter'});
37
+ expect(isVisible(picker), 'to be false');
38
+
39
+ // focus is kept on input field after auto-hidng by clicking day cell
40
+ // (issue #21)
41
+ const spyFocus = sinon.spy(input, 'focus');
42
+ dp.show();
43
+
44
+ getCells(picker)[25].click();
45
+ expect(spyFocus.called, 'to be true');
46
+
47
+ spyFocus.restore();
48
+
49
+ dp.destroy();
50
+ input.value = '';
51
+ });
52
+
53
+ it('can be updated with setOptions()', function () {
54
+ const {dp, picker} = createDP(input);
55
+ dp.setOptions({autohide: true});
56
+ dp.show();
57
+
58
+ dp.setDate('2/4/2020');
59
+ expect(isVisible(picker), 'to be false');
60
+
61
+ dp.setOptions({autohide: false});
62
+ dp.show();
63
+
64
+ dp.setDate('2/14/2020');
65
+ expect(isVisible(picker), 'to be true');
66
+
67
+ dp.destroy();
68
+ input.value = '';
69
+ });
70
+ });
71
+
72
+ describe('buttonClass', function () {
73
+ it('specifies the main class used for the button elements', function () {
74
+ const {dp, picker} = createDP(input, {buttonClass: 'btn'});
75
+ const [viewSwitch, prevBtn, nextBtn, todayBtn, clearBtn] = getParts(picker, [
76
+ '.view-switch',
77
+ '.prev-btn',
78
+ '.next-btn',
79
+ '.today-btn',
80
+ '.clear-btn',
81
+ ]);
82
+
83
+ expect(viewSwitch.className, 'to be', 'btn view-switch');
84
+ expect(prevBtn.className, 'to be', 'btn prev-btn');
85
+ expect(nextBtn.className, 'to be', 'btn next-btn');
86
+ expect(todayBtn.className, 'to be', 'btn today-btn');
87
+ expect(clearBtn.className, 'to be', 'btn clear-btn');
88
+
89
+ dp.destroy();
90
+ });
91
+
92
+ it('cannot be update with setOptions()', function () {
93
+ const {dp, picker} = createDP(input);
94
+ dp.setOptions({buttonClass: 'btn'});
95
+
96
+ const [viewSwitch, prevBtn, nextBtn, todayBtn, clearBtn] = getParts(picker, [
97
+ '.view-switch',
98
+ '.prev-btn',
99
+ '.next-btn',
100
+ '.today-btn',
101
+ '.clear-btn',
102
+ ]);
103
+ expect(viewSwitch.className, 'to be', 'button view-switch');
104
+ expect(prevBtn.className, 'to be', 'button prev-btn');
105
+ expect(nextBtn.className, 'to be', 'button next-btn');
106
+ expect(todayBtn.className, 'to be', 'button today-btn');
107
+ expect(clearBtn.className, 'to be', 'button clear-btn');
108
+
109
+ dp.destroy();
110
+ });
111
+ });
112
+
113
+ describe('calendarWeeks', function () {
114
+ const getDisplayedWeeks = (picker) => {
115
+ const calendarWeeks = picker.querySelector('.calendar-weeks');
116
+ return Array.from(calendarWeeks.querySelectorAll('.week')).map(el => el.textContent);
117
+ };
118
+
119
+ it('enables display ISO weeks in days view when true', function () {
120
+ const {dp, picker} = createDP(input, {calendarWeeks: true});
121
+ const [viewSwitch, prevBtn] = getParts(picker, ['.view-switch', '.prev-btn']);
122
+ dp.show();
123
+
124
+ let calendarWeeks = picker.querySelector('.calendar-weeks');
125
+ expect(isVisible(calendarWeeks), 'to be true');
126
+ expect(getDisplayedWeeks(picker), 'to equal', ['5', '6', '7', '8', '9', '10']);
127
+
128
+ prevBtn.click();
129
+ expect(getDisplayedWeeks(picker), 'to equal', ['1', '2', '3', '4', '5', '6']);
130
+
131
+ prevBtn.click();
132
+ expect(getDisplayedWeeks(picker), 'to equal', ['48', '49', '50', '51', '52', '1']);
133
+
134
+ prevBtn.click();
135
+ expect(getDisplayedWeeks(picker), 'to equal', ['44', '45', '46', '47', '48', '49']);
136
+
137
+ dp.setDate('01/01/2021');
138
+ expect(getDisplayedWeeks(picker), 'to equal', ['53', '1', '2', '3', '4', '5']);
139
+
140
+ prevBtn.click();
141
+ expect(getDisplayedWeeks(picker), 'to equal', ['49', '50', '51', '52', '53', '1']);
142
+
143
+ // months view
144
+ viewSwitch.click();
145
+ expect(picker.querySelector('.calendar-weeks'), 'to be null');
146
+
147
+ // years view
148
+ viewSwitch.click();
149
+ expect(picker.querySelector('.calendar-weeks'), 'to be null');
150
+
151
+ // decades view
152
+ viewSwitch.click();
153
+ expect(picker.querySelector('.calendar-weeks'), 'to be null');
154
+
155
+ dp.destroy();
156
+ });
157
+
158
+ it('can be updated with setOptions()', function () {
159
+ const {dp, picker} = createDP(input);
160
+ dp.setOptions({calendarWeeks: true});
161
+ dp.show();
162
+
163
+ expect(isVisible(picker.querySelector('.calendar-weeks')), 'to be true');
164
+
165
+ dp.setOptions({calendarWeeks: false});
166
+ expect(picker.querySelector('.calendar-weeks'), 'to be null');
167
+
168
+ dp.destroy();
169
+ });
170
+ });
171
+
172
+ describe('container', function () {
173
+ let foo;
174
+
175
+ beforeEach(function () {
176
+ foo = parseHTML('<div id="foo"><div>').firstChild;
177
+ testContainer.appendChild(foo);
178
+ });
179
+
180
+ afterEach(function () {
181
+ testContainer.removeChild(foo);
182
+ });
183
+
184
+ it('specifies the element to attach the picker', function () {
185
+ const dp = new Datepicker(input, {container: '#foo'});
186
+ expect(document.querySelector('.datepicker').parentElement, 'to be', foo);
187
+
188
+ dp.destroy();
189
+ });
190
+
191
+ it('cannot be update with setOptions()', function () {
192
+ const dp = new Datepicker(input);
193
+ dp.setOptions({container: '#foo'});
194
+
195
+ expect(document.querySelector('.datepicker').parentElement, 'to be', document.body);
196
+
197
+ dp.destroy();
198
+ });
199
+ });
200
+
201
+ describe('daysOfWeekHighlighted', function () {
202
+ const highlightedCellIndices = (picker) => {
203
+ const cells = getCells(picker);
204
+ return filterCells(cells, '.highlighted').map(el => cells.indexOf(el));
205
+ };
206
+ const highlighted1stWeekIndices = picker => highlightedCellIndices(picker).filter(val => val < 7);
207
+
208
+ it('specifies the days of week to highlight by dey numbers', function () {
209
+ const {dp, picker} = createDP(input, {daysOfWeekHighlighted: [1, 5]});
210
+ dp.show();
211
+
212
+ expect(highlightedCellIndices(picker), 'to equal', [1, 5, 8, 12, 15, 19, 22, 26, 29, 33, 36, 40]);
213
+
214
+ const viewSwitch = getViewSwitch(picker);
215
+ // months view
216
+ viewSwitch.click();
217
+ expect(highlightedCellIndices(picker), 'to equal', []);
218
+
219
+ // years view
220
+ viewSwitch.click();
221
+ expect(highlightedCellIndices(picker), 'to equal', []);
222
+
223
+ // decades view
224
+ viewSwitch.click();
225
+ expect(highlightedCellIndices(picker), 'to equal', []);
226
+
227
+ dp.destroy();
228
+ });
229
+
230
+ it('can contain values of 0 - 6 and max 6 items', function () {
231
+ const {dp, picker} = createDP(input, {daysOfWeekHighlighted: [0, -1, 1, 2, 3, 2, 4, 5, 6, 7]});
232
+ dp.show();
233
+
234
+ expect(highlighted1stWeekIndices(picker), 'to equal', [0, 1, 2, 3, 4, 5]);
235
+
236
+ dp.destroy();
237
+ });
238
+
239
+ it('can be updated with setOptions()', function () {
240
+ const {dp, picker} = createDP(input);
241
+ dp.setOptions({daysOfWeekHighlighted: [6, 0, 3]});
242
+ dp.show();
243
+
244
+ expect(highlighted1stWeekIndices(picker), 'to equal', [0, 3, 6]);
245
+
246
+ dp.setOptions({daysOfWeekHighlighted: []});
247
+ expect(highlightedCellIndices(picker), 'to equal', []);
248
+
249
+ dp.destroy();
250
+ });
251
+ });
252
+
253
+ describe('defaultViewDate', function () {
254
+ it('specifies the start view date in the case no selection is made', function () {
255
+ const date = new Date(1984, 0, 24);
256
+ const {dp, picker} = createDP(input, {defaultViewDate: date});
257
+ dp.show();
258
+
259
+ expect(getViewSwitch(picker).textContent, 'to be', 'January 1984');
260
+
261
+ let cells = getCells(picker);
262
+ expect(filterCells(cells, '.focused'), 'to equal', [cells[23]]);
263
+ expect(cells[23].textContent, 'to be', '24');
264
+
265
+ dp.setDate('7/4/2020');
266
+ dp.setDate({clear: true});
267
+
268
+ expect(getViewSwitch(picker).textContent, 'to be', 'January 1984');
269
+
270
+ cells = getCells(picker);
271
+ expect(filterCells(cells, '.focused'), 'to equal', [cells[23]]);
272
+ expect(cells[23].textContent, 'to be', '24');
273
+
274
+ picker.querySelector('.prev-btn').click();
275
+ dp.hide();
276
+ dp.show();
277
+
278
+ expect(getViewSwitch(picker).textContent, 'to be', 'January 1984');
279
+
280
+ cells = getCells(picker);
281
+ expect(filterCells(cells, '.focused'), 'to equal', [cells[23]]);
282
+ expect(cells[23].textContent, 'to be', '24');
283
+
284
+ dp.destroy();
285
+ });
286
+
287
+ it('can be updated with setOptions()', function () {
288
+ const {dp, picker} = createDP(input);
289
+ dp.show();
290
+
291
+ dp.setOptions({defaultViewDate: new Date(1984, 0, 24)});
292
+ dp.hide();
293
+ dp.show();
294
+
295
+ expect(getViewSwitch(picker).textContent, 'to be', 'January 1984');
296
+
297
+ let cells = getCells(picker);
298
+ expect(filterCells(cells, '.focused'), 'to equal', [cells[23]]);
299
+ expect(cells[23].textContent, 'to be', '24');
300
+
301
+ dp.setOptions({defaultViewDate: new Date(2007, 5, 29)});
302
+ dp.setDate('7/4/2020');
303
+ dp.setDate({clear: true});
304
+
305
+ expect(getViewSwitch(picker).textContent, 'to be', 'June 2007');
306
+
307
+ cells = getCells(picker);
308
+ expect(filterCells(cells, '.focused'), 'to equal', [cells[33]]);
309
+ expect(cells[33].textContent, 'to be', '29');
310
+
311
+ dp.destroy();
312
+ });
313
+ });
314
+
315
+ describe('disableTouchKeyboard', function () {
316
+ const ontouchstartSupported = 'ontouchstart' in document;
317
+
318
+ before(function () {
319
+ if (!ontouchstartSupported) {
320
+ document.ontouchstart = null;
321
+ }
322
+ });
323
+
324
+ after(function () {
325
+ if (!ontouchstartSupported) {
326
+ delete document.ontouchstart;
327
+ }
328
+ });
329
+
330
+ it('unfocuses the input after showing the picker', function () {
331
+ const dp = new Datepicker(input, {disableTouchKeyboard: true});
332
+ input.focus();
333
+
334
+ expect(document.activeElement, 'not to be', input);
335
+
336
+ dp.destroy();
337
+ });
338
+
339
+ it('prevents the input from getting focus after an eleent in the picker is clicked', function () {
340
+ const {dp, picker} = createDP(input, {disableTouchKeyboard: true});
341
+ const [viewSwitch, prevBtn] = getParts(picker, ['.view-switch', '.prev-btn']);
342
+ dp.show();
343
+
344
+ prevBtn.focus();
345
+ simulant.fire(prevBtn, 'click');
346
+ expect(document.activeElement, 'not to be', input);
347
+
348
+ simulant.fire(getCells(picker)[15], 'click');
349
+ expect(document.activeElement, 'not to be', input);
350
+
351
+ viewSwitch.focus();
352
+ simulant.fire(viewSwitch, 'click');
353
+ expect(document.activeElement, 'not to be', input);
354
+
355
+ simulant.fire(getCells(picker)[6], 'click');
356
+ expect(document.activeElement, 'not to be', input);
357
+
358
+ dp.destroy();
359
+ });
360
+
361
+ it('is ignored if the browser does not support document.ontouchstart', function () {
362
+ if (ontouchstartSupported) {
363
+ return;
364
+ }
365
+ delete document.ontouchstart;
366
+
367
+ const {dp, picker} = createDP(input, {disableTouchKeyboard: true});
368
+ const [viewSwitch, prevBtn] = getParts(picker, ['.view-switch', '.prev-btn']);
369
+ input.focus();
370
+
371
+ expect(document.activeElement, 'to be', input);
372
+
373
+ prevBtn.focus();
374
+ simulant.fire(prevBtn, 'click');
375
+ expect(document.activeElement, 'to be', input);
376
+
377
+ prevBtn.focus();
378
+ simulant.fire(getCells(picker)[15], 'click');
379
+ expect(document.activeElement, 'to be', input);
380
+
381
+ viewSwitch.focus();
382
+ simulant.fire(viewSwitch, 'click');
383
+ expect(document.activeElement, 'to be', input);
384
+
385
+ viewSwitch.focus();
386
+ simulant.fire(getCells(picker)[6], 'click');
387
+ expect(document.activeElement, 'to be', input);
388
+
389
+ dp.destroy();
390
+ document.ontouchstart = null;
391
+ });
392
+
393
+ it('can be updated with setOptions()', function () {
394
+ const dp = new Datepicker(input);
395
+ dp.setOptions({disableTouchKeyboard: true});
396
+ input.focus();
397
+
398
+ expect(document.activeElement, 'not to be', input);
399
+
400
+ dp.hide();
401
+ dp.setOptions({disableTouchKeyboard: false});
402
+ input.focus();
403
+
404
+ expect(document.activeElement, 'to be', input);
405
+
406
+ dp.destroy();
407
+ });
408
+ });
409
+
410
+ describe('nextArrow', function () {
411
+ it('specifies the label of the next button in HTML (or plain text)', function () {
412
+ const html = '<i class="icn icn-arrow-right"></i>';
413
+ const {dp, picker} = createDP(input, {nextArrow: html});
414
+ const nextBtn = picker.querySelector('.next-btn');
415
+ dp.show();
416
+
417
+ expect(nextBtn.innerHTML, 'to be', html);
418
+
419
+ dp.destroy();
420
+ });
421
+
422
+ it('can be updated with setOptions()', function () {
423
+ const {dp, picker} = createDP(input);
424
+ const nextBtn = picker.querySelector('.next-btn');
425
+ dp.setOptions({nextArrow: 'N'});
426
+ dp.show();
427
+
428
+ expect(nextBtn.textContent, 'to be', 'N');
429
+
430
+ dp.setOptions({nextArrow: '>'});
431
+ expect(nextBtn.textContent, 'to be', '>');
432
+
433
+ dp.destroy();
434
+ });
435
+ });
436
+
437
+ describe('prevArrow', function () {
438
+ it('specifies the label of the next button in HTML (or plain text)', function () {
439
+ const html = '<i class="icn icn-arrow-left"></i>';
440
+ const {dp, picker} = createDP(input, {prevArrow: html});
441
+ const prevBtn = picker.querySelector('.prev-btn');
442
+ dp.show();
443
+
444
+ expect(prevBtn.innerHTML, 'to be', html);
445
+
446
+ dp.destroy();
447
+ });
448
+
449
+ it('can be updated with setOptions()', function () {
450
+ const {dp, picker} = createDP(input);
451
+ const prevBtn = picker.querySelector('.prev-btn');
452
+ dp.setOptions({prevArrow: 'P'});
453
+ dp.show();
454
+
455
+ expect(prevBtn.textContent, 'to be', 'P');
456
+
457
+ dp.setOptions({prevArrow: '<'});
458
+ expect(prevBtn.textContent, 'to be', '<');
459
+
460
+ dp.destroy();
461
+ });
462
+ });
463
+
464
+ describe('showDaysOfWeek', function () {
465
+ it('hides day names of week when false', function () {
466
+ const {dp, picker} = createDP(input, {showDaysOfWeek: false});
467
+ dp.show();
468
+
469
+ expect(isVisible(picker.querySelector('.days-of-week')), 'to be false');
470
+
471
+ dp.destroy();
472
+ });
473
+
474
+ it('can be updated with setOptions()', function () {
475
+ const {dp, picker} = createDP(input);
476
+ dp.setOptions({showDaysOfWeek: false});
477
+ dp.show();
478
+
479
+ expect(isVisible(picker.querySelector('.days-of-week')), 'to be false');
480
+
481
+ dp.setOptions({showDaysOfWeek: true});
482
+ expect(isVisible(picker.querySelector('.days-of-week')), 'to be true');
483
+
484
+ dp.destroy();
485
+ });
486
+ });
487
+
488
+ describe('showOnClick', function () {
489
+ it('disables the picker to auto-open on clicking input when false', function () {
490
+ const {dp, picker} = createDP(input, {showOnClick: false});
491
+ input.focus();
492
+ dp.hide();
493
+
494
+ simulant.fire(input, 'mousedown');
495
+ input.click();
496
+ expect(isVisible(picker), 'to be false');
497
+
498
+ dp.destroy();
499
+ });
500
+
501
+ it('can be updated with setOptions()', function () {
502
+ const {dp, picker} = createDP(input);
503
+ dp.setOptions({showOnClick: false});
504
+ input.focus();
505
+ dp.hide();
506
+ simulant.fire(input, 'mousedown');
507
+ input.click();
508
+
509
+ expect(isVisible(picker), 'to be false');
510
+
511
+ dp.setOptions({showOnClick: true});
512
+ simulant.fire(input, 'mousedown');
513
+ input.click();
514
+
515
+ expect(isVisible(picker), 'to be true');
516
+
517
+ dp.destroy();
518
+ });
519
+ });
520
+
521
+ describe('showOnFocus', function () {
522
+ it('disables the picker to auto-open on focus when false', function () {
523
+ const {dp, picker} = createDP(input, {showOnFocus: false});
524
+ input.focus();
525
+
526
+ expect(isVisible(picker), 'to be false');
527
+
528
+ dp.destroy();
529
+ });
530
+
531
+ it('can be updated with setOptions()', function () {
532
+ const {dp, picker} = createDP(input);
533
+ dp.setOptions({showOnFocus: false});
534
+ input.focus();
535
+
536
+ expect(isVisible(picker), 'to be false');
537
+
538
+ input.blur();
539
+ dp.setOptions({showOnFocus: true});
540
+ input.focus();
541
+
542
+ expect(isVisible(picker), 'to be true');
543
+
544
+ dp.destroy();
545
+ });
546
+ });
547
+
548
+ describe('title', function () {
549
+ it('specifies the title of the picker and shows it when not empty', function () {
550
+ const {dp, picker} = createDP(input, {title: 'Foo Bar'});
551
+ const title = picker.querySelector('.datepicker-title');
552
+ dp.show();
553
+
554
+ expect(title.textContent, 'to be', 'Foo Bar');
555
+ expect(isVisible(title), 'to be true');
556
+
557
+ dp.destroy();
558
+ });
559
+
560
+ it('can be updated with setOptions()', function () {
561
+ const {dp, picker} = createDP(input);
562
+ const title = picker.querySelector('.datepicker-title');
563
+ dp.setOptions({title: 'My Datepicker'});
564
+ dp.show();
565
+
566
+ expect(title.textContent, 'to be', 'My Datepicker');
567
+ expect(isVisible(title), 'to be true');
568
+
569
+ dp.setOptions({title: ''});
570
+ expect(title.textContent, 'to be', '');
571
+ expect(isVisible(title), 'to be false');
572
+
573
+ dp.destroy();
574
+ });
575
+ });
576
+
577
+ describe('todayHighlight', function () {
578
+ it('highlights the current date in days view when true', function () {
579
+ const {dp, picker} = createDP(input, {todayHighlight: true});
580
+ const viewSwitch = getViewSwitch(picker);
581
+ dp.show();
582
+
583
+ let cells = getCells(picker);
584
+ expect(filterCells(cells, '.today'), 'to equal', [cells[19]]);
585
+
586
+ picker.querySelector('.prev-btn').click();
587
+ expect(filterCells(getCells(picker), '.today'), 'to equal', []);
588
+
589
+ picker.querySelector('.next-btn').click();
590
+ viewSwitch.click();
591
+ expect(filterCells(getCells(picker), '.today'), 'to equal', []);
592
+
593
+ viewSwitch.click();
594
+ expect(filterCells(getCells(picker), '.today'), 'to equal', []);
595
+
596
+ viewSwitch.click();
597
+ expect(filterCells(getCells(picker), '.today'), 'to equal', []);
598
+
599
+ dp.destroy();
600
+ });
601
+
602
+ it('can be updated with setOptions()', function () {
603
+ const {dp, picker} = createDP(input);
604
+ dp.setOptions({todayHighlight: true});
605
+ dp.show();
606
+
607
+ let cells = getCells(picker);
608
+ expect(filterCells(cells, '.today'), 'to equal', [cells[19]]);
609
+
610
+ dp.setOptions({todayHighlight: false});
611
+
612
+ cells = getCells(picker);
613
+ expect(filterCells(cells, '.today'), 'to equal', []);
614
+
615
+ dp.destroy();
616
+ });
617
+ });
618
+
619
+ describe('updateOnBlur', function () {
620
+ it('discards unparsed input on losing focus when false', function () {
621
+ const outsider = document.createElement('p');
622
+ testContainer.appendChild(outsider);
623
+
624
+ const {dp, picker} = createDP(input, {updateOnBlur: false});
625
+ input.focus();
626
+ input.value = 'foo';
627
+
628
+ // on tab key press
629
+ simulant.fire(input, 'keydown', {key: 'Tab'});
630
+ expect(input.value, 'to be', '');
631
+
632
+ dp.setDate('04/22/2020');
633
+ dp.show();
634
+ dp.enterEditMode();
635
+ input.value = 'foo';
636
+
637
+ simulant.fire(input, 'keydown', {key: 'Tab'});
638
+ expect(input.value, 'to be', '04/22/2020');
639
+
640
+ // on click outside
641
+ dp.show();
642
+ input.value = 'foo';
643
+
644
+ simulant.fire(picker.querySelector('.dow'), 'mousedown');
645
+ expect(input.value, 'to be', 'foo');
646
+
647
+ simulant.fire(input, 'mousedown');
648
+ expect(input.value, 'to be', 'foo');
649
+
650
+ simulant.fire(outsider, 'mousedown');
651
+ expect(input.value, 'to be', '04/22/2020');
652
+
653
+ dp.setDate({clear: true});
654
+ input.value = 'foo';
655
+
656
+ simulant.fire(outsider, 'mousedown');
657
+ expect(input.value, 'to be', '');
658
+
659
+ dp.destroy();
660
+ testContainer.removeChild(outsider);
661
+ });
662
+
663
+ it('can be updated with setOptions()', function () {
664
+ const dp = new Datepicker(input);
665
+ dp.setOptions({updateOnBlur: false});
666
+ input.focus();
667
+ input.value = '04/22/2020';
668
+
669
+ simulant.fire(input, 'keydown', {key: 'Tab'});
670
+ expect(input.value, 'to be', '');
671
+
672
+ dp.setOptions({updateOnBlur: true});
673
+ input.focus();
674
+ input.value = '04/22/2020';
675
+
676
+ simulant.fire(input, 'keydown', {key: 'Tab'});
677
+ expect(input.value, 'to be', '04/22/2020');
678
+
679
+ dp.destroy();
680
+ });
681
+ });
682
+
683
+ describe('weekStart', function () {
684
+ const getDayNames = (picker) => {
685
+ const daysOfWeek = picker.querySelector('.days-of-week');
686
+ return Array.from(daysOfWeek.children).map(el => el.textContent);
687
+ };
688
+ const getDatesInColumn = (picker, colIndex) => {
689
+ const cells = getCells(picker);
690
+ return cells.reduce((dates, el, ix) => {
691
+ if (ix % 7 === colIndex) {
692
+ dates.push(el.textContent);
693
+ }
694
+ return dates;
695
+ }, []);
696
+ };
697
+
698
+ it('specifies the day of week to display in the first column', function () {
699
+ const {dp, picker} = createDP(input, {weekStart: 1});
700
+ dp.show();
701
+
702
+ expect(getDayNames(picker), 'to equal', ['Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa', 'Su']);
703
+ expect(getDatesInColumn(picker, 0), 'to equal', ['27', '3', '10', '17', '24', '2']);
704
+ expect(getDatesInColumn(picker, 6), 'to equal', ['2', '9', '16', '23', '1', '8']);
705
+
706
+ dp.destroy();
707
+ });
708
+
709
+ it('can be updated with setOptions()', function () {
710
+ const {dp, picker} = createDP(input);
711
+ dp.setOptions({weekStart: 4});
712
+ dp.show();
713
+
714
+ expect(getDayNames(picker), 'to equal', ['Th', 'Fr', 'Sa', 'Su', 'Mo', 'Tu', 'We']);
715
+ expect(getDatesInColumn(picker, 0), 'to equal', ['30', '6', '13', '20', '27', '5']);
716
+ expect(getDatesInColumn(picker, 6), 'to equal', ['5', '12', '19', '26', '4', '11']);
717
+
718
+ dp.setOptions({weekStart: 0});
719
+
720
+ expect(getDayNames(picker), 'to equal', ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa']);
721
+ expect(getDatesInColumn(picker, 0), 'to equal', ['26', '2', '9', '16', '23', '1']);
722
+ expect(getDatesInColumn(picker, 6), 'to equal', ['1', '8', '15', '22', '29', '7']);
723
+
724
+ dp.destroy();
725
+ });
726
+ });
727
+ });