@keenthemes/ktui 1.1.0 → 1.1.2

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 (258) hide show
  1. package/README.md +0 -27
  2. package/dist/ktui.js +5269 -12550
  3. package/dist/ktui.min.js +1 -1
  4. package/dist/ktui.min.js.map +1 -1
  5. package/dist/styles.css +1133 -2706
  6. package/lib/cjs/components/datatable/__tests__/pagination-reset.test.js +596 -0
  7. package/lib/cjs/components/datatable/__tests__/pagination-reset.test.js.map +1 -0
  8. package/lib/cjs/components/datatable/__tests__/race-conditions.test.js +548 -0
  9. package/lib/cjs/components/datatable/__tests__/race-conditions.test.js.map +1 -0
  10. package/lib/cjs/components/datatable/__tests__/setup.js +63 -0
  11. package/lib/cjs/components/datatable/__tests__/setup.js.map +1 -0
  12. package/lib/cjs/components/datatable/datatable.js +92 -30
  13. package/lib/cjs/components/datatable/datatable.js.map +1 -1
  14. package/lib/cjs/components/select/combobox.js +0 -2
  15. package/lib/cjs/components/select/combobox.js.map +1 -1
  16. package/lib/cjs/components/select/config.js +4 -1
  17. package/lib/cjs/components/select/config.js.map +1 -1
  18. package/lib/cjs/components/select/dropdown.js +0 -16
  19. package/lib/cjs/components/select/dropdown.js.map +1 -1
  20. package/lib/cjs/components/select/remote.js +0 -40
  21. package/lib/cjs/components/select/remote.js.map +1 -1
  22. package/lib/cjs/components/select/search.js +80 -19
  23. package/lib/cjs/components/select/search.js.map +1 -1
  24. package/lib/cjs/components/select/select.js +98 -110
  25. package/lib/cjs/components/select/select.js.map +1 -1
  26. package/lib/cjs/components/select/tags.js +0 -2
  27. package/lib/cjs/components/select/tags.js.map +1 -1
  28. package/lib/cjs/index.js +1 -10
  29. package/lib/cjs/index.js.map +1 -1
  30. package/lib/esm/components/datatable/__tests__/pagination-reset.test.js +594 -0
  31. package/lib/esm/components/datatable/__tests__/pagination-reset.test.js.map +1 -0
  32. package/lib/esm/components/datatable/__tests__/race-conditions.test.js +546 -0
  33. package/lib/esm/components/datatable/__tests__/race-conditions.test.js.map +1 -0
  34. package/lib/esm/components/datatable/__tests__/setup.js +58 -0
  35. package/lib/esm/components/datatable/__tests__/setup.js.map +1 -0
  36. package/lib/esm/components/datatable/datatable.js +92 -30
  37. package/lib/esm/components/datatable/datatable.js.map +1 -1
  38. package/lib/esm/components/select/combobox.js +0 -2
  39. package/lib/esm/components/select/combobox.js.map +1 -1
  40. package/lib/esm/components/select/config.js +4 -1
  41. package/lib/esm/components/select/config.js.map +1 -1
  42. package/lib/esm/components/select/dropdown.js +0 -16
  43. package/lib/esm/components/select/dropdown.js.map +1 -1
  44. package/lib/esm/components/select/remote.js +0 -40
  45. package/lib/esm/components/select/remote.js.map +1 -1
  46. package/lib/esm/components/select/search.js +80 -19
  47. package/lib/esm/components/select/search.js.map +1 -1
  48. package/lib/esm/components/select/select.js +98 -110
  49. package/lib/esm/components/select/select.js.map +1 -1
  50. package/lib/esm/components/select/tags.js +0 -2
  51. package/lib/esm/components/select/tags.js.map +1 -1
  52. package/lib/esm/index.js +0 -7
  53. package/lib/esm/index.js.map +1 -1
  54. package/package.json +7 -9
  55. package/src/components/alert/alert.css +188 -429
  56. package/src/components/datatable/__tests__/pagination-reset.test.ts +657 -0
  57. package/src/components/datatable/__tests__/race-conditions.test.ts +455 -0
  58. package/src/components/datatable/__tests__/setup.ts +67 -0
  59. package/src/components/datatable/datatable.ts +66 -11
  60. package/src/components/input/input.css +0 -1
  61. package/src/components/select/__tests__/ux-behaviors.test.ts +619 -0
  62. package/src/components/select/combobox.ts +0 -1
  63. package/src/components/select/config.ts +7 -1
  64. package/src/components/select/dropdown.ts +0 -24
  65. package/src/components/select/remote.ts +0 -49
  66. package/src/components/select/search.ts +85 -21
  67. package/src/components/select/select.css +0 -1
  68. package/src/components/select/select.ts +118 -149
  69. package/src/components/select/tags.ts +0 -1
  70. package/src/components/select/variants.css +4 -0
  71. package/src/components/textarea/textarea.css +0 -1
  72. package/src/index.ts +0 -10
  73. package/styles.css +0 -1
  74. package/lib/cjs/components/alert/alert.js +0 -1025
  75. package/lib/cjs/components/alert/alert.js.map +0 -1
  76. package/lib/cjs/components/alert/index.js +0 -20
  77. package/lib/cjs/components/alert/index.js.map +0 -1
  78. package/lib/cjs/components/alert/templates.js +0 -120
  79. package/lib/cjs/components/alert/templates.js.map +0 -1
  80. package/lib/cjs/components/alert/types.js +0 -7
  81. package/lib/cjs/components/alert/types.js.map +0 -1
  82. package/lib/cjs/components/datepicker/config/config.js +0 -42
  83. package/lib/cjs/components/datepicker/config/config.js.map +0 -1
  84. package/lib/cjs/components/datepicker/config/index.js +0 -24
  85. package/lib/cjs/components/datepicker/config/index.js.map +0 -1
  86. package/lib/cjs/components/datepicker/config/interfaces.js +0 -7
  87. package/lib/cjs/components/datepicker/config/interfaces.js.map +0 -1
  88. package/lib/cjs/components/datepicker/config/types.js +0 -7
  89. package/lib/cjs/components/datepicker/config/types.js.map +0 -1
  90. package/lib/cjs/components/datepicker/core/event-manager.js +0 -135
  91. package/lib/cjs/components/datepicker/core/event-manager.js.map +0 -1
  92. package/lib/cjs/components/datepicker/core/focus-manager.js +0 -167
  93. package/lib/cjs/components/datepicker/core/focus-manager.js.map +0 -1
  94. package/lib/cjs/components/datepicker/core/helpers.js +0 -219
  95. package/lib/cjs/components/datepicker/core/helpers.js.map +0 -1
  96. package/lib/cjs/components/datepicker/core/index.js +0 -25
  97. package/lib/cjs/components/datepicker/core/index.js.map +0 -1
  98. package/lib/cjs/components/datepicker/core/unified-state-manager.js +0 -394
  99. package/lib/cjs/components/datepicker/core/unified-state-manager.js.map +0 -1
  100. package/lib/cjs/components/datepicker/datepicker.js +0 -2252
  101. package/lib/cjs/components/datepicker/datepicker.js.map +0 -1
  102. package/lib/cjs/components/datepicker/index.js +0 -24
  103. package/lib/cjs/components/datepicker/index.js.map +0 -1
  104. package/lib/cjs/components/datepicker/ui/index.js +0 -23
  105. package/lib/cjs/components/datepicker/ui/index.js.map +0 -1
  106. package/lib/cjs/components/datepicker/ui/input/dropdown.js +0 -489
  107. package/lib/cjs/components/datepicker/ui/input/dropdown.js.map +0 -1
  108. package/lib/cjs/components/datepicker/ui/input/index.js +0 -23
  109. package/lib/cjs/components/datepicker/ui/input/index.js.map +0 -1
  110. package/lib/cjs/components/datepicker/ui/input/segmented-input.js +0 -640
  111. package/lib/cjs/components/datepicker/ui/input/segmented-input.js.map +0 -1
  112. package/lib/cjs/components/datepicker/ui/renderers/calendar.js +0 -446
  113. package/lib/cjs/components/datepicker/ui/renderers/calendar.js.map +0 -1
  114. package/lib/cjs/components/datepicker/ui/renderers/footer.js +0 -42
  115. package/lib/cjs/components/datepicker/ui/renderers/footer.js.map +0 -1
  116. package/lib/cjs/components/datepicker/ui/renderers/header.js +0 -32
  117. package/lib/cjs/components/datepicker/ui/renderers/header.js.map +0 -1
  118. package/lib/cjs/components/datepicker/ui/renderers/index.js +0 -25
  119. package/lib/cjs/components/datepicker/ui/renderers/index.js.map +0 -1
  120. package/lib/cjs/components/datepicker/ui/renderers/time-picker.js +0 -384
  121. package/lib/cjs/components/datepicker/ui/renderers/time-picker.js.map +0 -1
  122. package/lib/cjs/components/datepicker/ui/templates/index.js +0 -22
  123. package/lib/cjs/components/datepicker/ui/templates/index.js.map +0 -1
  124. package/lib/cjs/components/datepicker/ui/templates/templates.js +0 -253
  125. package/lib/cjs/components/datepicker/ui/templates/templates.js.map +0 -1
  126. package/lib/cjs/components/datepicker/utils/date-formatters.js +0 -88
  127. package/lib/cjs/components/datepicker/utils/date-formatters.js.map +0 -1
  128. package/lib/cjs/components/datepicker/utils/date-utils.js +0 -194
  129. package/lib/cjs/components/datepicker/utils/date-utils.js.map +0 -1
  130. package/lib/cjs/components/datepicker/utils/index.js +0 -24
  131. package/lib/cjs/components/datepicker/utils/index.js.map +0 -1
  132. package/lib/cjs/components/datepicker/utils/time-utils.js +0 -213
  133. package/lib/cjs/components/datepicker/utils/time-utils.js.map +0 -1
  134. package/lib/esm/components/alert/alert.js +0 -1022
  135. package/lib/esm/components/alert/alert.js.map +0 -1
  136. package/lib/esm/components/alert/index.js +0 -4
  137. package/lib/esm/components/alert/index.js.map +0 -1
  138. package/lib/esm/components/alert/templates.js +0 -112
  139. package/lib/esm/components/alert/templates.js.map +0 -1
  140. package/lib/esm/components/alert/types.js +0 -6
  141. package/lib/esm/components/alert/types.js.map +0 -1
  142. package/lib/esm/components/datepicker/config/config.js +0 -39
  143. package/lib/esm/components/datepicker/config/config.js.map +0 -1
  144. package/lib/esm/components/datepicker/config/index.js +0 -8
  145. package/lib/esm/components/datepicker/config/index.js.map +0 -1
  146. package/lib/esm/components/datepicker/config/interfaces.js +0 -6
  147. package/lib/esm/components/datepicker/config/interfaces.js.map +0 -1
  148. package/lib/esm/components/datepicker/config/types.js +0 -6
  149. package/lib/esm/components/datepicker/config/types.js.map +0 -1
  150. package/lib/esm/components/datepicker/core/event-manager.js +0 -133
  151. package/lib/esm/components/datepicker/core/event-manager.js.map +0 -1
  152. package/lib/esm/components/datepicker/core/focus-manager.js +0 -164
  153. package/lib/esm/components/datepicker/core/focus-manager.js.map +0 -1
  154. package/lib/esm/components/datepicker/core/helpers.js +0 -211
  155. package/lib/esm/components/datepicker/core/helpers.js.map +0 -1
  156. package/lib/esm/components/datepicker/core/index.js +0 -9
  157. package/lib/esm/components/datepicker/core/index.js.map +0 -1
  158. package/lib/esm/components/datepicker/core/unified-state-manager.js +0 -391
  159. package/lib/esm/components/datepicker/core/unified-state-manager.js.map +0 -1
  160. package/lib/esm/components/datepicker/datepicker.js +0 -2248
  161. package/lib/esm/components/datepicker/datepicker.js.map +0 -1
  162. package/lib/esm/components/datepicker/index.js +0 -7
  163. package/lib/esm/components/datepicker/index.js.map +0 -1
  164. package/lib/esm/components/datepicker/ui/index.js +0 -7
  165. package/lib/esm/components/datepicker/ui/index.js.map +0 -1
  166. package/lib/esm/components/datepicker/ui/input/dropdown.js +0 -486
  167. package/lib/esm/components/datepicker/ui/input/dropdown.js.map +0 -1
  168. package/lib/esm/components/datepicker/ui/input/index.js +0 -7
  169. package/lib/esm/components/datepicker/ui/input/index.js.map +0 -1
  170. package/lib/esm/components/datepicker/ui/input/segmented-input.js +0 -637
  171. package/lib/esm/components/datepicker/ui/input/segmented-input.js.map +0 -1
  172. package/lib/esm/components/datepicker/ui/renderers/calendar.js +0 -443
  173. package/lib/esm/components/datepicker/ui/renderers/calendar.js.map +0 -1
  174. package/lib/esm/components/datepicker/ui/renderers/footer.js +0 -39
  175. package/lib/esm/components/datepicker/ui/renderers/footer.js.map +0 -1
  176. package/lib/esm/components/datepicker/ui/renderers/header.js +0 -29
  177. package/lib/esm/components/datepicker/ui/renderers/header.js.map +0 -1
  178. package/lib/esm/components/datepicker/ui/renderers/index.js +0 -9
  179. package/lib/esm/components/datepicker/ui/renderers/index.js.map +0 -1
  180. package/lib/esm/components/datepicker/ui/renderers/time-picker.js +0 -381
  181. package/lib/esm/components/datepicker/ui/renderers/time-picker.js.map +0 -1
  182. package/lib/esm/components/datepicker/ui/templates/index.js +0 -6
  183. package/lib/esm/components/datepicker/ui/templates/index.js.map +0 -1
  184. package/lib/esm/components/datepicker/ui/templates/templates.js +0 -242
  185. package/lib/esm/components/datepicker/ui/templates/templates.js.map +0 -1
  186. package/lib/esm/components/datepicker/utils/date-formatters.js +0 -83
  187. package/lib/esm/components/datepicker/utils/date-formatters.js.map +0 -1
  188. package/lib/esm/components/datepicker/utils/date-utils.js +0 -184
  189. package/lib/esm/components/datepicker/utils/date-utils.js.map +0 -1
  190. package/lib/esm/components/datepicker/utils/index.js +0 -8
  191. package/lib/esm/components/datepicker/utils/index.js.map +0 -1
  192. package/lib/esm/components/datepicker/utils/time-utils.js +0 -201
  193. package/lib/esm/components/datepicker/utils/time-utils.js.map +0 -1
  194. package/src/components/alert/alert.ts +0 -990
  195. package/src/components/alert/index.ts +0 -4
  196. package/src/components/alert/templates.ts +0 -110
  197. package/src/components/alert/tests/accessibility/aria-roles.test.ts +0 -19
  198. package/src/components/alert/tests/accessibility/focus-management.test.ts +0 -19
  199. package/src/components/alert/tests/accessibility/keyboard-nav.test.ts +0 -22
  200. package/src/components/alert/tests/actions/confirm-cancel.test.ts +0 -122
  201. package/src/components/alert/tests/actions/input-field.test.ts +0 -180
  202. package/src/components/alert/tests/alert.basic.test.ts +0 -126
  203. package/src/components/alert/tests/alert.config.test.ts +0 -75
  204. package/src/components/alert/tests/alert.templates.test.ts +0 -17
  205. package/src/components/alert/tests/config/attribute-config.test.ts +0 -94
  206. package/src/components/alert/tests/config/json-config.test.ts +0 -119
  207. package/src/components/alert/tests/config/merging.test.ts +0 -89
  208. package/src/components/alert/tests/dismissal/auto-dismiss.test.ts +0 -96
  209. package/src/components/alert/tests/dismissal/escape-key-dismiss.test.ts +0 -105
  210. package/src/components/alert/tests/dismissal/manual-dismiss.test.ts +0 -90
  211. package/src/components/alert/tests/dismissal/outside-click-dismiss.test.ts +0 -91
  212. package/src/components/alert/tests/edge-cases/invalid-config.test.ts +0 -19
  213. package/src/components/alert/tests/edge-cases/multiple-alerts.test.ts +0 -19
  214. package/src/components/alert/tests/rendering/custom-content.test.ts +0 -81
  215. package/src/components/alert/tests/rendering/info-alert.test.ts +0 -84
  216. package/src/components/alert/tests/rendering/success-alert.test.ts +0 -100
  217. package/src/components/alert/tests/templates/default-templates.test.ts +0 -16
  218. package/src/components/alert/tests/templates/user-templates.test.ts +0 -16
  219. package/src/components/alert/types.ts +0 -145
  220. package/src/components/datepicker/__tests__/datepicker-events.test.ts +0 -356
  221. package/src/components/datepicker/__tests__/datepicker-init.test.ts +0 -343
  222. package/src/components/datepicker/__tests__/datepicker-integration.test.ts +0 -435
  223. package/src/components/datepicker/__tests__/datepicker-timezone.test.ts +0 -220
  224. package/src/components/datepicker/__tests__/segmented-input-focus.test.ts +0 -380
  225. package/src/components/datepicker/__tests__/selective-state-updates.test.ts +0 -400
  226. package/src/components/datepicker/__tests__/state-manager.test.ts +0 -421
  227. package/src/components/datepicker/__tests__/time-preservation.test.ts +0 -387
  228. package/src/components/datepicker/config/config.ts +0 -40
  229. package/src/components/datepicker/config/index.ts +0 -8
  230. package/src/components/datepicker/config/interfaces.ts +0 -82
  231. package/src/components/datepicker/config/types.ts +0 -188
  232. package/src/components/datepicker/core/event-manager.ts +0 -159
  233. package/src/components/datepicker/core/focus-manager.ts +0 -201
  234. package/src/components/datepicker/core/helpers.ts +0 -231
  235. package/src/components/datepicker/core/index.ts +0 -9
  236. package/src/components/datepicker/core/unified-state-manager.ts +0 -459
  237. package/src/components/datepicker/datepicker.css +0 -435
  238. package/src/components/datepicker/datepicker.ts +0 -2548
  239. package/src/components/datepicker/index.ts +0 -8
  240. package/src/components/datepicker/ui/index.ts +0 -7
  241. package/src/components/datepicker/ui/input/dropdown.ts +0 -552
  242. package/src/components/datepicker/ui/input/index.ts +0 -7
  243. package/src/components/datepicker/ui/input/segmented-input.ts +0 -638
  244. package/src/components/datepicker/ui/renderers/__tests__/calendar-optimizations.test.ts +0 -611
  245. package/src/components/datepicker/ui/renderers/calendar.ts +0 -530
  246. package/src/components/datepicker/ui/renderers/footer.ts +0 -43
  247. package/src/components/datepicker/ui/renderers/header.ts +0 -33
  248. package/src/components/datepicker/ui/renderers/index.ts +0 -9
  249. package/src/components/datepicker/ui/renderers/time-picker.ts +0 -438
  250. package/src/components/datepicker/ui/templates/index.ts +0 -6
  251. package/src/components/datepicker/ui/templates/templates.ts +0 -306
  252. package/src/components/datepicker/utils/__tests__/date-formatters.test.ts +0 -160
  253. package/src/components/datepicker/utils/__tests__/date-utils-keys.test.ts +0 -86
  254. package/src/components/datepicker/utils/__tests__/date-utils-timezone.test.ts +0 -215
  255. package/src/components/datepicker/utils/date-formatters.ts +0 -85
  256. package/src/components/datepicker/utils/date-utils.ts +0 -172
  257. package/src/components/datepicker/utils/index.ts +0 -8
  258. package/src/components/datepicker/utils/time-utils.ts +0 -221
