@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,8 +0,0 @@
1
- import { KTDatepicker, initDatepickers } from './datepicker';
2
-
3
- // Attach static init method to KTDatepicker
4
- (KTDatepicker as any).init = initDatepickers;
5
-
6
- export { KTDatepicker };
7
- export * from './ui/templates/templates';
8
- export * from './config/types';
@@ -1,7 +0,0 @@
1
- /*
2
- * ui/index.ts - UI module exports
3
- * Provides all UI components for KTDatepicker
4
- */
5
-
6
- export * from './renderers';
7
- export * from './input';
@@ -1,552 +0,0 @@
1
- /*
2
- * dropdown.ts - Datepicker dropdown management
3
- * Provides dropdown functionality for KTDatepicker following select component patterns.
4
- * Handles positioning, transitions, and event management.
5
- */
6
-
7
- import {
8
- Instance as PopperInstance,
9
- createPopper,
10
- Placement,
11
- } from '@popperjs/core';
12
- import KTDom from '../../../../helpers/dom';
13
- import KTData from '../../../../helpers/data';
14
- import KTComponent from '../../../component';
15
- import { KTDatepickerConfig } from '../../config/types';
16
- import { EventManager } from '../../core/event-manager';
17
- import { StateObserver, KTDatepickerUnifiedStateManager } from '../../core/unified-state-manager';
18
- import { KTDatepickerState } from '../../config/types';
19
-
20
- /**
21
- * KTDatepickerDropdown
22
- *
23
- * A specialized dropdown implementation for the KTDatepicker component.
24
- * This module handles the dropdown functionality for the datepicker component,
25
- * including positioning and showing/hiding.
26
- */
27
- export class KTDatepickerDropdown extends KTComponent implements StateObserver {
28
- protected override readonly _name: string = 'datepicker-dropdown';
29
- protected override readonly _config: KTDatepickerConfig;
30
-
31
- // DOM Elements
32
- protected _element: HTMLElement;
33
- private _toggleElement: HTMLElement;
34
- private _dropdownElement: HTMLElement;
35
-
36
- // State (will be managed by unified state manager)
37
- private _isOpen: boolean = false;
38
- private _isTransitioning: boolean = false;
39
- private _popperInstance: PopperInstance | null = null;
40
- private _eventManager: EventManager;
41
-
42
- // Unified state manager reference
43
- private _unifiedStateManager: KTDatepickerUnifiedStateManager | null = null;
44
-
45
- /**
46
- * Constructor
47
- * @param element The parent element (datepicker wrapper)
48
- * @param toggleElement The element that triggers the dropdown
49
- * @param dropdownElement The dropdown content element
50
- * @param config The configuration options
51
- */
52
- constructor(
53
- element: HTMLElement,
54
- toggleElement: HTMLElement,
55
- dropdownElement: HTMLElement,
56
- config: KTDatepickerConfig,
57
- ) {
58
- super();
59
-
60
- this._element = element;
61
- this._toggleElement = toggleElement;
62
- this._dropdownElement = dropdownElement;
63
- this._config = config;
64
-
65
- const container = this._resolveDropdownContainer();
66
- if (container) {
67
- if (container !== this._dropdownElement.parentElement) {
68
- container.appendChild(this._dropdownElement);
69
- }
70
- }
71
-
72
- this._eventManager = new EventManager();
73
- this._setupEventListeners();
74
- }
75
-
76
- /**
77
- * Set up event listeners for the dropdown
78
- */
79
- private _setupEventListeners(): void {
80
- // Event listeners are managed by the main datepicker class
81
- }
82
-
83
- /**
84
- * StateObserver implementation
85
- */
86
- public onStateChange(newState: KTDatepickerState, oldState: KTDatepickerState): void {
87
- // React to dropdown state changes from unified state manager
88
- if (newState.dropdownState.isOpen !== oldState.dropdownState.isOpen) {
89
- if (newState.dropdownState.isOpen) {
90
- this._handleOpenFromState();
91
- } else {
92
- this._handleCloseFromState();
93
- }
94
- }
95
-
96
- if (newState.dropdownState.isTransitioning !== oldState.dropdownState.isTransitioning) {
97
- this._isTransitioning = newState.dropdownState.isTransitioning;
98
- }
99
- }
100
-
101
- public getUpdatePriority(): number {
102
- return 10; // Medium priority for dropdown updates
103
- }
104
-
105
- /**
106
- * Set unified state manager reference
107
- */
108
- public setUnifiedStateManager(stateManager: KTDatepickerUnifiedStateManager): void {
109
- this._unifiedStateManager = stateManager;
110
- }
111
-
112
- /**
113
- * Handle open state change from unified state manager
114
- */
115
- private _handleOpenFromState(): void {
116
- this._isOpen = true;
117
- this._performOpenTransition();
118
- }
119
-
120
- /**
121
- * Handle close state change from unified state manager
122
- */
123
- private _handleCloseFromState(): void {
124
- this._performCloseTransition();
125
- }
126
-
127
- /**
128
- * Perform the actual open transition
129
- */
130
- private _performOpenTransition(): void {
131
- if (this._isTransitioning) return;
132
-
133
- // Begin opening transition
134
- this._isTransitioning = true;
135
-
136
- // Set initial styles
137
- this._dropdownElement.classList.remove('hidden');
138
- this._dropdownElement.style.opacity = '0';
139
-
140
- // Set dropdown width
141
- this._setDropdownWidth();
142
-
143
- // Reflow
144
- KTDom.reflow(this._dropdownElement);
145
-
146
- // Apply z-index
147
- let zIndexToApply: number | null = null;
148
-
149
- if (this._config.dropdownZindex) {
150
- zIndexToApply = this._config.dropdownZindex;
151
- }
152
-
153
- // Consider the dropdown's current z-index if it's already set and higher
154
- const currentDropdownZIndexStr = KTDom.getCssProp(this._dropdownElement, 'z-index');
155
- if (currentDropdownZIndexStr && currentDropdownZIndexStr !== 'auto') {
156
- const currentDropdownZIndex = parseInt(currentDropdownZIndexStr);
157
- if (!isNaN(currentDropdownZIndex) && currentDropdownZIndex > (zIndexToApply || 0)) {
158
- zIndexToApply = currentDropdownZIndex;
159
- }
160
- }
161
-
162
- // Ensure dropdown is above elements within its original toggle's parent context
163
- const toggleParentContextZindex = KTDom.getHighestZindex(this._element);
164
- if (toggleParentContextZindex !== null && toggleParentContextZindex >= (zIndexToApply || 0)) {
165
- zIndexToApply = toggleParentContextZindex + 1;
166
- }
167
-
168
- if (zIndexToApply !== null) {
169
- this._dropdownElement.style.zIndex = zIndexToApply.toString();
170
- }
171
-
172
- // Initialize popper
173
- this._initPopper();
174
-
175
- // Add active classes for visual state
176
- this._dropdownElement.classList.add('open');
177
- this._toggleElement.classList.add('active');
178
-
179
- // Start transition
180
- this._dropdownElement.style.opacity = '1';
181
-
182
- // Handle transition end
183
- KTDom.transitionEnd(this._dropdownElement, () => {
184
- this._isTransitioning = false;
185
-
186
- // Notify unified state manager that transition is complete
187
- if (this._unifiedStateManager) {
188
- this._unifiedStateManager.setDropdownTransitioning(false, 'dropdown-transition-complete');
189
- }
190
- });
191
- }
192
-
193
- /**
194
- * Perform the actual close transition
195
- */
196
- private _performCloseTransition(): void {
197
- if (this._isTransitioning) return;
198
-
199
- this._isTransitioning = true;
200
- this._dropdownElement.style.opacity = '0';
201
-
202
- let transitionComplete = false;
203
- const fallbackTimer = setTimeout(() => {
204
- if (!transitionComplete) {
205
- transitionComplete = true;
206
- this._completeCloseTransition();
207
- }
208
- }, 300); // Fallback timeout
209
-
210
- const completeTransition = () => {
211
- if (!transitionComplete) {
212
- transitionComplete = true;
213
- clearTimeout(fallbackTimer);
214
- this._completeCloseTransition();
215
- }
216
- };
217
-
218
- KTDom.transitionEnd(this._dropdownElement, completeTransition);
219
- }
220
-
221
- /**
222
- * Complete the close transition
223
- */
224
- private _completeCloseTransition(): void {
225
- this._isTransitioning = false;
226
- this._isOpen = false;
227
-
228
- // Remove active classes
229
- this._dropdownElement.classList.remove('open');
230
- this._toggleElement.classList.remove('active');
231
-
232
- // Hide dropdown
233
- this._dropdownElement.classList.add('hidden');
234
-
235
- // Clean up popper
236
- this._destroyPopper();
237
-
238
- // Notify unified state manager that transition is complete
239
- if (this._unifiedStateManager) {
240
- this._unifiedStateManager.setDropdownTransitioning(false, 'dropdown-transition-complete');
241
- }
242
- }
243
-
244
- /**
245
- * Set dropdown width to match input wrapper element (matching ktselect behavior)
246
- * Dynamically calculates width based on visibleMonths for multi-month view
247
- */
248
- private _setDropdownWidth(): void {
249
- if (!this._dropdownElement || !this._element) return;
250
-
251
- // Find the input wrapper element to match its width
252
- const inputWrapper = this._element.querySelector('[data-kt-datepicker-input-wrapper]') as HTMLElement;
253
- if (!inputWrapper) return;
254
-
255
- // Get visible months count
256
- const visibleMonths = this._config.visibleMonths ?? 1;
257
-
258
- // Check if width is configured
259
- if (this._config.dropdownWidth) {
260
- // If custom width is set, use that
261
- if (this._config.dropdownWidth === 'auto') {
262
- // Try to measure the actual content width first (if already rendered)
263
- const multiMonthContainer = this._dropdownElement.querySelector('[data-kt-datepicker-multimonth-container]') as HTMLElement;
264
-
265
- if (multiMonthContainer && visibleMonths > 1) {
266
- // Content is already rendered, measure it
267
- // Force a reflow to ensure accurate measurement
268
- KTDom.reflow(multiMonthContainer);
269
-
270
- // Measure content width including gaps
271
- const contentWidth = multiMonthContainer.scrollWidth;
272
-
273
- // Add dropdown padding (px-3 = 12px on each side = 24px total)
274
- const padding = 24;
275
- const totalWidth = contentWidth + padding;
276
-
277
- this._dropdownElement.style.width = `${totalWidth}px`;
278
- this._dropdownElement.style.minWidth = `${totalWidth}px`;
279
- } else if (visibleMonths > 1) {
280
- // Content not yet rendered, calculate expected width
281
- // Base month width: 20rem (320px) per month
282
- // Gap between months: 1rem (16px) per gap (gap-4)
283
- // Padding: 0.75rem (12px) on each side = 1.5rem (24px) total
284
- const monthWidth = 320; // 20rem = 320px
285
- const gapWidth = 16; // 1rem = 16px (gap-4)
286
- const paddingWidth = 24; // 1.5rem = 24px (px-3 on each side)
287
-
288
- // Calculate total width: (n months * 320px) + ((n-1) gaps * 16px) + padding
289
- const totalWidth = (visibleMonths * monthWidth) + ((visibleMonths - 1) * gapWidth) + paddingWidth;
290
-
291
- this._dropdownElement.style.width = `${totalWidth}px`;
292
- this._dropdownElement.style.minWidth = `${totalWidth}px`;
293
- } else {
294
- // Single month: use auto (CSS default applies)
295
- this._dropdownElement.style.width = 'auto';
296
- this._dropdownElement.style.minWidth = 'auto';
297
- }
298
- } else if (typeof this._config.dropdownWidth === 'string') {
299
- this._dropdownElement.style.width = this._config.dropdownWidth;
300
- // Clear min-width when custom width is set
301
- this._dropdownElement.style.minWidth = '';
302
- }
303
- } else {
304
- // Otherwise, match input wrapper width for a cleaner appearance (like ktselect)
305
- const inputWrapperWidth = inputWrapper.offsetWidth;
306
- this._dropdownElement.style.width = `${inputWrapperWidth}px`;
307
- // Clear min-width to ensure input wrapper width takes precedence
308
- this._dropdownElement.style.minWidth = '';
309
- }
310
- }
311
-
312
- /**
313
- * Detect if the datepicker is inside a modal container
314
- * @returns The modal element if found, null otherwise
315
- */
316
- private _getModalContainer(): HTMLElement | null {
317
- return this._element.closest(
318
- '[data-kt-modal], .kt-modal, .kt-modal-center',
319
- ) as HTMLElement | null;
320
- }
321
-
322
- /**
323
- * Get the appropriate boundary element for Popper positioning
324
- * For centered modals, use .kt-modal-content to avoid transform calculation issues
325
- * @returns The boundary element, or null if no modal found
326
- */
327
- private _getModalBoundary(): HTMLElement | null {
328
- const modalParent = this._getModalContainer();
329
- if (!modalParent) {
330
- return null;
331
- }
332
-
333
- // For centered modals, use .kt-modal-content as boundary to avoid transform issues
334
- if (modalParent.classList.contains('kt-modal-center')) {
335
- const modalContent = modalParent.querySelector(
336
- '.kt-modal-content',
337
- ) as HTMLElement | null;
338
- return modalContent || modalParent;
339
- }
340
-
341
- // For non-centered modals, use the modal element itself
342
- return modalParent;
343
- }
344
-
345
- /**
346
- * Get the appropriate positioning strategy based on context
347
- * @returns 'fixed' if inside non-centered modal, 'absolute' for centered modals or no modal
348
- */
349
- private _getPositioningStrategy(): 'fixed' | 'absolute' {
350
- // Check if config explicitly sets strategy
351
- if (this._config.dropdownStrategy) {
352
- return this._config.dropdownStrategy as 'fixed' | 'absolute';
353
- }
354
-
355
- // For centered modals, use absolute positioning to avoid transform calculation issues
356
- // For non-centered modals, use fixed positioning
357
- const modalParent = this._getModalContainer();
358
- if (modalParent && modalParent.classList.contains('kt-modal-center')) {
359
- return 'absolute';
360
- }
361
-
362
- // Use fixed positioning for non-centered modals
363
- return modalParent ? 'fixed' : 'absolute';
364
- }
365
-
366
- /**
367
- * Get the reference element for Popper positioning (calendar button/icon)
368
- */
369
- private _getPopperReferenceElement(): HTMLElement {
370
- // Use calendar button (toggle element) for positioning - dropdown sticks under the icon
371
- return this._toggleElement;
372
- }
373
-
374
- /**
375
- * Initialize Popper.js for positioning
376
- */
377
- private _initPopper(): void {
378
- if (this._popperInstance) {
379
- this._popperInstance.destroy();
380
- }
381
-
382
- // Default offset - matching ktselect
383
- const offsetValue = this._config.dropdownOffset || '0, 5';
384
-
385
- // Get configuration options
386
- const placement = (this._config.dropdownPlacement as Placement) || 'bottom-start';
387
- const strategy = this._getPositioningStrategy();
388
- const preventOverflow = this._config.dropdownPreventOverflow !== false;
389
- const flip = this._config.dropdownFlip !== false;
390
-
391
- // Get appropriate boundary element for modal context
392
- const boundary = this._getModalBoundary() || this._config.dropdownBoundary || 'clippingParents';
393
-
394
- // Get reference element for positioning (input wrapper, not the calendar button)
395
- const referenceElement = this._getPopperReferenceElement();
396
-
397
- // Create new popper instance
398
- this._popperInstance = createPopper(
399
- referenceElement,
400
- this._dropdownElement,
401
- {
402
- placement: placement,
403
- strategy: strategy,
404
- modifiers: [
405
- {
406
- name: 'offset',
407
- options: {
408
- offset: this._parseOffset(offsetValue),
409
- },
410
- },
411
- {
412
- name: 'preventOverflow',
413
- options: {
414
- boundary: boundary,
415
- altAxis: preventOverflow,
416
- },
417
- },
418
- {
419
- name: 'flip',
420
- options: {
421
- enabled: flip,
422
- fallbackPlacements: ['top-start', 'bottom-end', 'top-end'],
423
- },
424
- },
425
- {
426
- name: 'sameWidth',
427
- enabled: !this._config.dropdownWidth, // Enable when dropdownWidth is null/undefined (matching ktselect)
428
- phase: 'beforeWrite',
429
- requires: ['computeStyles'],
430
- fn: ({ state }) => {
431
- // Use input wrapper width instead of toggle element width
432
- const inputWrapper = this._element.querySelector('[data-kt-datepicker-input-wrapper]') as HTMLElement;
433
- if (inputWrapper) {
434
- state.styles.popper.width = `${inputWrapper.offsetWidth}px`;
435
- } else {
436
- // Fallback to reference width if input wrapper not found
437
- state.styles.popper.width = `${state.rects.reference.width}px`;
438
- }
439
- },
440
- effect: ({ state }) => {
441
- // Use input wrapper width instead of toggle element width
442
- const inputWrapper = this._element.querySelector('[data-kt-datepicker-input-wrapper]') as HTMLElement;
443
- if (inputWrapper && 'offsetWidth' in inputWrapper) {
444
- state.elements.popper.style.width = `${inputWrapper.offsetWidth}px`;
445
- } else {
446
- // Fallback to reference width if input wrapper not found
447
- const reference = state.elements.reference as HTMLElement;
448
- if (reference && 'offsetWidth' in reference) {
449
- state.elements.popper.style.width = `${reference.offsetWidth}px`;
450
- }
451
- }
452
- },
453
- },
454
- ],
455
- },
456
- );
457
- }
458
-
459
- /**
460
- * Parse offset string to array
461
- */
462
- private _parseOffset(offset: string): number[] {
463
- return offset.split(',').map((val) => parseInt(val.trim(), 10));
464
- }
465
-
466
- /**
467
- * Destroy Popper instance
468
- */
469
- private _destroyPopper(): void {
470
- if (this._popperInstance) {
471
- this._popperInstance.destroy();
472
- this._popperInstance = null;
473
- }
474
- }
475
-
476
- /**
477
- * Update dropdown position
478
- */
479
- public updatePosition(): void {
480
- if (this._popperInstance) {
481
- this._popperInstance.update();
482
- }
483
- }
484
-
485
- /**
486
- * Update dropdown width (useful after content is rendered)
487
- */
488
- public updateWidth(): void {
489
- this._setDropdownWidth();
490
- // Also update popper position after width change
491
- if (this._popperInstance) {
492
- this._popperInstance.update();
493
- }
494
- }
495
-
496
- /**
497
- * Open the dropdown (legacy method - now handled by observer pattern)
498
- */
499
- public open(): void {
500
- // This method is now deprecated - use unified state manager instead
501
- if (this._unifiedStateManager) {
502
- this._unifiedStateManager.setDropdownOpen(true, 'legacy-open-method');
503
- }
504
- }
505
-
506
- /**
507
- * Close the dropdown (legacy method - now handled by observer pattern)
508
- */
509
- public close(): void {
510
- // This method is now deprecated - use unified state manager instead
511
- if (this._unifiedStateManager) {
512
- this._unifiedStateManager.setDropdownOpen(false, 'legacy-close-method');
513
- }
514
- }
515
-
516
- /**
517
- * Check if dropdown is open
518
- */
519
- public isOpen(): boolean {
520
- return this._isOpen;
521
- }
522
-
523
- /**
524
- * Dispose of the dropdown
525
- */
526
- public override dispose(): void {
527
- // Clean up event listeners
528
- this._eventManager.removeAllListeners(document as unknown as HTMLElement);
529
- this._destroyPopper();
530
-
531
- // Remove dropdown from DOM
532
- if (this._dropdownElement && this._dropdownElement.parentElement) {
533
- this._dropdownElement.parentElement.removeChild(this._dropdownElement);
534
- }
535
- }
536
-
537
- /**
538
- * Resolve the container for the dropdown
539
- */
540
- private _resolveDropdownContainer(): HTMLElement | null {
541
- // Check if dropdown should be rendered in a specific container
542
- if (this._config.dropdownContainer) {
543
- const container = document.querySelector(this._config.dropdownContainer);
544
- if (container instanceof HTMLElement) {
545
- return container;
546
- }
547
- }
548
-
549
- // Default to body for better positioning
550
- return document.body;
551
- }
552
- }
@@ -1,7 +0,0 @@
1
- /*
2
- * ui/input/index.ts - Input module exports
3
- * Provides input-related components for KTDatepicker
4
- */
5
-
6
- export * from './segmented-input';
7
- export * from './dropdown';