design-system-next 2.16.2 → 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 (45) hide show
  1. package/dist/design-system-next.es.js +7569 -6646
  2. package/dist/design-system-next.es.js.gz +0 -0
  3. package/dist/design-system-next.umd.js +14 -14
  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/App.vue +43 -1642
  10. package/src/assets/styles/tailwind.css +20 -0
  11. package/src/components/attribute-filter/attribute-filter.ts +5 -1
  12. package/src/components/attribute-filter/attribute-filter.vue +3 -3
  13. package/src/components/calendar/calendar.ts +1 -1
  14. package/src/components/calendar/calendar.vue +41 -18
  15. package/src/components/calendar/use-calendar.ts +13 -6
  16. package/src/components/calendar-cell/calendar-cell.ts +4 -0
  17. package/src/components/calendar-cell/use-calendar-cell.ts +21 -2
  18. package/src/components/card/card.ts +5 -0
  19. package/src/components/card/use-card.ts +15 -3
  20. package/src/components/date-picker/date-picker.ts +36 -5
  21. package/src/components/date-picker/date-picker.vue +2 -1
  22. package/src/components/date-picker/date-range-picker/date-range-picker.ts +14 -6
  23. package/src/components/date-picker/date-range-picker/date-range-picker.vue +2 -1
  24. package/src/components/date-picker/reusable-calendar/reusable-calendar.ts +121 -0
  25. package/src/components/date-picker/reusable-calendar/reusable-calendar.vue +192 -0
  26. package/src/components/date-picker/reusable-calendar/use-reusable-calendar.ts +366 -0
  27. package/src/components/date-picker/tabs/DatePickerCalendarTab.vue +321 -0
  28. package/src/components/date-picker/tabs/DatePickerMonthTab.vue +60 -0
  29. package/src/components/date-picker/tabs/DatePickerYearTab.vue +114 -0
  30. package/src/components/dropdown/dropdown.ts +25 -21
  31. package/src/components/dropdown/dropdown.vue +1 -1
  32. package/src/components/icon/icon.ts +36 -0
  33. package/src/components/icon/icon.vue +12 -0
  34. package/src/components/icon/use-icon.ts +67 -0
  35. package/src/components/lozenge/lozenge.ts +1 -1
  36. package/src/components/popper/popper.ts +12 -0
  37. package/src/components/popper/popper.vue +36 -0
  38. package/src/components/popper/use-popper.ts +16 -0
  39. package/src/components/select/select-ladderized/select-ladderized.ts +16 -12
  40. package/src/components/select/select-ladderized/select-ladderized.vue +1 -1
  41. package/src/components/select/select-multiple/select-multiple.ts +8 -4
  42. package/src/components/select/select-multiple/select-multiple.vue +1 -1
  43. package/src/components/select/select-multiple/use-select-multiple.ts +15 -4
  44. package/src/components/select/select.ts +4 -0
  45. package/src/components/select/select.vue +1 -1
