bge-ui 1.3.4 → 1.3.6
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/datePicker/components/ActionRow.vue.d.ts +1051 -0
- package/dist/datePicker/components/Common/ArrowBtn.vue.d.ts +29 -0
- package/dist/datePicker/components/Common/InstanceWrap.vue.d.ts +29 -0
- package/dist/datePicker/components/Common/SelectionOverlay.vue.d.ts +55 -0
- package/dist/datePicker/components/DatePicker/DatePicker.vue.d.ts +1114 -0
- package/dist/datePicker/components/DatePicker/DpCalendar.vue.d.ts +1085 -0
- package/dist/datePicker/components/DatePicker/DpHeader.vue.d.ts +1103 -0
- package/dist/datePicker/components/DatePicker/date-picker.d.ts +35 -0
- package/dist/datePicker/components/DatepickerInput.vue.d.ts +1008 -0
- package/dist/datePicker/components/DatepickerMenu.vue.d.ts +1061 -0
- package/dist/datePicker/components/Icons/CalendarIcon.d.ts +9 -0
- package/dist/datePicker/components/Icons/CancelIcon.d.ts +9 -0
- package/dist/datePicker/components/Icons/ChevronDownIcon.d.ts +9 -0
- package/dist/datePicker/components/Icons/ChevronLeftIcon.d.ts +9 -0
- package/dist/datePicker/components/Icons/ChevronRightIcon.d.ts +9 -0
- package/dist/datePicker/components/Icons/ChevronUpIcon.d.ts +9 -0
- package/dist/datePicker/components/Icons/ClockIcon.d.ts +9 -0
- package/dist/datePicker/components/Icons/index.d.ts +7 -0
- package/dist/datePicker/components/MonthPicker/MonthPicker.vue.d.ts +1071 -0
- package/dist/datePicker/components/MonthPicker/month-picker.d.ts +34 -0
- package/dist/datePicker/components/QuarterPicker/QuarterPicker.vue.d.ts +1043 -0
- package/dist/datePicker/components/QuarterPicker/quarter-picker.d.ts +25 -0
- package/dist/datePicker/components/TimePicker/TimeInput.vue.d.ts +1116 -0
- package/dist/datePicker/components/TimePicker/TimePicker.vue.d.ts +1087 -0
- package/dist/datePicker/components/TimePicker/TimePickerSolo.vue.d.ts +1036 -0
- package/dist/datePicker/components/TimePicker/time-picker-utils.d.ts +15 -0
- package/dist/datePicker/components/TimePicker/time-picker.d.ts +13 -0
- package/dist/datePicker/components/YearPicker/YearPicker.vue.d.ts +1040 -0
- package/dist/datePicker/components/YearPicker/year-picker.d.ts +9 -0
- package/dist/datePicker/components/shared/YearModePicker.vue.d.ts +1075 -0
- package/dist/datePicker/components/shared/month-quarter-picker.d.ts +29 -0
- package/dist/datePicker/composables/arrow-navigate.d.ts +26 -0
- package/dist/datePicker/composables/calendar-class.d.ts +8 -0
- package/dist/datePicker/composables/common.d.ts +6 -0
- package/dist/datePicker/composables/defaults.d.ts +37 -0
- package/dist/datePicker/composables/external-internal-mapper.d.ts +14 -0
- package/dist/datePicker/composables/flow.d.ts +10 -0
- package/dist/datePicker/composables/index.d.ts +14 -0
- package/dist/datePicker/composables/model.d.ts +17 -0
- package/dist/datePicker/composables/month-year.d.ts +10 -0
- package/dist/datePicker/composables/position.d.ts +25 -0
- package/dist/datePicker/composables/shared.d.ts +12 -0
- package/dist/datePicker/composables/slots.d.ts +10 -0
- package/dist/datePicker/composables/state.d.ts +8 -0
- package/dist/datePicker/composables/transition.d.ts +7 -0
- package/dist/datePicker/composables/validation.d.ts +12 -0
- package/dist/datePicker/constants/index.d.ts +43 -0
- package/dist/datePicker/datePicker.vue.d.ts +1006 -0
- package/dist/datePicker/directives/clickOutside.d.ts +2 -0
- package/dist/datePicker/index.vue.d.ts +1012 -0
- package/dist/datePicker/interfaces.d.ts +323 -0
- package/dist/datePicker/props.d.ts +865 -0
- package/dist/datePicker/utils/date-utils.d.ts +45 -0
- package/dist/datePicker/utils/defaults.d.ts +42 -0
- package/dist/datePicker/utils/timezone.d.ts +8 -0
- package/dist/datePicker/utils/type-guard.d.ts +1 -0
- package/dist/datePicker/utils/util.d.ts +57 -0
- package/dist/dialog/index.vue.d.ts +6 -3
- package/dist/index.d.ts +2 -1
- package/dist/index.js +13008 -1250
- package/dist/style.css +1188 -1
- package/dist/tooltip/index.vue.d.ts +2 -2
- package/dist/tooltip/usePopper.d.ts +5 -5
- package/package.json +3 -2
- package/src/datePicker/components/ActionRow.vue +216 -0
- package/src/datePicker/components/Common/ArrowBtn.vue +42 -0
- package/src/datePicker/components/Common/InstanceWrap.vue +28 -0
- package/src/datePicker/components/Common/SelectionOverlay.vue +320 -0
- package/src/datePicker/components/DatePicker/DatePicker.vue +302 -0
- package/src/datePicker/components/DatePicker/DpCalendar.vue +405 -0
- package/src/datePicker/components/DatePicker/DpHeader.vue +332 -0
- package/src/datePicker/components/DatePicker/date-picker.ts +674 -0
- package/src/datePicker/components/DatepickerInput.vue +334 -0
- package/src/datePicker/components/DatepickerMenu.vue +424 -0
- package/src/datePicker/components/Icons/CalendarIcon.ts +40 -0
- package/src/datePicker/components/Icons/CancelIcon.ts +32 -0
- package/src/datePicker/components/Icons/ChevronDownIcon.ts +29 -0
- package/src/datePicker/components/Icons/ChevronLeftIcon.ts +29 -0
- package/src/datePicker/components/Icons/ChevronRightIcon.ts +29 -0
- package/src/datePicker/components/Icons/ChevronUpIcon.ts +29 -0
- package/src/datePicker/components/Icons/ClockIcon.ts +32 -0
- package/src/datePicker/components/Icons/index.ts +8 -0
- package/src/datePicker/components/MonthPicker/MonthPicker.vue +130 -0
- package/src/datePicker/components/MonthPicker/month-picker.ts +232 -0
- package/src/datePicker/components/QuarterPicker/QuarterPicker.vue +111 -0
- package/src/datePicker/components/QuarterPicker/quarter-picker.ts +153 -0
- package/src/datePicker/components/TimePicker/TimeInput.vue +477 -0
- package/src/datePicker/components/TimePicker/TimePicker.vue +265 -0
- package/src/datePicker/components/TimePicker/TimePickerSolo.vue +79 -0
- package/src/datePicker/components/TimePicker/time-picker-utils.ts +179 -0
- package/src/datePicker/components/TimePicker/time-picker.ts +112 -0
- package/src/datePicker/components/YearPicker/YearPicker.vue +70 -0
- package/src/datePicker/components/YearPicker/year-picker.ts +109 -0
- package/src/datePicker/components/shared/YearModePicker.vue +105 -0
- package/src/datePicker/components/shared/month-quarter-picker.ts +199 -0
- package/src/datePicker/composables/arrow-navigate.ts +191 -0
- package/src/datePicker/composables/calendar-class.ts +383 -0
- package/src/datePicker/composables/common.ts +25 -0
- package/src/datePicker/composables/defaults.ts +123 -0
- package/src/datePicker/composables/external-internal-mapper.ts +442 -0
- package/src/datePicker/composables/flow.ts +70 -0
- package/src/datePicker/composables/index.ts +14 -0
- package/src/datePicker/composables/model.ts +89 -0
- package/src/datePicker/composables/month-year.ts +72 -0
- package/src/datePicker/composables/position.ts +297 -0
- package/src/datePicker/composables/shared.ts +98 -0
- package/src/datePicker/composables/slots.ts +84 -0
- package/src/datePicker/composables/state.ts +25 -0
- package/src/datePicker/composables/transition.ts +18 -0
- package/src/datePicker/composables/validation.ts +312 -0
- package/src/datePicker/constants/index.ts +49 -0
- package/src/datePicker/datePicker.vue +554 -0
- package/src/datePicker/directives/clickOutside.ts +79 -0
- package/src/datePicker/index.vue +158 -0
- package/src/datePicker/interfaces.ts +404 -0
- package/src/datePicker/props.ts +173 -0
- package/src/datePicker/style/components/_ActionRow.scss +73 -0
- package/src/datePicker/style/components/_Calendar.scss +284 -0
- package/src/datePicker/style/components/_DatepickerInput.scss +109 -0
- package/src/datePicker/style/components/_DatepickerMenu.scss +213 -0
- package/src/datePicker/style/components/_MonthYearInput.scss +97 -0
- package/src/datePicker/style/components/_QuarterPicker.scss +53 -0
- package/src/datePicker/style/components/_SelectionOverlay.scss +142 -0
- package/src/datePicker/style/components/_TimeInput.scss +181 -0
- package/src/datePicker/style/components/_shared.scss +15 -0
- package/src/datePicker/style/main.scss +259 -0
- package/src/datePicker/utils/date-utils.ts +440 -0
- package/src/datePicker/utils/defaults.ts +327 -0
- package/src/datePicker/utils/timezone.ts +38 -0
- package/src/datePicker/utils/type-guard.ts +3 -0
- package/src/datePicker/utils/util.ts +322 -0
- package/src/dialog/index.vue +9 -0
- package/src/form/index.vue +2 -1
- package/src/index.ts +6 -2
- package/src/slider/index.vue +1 -1
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div>
|
|
3
|
+
<slot v-if="$slots['top-extra']" name="top-extra" :value="internalModelValue" />
|
|
4
|
+
<template v-if="$slots['month-year']">
|
|
5
|
+
<slot
|
|
6
|
+
name="month-year"
|
|
7
|
+
v-bind="{
|
|
8
|
+
years: groupedYears,
|
|
9
|
+
selectYear,
|
|
10
|
+
}"
|
|
11
|
+
/>
|
|
12
|
+
</template>
|
|
13
|
+
<template v-else>
|
|
14
|
+
<selection-overlay
|
|
15
|
+
:items="groupedYears"
|
|
16
|
+
:is-last="autoApply && !defaultedConfig.keepActionRow"
|
|
17
|
+
:height="defaultedConfig.modeHeight"
|
|
18
|
+
:config="config"
|
|
19
|
+
:no-overlay-focus="Boolean(noOverlayFocus || textInput)"
|
|
20
|
+
:focus-value="focusYear"
|
|
21
|
+
type="year"
|
|
22
|
+
use-relative
|
|
23
|
+
@selected="selectYear"
|
|
24
|
+
@hover-value="setHoverValue"
|
|
25
|
+
>
|
|
26
|
+
<template v-if="$slots['year-overlay-value']" #item="{ item }">
|
|
27
|
+
<slot name="year-overlay-value" :text="item.text" :value="item.value" />
|
|
28
|
+
</template>
|
|
29
|
+
</selection-overlay>
|
|
30
|
+
</template>
|
|
31
|
+
</div>
|
|
32
|
+
</template>
|
|
33
|
+
|
|
34
|
+
<script lang="ts" setup>
|
|
35
|
+
import SelectionOverlay from '../../components/Common/SelectionOverlay.vue';
|
|
36
|
+
|
|
37
|
+
import { PickerBaseProps } from '../../props';
|
|
38
|
+
import { useYearPicker } from '../../components/YearPicker/year-picker';
|
|
39
|
+
import { useDefaults } from '../../composables';
|
|
40
|
+
|
|
41
|
+
const emit = defineEmits([
|
|
42
|
+
'update:internal-model-value',
|
|
43
|
+
'reset-flow',
|
|
44
|
+
'range-start',
|
|
45
|
+
'range-end',
|
|
46
|
+
'auto-apply',
|
|
47
|
+
'update-month-year',
|
|
48
|
+
]);
|
|
49
|
+
const props = defineProps({
|
|
50
|
+
...PickerBaseProps,
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
defineOptions({
|
|
54
|
+
compatConfig: {
|
|
55
|
+
MODE: 3,
|
|
56
|
+
},
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
const { groupedYears, modelValue, focusYear, selectYear, setHoverValue } = useYearPicker(props, emit);
|
|
60
|
+
const { defaultedConfig } = useDefaults(props);
|
|
61
|
+
|
|
62
|
+
const getSidebarProps = () => {
|
|
63
|
+
return {
|
|
64
|
+
modelValue,
|
|
65
|
+
selectYear,
|
|
66
|
+
};
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
defineExpose({ getSidebarProps });
|
|
70
|
+
</script>
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { computed, nextTick, onMounted, ref } from 'vue';
|
|
2
|
+
import { getYear, setYear, startOfYear } from 'date-fns';
|
|
3
|
+
|
|
4
|
+
import { useDefaults, useModel } from '../../composables';
|
|
5
|
+
import { checkMinMaxValue, getYears, groupListAndMap } from '../../utils/util';
|
|
6
|
+
import {
|
|
7
|
+
checkHighlightYear,
|
|
8
|
+
getDate,
|
|
9
|
+
getMinMaxYear,
|
|
10
|
+
isDateBetween,
|
|
11
|
+
resetDate,
|
|
12
|
+
resetDateTime,
|
|
13
|
+
} from '../../utils/date-utils';
|
|
14
|
+
import { checkRangeAutoApply, setMonthOrYearRange } from '../../composables/shared';
|
|
15
|
+
|
|
16
|
+
import type { PickerBasePropsType } from '../../props';
|
|
17
|
+
import type { VueEmit, IDefaultSelect } from '../../interfaces';
|
|
18
|
+
|
|
19
|
+
export const useYearPicker = (props: PickerBasePropsType, emit: VueEmit) => {
|
|
20
|
+
const reMap = () => {
|
|
21
|
+
if (props.isTextInputDate) focusYear.value = getYear(getDate(props.startDate));
|
|
22
|
+
};
|
|
23
|
+
const { modelValue } = useModel(props, emit, reMap);
|
|
24
|
+
const hoverDate = ref<Date | null>(null);
|
|
25
|
+
const { defaultedHighlight, defaultedMultiDates, defaultedFilters, defaultedRange, propDates } = useDefaults(props);
|
|
26
|
+
const focusYear = ref();
|
|
27
|
+
|
|
28
|
+
onMounted(() => {
|
|
29
|
+
if (props.startDate) {
|
|
30
|
+
if ((modelValue.value && props.focusStartDate) || !modelValue.value) {
|
|
31
|
+
focusYear.value = getYear(getDate(props.startDate));
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
const isYearActive = (year: number) => {
|
|
37
|
+
if (Array.isArray(modelValue.value)) {
|
|
38
|
+
return modelValue.value.some((date) => getYear(date) === year);
|
|
39
|
+
}
|
|
40
|
+
return modelValue.value ? getYear(modelValue.value) === year : false;
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
const isYearBetween = (year: number) => {
|
|
44
|
+
if (defaultedRange.value.enabled) {
|
|
45
|
+
if (Array.isArray(modelValue.value)) {
|
|
46
|
+
return isDateBetween(modelValue.value, hoverDate.value, yearToDate(year));
|
|
47
|
+
}
|
|
48
|
+
return false;
|
|
49
|
+
}
|
|
50
|
+
return false;
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
const groupedYears = computed(() => {
|
|
54
|
+
return groupListAndMap(getYears(props.yearRange, props.locale, props.reverseYears), (year: IDefaultSelect) => {
|
|
55
|
+
const active = isYearActive(year.value);
|
|
56
|
+
const disabled =
|
|
57
|
+
checkMinMaxValue(
|
|
58
|
+
year.value,
|
|
59
|
+
getMinMaxYear(propDates.value.minDate),
|
|
60
|
+
getMinMaxYear(propDates.value.maxDate),
|
|
61
|
+
) || defaultedFilters.value.years.includes(year.value);
|
|
62
|
+
const isBetween = isYearBetween(year.value) && !active;
|
|
63
|
+
const highlighted = checkHighlightYear(defaultedHighlight.value, year.value);
|
|
64
|
+
return { active, disabled, isBetween, highlighted };
|
|
65
|
+
});
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
const yearToDate = (year: number): Date => {
|
|
69
|
+
return setYear(resetDate(startOfYear(new Date())), year);
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
const selectYear = (year: number) => {
|
|
73
|
+
emit('update-month-year', { instance: 0, year });
|
|
74
|
+
if (defaultedMultiDates.value.enabled) {
|
|
75
|
+
if (!modelValue.value) {
|
|
76
|
+
modelValue.value = [setYear(resetDateTime(startOfYear(getDate())), year)];
|
|
77
|
+
} else if (Array.isArray(modelValue.value)) {
|
|
78
|
+
const years = modelValue.value?.map((date) => getYear(date));
|
|
79
|
+
if (years.includes(year)) {
|
|
80
|
+
modelValue.value = modelValue.value.filter((date) => getYear(date) !== year);
|
|
81
|
+
} else {
|
|
82
|
+
modelValue.value.push(setYear(resetDateTime(getDate()), year));
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
return emit('auto-apply', true);
|
|
86
|
+
}
|
|
87
|
+
if (defaultedRange.value.enabled) {
|
|
88
|
+
modelValue.value = setMonthOrYearRange(modelValue, yearToDate(year), emit);
|
|
89
|
+
nextTick().then(() => {
|
|
90
|
+
checkRangeAutoApply(modelValue.value as Date[], emit, props.autoApply, props.modelAuto);
|
|
91
|
+
});
|
|
92
|
+
} else {
|
|
93
|
+
modelValue.value = yearToDate(year);
|
|
94
|
+
emit('auto-apply');
|
|
95
|
+
}
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
const setHoverValue = (value: number) => {
|
|
99
|
+
hoverDate.value = setYear(resetDate(new Date()), value);
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
return {
|
|
103
|
+
groupedYears,
|
|
104
|
+
modelValue,
|
|
105
|
+
focusYear,
|
|
106
|
+
setHoverValue,
|
|
107
|
+
selectYear,
|
|
108
|
+
};
|
|
109
|
+
};
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="dp--year-mode-picker" :class="{ 'dp--hidden-el': overlayOpen }">
|
|
3
|
+
<ArrowBtn
|
|
4
|
+
v-if="showLeftIcon(defaultedMultiCalendars, instance)"
|
|
5
|
+
ref="mpPrevIconRef"
|
|
6
|
+
:aria-label="defaultedAriaLabels?.prevYear"
|
|
7
|
+
:disabled="isDisabled(false)"
|
|
8
|
+
:class="defaultedUI?.navBtnPrev"
|
|
9
|
+
@activate="handleYear(false)"
|
|
10
|
+
>
|
|
11
|
+
<slot v-if="$slots['arrow-left']" name="arrow-left" />
|
|
12
|
+
<ChevronLeftIcon v-if="!$slots['arrow-left']" />
|
|
13
|
+
</ArrowBtn>
|
|
14
|
+
<button
|
|
15
|
+
ref="mpYearButtonRef"
|
|
16
|
+
class="dp__btn dp--year-select"
|
|
17
|
+
type="button"
|
|
18
|
+
:aria-label="`${year}-${defaultedAriaLabels?.openYearsOverlay}`"
|
|
19
|
+
:data-test="`year-mode-btn-${instance}`"
|
|
20
|
+
@click="() => toggleYearPicker(false)"
|
|
21
|
+
@keydown.enter="() => toggleYearPicker(false)"
|
|
22
|
+
>
|
|
23
|
+
<slot v-if="$slots.year" name="year" :year="year" />
|
|
24
|
+
<template v-if="!$slots.year">{{ year }}</template>
|
|
25
|
+
</button>
|
|
26
|
+
<ArrowBtn
|
|
27
|
+
v-if="showRightIcon(defaultedMultiCalendars, instance)"
|
|
28
|
+
ref="mpNextIconRef"
|
|
29
|
+
:aria-label="defaultedAriaLabels?.nextYear"
|
|
30
|
+
:disabled="isDisabled(true)"
|
|
31
|
+
:class="defaultedUI?.navBtnNext"
|
|
32
|
+
@activate="handleYear(true)"
|
|
33
|
+
>
|
|
34
|
+
<slot v-if="$slots['arrow-right']" name="arrow-right" />
|
|
35
|
+
<ChevronRightIcon v-if="!$slots['arrow-right']" />
|
|
36
|
+
</ArrowBtn>
|
|
37
|
+
</div>
|
|
38
|
+
<transition :name="transitionName(showYearPicker)" :css="showTransition">
|
|
39
|
+
<SelectionOverlay
|
|
40
|
+
v-if="showYearPicker"
|
|
41
|
+
:items="items"
|
|
42
|
+
:text-input="textInput"
|
|
43
|
+
:esc-close="escClose"
|
|
44
|
+
:config="config"
|
|
45
|
+
:is-last="autoApply && !defaultedConfig.keepActionRow"
|
|
46
|
+
:hide-navigation="hideNavigation"
|
|
47
|
+
:aria-labels="ariaLabels"
|
|
48
|
+
:overlay-label="defaultedAriaLabels?.yearPicker?.(true)"
|
|
49
|
+
type="year"
|
|
50
|
+
@toggle="toggleYearPicker"
|
|
51
|
+
@selected="handleYearSelect($event)"
|
|
52
|
+
>
|
|
53
|
+
<template #button-icon>
|
|
54
|
+
<slot v-if="$slots['calendar-icon']" name="calendar-icon" />
|
|
55
|
+
<CalendarIcon v-if="!$slots['calendar-icon']" />
|
|
56
|
+
</template>
|
|
57
|
+
<template v-if="$slots['year-overlay-value']" #item="{ item }">
|
|
58
|
+
<slot name="year-overlay-value" :text="item.text" :value="item.value" />
|
|
59
|
+
</template>
|
|
60
|
+
</SelectionOverlay>
|
|
61
|
+
</transition>
|
|
62
|
+
</template>
|
|
63
|
+
|
|
64
|
+
<script setup lang="ts">
|
|
65
|
+
import SelectionOverlay from '../../components/Common/SelectionOverlay.vue';
|
|
66
|
+
import ArrowBtn from '../../components/Common/ArrowBtn.vue';
|
|
67
|
+
import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from '../../components/Icons';
|
|
68
|
+
|
|
69
|
+
import { useCommon, useDefaults, useTransitions } from '../../composables';
|
|
70
|
+
import { PickerBaseProps } from '../../props';
|
|
71
|
+
|
|
72
|
+
import { type PropType, ref } from 'vue';
|
|
73
|
+
import type { OverlayGridItem } from '../../interfaces';
|
|
74
|
+
|
|
75
|
+
const emit = defineEmits(['toggle-year-picker', 'year-select', 'handle-year']);
|
|
76
|
+
const props = defineProps({
|
|
77
|
+
...PickerBaseProps,
|
|
78
|
+
showYearPicker: { type: Boolean as PropType<boolean>, default: false },
|
|
79
|
+
items: { type: Array as PropType<OverlayGridItem[][]>, default: () => [] },
|
|
80
|
+
instance: { type: Number as PropType<number>, default: 0 },
|
|
81
|
+
year: { type: Number as PropType<number>, default: 0 },
|
|
82
|
+
isDisabled: { type: Function as PropType<(isNext: boolean) => boolean>, default: () => false },
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
const { showRightIcon, showLeftIcon } = useCommon();
|
|
86
|
+
const { defaultedConfig, defaultedMultiCalendars, defaultedAriaLabels, defaultedTransitions, defaultedUI } =
|
|
87
|
+
useDefaults(props);
|
|
88
|
+
const { showTransition, transitionName } = useTransitions(defaultedTransitions);
|
|
89
|
+
|
|
90
|
+
const overlayOpen = ref(false);
|
|
91
|
+
|
|
92
|
+
const toggleYearPicker = (flow = false, show?: boolean) => {
|
|
93
|
+
overlayOpen.value = !overlayOpen.value;
|
|
94
|
+
emit('toggle-year-picker', { flow, show });
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
const handleYearSelect = (year: number) => {
|
|
98
|
+
overlayOpen.value = false;
|
|
99
|
+
emit('year-select', year);
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
const handleYear = (increment = false): void => {
|
|
103
|
+
emit('handle-year', increment);
|
|
104
|
+
};
|
|
105
|
+
</script>
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
import { computed, onMounted, ref, watch } from 'vue';
|
|
2
|
+
import { addYears, differenceInYears, endOfYear, getMonth, getYear, set, startOfYear, subYears } from 'date-fns';
|
|
3
|
+
|
|
4
|
+
import { checkHighlightYear, getDate, getMinMaxYear, resetDate, validateMonthYear } from '../../utils/date-utils';
|
|
5
|
+
import { checkMinMaxValue, getYears, groupListAndMap } from '../../utils/util';
|
|
6
|
+
|
|
7
|
+
import type { ComputedRef, WritableComputedRef, Ref } from 'vue';
|
|
8
|
+
import type {
|
|
9
|
+
InternalModuleValue,
|
|
10
|
+
MultiCalendarsOptions,
|
|
11
|
+
ICalendarData,
|
|
12
|
+
IDefaultSelect,
|
|
13
|
+
OverlayGridItem,
|
|
14
|
+
VueEmit,
|
|
15
|
+
Highlight,
|
|
16
|
+
HighlightFn,
|
|
17
|
+
PropDates,
|
|
18
|
+
DateFilter,
|
|
19
|
+
RangeConfig,
|
|
20
|
+
} from '../../interfaces';
|
|
21
|
+
import type { PickerBasePropsType } from '../../props';
|
|
22
|
+
import { FlowStep } from '../../constants';
|
|
23
|
+
|
|
24
|
+
interface Opts {
|
|
25
|
+
multiCalendars: ComputedRef<MultiCalendarsOptions>;
|
|
26
|
+
calendars: Ref<ICalendarData[]>;
|
|
27
|
+
modelValue: WritableComputedRef<InternalModuleValue>;
|
|
28
|
+
props: PickerBasePropsType;
|
|
29
|
+
year: ComputedRef<(instance: number) => number>;
|
|
30
|
+
month: ComputedRef<(instance: number) => number>;
|
|
31
|
+
highlight: ComputedRef<Highlight | HighlightFn>;
|
|
32
|
+
propDates: ComputedRef<PropDates>;
|
|
33
|
+
filters: ComputedRef<DateFilter>;
|
|
34
|
+
range: ComputedRef<RangeConfig>;
|
|
35
|
+
emit: VueEmit;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Both modes shared logic
|
|
40
|
+
*/
|
|
41
|
+
export const useMonthOrQuarterPicker = ({
|
|
42
|
+
multiCalendars,
|
|
43
|
+
range,
|
|
44
|
+
highlight,
|
|
45
|
+
propDates,
|
|
46
|
+
calendars,
|
|
47
|
+
modelValue,
|
|
48
|
+
props,
|
|
49
|
+
filters,
|
|
50
|
+
year,
|
|
51
|
+
month,
|
|
52
|
+
emit,
|
|
53
|
+
}: Opts) => {
|
|
54
|
+
const years = computed(() => getYears(props.yearRange, props.locale, props.reverseYears));
|
|
55
|
+
const showYearPicker = ref([false]);
|
|
56
|
+
|
|
57
|
+
const isDisabled = computed(() => (instance: number, next: boolean) => {
|
|
58
|
+
const currentDate = set(resetDate(new Date()), {
|
|
59
|
+
month: month.value(instance),
|
|
60
|
+
year: year.value(instance),
|
|
61
|
+
});
|
|
62
|
+
const date = next ? endOfYear(currentDate) : startOfYear(currentDate);
|
|
63
|
+
return validateMonthYear(
|
|
64
|
+
date,
|
|
65
|
+
propDates.value.maxDate,
|
|
66
|
+
propDates.value.minDate,
|
|
67
|
+
props.preventMinMaxNavigation,
|
|
68
|
+
next,
|
|
69
|
+
);
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
const isSoloMultiInRange = () => {
|
|
73
|
+
return Array.isArray(modelValue.value) && multiCalendars.value.solo && modelValue.value[1];
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
const assignMultiCalendars = () => {
|
|
77
|
+
for (let i = 0; i < multiCalendars.value.count; i++) {
|
|
78
|
+
if (i === 0) {
|
|
79
|
+
calendars.value[i] = calendars.value[0];
|
|
80
|
+
} else if (i === multiCalendars.value.count - 1 && isSoloMultiInRange()) {
|
|
81
|
+
calendars.value[i] = {
|
|
82
|
+
month: getMonth((modelValue.value as Date[])[1]),
|
|
83
|
+
year: getYear((modelValue.value as Date[])[1]),
|
|
84
|
+
};
|
|
85
|
+
} else {
|
|
86
|
+
const prevDate = set(getDate(), calendars.value[i - 1]);
|
|
87
|
+
calendars.value[i] = { month: getMonth(prevDate), year: getYear(addYears(prevDate, 1)) };
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
const updateMultiCalendars = (instance: number) => {
|
|
93
|
+
if (!instance) return assignMultiCalendars();
|
|
94
|
+
const date = set(getDate(), calendars.value[instance]);
|
|
95
|
+
calendars.value[0].year = getYear(subYears(date, multiCalendars.value.count - 1));
|
|
96
|
+
return assignMultiCalendars();
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
const getDateToFocus = (dateOne: Date, dateTwo: Date) => {
|
|
100
|
+
const diff = differenceInYears(dateTwo, dateOne);
|
|
101
|
+
return range.value.showLastInRange && diff > 1 ? dateTwo : dateOne;
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
const getRangedValueDate = (dates: Date[]) => {
|
|
105
|
+
if (props.focusStartDate) return dates[0];
|
|
106
|
+
if (multiCalendars.value.solo) return dates[0];
|
|
107
|
+
return dates[1] ? getDateToFocus(dates[0], dates[1]) : dates[0];
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
const checkModelValue = () => {
|
|
111
|
+
if (modelValue.value) {
|
|
112
|
+
const firstDate = Array.isArray(modelValue.value) ? getRangedValueDate(modelValue.value) : modelValue.value;
|
|
113
|
+
calendars.value[0] = { month: getMonth(firstDate), year: getYear(firstDate) };
|
|
114
|
+
}
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
const assign = () => {
|
|
118
|
+
checkModelValue();
|
|
119
|
+
if (multiCalendars.value.count) {
|
|
120
|
+
assignMultiCalendars();
|
|
121
|
+
}
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
watch(modelValue, (newVal, oldVal) => {
|
|
125
|
+
if (props.isTextInputDate) {
|
|
126
|
+
if (JSON.stringify(newVal ?? {}) !== JSON.stringify(oldVal ?? {})) {
|
|
127
|
+
assign();
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
onMounted(() => {
|
|
133
|
+
assign();
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
const selectYear = (year: number, instance: number) => {
|
|
137
|
+
calendars.value[instance].year = year;
|
|
138
|
+
emit('update-month-year', { instance, year, month: calendars.value[instance].month });
|
|
139
|
+
if (multiCalendars.value.count && !multiCalendars.value.solo) {
|
|
140
|
+
updateMultiCalendars(instance);
|
|
141
|
+
}
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
const groupedYears = computed(() => (instance: number): OverlayGridItem[][] => {
|
|
145
|
+
return groupListAndMap(years.value, (y: IDefaultSelect) => {
|
|
146
|
+
const active = year.value(instance) === y.value;
|
|
147
|
+
const disabled =
|
|
148
|
+
checkMinMaxValue(
|
|
149
|
+
y.value,
|
|
150
|
+
getMinMaxYear(propDates.value.minDate),
|
|
151
|
+
getMinMaxYear(propDates.value.maxDate),
|
|
152
|
+
) || filters.value.years?.includes(year.value(instance));
|
|
153
|
+
const highlighted = checkHighlightYear(highlight.value, y.value);
|
|
154
|
+
|
|
155
|
+
return { active, disabled, highlighted };
|
|
156
|
+
});
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
const handleYearSelect = (year: number, instance: number) => {
|
|
160
|
+
selectYear(year, instance);
|
|
161
|
+
toggleYearPicker(instance);
|
|
162
|
+
};
|
|
163
|
+
|
|
164
|
+
const handleYear = (instance: number, increment = false): void => {
|
|
165
|
+
if (!isDisabled.value(instance, increment)) {
|
|
166
|
+
const yearToSelect = increment ? year.value(instance) + 1 : year.value(instance) - 1;
|
|
167
|
+
selectYear(yearToSelect, instance);
|
|
168
|
+
}
|
|
169
|
+
};
|
|
170
|
+
|
|
171
|
+
const toggleYearPicker = (instance: number, flow = false, show?: boolean): void => {
|
|
172
|
+
if (!flow) {
|
|
173
|
+
emit('reset-flow');
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
if (show !== undefined) {
|
|
177
|
+
showYearPicker.value[instance] = show;
|
|
178
|
+
} else {
|
|
179
|
+
showYearPicker.value[instance] = !showYearPicker.value[instance];
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
if (!showYearPicker.value[instance]) {
|
|
183
|
+
emit('overlay-closed');
|
|
184
|
+
emit('overlay-toggle', { open: false, overlay: FlowStep.year });
|
|
185
|
+
} else {
|
|
186
|
+
emit('overlay-toggle', { open: true, overlay: FlowStep.year });
|
|
187
|
+
}
|
|
188
|
+
};
|
|
189
|
+
|
|
190
|
+
return {
|
|
191
|
+
isDisabled,
|
|
192
|
+
groupedYears,
|
|
193
|
+
showYearPicker,
|
|
194
|
+
selectYear,
|
|
195
|
+
toggleYearPicker,
|
|
196
|
+
handleYearSelect,
|
|
197
|
+
handleYear,
|
|
198
|
+
};
|
|
199
|
+
};
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
import { computed, reactive, ref } from 'vue';
|
|
2
|
+
|
|
3
|
+
type ElRefs = Array<HTMLElement | null>;
|
|
4
|
+
|
|
5
|
+
const refSets = reactive({
|
|
6
|
+
monthYear: [] as ElRefs,
|
|
7
|
+
calendar: [] as ElRefs[],
|
|
8
|
+
time: [] as ElRefs,
|
|
9
|
+
actionRow: [] as ElRefs,
|
|
10
|
+
selectionGrid: [] as ElRefs[],
|
|
11
|
+
timePicker: {
|
|
12
|
+
'0': [] as ElRefs[],
|
|
13
|
+
'1': [] as ElRefs[],
|
|
14
|
+
},
|
|
15
|
+
monthPicker: [] as ElRefs[],
|
|
16
|
+
});
|
|
17
|
+
const timePickerBackRef = ref<HTMLElement | null>(null);
|
|
18
|
+
const isSelectionGrid = ref(false);
|
|
19
|
+
const isTimePicker = ref(false);
|
|
20
|
+
const isMonthPicker = ref(false);
|
|
21
|
+
const isTimePickerMode = ref(false);
|
|
22
|
+
|
|
23
|
+
const selectedIndex = ref(0);
|
|
24
|
+
const activeRow = ref(0);
|
|
25
|
+
|
|
26
|
+
export const useArrowNavigation = () => {
|
|
27
|
+
const matrix = computed((): ElRefs[] => {
|
|
28
|
+
if (isSelectionGrid.value) return [...refSets.selectionGrid, refSets.actionRow].filter((set) => set.length);
|
|
29
|
+
if (isTimePicker.value) {
|
|
30
|
+
return [
|
|
31
|
+
...refSets.timePicker[0],
|
|
32
|
+
...refSets.timePicker[1],
|
|
33
|
+
isTimePickerMode.value ? [] : [timePickerBackRef.value],
|
|
34
|
+
refSets.actionRow,
|
|
35
|
+
].filter((set) => set.length);
|
|
36
|
+
}
|
|
37
|
+
if (isMonthPicker.value) return [...refSets.monthPicker, refSets.actionRow];
|
|
38
|
+
return [refSets.monthYear, ...refSets.calendar, refSets.time, refSets.actionRow].filter((set) => set.length);
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
// Handles left and right arrow
|
|
42
|
+
const handleSelectionIndexX = (increment?: boolean): void => {
|
|
43
|
+
selectedIndex.value = increment ? selectedIndex.value + 1 : selectedIndex.value - 1;
|
|
44
|
+
let el = null;
|
|
45
|
+
if (matrix.value[activeRow.value]) {
|
|
46
|
+
el = matrix.value[activeRow.value][selectedIndex.value];
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
if (!el && matrix.value[activeRow.value + (increment ? 1 : -1)]) {
|
|
50
|
+
activeRow.value = activeRow.value + (increment ? 1 : -1);
|
|
51
|
+
selectedIndex.value = increment ? 0 : matrix.value[activeRow.value].length - 1;
|
|
52
|
+
} else if (!el) {
|
|
53
|
+
selectedIndex.value = increment ? selectedIndex.value - 1 : selectedIndex.value + 1;
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
// Handles up and down arrow
|
|
58
|
+
const handleSelectionIndexY = (increment?: boolean): void => {
|
|
59
|
+
if ((activeRow.value === 0 && !increment) || (activeRow.value === matrix.value.length && increment)) return;
|
|
60
|
+
activeRow.value = increment ? activeRow.value + 1 : activeRow.value - 1;
|
|
61
|
+
const el = matrix.value[activeRow.value];
|
|
62
|
+
|
|
63
|
+
if (!el) {
|
|
64
|
+
activeRow.value = increment ? activeRow.value - 1 : activeRow.value + 1;
|
|
65
|
+
} else if (
|
|
66
|
+
matrix.value[activeRow.value] &&
|
|
67
|
+
!matrix.value[activeRow.value][selectedIndex.value] &&
|
|
68
|
+
selectedIndex.value !== 0
|
|
69
|
+
) {
|
|
70
|
+
selectedIndex.value = matrix.value[activeRow.value].length - 1;
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
const handleElFocus = (increment: boolean): void => {
|
|
75
|
+
let el = null;
|
|
76
|
+
if (matrix.value[activeRow.value]) {
|
|
77
|
+
el = matrix.value[activeRow.value][selectedIndex.value];
|
|
78
|
+
}
|
|
79
|
+
if (el) {
|
|
80
|
+
el.focus({ preventScroll: !isSelectionGrid.value });
|
|
81
|
+
} else {
|
|
82
|
+
selectedIndex.value = increment ? selectedIndex.value - 1 : selectedIndex.value + 1;
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
const arrowRight = (): void => {
|
|
87
|
+
handleSelectionIndexX(true);
|
|
88
|
+
handleElFocus(true);
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
const arrowLeft = (): void => {
|
|
92
|
+
handleSelectionIndexX(false);
|
|
93
|
+
handleElFocus(false);
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
const arrowUp = (): void => {
|
|
97
|
+
handleSelectionIndexY(false);
|
|
98
|
+
handleElFocus(true);
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
const arrowDown = (): void => {
|
|
102
|
+
handleSelectionIndexY(true);
|
|
103
|
+
handleElFocus(true);
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Add values per page, holds the ref values of the focusable elements
|
|
108
|
+
* Build top to bottom
|
|
109
|
+
*/
|
|
110
|
+
const buildMatrix = (elements: Array<HTMLElement | null>, set: 'monthYear' | 'time' | 'actionRow'): void => {
|
|
111
|
+
refSets[set] = elements;
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
const buildMultiLevelMatrix = (
|
|
115
|
+
elements: HTMLElement[][],
|
|
116
|
+
set: 'calendar' | 'selectionGrid' | 'monthPicker',
|
|
117
|
+
): void => {
|
|
118
|
+
refSets[set] = elements;
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
const resetNavigation = (): void => {
|
|
122
|
+
selectedIndex.value = 0;
|
|
123
|
+
activeRow.value = 0;
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
const setMonthPicker = (value: boolean): void => {
|
|
127
|
+
isMonthPicker.value = value;
|
|
128
|
+
resetNavigation();
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* For selection grid, things are handled per grid
|
|
133
|
+
*/
|
|
134
|
+
const setSelectionGrid = (value: boolean): void => {
|
|
135
|
+
isSelectionGrid.value = value;
|
|
136
|
+
resetNavigation();
|
|
137
|
+
if (!value) {
|
|
138
|
+
refSets.selectionGrid = [];
|
|
139
|
+
}
|
|
140
|
+
};
|
|
141
|
+
|
|
142
|
+
const setTimePicker = (value: boolean, mode = false) => {
|
|
143
|
+
isTimePicker.value = value;
|
|
144
|
+
isTimePickerMode.value = mode;
|
|
145
|
+
resetNavigation();
|
|
146
|
+
if (!value) {
|
|
147
|
+
refSets.timePicker[0] = [];
|
|
148
|
+
refSets.timePicker[1] = [];
|
|
149
|
+
}
|
|
150
|
+
};
|
|
151
|
+
|
|
152
|
+
const setTimePickerElements = (elements: HTMLElement[][], order: 0 | 1 = 0): void => {
|
|
153
|
+
refSets.timePicker[order] = elements;
|
|
154
|
+
};
|
|
155
|
+
|
|
156
|
+
const setTimePickerBackRef = (el: HTMLElement | null): void => {
|
|
157
|
+
timePickerBackRef.value = el;
|
|
158
|
+
};
|
|
159
|
+
|
|
160
|
+
const clearArrowNav = (): void => {
|
|
161
|
+
refSets.monthYear = [];
|
|
162
|
+
refSets.calendar = [];
|
|
163
|
+
refSets.time = [];
|
|
164
|
+
refSets.actionRow = [];
|
|
165
|
+
refSets.selectionGrid = [];
|
|
166
|
+
refSets.timePicker[0] = [];
|
|
167
|
+
refSets.timePicker[1] = [];
|
|
168
|
+
isSelectionGrid.value = false;
|
|
169
|
+
isTimePicker.value = false;
|
|
170
|
+
isTimePickerMode.value = false;
|
|
171
|
+
isMonthPicker.value = false;
|
|
172
|
+
resetNavigation();
|
|
173
|
+
timePickerBackRef.value = null;
|
|
174
|
+
};
|
|
175
|
+
|
|
176
|
+
return {
|
|
177
|
+
buildMatrix,
|
|
178
|
+
buildMultiLevelMatrix,
|
|
179
|
+
setTimePickerBackRef,
|
|
180
|
+
setSelectionGrid,
|
|
181
|
+
setTimePicker,
|
|
182
|
+
setTimePickerElements,
|
|
183
|
+
arrowRight,
|
|
184
|
+
arrowLeft,
|
|
185
|
+
arrowUp,
|
|
186
|
+
arrowDown,
|
|
187
|
+
clearArrowNav,
|
|
188
|
+
setMonthPicker,
|
|
189
|
+
refSets, // exposed for testing
|
|
190
|
+
};
|
|
191
|
+
};
|