@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.
- package/README.md +0 -27
- package/dist/ktui.js +6790 -14063
- package/dist/ktui.min.js +1 -1
- package/dist/ktui.min.js.map +1 -1
- package/dist/styles.css +1132 -2705
- 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/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/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/select.css +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,438 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* time-picker.ts - Time picker renderer for KTDatepicker
|
|
3
|
-
* Provides time picker UI components with increment/decrement controls.
|
|
4
|
-
* Uses unified template system for consistent rendering.
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import { TimeState } from '../../config/types';
|
|
8
|
-
import { formatTime, validateTime } from '../../utils/time-utils';
|
|
9
|
-
import { createTemplateRenderer } from '../../ui/templates/templates';
|
|
10
|
-
import { KTDatepickerTemplateStrings } from '../../config/types';
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* Options for rendering time picker
|
|
14
|
-
*/
|
|
15
|
-
export interface TimePickerOptions {
|
|
16
|
-
time: TimeState;
|
|
17
|
-
granularity: 'second' | 'minute' | 'hour';
|
|
18
|
-
format: '12h' | '24h';
|
|
19
|
-
minTime?: string;
|
|
20
|
-
maxTime?: string;
|
|
21
|
-
timeStep?: number;
|
|
22
|
-
disabled?: boolean;
|
|
23
|
-
onChange?: (time: TimeState) => void;
|
|
24
|
-
templates?: KTDatepickerTemplateStrings;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* Render time picker component
|
|
29
|
-
* @param container Container element
|
|
30
|
-
* @param options Time picker options
|
|
31
|
-
* @returns Object with cleanup function and update function
|
|
32
|
-
*/
|
|
33
|
-
export function renderTimePicker(container: HTMLElement, options: TimePickerOptions): { cleanup: () => void; update: (newTime: TimeState) => void } {
|
|
34
|
-
const { time, granularity, format, minTime, maxTime, timeStep = 1, disabled = false, onChange, templates } = options;
|
|
35
|
-
|
|
36
|
-
// Initialize template renderer
|
|
37
|
-
const templateRenderer = createTemplateRenderer(templates || {});
|
|
38
|
-
|
|
39
|
-
// Clear container
|
|
40
|
-
container.innerHTML = '';
|
|
41
|
-
|
|
42
|
-
// Current time state (will be updated)
|
|
43
|
-
let currentTime = { ...time };
|
|
44
|
-
|
|
45
|
-
// Store references to updateable elements
|
|
46
|
-
const updateableElements: { [key: string]: HTMLElement } = {};
|
|
47
|
-
|
|
48
|
-
// Create increment/decrement buttons for each time unit
|
|
49
|
-
const timeUnits = getTimeUnits(granularity);
|
|
50
|
-
|
|
51
|
-
// Build time units HTML using templates
|
|
52
|
-
let timeUnitsHtml = '';
|
|
53
|
-
timeUnits.forEach((unit, index) => {
|
|
54
|
-
// Render time unit using template
|
|
55
|
-
const unitHtml = templateRenderer.renderTemplateString({
|
|
56
|
-
templateKey: 'timeUnit',
|
|
57
|
-
data: {
|
|
58
|
-
unitType: unit,
|
|
59
|
-
upButton: templateRenderer.renderTemplateString({
|
|
60
|
-
templateKey: 'timeUpButton',
|
|
61
|
-
data: {
|
|
62
|
-
unitType: unit,
|
|
63
|
-
disabled: disabled ? 'disabled' : ''
|
|
64
|
-
}
|
|
65
|
-
}),
|
|
66
|
-
valueDisplay: templateRenderer.renderTemplateString({
|
|
67
|
-
templateKey: 'timeValue',
|
|
68
|
-
data: {
|
|
69
|
-
value: getTimeUnitValue(currentTime, unit, format)
|
|
70
|
-
}
|
|
71
|
-
}),
|
|
72
|
-
downButton: templateRenderer.renderTemplateString({
|
|
73
|
-
templateKey: 'timeDownButton',
|
|
74
|
-
data: {
|
|
75
|
-
unitType: unit,
|
|
76
|
-
disabled: disabled ? 'disabled' : ''
|
|
77
|
-
}
|
|
78
|
-
})
|
|
79
|
-
}
|
|
80
|
-
});
|
|
81
|
-
|
|
82
|
-
timeUnitsHtml += unitHtml;
|
|
83
|
-
|
|
84
|
-
// Add separator between units (except after last unit)
|
|
85
|
-
if (index < timeUnits.length - 1) {
|
|
86
|
-
timeUnitsHtml += templateRenderer.renderTemplateString({
|
|
87
|
-
templateKey: 'timeSeparator',
|
|
88
|
-
data: { separator: ':' }
|
|
89
|
-
});
|
|
90
|
-
}
|
|
91
|
-
});
|
|
92
|
-
|
|
93
|
-
// Render time controls with units
|
|
94
|
-
const timeControlsHtml = templateRenderer.renderTemplateString({
|
|
95
|
-
templateKey: 'timeControls',
|
|
96
|
-
data: {
|
|
97
|
-
timeUnits: timeUnitsHtml,
|
|
98
|
-
ampmControl: format === '12h' ? templateRenderer.renderTemplateString({
|
|
99
|
-
templateKey: 'ampmControl',
|
|
100
|
-
data: {
|
|
101
|
-
ampmButton: templateRenderer.renderTemplateString({
|
|
102
|
-
templateKey: 'ampmButton',
|
|
103
|
-
data: {
|
|
104
|
-
ampmValue: currentTime.hour >= 12 ? 'PM' : 'AM',
|
|
105
|
-
disabled: disabled ? 'disabled' : ''
|
|
106
|
-
}
|
|
107
|
-
})
|
|
108
|
-
}
|
|
109
|
-
}) : ''
|
|
110
|
-
}
|
|
111
|
-
});
|
|
112
|
-
|
|
113
|
-
// Render time display
|
|
114
|
-
const timeDisplayHtml = templateRenderer.renderTemplateString({
|
|
115
|
-
templateKey: 'timeDisplay',
|
|
116
|
-
data: {
|
|
117
|
-
timeValue: formatTime(currentTime, granularity, format)
|
|
118
|
-
}
|
|
119
|
-
});
|
|
120
|
-
|
|
121
|
-
// Render complete time picker wrapper
|
|
122
|
-
const timePickerHtml = templateRenderer.renderTemplateString({
|
|
123
|
-
templateKey: 'timePickerWrapper',
|
|
124
|
-
data: {
|
|
125
|
-
timeDisplay: timeDisplayHtml,
|
|
126
|
-
timeControls: timeControlsHtml
|
|
127
|
-
}
|
|
128
|
-
});
|
|
129
|
-
|
|
130
|
-
// Insert rendered HTML into container
|
|
131
|
-
container.innerHTML = timePickerHtml;
|
|
132
|
-
|
|
133
|
-
// Get references to elements for event handling
|
|
134
|
-
const timeDisplay = container.querySelector('[data-kt-datepicker-time-display]') as HTMLElement;
|
|
135
|
-
|
|
136
|
-
// Add event listeners to time unit buttons
|
|
137
|
-
timeUnits.forEach((unit) => {
|
|
138
|
-
const upButton = container.querySelector(`[data-kt-datepicker-time-up][aria-label="Increment ${unit}"]`) as HTMLButtonElement;
|
|
139
|
-
const downButton = container.querySelector(`[data-kt-datepicker-time-down][aria-label="Decrement ${unit}"]`) as HTMLButtonElement;
|
|
140
|
-
const valueDisplay = container.querySelector(`[data-kt-datepicker-time-unit="${unit}"] [data-kt-datepicker-time-value]`) as HTMLElement;
|
|
141
|
-
|
|
142
|
-
// Store reference for updates
|
|
143
|
-
updateableElements[`${unit}Value`] = valueDisplay;
|
|
144
|
-
|
|
145
|
-
// Add event listeners with UI update
|
|
146
|
-
upButton.addEventListener('click', () => {
|
|
147
|
-
if (!disabled && onChange) {
|
|
148
|
-
const newTime = incrementTimeUnit(currentTime, unit, timeStep, format);
|
|
149
|
-
|
|
150
|
-
const validation = validateTime(newTime, minTime, maxTime);
|
|
151
|
-
|
|
152
|
-
if (validation.isValid) {
|
|
153
|
-
// Update current time state
|
|
154
|
-
currentTime = newTime;
|
|
155
|
-
// Update UI immediately
|
|
156
|
-
updateTimeDisplay(currentTime, updateableElements, timeDisplay, granularity, format);
|
|
157
|
-
// Call onChange callback
|
|
158
|
-
onChange(currentTime);
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
});
|
|
162
|
-
|
|
163
|
-
downButton.addEventListener('click', () => {
|
|
164
|
-
if (!disabled && onChange) {
|
|
165
|
-
const newTime = decrementTimeUnit(currentTime, unit, timeStep, format);
|
|
166
|
-
|
|
167
|
-
const validation = validateTime(newTime, minTime, maxTime);
|
|
168
|
-
|
|
169
|
-
if (validation.isValid) {
|
|
170
|
-
// Update current time state
|
|
171
|
-
currentTime = newTime;
|
|
172
|
-
// Update UI immediately
|
|
173
|
-
updateTimeDisplay(currentTime, updateableElements, timeDisplay, granularity, format);
|
|
174
|
-
// Call onChange callback
|
|
175
|
-
onChange(currentTime);
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
});
|
|
179
|
-
});
|
|
180
|
-
|
|
181
|
-
// Add AM/PM toggle for 12-hour format
|
|
182
|
-
if (format === '12h') {
|
|
183
|
-
const ampmButton = container.querySelector('[data-kt-datepicker-ampm-button]') as HTMLButtonElement;
|
|
184
|
-
|
|
185
|
-
ampmButton.addEventListener('click', () => {
|
|
186
|
-
if (!disabled && onChange) {
|
|
187
|
-
const newTime = { ...currentTime };
|
|
188
|
-
if (newTime.hour >= 12) {
|
|
189
|
-
newTime.hour = newTime.hour - 12;
|
|
190
|
-
} else {
|
|
191
|
-
newTime.hour = newTime.hour + 12;
|
|
192
|
-
}
|
|
193
|
-
if (validateTime(newTime, minTime, maxTime).isValid) {
|
|
194
|
-
// Update current time state
|
|
195
|
-
currentTime = newTime;
|
|
196
|
-
// Update UI immediately
|
|
197
|
-
updateTimeDisplay(currentTime, updateableElements, timeDisplay, granularity, format);
|
|
198
|
-
// Update AM/PM button text
|
|
199
|
-
ampmButton.textContent = currentTime.hour >= 12 ? 'PM' : 'AM';
|
|
200
|
-
// Call onChange callback
|
|
201
|
-
onChange(currentTime);
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
});
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
// Add keyboard navigation for time picker
|
|
208
|
-
container.addEventListener('keydown', (e) => {
|
|
209
|
-
if (disabled) return;
|
|
210
|
-
|
|
211
|
-
// Handle arrow up/down for time units
|
|
212
|
-
if (e.key === 'ArrowUp' || e.key === 'ArrowDown') {
|
|
213
|
-
e.preventDefault();
|
|
214
|
-
e.stopPropagation();
|
|
215
|
-
|
|
216
|
-
// Find the currently focused time unit
|
|
217
|
-
const focusedElement = document.activeElement;
|
|
218
|
-
if (!focusedElement || !container.contains(focusedElement)) return;
|
|
219
|
-
|
|
220
|
-
// Determine which time unit is focused
|
|
221
|
-
let focusedUnit: string | null = null;
|
|
222
|
-
timeUnits.forEach(unit => {
|
|
223
|
-
const unitElement = container.querySelector(`[data-kt-datepicker-time-unit="${unit}"]`);
|
|
224
|
-
if (unitElement && unitElement.contains(focusedElement)) {
|
|
225
|
-
focusedUnit = unit;
|
|
226
|
-
}
|
|
227
|
-
});
|
|
228
|
-
|
|
229
|
-
// If no specific unit is focused, focus the first one
|
|
230
|
-
if (!focusedUnit && timeUnits.length > 0) {
|
|
231
|
-
focusedUnit = timeUnits[0];
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
if (focusedUnit && onChange) {
|
|
235
|
-
let newTime: TimeState;
|
|
236
|
-
if (e.key === 'ArrowUp') {
|
|
237
|
-
newTime = incrementTimeUnit(currentTime, focusedUnit, timeStep, format);
|
|
238
|
-
} else {
|
|
239
|
-
newTime = decrementTimeUnit(currentTime, focusedUnit, timeStep, format);
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
const validation = validateTime(newTime, minTime, maxTime);
|
|
243
|
-
if (validation.isValid) {
|
|
244
|
-
// Update current time state
|
|
245
|
-
currentTime = newTime;
|
|
246
|
-
// Update UI immediately
|
|
247
|
-
updateTimeDisplay(currentTime, updateableElements, timeDisplay, granularity, format);
|
|
248
|
-
// Call onChange callback
|
|
249
|
-
onChange(currentTime);
|
|
250
|
-
}
|
|
251
|
-
}
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
// Handle Tab navigation between time units
|
|
255
|
-
if (e.key === 'Tab') {
|
|
256
|
-
const timeUnitElements = timeUnits.map(unit =>
|
|
257
|
-
container.querySelector(`[data-kt-datepicker-time-unit="${unit}"]`)
|
|
258
|
-
).filter(Boolean) as HTMLElement[];
|
|
259
|
-
|
|
260
|
-
if (timeUnitElements.length > 0) {
|
|
261
|
-
const currentIndex = timeUnitElements.findIndex(el => el.contains(document.activeElement));
|
|
262
|
-
let nextIndex = currentIndex;
|
|
263
|
-
|
|
264
|
-
if (e.shiftKey) {
|
|
265
|
-
// Shift+Tab: move to previous
|
|
266
|
-
nextIndex = currentIndex > 0 ? currentIndex - 1 : timeUnitElements.length - 1;
|
|
267
|
-
} else {
|
|
268
|
-
// Tab: move to next
|
|
269
|
-
nextIndex = currentIndex < timeUnitElements.length - 1 ? currentIndex + 1 : 0;
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
if (nextIndex >= 0 && nextIndex < timeUnitElements.length) {
|
|
273
|
-
timeUnitElements[nextIndex].focus();
|
|
274
|
-
e.preventDefault();
|
|
275
|
-
}
|
|
276
|
-
}
|
|
277
|
-
}
|
|
278
|
-
});
|
|
279
|
-
|
|
280
|
-
// Make time units focusable
|
|
281
|
-
timeUnits.forEach(unit => {
|
|
282
|
-
const unitElement = container.querySelector(`[data-kt-datepicker-time-unit="${unit}"]`) as HTMLElement;
|
|
283
|
-
if (unitElement) {
|
|
284
|
-
unitElement.tabIndex = 0;
|
|
285
|
-
unitElement.setAttribute('role', 'spinbutton');
|
|
286
|
-
unitElement.setAttribute('aria-label', `${unit} value`);
|
|
287
|
-
}
|
|
288
|
-
});
|
|
289
|
-
|
|
290
|
-
// Update function to sync with external state changes
|
|
291
|
-
const update = (newTime: TimeState) => {
|
|
292
|
-
currentTime = { ...newTime };
|
|
293
|
-
updateTimeDisplay(currentTime, updateableElements, timeDisplay, granularity, format);
|
|
294
|
-
|
|
295
|
-
// Update AM/PM button if it exists
|
|
296
|
-
if (format === '12h') {
|
|
297
|
-
const ampmButton = container.querySelector('.kt-datepicker-time-ampm-button') as HTMLButtonElement;
|
|
298
|
-
if (ampmButton) {
|
|
299
|
-
ampmButton.textContent = currentTime.hour >= 12 ? 'PM' : 'AM';
|
|
300
|
-
}
|
|
301
|
-
}
|
|
302
|
-
};
|
|
303
|
-
|
|
304
|
-
// Return cleanup function and update function
|
|
305
|
-
return {
|
|
306
|
-
cleanup: () => {
|
|
307
|
-
container.innerHTML = '';
|
|
308
|
-
},
|
|
309
|
-
update
|
|
310
|
-
};
|
|
311
|
-
}
|
|
312
|
-
|
|
313
|
-
/**
|
|
314
|
-
* Update time picker display elements with new time values
|
|
315
|
-
* @param time New time state
|
|
316
|
-
* @param updateableElements Object containing references to updateable DOM elements
|
|
317
|
-
* @param timeDisplay Main time display element
|
|
318
|
-
* @param granularity Time granularity
|
|
319
|
-
* @param format Time format
|
|
320
|
-
*/
|
|
321
|
-
function updateTimeDisplay(
|
|
322
|
-
time: TimeState,
|
|
323
|
-
updateableElements: { [key: string]: HTMLElement },
|
|
324
|
-
timeDisplay: HTMLElement,
|
|
325
|
-
granularity: 'second' | 'minute' | 'hour',
|
|
326
|
-
format: '12h' | '24h'
|
|
327
|
-
): void {
|
|
328
|
-
// Update main time display
|
|
329
|
-
const mainDisplayText = formatTime(time, granularity, format);
|
|
330
|
-
timeDisplay.textContent = mainDisplayText;
|
|
331
|
-
|
|
332
|
-
// Update individual time unit displays
|
|
333
|
-
const timeUnits = getTimeUnits(granularity);
|
|
334
|
-
|
|
335
|
-
timeUnits.forEach(unit => {
|
|
336
|
-
const elementKey = `${unit}Value`;
|
|
337
|
-
const element = updateableElements[elementKey];
|
|
338
|
-
if (element) {
|
|
339
|
-
const unitValue = getTimeUnitValue(time, unit, format);
|
|
340
|
-
element.textContent = unitValue;
|
|
341
|
-
}
|
|
342
|
-
});
|
|
343
|
-
}
|
|
344
|
-
|
|
345
|
-
/**
|
|
346
|
-
* Get time units based on granularity
|
|
347
|
-
* @param granularity Time granularity
|
|
348
|
-
* @returns Array of time unit names
|
|
349
|
-
*/
|
|
350
|
-
function getTimeUnits(granularity: 'second' | 'minute' | 'hour'): string[] {
|
|
351
|
-
switch (granularity) {
|
|
352
|
-
case 'hour':
|
|
353
|
-
return ['hour'];
|
|
354
|
-
case 'minute':
|
|
355
|
-
return ['hour', 'minute'];
|
|
356
|
-
case 'second':
|
|
357
|
-
return ['hour', 'minute', 'second'];
|
|
358
|
-
default:
|
|
359
|
-
return ['hour', 'minute'];
|
|
360
|
-
}
|
|
361
|
-
}
|
|
362
|
-
|
|
363
|
-
/**
|
|
364
|
-
* Get display value for time unit
|
|
365
|
-
* @param time TimeState object
|
|
366
|
-
* @param unit Time unit
|
|
367
|
-
* @param format Time format
|
|
368
|
-
* @returns Formatted unit value
|
|
369
|
-
*/
|
|
370
|
-
function getTimeUnitValue(time: TimeState, unit: string, format: '12h' | '24h'): string {
|
|
371
|
-
switch (unit) {
|
|
372
|
-
case 'hour':
|
|
373
|
-
let hour = time.hour;
|
|
374
|
-
if (format === '12h') {
|
|
375
|
-
hour = hour % 12;
|
|
376
|
-
hour = hour === 0 ? 12 : hour;
|
|
377
|
-
}
|
|
378
|
-
return hour.toString().padStart(2, '0');
|
|
379
|
-
case 'minute':
|
|
380
|
-
return time.minute.toString().padStart(2, '0');
|
|
381
|
-
case 'second':
|
|
382
|
-
return time.second.toString().padStart(2, '0');
|
|
383
|
-
default:
|
|
384
|
-
return '';
|
|
385
|
-
}
|
|
386
|
-
}
|
|
387
|
-
|
|
388
|
-
/**
|
|
389
|
-
* Increment time unit
|
|
390
|
-
* @param time Current time
|
|
391
|
-
* @param unit Time unit to increment
|
|
392
|
-
* @param step Step increment
|
|
393
|
-
* @param format Time format
|
|
394
|
-
* @returns New time state
|
|
395
|
-
*/
|
|
396
|
-
function incrementTimeUnit(time: TimeState, unit: string, step: number, format: '12h' | '24h'): TimeState {
|
|
397
|
-
const newTime = { ...time };
|
|
398
|
-
|
|
399
|
-
switch (unit) {
|
|
400
|
-
case 'hour':
|
|
401
|
-
newTime.hour = (newTime.hour + step) % 24;
|
|
402
|
-
break;
|
|
403
|
-
case 'minute':
|
|
404
|
-
newTime.minute = (newTime.minute + step) % 60;
|
|
405
|
-
break;
|
|
406
|
-
case 'second':
|
|
407
|
-
newTime.second = (newTime.second + step) % 60;
|
|
408
|
-
break;
|
|
409
|
-
}
|
|
410
|
-
|
|
411
|
-
return newTime;
|
|
412
|
-
}
|
|
413
|
-
|
|
414
|
-
/**
|
|
415
|
-
* Decrement time unit
|
|
416
|
-
* @param time Current time
|
|
417
|
-
* @param unit Time unit to decrement
|
|
418
|
-
* @param step Step increment
|
|
419
|
-
* @param format Time format
|
|
420
|
-
* @returns New time state
|
|
421
|
-
*/
|
|
422
|
-
function decrementTimeUnit(time: TimeState, unit: string, step: number, format: '12h' | '24h'): TimeState {
|
|
423
|
-
const newTime = { ...time };
|
|
424
|
-
|
|
425
|
-
switch (unit) {
|
|
426
|
-
case 'hour':
|
|
427
|
-
newTime.hour = (newTime.hour - step + 24) % 24;
|
|
428
|
-
break;
|
|
429
|
-
case 'minute':
|
|
430
|
-
newTime.minute = (newTime.minute - step + 60) % 60;
|
|
431
|
-
break;
|
|
432
|
-
case 'second':
|
|
433
|
-
newTime.second = (newTime.second - step + 60) % 60;
|
|
434
|
-
break;
|
|
435
|
-
}
|
|
436
|
-
|
|
437
|
-
return newTime;
|
|
438
|
-
}
|