@keenthemes/ktui 1.0.29 → 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/dist/ktui.js +3942 -8634
- package/dist/ktui.min.js +1 -1
- package/dist/ktui.min.js.map +1 -1
- package/dist/styles.css +0 -196
- 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 -5
- 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 -3
- package/lib/esm/index.js.map +1 -1
- package/package.json +9 -2
- 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/textarea/textarea.css +0 -1
- package/src/index.ts +0 -4
- package/styles.css +0 -1
- package/lib/cjs/components/datepicker/calendar.js +0 -1061
- package/lib/cjs/components/datepicker/calendar.js.map +0 -1
- package/lib/cjs/components/datepicker/config.js +0 -332
- package/lib/cjs/components/datepicker/config.js.map +0 -1
- package/lib/cjs/components/datepicker/datepicker.js +0 -949
- package/lib/cjs/components/datepicker/datepicker.js.map +0 -1
- package/lib/cjs/components/datepicker/dropdown.js +0 -635
- package/lib/cjs/components/datepicker/dropdown.js.map +0 -1
- package/lib/cjs/components/datepicker/events.js +0 -129
- package/lib/cjs/components/datepicker/events.js.map +0 -1
- package/lib/cjs/components/datepicker/index.js +0 -13
- package/lib/cjs/components/datepicker/index.js.map +0 -1
- package/lib/cjs/components/datepicker/keyboard.js +0 -536
- package/lib/cjs/components/datepicker/keyboard.js.map +0 -1
- package/lib/cjs/components/datepicker/locales.js +0 -78
- package/lib/cjs/components/datepicker/locales.js.map +0 -1
- package/lib/cjs/components/datepicker/templates.js +0 -403
- package/lib/cjs/components/datepicker/templates.js.map +0 -1
- package/lib/cjs/components/datepicker/types.js +0 -23
- package/lib/cjs/components/datepicker/types.js.map +0 -1
- package/lib/cjs/components/datepicker/utils.js +0 -524
- package/lib/cjs/components/datepicker/utils.js.map +0 -1
- package/lib/esm/components/datepicker/calendar.js +0 -1058
- package/lib/esm/components/datepicker/calendar.js.map +0 -1
- package/lib/esm/components/datepicker/config.js +0 -329
- package/lib/esm/components/datepicker/config.js.map +0 -1
- package/lib/esm/components/datepicker/datepicker.js +0 -946
- package/lib/esm/components/datepicker/datepicker.js.map +0 -1
- package/lib/esm/components/datepicker/dropdown.js +0 -632
- package/lib/esm/components/datepicker/dropdown.js.map +0 -1
- package/lib/esm/components/datepicker/events.js +0 -126
- package/lib/esm/components/datepicker/events.js.map +0 -1
- package/lib/esm/components/datepicker/index.js +0 -9
- package/lib/esm/components/datepicker/index.js.map +0 -1
- package/lib/esm/components/datepicker/keyboard.js +0 -533
- package/lib/esm/components/datepicker/keyboard.js.map +0 -1
- package/lib/esm/components/datepicker/locales.js +0 -74
- package/lib/esm/components/datepicker/locales.js.map +0 -1
- package/lib/esm/components/datepicker/templates.js +0 -390
- package/lib/esm/components/datepicker/templates.js.map +0 -1
- package/lib/esm/components/datepicker/types.js +0 -20
- package/lib/esm/components/datepicker/types.js.map +0 -1
- package/lib/esm/components/datepicker/utils.js +0 -508
- package/lib/esm/components/datepicker/utils.js.map +0 -1
- package/src/components/datepicker/calendar.ts +0 -1397
- package/src/components/datepicker/config.ts +0 -368
- package/src/components/datepicker/datepicker.css +0 -7
- package/src/components/datepicker/datepicker.ts +0 -1287
- package/src/components/datepicker/dropdown.ts +0 -757
- package/src/components/datepicker/events.ts +0 -149
- package/src/components/datepicker/index.ts +0 -10
- package/src/components/datepicker/keyboard.ts +0 -646
- package/src/components/datepicker/locales.ts +0 -80
- package/src/components/datepicker/templates.ts +0 -792
- package/src/components/datepicker/types.ts +0 -154
- package/src/components/datepicker/utils.ts +0 -631
|
@@ -1,368 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* KTUI - Free & Open-Source Tailwind UI Components by Keenthemes
|
|
3
|
-
* Copyright 2025 by Keenthemes Inc
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import { DefaultLocales } from './locales';
|
|
7
|
-
import {
|
|
8
|
-
KTDatepickerConfigInterface,
|
|
9
|
-
KTDatepickerStateInterface,
|
|
10
|
-
DateRangeInterface,
|
|
11
|
-
TimeConfigInterface,
|
|
12
|
-
} from './types';
|
|
13
|
-
import { isSameDay, isDateDisabled } from './utils';
|
|
14
|
-
import { KTDatepickerEventManager, KTDatepickerEventName } from './events';
|
|
15
|
-
|
|
16
|
-
export const DefaultConfig: KTDatepickerConfigInterface = {
|
|
17
|
-
locale: 'en-US',
|
|
18
|
-
locales: DefaultLocales, // all locales
|
|
19
|
-
|
|
20
|
-
weekDays: 'min',
|
|
21
|
-
forceLeadingZero: true,
|
|
22
|
-
|
|
23
|
-
// 0-indexed month
|
|
24
|
-
// minDate: new Date(2024, 7, 20),
|
|
25
|
-
// maxDate: new Date(2024, 8, 10),
|
|
26
|
-
|
|
27
|
-
// supported formats: refer to dateFormat
|
|
28
|
-
// minDate: '20/08/2024',
|
|
29
|
-
// maxDate: '10/09/2024',
|
|
30
|
-
|
|
31
|
-
// Calendar
|
|
32
|
-
visibleMonths: 1, // visible months calendar to show
|
|
33
|
-
visibleYears: 10, // visible years span to show on year selection
|
|
34
|
-
keepViewModeOnSelection: false, // automatically switch view modes when selecting month/year
|
|
35
|
-
|
|
36
|
-
// Date
|
|
37
|
-
format: 'dd/MM/yyyy',
|
|
38
|
-
|
|
39
|
-
// Time
|
|
40
|
-
enableTime: false,
|
|
41
|
-
timeFormat: 'hh:mm:ss A ZZZ', // 12-hours time format
|
|
42
|
-
// timeFormat: 'HH:mm:ss ZZZ', // 24-hours time format
|
|
43
|
-
am: 'AM',
|
|
44
|
-
pm: 'PM',
|
|
45
|
-
hourStep: 1,
|
|
46
|
-
// minuteStep: 5,
|
|
47
|
-
// secondStep: 10,
|
|
48
|
-
// disabledHours: [0, 1, 2, 3, 4, 5, 6, 22, 23],
|
|
49
|
-
// disabledMinutes: [0, 1, 2, 3],
|
|
50
|
-
|
|
51
|
-
// Date range
|
|
52
|
-
range: false,
|
|
53
|
-
rangeSeparator: ' - ',
|
|
54
|
-
|
|
55
|
-
// Multi-date selection
|
|
56
|
-
multiDateSelection: false,
|
|
57
|
-
maxDates: 0, // 0 means unlimited
|
|
58
|
-
|
|
59
|
-
// Date blocking patterns
|
|
60
|
-
disabledDates: [],
|
|
61
|
-
enableNaturalLanguage: true,
|
|
62
|
-
|
|
63
|
-
// Animation settings
|
|
64
|
-
animationDuration: 250,
|
|
65
|
-
animationEasing: '',
|
|
66
|
-
animationEnterClass: '',
|
|
67
|
-
animationExitClass: '',
|
|
68
|
-
};
|
|
69
|
-
|
|
70
|
-
/**
|
|
71
|
-
* State manager class for KTDatepicker
|
|
72
|
-
* Handles state management and configuration
|
|
73
|
-
*/
|
|
74
|
-
export class KTDatepickerStateManager {
|
|
75
|
-
private _element: HTMLElement;
|
|
76
|
-
private _config: KTDatepickerConfigInterface;
|
|
77
|
-
private _state: KTDatepickerStateInterface;
|
|
78
|
-
private _events: KTDatepickerEventManager;
|
|
79
|
-
|
|
80
|
-
/**
|
|
81
|
-
* Constructor for the KTDatepickerStateManager class
|
|
82
|
-
*
|
|
83
|
-
* @param element - The datepicker element
|
|
84
|
-
* @param config - Configuration object
|
|
85
|
-
*/
|
|
86
|
-
constructor(
|
|
87
|
-
element: HTMLElement,
|
|
88
|
-
config?: Partial<KTDatepickerConfigInterface>,
|
|
89
|
-
) {
|
|
90
|
-
this._element = element;
|
|
91
|
-
this._config = this._mergeConfig(config || {});
|
|
92
|
-
this._state = this._initializeState();
|
|
93
|
-
this._events = new KTDatepickerEventManager(element);
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
/**
|
|
97
|
-
* Merge provided configuration with default configuration
|
|
98
|
-
*
|
|
99
|
-
* @param config - User provided configuration
|
|
100
|
-
* @returns Merged configuration
|
|
101
|
-
*/
|
|
102
|
-
private _mergeConfig(
|
|
103
|
-
config: Partial<KTDatepickerConfigInterface>,
|
|
104
|
-
): KTDatepickerConfigInterface {
|
|
105
|
-
return { ...DefaultConfig, ...config };
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
/**
|
|
109
|
-
* Initialize the state object with default values
|
|
110
|
-
*/
|
|
111
|
-
private _initializeState(): KTDatepickerStateInterface {
|
|
112
|
-
const now = new Date();
|
|
113
|
-
const state: KTDatepickerStateInterface = {
|
|
114
|
-
currentDate: now,
|
|
115
|
-
selectedDate: null,
|
|
116
|
-
selectedDateRange: null,
|
|
117
|
-
selectedDates: [],
|
|
118
|
-
viewMode: 'days',
|
|
119
|
-
isOpen: false,
|
|
120
|
-
isFocused: false,
|
|
121
|
-
isRangeSelectionStart: true,
|
|
122
|
-
isRangeSelectionInProgress: false,
|
|
123
|
-
selectedTime: null,
|
|
124
|
-
prevIsOpen: false,
|
|
125
|
-
};
|
|
126
|
-
|
|
127
|
-
return state;
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
/**
|
|
131
|
-
* Get the current configuration
|
|
132
|
-
*
|
|
133
|
-
* @returns Current configuration
|
|
134
|
-
*/
|
|
135
|
-
public getConfig(): KTDatepickerConfigInterface {
|
|
136
|
-
return this._config;
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
/**
|
|
140
|
-
* Get the current state
|
|
141
|
-
*
|
|
142
|
-
* @returns Current state
|
|
143
|
-
*/
|
|
144
|
-
public getState(): KTDatepickerStateInterface {
|
|
145
|
-
return this._state;
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
/**
|
|
149
|
-
* Set the selected date
|
|
150
|
-
*
|
|
151
|
-
* @param date - Date to select
|
|
152
|
-
*/
|
|
153
|
-
public setSelectedDate(date: Date | null): void {
|
|
154
|
-
const state = this._state;
|
|
155
|
-
const config = this._config;
|
|
156
|
-
|
|
157
|
-
if (date === null) {
|
|
158
|
-
// Clear selection
|
|
159
|
-
state.selectedDate = null;
|
|
160
|
-
state.selectedDateRange = null;
|
|
161
|
-
state.isRangeSelectionInProgress = false;
|
|
162
|
-
this._dispatchChangeEvent();
|
|
163
|
-
return;
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
// Check if the date is disabled (outside min/max range or explicitly disabled)
|
|
167
|
-
// We add this check here as a second defense layer beyond the UI checks
|
|
168
|
-
if (isDateDisabled(date, config)) {
|
|
169
|
-
console.log(
|
|
170
|
-
'Date is disabled in setSelectedDate, ignoring selection:',
|
|
171
|
-
date.toISOString(),
|
|
172
|
-
);
|
|
173
|
-
return;
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
if (config.range) {
|
|
177
|
-
// Handle range selection
|
|
178
|
-
if (!state.selectedDateRange) {
|
|
179
|
-
// Initialize range object if it doesn't exist
|
|
180
|
-
state.selectedDateRange = { startDate: null, endDate: null };
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
// If start date isn't set or if we're resetting the range, set the start date
|
|
184
|
-
if (
|
|
185
|
-
!state.selectedDateRange.startDate ||
|
|
186
|
-
state.isRangeSelectionStart ||
|
|
187
|
-
state.selectedDateRange.endDate
|
|
188
|
-
) {
|
|
189
|
-
// Reset the range with a new start date
|
|
190
|
-
state.selectedDateRange.startDate = date;
|
|
191
|
-
state.selectedDateRange.endDate = null;
|
|
192
|
-
state.isRangeSelectionStart = false; // We've selected the start, next will be end
|
|
193
|
-
|
|
194
|
-
// Set the flag to keep dropdown open during range selection
|
|
195
|
-
state.isRangeSelectionInProgress = true;
|
|
196
|
-
console.log(
|
|
197
|
-
'Range start selected - setting isRangeSelectionInProgress to true',
|
|
198
|
-
);
|
|
199
|
-
} else {
|
|
200
|
-
// Set the end date if the start date is already set
|
|
201
|
-
// Ensure that start is before end (swap if needed)
|
|
202
|
-
if (date < state.selectedDateRange.startDate) {
|
|
203
|
-
// Swap dates if the selected date is before the start date
|
|
204
|
-
state.selectedDateRange.endDate = state.selectedDateRange.startDate;
|
|
205
|
-
state.selectedDateRange.startDate = date;
|
|
206
|
-
} else {
|
|
207
|
-
state.selectedDateRange.endDate = date;
|
|
208
|
-
}
|
|
209
|
-
state.isRangeSelectionStart = true; // Reset for next range selection
|
|
210
|
-
|
|
211
|
-
// Clear the flag as range selection is complete
|
|
212
|
-
state.isRangeSelectionInProgress = false;
|
|
213
|
-
console.log(
|
|
214
|
-
'Range end selected - setting isRangeSelectionInProgress to false',
|
|
215
|
-
);
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
// For date range, we still set selectedDate for current focus
|
|
219
|
-
state.selectedDate = date;
|
|
220
|
-
|
|
221
|
-
// Trigger event with range data
|
|
222
|
-
this._dispatchChangeEvent();
|
|
223
|
-
} else {
|
|
224
|
-
// Single date selection
|
|
225
|
-
state.selectedDate = date;
|
|
226
|
-
|
|
227
|
-
// Multi-date selection
|
|
228
|
-
if (config.multiDateSelection) {
|
|
229
|
-
// Add or remove the date from the array
|
|
230
|
-
const existingIndex = state.selectedDates.findIndex((d) =>
|
|
231
|
-
isSameDay(d, date),
|
|
232
|
-
);
|
|
233
|
-
if (existingIndex !== -1) {
|
|
234
|
-
// Remove if already selected
|
|
235
|
-
state.selectedDates.splice(existingIndex, 1);
|
|
236
|
-
} else if (state.selectedDates.length < config.maxDates) {
|
|
237
|
-
// Add if not exceeding max
|
|
238
|
-
state.selectedDates.push(date);
|
|
239
|
-
}
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
// Trigger event with single date data
|
|
243
|
-
this._dispatchChangeEvent();
|
|
244
|
-
}
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
/**
|
|
248
|
-
* Set the current view date (month/year being viewed)
|
|
249
|
-
*
|
|
250
|
-
* @param date - Date to set as current view
|
|
251
|
-
*/
|
|
252
|
-
public setCurrentDate(date: Date): void {
|
|
253
|
-
this._state.currentDate = date;
|
|
254
|
-
this._dispatchEvent('month-change', {
|
|
255
|
-
month: date.getMonth(),
|
|
256
|
-
year: date.getFullYear(),
|
|
257
|
-
});
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
/**
|
|
261
|
-
* Set the selected time
|
|
262
|
-
*
|
|
263
|
-
* @param time - Time configuration to set
|
|
264
|
-
*/
|
|
265
|
-
public setSelectedTime(time: TimeConfigInterface | null): void {
|
|
266
|
-
this._state.selectedTime = time;
|
|
267
|
-
this._dispatchChangeEvent();
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
/**
|
|
271
|
-
* Set the view mode (days, months, years)
|
|
272
|
-
*
|
|
273
|
-
* @param mode - View mode to set
|
|
274
|
-
*/
|
|
275
|
-
public setViewMode(mode: 'days' | 'months' | 'years'): void {
|
|
276
|
-
this._state.viewMode = mode;
|
|
277
|
-
this._dispatchEvent('view-mode-change', { mode });
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
/**
|
|
281
|
-
* Set the open state of the datepicker
|
|
282
|
-
*
|
|
283
|
-
* @param isOpen - Whether the datepicker is open
|
|
284
|
-
*/
|
|
285
|
-
public setOpen(isOpen: boolean): void {
|
|
286
|
-
this._state.isOpen = isOpen;
|
|
287
|
-
this._dispatchEvent(isOpen ? 'open' : 'close');
|
|
288
|
-
|
|
289
|
-
// Call callback if defined
|
|
290
|
-
if (isOpen && this._config.onOpen) {
|
|
291
|
-
this._config.onOpen();
|
|
292
|
-
} else if (!isOpen && this._config.onClose) {
|
|
293
|
-
this._config.onClose();
|
|
294
|
-
}
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
/**
|
|
298
|
-
* Set the focus state of the datepicker
|
|
299
|
-
*
|
|
300
|
-
* @param isFocused - Whether the datepicker is focused
|
|
301
|
-
*/
|
|
302
|
-
public setFocused(isFocused: boolean): void {
|
|
303
|
-
this._state.isFocused = isFocused;
|
|
304
|
-
this._dispatchEvent(isFocused ? 'focus' : 'blur');
|
|
305
|
-
}
|
|
306
|
-
|
|
307
|
-
/**
|
|
308
|
-
* Reset the state to initial values
|
|
309
|
-
*/
|
|
310
|
-
public resetState(): void {
|
|
311
|
-
this._state = this._initializeState();
|
|
312
|
-
this._dispatchEvent('reset');
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
/**
|
|
316
|
-
* Dispatch change event with current date/time selection
|
|
317
|
-
*/
|
|
318
|
-
private _dispatchChangeEvent(): void {
|
|
319
|
-
let payload: any = {};
|
|
320
|
-
|
|
321
|
-
if (this._config.range && this._state.selectedDateRange) {
|
|
322
|
-
payload.selectedDateRange = this._state.selectedDateRange;
|
|
323
|
-
} else if (this._config.multiDateSelection) {
|
|
324
|
-
payload.selectedDates = [...this._state.selectedDates];
|
|
325
|
-
} else {
|
|
326
|
-
payload.selectedDate = this._state.selectedDate;
|
|
327
|
-
}
|
|
328
|
-
|
|
329
|
-
if (this._config.enableTime && this._state.selectedTime) {
|
|
330
|
-
payload.selectedTime = { ...this._state.selectedTime };
|
|
331
|
-
}
|
|
332
|
-
|
|
333
|
-
this._events.dispatchDateChangeEvent(payload);
|
|
334
|
-
|
|
335
|
-
// Call onChange callback if defined
|
|
336
|
-
if (this._config.onChange) {
|
|
337
|
-
let value: Date | null | DateRangeInterface;
|
|
338
|
-
|
|
339
|
-
if (this._config.range) {
|
|
340
|
-
value = this._state.selectedDateRange || {
|
|
341
|
-
startDate: null,
|
|
342
|
-
endDate: null,
|
|
343
|
-
};
|
|
344
|
-
} else {
|
|
345
|
-
value = this._state.selectedDate;
|
|
346
|
-
}
|
|
347
|
-
|
|
348
|
-
this._config.onChange(value);
|
|
349
|
-
}
|
|
350
|
-
}
|
|
351
|
-
|
|
352
|
-
/**
|
|
353
|
-
* Dispatch custom event
|
|
354
|
-
*
|
|
355
|
-
* @param eventName - Name of the event
|
|
356
|
-
* @param payload - Optional payload data
|
|
357
|
-
*/
|
|
358
|
-
private _dispatchEvent(eventName: string, payload?: any): void {
|
|
359
|
-
this._events.dispatchEvent(eventName, payload);
|
|
360
|
-
}
|
|
361
|
-
|
|
362
|
-
/**
|
|
363
|
-
* Get the event manager instance
|
|
364
|
-
*/
|
|
365
|
-
public getEventManager(): KTDatepickerEventManager {
|
|
366
|
-
return this._events;
|
|
367
|
-
}
|
|
368
|
-
}
|