design-system-next 2.24.2 → 2.26.0
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/design-system-next.es.d.ts +152 -114
- package/dist/design-system-next.es.js +10058 -9379
- package/dist/design-system-next.es.js.gz +0 -0
- package/dist/design-system-next.umd.js +12 -12
- package/dist/design-system-next.umd.js.gz +0 -0
- package/dist/main.css +1 -1
- package/dist/main.css.gz +0 -0
- package/package.json +3 -2
- package/src/App.vue +1 -89
- package/src/components/date-picker/date-picker.ts +9 -12
- package/src/components/date-picker/date-picker.vue +1 -1
- package/src/components/date-picker/date-range-picker/date-range-picker.ts +9 -12
- package/src/components/date-picker/date-range-picker/use-date-range-picker.ts +64 -49
- package/src/components/date-picker/month-year-picker/month-year-picker.ts +134 -0
- package/src/components/date-picker/month-year-picker/month-year-picker.vue +233 -0
- package/src/components/date-picker/month-year-picker/use-month-year-picker.ts +603 -0
- package/src/components/date-picker/use-date-picker.ts +88 -147
- package/src/components/list/list-item/list-item.ts +60 -60
- package/src/components/list/list.ts +5 -0
- package/src/components/list/list.vue +2 -0
- package/src/components/list/use-list.ts +36 -3
- package/src/components/radio-grouped/radio-grouped.ts +65 -65
- package/src/components/radio-grouped/use-radio-grouped.ts +62 -62
- package/src/components/select/select-multiple/use-select-multiple.ts +7 -3
- package/src/components/select/use-select.ts +9 -5
- package/src/components/sidepanel/sidepanel.ts +7 -0
- package/src/components/sidepanel/sidepanel.vue +24 -4
- package/src/components/sidepanel/use-sidepanel.ts +4 -0
- package/src/components/table/table-header-dropdown/table-header-dropdown.vue +5 -1
- package/src/components/table/table.vue +14 -0
- package/src/components/table/use-table.ts +1 -2
package/src/App.vue
CHANGED
|
@@ -1,91 +1,3 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div
|
|
3
|
-
<spr-table
|
|
4
|
-
action
|
|
5
|
-
:headers="headers"
|
|
6
|
-
:data-table="data"
|
|
7
|
-
is-multi-select
|
|
8
|
-
:selected-key-id="'name'"
|
|
9
|
-
show-header-filter
|
|
10
|
-
@on-apply-filter="(filters) => console.log(filters)"
|
|
11
|
-
/>
|
|
12
|
-
</div>
|
|
2
|
+
<div>Test Component Here</div>
|
|
13
3
|
</template>
|
|
14
|
-
|
|
15
|
-
<script setup lang="ts">
|
|
16
|
-
import SprTable from './components/table/table.vue';
|
|
17
|
-
import { ref } from 'vue';
|
|
18
|
-
import { Header } from './components/table/table';
|
|
19
|
-
|
|
20
|
-
const headers = ref<Header[]>([
|
|
21
|
-
{ field: 'name', name: 'Role Name', sort: false, hasAvatar: true, hasSubtext: true, width: '250px',
|
|
22
|
-
filterList: [
|
|
23
|
-
{ text: 'Role 11', value: 'role11' },
|
|
24
|
-
{ text: 'Role 12', value: 'role12' },
|
|
25
|
-
{ text: 'Role 13', value: 'role13' },
|
|
26
|
-
{ text: 'Role 14', value: 'role14' },
|
|
27
|
-
{ text: 'Role 15', value: 'role15' }
|
|
28
|
-
]
|
|
29
|
-
},
|
|
30
|
-
{ field: 'firstUpdate', name: 'Date', sort: false, hasAvatar: false, hasSubtext: false, width: '150px',
|
|
31
|
-
filterList: [
|
|
32
|
-
{ text: 'Jan 10, 2025', value: 'jan10' },
|
|
33
|
-
{ text: 'Jan 11, 2025', value: 'jan11' },
|
|
34
|
-
{ text: 'Jan 12, 2025', value: 'jan12' },
|
|
35
|
-
{ text: 'Jan 13, 2025', value: 'jan13' },
|
|
36
|
-
{ text: 'Jan 14, 2025', value: 'jan14' }
|
|
37
|
-
]
|
|
38
|
-
},
|
|
39
|
-
{ field: 'lastUpdate', name: 'Date', sort: false, hasAvatar: false, hasSubtext: false, width: '150px',
|
|
40
|
-
filterList: [
|
|
41
|
-
{ text: 'Dec 10, 2025', value: 'dec10' },
|
|
42
|
-
{ text: 'Dec 11, 2025', value: 'dec11' },
|
|
43
|
-
{ text: 'Dec 12, 2025', value: 'dec12' },
|
|
44
|
-
{ text: 'Dec 13, 2025', value: 'dec13' },
|
|
45
|
-
{ text: 'Dec 14, 2025', value: 'dec14' }
|
|
46
|
-
]
|
|
47
|
-
},
|
|
48
|
-
{ field: 'note', name: 'Note', sort: false, hasAvatar: false, hasSubtext: true, width: '300px',
|
|
49
|
-
filterList: [
|
|
50
|
-
{ text: 'Note 11', value: 'note11' },
|
|
51
|
-
{ text: 'Note 12', value: 'note12' },
|
|
52
|
-
{ text: 'Note 13', value: 'note13' },
|
|
53
|
-
{ text: 'Note 14', value: 'note14' },
|
|
54
|
-
{ text: 'Note 15', value: 'note15' }
|
|
55
|
-
]
|
|
56
|
-
},
|
|
57
|
-
{ field: 'status', name: 'Status', sort: false, hasAvatar: false, hasSubtext: true, width: '200px',
|
|
58
|
-
filterList: [
|
|
59
|
-
{ text: 'Success', value: 'success' },
|
|
60
|
-
{ text: 'Pending', value: 'pending' },
|
|
61
|
-
{ text: 'Error', value: 'error' }
|
|
62
|
-
]
|
|
63
|
-
},
|
|
64
|
-
]);
|
|
65
|
-
|
|
66
|
-
const data = ref([
|
|
67
|
-
// 40 more elements
|
|
68
|
-
...Array.from({ length: 50 }, (_, i) => ({
|
|
69
|
-
name: {
|
|
70
|
-
title: `Role ${i + 11}`,
|
|
71
|
-
subtext: `Subtext for role ${i + 11}`,
|
|
72
|
-
},
|
|
73
|
-
firstUpdate: {
|
|
74
|
-
title: `Jan ${10 + i}, 2025`,
|
|
75
|
-
subtext: `Subtext for date ${10 + i}`,
|
|
76
|
-
},
|
|
77
|
-
lastUpdate: {
|
|
78
|
-
title: `Dec ${10 + i}, 2025`,
|
|
79
|
-
subtext: `Subtext for date ${10 + i}`,
|
|
80
|
-
},
|
|
81
|
-
note: {
|
|
82
|
-
title: `Note ${i + 11}`,
|
|
83
|
-
subtext: `Subtext for role ${i + 11}`,
|
|
84
|
-
},
|
|
85
|
-
status: {
|
|
86
|
-
title: ['Success', 'Pending', 'Error'][(i + 1) % 3],
|
|
87
|
-
subtext: `Status subtext ${i + 11}`,
|
|
88
|
-
},
|
|
89
|
-
})),
|
|
90
|
-
]);
|
|
91
|
-
</script>
|
|
@@ -59,6 +59,15 @@ export const datePickerPropTypes = {
|
|
|
59
59
|
},
|
|
60
60
|
minMaxYear: {
|
|
61
61
|
type: Object as PropType<MinMaxYearType>,
|
|
62
|
+
validator: (value: MinMaxYearType): boolean => {
|
|
63
|
+
return (
|
|
64
|
+
value &&
|
|
65
|
+
typeof value.min === 'number' &&
|
|
66
|
+
typeof value.max === 'number' &&
|
|
67
|
+
value.min >= 1900 &&
|
|
68
|
+
value.min <= value.max
|
|
69
|
+
);
|
|
70
|
+
},
|
|
62
71
|
default: () => ({
|
|
63
72
|
min: 1900,
|
|
64
73
|
max: new Date().getFullYear(),
|
|
@@ -146,18 +155,6 @@ export const datePickerEmitTypes = {
|
|
|
146
155
|
},
|
|
147
156
|
getMonthList: (value: Array<object>) => Array.isArray(value),
|
|
148
157
|
getYearList: (value: Array<number>) => Array.isArray(value),
|
|
149
|
-
getDateErrors: (value: Array<{ title: string; message: string }>) => {
|
|
150
|
-
return (
|
|
151
|
-
Array.isArray(value) &&
|
|
152
|
-
value.every(
|
|
153
|
-
(item) =>
|
|
154
|
-
item !== null &&
|
|
155
|
-
typeof item === 'object' &&
|
|
156
|
-
typeof item.title === 'string' &&
|
|
157
|
-
typeof item.message === 'string',
|
|
158
|
-
)
|
|
159
|
-
);
|
|
160
|
-
},
|
|
161
158
|
};
|
|
162
159
|
|
|
163
160
|
export type DatePickerPropTypes = ExtractPropTypes<typeof datePickerPropTypes>;
|
|
@@ -63,6 +63,15 @@ export const dateRangePickerPropTypes = {
|
|
|
63
63
|
},
|
|
64
64
|
minMaxYear: {
|
|
65
65
|
type: Object as PropType<MinMaxYearType>,
|
|
66
|
+
validator: (value: MinMaxYearType): boolean => {
|
|
67
|
+
return (
|
|
68
|
+
value &&
|
|
69
|
+
typeof value.min === 'number' &&
|
|
70
|
+
typeof value.max === 'number' &&
|
|
71
|
+
value.min >= 1900 &&
|
|
72
|
+
value.min <= value.max
|
|
73
|
+
);
|
|
74
|
+
},
|
|
66
75
|
default: () => ({
|
|
67
76
|
min: 1900,
|
|
68
77
|
max: new Date().getFullYear(),
|
|
@@ -174,18 +183,6 @@ export const dateRangePickerEmitTypes = {
|
|
|
174
183
|
},
|
|
175
184
|
getMonthList: (value: Array<object>) => Array.isArray(value),
|
|
176
185
|
getYearList: (value: Array<number>) => Array.isArray(value),
|
|
177
|
-
getDateErrors: (value: Array<{ title: string; message: string }>) => {
|
|
178
|
-
return (
|
|
179
|
-
Array.isArray(value) &&
|
|
180
|
-
value.every(
|
|
181
|
-
(item) =>
|
|
182
|
-
item !== null &&
|
|
183
|
-
typeof item === 'object' &&
|
|
184
|
-
typeof item.title === 'string' &&
|
|
185
|
-
typeof item.message === 'string',
|
|
186
|
-
)
|
|
187
|
-
);
|
|
188
|
-
},
|
|
189
186
|
rangeChange: (value: { startDate: string; endDate: string; isValid: boolean }) => {
|
|
190
187
|
return (
|
|
191
188
|
typeof value === 'object' &&
|
|
@@ -33,7 +33,10 @@ interface MonthsList {
|
|
|
33
33
|
|
|
34
34
|
type DayAbbreviation = 'su' | 'mo' | 'tu' | 'we' | 'th' | 'fr' | 'sa';
|
|
35
35
|
|
|
36
|
-
export const useDateRangePicker = (
|
|
36
|
+
export const useDateRangePicker = (
|
|
37
|
+
props: DateRangePickerPropTypes,
|
|
38
|
+
emit: SetupContext<DateRangePickerEmitTypes>['emit'],
|
|
39
|
+
) => {
|
|
37
40
|
const { active, disabled, readonly, error, currentYear, minMaxYear, restDays, disabledDates, format } = toRefs(props);
|
|
38
41
|
const slots = useSlots();
|
|
39
42
|
|
|
@@ -152,7 +155,7 @@ export const useDateRangePicker = (props: DateRangePickerPropTypes, emit: SetupC
|
|
|
152
155
|
text: dayjs().month(i).format('MMM'),
|
|
153
156
|
fullText: dayjs().month(i).format('MMMM'),
|
|
154
157
|
monthValue: i,
|
|
155
|
-
}))
|
|
158
|
+
})),
|
|
156
159
|
);
|
|
157
160
|
|
|
158
161
|
// Start date inputs
|
|
@@ -280,44 +283,43 @@ export const useDateRangePicker = (props: DateRangePickerPropTypes, emit: SetupC
|
|
|
280
283
|
};
|
|
281
284
|
|
|
282
285
|
const calendarTabIsSelectedDate = (day: { date: dayjs.Dayjs; inactive: boolean }) => {
|
|
283
|
-
|
|
284
286
|
const startDate = dayjs(modelValue.value.startDate).format('MM-DD-YYYY');
|
|
285
287
|
const endDate = dayjs(modelValue.value.endDate).format('MM-DD-YYYY');
|
|
286
|
-
|
|
288
|
+
|
|
287
289
|
const dayDate = day.date.format('MM-DD-YYYY');
|
|
288
290
|
// If only start date is selected, highlight it
|
|
289
291
|
if (startDate && !endDate) {
|
|
290
292
|
return dayDate === startDate;
|
|
291
293
|
}
|
|
292
|
-
|
|
294
|
+
|
|
293
295
|
// If both dates are selected, highlight start and end
|
|
294
296
|
if (startDate && endDate) {
|
|
295
297
|
return dayDate === startDate || dayDate === endDate;
|
|
296
298
|
}
|
|
297
|
-
|
|
299
|
+
|
|
298
300
|
return false;
|
|
299
301
|
};
|
|
300
302
|
|
|
301
303
|
const calendarTabIsInRange = (day: { date: dayjs.Dayjs; inactive: boolean }) => {
|
|
302
304
|
const startDate = modelValue.value.startDate;
|
|
303
305
|
const endDate = modelValue.value.endDate;
|
|
304
|
-
|
|
306
|
+
|
|
305
307
|
// Only show range when both dates are selected
|
|
306
308
|
if (!startDate || !endDate) return false;
|
|
307
|
-
|
|
309
|
+
|
|
308
310
|
const dayDate = day.date;
|
|
309
311
|
const start = dayjs(startDate, 'MM-DD-YYYY');
|
|
310
312
|
const end = dayjs(endDate, 'MM-DD-YYYY');
|
|
311
|
-
|
|
313
|
+
|
|
312
314
|
return dayDate.isAfter(start, 'day') && dayDate.isBefore(end, 'day');
|
|
313
315
|
};
|
|
314
316
|
|
|
315
317
|
const calendarTabIsUnSelectedDate = (day: { date: dayjs.Dayjs }) => {
|
|
316
318
|
const startDate = modelValue.value.startDate;
|
|
317
319
|
const endDate = modelValue.value.endDate;
|
|
318
|
-
|
|
320
|
+
|
|
319
321
|
if (!startDate || !endDate) return true;
|
|
320
|
-
|
|
322
|
+
|
|
321
323
|
const dayDate = day.date.format('MM-DD-YYYY');
|
|
322
324
|
return dayDate !== startDate && dayDate !== endDate;
|
|
323
325
|
};
|
|
@@ -346,12 +348,12 @@ export const useDateRangePicker = (props: DateRangePickerPropTypes, emit: SetupC
|
|
|
346
348
|
if (!safeDisabledDates.value?.pastDates) return false;
|
|
347
349
|
const dayDate = day.date;
|
|
348
350
|
const currentDate = dayjs();
|
|
349
|
-
|
|
351
|
+
|
|
350
352
|
if (typeof safeDisabledDates.value.pastDates === 'string') {
|
|
351
353
|
const pastDate = dayjs(safeDisabledDates.value.pastDates, 'MM-DD-YYYY');
|
|
352
354
|
return dayDate.isBefore(pastDate, 'day');
|
|
353
355
|
}
|
|
354
|
-
|
|
356
|
+
|
|
355
357
|
return dayDate.isBefore(currentDate, 'day');
|
|
356
358
|
};
|
|
357
359
|
|
|
@@ -359,12 +361,12 @@ export const useDateRangePicker = (props: DateRangePickerPropTypes, emit: SetupC
|
|
|
359
361
|
if (!safeDisabledDates.value?.futureDates) return false;
|
|
360
362
|
const dayDate = day.date;
|
|
361
363
|
const currentDate = dayjs();
|
|
362
|
-
|
|
364
|
+
|
|
363
365
|
if (typeof safeDisabledDates.value.futureDates === 'string') {
|
|
364
366
|
const futureDate = dayjs(safeDisabledDates.value.futureDates, 'MM-DD-YYYY');
|
|
365
367
|
return dayDate.isAfter(futureDate, 'day');
|
|
366
368
|
}
|
|
367
|
-
|
|
369
|
+
|
|
368
370
|
return dayDate.isAfter(currentDate, 'day');
|
|
369
371
|
};
|
|
370
372
|
|
|
@@ -395,9 +397,9 @@ export const useDateRangePicker = (props: DateRangePickerPropTypes, emit: SetupC
|
|
|
395
397
|
// Update calendarTabHandleDateInput to use format.value
|
|
396
398
|
const calendarTabHandleDateInput = (day: { date: dayjs.Dayjs }) => {
|
|
397
399
|
if (calendarTabIsDateIsDisabled(day)) return;
|
|
398
|
-
|
|
400
|
+
|
|
399
401
|
const selectedDate = dayjs(day.date).format(format.value);
|
|
400
|
-
|
|
402
|
+
|
|
401
403
|
// If no start date is selected, set it as start date
|
|
402
404
|
if (!modelValue.value.startDate) {
|
|
403
405
|
modelValue.value = {
|
|
@@ -431,7 +433,7 @@ export const useDateRangePicker = (props: DateRangePickerPropTypes, emit: SetupC
|
|
|
431
433
|
};
|
|
432
434
|
selectionMode.value = 'end';
|
|
433
435
|
}
|
|
434
|
-
|
|
436
|
+
|
|
435
437
|
updateInputFields();
|
|
436
438
|
emitRangeChange();
|
|
437
439
|
};
|
|
@@ -477,7 +479,10 @@ export const useDateRangePicker = (props: DateRangePickerPropTypes, emit: SetupC
|
|
|
477
479
|
};
|
|
478
480
|
|
|
479
481
|
const yearTabGoToNextPage = () => {
|
|
480
|
-
if (
|
|
482
|
+
if (
|
|
483
|
+
(yearTabPageData.value.currentPage + 1) * yearTabPageData.value.itemsPerPage <
|
|
484
|
+
yearTabPageData.value.yearsArray.length
|
|
485
|
+
) {
|
|
481
486
|
yearTabPageData.value.currentPage++;
|
|
482
487
|
}
|
|
483
488
|
};
|
|
@@ -488,7 +493,8 @@ export const useDateRangePicker = (props: DateRangePickerPropTypes, emit: SetupC
|
|
|
488
493
|
|
|
489
494
|
const yearTabIsNextButtonDisabled = computed(() => {
|
|
490
495
|
return (
|
|
491
|
-
(yearTabPageData.value.currentPage + 1) * yearTabPageData.value.itemsPerPage >=
|
|
496
|
+
(yearTabPageData.value.currentPage + 1) * yearTabPageData.value.itemsPerPage >=
|
|
497
|
+
yearTabPageData.value.yearsArray.length
|
|
492
498
|
);
|
|
493
499
|
});
|
|
494
500
|
|
|
@@ -551,7 +557,7 @@ export const useDateRangePicker = (props: DateRangePickerPropTypes, emit: SetupC
|
|
|
551
557
|
const setModelValue = () => {
|
|
552
558
|
const startDateValid = validateDate(startMonthInput.value, startDateInput.value, startYearInput.value);
|
|
553
559
|
const endDateValid = validateDate(endMonthInput.value, endDateInput.value, endYearInput.value);
|
|
554
|
-
|
|
560
|
+
|
|
555
561
|
if (startDateValid && endDateValid) {
|
|
556
562
|
const startDate = `${startMonthInput.value}-${startDateInput.value}-${startYearInput.value}`;
|
|
557
563
|
const endDate = `${endMonthInput.value}-${endDateInput.value}-${endYearInput.value}`;
|
|
@@ -572,25 +578,25 @@ export const useDateRangePicker = (props: DateRangePickerPropTypes, emit: SetupC
|
|
|
572
578
|
|
|
573
579
|
const validateDate = (month: string, date: string, year: string): boolean => {
|
|
574
580
|
if (!month || !date || !year) return false;
|
|
575
|
-
|
|
581
|
+
|
|
576
582
|
const monthObj = getMonthObject('monthValue', month);
|
|
577
583
|
if (!monthObj) {
|
|
578
584
|
setWarningPropsValue('startDate');
|
|
579
585
|
return false;
|
|
580
586
|
}
|
|
581
|
-
|
|
587
|
+
|
|
582
588
|
const dayjsDate = dayjs(`${monthObj.monthValue + 1}-${date}-${year}`, 'M-D-YYYY');
|
|
583
589
|
if (!dayjsDate.isValid()) {
|
|
584
590
|
setWarningPropsValue('startDate');
|
|
585
591
|
return false;
|
|
586
592
|
}
|
|
587
|
-
|
|
593
|
+
|
|
588
594
|
const yearNum = Number(year);
|
|
589
595
|
if (yearNum < minMaxYear.value.min || yearNum > minMaxYear.value.max) {
|
|
590
596
|
setWarningPropsValue('year');
|
|
591
597
|
return false;
|
|
592
598
|
}
|
|
593
|
-
|
|
599
|
+
|
|
594
600
|
clearWarningPropsValue('startDate');
|
|
595
601
|
clearWarningPropsValue('year');
|
|
596
602
|
return true;
|
|
@@ -668,9 +674,7 @@ export const useDateRangePicker = (props: DateRangePickerPropTypes, emit: SetupC
|
|
|
668
674
|
|
|
669
675
|
const handleConvertMonthIfValid = (type: 'start' | 'end') => {
|
|
670
676
|
const monthInput = type === 'start' ? startMonthInput.value : endMonthInput.value;
|
|
671
|
-
const monthObj = monthsList.value.find(
|
|
672
|
-
(month) => month.text.toLowerCase() === monthInput.toLowerCase(),
|
|
673
|
-
);
|
|
677
|
+
const monthObj = monthsList.value.find((month) => month.text.toLowerCase() === monthInput.toLowerCase());
|
|
674
678
|
|
|
675
679
|
if (monthObj) {
|
|
676
680
|
if (type === 'start') {
|
|
@@ -719,7 +723,7 @@ export const useDateRangePicker = (props: DateRangePickerPropTypes, emit: SetupC
|
|
|
719
723
|
startDateInput.value = startDate.format('DD');
|
|
720
724
|
startYearInput.value = startDate.format('YYYY');
|
|
721
725
|
}
|
|
722
|
-
|
|
726
|
+
|
|
723
727
|
if (modelValue.value.endDate) {
|
|
724
728
|
const endDate = dayjs(modelValue.value.endDate, 'MM-DD-YYYY');
|
|
725
729
|
endMonthInput.value = endDate.format('MMM');
|
|
@@ -741,7 +745,7 @@ export const useDateRangePicker = (props: DateRangePickerPropTypes, emit: SetupC
|
|
|
741
745
|
if (modelValue.value.startDate && modelValue.value.endDate) {
|
|
742
746
|
const startDate = dayjs(modelValue.value.startDate, 'MM-DD-YYYY');
|
|
743
747
|
const endDate = dayjs(modelValue.value.endDate, 'MM-DD-YYYY');
|
|
744
|
-
|
|
748
|
+
|
|
745
749
|
const formats = {
|
|
746
750
|
'MM-DD-YYYY': {
|
|
747
751
|
startDate: startDate.format('MM-DD-YYYY'),
|
|
@@ -760,7 +764,7 @@ export const useDateRangePicker = (props: DateRangePickerPropTypes, emit: SetupC
|
|
|
760
764
|
endDate: endDate.format('DD-MM-YYYY'),
|
|
761
765
|
},
|
|
762
766
|
};
|
|
763
|
-
|
|
767
|
+
|
|
764
768
|
emit('getDateFormats', formats);
|
|
765
769
|
}
|
|
766
770
|
};
|
|
@@ -782,21 +786,32 @@ export const useDateRangePicker = (props: DateRangePickerPropTypes, emit: SetupC
|
|
|
782
786
|
emit('getYearList', years);
|
|
783
787
|
};
|
|
784
788
|
|
|
785
|
-
const emitDateErrors = () => {
|
|
786
|
-
emit('getDateErrors', dateRangePickerErrors.value);
|
|
787
|
-
};
|
|
788
|
-
|
|
789
789
|
// #region - Watchers
|
|
790
|
-
watch(
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
790
|
+
watch(
|
|
791
|
+
modelValue,
|
|
792
|
+
() => {
|
|
793
|
+
updateInputFields();
|
|
794
|
+
emitDateFormats();
|
|
795
|
+
emitInputValue();
|
|
796
|
+
},
|
|
797
|
+
{ deep: true },
|
|
798
|
+
);
|
|
799
|
+
|
|
800
|
+
watch(dateRangePickerErrors, () => {}, { deep: true });
|
|
796
801
|
|
|
797
|
-
watch(
|
|
798
|
-
|
|
799
|
-
|
|
802
|
+
watch(
|
|
803
|
+
minMaxYear,
|
|
804
|
+
() => {
|
|
805
|
+
yearTabPageData.value.yearsArray = Array.from(
|
|
806
|
+
{ length: minMaxYear.value.max - minMaxYear.value.min + 1 },
|
|
807
|
+
(_, index) => minMaxYear.value.min + index,
|
|
808
|
+
).filter((year) => year <= minMaxYear.value.max && year >= minMaxYear.value.min);
|
|
809
|
+
|
|
810
|
+
yearTabPageData.value.currentPage = 0;
|
|
811
|
+
emitYearList();
|
|
812
|
+
},
|
|
813
|
+
{ deep: true },
|
|
814
|
+
);
|
|
800
815
|
|
|
801
816
|
// #region - Lifecycle
|
|
802
817
|
onMounted(() => {
|
|
@@ -842,7 +857,7 @@ export const useDateRangePicker = (props: DateRangePickerPropTypes, emit: SetupC
|
|
|
842
857
|
if (basePlacement !== 'top' && basePlacement !== 'bottom') {
|
|
843
858
|
basePlacement = 'bottom';
|
|
844
859
|
}
|
|
845
|
-
|
|
860
|
+
|
|
846
861
|
if (clickedInputType.value === 'start') {
|
|
847
862
|
// For start date: concatenate base placement with 'start'
|
|
848
863
|
return `${basePlacement}-start`;
|
|
@@ -864,7 +879,7 @@ export const useDateRangePicker = (props: DateRangePickerPropTypes, emit: SetupC
|
|
|
864
879
|
// Handle start date input clicks
|
|
865
880
|
const handleStartDateClick = () => {
|
|
866
881
|
if (disabled.value || readonly.value) return;
|
|
867
|
-
|
|
882
|
+
|
|
868
883
|
clickedInputType.value = 'start';
|
|
869
884
|
activeInputRef.value = startDateContainerRef.value;
|
|
870
885
|
datePopperState.value = true;
|
|
@@ -873,7 +888,7 @@ export const useDateRangePicker = (props: DateRangePickerPropTypes, emit: SetupC
|
|
|
873
888
|
// Handle end date input clicks
|
|
874
889
|
const handleEndDateClick = () => {
|
|
875
890
|
if (disabled.value || readonly.value) return;
|
|
876
|
-
|
|
891
|
+
|
|
877
892
|
clickedInputType.value = 'end';
|
|
878
893
|
activeInputRef.value = endDateContainerRef.value;
|
|
879
894
|
datePopperState.value = true;
|
|
@@ -882,7 +897,7 @@ export const useDateRangePicker = (props: DateRangePickerPropTypes, emit: SetupC
|
|
|
882
897
|
// Handle custom component clicks (for slot usage)
|
|
883
898
|
const handleCustomComponentClick = (event: Event) => {
|
|
884
899
|
if (disabled.value || readonly.value) return;
|
|
885
|
-
|
|
900
|
+
|
|
886
901
|
// For custom slots, use the clicked element as reference
|
|
887
902
|
activeInputRef.value = event.currentTarget as HTMLElement;
|
|
888
903
|
datePopperState.value = true;
|
|
@@ -954,4 +969,4 @@ export const useDateRangePicker = (props: DateRangePickerPropTypes, emit: SetupC
|
|
|
954
969
|
handleEndDateClick,
|
|
955
970
|
handleCustomComponentClick,
|
|
956
971
|
};
|
|
957
|
-
};
|
|
972
|
+
};
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import type { PropType, ExtractPropTypes } from 'vue';
|
|
2
|
+
|
|
3
|
+
const POPPER_STRATEGY_TYPES = ['fixed', 'absolute'] as const;
|
|
4
|
+
const PLACEMENTS_TYPES = [
|
|
5
|
+
'auto',
|
|
6
|
+
'auto-start',
|
|
7
|
+
'auto-end',
|
|
8
|
+
'top',
|
|
9
|
+
'top-start',
|
|
10
|
+
'top-end',
|
|
11
|
+
'right',
|
|
12
|
+
'right-start',
|
|
13
|
+
'right-end',
|
|
14
|
+
'bottom',
|
|
15
|
+
'bottom-start',
|
|
16
|
+
'bottom-end',
|
|
17
|
+
'left',
|
|
18
|
+
'left-start',
|
|
19
|
+
'left-end',
|
|
20
|
+
] as const;
|
|
21
|
+
|
|
22
|
+
export const monthYearPickerPropTypes = {
|
|
23
|
+
id: {
|
|
24
|
+
type: String,
|
|
25
|
+
required: true,
|
|
26
|
+
},
|
|
27
|
+
modelValue: {
|
|
28
|
+
type: String,
|
|
29
|
+
default: '',
|
|
30
|
+
required: true,
|
|
31
|
+
},
|
|
32
|
+
label: {
|
|
33
|
+
type: String,
|
|
34
|
+
default: '',
|
|
35
|
+
},
|
|
36
|
+
active: {
|
|
37
|
+
type: Boolean,
|
|
38
|
+
default: false,
|
|
39
|
+
},
|
|
40
|
+
disabled: {
|
|
41
|
+
type: Boolean,
|
|
42
|
+
default: false,
|
|
43
|
+
},
|
|
44
|
+
readonly: {
|
|
45
|
+
type: Boolean,
|
|
46
|
+
default: false,
|
|
47
|
+
},
|
|
48
|
+
error: {
|
|
49
|
+
type: Boolean,
|
|
50
|
+
default: false,
|
|
51
|
+
},
|
|
52
|
+
currentYear: {
|
|
53
|
+
type: String,
|
|
54
|
+
default: new Date().getFullYear().toString(),
|
|
55
|
+
},
|
|
56
|
+
minMaxYear: {
|
|
57
|
+
type: Object as PropType<MinMaxYearType>,
|
|
58
|
+
validator: (value: MinMaxYearType): boolean => {
|
|
59
|
+
return (
|
|
60
|
+
value &&
|
|
61
|
+
typeof value.min === 'number' &&
|
|
62
|
+
typeof value.max === 'number' &&
|
|
63
|
+
value.min >= 1900 &&
|
|
64
|
+
value.min <= value.max
|
|
65
|
+
);
|
|
66
|
+
},
|
|
67
|
+
default: () => ({
|
|
68
|
+
min: 1900,
|
|
69
|
+
max: new Date().getFullYear(),
|
|
70
|
+
}),
|
|
71
|
+
},
|
|
72
|
+
displayHelper: {
|
|
73
|
+
type: Boolean,
|
|
74
|
+
default: false,
|
|
75
|
+
},
|
|
76
|
+
helperText: {
|
|
77
|
+
type: String,
|
|
78
|
+
default: '',
|
|
79
|
+
},
|
|
80
|
+
helperIcon: {
|
|
81
|
+
type: String,
|
|
82
|
+
default: null,
|
|
83
|
+
},
|
|
84
|
+
width: {
|
|
85
|
+
type: String,
|
|
86
|
+
default: '100%',
|
|
87
|
+
},
|
|
88
|
+
placement: {
|
|
89
|
+
type: String as PropType<(typeof PLACEMENTS_TYPES)[number]>,
|
|
90
|
+
validator: (value: (typeof PLACEMENTS_TYPES)[number]) => PLACEMENTS_TYPES.includes(value),
|
|
91
|
+
default: 'bottom',
|
|
92
|
+
},
|
|
93
|
+
format: {
|
|
94
|
+
type: String,
|
|
95
|
+
default: 'MM-YYYY',
|
|
96
|
+
description: 'Format for the selected month and year. For example: MM-YYYY, YYYY-MM, MMMM YYYY, etc.',
|
|
97
|
+
},
|
|
98
|
+
wrapperPosition: {
|
|
99
|
+
type: String,
|
|
100
|
+
default: 'relative',
|
|
101
|
+
},
|
|
102
|
+
popperStrategy: {
|
|
103
|
+
type: String,
|
|
104
|
+
validator: (value: 'fixed' | 'absolute') => POPPER_STRATEGY_TYPES.includes(value),
|
|
105
|
+
default: 'absolute',
|
|
106
|
+
},
|
|
107
|
+
popperContainer: {
|
|
108
|
+
type: String,
|
|
109
|
+
default: '',
|
|
110
|
+
},
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
export type MinMaxYearType = {
|
|
114
|
+
min: number;
|
|
115
|
+
max: number;
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
export const monthYearPickerEmitTypes = {
|
|
119
|
+
'update:modelValue': (value: string) => typeof value === 'string',
|
|
120
|
+
getInputValue: (value: string | null) => value === null || typeof value === 'string',
|
|
121
|
+
getDateFormats: (value: Record<string, string>) => {
|
|
122
|
+
return (
|
|
123
|
+
typeof value === 'object' &&
|
|
124
|
+
value !== null &&
|
|
125
|
+
!Array.isArray(value) &&
|
|
126
|
+
Object.keys(value).every((key) => typeof value[key] === 'string')
|
|
127
|
+
);
|
|
128
|
+
},
|
|
129
|
+
getMonthList: (value: Array<object>) => Array.isArray(value),
|
|
130
|
+
getYearList: (value: Array<number>) => Array.isArray(value),
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
export type MonthYearPickerPropTypes = ExtractPropTypes<typeof monthYearPickerPropTypes>;
|
|
134
|
+
export type MonthYearPickerEmitTypes = typeof monthYearPickerEmitTypes;
|