design-system-next 2.16.3 → 2.17.4

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 (32) hide show
  1. package/dist/design-system-next.es.js +8148 -7277
  2. package/dist/design-system-next.es.js.gz +0 -0
  3. package/dist/design-system-next.umd.js +13 -13
  4. package/dist/design-system-next.umd.js.gz +0 -0
  5. package/dist/main.css +1 -1
  6. package/dist/main.css.gz +0 -0
  7. package/dist/package.json.d.ts +1 -1
  8. package/package.json +1 -1
  9. package/src/assets/styles/tailwind.css +20 -0
  10. package/src/components/attribute-filter/attribute-filter.ts +5 -1
  11. package/src/components/attribute-filter/attribute-filter.vue +3 -3
  12. package/src/components/calendar/calendar.ts +1 -1
  13. package/src/components/calendar/calendar.vue +41 -18
  14. package/src/components/calendar/use-calendar.ts +13 -6
  15. package/src/components/calendar-cell/calendar-cell.ts +4 -0
  16. package/src/components/calendar-cell/use-calendar-cell.ts +21 -2
  17. package/src/components/card/card.ts +5 -0
  18. package/src/components/card/use-card.ts +15 -3
  19. package/src/components/date-picker/date-picker.ts +23 -0
  20. package/src/components/date-picker/reusable-calendar/reusable-calendar.ts +121 -0
  21. package/src/components/date-picker/reusable-calendar/reusable-calendar.vue +192 -0
  22. package/src/components/date-picker/reusable-calendar/use-reusable-calendar.ts +366 -0
  23. package/src/components/date-picker/tabs/DatePickerCalendarTab.vue +321 -0
  24. package/src/components/date-picker/tabs/DatePickerMonthTab.vue +60 -0
  25. package/src/components/date-picker/tabs/DatePickerYearTab.vue +114 -0
  26. package/src/components/icon/icon.ts +36 -0
  27. package/src/components/icon/icon.vue +12 -0
  28. package/src/components/icon/use-icon.ts +67 -0
  29. package/src/components/lozenge/lozenge.ts +1 -1
  30. package/src/components/popper/popper.ts +12 -0
  31. package/src/components/popper/popper.vue +36 -0
  32. package/src/components/popper/use-popper.ts +16 -0
