@keenthemes/ktui 1.1.0 → 1.1.1

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 (222) hide show
  1. package/README.md +0 -27
  2. package/dist/ktui.js +6790 -14063
  3. package/dist/ktui.min.js +1 -1
  4. package/dist/ktui.min.js.map +1 -1
  5. package/dist/styles.css +1132 -2705
  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/index.js +1 -10
  15. package/lib/cjs/index.js.map +1 -1
  16. package/lib/esm/components/datatable/__tests__/pagination-reset.test.js +594 -0
  17. package/lib/esm/components/datatable/__tests__/pagination-reset.test.js.map +1 -0
  18. package/lib/esm/components/datatable/__tests__/race-conditions.test.js +546 -0
  19. package/lib/esm/components/datatable/__tests__/race-conditions.test.js.map +1 -0
  20. package/lib/esm/components/datatable/__tests__/setup.js +58 -0
  21. package/lib/esm/components/datatable/__tests__/setup.js.map +1 -0
  22. package/lib/esm/components/datatable/datatable.js +92 -30
  23. package/lib/esm/components/datatable/datatable.js.map +1 -1
  24. package/lib/esm/index.js +0 -7
  25. package/lib/esm/index.js.map +1 -1
  26. package/package.json +7 -9
  27. package/src/components/alert/alert.css +188 -429
  28. package/src/components/datatable/__tests__/pagination-reset.test.ts +657 -0
  29. package/src/components/datatable/__tests__/race-conditions.test.ts +455 -0
  30. package/src/components/datatable/__tests__/setup.ts +67 -0
  31. package/src/components/datatable/datatable.ts +66 -11
  32. package/src/components/input/input.css +0 -1
  33. package/src/components/select/select.css +0 -1
  34. package/src/components/select/variants.css +4 -0
  35. package/src/components/textarea/textarea.css +0 -1
  36. package/src/index.ts +0 -10
  37. package/styles.css +0 -1
  38. package/lib/cjs/components/alert/alert.js +0 -1025
  39. package/lib/cjs/components/alert/alert.js.map +0 -1
  40. package/lib/cjs/components/alert/index.js +0 -20
  41. package/lib/cjs/components/alert/index.js.map +0 -1
  42. package/lib/cjs/components/alert/templates.js +0 -120
  43. package/lib/cjs/components/alert/templates.js.map +0 -1
  44. package/lib/cjs/components/alert/types.js +0 -7
  45. package/lib/cjs/components/alert/types.js.map +0 -1
  46. package/lib/cjs/components/datepicker/config/config.js +0 -42
  47. package/lib/cjs/components/datepicker/config/config.js.map +0 -1
  48. package/lib/cjs/components/datepicker/config/index.js +0 -24
  49. package/lib/cjs/components/datepicker/config/index.js.map +0 -1
  50. package/lib/cjs/components/datepicker/config/interfaces.js +0 -7
  51. package/lib/cjs/components/datepicker/config/interfaces.js.map +0 -1
  52. package/lib/cjs/components/datepicker/config/types.js +0 -7
  53. package/lib/cjs/components/datepicker/config/types.js.map +0 -1
  54. package/lib/cjs/components/datepicker/core/event-manager.js +0 -135
  55. package/lib/cjs/components/datepicker/core/event-manager.js.map +0 -1
  56. package/lib/cjs/components/datepicker/core/focus-manager.js +0 -167
  57. package/lib/cjs/components/datepicker/core/focus-manager.js.map +0 -1
  58. package/lib/cjs/components/datepicker/core/helpers.js +0 -219
  59. package/lib/cjs/components/datepicker/core/helpers.js.map +0 -1
  60. package/lib/cjs/components/datepicker/core/index.js +0 -25
  61. package/lib/cjs/components/datepicker/core/index.js.map +0 -1
  62. package/lib/cjs/components/datepicker/core/unified-state-manager.js +0 -394
  63. package/lib/cjs/components/datepicker/core/unified-state-manager.js.map +0 -1
  64. package/lib/cjs/components/datepicker/datepicker.js +0 -2252
  65. package/lib/cjs/components/datepicker/datepicker.js.map +0 -1
  66. package/lib/cjs/components/datepicker/index.js +0 -24
  67. package/lib/cjs/components/datepicker/index.js.map +0 -1
  68. package/lib/cjs/components/datepicker/ui/index.js +0 -23
  69. package/lib/cjs/components/datepicker/ui/index.js.map +0 -1
  70. package/lib/cjs/components/datepicker/ui/input/dropdown.js +0 -489
  71. package/lib/cjs/components/datepicker/ui/input/dropdown.js.map +0 -1
  72. package/lib/cjs/components/datepicker/ui/input/index.js +0 -23
  73. package/lib/cjs/components/datepicker/ui/input/index.js.map +0 -1
  74. package/lib/cjs/components/datepicker/ui/input/segmented-input.js +0 -640
  75. package/lib/cjs/components/datepicker/ui/input/segmented-input.js.map +0 -1
  76. package/lib/cjs/components/datepicker/ui/renderers/calendar.js +0 -446
  77. package/lib/cjs/components/datepicker/ui/renderers/calendar.js.map +0 -1
  78. package/lib/cjs/components/datepicker/ui/renderers/footer.js +0 -42
  79. package/lib/cjs/components/datepicker/ui/renderers/footer.js.map +0 -1
  80. package/lib/cjs/components/datepicker/ui/renderers/header.js +0 -32
  81. package/lib/cjs/components/datepicker/ui/renderers/header.js.map +0 -1
  82. package/lib/cjs/components/datepicker/ui/renderers/index.js +0 -25
  83. package/lib/cjs/components/datepicker/ui/renderers/index.js.map +0 -1
  84. package/lib/cjs/components/datepicker/ui/renderers/time-picker.js +0 -384
  85. package/lib/cjs/components/datepicker/ui/renderers/time-picker.js.map +0 -1
  86. package/lib/cjs/components/datepicker/ui/templates/index.js +0 -22
  87. package/lib/cjs/components/datepicker/ui/templates/index.js.map +0 -1
  88. package/lib/cjs/components/datepicker/ui/templates/templates.js +0 -253
  89. package/lib/cjs/components/datepicker/ui/templates/templates.js.map +0 -1
  90. package/lib/cjs/components/datepicker/utils/date-formatters.js +0 -88
  91. package/lib/cjs/components/datepicker/utils/date-formatters.js.map +0 -1
  92. package/lib/cjs/components/datepicker/utils/date-utils.js +0 -194
  93. package/lib/cjs/components/datepicker/utils/date-utils.js.map +0 -1
  94. package/lib/cjs/components/datepicker/utils/index.js +0 -24
  95. package/lib/cjs/components/datepicker/utils/index.js.map +0 -1
  96. package/lib/cjs/components/datepicker/utils/time-utils.js +0 -213
  97. package/lib/cjs/components/datepicker/utils/time-utils.js.map +0 -1
  98. package/lib/esm/components/alert/alert.js +0 -1022
  99. package/lib/esm/components/alert/alert.js.map +0 -1
  100. package/lib/esm/components/alert/index.js +0 -4
  101. package/lib/esm/components/alert/index.js.map +0 -1
  102. package/lib/esm/components/alert/templates.js +0 -112
  103. package/lib/esm/components/alert/templates.js.map +0 -1
  104. package/lib/esm/components/alert/types.js +0 -6
  105. package/lib/esm/components/alert/types.js.map +0 -1
  106. package/lib/esm/components/datepicker/config/config.js +0 -39
  107. package/lib/esm/components/datepicker/config/config.js.map +0 -1
  108. package/lib/esm/components/datepicker/config/index.js +0 -8
  109. package/lib/esm/components/datepicker/config/index.js.map +0 -1
  110. package/lib/esm/components/datepicker/config/interfaces.js +0 -6
  111. package/lib/esm/components/datepicker/config/interfaces.js.map +0 -1
  112. package/lib/esm/components/datepicker/config/types.js +0 -6
  113. package/lib/esm/components/datepicker/config/types.js.map +0 -1
  114. package/lib/esm/components/datepicker/core/event-manager.js +0 -133
  115. package/lib/esm/components/datepicker/core/event-manager.js.map +0 -1
  116. package/lib/esm/components/datepicker/core/focus-manager.js +0 -164
  117. package/lib/esm/components/datepicker/core/focus-manager.js.map +0 -1
  118. package/lib/esm/components/datepicker/core/helpers.js +0 -211
  119. package/lib/esm/components/datepicker/core/helpers.js.map +0 -1
  120. package/lib/esm/components/datepicker/core/index.js +0 -9
  121. package/lib/esm/components/datepicker/core/index.js.map +0 -1
  122. package/lib/esm/components/datepicker/core/unified-state-manager.js +0 -391
  123. package/lib/esm/components/datepicker/core/unified-state-manager.js.map +0 -1
  124. package/lib/esm/components/datepicker/datepicker.js +0 -2248
  125. package/lib/esm/components/datepicker/datepicker.js.map +0 -1
  126. package/lib/esm/components/datepicker/index.js +0 -7
  127. package/lib/esm/components/datepicker/index.js.map +0 -1
  128. package/lib/esm/components/datepicker/ui/index.js +0 -7
  129. package/lib/esm/components/datepicker/ui/index.js.map +0 -1
  130. package/lib/esm/components/datepicker/ui/input/dropdown.js +0 -486
  131. package/lib/esm/components/datepicker/ui/input/dropdown.js.map +0 -1
  132. package/lib/esm/components/datepicker/ui/input/index.js +0 -7
  133. package/lib/esm/components/datepicker/ui/input/index.js.map +0 -1
  134. package/lib/esm/components/datepicker/ui/input/segmented-input.js +0 -637
  135. package/lib/esm/components/datepicker/ui/input/segmented-input.js.map +0 -1
  136. package/lib/esm/components/datepicker/ui/renderers/calendar.js +0 -443
  137. package/lib/esm/components/datepicker/ui/renderers/calendar.js.map +0 -1
  138. package/lib/esm/components/datepicker/ui/renderers/footer.js +0 -39
  139. package/lib/esm/components/datepicker/ui/renderers/footer.js.map +0 -1
  140. package/lib/esm/components/datepicker/ui/renderers/header.js +0 -29
  141. package/lib/esm/components/datepicker/ui/renderers/header.js.map +0 -1
  142. package/lib/esm/components/datepicker/ui/renderers/index.js +0 -9
  143. package/lib/esm/components/datepicker/ui/renderers/index.js.map +0 -1
  144. package/lib/esm/components/datepicker/ui/renderers/time-picker.js +0 -381
  145. package/lib/esm/components/datepicker/ui/renderers/time-picker.js.map +0 -1
  146. package/lib/esm/components/datepicker/ui/templates/index.js +0 -6
  147. package/lib/esm/components/datepicker/ui/templates/index.js.map +0 -1
  148. package/lib/esm/components/datepicker/ui/templates/templates.js +0 -242
  149. package/lib/esm/components/datepicker/ui/templates/templates.js.map +0 -1
  150. package/lib/esm/components/datepicker/utils/date-formatters.js +0 -83
  151. package/lib/esm/components/datepicker/utils/date-formatters.js.map +0 -1
  152. package/lib/esm/components/datepicker/utils/date-utils.js +0 -184
  153. package/lib/esm/components/datepicker/utils/date-utils.js.map +0 -1
  154. package/lib/esm/components/datepicker/utils/index.js +0 -8
  155. package/lib/esm/components/datepicker/utils/index.js.map +0 -1
  156. package/lib/esm/components/datepicker/utils/time-utils.js +0 -201
  157. package/lib/esm/components/datepicker/utils/time-utils.js.map +0 -1
  158. package/src/components/alert/alert.ts +0 -990
  159. package/src/components/alert/index.ts +0 -4
  160. package/src/components/alert/templates.ts +0 -110
  161. package/src/components/alert/tests/accessibility/aria-roles.test.ts +0 -19
  162. package/src/components/alert/tests/accessibility/focus-management.test.ts +0 -19
  163. package/src/components/alert/tests/accessibility/keyboard-nav.test.ts +0 -22
  164. package/src/components/alert/tests/actions/confirm-cancel.test.ts +0 -122
  165. package/src/components/alert/tests/actions/input-field.test.ts +0 -180
  166. package/src/components/alert/tests/alert.basic.test.ts +0 -126
  167. package/src/components/alert/tests/alert.config.test.ts +0 -75
  168. package/src/components/alert/tests/alert.templates.test.ts +0 -17
  169. package/src/components/alert/tests/config/attribute-config.test.ts +0 -94
  170. package/src/components/alert/tests/config/json-config.test.ts +0 -119
  171. package/src/components/alert/tests/config/merging.test.ts +0 -89
  172. package/src/components/alert/tests/dismissal/auto-dismiss.test.ts +0 -96
  173. package/src/components/alert/tests/dismissal/escape-key-dismiss.test.ts +0 -105
  174. package/src/components/alert/tests/dismissal/manual-dismiss.test.ts +0 -90
  175. package/src/components/alert/tests/dismissal/outside-click-dismiss.test.ts +0 -91
  176. package/src/components/alert/tests/edge-cases/invalid-config.test.ts +0 -19
  177. package/src/components/alert/tests/edge-cases/multiple-alerts.test.ts +0 -19
  178. package/src/components/alert/tests/rendering/custom-content.test.ts +0 -81
  179. package/src/components/alert/tests/rendering/info-alert.test.ts +0 -84
  180. package/src/components/alert/tests/rendering/success-alert.test.ts +0 -100
  181. package/src/components/alert/tests/templates/default-templates.test.ts +0 -16
  182. package/src/components/alert/tests/templates/user-templates.test.ts +0 -16
  183. package/src/components/alert/types.ts +0 -145
  184. package/src/components/datepicker/__tests__/datepicker-events.test.ts +0 -356
  185. package/src/components/datepicker/__tests__/datepicker-init.test.ts +0 -343
  186. package/src/components/datepicker/__tests__/datepicker-integration.test.ts +0 -435
  187. package/src/components/datepicker/__tests__/datepicker-timezone.test.ts +0 -220
  188. package/src/components/datepicker/__tests__/segmented-input-focus.test.ts +0 -380
  189. package/src/components/datepicker/__tests__/selective-state-updates.test.ts +0 -400
  190. package/src/components/datepicker/__tests__/state-manager.test.ts +0 -421
  191. package/src/components/datepicker/__tests__/time-preservation.test.ts +0 -387
  192. package/src/components/datepicker/config/config.ts +0 -40
  193. package/src/components/datepicker/config/index.ts +0 -8
  194. package/src/components/datepicker/config/interfaces.ts +0 -82
  195. package/src/components/datepicker/config/types.ts +0 -188
  196. package/src/components/datepicker/core/event-manager.ts +0 -159
  197. package/src/components/datepicker/core/focus-manager.ts +0 -201
  198. package/src/components/datepicker/core/helpers.ts +0 -231
  199. package/src/components/datepicker/core/index.ts +0 -9
  200. package/src/components/datepicker/core/unified-state-manager.ts +0 -459
  201. package/src/components/datepicker/datepicker.css +0 -435
  202. package/src/components/datepicker/datepicker.ts +0 -2548
  203. package/src/components/datepicker/index.ts +0 -8
  204. package/src/components/datepicker/ui/index.ts +0 -7
  205. package/src/components/datepicker/ui/input/dropdown.ts +0 -552
  206. package/src/components/datepicker/ui/input/index.ts +0 -7
  207. package/src/components/datepicker/ui/input/segmented-input.ts +0 -638
  208. package/src/components/datepicker/ui/renderers/__tests__/calendar-optimizations.test.ts +0 -611
  209. package/src/components/datepicker/ui/renderers/calendar.ts +0 -530
  210. package/src/components/datepicker/ui/renderers/footer.ts +0 -43
  211. package/src/components/datepicker/ui/renderers/header.ts +0 -33
  212. package/src/components/datepicker/ui/renderers/index.ts +0 -9
  213. package/src/components/datepicker/ui/renderers/time-picker.ts +0 -438
  214. package/src/components/datepicker/ui/templates/index.ts +0 -6
  215. package/src/components/datepicker/ui/templates/templates.ts +0 -306
  216. package/src/components/datepicker/utils/__tests__/date-formatters.test.ts +0 -160
  217. package/src/components/datepicker/utils/__tests__/date-utils-keys.test.ts +0 -86
  218. package/src/components/datepicker/utils/__tests__/date-utils-timezone.test.ts +0 -215
  219. package/src/components/datepicker/utils/date-formatters.ts +0 -85
  220. package/src/components/datepicker/utils/date-utils.ts +0 -172
  221. package/src/components/datepicker/utils/index.ts +0 -8
  222. 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
-