Skip to content

Commit f0e9712

Browse files
committed
refactor(pt.7): Remove state managed props, use props as defined
- All components now have access to all props - Tests adjusted
1 parent 5da151b commit f0e9712

31 files changed

+829
-831
lines changed

src/VueDatePicker/VueDatePicker.vue

+27-8
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
ref="inputRef"
55
:is-menu-open="isOpen"
66
v-model:input-value="inputValue"
7+
v-bind="{ ...$props, ...defaults }"
78
@clear="clearValue"
89
@open="openMenu"
910
@set-input-date="setInputDate"
@@ -25,6 +26,8 @@
2526
:class="theme"
2627
:style="menuPosition"
2728
:open-on-top="openOnTop"
29+
v-bind="{ ...$props, ...defaults }"
30+
v-model:internal-model-value="internalModelValue"
2831
@close-picker="closeMenu"
2932
@select-date="selectDate"
3033
@dp-open="recalculatePosition"
@@ -43,7 +46,7 @@
4346
</template>
4447

4548
<script lang="ts" setup>
46-
import { computed, nextTick, onMounted, onUnmounted, ref, toRef, useSlots, watch, watchEffect } from 'vue';
49+
import { computed, nextTick, onMounted, onUnmounted, ref, toRef, useSlots, watch } from 'vue';
4750
4851
import DatepickerInput from './components/DatepickerInput.vue';
4952
import DatepickerMenu from './components/DatepickerMenu.vue';
@@ -58,6 +61,14 @@
5861
} from '@/components/composables';
5962
import { onClickOutside } from './directives/clickOutside';
6063
import { AllProps } from './utils/props';
64+
import { getDefaultFilters } from '@/utils/util';
65+
import {
66+
defaultAriaLabels,
67+
defaultMultiCalendars,
68+
defaultPreviewFormat,
69+
defaultTransitions,
70+
getDefaultTextInputOptions,
71+
} from '@/utils/defaults';
6172
6273
import type { DynamicClass } from './interfaces';
6374
@@ -84,13 +95,9 @@
8495
const dpMenuRef = ref(null);
8596
const inputRef = ref(null);
8697
87-
const { setProps, internalModelValue, setMenuFocused, setShiftKey } = useState();
98+
const { setMenuFocused, setShiftKey } = useState();
8899
const { clearArrowNav } = useArrowNavigation();
89-
const { validateDate, isValidTime } = useUtils();
90-
91-
watchEffect(() => {
92-
setProps(props);
93-
});
100+
const { validateDate, isValidTime, getDefaultPattern, getDefaultStartTime } = useUtils(props);
94101
95102
onMounted(() => {
96103
parseExternalModelValue(props.modelValue);
@@ -126,9 +133,21 @@
126133
dpMenuRef,
127134
inputRef,
128135
emit,
136+
props,
129137
);
130138
131-
const { inputValue, parseExternalModelValue, emitModelValue, formatInputValue } = useExternalInternalMapper(emit);
139+
const defaults = computed(() => ({
140+
ariaLabels: defaultAriaLabels(props.ariaLabels),
141+
textInputOptions: Object.assign(getDefaultTextInputOptions(), props.textInputOptions),
142+
multiCalendars: defaultMultiCalendars(props.multiCalendars),
143+
previewFormat: defaultPreviewFormat(props.previewFormat, props.format, getDefaultPattern()),
144+
filters: getDefaultFilters(props.filters),
145+
transitions: defaultTransitions(props.transitions),
146+
startTime: getDefaultStartTime(),
147+
}));
148+
149+
const { inputValue, internalModelValue, parseExternalModelValue, emitModelValue, formatInputValue } =
150+
useExternalInternalMapper(emit, { ...props, ...defaults.value });
132151
133152
const wrapperClass = computed(
134153
(): DynamicClass => ({

src/VueDatePicker/components/ActionRow.vue

+43-39
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,14 @@
1313
<slot name="action-select" v-if="$slots['action-select']" :value="internalModelValue" />
1414
<template v-if="!$slots['action-select']">
1515
<span
16-
v-if="!config.inline"
16+
v-if="!inline"
1717
class="dp__action dp__cancel"
1818
ref="cancelButtonRef"
1919
tabindex="0"
2020
@click="$emit('close-picker')"
2121
@keydown.enter="$emit('close-picker')"
2222
@keydown.space="$emit('close-picker')"
23-
>{{ config.cancelText }}</span
23+
>{{ cancelText }}</span
2424
>
2525
<span
2626
:class="selectClass"
@@ -30,7 +30,7 @@
3030
@click="selectDate"
3131
data-test="select-button"
3232
ref="selectButtonRef"
33-
>{{ config.selectText }}</span
33+
>{{ selectText }}</span
3434
>
3535
</template>
3636
</div>
@@ -41,32 +41,36 @@
4141
import { computed, onMounted, ref } from 'vue';
4242
4343
import { convertType, unrefElement } from '@/utils/util';
44-
import { useArrowNavigation, useState, useUtils } from '@/components/composables';
44+
import { useArrowNavigation, useUtils } from '@/components/composables';
45+
import { MergedProps } from '@/utils/props';
4546
4647
import type { PropType } from 'vue';
47-
48-
const { config, internalModelValue } = useState();
49-
const { formatDate, getDate, isDateAfter, isDateBefore, isValidTime } = useUtils();
50-
const { buildMatrix } = useArrowNavigation();
48+
import type { InternalModuleValue } from '@/interfaces';
5149
5250
const emit = defineEmits(['close-picker', 'select-date', 'invalid-select']);
5351
5452
const props = defineProps({
5553
calendarWidth: { type: Number as PropType<number>, default: 0 },
5654
menuMount: { type: Boolean as PropType<boolean>, default: false },
55+
internalModelValue: { type: [Date, Array] as PropType<InternalModuleValue>, default: null },
56+
...MergedProps,
5757
});
58+
59+
const { formatDate, getDate, isDateAfter, isDateBefore, isValidTime } = useUtils(props);
60+
const { buildMatrix } = useArrowNavigation();
61+
5862
const cancelButtonRef = ref(null);
5963
const selectButtonRef = ref(null);
6064
6165
onMounted(() => {
62-
if (config.value.arrowNavigation) {
66+
if (props.arrowNavigation) {
6367
buildMatrix([unrefElement(cancelButtonRef), unrefElement(selectButtonRef)] as HTMLElement[], 'actionRow');
6468
}
6569
});
6670
6771
const validDateRange = computed(() => {
68-
return config.value.range && !config.value.partialRange && internalModelValue.value
69-
? (internalModelValue.value as Date[]).length === 2
72+
return props.range && !props.partialRange && props.internalModelValue
73+
? (props.internalModelValue as Date[]).length === 2
7074
: true;
7175
});
7276
@@ -77,67 +81,67 @@
7781
}));
7882
7983
const isTimeValid = computed((): boolean => {
80-
if (!config.value.enableTimePicker || config.value.ignoreTimeValidation) return true;
81-
return isValidTime(internalModelValue.value);
84+
if (!props.enableTimePicker || props.ignoreTimeValidation) return true;
85+
return isValidTime(props.internalModelValue);
8286
});
8387
8488
const isMonthValid = computed((): boolean => {
85-
if (!config.value.monthPicker) return true;
86-
return isMonthWithinRange(internalModelValue.value as Date);
89+
if (!props.monthPicker) return true;
90+
return isMonthWithinRange(props.internalModelValue as Date);
8791
});
8892
8993
const handleCustomPreviewFormat = () => {
90-
const formatFn = config.value.previewFormat as (val: Date | Date[]) => string | string[];
94+
const formatFn = props.previewFormat as (val: Date | Date[]) => string | string[];
9195
92-
if (config.value.timePicker) return formatFn(convertType(internalModelValue.value));
96+
if (props.timePicker) return formatFn(convertType(props.internalModelValue));
9397
94-
if (config.value.monthPicker) return formatFn(convertType(internalModelValue.value as Date));
98+
if (props.monthPicker) return formatFn(convertType(props.internalModelValue as Date));
9599
96-
return formatFn(convertType(internalModelValue.value));
100+
return formatFn(convertType(props.internalModelValue));
97101
};
98102
99103
const formatRangeDate = () => {
100-
const dates = internalModelValue.value as Date[];
101-
if (config.value.multiCalendars > 0) {
104+
const dates = props.internalModelValue as Date[];
105+
if (props.multiCalendars > 0) {
102106
return `${formatDate(dates[0])} - ${formatDate(dates[1])}`;
103107
}
104108
return [formatDate(dates[0]), formatDate(dates[1])];
105109
};
106110
107111
const previewValue = computed((): string | string[] => {
108-
if (!internalModelValue.value || !props.menuMount) return '';
109-
if (typeof config.value.previewFormat === 'string') {
110-
if (Array.isArray(internalModelValue.value)) {
111-
if (internalModelValue.value.length === 2 && internalModelValue.value[1]) {
112+
if (!props.internalModelValue || !props.menuMount) return '';
113+
if (typeof props.previewFormat === 'string') {
114+
if (Array.isArray(props.internalModelValue)) {
115+
if (props.internalModelValue.length === 2 && props.internalModelValue[1]) {
112116
return formatRangeDate();
113117
}
114-
if (config.value.multiDates) {
115-
return internalModelValue.value.map((date) => `${formatDate(date)}`);
118+
if (props.multiDates) {
119+
return props.internalModelValue.map((date) => `${formatDate(date)}`);
116120
}
117-
if (config.value.modelAuto) {
118-
return `${formatDate(internalModelValue.value[0])}`;
121+
if (props.modelAuto) {
122+
return `${formatDate(props.internalModelValue[0])}`;
119123
}
120-
return `${formatDate(internalModelValue.value[0])} -`;
124+
return `${formatDate(props.internalModelValue[0])} -`;
121125
}
122-
return formatDate(internalModelValue.value);
126+
return formatDate(props.internalModelValue);
123127
}
124128
return handleCustomPreviewFormat();
125129
});
126130
127131
const isMonthWithinRange = (date: Date | string): boolean => {
128-
if (!config.value.monthPicker) return true;
132+
if (!props.monthPicker) return true;
129133
let valid = true;
130-
if (config.value.minDate && config.value.maxDate) {
134+
if (props.minDate && props.maxDate) {
131135
return (
132-
isDateAfter(getDate(date), getDate(config.value.minDate)) &&
133-
isDateBefore(getDate(date), getDate(config.value.maxDate))
136+
isDateAfter(getDate(date), getDate(props.minDate)) &&
137+
isDateBefore(getDate(date), getDate(props.maxDate))
134138
);
135139
}
136-
if (config.value.minDate) {
137-
valid = isDateAfter(getDate(date), getDate(config.value.minDate));
140+
if (props.minDate) {
141+
valid = isDateAfter(getDate(date), getDate(props.minDate));
138142
}
139-
if (config.value.maxDate) {
140-
valid = isDateBefore(getDate(date), getDate(config.value.maxDate));
143+
if (props.maxDate) {
144+
valid = isDateBefore(getDate(date), getDate(props.maxDate));
141145
}
142146
143147
return valid;

0 commit comments

Comments
 (0)