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.
Files changed (31) hide show
  1. package/dist/design-system-next.es.d.ts +152 -114
  2. package/dist/design-system-next.es.js +10058 -9379
  3. package/dist/design-system-next.es.js.gz +0 -0
  4. package/dist/design-system-next.umd.js +12 -12
  5. package/dist/design-system-next.umd.js.gz +0 -0
  6. package/dist/main.css +1 -1
  7. package/dist/main.css.gz +0 -0
  8. package/package.json +3 -2
  9. package/src/App.vue +1 -89
  10. package/src/components/date-picker/date-picker.ts +9 -12
  11. package/src/components/date-picker/date-picker.vue +1 -1
  12. package/src/components/date-picker/date-range-picker/date-range-picker.ts +9 -12
  13. package/src/components/date-picker/date-range-picker/use-date-range-picker.ts +64 -49
  14. package/src/components/date-picker/month-year-picker/month-year-picker.ts +134 -0
  15. package/src/components/date-picker/month-year-picker/month-year-picker.vue +233 -0
  16. package/src/components/date-picker/month-year-picker/use-month-year-picker.ts +603 -0
  17. package/src/components/date-picker/use-date-picker.ts +88 -147
  18. package/src/components/list/list-item/list-item.ts +60 -60
  19. package/src/components/list/list.ts +5 -0
  20. package/src/components/list/list.vue +2 -0
  21. package/src/components/list/use-list.ts +36 -3
  22. package/src/components/radio-grouped/radio-grouped.ts +65 -65
  23. package/src/components/radio-grouped/use-radio-grouped.ts +62 -62
  24. package/src/components/select/select-multiple/use-select-multiple.ts +7 -3
  25. package/src/components/select/use-select.ts +9 -5
  26. package/src/components/sidepanel/sidepanel.ts +7 -0
  27. package/src/components/sidepanel/sidepanel.vue +24 -4
  28. package/src/components/sidepanel/use-sidepanel.ts +4 -0
  29. package/src/components/table/table-header-dropdown/table-header-dropdown.vue +5 -1
  30. package/src/components/table/table.vue +14 -0
  31. package/src/components/table/use-table.ts +1 -2
package/src/App.vue CHANGED
@@ -1,91 +1,3 @@
1
1
  <template>
2
- <div class="spr-h-[600px] spr-w-[75%]">
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>;
@@ -7,7 +7,7 @@
7
7
  :placement="props.placement"
8
8
  :triggers="[]"
9
9
  :popper-hide-triggers="[]"
10
- :auto-hide="true"
10
+ :auto-hide="false"
11
11
  :disabled="isDatePickerPopperDisabled"
12
12
  :container="props.popperContainer ? props.popperContainer : `#${props.id}`"
13
13
  :strategy="
@@ -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 = (props: DateRangePickerPropTypes, emit: SetupContext<DateRangePickerEmitTypes>['emit']) => {
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 ((yearTabPageData.value.currentPage + 1) * yearTabPageData.value.itemsPerPage < yearTabPageData.value.yearsArray.length) {
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 >= yearTabPageData.value.yearsArray.length
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(modelValue, () => {
791
- updateInputFields();
792
- emitDateFormats();
793
- emitInputValue();
794
- emitDateErrors();
795
- }, { deep: true });
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(dateRangePickerErrors, () => {
798
- emitDateErrors();
799
- }, { deep: true });
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;