@@ -0,0 +1,366 @@
1
+ import { computed, ref, watch } from 'vue';
2
+ import { toRefs } from 'vue';
3
+ import dayjs from 'dayjs';
4
+
5
+ import type { SetupContext } from 'vue';
6
+ import type { ReusableCalendarEmitTypes, ReusableCalendarPropTypes } from './reusable-calendar';
7
+
8
+ export const useReusableCalendar = (
9
+ props: ReusableCalendarPropTypes,
10
+ emit: SetupContext<ReusableCalendarEmitTypes>['emit']
11
+ ) => {
12
+ // Extract reactive props
13
+ const {
14
+ mode,
15
+ } = toRefs(props);
16
+
17
+ // Internal state
18
+ const currentTab = ref<string>('tab-calendar');
19
+ const calendarTabPageData = ref({
20
+ selectedMonth: props.selectedMonth ?? dayjs().month(),
21
+ selectedYear: props.selectedYear ?? dayjs().year(),
22
+ calendarDays: [] as Array<{ date: Date; inactive: boolean }>,
23
+ });
24
+
25
+ const yearTabPageData = ref({
26
+ currentPage: 0,
27
+ itemsPerPage: 12,
28
+ yearsArray: Array.from(
29
+ { length: props.minMaxYear.max - props.minMaxYear.min + 1 },
30
+ (_, index) => props.minMaxYear.min + index,
31
+ ).filter((year) => year <= props.minMaxYear.max && year >= props.minMaxYear.min),
32
+ });
33
+
34
+ // Computed properties
35
+ const showMonthInput = computed(() => mode.value === 'full' || mode.value === 'month-year');
36
+ const showDateInput = computed(() => mode.value === 'full');
37
+ const showYearInput = computed(() => mode.value === 'full' || mode.value === 'month-year' || mode.value === 'year-only');
38
+
39
+ const calendarDays = computed(() => calendarTabPageData.value.calendarDays);
40
+ const selectedMonthComputed = computed(() => calendarTabPageData.value.selectedMonth);
41
+ const selectedYearComputed = computed(() => calendarTabPageData.value.selectedYear);
42
+ const selectedDayComputed = computed(() => props.modelValue ? dayjs(props.modelValue, props.format).date() : 0);
43
+
44
+ // Calendar navigation computed properties
45
+ const calendarTabIsMinMonth = computed(() =>
46
+ dayjs()
47
+ .year(calendarTabPageData.value.selectedYear)
48
+ .month(calendarTabPageData.value.selectedMonth)
49
+ .isSame(dayjs().year(props.minMaxYear.min).month(0), 'month'),
50
+ );
51
+
52
+ const calendarTabIsMaxMonth = computed(() =>
53
+ dayjs()
54
+ .year(calendarTabPageData.value.selectedYear)
55
+ .month(calendarTabPageData.value.selectedMonth)
56
+ .isSame(dayjs().year(props.minMaxYear.max).month(11), 'month'),
57
+ );
58
+
59
+ const yearTabIsPreviousButtonDisabled = computed(() => {
60
+ return yearTabPageData.value.currentPage === 0;
61
+ });
62
+
63
+ const yearTabIsNextButtonDisabled = computed(() => {
64
+ return (
65
+ (yearTabPageData.value.currentPage + 1) * yearTabPageData.value.itemsPerPage >=
66
+ yearTabPageData.value.yearsArray.length
67
+ );
68
+ });
69
+
70
+ // Calendar update function
71
+ const calendarTabUpdateCalendar = () => {
72
+ const firstDay = dayjs()
73
+ .year(calendarTabPageData.value.selectedYear)
74
+ .month(calendarTabPageData.value.selectedMonth)
75
+ .startOf('month')
76
+ .day();
77
+
78
+ const lastDate = dayjs()
79
+ .year(calendarTabPageData.value.selectedYear)
80
+ .month(calendarTabPageData.value.selectedMonth)
81
+ .endOf('month')
82
+ .date();
83
+
84
+ const prevMonthDays = firstDay;
85
+ const totalDays = prevMonthDays + lastDate;
86
+ const nextMonthDays = totalDays % 7 === 0 ? 0 : 7 - (totalDays % 7);
87
+
88
+ const calendar = [];
89
+
90
+ // Previous month days
91
+ for (let index = prevMonthDays; index > 0; index--) {
92
+ const date = dayjs()
93
+ .year(calendarTabPageData.value.selectedYear)
94
+ .month(calendarTabPageData.value.selectedMonth)
95
+ .date(-index + 1);
96
+
97
+ calendar.push({ date, inactive: true });
98
+ }
99
+
100
+ // Current month days
101
+ for (let index = 1; index <= lastDate; index++) {
102
+ const date = dayjs()
103
+ .year(calendarTabPageData.value.selectedYear)
104
+ .month(calendarTabPageData.value.selectedMonth)
105
+ .date(index);
106
+
107
+ calendar.push({ date, inactive: false });
108
+ }
109
+
110
+ // Next month days
111
+ for (let index = 1; index <= nextMonthDays; index++) {
112
+ const date = dayjs()
113
+ .year(calendarTabPageData.value.selectedYear)
114
+ .month(calendarTabPageData.value.selectedMonth + 1)
115
+ .date(index);
116
+
117
+ calendar.push({ date, inactive: true });
118
+ }
119
+
120
+ calendarTabPageData.value.calendarDays = calendar.map((day) => ({ ...day, date: day.date.toDate() }));
121
+ goBackToCalendarTab();
122
+ };
123
+
124
+ const goBackToCalendarTab = () => {
125
+ if(props.mode === 'full' && currentTab.value !== 'tab-calendar') {
126
+ currentTab.value = 'tab-calendar';
127
+ }
128
+ }
129
+
130
+ // Navigation functions
131
+ const calendarTabPrevMonth = () => {
132
+ if (calendarTabIsMinMonth.value) return;
133
+
134
+ const newDate = dayjs()
135
+ .year(calendarTabPageData.value.selectedYear)
136
+ .month(calendarTabPageData.value.selectedMonth)
137
+ .subtract(1, 'month');
138
+
139
+ calendarTabPageData.value.selectedMonth = newDate.month();
140
+ calendarTabPageData.value.selectedYear = newDate.year();
141
+
142
+ calendarTabUpdateCalendar();
143
+ };
144
+
145
+ const calendarTabNextMonth = () => {
146
+ if (calendarTabIsMaxMonth.value) return;
147
+
148
+ const newDate = dayjs()
149
+ .year(calendarTabPageData.value.selectedYear)
150
+ .month(calendarTabPageData.value.selectedMonth)
151
+ .add(1, 'month');
152
+
153
+ calendarTabPageData.value.selectedMonth = newDate.month();
154
+ calendarTabPageData.value.selectedYear = newDate.year();
155
+
156
+ calendarTabUpdateCalendar();
157
+ };
158
+
159
+ const yearTabGoToPreviousPage = () => {
160
+ if (yearTabPageData.value.currentPage > 0) {
161
+ yearTabPageData.value.currentPage--;
162
+ }
163
+ };
164
+
165
+ const yearTabGoToNextPage = () => {
166
+ if (
167
+ (yearTabPageData.value.currentPage + 1) * yearTabPageData.value.itemsPerPage <
168
+ yearTabPageData.value.yearsArray.length
169
+ ) {
170
+ yearTabPageData.value.currentPage++;
171
+ }
172
+ };
173
+
174
+ // Tab functions
175
+ const getTabClasses = (tab: string) => {
176
+ return {
177
+ 'spr-cursor-pointer': true,
178
+ 'spr-background-color-pressed !spr-shadow-button': currentTab.value === tab,
179
+ };
180
+ };
181
+
182
+ const handleTabClick = (tab: string) => {
183
+ if (currentTab.value === tab && props.mode === 'full') {
184
+ currentTab.value = 'tab-calendar';
185
+ } else {
186
+ currentTab.value = tab;
187
+ }
188
+ };
189
+
190
+ // Month list for display
191
+ const monthsList = ref(
192
+ Array.from({ length: 12 }, (_, i) => ({
193
+ text: dayjs().month(i).format('MMM'),
194
+ fullText: dayjs().month(i).format('MMMM'),
195
+ monthValue: i,
196
+ })),
197
+ );
198
+
199
+ const getMonthObject = (field: string, value: string | number) => {
200
+ return monthsList.value.find(
201
+ (_month: { text: string; fullText: string; monthValue: number }) =>
202
+ _month[field as keyof typeof _month].toString().toLowerCase() === value.toString().toLowerCase(),
203
+ );
204
+ };
205
+
206
+ // Event handlers
207
+ const handleCalendarDateUpdate = (day: { date: Date; inactive: boolean }) => {
208
+ const selectedDate = dayjs(day.date);
209
+
210
+ // Update internal state
211
+ calendarTabPageData.value.selectedMonth = day.date.getMonth();
212
+ calendarTabPageData.value.selectedYear = day.date.getFullYear();
213
+
214
+ // Update calendar display
215
+ calendarTabUpdateCalendar();
216
+
217
+ // Emit events
218
+ emit('update:month', day.date.getMonth());
219
+ emit('update:year', day.date.getFullYear());
220
+ emit('update:day', day.date.getDate());
221
+ emit('update:modelValue', selectedDate.format(props.format));
222
+ };
223
+
224
+ const handleCalendarMonthUpdate = (month: number) => {
225
+ calendarTabPageData.value.selectedMonth = month;
226
+ emit('update:month', month);
227
+ };
228
+
229
+ const handleCalendarYearUpdate = (year: number) => {
230
+ calendarTabPageData.value.selectedYear = year;
231
+ emit('update:year', year);
232
+ };
233
+
234
+ const handleMonthTabMonthUpdate = (month: number) => {
235
+ calendarTabPageData.value.selectedMonth = month;
236
+ calendarTabUpdateCalendar();
237
+ emit('update:month', month);
238
+ };
239
+
240
+ const handleYearTabYearUpdate = (year: number) => {
241
+ calendarTabPageData.value.selectedYear = year;
242
+ calendarTabUpdateCalendar();
243
+ emit('update:year', year);
244
+ };
245
+
246
+ const handleYearTabCurrentPageUpdate = (page: number) => {
247
+ yearTabPageData.value.currentPage = page;
248
+ };
249
+
250
+ // Wrapper functions for event handlers
251
+ const handleCalendarDateUpdateWrapper = (day: { date: Date; inactive: boolean }) => {
252
+ handleCalendarDateUpdate(day);
253
+ };
254
+
255
+ const handleCalendarMonthUpdateWrapper = (month: number) => {
256
+ handleCalendarMonthUpdate(month);
257
+ };
258
+
259
+ const handleCalendarYearUpdateWrapper = (year: number) => {
260
+ handleCalendarYearUpdate(year);
261
+ };
262
+
263
+ const handleMonthTabMonthUpdateWrapper = (month: number) => {
264
+ handleMonthTabMonthUpdate(month);
265
+ };
266
+
267
+ const handleYearTabYearUpdateWrapper = (year: number) => {
268
+ handleYearTabYearUpdate(year);
269
+ };
270
+
271
+ const handleYearTabCurrentPageUpdateWrapper = (page: number) => {
272
+ handleYearTabCurrentPageUpdate(page);
273
+ };
274
+
275
+ // Initialize based on mode
276
+ const getInitialTab = () => {
277
+ switch (props.mode) {
278
+ case 'month-year':
279
+ return 'tab-months';
280
+ case 'year-only':
281
+ return 'tab-years';
282
+ default:
283
+ return 'tab-calendar';
284
+ }
285
+ };
286
+
287
+ // Initialize component
288
+ currentTab.value = getInitialTab();
289
+ calendarTabUpdateCalendar();
290
+
291
+ // Watch for prop changes
292
+ watch(() => props.modelValue, (newValue) => {
293
+ if (newValue) {
294
+ const parsedDate = dayjs(newValue, props.format);
295
+ if (parsedDate.isValid()) {
296
+ calendarTabPageData.value.selectedMonth = parsedDate.month();
297
+ calendarTabPageData.value.selectedYear = parsedDate.year();
298
+ calendarTabUpdateCalendar();
299
+ }
300
+ }
301
+ });
302
+
303
+ watch(() => props.selectedMonth, (newMonth) => {
304
+ if (newMonth !== undefined) {
305
+ calendarTabPageData.value.selectedMonth = newMonth;
306
+ calendarTabUpdateCalendar();
307
+ }
308
+ });
309
+
310
+ watch(() => props.selectedYear, (newYear) => {
311
+ if (newYear !== undefined) {
312
+ calendarTabPageData.value.selectedYear = newYear;
313
+ calendarTabUpdateCalendar();
314
+ }
315
+ });
316
+
317
+ watch(() => props.mode, () => {
318
+ currentTab.value = getInitialTab();
319
+ });
320
+
321
+ watch(() => props.minMaxYear, () => {
322
+ yearTabPageData.value.yearsArray = Array.from(
323
+ { length: props.minMaxYear.max - props.minMaxYear.min + 1 },
324
+ (_, index) => props.minMaxYear.min + index,
325
+ ).filter((year) => year <= props.minMaxYear.max && year >= props.minMaxYear.min);
326
+
327
+ yearTabPageData.value.currentPage = 0;
328
+ }, { deep: true });
329
+
330
+ return {
331
+ // State
332
+ currentTab,
333
+ calendarTabPageData,
334
+ yearTabPageData,
335
+
336
+ // Computed properties
337
+ showMonthInput,
338
+ showDateInput,
339
+ showYearInput,
340
+ calendarDays,
341
+ selectedMonthComputed,
342
+ selectedYearComputed,
343
+ selectedDayComputed,
344
+ calendarTabIsMinMonth,
345
+ calendarTabIsMaxMonth,
346
+ yearTabIsPreviousButtonDisabled,
347
+ yearTabIsNextButtonDisabled,
348
+
349
+ // Functions
350
+ getTabClasses,
351
+ handleTabClick,
352
+ getMonthObject,
353
+ calendarTabPrevMonth,
354
+ calendarTabNextMonth,
355
+ yearTabGoToPreviousPage,
356
+ yearTabGoToNextPage,
357
+
358
+ // Event handlers
359
+ handleCalendarDateUpdateWrapper,
360
+ handleCalendarMonthUpdateWrapper,
361
+ handleCalendarYearUpdateWrapper,
362
+ handleMonthTabMonthUpdateWrapper,
363
+ handleYearTabYearUpdateWrapper,
364
+ handleYearTabCurrentPageUpdateWrapper,
365
+ };
366
+ };
@@ -0,0 +1,321 @@
1
+ <template>
2
+ <div class="spr-grid spr-grid-cols-7">
3
+ <div
4
+ v-for="(dayOfWeek, dayOfWeekIndex) in daysOfWeek"
5
+ :key="dayOfWeekIndex"
6
+ class="spr-py-1 spr-text-center spr-font-semibold"
7
+ >
8
+ {{ dayOfWeek.text }}
9
+ </div>
10
+
11
+ <template v-for="day in calendarDays" :key="day.date">
12
+ <div
13
+ v-if="minMaxYear.min <= day.date.getFullYear() && minMaxYear.max >= day.date.getFullYear()"
14
+ :class="[
15
+ 'spr-relative spr-box-border spr-flex spr-h-[40px] spr-items-center spr-justify-center spr-p-2',
16
+ 'spr-transition spr-duration-150 spr-ease-in-out',
17
+ {
18
+ // Rest Days
19
+ 'spr-background-color-disabled': isRestDay(day),
20
+
21
+ // Today Indicator - only apply brand color if not selected
22
+ 'spr-text-color-brand-base': isTodayIndicator(day) && !isSelectedDate(day),
23
+
24
+ // Active Month Dates - only apply if not selected and not today
25
+ 'spr-text-color-strong':
26
+ isActiveMonthDates(day) &&
27
+ !isSelectedDate(day) &&
28
+ !isTodayIndicator(day),
29
+
30
+ // Inactive Month Dates (Past/Future)
31
+ 'spr-text-color-disabled': isInactiveMonthDates(day),
32
+
33
+ // Selected Date
34
+ 'spr-background-color-brand-base active:spr-background-color-brand-pressed spr-text-color-inverted-strong spr-cursor-pointer !spr-text-white-50 active:spr-scale-95':
35
+ isSelectedDate(day),
36
+
37
+ // Unselected Date
38
+ 'hover:spr-background-color-hover spr-border-color-weak active:spr-background-color-pressed spr-cursor-pointer spr-border spr-border-solid active:spr-scale-95':
39
+ isUnSelectedDate(day),
40
+
41
+ // Disabled Dates
42
+ 'spr-cursor-not-allowed spr-opacity-30': isDateDisabled(day),
43
+ },
44
+ ]"
45
+ @click="!isDateDisabled(day) ? handleDateClick(day) : null"
46
+ >
47
+ <span>{{ day.date.getDate() }}</span>
48
+ <div
49
+ v-if="isTodayIndicator(day)"
50
+ class="spr-background-color-brand-base spr-absolute spr-bottom-1 spr-m-auto spr-h-1 spr-w-1 spr-rounded-full"
51
+ ></div>
52
+ </div>
53
+ <div v-else></div>
54
+ </template>
55
+ </div>
56
+ </template>
57
+
58
+ <script lang="ts" setup>
59
+ import { computed } from 'vue';
60
+ import dayjs from 'dayjs';
61
+ import isSameOrAfter from 'dayjs/plugin/isSameOrAfter';
62
+ import isSameOrBefore from 'dayjs/plugin/isSameOrBefore';
63
+ import type { TabComponentProps, CalendarTabEmits, RestDayType, DisabledDatesType } from '../date-picker';
64
+
65
+ dayjs.extend(isSameOrAfter);
66
+ dayjs.extend(isSameOrBefore);
67
+
68
+ interface Props extends TabComponentProps {
69
+ calendarDays: Array<{ date: Date; inactive: boolean }>;
70
+ restDays: RestDayType[];
71
+ disabledDates?: DisabledDatesType;
72
+ selectedDate?: Date;
73
+ selectedMonth: number;
74
+ selectedDay?: number;
75
+ }
76
+
77
+ type Emits = CalendarTabEmits;
78
+
79
+ const props = defineProps<Props>();
80
+ const emit = defineEmits<Emits>();
81
+
82
+ const daysOfWeek = computed(() =>
83
+ Array.from({ length: 7 }, (_, i) => ({
84
+ text: dayjs().day(i).format('dd'),
85
+ fullText: dayjs().day(i).format('dddd'),
86
+ dayValue: i,
87
+ }))
88
+ );
89
+
90
+ const currentDate = computed(() => dayjs());
91
+
92
+ const isRestDay = (day: { date: Date; inactive: boolean }) => {
93
+ const restDaysValue = props.restDays.map((restDay) => {
94
+ return daysOfWeek.value.find((d) => d.text.toLowerCase() === restDay.toLowerCase())?.dayValue;
95
+ });
96
+
97
+ if (isSelectedDate(day)) {
98
+ return false;
99
+ }
100
+
101
+ if (restDaysValue.includes(day.date.getDay())) {
102
+ return true;
103
+ }
104
+
105
+ return false;
106
+ };
107
+
108
+ const isTodayIndicator = (day: { date: Date }) => {
109
+ if (day.date.toDateString() === currentDate.value.format('ddd MMM DD YYYY')) {
110
+ return true;
111
+ }
112
+
113
+ return false;
114
+ };
115
+
116
+ const isActiveMonthDates = (day: { date: Date; inactive: boolean }) => {
117
+ if (!day.inactive && !isDateDisabled(day)) {
118
+ return true;
119
+ }
120
+
121
+ return false;
122
+ };
123
+
124
+ const isInactiveMonthDates = (day: { date: Date; inactive: boolean }) => {
125
+ if (day.inactive && !isDateDisabled(day)) {
126
+ return true;
127
+ }
128
+
129
+ return false;
130
+ };
131
+
132
+ const isSelectedDate = (day: { date: Date; inactive: boolean }) => {
133
+ if (isDateDisabled(day)) {
134
+ return false;
135
+ }
136
+
137
+ // Check if day, month, and year are selected (full mode)
138
+ if (props.selectedDay && props.selectedMonth !== undefined && props.selectedYear) {
139
+ return (
140
+ day.date.getDate() === props.selectedDay &&
141
+ day.date.getMonth() === props.selectedMonth &&
142
+ day.date.getFullYear() === props.selectedYear &&
143
+ !day.inactive
144
+ );
145
+ }
146
+
147
+ // Check if day and month are selected, but not year
148
+ if (props.selectedDay && props.selectedMonth !== undefined && !props.selectedYear) {
149
+ return day.date.getDate() === props.selectedDay && day.date.getMonth() === props.selectedMonth && !day.inactive;
150
+ }
151
+
152
+ // Check if only day is selected
153
+ if (props.selectedDay && !props.selectedMonth && !props.selectedYear) {
154
+ return day.date.getDate() === props.selectedDay && !day.inactive;
155
+ }
156
+
157
+
158
+ return false;
159
+ };
160
+
161
+ const isUnSelectedDate = (day: { date: Date }) => {
162
+ if (isDateDisabled(day)) {
163
+ return false;
164
+ }
165
+
166
+ // If no selection at all, all dates are unselected
167
+ if (!props.selectedDay && !props.selectedMonth && !props.selectedYear) {
168
+ return true;
169
+ }
170
+
171
+ // If only month is selected, all dates are unselected
172
+ if (!props.selectedDay && props.selectedMonth !== undefined && !props.selectedYear) {
173
+ return true;
174
+ }
175
+
176
+ // If day, month, and year are selected, check if this date matches
177
+ if (props.selectedDay && props.selectedMonth !== undefined && props.selectedYear) {
178
+ return !(
179
+ day.date.getDate() === props.selectedDay &&
180
+ day.date.getMonth() === props.selectedMonth &&
181
+ day.date.getFullYear() === props.selectedYear
182
+ );
183
+ }
184
+
185
+ // If day and month are selected, check if this date matches
186
+ if (props.selectedDay && props.selectedMonth !== undefined && !props.selectedYear) {
187
+ return !(
188
+ day.date.getDate() === props.selectedDay &&
189
+ day.date.getMonth() === props.selectedMonth
190
+ );
191
+ }
192
+
193
+ // If only day is selected, check if this date matches
194
+ if (props.selectedDay && !props.selectedMonth && !props.selectedYear) {
195
+ return day.date.getDate() !== props.selectedDay;
196
+ }
197
+
198
+ return true;
199
+ };
200
+
201
+ const isDateDisabled = (day: { date: Date }) => {
202
+ if (
203
+ isDateDisabledFromTo(day) ||
204
+ isDateDisabledPastDate(day) ||
205
+ isDateDisabledFutureDate(day) ||
206
+ isDateDisabledSelectedDates(day) ||
207
+ isDateDisabledWeekends(day) ||
208
+ isDateDisabledWeekdays(day) ||
209
+ isDateDisabledSelectedDays(day)
210
+ ) {
211
+ return true;
212
+ }
213
+
214
+ return false;
215
+ };
216
+
217
+ const isDateDisabledFromTo = (day: { date: Date }) => {
218
+ if (props.disabledDates?.from && props.disabledDates?.to) {
219
+ const disabledFrom = dayjs(props.disabledDates.from, 'MM-DD-YYYY').startOf('day');
220
+ const disabledTo = dayjs(props.disabledDates.to, 'MM-DD-YYYY').endOf('day');
221
+
222
+ const dayDate = dayjs(day.date);
223
+
224
+ return dayDate.isSameOrAfter(disabledFrom, 'day') && dayDate.isSameOrBefore(disabledTo, 'day');
225
+ }
226
+
227
+ return false;
228
+ };
229
+
230
+ const isDateDisabledPastDate = (day: { date: Date }) => {
231
+ if (props.disabledDates?.pastDates) {
232
+ const dayDate = dayjs(day.date);
233
+
234
+ if (typeof props.disabledDates.pastDates === 'boolean') {
235
+ return dayDate.isBefore(currentDate.value.startOf('day'));
236
+ } else {
237
+ const selectedDate = dayjs(props.disabledDates.pastDates);
238
+
239
+ return dayDate.isBefore(dayjs(selectedDate, 'MM-DD-YYYY').startOf('day'));
240
+ }
241
+ }
242
+
243
+ return false;
244
+ };
245
+
246
+ const isDateDisabledFutureDate = (day: { date: Date }) => {
247
+ if (props.disabledDates?.futureDates) {
248
+ const dayDate = dayjs(day.date);
249
+
250
+ if (typeof props.disabledDates.futureDates === 'boolean') {
251
+ return dayDate.isAfter(currentDate.value.endOf('day'));
252
+ } else {
253
+ const selectedDate = dayjs(props.disabledDates.futureDates);
254
+
255
+ return dayDate.isAfter(dayjs(selectedDate, 'MM-DD-YYYY').endOf('day'));
256
+ }
257
+ }
258
+
259
+ return false;
260
+ };
261
+
262
+ const isDateDisabledSelectedDates = (day: { date: Date }) => {
263
+ if (props.disabledDates?.selectedDates && props.disabledDates.selectedDates.length > 0) {
264
+ const dayDate = dayjs(day.date);
265
+
266
+ props.disabledDates.selectedDates.forEach((_date) => {
267
+ if (!dayjs(_date).isValid()) {
268
+ console.error(`Error: disabledDates Props - Selected Dates - Invalid date format: "${_date}"`);
269
+ }
270
+ });
271
+
272
+ return props.disabledDates.selectedDates.some((date) => dayDate.isSame(dayjs(date, 'MM-DD-YYYY'), 'day'));
273
+ }
274
+
275
+ return false;
276
+ };
277
+
278
+ const isDateDisabledWeekends = (day: { date: Date }) => {
279
+ if (props.disabledDates?.weekends) {
280
+ const dayDate = dayjs(day.date);
281
+
282
+ return dayDate.day() === 0 || dayDate.day() === 6;
283
+ }
284
+
285
+ return false;
286
+ };
287
+
288
+ const isDateDisabledWeekdays = (day: { date: Date }) => {
289
+ if (props.disabledDates?.weekdays) {
290
+ const dayDate = dayjs(day.date);
291
+
292
+ return dayDate.day() > 0 && dayDate.day() < 6;
293
+ }
294
+
295
+ return false;
296
+ };
297
+
298
+ const isDateDisabledSelectedDays = (day: { date: Date }) => {
299
+ if (props.disabledDates?.selectedDays) {
300
+ const dayDate = dayjs(day.date);
301
+
302
+ return props.disabledDates.selectedDays.some((day) => {
303
+ const foundDay = daysOfWeek.value.find((d) => d.text.toLowerCase() === day.toLowerCase());
304
+
305
+ if (!foundDay) {
306
+ console.error(`Error: disabledDates Props - Selected Days - Invalid day: "${day}"`);
307
+ }
308
+
309
+ return foundDay ? dayDate.day() === daysOfWeek.value.indexOf(foundDay) : false;
310
+ });
311
+ }
312
+
313
+ return false;
314
+ };
315
+
316
+ const handleDateClick = (day: { date: Date; inactive: boolean }) => {
317
+ emit('update:date', day);
318
+ emit('update:month', day.date.getMonth());
319
+ emit('update:year', day.date.getFullYear());
320
+ };
321
+ </script>