| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177 |
- <template>
- <Popup
- :show="popupShow"
- @close="onCancel"
- :closeIcon="false"
- position="bottom"
- closeable
- >
- <ActionSheetTitle
- v-bind="titleProps"
- :title="title"
- :confirmDisabled="confirmDisabled"
- border
- @cancel="onCancel"
- @confirm="onConfirm"
- />
- <Height :size="20" />
- <Calendar
- v-if="popupShow"
- v-bind="props"
- v-model="tempValue"
- @selectTextChange="onSelectTextChange"
- />
- <slot name="footer">
- <Height :size="20" />
- </slot>
- </Popup>
- <Text
- v-if="showSelectText"
- :size="30"
- :color="selectText ? 'text.content' : 'text.second'"
- :text="selectText || placeholder"
- :maxWidth="300"
- v-bind="textProps"
- />
- </template>
- <script setup lang="ts">
- import { computed, ref, toRef, watch } from 'vue';
- import { useFieldChildValueInjector } from './FormContext';
- import { usePickerFieldTempStorageData } from './PickerUtils';
- import type { CalendarProps } from './Calendar.vue';
- import Popup from '../dialog/Popup.vue';
- import ActionSheetTitle, { type ActionSheetTitleProps } from '../dialog/ActionSheetTitle.vue';
- import Calendar from './Calendar.vue';
- import Height from '../layout/space/Height.vue';
- import Text, { type TextProps } from '../basic/Text.vue';
- export interface CalendarFieldProps extends Omit<CalendarProps, 'modelValue'> {
-
- modelValue?: string|string[];
- /**
- * 标题
- */
- title?: string,
- /**
- * 标题属性
- */
- titleProps?: Omit<ActionSheetTitleProps, 'title'>,
- /**
- * 是否显示选择的文本。
- * @default true
- */
- showSelectText?: boolean,
- /**
- * 占位符
- */
- placeholder?: string,
- /**
- * 初始值
- */
- initalValue?: string[],
- /**
- * 是否在选择完成后立即更新值。
- * @default false
- */
- shouldUpdateValueImmediately?: boolean,
- /**
- * 显示的文本属性
- */
- textProps?: TextProps,
- /**
- * 是否在单选或者范围模式下,选择完成后直接关闭。
- * @default false
- */
- autoConfirm?: boolean,
- /**
- * 确认前的回调
- * @param value 选中的值
- * @returns 返回true可以阻止关闭弹窗
- */
- beforeConfirm?: (value: string|string[]|undefined) => Promise<boolean>,
- }
- const emit = defineEmits([ 'update:modelValue', 'cancel', 'confirm', 'selectTextChange', 'tempValueChange' ]);
- const props = withDefaults(defineProps<CalendarFieldProps>(), {
- title: '请选择日期',
- placeholder: '请选择日期',
- titleProps: () => ({
- cancelText: '取消',
- confirmText: '确定',
- }),
- showSelectText: true,
- showFestival: true,
- });
- const confirmDisabled = computed(() => {
- switch (props.pickType) {
- default:
- case 'days':
- case 'day':
- return (tempValue.value?.length || 0) < 1;
- case 'range':
- return tempValue.value?.length !== 2;
- }
- })
- const popupShow = ref(false);
- const {
- value,
- updateValue,
- } = useFieldChildValueInjector(
- toRef(props, 'modelValue'),
- (v) => emit('update:modelValue', v),
- undefined,
- () => {
- popupShow.value = true;
- },
- props.initalValue,
- );
- const {
- onSelectTextChange,
- onCancel,
- onConfirm,
- selectText,
- tempValue,
- } = usePickerFieldTempStorageData(
- value,
- updateValue,
- () => popupShow.value = false,
- emit as any,
- [],
- props.shouldUpdateValueImmediately,
- props.beforeConfirm,
- );
- watch(tempValue, (v) => {
- if (props.autoConfirm) {
- switch (props.pickType) {
- default:
- case 'day':
- if (v?.length)
- onConfirm();
- break;
- case 'range':
- if (v?.length === 2)
- onConfirm();
- break;
- case 'days':
- if ((v?.length || 0) >= (props.maxPickRangeDays || 100))
- onConfirm();
- break;
- }
- }
- })
- defineOptions({
- options: {
- styleIsolation: "shared",
- virtualHost: true,
- }
- })
- </script>
|