@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,530 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* calendar.ts - Calendar renderer for KTDatepicker
|
|
3
|
-
* Renders the calendar grid (days) using provided template and data.
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import { isTemplateFunction, renderTemplateString, renderTemplateToDOM } from '../templates/templates';
|
|
7
|
-
import { defaultTemplates } from '../templates/templates';
|
|
8
|
-
import { formatDateToLocalString, parseLocalDate, getDateKey } from '../../utils/date-utils';
|
|
9
|
-
|
|
10
|
-
// Cache for localized day names to avoid regeneration on every render
|
|
11
|
-
const dayNameCache = new Map<string, string[]>();
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Gets localized day names for a given locale, using cache to avoid regeneration.
|
|
15
|
-
* @param locale Locale string (e.g., 'en-US', 'de-DE')
|
|
16
|
-
* @returns Array of 7 day names starting with Sunday
|
|
17
|
-
*/
|
|
18
|
-
function getDayNames(locale: string): string[] {
|
|
19
|
-
if (dayNameCache.has(locale)) {
|
|
20
|
-
return dayNameCache.get(locale)!;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
const dayNames: string[] = [];
|
|
24
|
-
for (let i = 0; i < 7; i++) {
|
|
25
|
-
const date = new Date(2023, 0, i + 1); // Use January 1st, 2023 as reference (Sunday = 0)
|
|
26
|
-
const dayName = date.toLocaleDateString(locale, { weekday: 'short' });
|
|
27
|
-
dayNames.push(dayName);
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
dayNameCache.set(locale, dayNames);
|
|
31
|
-
return dayNames;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* Day cell computation data interface for centralized day cell rendering logic.
|
|
36
|
-
* Used by both single-month and multi-month views to ensure consistent rendering.
|
|
37
|
-
*/
|
|
38
|
-
interface DayCellData {
|
|
39
|
-
day: number;
|
|
40
|
-
date: Date;
|
|
41
|
-
isCurrentMonth: boolean;
|
|
42
|
-
isToday: boolean;
|
|
43
|
-
isSelected: boolean;
|
|
44
|
-
inRange: boolean;
|
|
45
|
-
attributes: string;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
/**
|
|
49
|
-
* Computes day cell data (attributes, states) for a given day.
|
|
50
|
-
* This centralized helper function ensures consistent day cell rendering
|
|
51
|
-
* across single-month and multi-month views.
|
|
52
|
-
*
|
|
53
|
-
* @param day - The date for this day cell
|
|
54
|
-
* @param currentDate - The current month being viewed (for isCurrentMonth calculation)
|
|
55
|
-
* @param todayKey - Pre-computed date key for today (for performance)
|
|
56
|
-
* @param checkIsSelected - Function to check if a date is selected
|
|
57
|
-
* @param selectedRange - Optional range selection
|
|
58
|
-
* @param dayIndex - Index of this day in the calendar grid (0-based)
|
|
59
|
-
* @param tabbableIndex - Index of the tabbable day (for keyboard navigation)
|
|
60
|
-
* @returns Day cell data object with computed states and attributes
|
|
61
|
-
*/
|
|
62
|
-
function computeDayCellData(
|
|
63
|
-
day: Date,
|
|
64
|
-
currentDate: Date,
|
|
65
|
-
todayKey: number,
|
|
66
|
-
checkIsSelected: (day: Date) => boolean,
|
|
67
|
-
selectedRange: { start: Date | null; end: Date | null } | undefined,
|
|
68
|
-
dayIndex: number,
|
|
69
|
-
tabbableIndex: number
|
|
70
|
-
): DayCellData {
|
|
71
|
-
const isCurrentMonth = day.getMonth() === currentDate.getMonth();
|
|
72
|
-
const isToday = getDateKey(day) === todayKey;
|
|
73
|
-
const isSelected = checkIsSelected(day);
|
|
74
|
-
|
|
75
|
-
let inRange = false;
|
|
76
|
-
if (selectedRange && selectedRange.start && selectedRange.end) {
|
|
77
|
-
// Use date keys for efficient range comparison (no Date object creation needed)
|
|
78
|
-
const dayKey = getDateKey(day);
|
|
79
|
-
const startKey = getDateKey(selectedRange.start);
|
|
80
|
-
const endKey = getDateKey(selectedRange.end);
|
|
81
|
-
inRange = dayKey >= startKey && dayKey <= endKey;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
const dateLocal = formatDateToLocalString(day);
|
|
85
|
-
const attributes = [
|
|
86
|
-
isSelected ? 'data-kt-selected="true" aria-selected="true"' : '',
|
|
87
|
-
isToday ? 'data-today="true"' : '',
|
|
88
|
-
isCurrentMonth ? '' : 'data-outside="true"',
|
|
89
|
-
// Use data-kt-hover-range for completed ranges too (consolidated with hover preview)
|
|
90
|
-
inRange ? 'data-kt-hover-range="true"' : '',
|
|
91
|
-
`data-date="${dateLocal}"`,
|
|
92
|
-
`data-day-index="${dayIndex}"`,
|
|
93
|
-
`tabindex=\"${dayIndex === tabbableIndex ? '0' : '-1'}\"`
|
|
94
|
-
].filter(Boolean).join(' ');
|
|
95
|
-
|
|
96
|
-
return {
|
|
97
|
-
day: day.getDate(),
|
|
98
|
-
date: day,
|
|
99
|
-
isCurrentMonth,
|
|
100
|
-
isToday,
|
|
101
|
-
isSelected,
|
|
102
|
-
inRange,
|
|
103
|
-
attributes
|
|
104
|
-
};
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
/**
|
|
108
|
-
* Renders the datepicker calendar and returns an HTMLElement.
|
|
109
|
-
*
|
|
110
|
-
* This function uses centralized day cell computation logic (computeDayCellData)
|
|
111
|
-
* to ensure consistent rendering across single-month and multi-month views.
|
|
112
|
-
* Both views call this function with identical state parameters, guaranteeing
|
|
113
|
-
* that the same date appears identically regardless of which view is displayed.
|
|
114
|
-
*
|
|
115
|
-
* @param tpl - The template string or function for the day cell
|
|
116
|
-
* @param days - Array of Date objects for the calendar grid
|
|
117
|
-
* @param currentDate - The current month being viewed
|
|
118
|
-
* @param selectedDate - The currently selected date
|
|
119
|
-
* @param onDayClick - Callback for day cell click, receives the Date
|
|
120
|
-
* @param locale - Locale string for day name localization
|
|
121
|
-
* @param selectedRange - Optional range selection
|
|
122
|
-
* @param selectedDates - Optional array of selected dates for multi-date mode
|
|
123
|
-
*/
|
|
124
|
-
export function renderCalendar(
|
|
125
|
-
tpl: string | ((data: any) => string),
|
|
126
|
-
days: Date[],
|
|
127
|
-
currentDate: Date,
|
|
128
|
-
selectedDate: Date | null,
|
|
129
|
-
onDayClick: (date: Date) => void,
|
|
130
|
-
locale?: string,
|
|
131
|
-
selectedRange?: { start: Date | null; end: Date | null },
|
|
132
|
-
selectedDates?: Date[]
|
|
133
|
-
): HTMLElement {
|
|
134
|
-
// Get localized day names from cache
|
|
135
|
-
const localeToUse = locale || 'en-US';
|
|
136
|
-
const dayNames = getDayNames(localeToUse);
|
|
137
|
-
|
|
138
|
-
// Cache "today" date object to avoid creating it multiple times
|
|
139
|
-
const today = new Date();
|
|
140
|
-
today.setHours(0, 0, 0, 0);
|
|
141
|
-
const todayKey = getDateKey(today);
|
|
142
|
-
|
|
143
|
-
// Pre-compute date keys for selected dates for O(1) lookups
|
|
144
|
-
const selectedDateKey = selectedDate ? getDateKey(selectedDate) : null;
|
|
145
|
-
const selectedDatesKeys = selectedDates && selectedDates.length > 0
|
|
146
|
-
? new Set(selectedDates.map(d => getDateKey(d)))
|
|
147
|
-
: null;
|
|
148
|
-
const selectedRangeStartKey = selectedRange?.start ? getDateKey(selectedRange.start) : null;
|
|
149
|
-
const selectedRangeEndKey = selectedRange?.end ? getDateKey(selectedRange.end) : null;
|
|
150
|
-
|
|
151
|
-
// Use template system for table, tbody, tr, td
|
|
152
|
-
const tableTpl = defaultTemplates.calendarTable;
|
|
153
|
-
const bodyTpl = defaultTemplates.calendarBody;
|
|
154
|
-
const rowTpl = defaultTemplates.calendarRow;
|
|
155
|
-
const rows = [];
|
|
156
|
-
// Determine which day should be tabbable (selected, or today if none) using date keys
|
|
157
|
-
let tabbableIndex = -1;
|
|
158
|
-
if (selectedDateKey !== null) {
|
|
159
|
-
tabbableIndex = days.findIndex(d => getDateKey(d) === selectedDateKey);
|
|
160
|
-
}
|
|
161
|
-
if (tabbableIndex === -1 && selectedDatesKeys) {
|
|
162
|
-
tabbableIndex = days.findIndex(d => selectedDatesKeys.has(getDateKey(d)));
|
|
163
|
-
}
|
|
164
|
-
if (tabbableIndex === -1 && selectedRangeStartKey !== null) {
|
|
165
|
-
tabbableIndex = days.findIndex(d => getDateKey(d) === selectedRangeStartKey);
|
|
166
|
-
}
|
|
167
|
-
if (tabbableIndex === -1) {
|
|
168
|
-
tabbableIndex = days.findIndex(d => getDateKey(d) === todayKey);
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
// Helper function to check if a date is selected using date keys for O(1) lookups
|
|
172
|
-
const checkIsSelected = (day: Date): boolean => {
|
|
173
|
-
const dayKey = getDateKey(day);
|
|
174
|
-
// Check single date selection
|
|
175
|
-
if (selectedDateKey !== null && dayKey === selectedDateKey) {
|
|
176
|
-
return true;
|
|
177
|
-
}
|
|
178
|
-
// Check multi-date selection
|
|
179
|
-
if (selectedDatesKeys && selectedDatesKeys.has(dayKey)) {
|
|
180
|
-
return true;
|
|
181
|
-
}
|
|
182
|
-
// Check range selection start/end dates
|
|
183
|
-
if (selectedRangeStartKey !== null && dayKey === selectedRangeStartKey) {
|
|
184
|
-
return true;
|
|
185
|
-
}
|
|
186
|
-
if (selectedRangeEndKey !== null && dayKey === selectedRangeEndKey) {
|
|
187
|
-
return true;
|
|
188
|
-
}
|
|
189
|
-
return false;
|
|
190
|
-
};
|
|
191
|
-
|
|
192
|
-
// Render calendar weeks using centralized day cell computation
|
|
193
|
-
// This ensures consistent rendering across single-month and multi-month views
|
|
194
|
-
for (let i = 0; i < days.length; i += 7) {
|
|
195
|
-
const week = days.slice(i, i + 7);
|
|
196
|
-
const tds = week.map((day, j) => {
|
|
197
|
-
const dayIndex = i + j;
|
|
198
|
-
// Use centralized helper function to compute day cell data
|
|
199
|
-
// This guarantees identical logic for single-month and multi-month views
|
|
200
|
-
const data = computeDayCellData(
|
|
201
|
-
day,
|
|
202
|
-
currentDate,
|
|
203
|
-
todayKey,
|
|
204
|
-
checkIsSelected,
|
|
205
|
-
selectedRange,
|
|
206
|
-
dayIndex,
|
|
207
|
-
tabbableIndex
|
|
208
|
-
);
|
|
209
|
-
return isTemplateFunction(tpl)
|
|
210
|
-
? tpl(data)
|
|
211
|
-
: renderTemplateString(typeof tpl === 'string' ? tpl : (typeof defaultTemplates.dayCell === 'string' ? defaultTemplates.dayCell : ''), data);
|
|
212
|
-
}).join('');
|
|
213
|
-
// Use row template
|
|
214
|
-
const rowHtml = isTemplateFunction(rowTpl)
|
|
215
|
-
? rowTpl({ cells: tds })
|
|
216
|
-
: (rowTpl as string).replace(/{{cells}}/g, tds);
|
|
217
|
-
rows.push(rowHtml);
|
|
218
|
-
}
|
|
219
|
-
// Use body template
|
|
220
|
-
const bodyHtml = isTemplateFunction(bodyTpl)
|
|
221
|
-
? bodyTpl({ rows: rows.join('') })
|
|
222
|
-
: (bodyTpl as string).replace(/{{rows}}/g, rows.join(''));
|
|
223
|
-
// Use table template with localized day names
|
|
224
|
-
const tableHtml = isTemplateFunction(tableTpl)
|
|
225
|
-
? tableTpl({
|
|
226
|
-
body: bodyHtml,
|
|
227
|
-
sunday: dayNames[0],
|
|
228
|
-
monday: dayNames[1],
|
|
229
|
-
tuesday: dayNames[2],
|
|
230
|
-
wednesday: dayNames[3],
|
|
231
|
-
thursday: dayNames[4],
|
|
232
|
-
friday: dayNames[5],
|
|
233
|
-
saturday: dayNames[6]
|
|
234
|
-
})
|
|
235
|
-
: (tableTpl as string)
|
|
236
|
-
.replace(/{{body}}/g, bodyHtml)
|
|
237
|
-
.replace(/{{sunday}}/g, dayNames[0])
|
|
238
|
-
.replace(/{{monday}}/g, dayNames[1])
|
|
239
|
-
.replace(/{{tuesday}}/g, dayNames[2])
|
|
240
|
-
.replace(/{{wednesday}}/g, dayNames[3])
|
|
241
|
-
.replace(/{{thursday}}/g, dayNames[4])
|
|
242
|
-
.replace(/{{friday}}/g, dayNames[5])
|
|
243
|
-
.replace(/{{saturday}}/g, dayNames[6]);
|
|
244
|
-
const calendarFrag = renderTemplateToDOM(tableHtml);
|
|
245
|
-
const calendar = calendarFrag.firstElementChild as HTMLElement;
|
|
246
|
-
|
|
247
|
-
// Build cell reference cache for O(1) lookups during hover range updates
|
|
248
|
-
// Map<dateKey, HTMLElement> for efficient cell lookups
|
|
249
|
-
const cellCache = new Map<number, HTMLElement>();
|
|
250
|
-
const allCells = calendar.querySelectorAll('td[data-kt-datepicker-day]');
|
|
251
|
-
allCells.forEach((cell) => {
|
|
252
|
-
const dateAttr = cell.getAttribute('data-date');
|
|
253
|
-
if (dateAttr) {
|
|
254
|
-
const cellDate = parseLocalDate(dateAttr);
|
|
255
|
-
const dateKey = getDateKey(cellDate);
|
|
256
|
-
cellCache.set(dateKey, cell as HTMLElement);
|
|
257
|
-
}
|
|
258
|
-
});
|
|
259
|
-
|
|
260
|
-
// Store selectedRange state on the calendar element so hover handlers can access current state
|
|
261
|
-
// This allows the state to be updated without re-rendering the entire calendar
|
|
262
|
-
// The _updateCalendar() method will update these attributes when the state changes
|
|
263
|
-
if (selectedRange) {
|
|
264
|
-
if (selectedRange.start) {
|
|
265
|
-
calendar.setAttribute('data-kt-range-start', formatDateToLocalString(selectedRange.start));
|
|
266
|
-
}
|
|
267
|
-
if (selectedRange.end) {
|
|
268
|
-
calendar.setAttribute('data-kt-range-end', formatDateToLocalString(selectedRange.end));
|
|
269
|
-
}
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
// Helper function to parse ISO date string (YYYY-MM-DD) as local date to avoid timezone issues
|
|
273
|
-
const parseLocalDateFromAttr = (dateStr: string): Date => {
|
|
274
|
-
// Parse YYYY-MM-DD string and create local date at midnight
|
|
275
|
-
return parseLocalDate(dateStr);
|
|
276
|
-
};
|
|
277
|
-
|
|
278
|
-
// Helper function to get current selectedRange from calendar element data attributes
|
|
279
|
-
const getCurrentSelectedRange = (): { start: Date | null; end: Date | null } | null => {
|
|
280
|
-
const startAttr = calendar.getAttribute('data-kt-range-start');
|
|
281
|
-
const endAttr = calendar.getAttribute('data-kt-range-end');
|
|
282
|
-
|
|
283
|
-
if (!startAttr && !endAttr) {
|
|
284
|
-
return null;
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
return {
|
|
288
|
-
start: startAttr ? parseLocalDateFromAttr(startAttr) : null,
|
|
289
|
-
end: endAttr ? parseLocalDateFromAttr(endAttr) : null
|
|
290
|
-
};
|
|
291
|
-
};
|
|
292
|
-
|
|
293
|
-
// Helper function to check if we're in range preview mode (checked dynamically)
|
|
294
|
-
const isRangePreviewMode = (): boolean => {
|
|
295
|
-
const currentRange = getCurrentSelectedRange();
|
|
296
|
-
return !!(currentRange && currentRange.start && !currentRange.end);
|
|
297
|
-
};
|
|
298
|
-
|
|
299
|
-
// Helper function to clear all hover range attributes
|
|
300
|
-
const clearHoverRange = () => {
|
|
301
|
-
calendar.querySelectorAll('[data-kt-hover-range]').forEach((cell) => {
|
|
302
|
-
(cell as HTMLElement).removeAttribute('data-kt-hover-range');
|
|
303
|
-
});
|
|
304
|
-
};
|
|
305
|
-
|
|
306
|
-
// Helper function to get all dates in a range (inclusive)
|
|
307
|
-
const getDatesInRange = (startDate: Date, endDate: Date): Date[] => {
|
|
308
|
-
const dates: Date[] = [];
|
|
309
|
-
const start = new Date(startDate);
|
|
310
|
-
const end = new Date(endDate);
|
|
311
|
-
|
|
312
|
-
// Normalize dates to midnight for accurate comparison
|
|
313
|
-
start.setHours(0, 0, 0, 0);
|
|
314
|
-
end.setHours(0, 0, 0, 0);
|
|
315
|
-
|
|
316
|
-
// Determine the actual start and end (handles reverse ranges)
|
|
317
|
-
const actualStart = start <= end ? start : end;
|
|
318
|
-
const actualEnd = start <= end ? end : start;
|
|
319
|
-
|
|
320
|
-
// Generate all dates in the range
|
|
321
|
-
const current = new Date(actualStart);
|
|
322
|
-
while (current <= actualEnd) {
|
|
323
|
-
dates.push(new Date(current));
|
|
324
|
-
current.setDate(current.getDate() + 1);
|
|
325
|
-
}
|
|
326
|
-
|
|
327
|
-
return dates;
|
|
328
|
-
};
|
|
329
|
-
|
|
330
|
-
// Helper function to find a date cell by date using cached cell references
|
|
331
|
-
const findDateCell = (targetDate: Date): HTMLElement | null => {
|
|
332
|
-
const targetKey = getDateKey(targetDate);
|
|
333
|
-
return cellCache.get(targetKey) || null;
|
|
334
|
-
};
|
|
335
|
-
|
|
336
|
-
// Helper function to update hover range preview
|
|
337
|
-
const updateHoverRange = (hoveredDate: Date) => {
|
|
338
|
-
if (!isRangePreviewMode()) {
|
|
339
|
-
return;
|
|
340
|
-
}
|
|
341
|
-
|
|
342
|
-
// Get current range state from calendar element (reads dynamically)
|
|
343
|
-
const currentRange = getCurrentSelectedRange();
|
|
344
|
-
if (!currentRange?.start) {
|
|
345
|
-
return;
|
|
346
|
-
}
|
|
347
|
-
|
|
348
|
-
// Normalize hovered date
|
|
349
|
-
const normalizedHovered = new Date(hoveredDate);
|
|
350
|
-
normalizedHovered.setHours(0, 0, 0, 0);
|
|
351
|
-
|
|
352
|
-
// Normalize start date
|
|
353
|
-
const normalizedStart = new Date(currentRange.start);
|
|
354
|
-
normalizedStart.setHours(0, 0, 0, 0);
|
|
355
|
-
|
|
356
|
-
// Clear previous hover range from ALL calendars in multi-month view
|
|
357
|
-
const dropdownEl = calendar.closest('[data-kt-datepicker-dropdown]') as HTMLElement;
|
|
358
|
-
if (dropdownEl) {
|
|
359
|
-
const allCalendars = dropdownEl.querySelectorAll('[data-kt-datepicker-calendar-table]');
|
|
360
|
-
allCalendars.forEach((cal) => {
|
|
361
|
-
const hoverCells = cal.querySelectorAll('[data-kt-hover-range]');
|
|
362
|
-
hoverCells.forEach((cell) => {
|
|
363
|
-
cell.removeAttribute('data-kt-hover-range');
|
|
364
|
-
});
|
|
365
|
-
});
|
|
366
|
-
} else {
|
|
367
|
-
clearHoverRange();
|
|
368
|
-
}
|
|
369
|
-
|
|
370
|
-
// Calculate range between start date and hovered date
|
|
371
|
-
const rangeDates = getDatesInRange(normalizedStart, normalizedHovered);
|
|
372
|
-
|
|
373
|
-
// Add data-kt-hover-range to all dates in the range across ALL visible calendars
|
|
374
|
-
// This enables hover preview to work across multiple months
|
|
375
|
-
const allCalendars = dropdownEl
|
|
376
|
-
? Array.from(dropdownEl.querySelectorAll('[data-kt-datepicker-calendar-table]')) as HTMLElement[]
|
|
377
|
-
: [calendar];
|
|
378
|
-
|
|
379
|
-
rangeDates.forEach((date) => {
|
|
380
|
-
const dateLocal = formatDateToLocalString(date);
|
|
381
|
-
// Search across all calendars to find the cell by data-date attribute
|
|
382
|
-
for (const cal of allCalendars) {
|
|
383
|
-
const cell = cal.querySelector(`td[data-kt-datepicker-day][data-date="${dateLocal}"]`) as HTMLElement;
|
|
384
|
-
if (cell) {
|
|
385
|
-
// Set attribute if cell is found in this calendar
|
|
386
|
-
cell.setAttribute('data-kt-hover-range', '');
|
|
387
|
-
break; // Found in this calendar, no need to search others
|
|
388
|
-
}
|
|
389
|
-
}
|
|
390
|
-
});
|
|
391
|
-
};
|
|
392
|
-
|
|
393
|
-
// Event delegation: attach single listeners to calendar table instead of individual cell listeners
|
|
394
|
-
// This reduces memory footprint from 42+ listeners to 2-3 listeners
|
|
395
|
-
calendar.addEventListener('click', (e) => {
|
|
396
|
-
const target = e.target as HTMLElement;
|
|
397
|
-
// Check if click is on a button or inside a button within a calendar cell
|
|
398
|
-
const button = target.closest('button[data-day]') as HTMLButtonElement;
|
|
399
|
-
if (!button) return;
|
|
400
|
-
|
|
401
|
-
const cell = button.closest('td[data-kt-datepicker-day]') as HTMLElement;
|
|
402
|
-
if (!cell) return;
|
|
403
|
-
|
|
404
|
-
const dateAttr = cell.getAttribute('data-date');
|
|
405
|
-
if (!dateAttr) return;
|
|
406
|
-
|
|
407
|
-
const dayObj = parseLocalDate(dateAttr);
|
|
408
|
-
if (dayObj.getMonth() === currentDate.getMonth()) {
|
|
409
|
-
e.stopPropagation();
|
|
410
|
-
onDayClick(dayObj);
|
|
411
|
-
}
|
|
412
|
-
});
|
|
413
|
-
|
|
414
|
-
// Track currently hovered cell to prevent race conditions during fast mouse movement
|
|
415
|
-
let currentHoveredCell: HTMLElement | null = null;
|
|
416
|
-
let hoverTimeout: number | null = null;
|
|
417
|
-
|
|
418
|
-
// Delegated hover handlers for single date hover and range preview
|
|
419
|
-
// Use mouseover/mouseout on calendar with relatedTarget check for proper delegation
|
|
420
|
-
calendar.addEventListener('mouseover', (e) => {
|
|
421
|
-
const target = e.target as HTMLElement;
|
|
422
|
-
// Check if mouseover is on a button or inside a button within a calendar cell
|
|
423
|
-
const button = target.closest('button[data-day]') as HTMLButtonElement;
|
|
424
|
-
if (!button) return;
|
|
425
|
-
|
|
426
|
-
const cell = button.closest('td[data-kt-datepicker-day]') as HTMLElement;
|
|
427
|
-
if (!cell) return;
|
|
428
|
-
|
|
429
|
-
const dateAttr = cell.getAttribute('data-date');
|
|
430
|
-
if (!dateAttr) return;
|
|
431
|
-
|
|
432
|
-
// Clear any pending hover removal timeout
|
|
433
|
-
if (hoverTimeout) {
|
|
434
|
-
clearTimeout(hoverTimeout);
|
|
435
|
-
hoverTimeout = null;
|
|
436
|
-
}
|
|
437
|
-
|
|
438
|
-
// Clear previous hovered cell if different
|
|
439
|
-
if (currentHoveredCell && currentHoveredCell !== cell) {
|
|
440
|
-
currentHoveredCell.removeAttribute('data-kt-hover');
|
|
441
|
-
}
|
|
442
|
-
|
|
443
|
-
// Set new hovered cell
|
|
444
|
-
currentHoveredCell = cell;
|
|
445
|
-
cell.setAttribute('data-kt-hover', '');
|
|
446
|
-
|
|
447
|
-
// If in range preview mode, update hover range
|
|
448
|
-
if (isRangePreviewMode()) {
|
|
449
|
-
const dayObj = parseLocalDate(dateAttr);
|
|
450
|
-
updateHoverRange(dayObj);
|
|
451
|
-
}
|
|
452
|
-
});
|
|
453
|
-
|
|
454
|
-
calendar.addEventListener('mouseout', (e) => {
|
|
455
|
-
const target = e.target as HTMLElement;
|
|
456
|
-
const relatedTarget = (e as MouseEvent).relatedTarget as HTMLElement;
|
|
457
|
-
|
|
458
|
-
// Check if mouseout is leaving a button
|
|
459
|
-
const button = target.closest('button[data-day]') as HTMLButtonElement;
|
|
460
|
-
if (!button) return;
|
|
461
|
-
|
|
462
|
-
// If moving to another element within the same calendar, don't remove hover
|
|
463
|
-
if (relatedTarget && calendar.contains(relatedTarget)) {
|
|
464
|
-
const relatedButton = relatedTarget.closest('button[data-day]');
|
|
465
|
-
if (relatedButton) {
|
|
466
|
-
// Moving to another button - mouseover will handle the transition
|
|
467
|
-
return;
|
|
468
|
-
}
|
|
469
|
-
}
|
|
470
|
-
|
|
471
|
-
const cell = button.closest('td[data-kt-datepicker-day]') as HTMLElement;
|
|
472
|
-
if (!cell) return;
|
|
473
|
-
|
|
474
|
-
// Clear any pending hover removal timeout
|
|
475
|
-
if (hoverTimeout) {
|
|
476
|
-
clearTimeout(hoverTimeout);
|
|
477
|
-
hoverTimeout = null;
|
|
478
|
-
}
|
|
479
|
-
|
|
480
|
-
// Use a small delay to prevent flickering when moving fast between cells
|
|
481
|
-
// This allows mouseover on the next cell to fire first
|
|
482
|
-
hoverTimeout = window.setTimeout(() => {
|
|
483
|
-
// Only remove if this is still the current hovered cell
|
|
484
|
-
if (currentHoveredCell === cell) {
|
|
485
|
-
cell.removeAttribute('data-kt-hover');
|
|
486
|
-
currentHoveredCell = null;
|
|
487
|
-
}
|
|
488
|
-
hoverTimeout = null;
|
|
489
|
-
}, 50);
|
|
490
|
-
|
|
491
|
-
// Note: Hover range clearing is handled at calendar level to prevent flickering
|
|
492
|
-
});
|
|
493
|
-
|
|
494
|
-
// Track hover state to prevent flickering when moving between dates
|
|
495
|
-
let hoverRangeClearTimeout: number | null = null;
|
|
496
|
-
|
|
497
|
-
// Handle calendar-level mouseleave to clear hover range when mouse leaves calendar entirely
|
|
498
|
-
calendar.addEventListener('mouseleave', (e) => {
|
|
499
|
-
if (!isRangePreviewMode()) return;
|
|
500
|
-
|
|
501
|
-
// Check if we're moving to another button within the calendar
|
|
502
|
-
const relatedTarget = (e as MouseEvent).relatedTarget as HTMLElement;
|
|
503
|
-
if (relatedTarget && calendar.contains(relatedTarget)) {
|
|
504
|
-
// Mouse is moving to another element within the calendar, don't clear
|
|
505
|
-
return;
|
|
506
|
-
}
|
|
507
|
-
|
|
508
|
-
// Clear hover range with a small delay to allow smooth transitions
|
|
509
|
-
if (hoverRangeClearTimeout) {
|
|
510
|
-
clearTimeout(hoverRangeClearTimeout);
|
|
511
|
-
}
|
|
512
|
-
hoverRangeClearTimeout = window.setTimeout(() => {
|
|
513
|
-
clearHoverRange();
|
|
514
|
-
hoverRangeClearTimeout = null;
|
|
515
|
-
}, 50);
|
|
516
|
-
});
|
|
517
|
-
|
|
518
|
-
// Clear timeout if mouse re-enters calendar
|
|
519
|
-
calendar.addEventListener('mouseenter', () => {
|
|
520
|
-
if (hoverRangeClearTimeout) {
|
|
521
|
-
clearTimeout(hoverRangeClearTimeout);
|
|
522
|
-
hoverRangeClearTimeout = null;
|
|
523
|
-
}
|
|
524
|
-
});
|
|
525
|
-
|
|
526
|
-
return calendar;
|
|
527
|
-
}
|
|
528
|
-
|
|
529
|
-
// Note: isSameDay function removed - all date comparisons now use date keys for better performance
|
|
530
|
-
// If needed elsewhere, use isSameLocalDay or isSameDayByKey from date-utils
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* footer.ts - Footer renderer for KTDatepicker
|
|
3
|
-
* Renders the calendar footer (today, clear, apply buttons) using provided template and data.
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import { isTemplateFunction, renderTemplateString, renderTemplateToDOM } from '../templates/templates';
|
|
7
|
-
import { defaultTemplates } from '../templates/templates';
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Renders the datepicker footer and returns an HTMLElement.
|
|
11
|
-
* @param tpl - The template string or function for the footer
|
|
12
|
-
* @param data - Data for the template (todayButton, clearButton, applyButton, etc.)
|
|
13
|
-
* @param onToday - Callback for today button
|
|
14
|
-
* @param onClear - Callback for clear button
|
|
15
|
-
* @param onApply - Callback for apply button
|
|
16
|
-
*/
|
|
17
|
-
export function renderFooter(
|
|
18
|
-
tpl: string | ((data: any) => string),
|
|
19
|
-
data: any,
|
|
20
|
-
onToday?: (e: Event) => void,
|
|
21
|
-
onClear?: (e: Event) => void,
|
|
22
|
-
onApply?: (e: Event) => void
|
|
23
|
-
): HTMLElement {
|
|
24
|
-
const footerHtml = isTemplateFunction(tpl)
|
|
25
|
-
? tpl(data)
|
|
26
|
-
: renderTemplateString(typeof tpl === 'string' ? tpl : (typeof defaultTemplates.footer === 'string' ? defaultTemplates.footer : ''), data);
|
|
27
|
-
const footerFrag = renderTemplateToDOM(footerHtml);
|
|
28
|
-
const footer = footerFrag.firstElementChild as HTMLElement;
|
|
29
|
-
// Add button event listeners if present
|
|
30
|
-
if (onToday) {
|
|
31
|
-
const todayBtn = footer.querySelector('[data-kt-datepicker-today]');
|
|
32
|
-
if (todayBtn) todayBtn.addEventListener('click', onToday);
|
|
33
|
-
}
|
|
34
|
-
if (onClear) {
|
|
35
|
-
const clearBtn = footer.querySelector('[data-kt-datepicker-clear]');
|
|
36
|
-
if (clearBtn) clearBtn.addEventListener('click', onClear);
|
|
37
|
-
}
|
|
38
|
-
if (onApply) {
|
|
39
|
-
const applyBtn = footer.querySelector('[data-kt-datepicker-apply]');
|
|
40
|
-
if (applyBtn) applyBtn.addEventListener('click', onApply);
|
|
41
|
-
}
|
|
42
|
-
return footer;
|
|
43
|
-
}
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* header.ts - Header renderer for KTDatepicker
|
|
3
|
-
* Renders the calendar header (month, year, navigation buttons) using provided template and data.
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import { isTemplateFunction, renderTemplateString, renderTemplateToDOM } from '../templates/templates';
|
|
7
|
-
import { defaultTemplates } from '../templates/templates';
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Renders the datepicker header and returns an HTMLElement.
|
|
11
|
-
* @param tpl - The template string or function for the header
|
|
12
|
-
* @param data - Data for the template (month, year, prevButton, nextButton)
|
|
13
|
-
* @param onPrev - Callback for previous month button
|
|
14
|
-
* @param onNext - Callback for next month button
|
|
15
|
-
*/
|
|
16
|
-
export function renderHeader(
|
|
17
|
-
tpl: string | ((data: any) => string),
|
|
18
|
-
data: any,
|
|
19
|
-
onPrev: (e: Event) => void,
|
|
20
|
-
onNext: (e: Event) => void
|
|
21
|
-
): HTMLElement {
|
|
22
|
-
const headerHtml = isTemplateFunction(tpl)
|
|
23
|
-
? tpl(data)
|
|
24
|
-
: renderTemplateString(typeof tpl === 'string' ? tpl : (typeof defaultTemplates.header === 'string' ? defaultTemplates.header : ''), data);
|
|
25
|
-
const headerFrag = renderTemplateToDOM(headerHtml);
|
|
26
|
-
const header = headerFrag.firstElementChild as HTMLElement;
|
|
27
|
-
// Add navigation event listeners
|
|
28
|
-
const prevBtn = header.querySelector('[data-kt-datepicker-prev]');
|
|
29
|
-
const nextBtn = header.querySelector('[data-kt-datepicker-next]');
|
|
30
|
-
if (prevBtn) prevBtn.addEventListener('click', onPrev);
|
|
31
|
-
if (nextBtn) nextBtn.addEventListener('click', onNext);
|
|
32
|
-
return header;
|
|
33
|
-
}
|