@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.
- package/README.md +0 -27
- package/dist/ktui.js +5269 -12550
- package/dist/ktui.min.js +1 -1
- package/dist/ktui.min.js.map +1 -1
- package/dist/styles.css +1133 -2706
- package/lib/cjs/components/datatable/__tests__/pagination-reset.test.js +596 -0
- package/lib/cjs/components/datatable/__tests__/pagination-reset.test.js.map +1 -0
- package/lib/cjs/components/datatable/__tests__/race-conditions.test.js +548 -0
- package/lib/cjs/components/datatable/__tests__/race-conditions.test.js.map +1 -0
- package/lib/cjs/components/datatable/__tests__/setup.js +63 -0
- package/lib/cjs/components/datatable/__tests__/setup.js.map +1 -0
- package/lib/cjs/components/datatable/datatable.js +92 -30
- package/lib/cjs/components/datatable/datatable.js.map +1 -1
- package/lib/cjs/components/select/combobox.js +0 -2
- package/lib/cjs/components/select/combobox.js.map +1 -1
- package/lib/cjs/components/select/config.js +4 -1
- package/lib/cjs/components/select/config.js.map +1 -1
- package/lib/cjs/components/select/dropdown.js +0 -16
- package/lib/cjs/components/select/dropdown.js.map +1 -1
- package/lib/cjs/components/select/remote.js +0 -40
- package/lib/cjs/components/select/remote.js.map +1 -1
- package/lib/cjs/components/select/search.js +80 -19
- package/lib/cjs/components/select/search.js.map +1 -1
- package/lib/cjs/components/select/select.js +98 -110
- package/lib/cjs/components/select/select.js.map +1 -1
- package/lib/cjs/components/select/tags.js +0 -2
- package/lib/cjs/components/select/tags.js.map +1 -1
- package/lib/cjs/index.js +1 -10
- package/lib/cjs/index.js.map +1 -1
- package/lib/esm/components/datatable/__tests__/pagination-reset.test.js +594 -0
- package/lib/esm/components/datatable/__tests__/pagination-reset.test.js.map +1 -0
- package/lib/esm/components/datatable/__tests__/race-conditions.test.js +546 -0
- package/lib/esm/components/datatable/__tests__/race-conditions.test.js.map +1 -0
- package/lib/esm/components/datatable/__tests__/setup.js +58 -0
- package/lib/esm/components/datatable/__tests__/setup.js.map +1 -0
- package/lib/esm/components/datatable/datatable.js +92 -30
- package/lib/esm/components/datatable/datatable.js.map +1 -1
- package/lib/esm/components/select/combobox.js +0 -2
- package/lib/esm/components/select/combobox.js.map +1 -1
- package/lib/esm/components/select/config.js +4 -1
- package/lib/esm/components/select/config.js.map +1 -1
- package/lib/esm/components/select/dropdown.js +0 -16
- package/lib/esm/components/select/dropdown.js.map +1 -1
- package/lib/esm/components/select/remote.js +0 -40
- package/lib/esm/components/select/remote.js.map +1 -1
- package/lib/esm/components/select/search.js +80 -19
- package/lib/esm/components/select/search.js.map +1 -1
- package/lib/esm/components/select/select.js +98 -110
- package/lib/esm/components/select/select.js.map +1 -1
- package/lib/esm/components/select/tags.js +0 -2
- package/lib/esm/components/select/tags.js.map +1 -1
- package/lib/esm/index.js +0 -7
- package/lib/esm/index.js.map +1 -1
- package/package.json +7 -9
- package/src/components/alert/alert.css +188 -429
- package/src/components/datatable/__tests__/pagination-reset.test.ts +657 -0
- package/src/components/datatable/__tests__/race-conditions.test.ts +455 -0
- package/src/components/datatable/__tests__/setup.ts +67 -0
- package/src/components/datatable/datatable.ts +66 -11
- package/src/components/input/input.css +0 -1
- package/src/components/select/__tests__/ux-behaviors.test.ts +619 -0
- package/src/components/select/combobox.ts +0 -1
- package/src/components/select/config.ts +7 -1
- package/src/components/select/dropdown.ts +0 -24
- package/src/components/select/remote.ts +0 -49
- package/src/components/select/search.ts +85 -21
- package/src/components/select/select.css +0 -1
- package/src/components/select/select.ts +118 -149
- package/src/components/select/tags.ts +0 -1
- package/src/components/select/variants.css +4 -0
- package/src/components/textarea/textarea.css +0 -1
- package/src/index.ts +0 -10
- package/styles.css +0 -1
- package/lib/cjs/components/alert/alert.js +0 -1025
- package/lib/cjs/components/alert/alert.js.map +0 -1
- package/lib/cjs/components/alert/index.js +0 -20
- package/lib/cjs/components/alert/index.js.map +0 -1
- package/lib/cjs/components/alert/templates.js +0 -120
- package/lib/cjs/components/alert/templates.js.map +0 -1
- package/lib/cjs/components/alert/types.js +0 -7
- package/lib/cjs/components/alert/types.js.map +0 -1
- package/lib/cjs/components/datepicker/config/config.js +0 -42
- package/lib/cjs/components/datepicker/config/config.js.map +0 -1
- package/lib/cjs/components/datepicker/config/index.js +0 -24
- package/lib/cjs/components/datepicker/config/index.js.map +0 -1
- package/lib/cjs/components/datepicker/config/interfaces.js +0 -7
- package/lib/cjs/components/datepicker/config/interfaces.js.map +0 -1
- package/lib/cjs/components/datepicker/config/types.js +0 -7
- package/lib/cjs/components/datepicker/config/types.js.map +0 -1
- package/lib/cjs/components/datepicker/core/event-manager.js +0 -135
- package/lib/cjs/components/datepicker/core/event-manager.js.map +0 -1
- package/lib/cjs/components/datepicker/core/focus-manager.js +0 -167
- package/lib/cjs/components/datepicker/core/focus-manager.js.map +0 -1
- package/lib/cjs/components/datepicker/core/helpers.js +0 -219
- package/lib/cjs/components/datepicker/core/helpers.js.map +0 -1
- package/lib/cjs/components/datepicker/core/index.js +0 -25
- package/lib/cjs/components/datepicker/core/index.js.map +0 -1
- package/lib/cjs/components/datepicker/core/unified-state-manager.js +0 -394
- package/lib/cjs/components/datepicker/core/unified-state-manager.js.map +0 -1
- package/lib/cjs/components/datepicker/datepicker.js +0 -2252
- package/lib/cjs/components/datepicker/datepicker.js.map +0 -1
- package/lib/cjs/components/datepicker/index.js +0 -24
- package/lib/cjs/components/datepicker/index.js.map +0 -1
- package/lib/cjs/components/datepicker/ui/index.js +0 -23
- package/lib/cjs/components/datepicker/ui/index.js.map +0 -1
- package/lib/cjs/components/datepicker/ui/input/dropdown.js +0 -489
- package/lib/cjs/components/datepicker/ui/input/dropdown.js.map +0 -1
- package/lib/cjs/components/datepicker/ui/input/index.js +0 -23
- package/lib/cjs/components/datepicker/ui/input/index.js.map +0 -1
- package/lib/cjs/components/datepicker/ui/input/segmented-input.js +0 -640
- package/lib/cjs/components/datepicker/ui/input/segmented-input.js.map +0 -1
- package/lib/cjs/components/datepicker/ui/renderers/calendar.js +0 -446
- package/lib/cjs/components/datepicker/ui/renderers/calendar.js.map +0 -1
- package/lib/cjs/components/datepicker/ui/renderers/footer.js +0 -42
- package/lib/cjs/components/datepicker/ui/renderers/footer.js.map +0 -1
- package/lib/cjs/components/datepicker/ui/renderers/header.js +0 -32
- package/lib/cjs/components/datepicker/ui/renderers/header.js.map +0 -1
- package/lib/cjs/components/datepicker/ui/renderers/index.js +0 -25
- package/lib/cjs/components/datepicker/ui/renderers/index.js.map +0 -1
- package/lib/cjs/components/datepicker/ui/renderers/time-picker.js +0 -384
- package/lib/cjs/components/datepicker/ui/renderers/time-picker.js.map +0 -1
- package/lib/cjs/components/datepicker/ui/templates/index.js +0 -22
- package/lib/cjs/components/datepicker/ui/templates/index.js.map +0 -1
- package/lib/cjs/components/datepicker/ui/templates/templates.js +0 -253
- package/lib/cjs/components/datepicker/ui/templates/templates.js.map +0 -1
- package/lib/cjs/components/datepicker/utils/date-formatters.js +0 -88
- package/lib/cjs/components/datepicker/utils/date-formatters.js.map +0 -1
- package/lib/cjs/components/datepicker/utils/date-utils.js +0 -194
- package/lib/cjs/components/datepicker/utils/date-utils.js.map +0 -1
- package/lib/cjs/components/datepicker/utils/index.js +0 -24
- package/lib/cjs/components/datepicker/utils/index.js.map +0 -1
- package/lib/cjs/components/datepicker/utils/time-utils.js +0 -213
- package/lib/cjs/components/datepicker/utils/time-utils.js.map +0 -1
- package/lib/esm/components/alert/alert.js +0 -1022
- package/lib/esm/components/alert/alert.js.map +0 -1
- package/lib/esm/components/alert/index.js +0 -4
- package/lib/esm/components/alert/index.js.map +0 -1
- package/lib/esm/components/alert/templates.js +0 -112
- package/lib/esm/components/alert/templates.js.map +0 -1
- package/lib/esm/components/alert/types.js +0 -6
- package/lib/esm/components/alert/types.js.map +0 -1
- package/lib/esm/components/datepicker/config/config.js +0 -39
- package/lib/esm/components/datepicker/config/config.js.map +0 -1
- package/lib/esm/components/datepicker/config/index.js +0 -8
- package/lib/esm/components/datepicker/config/index.js.map +0 -1
- package/lib/esm/components/datepicker/config/interfaces.js +0 -6
- package/lib/esm/components/datepicker/config/interfaces.js.map +0 -1
- package/lib/esm/components/datepicker/config/types.js +0 -6
- package/lib/esm/components/datepicker/config/types.js.map +0 -1
- package/lib/esm/components/datepicker/core/event-manager.js +0 -133
- package/lib/esm/components/datepicker/core/event-manager.js.map +0 -1
- package/lib/esm/components/datepicker/core/focus-manager.js +0 -164
- package/lib/esm/components/datepicker/core/focus-manager.js.map +0 -1
- package/lib/esm/components/datepicker/core/helpers.js +0 -211
- package/lib/esm/components/datepicker/core/helpers.js.map +0 -1
- package/lib/esm/components/datepicker/core/index.js +0 -9
- package/lib/esm/components/datepicker/core/index.js.map +0 -1
- package/lib/esm/components/datepicker/core/unified-state-manager.js +0 -391
- package/lib/esm/components/datepicker/core/unified-state-manager.js.map +0 -1
- package/lib/esm/components/datepicker/datepicker.js +0 -2248
- package/lib/esm/components/datepicker/datepicker.js.map +0 -1
- package/lib/esm/components/datepicker/index.js +0 -7
- package/lib/esm/components/datepicker/index.js.map +0 -1
- package/lib/esm/components/datepicker/ui/index.js +0 -7
- package/lib/esm/components/datepicker/ui/index.js.map +0 -1
- package/lib/esm/components/datepicker/ui/input/dropdown.js +0 -486
- package/lib/esm/components/datepicker/ui/input/dropdown.js.map +0 -1
- package/lib/esm/components/datepicker/ui/input/index.js +0 -7
- package/lib/esm/components/datepicker/ui/input/index.js.map +0 -1
- package/lib/esm/components/datepicker/ui/input/segmented-input.js +0 -637
- package/lib/esm/components/datepicker/ui/input/segmented-input.js.map +0 -1
- package/lib/esm/components/datepicker/ui/renderers/calendar.js +0 -443
- package/lib/esm/components/datepicker/ui/renderers/calendar.js.map +0 -1
- package/lib/esm/components/datepicker/ui/renderers/footer.js +0 -39
- package/lib/esm/components/datepicker/ui/renderers/footer.js.map +0 -1
- package/lib/esm/components/datepicker/ui/renderers/header.js +0 -29
- package/lib/esm/components/datepicker/ui/renderers/header.js.map +0 -1
- package/lib/esm/components/datepicker/ui/renderers/index.js +0 -9
- package/lib/esm/components/datepicker/ui/renderers/index.js.map +0 -1
- package/lib/esm/components/datepicker/ui/renderers/time-picker.js +0 -381
- package/lib/esm/components/datepicker/ui/renderers/time-picker.js.map +0 -1
- package/lib/esm/components/datepicker/ui/templates/index.js +0 -6
- package/lib/esm/components/datepicker/ui/templates/index.js.map +0 -1
- package/lib/esm/components/datepicker/ui/templates/templates.js +0 -242
- package/lib/esm/components/datepicker/ui/templates/templates.js.map +0 -1
- package/lib/esm/components/datepicker/utils/date-formatters.js +0 -83
- package/lib/esm/components/datepicker/utils/date-formatters.js.map +0 -1
- package/lib/esm/components/datepicker/utils/date-utils.js +0 -184
- package/lib/esm/components/datepicker/utils/date-utils.js.map +0 -1
- package/lib/esm/components/datepicker/utils/index.js +0 -8
- package/lib/esm/components/datepicker/utils/index.js.map +0 -1
- package/lib/esm/components/datepicker/utils/time-utils.js +0 -201
- package/lib/esm/components/datepicker/utils/time-utils.js.map +0 -1
- package/src/components/alert/alert.ts +0 -990
- package/src/components/alert/index.ts +0 -4
- package/src/components/alert/templates.ts +0 -110
- package/src/components/alert/tests/accessibility/aria-roles.test.ts +0 -19
- package/src/components/alert/tests/accessibility/focus-management.test.ts +0 -19
- package/src/components/alert/tests/accessibility/keyboard-nav.test.ts +0 -22
- package/src/components/alert/tests/actions/confirm-cancel.test.ts +0 -122
- package/src/components/alert/tests/actions/input-field.test.ts +0 -180
- package/src/components/alert/tests/alert.basic.test.ts +0 -126
- package/src/components/alert/tests/alert.config.test.ts +0 -75
- package/src/components/alert/tests/alert.templates.test.ts +0 -17
- package/src/components/alert/tests/config/attribute-config.test.ts +0 -94
- package/src/components/alert/tests/config/json-config.test.ts +0 -119
- package/src/components/alert/tests/config/merging.test.ts +0 -89
- package/src/components/alert/tests/dismissal/auto-dismiss.test.ts +0 -96
- package/src/components/alert/tests/dismissal/escape-key-dismiss.test.ts +0 -105
- package/src/components/alert/tests/dismissal/manual-dismiss.test.ts +0 -90
- package/src/components/alert/tests/dismissal/outside-click-dismiss.test.ts +0 -91
- package/src/components/alert/tests/edge-cases/invalid-config.test.ts +0 -19
- package/src/components/alert/tests/edge-cases/multiple-alerts.test.ts +0 -19
- package/src/components/alert/tests/rendering/custom-content.test.ts +0 -81
- package/src/components/alert/tests/rendering/info-alert.test.ts +0 -84
- package/src/components/alert/tests/rendering/success-alert.test.ts +0 -100
- package/src/components/alert/tests/templates/default-templates.test.ts +0 -16
- package/src/components/alert/tests/templates/user-templates.test.ts +0 -16
- package/src/components/alert/types.ts +0 -145
- package/src/components/datepicker/__tests__/datepicker-events.test.ts +0 -356
- package/src/components/datepicker/__tests__/datepicker-init.test.ts +0 -343
- package/src/components/datepicker/__tests__/datepicker-integration.test.ts +0 -435
- package/src/components/datepicker/__tests__/datepicker-timezone.test.ts +0 -220
- package/src/components/datepicker/__tests__/segmented-input-focus.test.ts +0 -380
- package/src/components/datepicker/__tests__/selective-state-updates.test.ts +0 -400
- package/src/components/datepicker/__tests__/state-manager.test.ts +0 -421
- package/src/components/datepicker/__tests__/time-preservation.test.ts +0 -387
- package/src/components/datepicker/config/config.ts +0 -40
- package/src/components/datepicker/config/index.ts +0 -8
- package/src/components/datepicker/config/interfaces.ts +0 -82
- package/src/components/datepicker/config/types.ts +0 -188
- package/src/components/datepicker/core/event-manager.ts +0 -159
- package/src/components/datepicker/core/focus-manager.ts +0 -201
- package/src/components/datepicker/core/helpers.ts +0 -231
- package/src/components/datepicker/core/index.ts +0 -9
- package/src/components/datepicker/core/unified-state-manager.ts +0 -459
- package/src/components/datepicker/datepicker.css +0 -435
- package/src/components/datepicker/datepicker.ts +0 -2548
- package/src/components/datepicker/index.ts +0 -8
- package/src/components/datepicker/ui/index.ts +0 -7
- package/src/components/datepicker/ui/input/dropdown.ts +0 -552
- package/src/components/datepicker/ui/input/index.ts +0 -7
- package/src/components/datepicker/ui/input/segmented-input.ts +0 -638
- package/src/components/datepicker/ui/renderers/__tests__/calendar-optimizations.test.ts +0 -611
- package/src/components/datepicker/ui/renderers/calendar.ts +0 -530
- package/src/components/datepicker/ui/renderers/footer.ts +0 -43
- package/src/components/datepicker/ui/renderers/header.ts +0 -33
- package/src/components/datepicker/ui/renderers/index.ts +0 -9
- package/src/components/datepicker/ui/renderers/time-picker.ts +0 -438
- package/src/components/datepicker/ui/templates/index.ts +0 -6
- package/src/components/datepicker/ui/templates/templates.ts +0 -306
- package/src/components/datepicker/utils/__tests__/date-formatters.test.ts +0 -160
- package/src/components/datepicker/utils/__tests__/date-utils-keys.test.ts +0 -86
- package/src/components/datepicker/utils/__tests__/date-utils-timezone.test.ts +0 -215
- package/src/components/datepicker/utils/date-formatters.ts +0 -85
- package/src/components/datepicker/utils/date-utils.ts +0 -172
- package/src/components/datepicker/utils/index.ts +0 -8
- package/src/components/datepicker/utils/time-utils.ts +0 -221
|
@@ -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
|
-
}
|