@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,159 +0,0 @@
1
- /*
2
- * event-manager.ts - Internal event management for KTDatepicker
3
- * Replaces external dependency on select component's EventManager
4
- */
5
-
6
- /**
7
- * Event listener function type
8
- */
9
- export type EventListener = (event: Event) => void;
10
-
11
- /**
12
- * Event manager configuration
13
- */
14
- export interface EventManagerConfig {
15
- enableEventBubbling: boolean;
16
- enableCustomEvents: boolean;
17
- enableValidation: boolean;
18
- enableDebugging: boolean;
19
- }
20
-
21
- /**
22
- * Event manager for handling DOM events
23
- */
24
- export class EventManager {
25
- // Alias for backward compatibility
26
- static KTDropdownEventManager = EventManager;
27
- private _listeners: Map<HTMLElement, Map<string, Set<EventListener>>> = new Map();
28
- private _config: EventManagerConfig;
29
-
30
- constructor(config?: Partial<EventManagerConfig>) {
31
- this._config = {
32
- enableEventBubbling: true,
33
- enableCustomEvents: false,
34
- enableValidation: true,
35
- enableDebugging: false,
36
- ...config
37
- };
38
- }
39
-
40
- /**
41
- * Add event listener to element
42
- */
43
- public addListener(element: HTMLElement, eventType: string, listener: EventListener): void {
44
- if (!this._listeners.has(element)) {
45
- this._listeners.set(element, new Map());
46
- }
47
-
48
- const elementListeners = this._listeners.get(element)!;
49
- if (!elementListeners.has(eventType)) {
50
- elementListeners.set(eventType, new Set());
51
- }
52
-
53
- const listeners = elementListeners.get(eventType)!;
54
- listeners.add(listener);
55
-
56
- element.addEventListener(eventType, listener, !this._config.enableEventBubbling);
57
- }
58
-
59
- /**
60
- * Remove event listener from element
61
- */
62
- public removeListener(element: HTMLElement, eventType: string, listener: EventListener): void {
63
- const elementListeners = this._listeners.get(element);
64
- if (!elementListeners) return;
65
-
66
- const listeners = elementListeners.get(eventType);
67
- if (!listeners) return;
68
-
69
- listeners.delete(listener);
70
- element.removeEventListener(eventType, listener, !this._config.enableEventBubbling);
71
-
72
- if (listeners.size === 0) {
73
- elementListeners.delete(eventType);
74
- }
75
-
76
- if (elementListeners.size === 0) {
77
- this._listeners.delete(element);
78
- }
79
- }
80
-
81
- /**
82
- * Remove all listeners from element
83
- */
84
- public removeAllListeners(element: HTMLElement): void {
85
- const elementListeners = this._listeners.get(element);
86
- if (!elementListeners) return;
87
-
88
- elementListeners.forEach((listeners, eventType) => {
89
- listeners.forEach(listener => {
90
- element.removeEventListener(eventType, listener, !this._config.enableEventBubbling);
91
- });
92
- });
93
-
94
- this._listeners.delete(element);
95
- }
96
-
97
- /**
98
- * Remove all listeners from all elements
99
- */
100
- public removeAllListenersFromAll(): void {
101
- this._listeners.forEach((elementListeners, element) => {
102
- elementListeners.forEach((listeners, eventType) => {
103
- listeners.forEach(listener => {
104
- element.removeEventListener(eventType, listener, !this._config.enableEventBubbling);
105
- });
106
- });
107
- });
108
-
109
- this._listeners.clear();
110
- }
111
-
112
- /**
113
- * Dispatch custom event
114
- */
115
- public dispatchEvent(element: HTMLElement, eventType: string, detail?: any): boolean {
116
- if (!this._config.enableCustomEvents) {
117
- return false;
118
- }
119
-
120
- const event = new CustomEvent(eventType, {
121
- detail,
122
- bubbles: this._config.enableEventBubbling,
123
- cancelable: true
124
- });
125
-
126
- const result = element.dispatchEvent(event);
127
-
128
- return result;
129
- }
130
-
131
- /**
132
- * Get listener count for element and event type
133
- */
134
- public getListenerCount(element: HTMLElement, eventType?: string): number {
135
- const elementListeners = this._listeners.get(element);
136
- if (!elementListeners) return 0;
137
-
138
- if (eventType) {
139
- return elementListeners.get(eventType)?.size || 0;
140
- }
141
-
142
- let total = 0;
143
- elementListeners.forEach(listeners => {
144
- total += listeners.size;
145
- });
146
- return total;
147
- }
148
-
149
- /**
150
- * Dispose of event manager
151
- */
152
- public dispose(): void {
153
- this.removeAllListenersFromAll();
154
- this._listeners.clear();
155
- }
156
- }
157
-
158
- // Export alias for backward compatibility
159
- export { EventManager as KTDropdownEventManager };
@@ -1,201 +0,0 @@
1
- /*
2
- * focus-manager.ts - Internal focus management for KTDatepicker
3
- * Replaces external dependency on select component's FocusManager
4
- */
5
-
6
- /**
7
- * Focus manager configuration
8
- */
9
- export interface FocusManagerConfig {
10
- enableFocusTrapping: boolean;
11
- enableFocusRestoration: boolean;
12
- enableKeyboardNavigation: boolean;
13
- enableDebugging: boolean;
14
- }
15
-
16
- /**
17
- * Focusable element interface
18
- */
19
- export interface FocusableElement {
20
- element: HTMLElement;
21
- tabIndex: number;
22
- isFocusable: boolean;
23
- }
24
-
25
- /**
26
- * Focus manager for handling focus states and navigation
27
- */
28
- export class FocusManager {
29
- private _config: FocusManagerConfig;
30
- private _focusedElement: HTMLElement | null = null;
31
- private _previousFocusedElement: HTMLElement | null = null;
32
- private _focusableElements: FocusableElement[] = [];
33
- private _currentFocusIndex: number = -1;
34
-
35
- constructor(config?: Partial<FocusManagerConfig>) {
36
- this._config = {
37
- enableFocusTrapping: true,
38
- enableFocusRestoration: true,
39
- enableKeyboardNavigation: true,
40
- enableDebugging: false,
41
- ...config
42
- };
43
- }
44
-
45
- /**
46
- * Set focus to element
47
- */
48
- public focus(element: HTMLElement): boolean {
49
- if (!element || !this._isElementFocusable(element)) {
50
- return false;
51
- }
52
-
53
- this._previousFocusedElement = this._focusedElement;
54
- this._focusedElement = element;
55
-
56
- try {
57
- element.focus();
58
- return true;
59
- } catch (error) {
60
- return false;
61
- }
62
- }
63
-
64
- /**
65
- * Get currently focused element
66
- */
67
- public getFocusedElement(): HTMLElement | null {
68
- return this._focusedElement;
69
- }
70
-
71
- /**
72
- * Get previously focused element
73
- */
74
- public getPreviousFocusedElement(): HTMLElement | null {
75
- return this._previousFocusedElement;
76
- }
77
-
78
- /**
79
- * Restore focus to previous element
80
- */
81
- public restoreFocus(): boolean {
82
- if (!this._config.enableFocusRestoration || !this._previousFocusedElement) {
83
- return false;
84
- }
85
-
86
- return this.focus(this._previousFocusedElement);
87
- }
88
-
89
- /**
90
- * Set focusable elements for navigation
91
- */
92
- public setFocusableElements(elements: HTMLElement[]): void {
93
- this._focusableElements = elements
94
- .filter(element => this._isElementFocusable(element))
95
- .map(element => ({
96
- element,
97
- tabIndex: this._getTabIndex(element),
98
- isFocusable: true
99
- }))
100
- .sort((a, b) => a.tabIndex - b.tabIndex);
101
- }
102
-
103
- /**
104
- * Focus next element
105
- */
106
- public focusNext(): boolean {
107
- if (!this._config.enableKeyboardNavigation || this._focusableElements.length === 0) {
108
- return false;
109
- }
110
-
111
- this._currentFocusIndex = (this._currentFocusIndex + 1) % this._focusableElements.length;
112
- const nextElement = this._focusableElements[this._currentFocusIndex];
113
-
114
- return this.focus(nextElement.element);
115
- }
116
-
117
- /**
118
- * Focus previous element
119
- */
120
- public focusPrevious(): boolean {
121
- if (!this._config.enableKeyboardNavigation || this._focusableElements.length === 0) {
122
- return false;
123
- }
124
-
125
- this._currentFocusIndex = this._currentFocusIndex <= 0
126
- ? this._focusableElements.length - 1
127
- : this._currentFocusIndex - 1;
128
-
129
- const prevElement = this._focusableElements[this._currentFocusIndex];
130
-
131
- return this.focus(prevElement.element);
132
- }
133
-
134
- /**
135
- * Focus first element
136
- */
137
- public focusFirst(): boolean {
138
- if (this._focusableElements.length === 0) {
139
- return false;
140
- }
141
-
142
- this._currentFocusIndex = 0;
143
- return this.focus(this._focusableElements[0].element);
144
- }
145
-
146
- /**
147
- * Focus last element
148
- */
149
- public focusLast(): boolean {
150
- if (this._focusableElements.length === 0) {
151
- return false;
152
- }
153
-
154
- this._currentFocusIndex = this._focusableElements.length - 1;
155
- return this.focus(this._focusableElements[this._currentFocusIndex].element);
156
- }
157
-
158
- /**
159
- * Check if element is focusable
160
- */
161
- private _isElementFocusable(element: HTMLElement): boolean {
162
- if (!element || element.hidden || element.style.display === 'none') {
163
- return false;
164
- }
165
-
166
- const tabIndex = this._getTabIndex(element);
167
- return tabIndex >= 0;
168
- }
169
-
170
- /**
171
- * Get tab index of element
172
- */
173
- private _getTabIndex(element: HTMLElement): number {
174
- const tabIndex = element.getAttribute('tabindex');
175
- if (tabIndex === null) {
176
- // Check if element is naturally focusable
177
- const tagName = element.tagName.toLowerCase();
178
- const naturallyFocusable = ['input', 'button', 'select', 'textarea', 'a'].includes(tagName);
179
- return naturallyFocusable ? 0 : -1;
180
- }
181
-
182
- return parseInt(tabIndex, 10);
183
- }
184
-
185
- /**
186
- * Clear focus
187
- */
188
- public clearFocus(): void {
189
- this._focusedElement = null;
190
- this._currentFocusIndex = -1;
191
- }
192
-
193
- /**
194
- * Dispose of focus manager
195
- */
196
- public dispose(): void {
197
- this.clearFocus();
198
- this._focusableElements = [];
199
- this._previousFocusedElement = null;
200
- }
201
- }
@@ -1,231 +0,0 @@
1
- /*
2
- * datepicker-helpers.ts - Modular helpers for KTDatepicker input rendering and state
3
- */
4
- import { KTDatepickerConfig, KTDatepickerState } from '../config/types';
5
- import { renderTemplateToDOM, createTemplateRenderer, getTemplateStrings } from '../ui/templates/templates';
6
- import { SegmentedInput } from '../ui/input/segmented-input';
7
- import { getTimeSegments } from '../utils/time-utils';
8
- import { getSegmentOrderFromFormat, normalizeDateToLocalMidnight } from '../utils/date-utils';
9
-
10
- /**
11
- * Get segments array based on configuration (date + optional time)
12
- * @param config Datepicker configuration
13
- * @returns Array of segment types
14
- */
15
- export function getSegmentsForConfig(config: KTDatepickerConfig): Array<'day' | 'month' | 'year' | 'hour' | 'minute' | 'second' | 'ampm'> {
16
- // Determine date segments based on format
17
- let segments: Array<'day' | 'month' | 'year' | 'hour' | 'minute' | 'second' | 'ampm'>;
18
-
19
- if (config.format && typeof config.format === 'string') {
20
- // Use format-derived segment order for date parts
21
- segments = getSegmentOrderFromFormat(config.format);
22
- } else {
23
- // Default fallback
24
- segments = ['month', 'day', 'year'];
25
- }
26
-
27
- // Add time segments if time is enabled
28
- if (config.enableTime) {
29
- const timeSegments = getTimeSegments(config.timeGranularity || 'minute');
30
- segments = [...segments, ...timeSegments];
31
-
32
- // Add AM/PM for 12-hour format
33
- if (config.timeFormat === '12h') {
34
- segments.push('ampm');
35
- }
36
- }
37
-
38
- return segments;
39
- }
40
-
41
- export {};
42
-
43
- export function renderSingleSegmentedInputUI(
44
- inputWrapperTpl: string | ((data: any) => string),
45
- calendarButtonHtml: string,
46
- config?: KTDatepickerConfig
47
- ): HTMLElement {
48
- // Get template renderer with proper configuration
49
- const templates = getTemplateStrings(config);
50
- const templateRenderer = createTemplateRenderer(templates);
51
-
52
- // Create the segmented input container using the template system
53
- const segmentedInputEl = templateRenderer.renderTemplateToElement({
54
- templateKey: 'segmentedDateInput',
55
- data: { segments: '' }, // Empty segments initially, will be populated by SegmentedInput
56
- configClasses: config?.classes // Pass config classes for proper styling
57
- });
58
-
59
- let inputWrapperHtml: string;
60
- if (typeof inputWrapperTpl === 'function') {
61
- inputWrapperHtml = inputWrapperTpl({ input: segmentedInputEl.outerHTML, icon: calendarButtonHtml, class: '' });
62
- } else {
63
- inputWrapperHtml = inputWrapperTpl
64
- .replace(/{{icon}}/g, calendarButtonHtml)
65
- .replace(/{{input}}/g, segmentedInputEl.outerHTML)
66
- .replace(/{{class}}/g, ''); // Replace class placeholder with empty string if no class provided
67
- }
68
- const inputWrapperFrag = renderTemplateToDOM(inputWrapperHtml);
69
- return inputWrapperFrag.firstElementChild as HTMLElement;
70
- }
71
-
72
- export function renderRangeSegmentedInputUI(
73
- inputWrapperTpl: string | ((data: any) => string),
74
- rangeTpl: string | ((data: any) => string),
75
- calendarButtonHtml: string,
76
- config?: KTDatepickerConfig
77
- ): { inputWrapperEl: HTMLElement; startContainer: HTMLElement; endContainer: HTMLElement } {
78
- // Get template renderer with proper configuration
79
- const templates = getTemplateStrings(config);
80
- const templateRenderer = createTemplateRenderer(templates);
81
-
82
- let inputWrapperHtml: string;
83
- if (typeof inputWrapperTpl === 'function') {
84
- inputWrapperHtml = inputWrapperTpl({ input: '', icon: calendarButtonHtml, class: '' });
85
- } else {
86
- inputWrapperHtml = inputWrapperTpl
87
- .replace(/{{icon}}/g, calendarButtonHtml)
88
- .replace(/{{input}}/g, '')
89
- .replace(/{{class}}/g, ''); // Replace class placeholder with empty string if no class provided
90
- }
91
- const inputWrapperFrag = renderTemplateToDOM(inputWrapperHtml);
92
- const inputWrapperEl = inputWrapperFrag.firstElementChild as HTMLElement;
93
-
94
- // Create containers for start and end segmented inputs using template system
95
- const startContainer = templateRenderer.renderTemplateToElement({
96
- templateKey: 'segmentedDateInput',
97
- data: { segments: '' },
98
- configClasses: { ...config?.classes, segmentedDateInput: 'kt-segmented-input-start' }
99
- });
100
- startContainer.setAttribute('aria-label', 'Start date');
101
- startContainer.setAttribute('data-kt-datepicker-start-container', '');
102
-
103
- const endContainer = templateRenderer.renderTemplateToElement({
104
- templateKey: 'segmentedDateInput',
105
- data: { segments: '' },
106
- configClasses: { ...config?.classes, segmentedDateInput: 'kt-segmented-input-end' }
107
- });
108
- endContainer.setAttribute('aria-label', 'End date');
109
- endContainer.setAttribute('data-kt-datepicker-end-container', '');
110
- // Render template with placeholders using template system
111
- const separator = '–';
112
-
113
- // Render start and end containers using templates
114
- const startContainerHtml = templateRenderer.renderTemplateString({
115
- templateKey: 'rangeStartContainer',
116
- data: {},
117
- configClasses: config?.classes
118
- });
119
-
120
- const endContainerHtml = templateRenderer.renderTemplateString({
121
- templateKey: 'rangeEndContainer',
122
- data: {},
123
- configClasses: config?.classes
124
- });
125
-
126
- let rangeHtml: string;
127
- if (typeof rangeTpl === 'function') {
128
- rangeHtml = rangeTpl({
129
- start: startContainerHtml,
130
- separator,
131
- end: endContainerHtml,
132
- class: ''
133
- });
134
- } else {
135
- rangeHtml = rangeTpl
136
- .replace(/{{start}}/g, startContainerHtml)
137
- .replace(/{{separator}}/g, separator)
138
- .replace(/{{end}}/g, endContainerHtml)
139
- .replace(/{{class}}/g, ''); // Replace class placeholder with empty string if no class provided
140
- }
141
- const rangeFrag = renderTemplateToDOM(rangeHtml);
142
- // Find mount points
143
- const startMount = rangeFrag.querySelector('[data-kt-datepicker-segmented-start]') as HTMLElement;
144
- const endMount = rangeFrag.querySelector('[data-kt-datepicker-segmented-end]') as HTMLElement;
145
- if (startMount) startMount.replaceWith(startContainer);
146
- if (endMount) endMount.replaceWith(endContainer);
147
- // Insert the range input UI at the start of the wrapper
148
- inputWrapperEl.insertBefore(rangeFrag.firstElementChild!, inputWrapperEl.firstChild);
149
- return { inputWrapperEl, startContainer, endContainer };
150
- }
151
-
152
- export function instantiateSingleSegmentedInput(
153
- container: HTMLElement,
154
- state: KTDatepickerState,
155
- config: KTDatepickerConfig,
156
- onChange: (date: Date) => void
157
- ): void {
158
- // Use shared utility to determine segments
159
- const segments = getSegmentsForConfig(config);
160
-
161
- SegmentedInput(container, {
162
- value: state.selectedDate || state.currentDate || new Date(),
163
- format: config.format,
164
- segments,
165
- disabled: !!config.disabled,
166
- required: !!config.required,
167
- readOnly: !!config.readOnly,
168
- locale: config.locale,
169
- timeFormat: config.timeFormat,
170
- onChange,
171
- });
172
- }
173
-
174
- export function instantiateRangeSegmentedInputs(
175
- startContainer: HTMLElement,
176
- endContainer: HTMLElement,
177
- state: KTDatepickerState,
178
- config: KTDatepickerConfig,
179
- onStartChange: (date: Date) => void,
180
- onEndChange: (date: Date) => void
181
- ): void {
182
- // Use shared utility to determine segments (includes time if enabled)
183
- const segments = getSegmentsForConfig(config);
184
-
185
- SegmentedInput(startContainer, {
186
- value: state.selectedRange?.start || new Date(),
187
- format: config.format,
188
- segments,
189
- disabled: !!config.disabled,
190
- required: !!config.required,
191
- readOnly: !!config.readOnly,
192
- locale: config.locale,
193
- timeFormat: config.timeFormat,
194
- onChange: onStartChange,
195
- });
196
- SegmentedInput(endContainer, {
197
- value: state.selectedRange?.end || new Date(),
198
- format: config.format,
199
- segments,
200
- disabled: !!config.disabled,
201
- required: !!config.required,
202
- readOnly: !!config.readOnly,
203
- locale: config.locale,
204
- timeFormat: config.timeFormat,
205
- onChange: onEndChange,
206
- });
207
- }
208
-
209
- export function updateRangeSelection(
210
- selectedRange: { start: Date | null; end: Date | null } | null,
211
- date: Date
212
- ): { start: Date | null; end: Date | null } {
213
- // Normalize dates to local midnight for date-only comparisons
214
- const normalizedDate = normalizeDateToLocalMidnight(date);
215
-
216
- if (!selectedRange || (!selectedRange.start && !selectedRange.end)) {
217
- return { start: normalizedDate, end: null };
218
- } else if (selectedRange.start && !selectedRange.end) {
219
- const normalizedStart = normalizeDateToLocalMidnight(selectedRange.start);
220
- if (normalizedDate >= normalizedStart) {
221
- // Forward selection: new date is after start, becomes end
222
- return { start: selectedRange.start, end: normalizedDate };
223
- } else {
224
- // Backward selection: new date is before start, swap so start is always earlier
225
- // The clicked date becomes the actual start, original start becomes end
226
- return { start: normalizedDate, end: selectedRange.start };
227
- }
228
- } else {
229
- return { start: normalizedDate, end: null };
230
- }
231
- }
@@ -1,9 +0,0 @@
1
- /*
2
- * core/index.ts - Core module exports
3
- * Provides core logic components for KTDatepicker
4
- */
5
-
6
- export * from './unified-state-manager';
7
- export * from './event-manager';
8
- export * from './focus-manager';
9
- export * from './helpers';