@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,306 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* templates.ts - Unified template system for KTDatepicker
|
|
3
|
-
* Consolidates all template functionality including default templates, merging logic,
|
|
4
|
-
* rendering utilities, and template management into a single, unified system.
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import { KTDatepickerConfig, KTDatepickerTemplateStrings } from '../../config/types';
|
|
8
|
-
|
|
9
|
-
// Default template strings for all UI fragments
|
|
10
|
-
export const defaultTemplates: KTDatepickerTemplateStrings = {
|
|
11
|
-
// Add role="dialog" and aria-modal to the dropdown container
|
|
12
|
-
container: `<div data-kt-datepicker-container {{class}}></div>`,
|
|
13
|
-
header: `<div data-kt-datepicker-header {{class}}">{{prevButton}}<span data-kt-datepicker-month-year>{{month}} {{year}}</span>{{nextButton}}</div>`,
|
|
14
|
-
footer: `<div data-kt-datepicker-footer {{class}}">{{todayButton}} {{clearButton}} {{applyButton}}</div>`,
|
|
15
|
-
// Add role="grid" and aria-label to the calendar grid
|
|
16
|
-
calendarGrid: `<table data-kt-datepicker-calendar-grid role="grid" aria-label="Calendar" aria-readonly="true" {{class}}>{{calendar}}</table>`,
|
|
17
|
-
// Add role="gridcell" to dayCell, aria-selected, and tabindex for keyboard nav
|
|
18
|
-
dayCell: `<td data-kt-datepicker-day role="gridcell" {{attributes}} {{class}}><button type="button" data-day="{{day}}" aria-label="Select {{day}}" tabindex="-1">{{day}}</button></td>`,
|
|
19
|
-
// Month/year selectors (add aria-live for dynamic updates)
|
|
20
|
-
monthYearSelect: `<div data-kt-datepicker-monthyear-select aria-live="polite" {{class}}>{{monthSelect}} {{yearSelect}}</div>`,
|
|
21
|
-
monthSelection: `<div data-kt-datepicker-month-selection {{class}}>{{months}}</div>`,
|
|
22
|
-
yearSelection: `<div data-kt-datepicker-year-selection {{class}}>{{years}}</div>`,
|
|
23
|
-
inputWrapper: `<div data-kt-datepicker-input-wrapper class="flex items-center {{class}}">{{input}} {{icon}}</div>`,
|
|
24
|
-
segmentedDateInput: `<div data-kt-datepicker-segmented-input class="flex items-center {{class}}">{{segments}}</div>`,
|
|
25
|
-
segmentedDateRangeInput: `<div data-kt-datepicker-segmented-range-input class="flex items-center {{class}}">{{start}}{{separator}}{{end}}</div>`,
|
|
26
|
-
/**
|
|
27
|
-
* Template for a single date segment (e.g., day, month, year)
|
|
28
|
-
* Placeholders: segmentType, segmentValue, ariaLabel, ariaValueNow, ariaValueText, ariaValueMin, ariaValueMax, tabindex, contenteditable
|
|
29
|
-
*/
|
|
30
|
-
dateSegment: `<span data-segment="{{segmentType}}" role="spinbutton" aria-label="{{ariaLabel}}" aria-valuenow="{{ariaValueNow}}" aria-valuetext="{{ariaValueText}}" aria-valuemin="{{ariaValueMin}}" aria-valuemax="{{ariaValueMax}}" tabindex="{{tabindex}}" contenteditable="{{contenteditable}}" {{class}}>{{segmentValue}}</span>`,
|
|
31
|
-
/**
|
|
32
|
-
* Template for a segment separator (e.g., / or space)
|
|
33
|
-
* Placeholders: separator
|
|
34
|
-
*/
|
|
35
|
-
segmentSeparator: `<span data-segment-separator {{class}}>{{separator}}</span>`,
|
|
36
|
-
placeholder: `<span data-kt-datepicker-placeholder {{class}}>{{placeholder}}</span>`,
|
|
37
|
-
displayWrapper: `<div data-kt-datepicker-display-wrapper {{class}}>{{value}}</div>`,
|
|
38
|
-
displayElement: `<span data-kt-datepicker-display-element {{class}}>{{value}}</span>`,
|
|
39
|
-
timePanel: `<div data-kt-datepicker-time-panel {{class}}>{{hours}}:{{minutes}}:{{seconds}} {{amPm}}</div>`,
|
|
40
|
-
multiDateTag: `<span data-kt-datepicker-multidate-tag {{class}}>{{date}} <button>{{removeButton}}</button></span>`,
|
|
41
|
-
emptyState: `<div data-kt-datepicker-empty {{class}}>{{message}}</div>`,
|
|
42
|
-
// Add aria-haspopup and aria-expanded to calendar button
|
|
43
|
-
calendarButton: `<button type="button" data-kt-datepicker-calendar-btn aria-label="Open calendar" aria-haspopup="dialog" aria-expanded="false" {{class}}>
|
|
44
|
-
<svg width="16" height="16" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24" aria-hidden="true">
|
|
45
|
-
<rect x="3" y="4" width="18" height="18" rx="2"/>
|
|
46
|
-
<path d="M16 2v4M8 2v4M3 10h18"/>
|
|
47
|
-
</svg>
|
|
48
|
-
</button>`,
|
|
49
|
-
// Add role="dialog" and aria-modal to dropdown
|
|
50
|
-
dropdown: `<div data-kt-datepicker-dropdown role="dialog" aria-modal="true" aria-label="Date picker" class="hidden {{class}}"></div>`,
|
|
51
|
-
prevButton: `<button type="button" data-kt-datepicker-prev aria-label="Previous month" {{class}}>
|
|
52
|
-
<svg width="16" height="16" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" viewBox="0 0 24 24" aria-hidden="true">
|
|
53
|
-
<path d="m15 18-6-6 6-6"/>
|
|
54
|
-
</svg>
|
|
55
|
-
</button>`,
|
|
56
|
-
nextButton: `<button type="button" data-kt-datepicker-next aria-label="Next month" {{class}}>
|
|
57
|
-
<svg width="16" height="16" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" viewBox="0 0 24 24" aria-hidden="true">
|
|
58
|
-
<path d="m9 18 6-6-6-6"/>
|
|
59
|
-
</svg>
|
|
60
|
-
</button>`,
|
|
61
|
-
// Add role="row" to calendar table rows
|
|
62
|
-
calendarTable: `<table data-kt-datepicker-calendar-table role="grid" aria-label="Calendar" aria-readonly="true" {{class}}><thead><tr role="row">
|
|
63
|
-
<th class="py-1 px-1 text-xs font-semibold text-gray-500 dark:text-gray-400">{{sunday}}</th>
|
|
64
|
-
<th class="py-1 px-1 text-xs font-semibold text-gray-500 dark:text-gray-400">{{monday}}</th>
|
|
65
|
-
<th class="py-1 px-1 text-xs font-semibold text-gray-500 dark:text-gray-400">{{tuesday}}</th>
|
|
66
|
-
<th class="py-1 px-1 text-xs font-semibold text-gray-500 dark:text-gray-400">{{wednesday}}</th>
|
|
67
|
-
<th class="py-1 px-1 text-xs font-semibold text-gray-500 dark:text-gray-400">{{thursday}}</th>
|
|
68
|
-
<th class="py-1 px-1 text-xs font-semibold text-gray-500 dark:text-gray-400">{{friday}}</th>
|
|
69
|
-
<th class="py-1 px-1 text-xs font-semibold text-gray-500 dark:text-gray-400">{{saturday}}</th>
|
|
70
|
-
</tr></thead>{{body}}</table>`,
|
|
71
|
-
calendarBody: `<tbody data-kt-datepicker-calendar-body {{class}}>{{rows}}</tbody>`,
|
|
72
|
-
calendarRow: `<tr data-kt-datepicker-calendar-row role="row" {{class}}>{{cells}}</tr>`,
|
|
73
|
-
todayButton: `<button type="button" data-kt-datepicker-today {{class}}>Today</button>`,
|
|
74
|
-
clearButton: `<button type="button" data-kt-datepicker-clear {{class}}>Clear</button>`,
|
|
75
|
-
applyButton: `<button type="button" data-kt-datepicker-apply {{class}}>Apply</button>`,
|
|
76
|
-
/**
|
|
77
|
-
* Container for multiple calendar months (horizontal multi-month view)
|
|
78
|
-
*/
|
|
79
|
-
multiMonthContainer: `<div data-kt-datepicker-multimonth-container class="flex flex-col md:flex-row gap-4 {{class}}">{{calendars}}</div>`,
|
|
80
|
-
|
|
81
|
-
// Time picker templates
|
|
82
|
-
timePickerWrapper: `<div data-kt-datepicker-time-picker {{class}}>{{timeDisplay}} {{timeControls}}</div>`,
|
|
83
|
-
timeDisplay: `<div data-kt-datepicker-time-display {{class}}>{{timeValue}}</div>`,
|
|
84
|
-
timeControls: `<div data-kt-datepicker-time-controls {{class}}>{{timeUnits}} {{ampmControl}}</div>`,
|
|
85
|
-
timeUnit: `<div data-kt-datepicker-time-unit data-kt-datepicker-time-unit="{{unitType}}" {{class}}>{{upButton}} {{valueDisplay}} {{downButton}}</div>`,
|
|
86
|
-
timeUpButton: `<button type="button" data-kt-datepicker-time-up aria-label="Increment {{unitType}}" {{class}} {{disabled}}>▲</button>`,
|
|
87
|
-
timeDownButton: `<button type="button" data-kt-datepicker-time-down aria-label="Decrement {{unitType}}" {{class}} {{disabled}}>▼</button>`,
|
|
88
|
-
timeValue: `<span data-kt-datepicker-time-value {{class}}>{{value}}</span>`,
|
|
89
|
-
timeSeparator: `<span data-kt-datepicker-time-separator {{class}}>{{separator}}</span>`,
|
|
90
|
-
ampmControl: `<div data-kt-datepicker-ampm-control {{class}}>{{ampmButton}}</div>`,
|
|
91
|
-
ampmButton: `<button type="button" data-kt-datepicker-ampm-button aria-label="Toggle AM/PM" {{class}} {{disabled}}>{{ampmValue}}</button>`,
|
|
92
|
-
/**
|
|
93
|
-
* Panel wrapper for header + calendar
|
|
94
|
-
*/
|
|
95
|
-
panel: `<div data-kt-datepicker-panel {{class}}>{{header}}{{calendar}}</div>`,
|
|
96
|
-
/**
|
|
97
|
-
* Live region for accessibility announcements
|
|
98
|
-
*/
|
|
99
|
-
liveRegion: `<div data-kt-datepicker-live aria-live="polite" {{class}}></div>`,
|
|
100
|
-
/**
|
|
101
|
-
* Container for range input start date segment
|
|
102
|
-
*/
|
|
103
|
-
rangeStartContainer: `<div data-kt-datepicker-segmented-start {{class}}></div>`,
|
|
104
|
-
/**
|
|
105
|
-
* Container for range input end date segment
|
|
106
|
-
*/
|
|
107
|
-
rangeEndContainer: `<div data-kt-datepicker-segmented-end {{class}}></div>`,
|
|
108
|
-
};
|
|
109
|
-
|
|
110
|
-
/**
|
|
111
|
-
* Template rendering options
|
|
112
|
-
*/
|
|
113
|
-
export interface TemplateRenderOptions {
|
|
114
|
-
templateKey: keyof KTDatepickerTemplateStrings;
|
|
115
|
-
data: Record<string, any>;
|
|
116
|
-
configClasses?: Record<string, string>;
|
|
117
|
-
fallbackTemplate?: string | ((data: any) => string);
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
/**
|
|
121
|
-
* Merges default templates with user overrides.
|
|
122
|
-
* User overrides take precedence.
|
|
123
|
-
*/
|
|
124
|
-
export function mergeTemplates(
|
|
125
|
-
defaults: KTDatepickerTemplateStrings,
|
|
126
|
-
overrides?: KTDatepickerTemplateStrings
|
|
127
|
-
): KTDatepickerTemplateStrings {
|
|
128
|
-
return { ...defaults, ...(overrides || {}) };
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
/**
|
|
132
|
-
* Merges default, config, and user templates (string or function)
|
|
133
|
-
* Precedence: default < config < user
|
|
134
|
-
*/
|
|
135
|
-
export function getMergedTemplates(
|
|
136
|
-
configTemplates?: Record<string, string | ((data: any) => string)>,
|
|
137
|
-
userTemplates?: Record<string, string | ((data: any) => string)>
|
|
138
|
-
): Record<string, string | ((data: any) => string)> {
|
|
139
|
-
return {
|
|
140
|
-
...(defaultTemplates as Record<string, string | ((data: any) => string)>),
|
|
141
|
-
...(configTemplates || {}),
|
|
142
|
-
...(userTemplates || {}),
|
|
143
|
-
};
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
/**
|
|
147
|
-
* Renders a template string with data using {{key}} placeholders.
|
|
148
|
-
* Enhanced to handle class placeholders specifically.
|
|
149
|
-
*/
|
|
150
|
-
export function renderTemplateString(
|
|
151
|
-
template: string,
|
|
152
|
-
data: Record<string, any>
|
|
153
|
-
): string {
|
|
154
|
-
return template.replace(/{{(\w+)}}/g, (_, key) => {
|
|
155
|
-
const value = data[key];
|
|
156
|
-
if (value !== undefined) {
|
|
157
|
-
return String(value);
|
|
158
|
-
}
|
|
159
|
-
return '';
|
|
160
|
-
});
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
/**
|
|
164
|
-
* Merges class data with template data for rendering.
|
|
165
|
-
* Extracts class for specific template key from config classes object.
|
|
166
|
-
*/
|
|
167
|
-
export function mergeClassData(
|
|
168
|
-
templateKey: string,
|
|
169
|
-
templateData: Record<string, any>,
|
|
170
|
-
configClasses?: Record<string, string>
|
|
171
|
-
): Record<string, any> {
|
|
172
|
-
const classValue = configClasses?.[templateKey] || '';
|
|
173
|
-
return {
|
|
174
|
-
...templateData,
|
|
175
|
-
class: classValue
|
|
176
|
-
};
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
/**
|
|
180
|
-
* Checks if a template is a function.
|
|
181
|
-
*/
|
|
182
|
-
export function isTemplateFunction(tpl: unknown): tpl is (data: any) => string {
|
|
183
|
-
return typeof tpl === 'function';
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
/**
|
|
187
|
-
* Renders a template string with data and returns a DocumentFragment.
|
|
188
|
-
* Usage: const frag = renderTemplateToDOM(template, data)
|
|
189
|
-
*/
|
|
190
|
-
export function renderTemplateToDOM(template: string, data: Record<string, any> = {}): DocumentFragment {
|
|
191
|
-
const html = renderTemplateString(template, data);
|
|
192
|
-
const frag = document.createDocumentFragment();
|
|
193
|
-
const temp = document.createElement('div');
|
|
194
|
-
temp.innerHTML = html;
|
|
195
|
-
while (temp.firstChild) {
|
|
196
|
-
frag.appendChild(temp.firstChild);
|
|
197
|
-
}
|
|
198
|
-
return frag;
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
/**
|
|
202
|
-
* Unified template renderer for all datepicker UI components
|
|
203
|
-
* Ensures consistent template usage and eliminates scattered rendering logic
|
|
204
|
-
*/
|
|
205
|
-
export class TemplateRenderer {
|
|
206
|
-
private _templates: KTDatepickerTemplateStrings;
|
|
207
|
-
|
|
208
|
-
constructor(templates: KTDatepickerTemplateStrings) {
|
|
209
|
-
this._templates = templates;
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
/**
|
|
213
|
-
* Render a template with data and return HTML string
|
|
214
|
-
*/
|
|
215
|
-
renderTemplateString(options: TemplateRenderOptions): string {
|
|
216
|
-
const { templateKey, data, configClasses, fallbackTemplate } = options;
|
|
217
|
-
|
|
218
|
-
// Get template from template set
|
|
219
|
-
let template = this._templates[templateKey];
|
|
220
|
-
|
|
221
|
-
// Use fallback if template not found
|
|
222
|
-
if (!template && fallbackTemplate) {
|
|
223
|
-
template = fallbackTemplate;
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
// Validate template exists
|
|
227
|
-
if (!template) {
|
|
228
|
-
throw new Error(`Template not found for key: ${templateKey}`);
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
// Merge class data
|
|
232
|
-
const mergedData = mergeClassData(templateKey, data, configClasses);
|
|
233
|
-
|
|
234
|
-
// Render template
|
|
235
|
-
if (isTemplateFunction(template)) {
|
|
236
|
-
return template(mergedData);
|
|
237
|
-
} else {
|
|
238
|
-
return renderTemplateString(template as string, mergedData);
|
|
239
|
-
}
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
/**
|
|
243
|
-
* Render a template with data and return HTMLElement
|
|
244
|
-
*/
|
|
245
|
-
renderTemplateToElement(options: TemplateRenderOptions): HTMLElement {
|
|
246
|
-
const html = this.renderTemplateString(options);
|
|
247
|
-
const fragment = renderTemplateToDOM(html);
|
|
248
|
-
const element = fragment.firstElementChild as HTMLElement;
|
|
249
|
-
|
|
250
|
-
if (!element) {
|
|
251
|
-
throw new Error(`Failed to render template to element for key: ${options.templateKey}`);
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
return element;
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
/**
|
|
258
|
-
* Render a template with data and return DocumentFragment
|
|
259
|
-
*/
|
|
260
|
-
renderTemplateToFragment(options: TemplateRenderOptions): DocumentFragment {
|
|
261
|
-
const html = this.renderTemplateString(options);
|
|
262
|
-
return renderTemplateToDOM(html);
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
/**
|
|
266
|
-
* Check if a template exists
|
|
267
|
-
*/
|
|
268
|
-
hasTemplate(templateKey: keyof KTDatepickerTemplateStrings): boolean {
|
|
269
|
-
return !!this._templates[templateKey];
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
/**
|
|
273
|
-
* Get template by key
|
|
274
|
-
*/
|
|
275
|
-
getTemplate(templateKey: keyof KTDatepickerTemplateStrings): string | ((data: any) => string) | undefined {
|
|
276
|
-
return this._templates[templateKey];
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
/**
|
|
280
|
-
* Update templates
|
|
281
|
-
*/
|
|
282
|
-
updateTemplates(templates: KTDatepickerTemplateStrings): void {
|
|
283
|
-
this._templates = templates;
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
/**
|
|
287
|
-
* Get all templates
|
|
288
|
-
*/
|
|
289
|
-
getTemplates(): KTDatepickerTemplateStrings {
|
|
290
|
-
return { ...this._templates };
|
|
291
|
-
}
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
/**
|
|
295
|
-
* Factory function to create a template renderer
|
|
296
|
-
*/
|
|
297
|
-
export function createTemplateRenderer(templates: KTDatepickerTemplateStrings): TemplateRenderer {
|
|
298
|
-
return new TemplateRenderer(templates);
|
|
299
|
-
}
|
|
300
|
-
|
|
301
|
-
/**
|
|
302
|
-
* Returns the merged template set for a given config.
|
|
303
|
-
*/
|
|
304
|
-
export function getTemplateStrings(config?: KTDatepickerConfig): KTDatepickerTemplateStrings {
|
|
305
|
-
return mergeTemplates(defaultTemplates, config?.templates);
|
|
306
|
-
}
|
|
@@ -1,160 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* date-formatters.test.ts - Unit tests for date formatting utilities
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import { describe, it, expect } from 'vitest';
|
|
6
|
-
import { formatDate, isSameDay, normalizeDateToMidnight } from '../date-formatters';
|
|
7
|
-
|
|
8
|
-
describe('formatDate', () => {
|
|
9
|
-
it('should format date with yyyy-MM-dd format', () => {
|
|
10
|
-
const date = new Date(2024, 0, 15); // January 15, 2024
|
|
11
|
-
expect(formatDate(date, 'yyyy-MM-dd')).toBe('2024-01-15');
|
|
12
|
-
});
|
|
13
|
-
|
|
14
|
-
it('should format date with dd/MM/yyyy format', () => {
|
|
15
|
-
const date = new Date(2024, 0, 15);
|
|
16
|
-
expect(formatDate(date, 'dd/MM/yyyy')).toBe('15/01/2024');
|
|
17
|
-
});
|
|
18
|
-
|
|
19
|
-
it('should format date with time components', () => {
|
|
20
|
-
const date = new Date(2024, 0, 15, 14, 30, 45);
|
|
21
|
-
expect(formatDate(date, 'HH:mm:ss')).toBe('14:30:45');
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
it('should format date with AM/PM indicator', () => {
|
|
25
|
-
const date = new Date(2024, 0, 15, 14, 30); // 2:30 PM
|
|
26
|
-
expect(formatDate(date, 'HH:mm a')).toBe('14:30 PM');
|
|
27
|
-
const morningDate = new Date(2024, 0, 15, 9, 30); // 9:30 AM
|
|
28
|
-
expect(formatDate(morningDate, 'HH:mm a')).toBe('09:30 AM');
|
|
29
|
-
const midnightDate = new Date(2024, 0, 15, 0, 0); // Midnight
|
|
30
|
-
expect(formatDate(midnightDate, 'HH:mm a')).toBe('00:00 AM');
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
it('should handle single digit months and days', () => {
|
|
34
|
-
const date = new Date(2024, 0, 5); // January 5, 2024
|
|
35
|
-
expect(formatDate(date, 'M/d/yyyy')).toBe('1/5/2024');
|
|
36
|
-
expect(formatDate(date, 'MM/dd/yyyy')).toBe('01/05/2024');
|
|
37
|
-
});
|
|
38
|
-
|
|
39
|
-
it('should handle 2-digit year format', () => {
|
|
40
|
-
const date = new Date(2024, 0, 15);
|
|
41
|
-
expect(formatDate(date, 'yy-MM-dd')).toBe('24-01-15');
|
|
42
|
-
});
|
|
43
|
-
|
|
44
|
-
it('should return empty string for invalid date', () => {
|
|
45
|
-
const invalidDate = new Date('invalid');
|
|
46
|
-
expect(formatDate(invalidDate, 'yyyy-MM-dd')).toBe('');
|
|
47
|
-
});
|
|
48
|
-
|
|
49
|
-
it('should return empty string for non-Date object', () => {
|
|
50
|
-
expect(formatDate(null as any, 'yyyy-MM-dd')).toBe('');
|
|
51
|
-
expect(formatDate(undefined as any, 'yyyy-MM-dd')).toBe('');
|
|
52
|
-
});
|
|
53
|
-
|
|
54
|
-
it('should handle complex format strings', () => {
|
|
55
|
-
const date = new Date(2024, 0, 15, 14, 30, 45);
|
|
56
|
-
expect(formatDate(date, 'yyyy-MM-dd HH:mm:ss')).toBe('2024-01-15 14:30:45');
|
|
57
|
-
});
|
|
58
|
-
});
|
|
59
|
-
|
|
60
|
-
describe('isSameDay', () => {
|
|
61
|
-
it('should return true for same day with different times', () => {
|
|
62
|
-
const date1 = new Date(2024, 0, 15, 10, 30);
|
|
63
|
-
const date2 = new Date(2024, 0, 15, 14, 45);
|
|
64
|
-
expect(isSameDay(date1, date2)).toBe(true);
|
|
65
|
-
});
|
|
66
|
-
|
|
67
|
-
it('should return false for different days', () => {
|
|
68
|
-
const date1 = new Date(2024, 0, 15);
|
|
69
|
-
const date2 = new Date(2024, 0, 16);
|
|
70
|
-
expect(isSameDay(date1, date2)).toBe(false);
|
|
71
|
-
});
|
|
72
|
-
|
|
73
|
-
it('should return false for different months', () => {
|
|
74
|
-
const date1 = new Date(2024, 0, 15);
|
|
75
|
-
const date2 = new Date(2024, 1, 15);
|
|
76
|
-
expect(isSameDay(date1, date2)).toBe(false);
|
|
77
|
-
});
|
|
78
|
-
|
|
79
|
-
it('should return false for different years', () => {
|
|
80
|
-
const date1 = new Date(2024, 0, 15);
|
|
81
|
-
const date2 = new Date(2025, 0, 15);
|
|
82
|
-
expect(isSameDay(date1, date2)).toBe(false);
|
|
83
|
-
});
|
|
84
|
-
|
|
85
|
-
it('should return true for same date at midnight', () => {
|
|
86
|
-
const date1 = new Date(2024, 0, 15, 0, 0, 0);
|
|
87
|
-
const date2 = new Date(2024, 0, 15, 0, 0, 0);
|
|
88
|
-
expect(isSameDay(date1, date2)).toBe(true);
|
|
89
|
-
});
|
|
90
|
-
|
|
91
|
-
it('should handle edge case: last day of month', () => {
|
|
92
|
-
const date1 = new Date(2024, 0, 31, 10, 0);
|
|
93
|
-
const date2 = new Date(2024, 0, 31, 20, 0);
|
|
94
|
-
expect(isSameDay(date1, date2)).toBe(true);
|
|
95
|
-
});
|
|
96
|
-
|
|
97
|
-
it('should handle edge case: first day of month', () => {
|
|
98
|
-
const date1 = new Date(2024, 0, 1, 0, 0);
|
|
99
|
-
const date2 = new Date(2024, 0, 1, 23, 59);
|
|
100
|
-
expect(isSameDay(date1, date2)).toBe(true);
|
|
101
|
-
});
|
|
102
|
-
});
|
|
103
|
-
|
|
104
|
-
describe('normalizeDateToMidnight', () => {
|
|
105
|
-
it('should set time to 00:00:00', () => {
|
|
106
|
-
const date = new Date(2024, 0, 15, 14, 30, 45);
|
|
107
|
-
const normalized = normalizeDateToMidnight(date);
|
|
108
|
-
expect(normalized.getHours()).toBe(0);
|
|
109
|
-
expect(normalized.getMinutes()).toBe(0);
|
|
110
|
-
expect(normalized.getSeconds()).toBe(0);
|
|
111
|
-
expect(normalized.getMilliseconds()).toBe(0);
|
|
112
|
-
});
|
|
113
|
-
|
|
114
|
-
it('should preserve date components', () => {
|
|
115
|
-
const date = new Date(2024, 0, 15, 14, 30, 45);
|
|
116
|
-
const normalized = normalizeDateToMidnight(date);
|
|
117
|
-
expect(normalized.getFullYear()).toBe(2024);
|
|
118
|
-
expect(normalized.getMonth()).toBe(0);
|
|
119
|
-
expect(normalized.getDate()).toBe(15);
|
|
120
|
-
});
|
|
121
|
-
|
|
122
|
-
it('should return a new Date object', () => {
|
|
123
|
-
const date = new Date(2024, 0, 15, 14, 30, 45);
|
|
124
|
-
const normalized = normalizeDateToMidnight(date);
|
|
125
|
-
expect(normalized).not.toBe(date);
|
|
126
|
-
expect(date.getHours()).toBe(14); // Original date unchanged
|
|
127
|
-
});
|
|
128
|
-
|
|
129
|
-
it('should handle date already at midnight', () => {
|
|
130
|
-
const date = new Date(2024, 0, 15, 0, 0, 0);
|
|
131
|
-
const normalized = normalizeDateToMidnight(date);
|
|
132
|
-
expect(normalized.getHours()).toBe(0);
|
|
133
|
-
expect(normalized.getMinutes()).toBe(0);
|
|
134
|
-
expect(normalized.getSeconds()).toBe(0);
|
|
135
|
-
});
|
|
136
|
-
|
|
137
|
-
it('should handle date at end of day', () => {
|
|
138
|
-
const date = new Date(2024, 0, 15, 23, 59, 59);
|
|
139
|
-
const normalized = normalizeDateToMidnight(date);
|
|
140
|
-
expect(normalized.getHours()).toBe(0);
|
|
141
|
-
expect(normalized.getDate()).toBe(15); // Same day
|
|
142
|
-
});
|
|
143
|
-
|
|
144
|
-
it('should work with dates at different times', () => {
|
|
145
|
-
const times = [
|
|
146
|
-
new Date(2024, 0, 15, 0, 0, 0),
|
|
147
|
-
new Date(2024, 0, 15, 12, 0, 0),
|
|
148
|
-
new Date(2024, 0, 15, 23, 59, 59)
|
|
149
|
-
];
|
|
150
|
-
|
|
151
|
-
times.forEach(date => {
|
|
152
|
-
const normalized = normalizeDateToMidnight(date);
|
|
153
|
-
expect(normalized.getHours()).toBe(0);
|
|
154
|
-
expect(normalized.getMinutes()).toBe(0);
|
|
155
|
-
expect(normalized.getSeconds()).toBe(0);
|
|
156
|
-
expect(normalized.getDate()).toBe(15);
|
|
157
|
-
});
|
|
158
|
-
});
|
|
159
|
-
});
|
|
160
|
-
|
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect } from 'vitest';
|
|
2
|
-
import { getDateKey, isSameDayByKey } from '../date-utils';
|
|
3
|
-
|
|
4
|
-
describe('Date Utils - Date Key Functions', () => {
|
|
5
|
-
describe('getDateKey', () => {
|
|
6
|
-
it('should generate correct date key for a given date', () => {
|
|
7
|
-
const date = new Date(2024, 0, 15); // Jan 15, 2024
|
|
8
|
-
const key = getDateKey(date);
|
|
9
|
-
expect(key).toBe(20240115); // year * 10000 + month * 100 + day
|
|
10
|
-
});
|
|
11
|
-
|
|
12
|
-
it('should handle single-digit months and days', () => {
|
|
13
|
-
const date = new Date(2024, 0, 5); // Jan 5, 2024
|
|
14
|
-
const key = getDateKey(date);
|
|
15
|
-
expect(key).toBe(20240105);
|
|
16
|
-
});
|
|
17
|
-
|
|
18
|
-
it('should handle year boundaries correctly', () => {
|
|
19
|
-
const date1 = new Date(2023, 11, 31); // Dec 31, 2023
|
|
20
|
-
const date2 = new Date(2024, 0, 1); // Jan 1, 2024
|
|
21
|
-
expect(getDateKey(date1)).toBe(20231231);
|
|
22
|
-
expect(getDateKey(date2)).toBe(20240101);
|
|
23
|
-
});
|
|
24
|
-
|
|
25
|
-
it('should handle leap years correctly', () => {
|
|
26
|
-
const date = new Date(2024, 1, 29); // Feb 29, 2024 (leap year)
|
|
27
|
-
const key = getDateKey(date);
|
|
28
|
-
expect(key).toBe(20240229);
|
|
29
|
-
});
|
|
30
|
-
|
|
31
|
-
it('should ignore time components', () => {
|
|
32
|
-
const date1 = new Date(2024, 0, 15, 0, 0, 0); // Jan 15, 2024 00:00:00
|
|
33
|
-
const date2 = new Date(2024, 0, 15, 23, 59, 59); // Jan 15, 2024 23:59:59
|
|
34
|
-
expect(getDateKey(date1)).toBe(getDateKey(date2));
|
|
35
|
-
});
|
|
36
|
-
|
|
37
|
-
it('should generate unique keys for different dates', () => {
|
|
38
|
-
const date1 = new Date(2024, 0, 15);
|
|
39
|
-
const date2 = new Date(2024, 0, 16);
|
|
40
|
-
const date3 = new Date(2024, 1, 15);
|
|
41
|
-
const date4 = new Date(2025, 0, 15);
|
|
42
|
-
|
|
43
|
-
const key1 = getDateKey(date1);
|
|
44
|
-
const key2 = getDateKey(date2);
|
|
45
|
-
const key3 = getDateKey(date3);
|
|
46
|
-
const key4 = getDateKey(date4);
|
|
47
|
-
|
|
48
|
-
expect(key1).not.toBe(key2);
|
|
49
|
-
expect(key1).not.toBe(key3);
|
|
50
|
-
expect(key1).not.toBe(key4);
|
|
51
|
-
});
|
|
52
|
-
});
|
|
53
|
-
|
|
54
|
-
describe('isSameDayByKey', () => {
|
|
55
|
-
it('should return true for same calendar day', () => {
|
|
56
|
-
const date1 = new Date(2024, 0, 15, 10, 30, 0);
|
|
57
|
-
const date2 = new Date(2024, 0, 15, 20, 45, 0);
|
|
58
|
-
expect(isSameDayByKey(date1, date2)).toBe(true);
|
|
59
|
-
});
|
|
60
|
-
|
|
61
|
-
it('should return false for different days', () => {
|
|
62
|
-
const date1 = new Date(2024, 0, 15);
|
|
63
|
-
const date2 = new Date(2024, 0, 16);
|
|
64
|
-
expect(isSameDayByKey(date1, date2)).toBe(false);
|
|
65
|
-
});
|
|
66
|
-
|
|
67
|
-
it('should return false for different months', () => {
|
|
68
|
-
const date1 = new Date(2024, 0, 15);
|
|
69
|
-
const date2 = new Date(2024, 1, 15);
|
|
70
|
-
expect(isSameDayByKey(date1, date2)).toBe(false);
|
|
71
|
-
});
|
|
72
|
-
|
|
73
|
-
it('should return false for different years', () => {
|
|
74
|
-
const date1 = new Date(2024, 0, 15);
|
|
75
|
-
const date2 = new Date(2025, 0, 15);
|
|
76
|
-
expect(isSameDayByKey(date1, date2)).toBe(false);
|
|
77
|
-
});
|
|
78
|
-
|
|
79
|
-
it('should handle year boundaries correctly', () => {
|
|
80
|
-
const date1 = new Date(2023, 11, 31);
|
|
81
|
-
const date2 = new Date(2024, 0, 1);
|
|
82
|
-
expect(isSameDayByKey(date1, date2)).toBe(false);
|
|
83
|
-
});
|
|
84
|
-
});
|
|
85
|
-
});
|
|
86
|
-
|