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