@@ -0,0 +1,192 @@
1
+ <template>
2
+ <div
3
+ ref="reusableCalendarRef"
4
+ :class="reusableCalendarClasses"
5
+ >
6
+ <div
7
+ :class="[
8
+ 'spr-flex spr-justify-between spr-gap-2 spr-px-4 spr-py-3',
9
+ 'spr-border spr-border-x-0 spr-border-b spr-border-t-0 spr-border-solid spr-border-mushroom-200',
10
+ ]"
11
+ >
12
+ <!-- Tabs -->
13
+ <div class="spr-flex spr-gap-1">
14
+ <spr-button
15
+ v-if="showMonthInput"
16
+ :class="getTabClasses('tab-months')"
17
+ variant="secondary"
18
+ size="small"
19
+ @click="handleTabClick('tab-months')"
20
+ >
21
+ {{ getMonthObject('monthValue', calendarTabPageData.selectedMonth)?.fullText }}
22
+ </spr-button>
23
+ <spr-button
24
+ v-if="showYearInput"
25
+ :class="getTabClasses('tab-years')"
26
+ variant="secondary"
27
+ size="small"
28
+ @click="handleTabClick('tab-years')"
29
+ >
30
+ {{ calendarTabPageData.selectedYear }}
31
+ </spr-button>
32
+ </div>
33
+
34
+ <!-- Next & Previous Buttons -->
35
+ <div v-if="currentTab === 'tab-calendar'" class="spr-flex spr-gap-1">
36
+ <spr-button
37
+ class="spr-cursor-pointer"
38
+ variant="secondary"
39
+ size="small"
40
+ :disabled="calendarTabIsMinMonth"
41
+ @click="calendarTabPrevMonth"
42
+ >
43
+ <Icon icon="ph:caret-left" />
44
+ </spr-button>
45
+ <spr-button
46
+ class="spr-cursor-pointer"
47
+ variant="secondary"
48
+ size="small"
49
+ :disabled="calendarTabIsMaxMonth"
50
+ @click="calendarTabNextMonth"
51
+ >
52
+ <Icon icon="ph:caret-right" />
53
+ </spr-button>
54
+ </div>
55
+
56
+ <div v-if="currentTab === 'tab-years'" class="spr-flex spr-gap-1">
57
+ <spr-button
58
+ class="spr-cursor-pointer"
59
+ variant="secondary"
60
+ size="small"
61
+ :disabled="yearTabIsPreviousButtonDisabled"
62
+ @click="yearTabGoToPreviousPage"
63
+ >
64
+ <Icon icon="ph:caret-left" />
65
+ </spr-button>
66
+ <spr-button
67
+ class="spr-cursor-pointer"
68
+ variant="secondary"
69
+ size="small"
70
+ :disabled="yearTabIsNextButtonDisabled"
71
+ @click="yearTabGoToNextPage"
72
+ >
73
+ <Icon icon="ph:caret-right" />
74
+ </spr-button>
75
+ </div>
76
+ </div>
77
+
78
+ <div class="spr-px-4 spr-pb-4 spr-pt-2">
79
+ <!-- Calendar Tab -->
80
+ <DatePickerCalendarTab
81
+ v-if="currentTab === 'tab-calendar' && showDateInput"
82
+ :calendar-days="calendarDays"
83
+ :selected-month="selectedMonthComputed"
84
+ :selected-year="selectedYearComputed"
85
+ :selected-day="selectedDayComputed"
86
+ :min-max-year="minMaxYear"
87
+ :rest-days="restDays"
88
+ :disabled-dates="disabledDates"
89
+ :disabled="disabled"
90
+ :readonly="readonly"
91
+ @update:date="handleCalendarDateUpdateWrapper as any"
92
+ @update:month="handleCalendarMonthUpdateWrapper as any"
93
+ @update:year="handleCalendarYearUpdateWrapper as any"
94
+ />
95
+
96
+ <!-- Months Tab -->
97
+ <DatePickerMonthTab
98
+ v-if="currentTab === 'tab-months' && showMonthInput"
99
+ :selected-month="selectedMonthComputed"
100
+ :selected-year="selectedYearComputed"
101
+ :min-max-year="minMaxYear"
102
+ :disabled="disabled"
103
+ :readonly="readonly"
104
+ @update:month="handleMonthTabMonthUpdateWrapper as any"
105
+ />
106
+
107
+ <!-- Years Tab -->
108
+ <DatePickerYearTab
109
+ v-if="currentTab === 'tab-years' && showYearInput"
110
+ :selected-month="selectedMonthComputed"
111
+ :selected-year="selectedYearComputed"
112
+ :min-max-year="minMaxYear"
113
+ :years-array="yearTabPageData.yearsArray"
114
+ :current-page="yearTabPageData.currentPage"
115
+ :items-per-page="yearTabPageData.itemsPerPage"
116
+ :disabled="disabled"
117
+ :readonly="readonly"
118
+ @update:year="handleYearTabYearUpdateWrapper as any"
119
+ @update:current-page="handleYearTabCurrentPageUpdateWrapper as any"
120
+ />
121
+ </div>
122
+ </div>
123
+ </template>
124
+
125
+ <script lang="ts" setup>
126
+ import { computed, ref } from 'vue';
127
+ import { Icon } from '@iconify/vue';
128
+ import classNames from 'classnames';
129
+
130
+ import SprButton from '@/components/button/button.vue';
131
+ import DatePickerCalendarTab from '../tabs/DatePickerCalendarTab.vue';
132
+ import DatePickerMonthTab from '../tabs/DatePickerMonthTab.vue';
133
+ import DatePickerYearTab from '../tabs/DatePickerYearTab.vue';
134
+
135
+ import { useReusableCalendar } from './use-reusable-calendar';
136
+ import { reusableCalendarEmitTypes, reusableCalendarPropTypes } from './reusable-calendar';
137
+
138
+ const props = defineProps(reusableCalendarPropTypes);
139
+ const emit = defineEmits(reusableCalendarEmitTypes);
140
+
141
+ const reusableCalendarRef = ref<HTMLElement | null>(null);
142
+
143
+ // Use the composable for all logic
144
+ const {
145
+ // State
146
+ currentTab,
147
+ calendarTabPageData,
148
+ yearTabPageData,
149
+
150
+ // Computed properties
151
+ showMonthInput,
152
+ showDateInput,
153
+ showYearInput,
154
+ calendarDays,
155
+ selectedMonthComputed,
156
+ selectedYearComputed,
157
+ selectedDayComputed,
158
+ calendarTabIsMinMonth,
159
+ calendarTabIsMaxMonth,
160
+ yearTabIsPreviousButtonDisabled,
161
+ yearTabIsNextButtonDisabled,
162
+
163
+ // Functions
164
+ getTabClasses,
165
+ handleTabClick,
166
+ getMonthObject,
167
+ calendarTabPrevMonth,
168
+ calendarTabNextMonth,
169
+ yearTabGoToPreviousPage,
170
+ yearTabGoToNextPage,
171
+
172
+ // Event handlers
173
+ handleCalendarDateUpdateWrapper,
174
+ handleCalendarMonthUpdateWrapper,
175
+ handleCalendarYearUpdateWrapper,
176
+ handleMonthTabMonthUpdateWrapper,
177
+ handleYearTabYearUpdateWrapper,
178
+ handleYearTabCurrentPageUpdateWrapper,
179
+ } = useReusableCalendar(props, emit);
180
+
181
+ // Compute CSS classes using classNames utility
182
+ const reusableCalendarClasses = computed(() => {
183
+ return classNames(
184
+ 'reusable-calendar-container spr-bg-white spr-rounded-lg spr-shadow-lg spr-border spr-border-solid spr-border-mushroom-200 min-w-[320px]',
185
+ {
186
+ 'spr-disabled': props.disabled,
187
+ 'spr-readonly': props.readonly,
188
+ }
189
+ );
190
+ });
191
+ </script>
192
+
@@ -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
+ };