@@ -1,435 +0,0 @@
1
- /**
2
- * datepicker-integration.test.ts - Integration tests for KTDatepicker
3
- * Tests backward compatibility, configuration options, and real-world usage patterns
4
- */
5
-
6
- import { describe, it, expect, beforeEach, vi } from 'vitest';
7
- import { KTDatepicker } from '../datepicker';
8
- import { KTDatepickerConfig } from '../config/types';
9
-
10
- describe('KTDatepicker Integration', () => {
11
- let element: HTMLElement;
12
-
13
- beforeEach(() => {
14
- // Create a fresh element for each test
15
- element = document.createElement('div');
16
- element.innerHTML = `
17
- <div class="kt-datepicker" data-kt-datepicker-segmented>
18
- <input type="text" data-kt-datepicker-input placeholder="Select date">
19
- </div>
20
- `;
21
-
22
- // Clear any existing content and add our test element
23
- document.body.innerHTML = '';
24
- document.body.appendChild(element);
25
- });
26
-
27
- describe('Configuration Options', () => {
28
- it('should accept all configuration options without errors', () => {
29
- const config: KTDatepickerConfig = {
30
- format: 'dd/MM/yyyy',
31
- range: false,
32
- multiDate: false,
33
- minDate: new Date(2024, 0, 1),
34
- maxDate: new Date(2024, 11, 31),
35
- disabled: false,
36
- locale: 'en-US',
37
- placeholder: 'Select a date',
38
- value: new Date(2024, 0, 15),
39
- showOnFocus: true,
40
- closeOnSelect: true,
41
- closeOnOutsideClick: true,
42
- visibleMonths: 1,
43
- enableTime: false,
44
- timeGranularity: 'minute',
45
- timeFormat: '24h',
46
- minTime: '00:00',
47
- maxTime: '23:59',
48
- timeStep: 1,
49
- dropdownPlacement: 'bottom-start',
50
- dropdownOffset: '0,8',
51
- dropdownBoundary: 'clippingParents',
52
- dropdownWidth: 'auto',
53
- dropdownZindex: 9999,
54
- classes: {
55
- container: 'custom-container',
56
- inputWrapper: 'custom-input-wrapper'
57
- },
58
- onChange: vi.fn(),
59
- onOpen: vi.fn(),
60
- onClose: vi.fn()
61
- };
62
-
63
- expect(() => {
64
- new KTDatepicker(element.querySelector('.kt-datepicker')!, config);
65
- }).not.toThrow();
66
- });
67
-
68
- it('should work with minimal configuration', () => {
69
- const config: KTDatepickerConfig = {
70
- format: 'yyyy-MM-dd'
71
- };
72
-
73
- expect(() => {
74
- const datepicker = new KTDatepicker(element.querySelector('.kt-datepicker')!, config);
75
- expect(datepicker).toBeDefined();
76
- }).not.toThrow();
77
- });
78
-
79
- it('should handle undefined configuration', () => {
80
- expect(() => {
81
- const datepicker = new KTDatepicker(element.querySelector('.kt-datepicker')!, undefined);
82
- expect(datepicker).toBeDefined();
83
- }).not.toThrow();
84
- });
85
- });
86
-
87
- describe('DOM Integration', () => {
88
- it('should create proper DOM structure', () => {
89
- const datepicker = new KTDatepicker(element.querySelector('.kt-datepicker')!);
90
-
91
- // Should have created input wrapper
92
- const inputWrapper = element.querySelector('[data-kt-datepicker-input-wrapper]');
93
- expect(inputWrapper).toBeTruthy();
94
-
95
- // Should have segmented input elements
96
- const segments = element.querySelectorAll('[data-segment]');
97
- expect(segments.length).toBeGreaterThan(0);
98
-
99
- // Dropdown is created lazily when opened
100
- datepicker.open();
101
- // Wait a bit for DOM updates
102
- return new Promise(resolve => {
103
- setTimeout(() => {
104
- const dropdown = document.querySelector('[data-kt-datepicker-dropdown]');
105
- expect(dropdown).toBeTruthy();
106
- resolve(void 0);
107
- }, 10);
108
- });
109
- });
110
-
111
- it('should handle existing input element', () => {
112
- // Element already has input in beforeEach
113
- const existingInput = element.querySelector('input');
114
- expect(existingInput).toBeTruthy(); // Input should exist before datepicker creation
115
-
116
- const datepicker = new KTDatepicker(element.querySelector('.kt-datepicker')!);
117
-
118
- // In segmented mode, the input is processed and segmented UI is created
119
- // Check that segmented input elements were created (this is the expected behavior)
120
- const segmentedElements = element.querySelectorAll('[data-segment]');
121
- expect(segmentedElements.length).toBeGreaterThan(0);
122
-
123
- // Verify datepicker was created successfully
124
- expect(datepicker).toBeDefined();
125
- });
126
-
127
- it('should create input element if none exists', () => {
128
- // Create a fresh element without input
129
- const testElement = document.createElement('div');
130
- testElement.innerHTML = `
131
- <div class="kt-datepicker" data-kt-datepicker-segmented>
132
- </div>
133
- `;
134
- document.body.appendChild(testElement);
135
-
136
- const datepicker = new KTDatepicker(testElement.querySelector('.kt-datepicker')!);
137
-
138
- // Should have created new input - it might be in the document root or moved
139
- const newInput = document.querySelector('input[data-kt-datepicker-input]');
140
- expect(newInput).toBeTruthy();
141
-
142
- // Cleanup
143
- document.body.removeChild(testElement);
144
- });
145
- });
146
-
147
- describe('Data Attributes', () => {
148
- it('should read data attributes for configuration', () => {
149
- element.innerHTML = `
150
- <div class="kt-datepicker"
151
- data-kt-datepicker-segmented
152
- data-kt-datepicker-show-on-focus="false"
153
- data-kt-datepicker-close-on-select="false"
154
- data-kt-datepicker-enable-time="true"
155
- data-kt-datepicker-range="true"
156
- data-kt-datepicker-close-on-outside-click="false">
157
- <input type="text" data-kt-datepicker-input>
158
- </div>
159
- `;
160
-
161
- const datepicker = new KTDatepicker(element.querySelector('.kt-datepicker')!);
162
-
163
- // Note: We can't easily test internal config, but the component should initialize without errors
164
- expect(datepicker).toBeDefined();
165
- });
166
-
167
- it('should parse JSON config from data attribute', () => {
168
- const jsonConfig = {
169
- format: 'MM/dd/yyyy',
170
- disabled: true,
171
- placeholder: 'Custom placeholder'
172
- };
173
-
174
- element.innerHTML = `
175
- <div class="kt-datepicker"
176
- data-kt-datepicker-config='${JSON.stringify(jsonConfig)}'>
177
- <input type="text" data-kt-datepicker-input>
178
- </div>
179
- `;
180
-
181
- const datepicker = new KTDatepicker(element.querySelector('.kt-datepicker')!);
182
-
183
- expect(datepicker).toBeDefined();
184
- });
185
-
186
- it('should handle invalid JSON config gracefully', () => {
187
- element.innerHTML = `
188
- <div class="kt-datepicker"
189
- data-kt-datepicker-config='{invalid json}'>
190
- <input type="text" data-kt-datepicker-input>
191
- </div>
192
- `;
193
-
194
- expect(() => {
195
- new KTDatepicker(element.querySelector('.kt-datepicker')!);
196
- }).not.toThrow();
197
- });
198
- });
199
-
200
- describe('Range Mode', () => {
201
- it('should initialize in range mode', () => {
202
- const config: KTDatepickerConfig = {
203
- range: true,
204
- format: 'dd/MM/yyyy'
205
- };
206
-
207
- const datepicker = new KTDatepicker(element.querySelector('.kt-datepicker')!, config);
208
-
209
- expect(datepicker).toBeDefined();
210
- });
211
-
212
- it('should handle range value initialization', () => {
213
- const config: KTDatepickerConfig = {
214
- range: true,
215
- format: 'dd/MM/yyyy',
216
- valueRange: {
217
- start: new Date(2024, 0, 15),
218
- end: new Date(2024, 0, 20)
219
- }
220
- };
221
-
222
- const datepicker = new KTDatepicker(element.querySelector('.kt-datepicker')!, config);
223
-
224
- expect(datepicker).toBeDefined();
225
- });
226
- });
227
-
228
- describe('Multi-Date Mode', () => {
229
- it('should initialize in multi-date mode', () => {
230
- const config: KTDatepickerConfig = {
231
- multiDate: true,
232
- format: 'dd/MM/yyyy'
233
- };
234
-
235
- const datepicker = new KTDatepicker(element.querySelector('.kt-datepicker')!, config);
236
-
237
- expect(datepicker).toBeDefined();
238
- });
239
-
240
- it('should handle multiple values initialization', () => {
241
- const config: KTDatepickerConfig = {
242
- multiDate: true,
243
- format: 'dd/MM/yyyy',
244
- values: [
245
- new Date(2024, 0, 15),
246
- new Date(2024, 0, 20),
247
- new Date(2024, 0, 25)
248
- ]
249
- };
250
-
251
- const datepicker = new KTDatepicker(element.querySelector('.kt-datepicker')!, config);
252
-
253
- expect(datepicker).toBeDefined();
254
- });
255
- });
256
-
257
- describe('Time Picker', () => {
258
- it('should initialize with time picker enabled', () => {
259
- const config: KTDatepickerConfig = {
260
- enableTime: true,
261
- timeFormat: '12h',
262
- format: 'dd/MM/yyyy'
263
- };
264
-
265
- const datepicker = new KTDatepicker(element.querySelector('.kt-datepicker')!, config);
266
-
267
- expect(datepicker).toBeDefined();
268
- });
269
-
270
- it('should handle time constraints', () => {
271
- const config: KTDatepickerConfig = {
272
- enableTime: true,
273
- format: 'dd/MM/yyyy',
274
- minTime: '09:00',
275
- maxTime: '17:00',
276
- timeStep: 30
277
- };
278
-
279
- const datepicker = new KTDatepicker(element.querySelector('.kt-datepicker')!, config);
280
-
281
- expect(datepicker).toBeDefined();
282
- });
283
-
284
- it('should preserve time when selecting dates from calendar after setting time via segmented inputs', () => {
285
- // Set up datepicker with time enabled
286
- const config: KTDatepickerConfig = {
287
- enableTime: true,
288
- timeFormat: '12h',
289
- format: 'dd/MM/yyyy',
290
- value: new Date(2024, 10, 15, 10, 30) // Nov 15, 2024, 10:30 AM
291
- };
292
-
293
- const datepickerElement = element.querySelector('.kt-datepicker')!;
294
- const datepicker = new KTDatepicker(datepickerElement, config);
295
-
296
- // Wait for initialization
297
- expect(datepicker).toBeDefined();
298
-
299
- return new Promise<void>((resolve) => {
300
- setTimeout(() => {
301
- // Simulate segmented input changing time to 3:45 PM
302
- const newDateTime = new Date(2024, 10, 15, 15, 45); // Nov 15, 2024, 3:45 PM
303
- (datepicker as any)._handleSegmentedInputChange(newDateTime);
304
-
305
- // Wait for state update and verify selectedTime was updated
306
- setTimeout(() => {
307
- const updatedState = (datepicker as any)._unifiedStateManager.getState();
308
- expect(updatedState.selectedTime).toBeTruthy();
309
- expect(updatedState.selectedTime.hour).toBe(15); // 3 PM in 24-hour format
310
- expect(updatedState.selectedTime.minute).toBe(45);
311
- expect(updatedState.selectedDate.getHours()).toBe(15);
312
- expect(updatedState.selectedDate.getMinutes()).toBe(45);
313
-
314
- // Now simulate calendar date selection (November 20th)
315
- const newDate = new Date(2024, 10, 20); // Nov 20, 2024
316
- datepicker.setDate(newDate);
317
-
318
- // Wait for update and verify time is still preserved
319
- setTimeout(() => {
320
- const finalState = (datepicker as any)._unifiedStateManager.getState();
321
- expect(finalState.selectedTime).toBeTruthy();
322
- expect(finalState.selectedTime.hour).toBe(15); // Time should still be 3:45 PM
323
- expect(finalState.selectedTime.minute).toBe(45);
324
- expect(finalState.selectedDate.getDate()).toBe(20); // Date should be 20th
325
- expect(finalState.selectedDate.getHours()).toBe(15); // Time should be preserved
326
- expect(finalState.selectedDate.getMinutes()).toBe(45);
327
-
328
- resolve();
329
- }, 50);
330
- }, 50);
331
- }, 100);
332
- });
333
- });
334
- });
335
-
336
- describe('Constraints', () => {
337
- it('should handle min/max date constraints', () => {
338
- const config: KTDatepickerConfig = {
339
- format: 'dd/MM/yyyy',
340
- minDate: new Date(2024, 0, 1),
341
- maxDate: new Date(2024, 11, 31)
342
- };
343
-
344
- const datepicker = new KTDatepicker(element.querySelector('.kt-datepicker')!, config);
345
-
346
- expect(datepicker).toBeDefined();
347
- });
348
-
349
- it('should handle disabled dates array', () => {
350
- const config: KTDatepickerConfig = {
351
- format: 'dd/MM/yyyy',
352
- disabledDates: [
353
- new Date(2024, 0, 1), // New Year's Day
354
- new Date(2024, 0, 15), // Some holiday
355
- ]
356
- };
357
-
358
- const datepicker = new KTDatepicker(element.querySelector('.kt-datepicker')!, config);
359
-
360
- expect(datepicker).toBeDefined();
361
- });
362
- });
363
-
364
- describe('Multiple Instances', () => {
365
- it('should support multiple independent datepickers', () => {
366
- // Create first datepicker
367
- const datepicker1 = new KTDatepicker(element.querySelector('.kt-datepicker')!, {
368
- format: 'dd/MM/yyyy'
369
- });
370
-
371
- // Create second datepicker element
372
- const element2 = document.createElement('div');
373
- element2.innerHTML = `
374
- <div class="kt-datepicker" data-kt-datepicker-segmented>
375
- <input type="text" data-kt-datepicker-input placeholder="Select date 2">
376
- </div>
377
- `;
378
- document.body.appendChild(element2);
379
-
380
- // Create second datepicker
381
- const datepicker2 = new KTDatepicker(element2.querySelector('.kt-datepicker')!, {
382
- format: 'yyyy-MM-dd'
383
- });
384
-
385
- // Both should exist independently
386
- expect(datepicker1).toBeDefined();
387
- expect(datepicker2).toBeDefined();
388
-
389
- // Cleanup
390
- document.body.removeChild(element2);
391
- });
392
- });
393
-
394
- describe('Error Recovery', () => {
395
- it('should handle invalid element gracefully', () => {
396
- expect(() => {
397
- new KTDatepicker(null as any);
398
- }).toThrow(); // Should throw for null element
399
- });
400
-
401
- it('should handle missing DOM methods gracefully', () => {
402
- // Create element without proper DOM methods
403
- const mockElement = {
404
- querySelector: () => null,
405
- setAttribute: vi.fn(),
406
- getAttribute: vi.fn()
407
- };
408
-
409
- expect(() => {
410
- new KTDatepicker(mockElement as any);
411
- }).toThrow(); // Should throw when DOM methods fail
412
- });
413
- });
414
-
415
- describe('Memory Management', () => {
416
- it('should clean up event listeners on destruction', () => {
417
- const datepicker = new KTDatepicker(element.querySelector('.kt-datepicker')!);
418
-
419
- // Mock the event manager's removeListener method
420
- const mockRemoveListener = vi.fn();
421
- (datepicker as any)._eventManager = {
422
- removeListener: mockRemoveListener,
423
- addListener: vi.fn()
424
- };
425
-
426
- // Trigger cleanup (this would normally happen on destruction)
427
- if ((datepicker as any).dispose) {
428
- (datepicker as any).dispose();
429
- }
430
-
431
- // Event listeners should be cleaned up
432
- // Note: This test assumes a dispose method exists or will be added
433
- });
434
- });
435
- });
@@ -1,220 +0,0 @@
1
- import { describe, it, expect, beforeEach, afterEach } from 'vitest';
2
- import { KTDatepicker } from '../datepicker';
3
- import { formatDateToLocalString, parseLocalDate } from '../utils/date-utils';
4
-
5
- describe('KTDatepicker - Timezone Handling', () => {
6
- let container: HTMLElement;
7
-
8
- beforeEach(() => {
9
- container = document.createElement('div');
10
- container.setAttribute('data-kt-datepicker', '');
11
- document.body.appendChild(container);
12
- });
13
-
14
- afterEach(() => {
15
- if (container.parentNode) {
16
- document.body.removeChild(container);
17
- }
18
- });
19
-
20
- describe('Date Selection with Local Timezone', () => {
21
- it('should store selected date in local timezone', () => {
22
- const datepicker = new KTDatepicker(container);
23
- const testDate = new Date(2024, 0, 15, 14, 30, 0); // Jan 15, 2024 2:30 PM
24
-
25
- datepicker.setDate(testDate);
26
- const state = datepicker.getState();
27
-
28
- expect(state.selectedDate).toBeDefined();
29
- if (state.selectedDate) {
30
- // Date should preserve the local date components
31
- expect(state.selectedDate.getFullYear()).toBe(2024);
32
- expect(state.selectedDate.getMonth()).toBe(0);
33
- expect(state.selectedDate.getDate()).toBe(15);
34
- }
35
- });
36
-
37
- it('should not shift dates when selecting late evening times', () => {
38
- const datepicker = new KTDatepicker(container);
39
- // Late evening that could shift to next day in UTC
40
- const lateEvening = new Date(2024, 0, 15, 23, 30, 0); // Jan 15, 11:30 PM
41
-
42
- datepicker.setDate(lateEvening);
43
- const state = datepicker.getState();
44
-
45
- expect(state.selectedDate).toBeDefined();
46
- if (state.selectedDate) {
47
- // Should still be Jan 15, not shifted to Jan 16
48
- expect(state.selectedDate.getDate()).toBe(15);
49
- expect(state.selectedDate.getMonth()).toBe(0);
50
- }
51
- });
52
-
53
- it('should format dates using local timezone in calendar cells', () => {
54
- const datepicker = new KTDatepicker(container);
55
- const testDate = new Date(2024, 0, 15);
56
- datepicker.setDate(testDate);
57
- datepicker.open();
58
-
59
- // Wait for dropdown to render
60
- const dropdown = container.querySelector('[data-kt-datepicker-dropdown]') as HTMLElement;
61
- if (!dropdown) {
62
- // If dropdown not found, skip this test (may need async rendering)
63
- return;
64
- }
65
-
66
- // Find the selected date cell
67
- const selectedCell = dropdown.querySelector('[data-kt-selected="true"]') as HTMLElement;
68
- if (selectedCell) {
69
- // Check that the data-date attribute uses local timezone format
70
- const dateAttr = selectedCell.getAttribute('data-date');
71
- expect(dateAttr).toBe(formatDateToLocalString(testDate));
72
- }
73
- });
74
- });
75
-
76
- describe('Date Range Selection with Local Timezone', () => {
77
- it('should store range dates in local timezone', () => {
78
- const datepicker = new KTDatepicker(container, { range: true });
79
- const startDate = new Date(2024, 0, 10, 10, 0, 0);
80
- const endDate = new Date(2024, 0, 15, 20, 0, 0);
81
-
82
- datepicker.setDate(startDate);
83
- datepicker.setDate(endDate);
84
-
85
- const state = datepicker.getState();
86
- expect(state.selectedRange).toBeDefined();
87
- if (state.selectedRange) {
88
- expect(state.selectedRange.start).toBeDefined();
89
- expect(state.selectedRange.end).toBeDefined();
90
- if (state.selectedRange.start && state.selectedRange.end) {
91
- expect(state.selectedRange.start.getDate()).toBe(10);
92
- expect(state.selectedRange.end.getDate()).toBe(15);
93
- }
94
- }
95
- });
96
-
97
- it('should format range dates using local timezone in data attributes', () => {
98
- const datepicker = new KTDatepicker(container, { range: true });
99
- const startDate = new Date(2024, 0, 10);
100
- const endDate = new Date(2024, 0, 15);
101
-
102
- datepicker.setDate(startDate);
103
- datepicker.setDate(endDate);
104
- datepicker.open();
105
-
106
- const dropdown = container.querySelector('[data-kt-datepicker-dropdown]') as HTMLElement;
107
- if (!dropdown) return;
108
-
109
- const calendar = dropdown.querySelector('table') as HTMLElement;
110
- if (calendar) {
111
- // Check range attributes use local timezone format
112
- const rangeStart = calendar.getAttribute('data-kt-range-start');
113
- const rangeEnd = calendar.getAttribute('data-kt-range-end');
114
-
115
- if (rangeStart && rangeEnd) {
116
- expect(rangeStart).toBe(formatDateToLocalString(startDate));
117
- expect(rangeEnd).toBe(formatDateToLocalString(endDate));
118
- }
119
- }
120
- });
121
-
122
- it('should parse range dates from attributes using local timezone', () => {
123
- const datepicker = new KTDatepicker(container, { range: true });
124
- const startDate = new Date(2024, 0, 10);
125
- const endDate = new Date(2024, 0, 15);
126
-
127
- datepicker.setDate(startDate);
128
- datepicker.setDate(endDate);
129
- datepicker.open();
130
-
131
- const dropdown = container.querySelector('[data-kt-datepicker-dropdown]') as HTMLElement;
132
- if (!dropdown) return;
133
-
134
- const calendar = dropdown.querySelector('table') as HTMLElement;
135
- if (calendar) {
136
- // Get attributes and parse them
137
- const rangeStartAttr = calendar.getAttribute('data-kt-range-start');
138
- const rangeEndAttr = calendar.getAttribute('data-kt-range-end');
139
-
140
- if (rangeStartAttr && rangeEndAttr) {
141
- const parsedStart = parseLocalDate(rangeStartAttr);
142
- const parsedEnd = parseLocalDate(rangeEndAttr);
143
-
144
- // Parsed dates should match original dates
145
- expect(parsedStart.getDate()).toBe(startDate.getDate());
146
- expect(parsedStart.getMonth()).toBe(startDate.getMonth());
147
- expect(parsedEnd.getDate()).toBe(endDate.getDate());
148
- expect(parsedEnd.getMonth()).toBe(endDate.getMonth());
149
- }
150
- }
151
- });
152
- });
153
-
154
- describe('Date Comparison with Local Timezone', () => {
155
- it('should compare dates using local timezone normalization', () => {
156
- const datepicker = new KTDatepicker(container);
157
- const date1 = new Date(2024, 0, 15, 10, 0, 0);
158
- const date2 = new Date(2024, 0, 15, 20, 0, 0);
159
-
160
- datepicker.setDate(date1);
161
- const state1 = datepicker.getState();
162
-
163
- datepicker.setDate(date2);
164
- const state2 = datepicker.getState();
165
-
166
- // Both should be considered the same day
167
- if (state1.selectedDate && state2.selectedDate) {
168
- expect(state1.selectedDate.getDate()).toBe(state2.selectedDate.getDate());
169
- expect(state1.selectedDate.getMonth()).toBe(state2.selectedDate.getMonth());
170
- }
171
- });
172
-
173
- it('should highlight correct date cell regardless of time component', () => {
174
- const datepicker = new KTDatepicker(container);
175
- const testDate = new Date(2024, 0, 15, 23, 59, 59); // Late in the day
176
-
177
- datepicker.setDate(testDate);
178
- datepicker.open();
179
-
180
- const dropdown = container.querySelector('[data-kt-datepicker-dropdown]') as HTMLElement;
181
- if (dropdown) {
182
- const selectedCell = dropdown.querySelector('[data-kt-selected="true"]') as HTMLElement;
183
- if (selectedCell) {
184
- const dateAttr = selectedCell.getAttribute('data-date');
185
- expect(dateAttr).toBe('2024-01-15'); // Should be Jan 15, not shifted
186
- }
187
- }
188
- });
189
- });
190
-
191
- describe('Date String Formatting Consistency', () => {
192
- it('should use consistent local timezone format throughout', () => {
193
- const datepicker = new KTDatepicker(container);
194
- const testDate = new Date(2024, 0, 15, 14, 30, 0);
195
-
196
- datepicker.setDate(testDate);
197
- datepicker.open();
198
-
199
- const dropdown = container.querySelector('[data-kt-datepicker-dropdown]') as HTMLElement;
200
- if (dropdown) {
201
- const calendar = dropdown.querySelector('table') as HTMLElement;
202
- if (calendar) {
203
- // All date cells should use local timezone format
204
- const dateCells = calendar.querySelectorAll('[data-date]');
205
- dateCells.forEach(cell => {
206
- const dateStr = cell.getAttribute('data-date');
207
- if (dateStr) {
208
- // Should be in YYYY-MM-DD format
209
- expect(dateStr).toMatch(/^\d{4}-\d{2}-\d{2}$/);
210
- // Should be parseable as local date
211
- const parsed = parseLocalDate(dateStr);
212
- expect(parsed).toBeInstanceOf(Date);
213
- }
214
- });
215
- }
216
- }
217
- });
218
- });
219
- });
220
-