@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,400 +0,0 @@
1
- /**
2
- * selective-state-updates.test.ts - Tests for selective state update optimizations
3
- * Tests change tracking, changed properties computation, and selective UI updates
4
- */
5
-
6
- import { describe, it, expect, beforeEach, vi } from 'vitest';
7
- import { KTDatepickerUnifiedStateManager } from '../core/unified-state-manager';
8
- import { KTDatepickerState } from '../config/types';
9
-
10
- describe('Selective State Updates - Change Tracking', () => {
11
- let stateManager: KTDatepickerUnifiedStateManager;
12
- let mockObserver: any;
13
-
14
- beforeEach(() => {
15
- stateManager = new KTDatepickerUnifiedStateManager({
16
- enableValidation: true,
17
- enableDebugging: false,
18
- enableUpdateBatching: false // Disable batching for simpler tests
19
- });
20
-
21
- mockObserver = {
22
- onStateChange: vi.fn(),
23
- getUpdatePriority: vi.fn().mockReturnValue(1)
24
- };
25
- });
26
-
27
- describe('Changed Properties Tracking', () => {
28
- it('should track changed properties for primitive values', () => {
29
- const unsubscribe = stateManager.subscribe(mockObserver);
30
-
31
- // Update isOpen
32
- stateManager.updateState({ isOpen: true }, 'test', true);
33
-
34
- const changedProperties = stateManager.getLastChangedProperties();
35
- expect(changedProperties.has('isOpen')).toBe(true);
36
- expect(changedProperties.size).toBe(1);
37
-
38
- unsubscribe();
39
- });
40
-
41
- it('should track changed properties for Date objects', () => {
42
- const unsubscribe = stateManager.subscribe(mockObserver);
43
-
44
- const testDate = new Date(2024, 0, 15);
45
- stateManager.updateState({ selectedDate: testDate }, 'test', true);
46
-
47
- const changedProperties = stateManager.getLastChangedProperties();
48
- expect(changedProperties.has('selectedDate')).toBe(true);
49
-
50
- unsubscribe();
51
- });
52
-
53
- it('should not track unchanged Date objects', () => {
54
- const unsubscribe = stateManager.subscribe(mockObserver);
55
-
56
- const testDate = new Date(2024, 0, 15);
57
- stateManager.updateState({ selectedDate: testDate }, 'test', true);
58
- mockObserver.onStateChange.mockClear();
59
-
60
- // Update with same date
61
- const sameDate = new Date(2024, 0, 15);
62
- stateManager.updateState({ selectedDate: sameDate }, 'test', true);
63
-
64
- const changedProperties = stateManager.getLastChangedProperties();
65
- // Should still track it as changed in the changes object, but the comparison should work
66
- expect(mockObserver.onStateChange).toHaveBeenCalled();
67
-
68
- unsubscribe();
69
- });
70
-
71
- it('should track changed properties for arrays (selectedDates)', () => {
72
- const unsubscribe = stateManager.subscribe(mockObserver);
73
-
74
- const dates = [new Date(2024, 0, 15), new Date(2024, 0, 20)];
75
- stateManager.updateState({ selectedDates: dates }, 'test', true);
76
-
77
- const changedProperties = stateManager.getLastChangedProperties();
78
- expect(changedProperties.has('selectedDates')).toBe(true);
79
-
80
- unsubscribe();
81
- });
82
-
83
- it('should track changed properties for nested objects (selectedRange)', () => {
84
- const unsubscribe = stateManager.subscribe(mockObserver);
85
-
86
- const range = {
87
- start: new Date(2024, 0, 15),
88
- end: new Date(2024, 0, 20)
89
- };
90
- stateManager.updateState({ selectedRange: range }, 'test', true);
91
-
92
- const changedProperties = stateManager.getLastChangedProperties();
93
- expect(changedProperties.has('selectedRange')).toBe(true);
94
- // Nested properties are tracked only when they actually differ from previous state
95
- // Initial state has selectedRange: null, so start and end will differ from null
96
- // The nested properties are tracked if the oldValue and newValue differ
97
- if (changedProperties.has('selectedRange')) {
98
- // Nested tracking depends on whether oldState.selectedRange exists
99
- // Since initial state has null, the comparison should work
100
- const hasStart = changedProperties.has('selectedRange.start');
101
- const hasEnd = changedProperties.has('selectedRange.end');
102
- // At least the parent property should be tracked
103
- expect(changedProperties.has('selectedRange')).toBe(true);
104
- }
105
-
106
- unsubscribe();
107
- });
108
-
109
- it('should track only changed nested properties in selectedRange', () => {
110
- const unsubscribe = stateManager.subscribe(mockObserver);
111
-
112
- // Set initial range
113
- const initialRange = {
114
- start: new Date(2024, 0, 15),
115
- end: new Date(2024, 0, 20)
116
- };
117
- stateManager.updateState({ selectedRange: initialRange }, 'test', true);
118
- mockObserver.onStateChange.mockClear();
119
-
120
- // Update only the end date
121
- const updatedRange = {
122
- start: new Date(2024, 0, 15), // Same
123
- end: new Date(2024, 0, 25) // Different
124
- };
125
- stateManager.updateState({ selectedRange: updatedRange }, 'test', true);
126
-
127
- const changedProperties = stateManager.getLastChangedProperties();
128
- expect(changedProperties.has('selectedRange')).toBe(true);
129
- expect(changedProperties.has('selectedRange.start')).toBe(false); // Not changed
130
- expect(changedProperties.has('selectedRange.end')).toBe(true); // Changed
131
-
132
- unsubscribe();
133
- });
134
-
135
- it('should track multiple changed properties in single update', () => {
136
- const unsubscribe = stateManager.subscribe(mockObserver);
137
-
138
- stateManager.updateState({
139
- selectedDate: new Date(2024, 0, 15),
140
- isOpen: true,
141
- currentDate: new Date(2024, 1, 1)
142
- }, 'test', true);
143
-
144
- const changedProperties = stateManager.getLastChangedProperties();
145
- expect(changedProperties.has('selectedDate')).toBe(true);
146
- expect(changedProperties.has('isOpen')).toBe(true);
147
- expect(changedProperties.has('currentDate')).toBe(true);
148
- expect(changedProperties.size).toBeGreaterThanOrEqual(3);
149
-
150
- unsubscribe();
151
- });
152
-
153
- it('should clear changed properties between updates', () => {
154
- const unsubscribe = stateManager.subscribe(mockObserver);
155
-
156
- // First update
157
- stateManager.updateState({ isOpen: true }, 'test1', true);
158
- let changedProperties = stateManager.getLastChangedProperties();
159
- expect(changedProperties.has('isOpen')).toBe(true);
160
-
161
- // Second update with different property
162
- stateManager.updateState({ selectedDate: new Date(2024, 0, 15) }, 'test2', true);
163
- changedProperties = stateManager.getLastChangedProperties();
164
- expect(changedProperties.has('isOpen')).toBe(false); // Should not be in new change set
165
- expect(changedProperties.has('selectedDate')).toBe(true);
166
-
167
- unsubscribe();
168
- });
169
- });
170
-
171
- describe('Complex Property Comparisons', () => {
172
- it('should correctly compare Date objects with same time', () => {
173
- const unsubscribe = stateManager.subscribe(mockObserver);
174
-
175
- const date1 = new Date(2024, 0, 15, 10, 30, 0);
176
- const date2 = new Date(2024, 0, 15, 10, 30, 0);
177
-
178
- stateManager.updateState({ selectedDate: date1 }, 'test', true);
179
- mockObserver.onStateChange.mockClear();
180
-
181
- stateManager.updateState({ selectedDate: date2 }, 'test', true);
182
-
183
- // Both have same time value, but since we're updating with the same date in changes,
184
- // it should still trigger (the change tracking compares the changes object)
185
- expect(mockObserver.onStateChange).toHaveBeenCalled();
186
-
187
- unsubscribe();
188
- });
189
-
190
- it('should correctly compare arrays of dates', () => {
191
- const unsubscribe = stateManager.subscribe(mockObserver);
192
-
193
- const dates1 = [new Date(2024, 0, 15), new Date(2024, 0, 20)];
194
- const dates2 = [new Date(2024, 0, 15), new Date(2024, 0, 20)]; // Same dates, different objects
195
-
196
- stateManager.updateState({ selectedDates: dates1 }, 'test', true);
197
- mockObserver.onStateChange.mockClear();
198
-
199
- stateManager.updateState({ selectedDates: dates2 }, 'test', true);
200
-
201
- // Observer should be called even with equivalent arrays (because it's in the changes object)
202
- expect(mockObserver.onStateChange).toHaveBeenCalled();
203
- const changedProperties = stateManager.getLastChangedProperties();
204
- // The change tracking compares old and new state values
205
- // If the array values are equivalent (same time values), it won't track as changed
206
- // This is the expected behavior - only track when values actually differ
207
- expect(changedProperties.has('selectedDates')).toBe(false); // Same values, so not tracked
208
-
209
- unsubscribe();
210
- });
211
-
212
- it('should detect changes in array order', () => {
213
- const unsubscribe = stateManager.subscribe(mockObserver);
214
-
215
- const dates1 = [new Date(2024, 0, 15), new Date(2024, 0, 20)];
216
- const dates2 = [new Date(2024, 0, 20), new Date(2024, 0, 15)]; // Different order
217
-
218
- stateManager.updateState({ selectedDates: dates1 }, 'test', true);
219
- mockObserver.onStateChange.mockClear();
220
-
221
- stateManager.updateState({ selectedDates: dates2 }, 'test', true);
222
-
223
- const changedProperties = stateManager.getLastChangedProperties();
224
- expect(changedProperties.has('selectedDates')).toBe(true);
225
-
226
- unsubscribe();
227
- });
228
-
229
- it('should handle null values correctly', () => {
230
- const unsubscribe = stateManager.subscribe(mockObserver);
231
-
232
- // Set a date first
233
- stateManager.updateState({ selectedDate: new Date(2024, 0, 15) }, 'test', true);
234
- mockObserver.onStateChange.mockClear();
235
-
236
- // Then set to null
237
- stateManager.updateState({ selectedDate: null }, 'test', true);
238
-
239
- const changedProperties = stateManager.getLastChangedProperties();
240
- expect(changedProperties.has('selectedDate')).toBe(true);
241
-
242
- unsubscribe();
243
- });
244
-
245
- it('should handle selectedRange with null start or end', () => {
246
- const unsubscribe = stateManager.subscribe(mockObserver);
247
-
248
- // Set range with null start
249
- stateManager.updateState({
250
- selectedRange: { start: null, end: new Date(2024, 0, 20) }
251
- }, 'test', true);
252
-
253
- let changedProperties = stateManager.getLastChangedProperties();
254
- expect(changedProperties.has('selectedRange')).toBe(true);
255
-
256
- mockObserver.onStateChange.mockClear();
257
-
258
- // Update to add start date
259
- stateManager.updateState({
260
- selectedRange: { start: new Date(2024, 0, 15), end: new Date(2024, 0, 20) }
261
- }, 'test', true);
262
-
263
- changedProperties = stateManager.getLastChangedProperties();
264
- expect(changedProperties.has('selectedRange.start')).toBe(true);
265
-
266
- unsubscribe();
267
- });
268
- });
269
-
270
- describe('State Synchronization', () => {
271
- it('should maintain state consistency with selective updates', () => {
272
- const unsubscribe = stateManager.subscribe(mockObserver);
273
-
274
- // Perform multiple sequential updates
275
- stateManager.updateState({ selectedDate: new Date(2024, 0, 15) }, 'test1', true);
276
- stateManager.updateState({ currentDate: new Date(2024, 1, 1) }, 'test2', true);
277
- stateManager.updateState({ isOpen: true }, 'test3', true);
278
-
279
- const finalState = stateManager.getState();
280
- expect(finalState.selectedDate).toEqual(new Date(2024, 0, 15));
281
- expect(finalState.currentDate).toEqual(new Date(2024, 1, 1));
282
- expect(finalState.isOpen).toBe(true);
283
-
284
- unsubscribe();
285
- });
286
-
287
- it('should not lose state properties during selective updates', () => {
288
- const unsubscribe = stateManager.subscribe(mockObserver);
289
-
290
- // Set multiple properties
291
- stateManager.updateState({
292
- selectedDate: new Date(2024, 0, 15),
293
- currentDate: new Date(2024, 0, 1),
294
- isOpen: false
295
- }, 'test', true);
296
-
297
- const state1 = stateManager.getState();
298
- expect(state1.selectedDate).toBeTruthy();
299
- expect(state1.currentDate).toBeTruthy();
300
- expect(state1.isOpen).toBe(false);
301
-
302
- // Update only one property
303
- stateManager.updateState({ isOpen: true }, 'test2', true);
304
-
305
- const state2 = stateManager.getState();
306
- // Other properties should still be present
307
- expect(state2.selectedDate).toEqual(state1.selectedDate);
308
- expect(state2.currentDate).toEqual(state1.currentDate);
309
- expect(state2.isOpen).toBe(true); // This one changed
310
-
311
- unsubscribe();
312
- });
313
-
314
- it('should correctly merge batched updates with changed properties', async () => {
315
- stateManager = new KTDatepickerUnifiedStateManager({
316
- enableValidation: true,
317
- enableUpdateBatching: true,
318
- batchDelay: 16
319
- });
320
-
321
- const unsubscribe = stateManager.subscribe(mockObserver);
322
-
323
- // Multiple batched updates
324
- stateManager.updateState({ selectedDate: new Date(2024, 0, 15) }, 'test1', false);
325
- stateManager.updateState({ currentDate: new Date(2024, 1, 1) }, 'test2', false);
326
-
327
- // Wait for batch
328
- await new Promise(resolve => setTimeout(resolve, 20));
329
-
330
- expect(mockObserver.onStateChange).toHaveBeenCalledTimes(1);
331
-
332
- const finalState = stateManager.getState();
333
- expect(finalState.selectedDate).toEqual(new Date(2024, 0, 15));
334
- expect(finalState.currentDate).toEqual(new Date(2024, 1, 1));
335
-
336
- // Check changed properties (should include both)
337
- const changedProperties = stateManager.getLastChangedProperties();
338
- expect(changedProperties.has('selectedDate')).toBe(true);
339
- expect(changedProperties.has('currentDate')).toBe(true);
340
-
341
- unsubscribe();
342
- });
343
- });
344
-
345
- describe('Time State Tracking', () => {
346
- it('should track changes to selectedTime', () => {
347
- const unsubscribe = stateManager.subscribe(mockObserver);
348
-
349
- stateManager.updateState({
350
- selectedTime: { hour: 14, minute: 30, second: 0 }
351
- }, 'test', true);
352
-
353
- const changedProperties = stateManager.getLastChangedProperties();
354
- expect(changedProperties.has('selectedTime')).toBe(true);
355
-
356
- unsubscribe();
357
- });
358
-
359
- it('should detect changes in time values', () => {
360
- const unsubscribe = stateManager.subscribe(mockObserver);
361
-
362
- // Set initial time
363
- stateManager.updateState({
364
- selectedTime: { hour: 14, minute: 30, second: 0 }
365
- }, 'test', true);
366
- mockObserver.onStateChange.mockClear();
367
-
368
- // Update time
369
- stateManager.updateState({
370
- selectedTime: { hour: 15, minute: 45, second: 0 }
371
- }, 'test', true);
372
-
373
- const changedProperties = stateManager.getLastChangedProperties();
374
- expect(changedProperties.has('selectedTime')).toBe(true);
375
-
376
- unsubscribe();
377
- });
378
- });
379
-
380
- describe('Readonly Access', () => {
381
- it('should return readonly set that cannot be modified', () => {
382
- const unsubscribe = stateManager.subscribe(mockObserver);
383
-
384
- stateManager.updateState({ isOpen: true }, 'test', true);
385
-
386
- const changedProperties = stateManager.getLastChangedProperties();
387
- const originalSize = changedProperties.size;
388
-
389
- // Try to modify (should not affect internal state)
390
- (changedProperties as any).add('testProperty');
391
-
392
- // Get again - should be unchanged
393
- const changedProperties2 = stateManager.getLastChangedProperties();
394
- expect(changedProperties2.has('testProperty')).toBe(false);
395
-
396
- unsubscribe();
397
- });
398
- });
399
- });
400
-