@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,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';