h5-tdsign-for-vue 0.1.0 → 0.1.1

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.
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sources":["../src/composables/usePopupField.ts","../src/components/SmartSelect/index.vue","../src/components/SmartTimePicker/index.vue","../src/components/SmartCascader/index.vue","../src/components/SmartTreeSelect/index.vue","../src/components/SmartUpload/index.vue","../src/components/SmartForm/index.vue"],"sourcesContent":["import { ref, computed, type Ref, type ComputedRef } from 'vue'\n\n/**\n * 弹窗字段通用逻辑 Hook\n * 用于 SmartSelect、SmartCascader、SmartTreeSelect、SmartTimePicker 等组件\n */\n\nexport interface UsePopupFieldOptions<T, O> {\n /** 当前选中值 (响应式) */\n modelValue: Ref<T | undefined>\n /** 数据源 (响应式) */\n options: Ref<O[]>\n /** 从选项中查找 label 的函数 */\n findLabel: (options: O[], value: T) => string | null\n /** 用户传入的显示 label (用于异步场景的 fallback) */\n displayLabel?: Ref<string | undefined>\n}\n\nexport interface UsePopupFieldReturn {\n /** 弹窗可见状态 */\n visible: Ref<boolean>\n /** 计算后的显示文本 */\n displayValue: ComputedRef<string>\n /** 打开弹窗 */\n openPopup: () => void\n /** 关闭弹窗 */\n closePopup: () => void\n}\n\nexport function usePopupField<T, O>(options: UsePopupFieldOptions<T, O>): UsePopupFieldReturn {\n const visible = ref(false)\n\n const displayValue = computed(() => {\n const val = options.modelValue.value\n if (val === undefined || val === null || val === '') {\n return ''\n }\n\n // 2. 尝试从 options 中查找 label\n const foundLabel = options.findLabel(options.options.value, val)\n if (foundLabel !== null) {\n return foundLabel\n }\n\n // 3. Fallback: 使用用户传入的 displayLabel\n if (options.displayLabel?.value) {\n return options.displayLabel.value\n }\n\n // 4. 最终 fallback: 直接显示原始值\n return String(val)\n })\n\n const openPopup = () => {\n visible.value = true\n }\n\n const closePopup = () => {\n visible.value = false\n }\n\n return {\n visible,\n displayValue,\n openPopup,\n closePopup,\n }\n}\n","<script lang=\"ts\">\nexport default {\n name: 'SmartSelect',\n}\n</script>\n\n<script setup lang=\"ts\">\nimport { h, computed, toRef } from 'vue'\nimport { Input as TInput, Popup as TPopup, Picker as TPicker, Icon } from 'tdesign-mobile-vue'\nimport type { PickerValue, PickerColumnItem } from 'tdesign-mobile-vue'\nimport type { SmartSelectProps } from './props'\nimport { usePopupField } from '../../composables/usePopupField'\n\nconst props = withDefaults(defineProps<SmartSelectProps>(), {\n modelValue: '',\n placeholder: '请选择',\n columns: () => [],\n title: '',\n required: false,\n rules: () => [],\n align: 'left',\n borderless: true,\n clearable: false,\n readonly: false,\n disabled: false,\n cancelBtn: true,\n confirmBtn: true,\n placement: 'bottom',\n showOverlay: true,\n})\n\nconst emit = defineEmits<{\n (e: 'update:modelValue', value: string | number | boolean): void\n (e: 'change', value: PickerValue[], context: unknown): void\n (e: 'confirm', value: PickerValue[], context: unknown): void\n (e: 'cancel', context: unknown): void\n}>()\n\nconst findLabelFromColumns = (\n cols: PickerColumnItem[] | PickerColumnItem[][],\n value: string | number | boolean,\n): string | null => {\n let flatColumns: PickerColumnItem[] = []\n if (Array.isArray(cols)) {\n if (cols.length > 0 && Array.isArray(cols[0])) {\n flatColumns = (cols as PickerColumnItem[][]).flat()\n } else {\n flatColumns = cols as PickerColumnItem[]\n }\n }\n const selectedItem = flatColumns.find((item) => item.value === value)\n return selectedItem ? selectedItem.label : null\n}\n\nconst { visible, displayValue, openPopup, closePopup } = usePopupField({\n modelValue: toRef(() => props.modelValue),\n options: toRef(() => props.columns as PickerColumnItem[]),\n findLabel: (cols, val) => findLabelFromColumns(cols, val as string | number | boolean),\n displayLabel: toRef(() => props.displayLabel),\n})\n\nconst POPUP_KEYS = ['attach', 'closeBtn', 'closeOnOverlayClick', 'destroyOnClose', 'duration', 'overlayProps', 'placement', 'preventScrollThrough', 'showOverlay', 'transitionName', 'zIndex'] as const\n\nconst popupBindProps = computed(() => {\n const result: Record<string, unknown> = {}\n const propsAny = props as Record<string, unknown>\n POPUP_KEYS.forEach((key) => {\n if (propsAny[key] !== undefined) {\n result[key] = propsAny[key]\n }\n })\n return result\n})\n\nconst INPUT_KEYS = ['align', 'autofocus', 'borderless', 'clearable', 'clearTrigger', 'disabled', 'label', 'layout', 'maxcharacter', 'maxlength', 'name', 'placeholder', 'prefixIcon', 'readonly', 'size', 'status', 'suffix', 'suffixIcon', 'tips', 'type'] as const\n\nconst inputBindProps = computed(() => {\n const result: Record<string, unknown> = {}\n const propsAny = props as Record<string, unknown>\n INPUT_KEYS.forEach((key) => {\n if (propsAny[key] !== undefined) {\n result[key] = propsAny[key]\n }\n })\n return result\n})\n\nconst onConfirm = (value: PickerValue[], context: unknown) => {\n const selectedValue = value[0]\n if (selectedValue !== undefined && typeof selectedValue !== 'object') {\n emit('update:modelValue', selectedValue)\n }\n emit('confirm', value, context)\n closePopup()\n}\n\nconst onCancel = (context: unknown) => {\n emit('cancel', context)\n closePopup()\n}\n\nconst onChange = (value: PickerValue[], context: unknown) => {\n emit('change', value, context)\n}\n</script>\n\n<template>\n <div class=\"smart-select\">\n <t-input\n :value=\"displayValue\"\n @click=\"openPopup\"\n v-bind=\"{ ...$attrs, ...inputBindProps }\"\n readonly\n :suffix-icon=\"() => h(Icon, { name: 'chevron-right' })\"\n >\n <template v-for=\"(_, slotName) in $slots\" #[slotName]=\"slotData\">\n <slot :name=\"slotName\" v-bind=\"slotData || {}\" />\n </template>\n </t-input>\n\n <t-popup v-model=\"visible\" placement=\"bottom\" v-bind=\"popupBindProps\">\n <t-picker\n :value=\"[modelValue as PickerValue]\"\n :columns=\"columns\"\n :title=\"title\"\n :cancel-btn=\"cancelBtn\"\n :confirm-btn=\"confirmBtn\"\n @confirm=\"onConfirm\"\n @cancel=\"onCancel\"\n @change=\"onChange\"\n />\n </t-popup>\n </div>\n</template>\n\n<style lang=\"scss\" scoped>\n.smart-select {\n width: 100%;\n}\n</style>\n","<script lang=\"ts\">\nexport default {\n name: 'SmartTimePicker',\n}\n</script>\n\n<script setup lang=\"ts\">\nimport { ref, h, computed } from 'vue'\nimport {\n Input as TInput,\n Popup as TPopup,\n DateTimePicker as TDateTimePicker,\n Icon,\n} from 'tdesign-mobile-vue'\nimport type { SmartTimePickerProps } from './props'\n\nconst props = withDefaults(defineProps<SmartTimePickerProps>(), {\n modelValue: '',\n // label: '', // 移除默认 label,避免在 SmartForm 中出现双重 label\n placeholder: '请选择时间',\n required: false,\n rules: () => [],\n\n // Input Defaults\n align: 'left',\n clearTrigger: 'always',\n cursorColor: '#0052d9',\n layout: 'horizontal',\n name: '',\n status: 'default',\n type: 'text',\n autofocus: false,\n borderless: true, // 默认无边框,避免与 FormItem 双下划线\n clearable: false,\n readonly: false,\n disabled: false,\n\n // DateTimePicker Defaults\n cancelBtn: '',\n confirmBtn: '',\n format: 'YYYY-MM-DD HH:mm:ss',\n mode: 'date',\n showWeek: false,\n steps: () => ({}),\n title: '',\n\n // Popup Defaults\n attach: 'body',\n closeOnOverlayClick: true,\n duration: 240,\n overlayProps: () => ({}),\n placement: 'bottom',\n preventScrollThrough: true,\n showOverlay: true,\n transitionName: '',\n})\n\nconst emit = defineEmits<{\n (e: 'update:modelValue', value: string | number): void\n (e: 'change', value: string | number): void\n (e: 'confirm', value: string | number): void\n (e: 'cancel', context: { e: MouseEvent }): void\n (e: 'pick', value: string | number): void\n}>()\n\nconst visible = ref(false)\n// const displayValue = ref('')\n\nconst POPUP_KEYS = [\n 'attach',\n 'closeBtn',\n 'closeOnOverlayClick',\n 'destroyOnClose',\n 'duration',\n 'overlayProps',\n 'placement',\n 'preventScrollThrough',\n 'showOverlay',\n 'transitionName',\n 'zIndex',\n 'onClose',\n 'onClosed',\n 'onOpen',\n 'onOpened',\n] as const\n\nconst propsAny = props as Record<string, unknown>\n\nconst popupBindProps = computed(() => {\n const result: Record<string, unknown> = {}\n POPUP_KEYS.forEach((key) => {\n if (propsAny[key] !== undefined) {\n result[key] = propsAny[key]\n }\n })\n return result\n})\n\nconst inputBindProps = computed(() => {\n const { modelValue, title, inputFormat, ...others } = props\n const result = { ...others } as Record<string, unknown>\n POPUP_KEYS.forEach((key) => {\n delete result[key]\n })\n // Omit DateTimePicker specific props that shouldn't be on Input\n const PICKER_KEYS = [\n 'cancelBtn',\n 'confirmBtn',\n 'end',\n 'footer',\n 'header',\n 'mode',\n 'renderLabel',\n 'showWeek',\n 'start',\n 'steps',\n 'format',\n ]\n PICKER_KEYS.forEach((key) => delete result[key])\n\n // Map inputFormat to format for Input component\n if (inputFormat) {\n result.format = inputFormat\n }\n\n return result\n})\n\nconst dateTimePickerBindProps = computed(() => {\n const { label, placeholder, rules, required, modelValue, ...others } = props\n const result = { ...others } as Record<string, unknown>\n POPUP_KEYS.forEach((key) => {\n delete result[key]\n })\n return result\n})\n\n// 使用 computed 替代 watch + ref\nconst displayValue = computed(() => {\n return String(props.modelValue || '')\n})\n\nconst onTriggerClick = () => {\n visible.value = true\n}\n\nconst onConfirm = (value: string | number) => {\n emit('update:modelValue', value)\n emit('confirm', value)\n visible.value = false\n}\n\nconst onCancel = (context: { e: MouseEvent }) => {\n emit('cancel', context)\n visible.value = false\n}\n\nconst onChange = (value: string | number) => {\n emit('change', value)\n}\n\nconst onPick = (value: string | number) => {\n emit('pick', value)\n}\n</script>\n\n<template>\n <div class=\"smart-time-picker\">\n <t-input\n :value=\"displayValue\"\n @click=\"onTriggerClick\"\n v-bind=\"{ ...$attrs, ...inputBindProps }\"\n readonly\n :suffix-icon=\"() => h(Icon, { name: 'chevron-right' })\"\n >\n <template v-for=\"(_, name) in $slots\" #[name]=\"slotData\">\n <slot :name=\"name\" v-bind=\"slotData || {}\" />\n </template>\n </t-input>\n\n <t-popup v-model=\"visible\" placement=\"bottom\" v-bind=\"popupBindProps\">\n <t-date-time-picker\n :value=\"modelValue\"\n v-bind=\"dateTimePickerBindProps\"\n @confirm=\"onConfirm\"\n @cancel=\"onCancel\"\n @change=\"onChange\"\n @pick=\"onPick\"\n />\n </t-popup>\n </div>\n</template>\n\n<style lang=\"scss\" scoped>\n.smart-time-picker {\n width: 100%;\n}\n</style>\n","<script lang=\"ts\">\nexport default {\n name: 'SmartCascader',\n}\n</script>\n\n<script setup lang=\"ts\">\nimport { h, computed, toRef } from 'vue'\nimport { Input as TInput, Cascader as TCascader, Icon } from 'tdesign-mobile-vue'\nimport type { SmartCascaderProps } from './props'\nimport { usePopupField } from '../../composables/usePopupField'\n\ninterface CascaderOption {\n label?: unknown\n value?: string | number\n children?: CascaderOption[]\n [key: string]: unknown\n}\n\nconst props = withDefaults(defineProps<SmartCascaderProps>(), {\n modelValue: '',\n placeholder: '请选择',\n options: () => [],\n title: '',\n required: false,\n rules: () => [],\n align: 'left',\n borderless: true,\n clearable: false,\n readonly: false,\n disabled: false,\n checkStrictly: false,\n theme: 'step',\n})\n\nconst emit = defineEmits<{\n (e: 'update:modelValue', value: string | number): void\n (e: 'change', value: string | number, context: unknown): void\n (e: 'pick', value: string | number, context: unknown): void\n (e: 'close', trigger: unknown): void\n}>()\n\nconst findLabelPath = (\n options: CascaderOption[],\n targetValue: string | number,\n path: string[] = [],\n): string[] | null => {\n for (const option of options) {\n const value = option.value ?? (option.id as string | number)\n const label = option.label ?? option.name\n if (value === targetValue) {\n return [...path, String(label)]\n }\n if (option.children && option.children.length > 0) {\n const found = findLabelPath(option.children, targetValue, [...path, String(label)])\n if (found) return found\n }\n }\n return null\n}\n\nconst findLabelFromOptions = (options: CascaderOption[], value: string | number): string | null => {\n const path = findLabelPath(options, value)\n return path ? path.join(' / ') : null\n}\n\nconst { visible, displayValue, openPopup, closePopup } = usePopupField({\n modelValue: toRef(() => props.modelValue),\n options: toRef(() => (props.options || []) as CascaderOption[]),\n findLabel: findLabelFromOptions,\n displayLabel: toRef(() => props.displayLabel),\n})\n\nconst INPUT_KEYS = ['align', 'autofocus', 'borderless', 'clearable', 'clearTrigger', 'disabled', 'label', 'layout', 'maxcharacter', 'maxlength', 'name', 'placeholder', 'prefixIcon', 'readonly', 'size', 'status', 'suffix', 'suffixIcon', 'tips', 'type'] as const\n\nconst inputBindProps = computed(() => {\n const result: Record<string, unknown> = {}\n const propsAny = props as Record<string, unknown>\n INPUT_KEYS.forEach((key) => {\n if (propsAny[key] !== undefined) {\n result[key] = propsAny[key]\n }\n })\n return result\n})\n\nconst CASCADER_KEYS = ['checkStrictly', 'closeBtn', 'header', 'keys', 'load', 'middleContent', 'options', 'overlayProps', 'subTitles', 'theme', 'title'] as const\n\nconst cascaderBindProps = computed(() => {\n const result: Record<string, unknown> = {}\n const propsAny = props as Record<string, unknown>\n CASCADER_KEYS.forEach((key) => {\n if (propsAny[key] !== undefined) {\n result[key] = propsAny[key]\n }\n })\n return result\n})\n\nconst onChange = (value: string | number, context: unknown) => {\n emit('update:modelValue', value)\n emit('change', value, context)\n closePopup()\n}\n\nconst onPick = (context: { value: string | number; label: string; index: number; level: number }) => {\n emit('pick', context.value, context)\n}\n\nconst onClose = (trigger: unknown) => {\n emit('close', trigger)\n closePopup()\n}\n</script>\n\n<template>\n <div class=\"smart-cascader\">\n <t-input\n :value=\"displayValue\"\n @click=\"openPopup\"\n v-bind=\"{ ...$attrs, ...inputBindProps }\"\n readonly\n :suffix-icon=\"() => h(Icon, { name: 'chevron-right' })\"\n >\n <template v-for=\"(_, slotName) in $slots\" #[slotName]=\"slotData\">\n <slot :name=\"slotName\" v-bind=\"slotData || {}\" />\n </template>\n </t-input>\n\n <t-cascader\n v-model:visible=\"visible\"\n :value=\"modelValue\"\n v-bind=\"cascaderBindProps\"\n @change=\"onChange\"\n @pick=\"onPick\"\n @close=\"onClose\"\n />\n </div>\n</template>\n\n<style lang=\"scss\" scoped>\n.smart-cascader {\n width: 100%;\n}\n</style>\n","<script lang=\"ts\">\nexport default {\n name: 'SmartTreeSelect',\n}\n</script>\n\n<script setup lang=\"ts\">\nimport { ref, h, computed, watch } from 'vue'\nimport {\n Input as TInput,\n Popup as TPopup,\n TreeSelect as TTreeSelect,\n Icon,\n} from 'tdesign-mobile-vue'\nimport type { TreeSelectValue, TreeLevel } from 'tdesign-mobile-vue'\nimport type { SmartTreeSelectProps } from './props'\n\nconst props = withDefaults(defineProps<SmartTreeSelectProps>(), {\n placeholder: '请选择',\n options: () => [],\n title: '',\n required: false,\n rules: () => [],\n // Input Defaults\n align: 'left',\n clearTrigger: 'always',\n cursorColor: '#0052d9',\n layout: 'horizontal',\n name: '',\n status: 'default',\n type: 'text',\n autofocus: false,\n borderless: true, // 默认无边框,避免与 FormItem 双下划线\n clearable: false,\n readonly: false,\n disabled: false,\n // TreeSelect Defaults\n height: 336,\n multiple: false,\n filterable: false,\n customStyle: '',\n // Popup Defaults\n attach: 'body',\n closeOnOverlayClick: true,\n duration: 240,\n overlayProps: () => ({}),\n placement: 'bottom',\n preventScrollThrough: true,\n showOverlay: true,\n transitionName: '',\n})\n\nconst emit = defineEmits<{\n (e: 'update:modelValue', value: TreeSelectValue): void\n (e: 'change', value: TreeSelectValue, level: TreeLevel): void\n (e: 'close', trigger: unknown): void\n}>()\n\nconst visible = ref(false)\n\n// Popup 属性 keys 列表\nconst POPUP_KEYS = [\n 'attach',\n 'closeBtn',\n 'closeOnOverlayClick',\n 'destroyOnClose',\n 'duration',\n 'overlayProps',\n 'placement',\n 'preventScrollThrough',\n 'showOverlay',\n 'transitionName',\n 'zIndex',\n 'onClose',\n 'onClosed',\n 'onOpen',\n 'onOpened',\n] as const\n\n// TreeSelect 专属属性 keys 列表\nconst TREE_SELECT_KEYS = [\n 'customStyle',\n 'filterable',\n 'height',\n 'keys',\n 'multiple',\n 'options',\n] as const\n\nconst propsAny = props as Record<string, unknown>\n\nconst popupBindProps = computed(() => {\n const result: Record<string, unknown> = {}\n POPUP_KEYS.forEach((key) => {\n if (propsAny[key] !== undefined) {\n result[key] = propsAny[key]\n }\n })\n return result\n})\n\nconst inputBindProps = computed(() => {\n const { modelValue, ...others } = props\n const result = { ...others } as Record<string, unknown>\n // 移除 Popup 属性\n POPUP_KEYS.forEach((key) => {\n delete result[key]\n })\n // 移除 TreeSelect 属性\n TREE_SELECT_KEYS.forEach((key) => {\n delete result[key]\n })\n // 移除自定义属性\n delete result['rules']\n delete result['required']\n delete result['title']\n return result\n})\n\nconst treeSelectBindProps = computed(() => {\n const result: Record<string, unknown> = {}\n TREE_SELECT_KEYS.forEach((key) => {\n if (key !== 'options' && propsAny[key] !== undefined) {\n result[key] = propsAny[key]\n }\n })\n // 添加 keys 属性\n if (propsAny['keys'] !== undefined) {\n result['keys'] = propsAny['keys']\n }\n return result\n})\n\n// 递归查找 Label\ninterface TreeOption {\n label?: string\n value?: string | number\n children?: TreeOption[]\n [key: string]: unknown\n}\n\n/**\n * 判断某个值是否是叶子节点\n */\nconst isLeafValue = (options: TreeOption[], targetValue: string | number): boolean => {\n for (const option of options) {\n if (option.value === targetValue) {\n // 如果没有 children 或 children 为空,则是叶子节点\n return !option.children || option.children.length === 0\n }\n if (option.children && option.children.length > 0) {\n const found = isLeafValue(option.children, targetValue)\n if (found !== false) return found\n }\n }\n return false\n}\n\n/**\n * 根据叶子节点值,构建完整的路径值数组\n * TDesign TreeSelect 需要 [level0Value, level1Value, level2Value] 格式的 value\n */\nconst buildValuePath = (\n options: TreeOption[],\n targetValue: string | number,\n path: (string | number)[] = [],\n): (string | number)[] | null => {\n for (const option of options) {\n if (option.value === targetValue) {\n return [...path, option.value]\n }\n if (option.children && option.children.length > 0) {\n const found = buildValuePath(option.children, targetValue, [...path, option.value!])\n if (found) return found\n }\n }\n return null\n}\n\n/**\n * 内部使用的数组格式 value(TDesign TreeSelect 需要)\n */\nconst internalValue = ref<Array<string | number>>([])\n\nconst normalizePathValue = (value: TreeSelectValue): Array<string | number> => {\n if (Array.isArray(value)) {\n return value\n .flatMap((item) => (Array.isArray(item) ? item : [item]))\n .filter(\n (item): item is string | number => typeof item === 'string' || typeof item === 'number',\n )\n }\n if (value === null || value === undefined || value === '') {\n return []\n }\n return [value as string | number]\n}\n\n// 监听外部 modelValue 变化,转换为内部数组格式\nwatch(\n () => props.modelValue,\n (newVal) => {\n if (Array.isArray(newVal)) {\n internalValue.value = normalizePathValue(newVal)\n } else if (newVal !== undefined && newVal !== '' && newVal !== null) {\n // 单个值,需要构建完整路径\n const opts = (props.options || []) as TreeOption[]\n const path = buildValuePath(opts, newVal as string | number)\n internalValue.value = path || []\n } else {\n internalValue.value = []\n }\n },\n { immediate: true },\n)\n\n// 监听 options 变化时也需要重新计算\nwatch(\n () => props.options,\n () => {\n const val = props.modelValue\n if (!Array.isArray(val) && val !== undefined && val !== '' && val !== null) {\n const opts = (props.options || []) as TreeOption[]\n const path = buildValuePath(opts, val as string | number)\n internalValue.value = path || []\n }\n },\n { deep: true },\n)\n\nconst findLabel = (options: TreeOption[], targetValue: string | number): string | null => {\n for (const option of options) {\n if (option.value === targetValue) {\n return option.label || String(option.value)\n }\n if (option.children && option.children.length > 0) {\n const found = findLabel(option.children, targetValue)\n if (found) return found\n }\n }\n return null\n}\n\nconst displayValue = computed(() => {\n const val = props.modelValue\n if (!val && val !== 0) {\n return ''\n }\n\n const opts = (props.options || []) as TreeOption[]\n\n if (Array.isArray(val)) {\n // 取最后一个值作为显示值\n const lastVal = val[val.length - 1]\n if (lastVal !== undefined) {\n return findLabel(opts, lastVal as string | number) || String(lastVal)\n }\n return ''\n }\n\n return findLabel(opts, val as string | number) || String(val)\n})\n\nconst onTriggerClick = () => {\n if (props.disabled) return\n visible.value = true\n}\n\n// 修复 onChange 事件签名,与组件库保持一致\nconst onChange = (value: TreeSelectValue, level: TreeLevel) => {\n // TDesign TreeSelect 返回的是数组格式 [level0, level1, level2, ...]\n // 我们需要取最后一级的值作为最终值传给父组件\n if (Array.isArray(value)) {\n const normalizedValue = normalizePathValue(value)\n const leafValue = normalizedValue[normalizedValue.length - 1]\n internalValue.value = normalizedValue\n\n // 判断是否选中了叶子节点\n const opts = (props.options || []) as TreeOption[]\n const isLeaf = isLeafValue(opts, leafValue as string | number)\n\n if (isLeaf) {\n // 只有选中叶子节点才更新外部值并关闭弹窗\n emit('update:modelValue', leafValue as TreeSelectValue)\n emit('change', leafValue as TreeSelectValue, level)\n // 单选时关闭弹窗\n if (!props.multiple) {\n visible.value = false\n }\n }\n } else {\n internalValue.value = normalizePathValue(value)\n emit('update:modelValue', value)\n emit('change', value, level)\n }\n}\n</script>\n\n<template>\n <div class=\"smart-tree-select\">\n <t-input\n :value=\"displayValue\"\n @click=\"onTriggerClick\"\n v-bind=\"{ ...$attrs, ...inputBindProps }\"\n readonly\n :suffix-icon=\"() => h(Icon, { name: 'chevron-right' })\"\n >\n <template v-for=\"(_, name) in $slots\" #[name]=\"slotData\">\n <slot :name=\"name\" v-bind=\"slotData || {}\" />\n </template>\n </t-input>\n\n <t-popup v-model=\"visible\" placement=\"bottom\" v-bind=\"popupBindProps\">\n <div class=\"tree-select-wrapper\">\n <t-tree-select\n v-if=\"visible\"\n :value=\"internalValue\"\n :options=\"options\"\n v-bind=\"treeSelectBindProps\"\n @change=\"onChange\"\n />\n </div>\n </t-popup>\n </div>\n</template>\n\n<style lang=\"scss\" scoped>\n.smart-tree-select {\n width: 100%;\n}\n.tree-select-wrapper {\n height: 50vh; // TreeSelect 需要高度\n display: flex;\n flex-direction: column;\n}\n</style>\n","<script lang=\"ts\">\nexport default {\n name: 'SmartUpload',\n}\n</script>\n\n<script setup lang=\"ts\">\nimport { computed, ref, watch, nextTick } from 'vue'\nimport {\n Upload as TUpload,\n Message,\n type SuccessContext,\n type UploadFailContext,\n type UploadRemoveContext,\n} from 'tdesign-mobile-vue'\nimport type { SmartUploadProps, SmartUploadFile, FileItem, FileListValue, FileListValueType } from './props'\n\nconst props = withDefaults(defineProps<SmartUploadProps>(), {\n modelValue: '',\n separator: ',',\n urlPrefix: '',\n urlKey: 'fileUrl',\n nameKey: 'filename',\n mode: 'image',\n accept: 'image/*',\n max: 9,\n maxSize: 10 * 1024,\n multiple: true,\n disabled: false,\n})\n\nconst emit = defineEmits<{\n (e: 'update:modelValue', value: FileListValue): void\n (e: 'success', context: SuccessContext): void\n (e: 'fail', context: UploadFailContext): void\n (e: 'remove', file: SmartUploadFile, index: number): void\n}>()\n\n\n// 内部文件列表(完全由 t-upload 控制)\nconst internalFiles = ref<SmartUploadFile[]>([])\n\n// 计算 accept 字符串\nconst acceptString = computed(() => {\n if (Array.isArray(props.accept)) {\n return props.accept.join(',')\n }\n return props.accept\n})\n\n/**\n * 判断值类型\n * 优先使用 props.valueType,否则自动推断\n */\nconst valueType = computed<FileListValueType>(() => {\n if (props.valueType) return props.valueType\n\n const list = props.modelValue\n if (typeof list === 'string') return 'string'\n if (Array.isArray(list)) {\n if (list.length === 0) return 'stringArray'\n if (typeof list[0] === 'object' && list[0] !== null) return 'objectArray'\n return 'stringArray'\n }\n return 'string'\n})\n\n/**\n * 判断是否为完整 URL\n */\nconst isFullUrl = (url: string) => /^(https?:|blob:|data:)/i.test(url)\n\n/**\n * 从对象或字符串中提取 URL\n */\nconst extractUrl = (item: string | FileItem): string => {\n if (typeof item === 'string') return item\n const url = item[props.urlKey]\n return typeof url === 'string' ? url : ''\n}\n\n/**\n * 从对象中提取 name\n */\nconst extractName = (item: string | FileItem, url: string): string => {\n if (typeof item === 'object' && item[props.nameKey]) {\n const name = item[props.nameKey]\n return typeof name === 'string' ? name : String(name)\n }\n return url.split('/').pop() || ''\n}\n\n/**\n * 从 URL 中去除前缀\n */\nconst removeUrlPrefix = (url: string): string => {\n if (!props.urlPrefix || !url) return url\n if (url.startsWith(props.urlPrefix)) {\n return url.slice(props.urlPrefix.length)\n }\n return url\n}\n\n/**\n * 将外部值转换为 UploadFile[] 用于显示\n */\nconst parseModelValue = (value: FileListValue): SmartUploadFile[] => {\n if (!value) return []\n\n // 解析为项目数组\n let items: (string | FileItem)[] = []\n if (typeof value === 'string') {\n items = value.split(props.separator).filter(Boolean)\n } else {\n items = value.filter(Boolean) as (string | FileItem)[]\n }\n\n // 转换为 SmartUploadFile[]\n return items.map((item, index) => {\n const url = extractUrl(item)\n if (!url) return null\n\n // 拼接前缀\n const displayUrl = isFullUrl(url) ? url : (props.urlPrefix + url)\n\n const fileInfo: SmartUploadFile = {\n url: displayUrl,\n name: extractName(item, url),\n status: 'success' as const,\n originalPath: url,\n }\n\n // 对象数组模式下,保存原始对象\n if (typeof item === 'object') {\n fileInfo.__rawResult__ = item as Record<string, unknown>\n }\n\n return fileInfo\n }).filter(Boolean) as SmartUploadFile[]\n}\n\n// 初始化/同步外部值到内部文件列表\nwatch(\n () => props.modelValue,\n (newVal) => {\n const parsed = parseModelValue(newVal)\n const currentSuccessUrls = internalFiles.value\n .filter((f) => f.status === 'success')\n .map((f) => f.originalPath || f.url)\n const parsedUrls = parsed.map((f) => f.originalPath || f.url)\n\n if (JSON.stringify(currentSuccessUrls) !== JSON.stringify(parsedUrls)) {\n const uploadingFiles = internalFiles.value.filter((f) => f.status !== 'success')\n internalFiles.value = [...parsed, ...uploadingFiles]\n }\n },\n { immediate: true },\n)\n\n\n/**\n * 同步内部文件列表到 modelValue\n */\nconst syncModelValue = () => {\n const finishedFiles = internalFiles.value.filter((f) => f.status === 'success')\n\n let result: FileListValue\n\n switch (valueType.value) {\n case 'string':\n result = finishedFiles\n .map((f) => removeUrlPrefix(f.originalPath || f.url || ''))\n .filter(Boolean)\n .join(props.separator)\n break\n\n case 'objectArray':\n result = finishedFiles.map((f) => {\n // 优先使用保存的完整返回对象\n if (f.__rawResult__ && typeof f.__rawResult__ === 'object') {\n const rawUrl = f.__rawResult__[props.urlKey]\n return {\n ...f.__rawResult__,\n [props.urlKey]: removeUrlPrefix(typeof rawUrl === 'string' ? rawUrl : (f.originalPath || f.url || '')),\n }\n }\n // 否则构建基础对象\n const baseObj: Record<string, unknown> = {\n [props.urlKey]: removeUrlPrefix(f.originalPath || f.url || ''),\n }\n if (props.nameKey) {\n baseObj[props.nameKey] = f.name\n }\n return baseObj\n })\n break\n\n case 'stringArray':\n default:\n result = finishedFiles\n .map((f) => removeUrlPrefix(f.originalPath || f.url || ''))\n .filter(Boolean)\n break\n }\n\n emit('update:modelValue', result)\n}\n\n// 上传成功处理\nconst onSuccess = (context: SuccessContext) => {\n const { file, response } = context\n\n console.log('[SmartUpload] onSuccess', { file, response })\n\n if (file) {\n // 使用 formatResponse 提取数据\n let uploadResult: string | Record<string, unknown> = ''\n if (props.formatResponse) {\n uploadResult = props.formatResponse(response)\n } else if (response && typeof response === 'object') {\n // TDesign 会把 response 包装成数组\n const data = Array.isArray(response) ? response[0] : response\n if (data && 'url' in data) {\n uploadResult = (data as { url: string }).url\n }\n }\n\n console.log('[SmartUpload] uploadResult:', uploadResult)\n\n if (uploadResult) {\n const isResultObject = typeof uploadResult === 'object'\n // 根据结果类型提取 fileUrl\n let fileUrl = ''\n let rawResultObj: Record<string, unknown> | undefined\n\n if (isResultObject) {\n const urlValue = (uploadResult as Record<string, unknown>)[props.urlKey]\n fileUrl = typeof urlValue === 'string' ? urlValue : ''\n rawResultObj = uploadResult as Record<string, unknown>\n } else {\n fileUrl = uploadResult as string\n }\n\n const displayUrl = isFullUrl(fileUrl) ? fileUrl : props.urlPrefix + fileUrl\n\n nextTick(() => {\n const fileIndex = internalFiles.value.findIndex((f) => f.name === file.name)\n console.log('[SmartUpload] fileIndex:', fileIndex)\n\n if (fileIndex >= 0) {\n internalFiles.value[fileIndex] = {\n ...internalFiles.value[fileIndex],\n status: 'success',\n url: displayUrl,\n originalPath: fileUrl,\n // 对象数组模式下保存完整返回\n __rawResult__: rawResultObj,\n }\n }\n\n syncModelValue()\n })\n }\n }\n\n emit('success', context)\n}\n\n// 上传失败处理\nconst onFail = (context: UploadFailContext) => {\n const { file } = context\n\n if (file) {\n const fileIndex = internalFiles.value.findIndex((f) => f.name === file.name)\n if (fileIndex >= 0) {\n internalFiles.value.splice(fileIndex, 1)\n }\n }\n\n Message.error('上传失败,请重试')\n emit('fail', context)\n}\n\n// 删除文件\nconst onRemove = (context: UploadRemoveContext) => {\n const { index = 0, file } = context\n emit('remove', file as SmartUploadFile, index)\n nextTick(() => {\n syncModelValue()\n })\n}\n\n// 校验处理:显示重复文件、文件过大等提示\nconst onValidate = (context: { type: string; files: unknown[] }) => {\n const { type, files } = context\n console.log('[SmartUpload] onValidate', { type, files })\n\n switch (type) {\n case 'FILTER_FILE_SAME_NAME':\n Message.info('请勿上传重复的文件')\n break\n case 'FILE_OVER_SIZE_LIMIT':\n Message.error(`文件大小超过限制(最大 ${Math.round(props.maxSize / 1024)}MB)`)\n break\n case 'FILES_OVER_LENGTH_LIMIT':\n Message.info(`最多只能上传 ${props.max} 个文件`)\n break\n }\n}\n\n</script>\n\n<template>\n <div class=\"smart-upload\">\n <!-- 图片模式 - 使用 TDesign 默认样式 -->\n <template v-if=\"mode === 'image'\">\n <t-upload\n v-model=\"internalFiles\"\n :action=\"action\"\n :accept=\"acceptString\"\n :max=\"max\"\n :size-limit=\"{ size: maxSize, unit: 'KB' }\"\n :multiple=\"multiple\"\n :disabled=\"disabled\"\n :request-method=\"requestMethod\"\n @success=\"onSuccess\"\n @fail=\"onFail\"\n @remove=\"onRemove\"\n @validate=\"onValidate\"\n />\n </template>\n\n <!-- 文件模式 - 使用 TDesign 默认样式 -->\n <template v-else>\n <t-upload\n v-model=\"internalFiles\"\n :action=\"action\"\n :accept=\"acceptString\"\n :max=\"max\"\n :size-limit=\"{ size: maxSize, unit: 'KB' }\"\n :multiple=\"multiple\"\n :disabled=\"disabled\"\n :request-method=\"requestMethod\"\n @success=\"onSuccess\"\n @fail=\"onFail\"\n @remove=\"onRemove\"\n @validate=\"onValidate\"\n />\n </template>\n </div>\n</template>\n\n<style lang=\"scss\" scoped>\n.smart-upload {\n width: 100%;\n :deep(.t-upload__item) {\n &:has(.t-image){\n background-color: #F1F1F1;\n display: flex;\n align-items: center;\n justify-content: center;\n }\n }\n :deep(.t-upload){\n grid-template-columns: repeat(3,1fr);\n row-gap: 8px;\n }\n}\n</style>\n\n","<script lang=\"ts\">\nexport default {\n name: 'SmartForm',\n}\n</script>\n\n<script setup lang=\"ts\" generic=\"T extends Record<string, unknown>\">\nimport { ref, toRaw, type Component } from 'vue'\nimport {\n Form as TForm,\n FormItem as TFormItem,\n Button as TButton,\n Input as TInput,\n Textarea as TTextarea,\n Switch as TSwitch,\n RadioGroup as TRadioGroup,\n CheckboxGroup as TCheckboxGroup,\n Stepper as TStepper,\n type SubmitContext,\n} from 'tdesign-mobile-vue'\nimport SmartSelect from '../SmartSelect/index.vue'\nimport SmartTimePicker from '../SmartTimePicker/index.vue'\nimport SmartCascader from '../SmartCascader/index.vue'\nimport SmartTreeSelect from '../SmartTreeSelect/index.vue'\nimport SmartUpload from '../SmartUpload/index.vue'\nimport type { FormSchema, SmartFormProps } from './types'\n\ninterface FormInstance {\n validate: (params?: {\n fields?: string[]\n trigger?: 'blur' | 'change' | 'all'\n showErrorMessage?: boolean\n }) => Promise<unknown>\n validateOnly: (params?: { fields?: string[]; trigger?: 'change' }) => Promise<unknown>\n submit: (params?: { showErrorMessage?: boolean }) => Promise<unknown>\n reset: (params?: { type?: 'initial' | 'empty'; fields?: string[] }) => void\n clearValidate: (fields?: string[]) => void\n setValidateMessage: (message: Record<string, unknown>) => void\n}\n\nconst props = withDefaults(defineProps<SmartFormProps<T>>(), {\n labelWidth: '80px',\n labelAlign: 'left',\n showFooter: true,\n submitBtnText: '提交',\n resetBtnText: '重置',\n loading: false,\n disabled: false,\n})\n\nconst emit = defineEmits<{\n (e: 'update:modelValue', value: Record<string, unknown>): void\n (e: 'submit', value: Record<string, unknown>): void\n (e: 'reset'): void\n (e: 'validate-failed', errors: unknown): void\n}>()\n\nconst formRef = ref<FormInstance>()\n\n// 内置组件映射\nconst builtInComponentMap: Record<string, Component> = {\n input: TInput,\n password: TInput,\n number: TInput,\n textarea: TTextarea,\n select: SmartSelect,\n cascader: SmartCascader,\n 'tree-select': SmartTreeSelect,\n date: SmartTimePicker,\n time: SmartTimePicker,\n switch: TSwitch,\n radio: TRadioGroup,\n checkbox: TCheckboxGroup,\n stepper: TStepper,\n upload: SmartUpload,\n}\n\n// 获取组件映射(优先使用用户自定义的 componentMap)\nconst getComponent = (type?: string): Component | null => {\n const targetType = type || 'input'\n\n // 1. 优先从用户自定义 componentMap 中查找\n if (props.componentMap?.[targetType]) {\n return props.componentMap[targetType]\n }\n\n // 2. 回退到内置组件映射\n return builtInComponentMap[targetType] ?? null\n}\n\n// 获取验证规则\nconst getRules = (schema: FormSchema<T>) => {\n const rules = []\n if (schema.required) {\n rules.push({ required: true, message: `${schema.label || '该项'}不能为空` })\n }\n if (schema.rules) {\n rules.push(...schema.rules)\n }\n return rules\n}\n\n// 处理表单项属性\nconst getItemProps = (schema: FormSchema<T>) => {\n const model = props.modelValue\n let itemProps: Record<string, unknown> = {}\n\n // 1. 获取基础 props\n if (typeof schema.props === 'function') {\n itemProps = schema.props(model)\n } else if (schema.props) {\n itemProps = { ...schema.props }\n }\n\n // 2. 处理特殊类型属性\n const type = schema.type || 'input'\n if (type === 'password') {\n Object.assign(itemProps, { type: 'password' })\n } else if (type === 'number') {\n Object.assign(itemProps, { type: 'number' })\n } else if (type === 'date') {\n Object.assign(itemProps, { mode: 'date' })\n } else if (type === 'time') {\n Object.assign(itemProps, { mode: ['hour', 'minute'] })\n }\n\n // 3. 对于 Input/Textarea 类型,仅在用户未显式设置时才应用默认 borderless\n // 这样用户可以通过 schema.props.borderless = false 来覆盖默认行为\n if (['input', 'password', 'number', 'textarea'].includes(type)) {\n // 检查用户是否显式设置了 borderless(包括设置为 false 的情况)\n const userExplicitlySetBorderless =\n typeof schema.props === 'object' &&\n schema.props !== null &&\n Object.prototype.hasOwnProperty.call(schema.props, 'borderless')\n if (!userExplicitlySetBorderless && itemProps.borderless === undefined) {\n itemProps.borderless = true\n }\n\n // 安全防护:防止 Input 组件接收 type=\"file\"\n // 如果 schema.type 默认为 input,但 props 中传入了 type: 'file',会导致 v-model 绑定失败引发 InvalidStateError\n if (itemProps.type === 'file') {\n console.warn(\n `[SmartForm] Detected type=\"file\" on Input component (field: ${schema.name}). Please use type: \"upload\" in your schema instead.`,\n )\n delete itemProps.type\n }\n }\n\n // 4. 全局禁用状态传递\n if (props.disabled) {\n Object.assign(itemProps, { disabled: true })\n } else if (schema.disabled) {\n // 字段级禁用控制\n const isDisabled =\n typeof schema.disabled === 'function' ? schema.disabled(model) : schema.disabled\n Object.assign(itemProps, { disabled: isDisabled })\n }\n\n return itemProps\n}\n\n// 判断表单项是否可见\nconst isVisible = (schema: FormSchema<T>) => {\n if (schema.hidden === undefined) return true\n if (typeof schema.hidden === 'function') {\n return !schema.hidden(props.modelValue)\n }\n return !schema.hidden\n}\n\nconst onSubmit = (context: SubmitContext) => {\n if (context.validateResult === true) {\n emit('submit', toRaw(props.modelValue))\n } else {\n emit('validate-failed', context.validateResult)\n }\n}\n\n// 重置处理\nconst onReset = () => {\n formRef.value?.reset()\n emit('reset')\n}\n\n// 暴露方法\ndefineExpose({\n validate: () => formRef.value?.validate(),\n reset: () => formRef.value?.reset(),\n clearValidate: () => formRef.value?.clearValidate(),\n})\n</script>\n\n<template>\n <div class=\"smart-form\">\n <t-form\n ref=\"formRef\"\n :data=\"modelValue\"\n :label-width=\"labelWidth\"\n :label-align=\"labelAlign\"\n @submit=\"onSubmit\"\n >\n <template v-for=\"schema in schemas\" :key=\"schema.name\">\n <t-form-item\n v-if=\"isVisible(schema)\"\n :name=\"schema.name\"\n :label=\"schema.label\"\n :rules=\"getRules(schema)\"\n :help=\"schema.help\"\n >\n <!-- 自定义插槽 -->\n <template v-if=\"schema.type === 'slot' && schema.slot\">\n <slot :name=\"schema.slot\" :model=\"modelValue\" :schema=\"schema\" />\n </template>\n\n <!-- 动态组件渲染 -->\n <component\n :is=\"getComponent(schema.type)\"\n v-else\n v-model=\"(modelValue as Record<string, any>)[schema.name]\"\n v-bind=\"getItemProps(schema)\"\n />\n </t-form-item>\n </template>\n\n <!-- 底部按钮 -->\n <div v-if=\"showFooter\" class=\"smart-form-footer\">\n <t-button theme=\"primary\" type=\"submit\" block :loading=\"loading\" :disabled=\"disabled\">\n {{ submitBtnText }}\n </t-button>\n <t-button\n v-if=\"resetBtnText\"\n theme=\"default\"\n variant=\"outline\"\n block\n class=\"reset-btn\"\n @click=\"onReset\"\n :disabled=\"disabled || loading\"\n >\n {{ resetBtnText }}\n </t-button>\n </div>\n </t-form>\n </div>\n</template>\n\n<style lang=\"scss\" scoped>\n.smart-form {\n .smart-form-footer {\n padding: 16px;\n display: flex;\n flex-direction: column;\n gap: 12px;\n\n .reset-btn {\n margin-top: 0; // 覆盖 tdesign 默认样式\n }\n }\n}\n</style>\n"],"names":["usePopupField","options","visible","ref","displayValue","computed","val","foundLabel","__default__","props","__props","emit","__emit","findLabelFromColumns","cols","value","flatColumns","selectedItem","item","openPopup","closePopup","toRef","POPUP_KEYS","popupBindProps","result","propsAny","key","INPUT_KEYS","inputBindProps","onConfirm","context","selectedValue","onCancel","onChange","_openBlock","_createElementBlock","_hoisted_1","_createVNode","_unref","_mergeProps","$attrs","h","Icon","$slots","_","slotName","_withCtx","slotData","_renderSlot","_ctx","_normalizeProps","_guardReactiveProps","$event","TPicker","modelValue","title","inputFormat","others","dateTimePickerBindProps","label","placeholder","rules","required","onTriggerClick","onPick","name","findLabelPath","targetValue","path","option","found","findLabelFromOptions","CASCADER_KEYS","cascaderBindProps","onClose","trigger","TREE_SELECT_KEYS","treeSelectBindProps","isLeafValue","buildValuePath","internalValue","normalizePathValue","watch","newVal","opts","findLabel","lastVal","level","normalizedValue","leafValue","_createElementVNode","_hoisted_2","_createBlock","internalFiles","acceptString","valueType","list","isFullUrl","url","extractUrl","extractName","removeUrlPrefix","parseModelValue","items","index","fileInfo","parsed","currentSuccessUrls","f","parsedUrls","uploadingFiles","syncModelValue","finishedFiles","rawUrl","baseObj","onSuccess","file","response","uploadResult","data","isResultObject","fileUrl","rawResultObj","urlValue","displayUrl","nextTick","fileIndex","onFail","Message","onRemove","onValidate","type","files","TUpload","formRef","builtInComponentMap","TInput","TTextarea","SmartSelect","SmartCascader","SmartTreeSelect","SmartTimePicker","TSwitch","TRadioGroup","TCheckboxGroup","TStepper","SmartUpload","getComponent","targetType","getRules","schema","getItemProps","model","itemProps","isDisabled","isVisible","onSubmit","toRaw","onReset","__expose","TForm","_Fragment","_renderList","TFormItem","_resolveDynamicComponent","TButton"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs","sources":["../src/composables/usePopupField.ts","../src/components/SmartSelect/index.vue","../src/components/SmartTimePicker/index.vue","../src/components/SmartCascader/index.vue","../src/components/SmartTreeSelect/index.vue","../src/components/SmartUpload/index.vue","../src/components/SmartForm/index.vue","../src/components/SmartPage/index.vue"],"sourcesContent":["import { ref, computed, type Ref, type ComputedRef } from 'vue'\n\n/**\n * 弹窗字段通用逻辑 Hook\n * 用于 SmartSelect、SmartCascader、SmartTreeSelect、SmartTimePicker 等组件\n */\n\nexport interface UsePopupFieldOptions<T, O> {\n /** 当前选中值 (响应式) */\n modelValue: Ref<T | undefined>\n /** 数据源 (响应式) */\n options: Ref<O[]>\n /** 从选项中查找 label 的函数 */\n findLabel: (options: O[], value: T) => string | null\n /** 用户传入的显示 label (用于异步场景的 fallback) */\n displayLabel?: Ref<string | undefined>\n}\n\nexport interface UsePopupFieldReturn {\n /** 弹窗可见状态 */\n visible: Ref<boolean>\n /** 计算后的显示文本 */\n displayValue: ComputedRef<string>\n /** 打开弹窗 */\n openPopup: () => void\n /** 关闭弹窗 */\n closePopup: () => void\n}\n\nexport function usePopupField<T, O>(options: UsePopupFieldOptions<T, O>): UsePopupFieldReturn {\n const visible = ref(false)\n\n const displayValue = computed(() => {\n const val = options.modelValue.value\n if (val === undefined || val === null || val === '') {\n return ''\n }\n\n // 2. 尝试从 options 中查找 label\n const foundLabel = options.findLabel(options.options.value, val)\n if (foundLabel !== null) {\n return foundLabel\n }\n\n // 3. Fallback: 使用用户传入的 displayLabel\n if (options.displayLabel?.value) {\n return options.displayLabel.value\n }\n\n // 4. 最终 fallback: 直接显示原始值\n return String(val)\n })\n\n const openPopup = () => {\n visible.value = true\n }\n\n const closePopup = () => {\n visible.value = false\n }\n\n return {\n visible,\n displayValue,\n openPopup,\n closePopup,\n }\n}\n","<script lang=\"ts\">\nexport default {\n name: 'SmartSelect',\n}\n</script>\n\n<script setup lang=\"ts\">\nimport { h, computed, toRef } from 'vue'\nimport { Input as TInput, Popup as TPopup, Picker as TPicker, Icon } from 'tdesign-mobile-vue'\nimport type { PickerValue, PickerColumnItem } from 'tdesign-mobile-vue'\nimport type { SmartSelectProps } from './props'\nimport { usePopupField } from '../../composables/usePopupField'\n\nconst props = withDefaults(defineProps<SmartSelectProps>(), {\n modelValue: '',\n placeholder: '请选择',\n columns: () => [],\n title: '',\n required: false,\n rules: () => [],\n align: 'left',\n borderless: true,\n clearable: false,\n readonly: false,\n disabled: false,\n cancelBtn: true,\n confirmBtn: true,\n placement: 'bottom',\n showOverlay: true,\n})\n\nconst emit = defineEmits<{\n (e: 'update:modelValue', value: string | number | boolean): void\n (e: 'change', value: PickerValue[], context: unknown): void\n (e: 'confirm', value: PickerValue[], context: unknown): void\n (e: 'cancel', context: unknown): void\n}>()\n\nconst findLabelFromColumns = (\n cols: PickerColumnItem[] | PickerColumnItem[][],\n value: string | number | boolean,\n): string | null => {\n let flatColumns: PickerColumnItem[] = []\n if (Array.isArray(cols)) {\n if (cols.length > 0 && Array.isArray(cols[0])) {\n flatColumns = (cols as PickerColumnItem[][]).flat()\n } else {\n flatColumns = cols as PickerColumnItem[]\n }\n }\n const selectedItem = flatColumns.find((item) => item.value === value)\n return selectedItem ? selectedItem.label : null\n}\n\nconst { visible, displayValue, openPopup, closePopup } = usePopupField({\n modelValue: toRef(() => props.modelValue),\n options: toRef(() => props.columns as PickerColumnItem[]),\n findLabel: (cols, val) => findLabelFromColumns(cols, val as string | number | boolean),\n displayLabel: toRef(() => props.displayLabel),\n})\n\nconst POPUP_KEYS = ['attach', 'closeBtn', 'closeOnOverlayClick', 'destroyOnClose', 'duration', 'overlayProps', 'placement', 'preventScrollThrough', 'showOverlay', 'transitionName', 'zIndex'] as const\n\nconst popupBindProps = computed(() => {\n const result: Record<string, unknown> = {}\n const propsAny = props as Record<string, unknown>\n POPUP_KEYS.forEach((key) => {\n if (propsAny[key] !== undefined) {\n result[key] = propsAny[key]\n }\n })\n return result\n})\n\nconst INPUT_KEYS = ['align', 'autofocus', 'borderless', 'clearable', 'clearTrigger', 'disabled', 'label', 'layout', 'maxcharacter', 'maxlength', 'name', 'placeholder', 'prefixIcon', 'readonly', 'size', 'status', 'suffix', 'suffixIcon', 'tips', 'type'] as const\n\nconst inputBindProps = computed(() => {\n const result: Record<string, unknown> = {}\n const propsAny = props as Record<string, unknown>\n INPUT_KEYS.forEach((key) => {\n if (propsAny[key] !== undefined) {\n result[key] = propsAny[key]\n }\n })\n return result\n})\n\nconst onConfirm = (value: PickerValue[], context: unknown) => {\n const selectedValue = value[0]\n if (selectedValue !== undefined && typeof selectedValue !== 'object') {\n emit('update:modelValue', selectedValue)\n }\n emit('confirm', value, context)\n closePopup()\n}\n\nconst onCancel = (context: unknown) => {\n emit('cancel', context)\n closePopup()\n}\n\nconst onChange = (value: PickerValue[], context: unknown) => {\n emit('change', value, context)\n}\n</script>\n\n<template>\n <div class=\"smart-select\">\n <t-input\n :value=\"displayValue\"\n @click=\"openPopup\"\n v-bind=\"{ ...$attrs, ...inputBindProps }\"\n readonly\n :suffix-icon=\"() => h(Icon, { name: 'chevron-right' })\"\n >\n <template v-for=\"(_, slotName) in $slots\" #[slotName]=\"slotData\">\n <slot :name=\"slotName\" v-bind=\"slotData || {}\" />\n </template>\n </t-input>\n\n <t-popup v-model=\"visible\" placement=\"bottom\" v-bind=\"popupBindProps\">\n <t-picker\n :value=\"[modelValue as PickerValue]\"\n :columns=\"columns\"\n :title=\"title\"\n :cancel-btn=\"cancelBtn\"\n :confirm-btn=\"confirmBtn\"\n @confirm=\"onConfirm\"\n @cancel=\"onCancel\"\n @change=\"onChange\"\n />\n </t-popup>\n </div>\n</template>\n\n<style lang=\"scss\" scoped>\n.smart-select {\n width: 100%;\n}\n</style>\n","<script lang=\"ts\">\nexport default {\n name: 'SmartTimePicker',\n}\n</script>\n\n<script setup lang=\"ts\">\nimport { ref, h, computed } from 'vue'\nimport {\n Input as TInput,\n Popup as TPopup,\n DateTimePicker as TDateTimePicker,\n Icon,\n} from 'tdesign-mobile-vue'\nimport type { SmartTimePickerProps } from './props'\n\nconst props = withDefaults(defineProps<SmartTimePickerProps>(), {\n modelValue: '',\n // label: '', // 移除默认 label,避免在 SmartForm 中出现双重 label\n placeholder: '请选择时间',\n required: false,\n rules: () => [],\n\n // Input Defaults\n align: 'left',\n clearTrigger: 'always',\n cursorColor: '#0052d9',\n layout: 'horizontal',\n name: '',\n status: 'default',\n type: 'text',\n autofocus: false,\n borderless: true, // 默认无边框,避免与 FormItem 双下划线\n clearable: false,\n readonly: false,\n disabled: false,\n\n // DateTimePicker Defaults\n cancelBtn: '',\n confirmBtn: '',\n format: 'YYYY-MM-DD HH:mm:ss',\n mode: 'date',\n showWeek: false,\n steps: () => ({}),\n title: '',\n\n // Popup Defaults\n attach: 'body',\n closeOnOverlayClick: true,\n duration: 240,\n overlayProps: () => ({}),\n placement: 'bottom',\n preventScrollThrough: true,\n showOverlay: true,\n transitionName: '',\n})\n\nconst emit = defineEmits<{\n (e: 'update:modelValue', value: string | number): void\n (e: 'change', value: string | number): void\n (e: 'confirm', value: string | number): void\n (e: 'cancel', context: { e: MouseEvent }): void\n (e: 'pick', value: string | number): void\n}>()\n\nconst visible = ref(false)\n// const displayValue = ref('')\n\nconst POPUP_KEYS = [\n 'attach',\n 'closeBtn',\n 'closeOnOverlayClick',\n 'destroyOnClose',\n 'duration',\n 'overlayProps',\n 'placement',\n 'preventScrollThrough',\n 'showOverlay',\n 'transitionName',\n 'zIndex',\n 'onClose',\n 'onClosed',\n 'onOpen',\n 'onOpened',\n] as const\n\nconst propsAny = props as Record<string, unknown>\n\nconst popupBindProps = computed(() => {\n const result: Record<string, unknown> = {}\n POPUP_KEYS.forEach((key) => {\n if (propsAny[key] !== undefined) {\n result[key] = propsAny[key]\n }\n })\n return result\n})\n\nconst inputBindProps = computed(() => {\n const { modelValue, title, inputFormat, ...others } = props\n const result = { ...others } as Record<string, unknown>\n POPUP_KEYS.forEach((key) => {\n delete result[key]\n })\n // Omit DateTimePicker specific props that shouldn't be on Input\n const PICKER_KEYS = [\n 'cancelBtn',\n 'confirmBtn',\n 'end',\n 'footer',\n 'header',\n 'mode',\n 'renderLabel',\n 'showWeek',\n 'start',\n 'steps',\n 'format',\n ]\n PICKER_KEYS.forEach((key) => delete result[key])\n\n // Map inputFormat to format for Input component\n if (inputFormat) {\n result.format = inputFormat\n }\n\n return result\n})\n\nconst dateTimePickerBindProps = computed(() => {\n const { label, placeholder, rules, required, modelValue, ...others } = props\n const result = { ...others } as Record<string, unknown>\n POPUP_KEYS.forEach((key) => {\n delete result[key]\n })\n return result\n})\n\n// 使用 computed 替代 watch + ref\nconst displayValue = computed(() => {\n return String(props.modelValue || '')\n})\n\nconst onTriggerClick = () => {\n visible.value = true\n}\n\nconst onConfirm = (value: string | number) => {\n emit('update:modelValue', value)\n emit('confirm', value)\n visible.value = false\n}\n\nconst onCancel = (context: { e: MouseEvent }) => {\n emit('cancel', context)\n visible.value = false\n}\n\nconst onChange = (value: string | number) => {\n emit('change', value)\n}\n\nconst onPick = (value: string | number) => {\n emit('pick', value)\n}\n</script>\n\n<template>\n <div class=\"smart-time-picker\">\n <t-input\n :value=\"displayValue\"\n @click=\"onTriggerClick\"\n v-bind=\"{ ...$attrs, ...inputBindProps }\"\n readonly\n :suffix-icon=\"() => h(Icon, { name: 'chevron-right' })\"\n >\n <template v-for=\"(_, name) in $slots\" #[name]=\"slotData\">\n <slot :name=\"name\" v-bind=\"slotData || {}\" />\n </template>\n </t-input>\n\n <t-popup v-model=\"visible\" placement=\"bottom\" v-bind=\"popupBindProps\">\n <t-date-time-picker\n :value=\"modelValue\"\n v-bind=\"dateTimePickerBindProps\"\n @confirm=\"onConfirm\"\n @cancel=\"onCancel\"\n @change=\"onChange\"\n @pick=\"onPick\"\n />\n </t-popup>\n </div>\n</template>\n\n<style lang=\"scss\" scoped>\n.smart-time-picker {\n width: 100%;\n}\n</style>\n","<script lang=\"ts\">\nexport default {\n name: 'SmartCascader',\n}\n</script>\n\n<script setup lang=\"ts\">\nimport { h, computed, toRef } from 'vue'\nimport { Input as TInput, Cascader as TCascader, Icon } from 'tdesign-mobile-vue'\nimport type { SmartCascaderProps } from './props'\nimport { usePopupField } from '../../composables/usePopupField'\n\ninterface CascaderOption {\n label?: unknown\n value?: string | number\n children?: CascaderOption[]\n [key: string]: unknown\n}\n\nconst props = withDefaults(defineProps<SmartCascaderProps>(), {\n modelValue: '',\n placeholder: '请选择',\n options: () => [],\n title: '',\n required: false,\n rules: () => [],\n align: 'left',\n borderless: true,\n clearable: false,\n readonly: false,\n disabled: false,\n checkStrictly: false,\n theme: 'step',\n})\n\nconst emit = defineEmits<{\n (e: 'update:modelValue', value: string | number): void\n (e: 'change', value: string | number, context: unknown): void\n (e: 'pick', value: string | number, context: unknown): void\n (e: 'close', trigger: unknown): void\n}>()\n\nconst findLabelPath = (\n options: CascaderOption[],\n targetValue: string | number,\n path: string[] = [],\n): string[] | null => {\n for (const option of options) {\n const value = option.value ?? (option.id as string | number)\n const label = option.label ?? option.name\n if (value === targetValue) {\n return [...path, String(label)]\n }\n if (option.children && option.children.length > 0) {\n const found = findLabelPath(option.children, targetValue, [...path, String(label)])\n if (found) return found\n }\n }\n return null\n}\n\nconst findLabelFromOptions = (options: CascaderOption[], value: string | number): string | null => {\n const path = findLabelPath(options, value)\n return path ? path.join(' / ') : null\n}\n\nconst { visible, displayValue, openPopup, closePopup } = usePopupField({\n modelValue: toRef(() => props.modelValue),\n options: toRef(() => (props.options || []) as CascaderOption[]),\n findLabel: findLabelFromOptions,\n displayLabel: toRef(() => props.displayLabel),\n})\n\nconst INPUT_KEYS = ['align', 'autofocus', 'borderless', 'clearable', 'clearTrigger', 'disabled', 'label', 'layout', 'maxcharacter', 'maxlength', 'name', 'placeholder', 'prefixIcon', 'readonly', 'size', 'status', 'suffix', 'suffixIcon', 'tips', 'type'] as const\n\nconst inputBindProps = computed(() => {\n const result: Record<string, unknown> = {}\n const propsAny = props as Record<string, unknown>\n INPUT_KEYS.forEach((key) => {\n if (propsAny[key] !== undefined) {\n result[key] = propsAny[key]\n }\n })\n return result\n})\n\nconst CASCADER_KEYS = ['checkStrictly', 'closeBtn', 'header', 'keys', 'load', 'middleContent', 'options', 'overlayProps', 'subTitles', 'theme', 'title'] as const\n\nconst cascaderBindProps = computed(() => {\n const result: Record<string, unknown> = {}\n const propsAny = props as Record<string, unknown>\n CASCADER_KEYS.forEach((key) => {\n if (propsAny[key] !== undefined) {\n result[key] = propsAny[key]\n }\n })\n return result\n})\n\nconst onChange = (value: string | number, context: unknown) => {\n emit('update:modelValue', value)\n emit('change', value, context)\n closePopup()\n}\n\nconst onPick = (context: { value: string | number; label: string; index: number; level: number }) => {\n emit('pick', context.value, context)\n}\n\nconst onClose = (trigger: unknown) => {\n emit('close', trigger)\n closePopup()\n}\n</script>\n\n<template>\n <div class=\"smart-cascader\">\n <t-input\n :value=\"displayValue\"\n @click=\"openPopup\"\n v-bind=\"{ ...$attrs, ...inputBindProps }\"\n readonly\n :suffix-icon=\"() => h(Icon, { name: 'chevron-right' })\"\n >\n <template v-for=\"(_, slotName) in $slots\" #[slotName]=\"slotData\">\n <slot :name=\"slotName\" v-bind=\"slotData || {}\" />\n </template>\n </t-input>\n\n <t-cascader\n v-model:visible=\"visible\"\n :value=\"modelValue\"\n v-bind=\"cascaderBindProps\"\n @change=\"onChange\"\n @pick=\"onPick\"\n @close=\"onClose\"\n />\n </div>\n</template>\n\n<style lang=\"scss\" scoped>\n.smart-cascader {\n width: 100%;\n}\n</style>\n","<script lang=\"ts\">\nexport default {\n name: 'SmartTreeSelect',\n}\n</script>\n\n<script setup lang=\"ts\">\nimport { ref, h, computed, watch } from 'vue'\nimport {\n Input as TInput,\n Popup as TPopup,\n TreeSelect as TTreeSelect,\n Icon,\n} from 'tdesign-mobile-vue'\nimport type { TreeSelectValue, TreeLevel } from 'tdesign-mobile-vue'\nimport type { SmartTreeSelectProps } from './props'\n\nconst props = withDefaults(defineProps<SmartTreeSelectProps>(), {\n placeholder: '请选择',\n options: () => [],\n title: '',\n required: false,\n rules: () => [],\n // Input Defaults\n align: 'left',\n clearTrigger: 'always',\n cursorColor: '#0052d9',\n layout: 'horizontal',\n name: '',\n status: 'default',\n type: 'text',\n autofocus: false,\n borderless: true, // 默认无边框,避免与 FormItem 双下划线\n clearable: false,\n readonly: false,\n disabled: false,\n // TreeSelect Defaults\n height: 336,\n multiple: false,\n filterable: false,\n customStyle: '',\n // Popup Defaults\n attach: 'body',\n closeOnOverlayClick: true,\n duration: 240,\n overlayProps: () => ({}),\n placement: 'bottom',\n preventScrollThrough: true,\n showOverlay: true,\n transitionName: '',\n})\n\nconst emit = defineEmits<{\n (e: 'update:modelValue', value: TreeSelectValue): void\n (e: 'change', value: TreeSelectValue, level: TreeLevel): void\n (e: 'close', trigger: unknown): void\n}>()\n\nconst visible = ref(false)\n\n// Popup 属性 keys 列表\nconst POPUP_KEYS = [\n 'attach',\n 'closeBtn',\n 'closeOnOverlayClick',\n 'destroyOnClose',\n 'duration',\n 'overlayProps',\n 'placement',\n 'preventScrollThrough',\n 'showOverlay',\n 'transitionName',\n 'zIndex',\n 'onClose',\n 'onClosed',\n 'onOpen',\n 'onOpened',\n] as const\n\n// TreeSelect 专属属性 keys 列表\nconst TREE_SELECT_KEYS = [\n 'customStyle',\n 'filterable',\n 'height',\n 'keys',\n 'multiple',\n 'options',\n] as const\n\nconst propsAny = props as Record<string, unknown>\n\nconst popupBindProps = computed(() => {\n const result: Record<string, unknown> = {}\n POPUP_KEYS.forEach((key) => {\n if (propsAny[key] !== undefined) {\n result[key] = propsAny[key]\n }\n })\n return result\n})\n\nconst inputBindProps = computed(() => {\n const { modelValue, ...others } = props\n const result = { ...others } as Record<string, unknown>\n // 移除 Popup 属性\n POPUP_KEYS.forEach((key) => {\n delete result[key]\n })\n // 移除 TreeSelect 属性\n TREE_SELECT_KEYS.forEach((key) => {\n delete result[key]\n })\n // 移除自定义属性\n delete result['rules']\n delete result['required']\n delete result['title']\n return result\n})\n\nconst treeSelectBindProps = computed(() => {\n const result: Record<string, unknown> = {}\n TREE_SELECT_KEYS.forEach((key) => {\n if (key !== 'options' && propsAny[key] !== undefined) {\n result[key] = propsAny[key]\n }\n })\n // 添加 keys 属性\n if (propsAny['keys'] !== undefined) {\n result['keys'] = propsAny['keys']\n }\n return result\n})\n\n// 递归查找 Label\ninterface TreeOption {\n label?: string\n value?: string | number\n children?: TreeOption[]\n [key: string]: unknown\n}\n\n/**\n * 判断某个值是否是叶子节点\n */\nconst isLeafValue = (options: TreeOption[], targetValue: string | number): boolean => {\n for (const option of options) {\n if (option.value === targetValue) {\n // 如果没有 children 或 children 为空,则是叶子节点\n return !option.children || option.children.length === 0\n }\n if (option.children && option.children.length > 0) {\n const found = isLeafValue(option.children, targetValue)\n if (found !== false) return found\n }\n }\n return false\n}\n\n/**\n * 根据叶子节点值,构建完整的路径值数组\n * TDesign TreeSelect 需要 [level0Value, level1Value, level2Value] 格式的 value\n */\nconst buildValuePath = (\n options: TreeOption[],\n targetValue: string | number,\n path: (string | number)[] = [],\n): (string | number)[] | null => {\n for (const option of options) {\n if (option.value === targetValue) {\n return [...path, option.value]\n }\n if (option.children && option.children.length > 0) {\n const found = buildValuePath(option.children, targetValue, [...path, option.value!])\n if (found) return found\n }\n }\n return null\n}\n\n/**\n * 内部使用的数组格式 value(TDesign TreeSelect 需要)\n */\nconst internalValue = ref<Array<string | number>>([])\n\nconst normalizePathValue = (value: TreeSelectValue): Array<string | number> => {\n if (Array.isArray(value)) {\n return value\n .flatMap((item) => (Array.isArray(item) ? item : [item]))\n .filter(\n (item): item is string | number => typeof item === 'string' || typeof item === 'number',\n )\n }\n if (value === null || value === undefined || value === '') {\n return []\n }\n return [value as string | number]\n}\n\n// 监听外部 modelValue 变化,转换为内部数组格式\nwatch(\n () => props.modelValue,\n (newVal) => {\n if (Array.isArray(newVal)) {\n internalValue.value = normalizePathValue(newVal)\n } else if (newVal !== undefined && newVal !== '' && newVal !== null) {\n // 单个值,需要构建完整路径\n const opts = (props.options || []) as TreeOption[]\n const path = buildValuePath(opts, newVal as string | number)\n internalValue.value = path || []\n } else {\n internalValue.value = []\n }\n },\n { immediate: true },\n)\n\n// 监听 options 变化时也需要重新计算\nwatch(\n () => props.options,\n () => {\n const val = props.modelValue\n if (!Array.isArray(val) && val !== undefined && val !== '' && val !== null) {\n const opts = (props.options || []) as TreeOption[]\n const path = buildValuePath(opts, val as string | number)\n internalValue.value = path || []\n }\n },\n { deep: true },\n)\n\nconst findLabel = (options: TreeOption[], targetValue: string | number): string | null => {\n for (const option of options) {\n if (option.value === targetValue) {\n return option.label || String(option.value)\n }\n if (option.children && option.children.length > 0) {\n const found = findLabel(option.children, targetValue)\n if (found) return found\n }\n }\n return null\n}\n\nconst displayValue = computed(() => {\n const val = props.modelValue\n if (!val && val !== 0) {\n return ''\n }\n\n const opts = (props.options || []) as TreeOption[]\n\n if (Array.isArray(val)) {\n // 取最后一个值作为显示值\n const lastVal = val[val.length - 1]\n if (lastVal !== undefined) {\n return findLabel(opts, lastVal as string | number) || String(lastVal)\n }\n return ''\n }\n\n return findLabel(opts, val as string | number) || String(val)\n})\n\nconst onTriggerClick = () => {\n if (props.disabled) return\n visible.value = true\n}\n\n// 修复 onChange 事件签名,与组件库保持一致\nconst onChange = (value: TreeSelectValue, level: TreeLevel) => {\n // TDesign TreeSelect 返回的是数组格式 [level0, level1, level2, ...]\n // 我们需要取最后一级的值作为最终值传给父组件\n if (Array.isArray(value)) {\n const normalizedValue = normalizePathValue(value)\n const leafValue = normalizedValue[normalizedValue.length - 1]\n internalValue.value = normalizedValue\n\n // 判断是否选中了叶子节点\n const opts = (props.options || []) as TreeOption[]\n const isLeaf = isLeafValue(opts, leafValue as string | number)\n\n if (isLeaf) {\n // 只有选中叶子节点才更新外部值并关闭弹窗\n emit('update:modelValue', leafValue as TreeSelectValue)\n emit('change', leafValue as TreeSelectValue, level)\n // 单选时关闭弹窗\n if (!props.multiple) {\n visible.value = false\n }\n }\n } else {\n internalValue.value = normalizePathValue(value)\n emit('update:modelValue', value)\n emit('change', value, level)\n }\n}\n</script>\n\n<template>\n <div class=\"smart-tree-select\">\n <t-input\n :value=\"displayValue\"\n @click=\"onTriggerClick\"\n v-bind=\"{ ...$attrs, ...inputBindProps }\"\n readonly\n :suffix-icon=\"() => h(Icon, { name: 'chevron-right' })\"\n >\n <template v-for=\"(_, name) in $slots\" #[name]=\"slotData\">\n <slot :name=\"name\" v-bind=\"slotData || {}\" />\n </template>\n </t-input>\n\n <t-popup v-model=\"visible\" placement=\"bottom\" v-bind=\"popupBindProps\">\n <div class=\"tree-select-wrapper\">\n <t-tree-select\n v-if=\"visible\"\n :value=\"internalValue\"\n :options=\"options\"\n v-bind=\"treeSelectBindProps\"\n @change=\"onChange\"\n />\n </div>\n </t-popup>\n </div>\n</template>\n\n<style lang=\"scss\" scoped>\n.smart-tree-select {\n width: 100%;\n}\n.tree-select-wrapper {\n height: 50vh; // TreeSelect 需要高度\n display: flex;\n flex-direction: column;\n}\n</style>\n","<script lang=\"ts\">\nexport default {\n name: 'SmartUpload',\n}\n</script>\n\n<script setup lang=\"ts\">\nimport { computed, ref, watch, nextTick } from 'vue'\nimport {\n Upload as TUpload,\n Message,\n type SuccessContext,\n type UploadFailContext,\n type UploadRemoveContext,\n} from 'tdesign-mobile-vue'\nimport type { SmartUploadProps, SmartUploadFile, FileItem, FileListValue, FileListValueType } from './props'\n\nconst props = withDefaults(defineProps<SmartUploadProps>(), {\n modelValue: '',\n separator: ',',\n urlPrefix: '',\n urlKey: 'fileUrl',\n nameKey: 'filename',\n mode: 'image',\n accept: 'image/*',\n max: 9,\n maxSize: 10 * 1024,\n multiple: true,\n disabled: false,\n})\n\nconst emit = defineEmits<{\n (e: 'update:modelValue', value: FileListValue): void\n (e: 'success', context: SuccessContext): void\n (e: 'fail', context: UploadFailContext): void\n (e: 'remove', file: SmartUploadFile, index: number): void\n}>()\n\n\n// 内部文件列表(完全由 t-upload 控制)\nconst internalFiles = ref<SmartUploadFile[]>([])\n\n// 计算 accept 字符串\nconst acceptString = computed(() => {\n if (Array.isArray(props.accept)) {\n return props.accept.join(',')\n }\n return props.accept\n})\n\n/**\n * 判断值类型\n * 优先使用 props.valueType,否则自动推断\n */\nconst valueType = computed<FileListValueType>(() => {\n if (props.valueType) return props.valueType\n\n const list = props.modelValue\n if (typeof list === 'string') return 'string'\n if (Array.isArray(list)) {\n if (list.length === 0) return 'stringArray'\n if (typeof list[0] === 'object' && list[0] !== null) return 'objectArray'\n return 'stringArray'\n }\n return 'string'\n})\n\n/**\n * 判断是否为完整 URL\n */\nconst isFullUrl = (url: string) => /^(https?:|blob:|data:)/i.test(url)\n\n/**\n * 从对象或字符串中提取 URL\n */\nconst extractUrl = (item: string | FileItem): string => {\n if (typeof item === 'string') return item\n const url = item[props.urlKey]\n return typeof url === 'string' ? url : ''\n}\n\n/**\n * 从对象中提取 name\n */\nconst extractName = (item: string | FileItem, url: string): string => {\n if (typeof item === 'object' && item[props.nameKey]) {\n const name = item[props.nameKey]\n return typeof name === 'string' ? name : String(name)\n }\n return url.split('/').pop() || ''\n}\n\n/**\n * 从 URL 中去除前缀\n */\nconst removeUrlPrefix = (url: string): string => {\n if (!props.urlPrefix || !url) return url\n if (url.startsWith(props.urlPrefix)) {\n return url.slice(props.urlPrefix.length)\n }\n return url\n}\n\n/**\n * 将外部值转换为 UploadFile[] 用于显示\n */\nconst parseModelValue = (value: FileListValue): SmartUploadFile[] => {\n if (!value) return []\n\n // 解析为项目数组\n let items: (string | FileItem)[] = []\n if (typeof value === 'string') {\n items = value.split(props.separator).filter(Boolean)\n } else {\n items = value.filter(Boolean) as (string | FileItem)[]\n }\n\n // 转换为 SmartUploadFile[]\n return items.map((item, index) => {\n const url = extractUrl(item)\n if (!url) return null\n\n // 拼接前缀\n const displayUrl = isFullUrl(url) ? url : (props.urlPrefix + url)\n\n const fileInfo: SmartUploadFile = {\n url: displayUrl,\n name: extractName(item, url),\n status: 'success' as const,\n originalPath: url,\n }\n\n // 对象数组模式下,保存原始对象\n if (typeof item === 'object') {\n fileInfo.__rawResult__ = item as Record<string, unknown>\n }\n\n return fileInfo\n }).filter(Boolean) as SmartUploadFile[]\n}\n\n// 初始化/同步外部值到内部文件列表\nwatch(\n () => props.modelValue,\n (newVal) => {\n const parsed = parseModelValue(newVal)\n const currentSuccessUrls = internalFiles.value\n .filter((f) => f.status === 'success')\n .map((f) => f.originalPath || f.url)\n const parsedUrls = parsed.map((f) => f.originalPath || f.url)\n\n if (JSON.stringify(currentSuccessUrls) !== JSON.stringify(parsedUrls)) {\n const uploadingFiles = internalFiles.value.filter((f) => f.status !== 'success')\n internalFiles.value = [...parsed, ...uploadingFiles]\n }\n },\n { immediate: true },\n)\n\n\n/**\n * 同步内部文件列表到 modelValue\n */\nconst syncModelValue = () => {\n const finishedFiles = internalFiles.value.filter((f) => f.status === 'success')\n\n let result: FileListValue\n\n switch (valueType.value) {\n case 'string':\n result = finishedFiles\n .map((f) => removeUrlPrefix(f.originalPath || f.url || ''))\n .filter(Boolean)\n .join(props.separator)\n break\n\n case 'objectArray':\n result = finishedFiles.map((f) => {\n // 优先使用保存的完整返回对象\n if (f.__rawResult__ && typeof f.__rawResult__ === 'object') {\n const rawUrl = f.__rawResult__[props.urlKey]\n return {\n ...f.__rawResult__,\n [props.urlKey]: removeUrlPrefix(typeof rawUrl === 'string' ? rawUrl : (f.originalPath || f.url || '')),\n }\n }\n // 否则构建基础对象\n const baseObj: Record<string, unknown> = {\n [props.urlKey]: removeUrlPrefix(f.originalPath || f.url || ''),\n }\n if (props.nameKey) {\n baseObj[props.nameKey] = f.name\n }\n return baseObj\n })\n break\n\n case 'stringArray':\n default:\n result = finishedFiles\n .map((f) => removeUrlPrefix(f.originalPath || f.url || ''))\n .filter(Boolean)\n break\n }\n\n emit('update:modelValue', result)\n}\n\n// 上传成功处理\nconst onSuccess = (context: SuccessContext) => {\n const { file, response } = context\n\n console.log('[SmartUpload] onSuccess', { file, response })\n\n if (file) {\n // 使用 formatResponse 提取数据\n let uploadResult: string | Record<string, unknown> = ''\n if (props.formatResponse) {\n uploadResult = props.formatResponse(response)\n } else if (response && typeof response === 'object') {\n // TDesign 会把 response 包装成数组\n const data = Array.isArray(response) ? response[0] : response\n if (data && 'url' in data) {\n uploadResult = (data as { url: string }).url\n }\n }\n\n console.log('[SmartUpload] uploadResult:', uploadResult)\n\n if (uploadResult) {\n const isResultObject = typeof uploadResult === 'object'\n // 根据结果类型提取 fileUrl\n let fileUrl = ''\n let rawResultObj: Record<string, unknown> | undefined\n\n if (isResultObject) {\n const urlValue = (uploadResult as Record<string, unknown>)[props.urlKey]\n fileUrl = typeof urlValue === 'string' ? urlValue : ''\n rawResultObj = uploadResult as Record<string, unknown>\n } else {\n fileUrl = uploadResult as string\n }\n\n const displayUrl = isFullUrl(fileUrl) ? fileUrl : props.urlPrefix + fileUrl\n\n nextTick(() => {\n const fileIndex = internalFiles.value.findIndex((f) => f.name === file.name)\n console.log('[SmartUpload] fileIndex:', fileIndex)\n\n if (fileIndex >= 0) {\n internalFiles.value[fileIndex] = {\n ...internalFiles.value[fileIndex],\n status: 'success',\n url: displayUrl,\n originalPath: fileUrl,\n // 对象数组模式下保存完整返回\n __rawResult__: rawResultObj,\n }\n }\n\n syncModelValue()\n })\n }\n }\n\n emit('success', context)\n}\n\n// 上传失败处理\nconst onFail = (context: UploadFailContext) => {\n const { file } = context\n\n if (file) {\n const fileIndex = internalFiles.value.findIndex((f) => f.name === file.name)\n if (fileIndex >= 0) {\n internalFiles.value.splice(fileIndex, 1)\n }\n }\n\n Message.error('上传失败,请重试')\n emit('fail', context)\n}\n\n// 删除文件\nconst onRemove = (context: UploadRemoveContext) => {\n const { index = 0, file } = context\n emit('remove', file as SmartUploadFile, index)\n nextTick(() => {\n syncModelValue()\n })\n}\n\n// 校验处理:显示重复文件、文件过大等提示\nconst onValidate = (context: { type: string; files: unknown[] }) => {\n const { type, files } = context\n console.log('[SmartUpload] onValidate', { type, files })\n\n switch (type) {\n case 'FILTER_FILE_SAME_NAME':\n Message.info('请勿上传重复的文件')\n break\n case 'FILE_OVER_SIZE_LIMIT':\n Message.error(`文件大小超过限制(最大 ${Math.round(props.maxSize / 1024)}MB)`)\n break\n case 'FILES_OVER_LENGTH_LIMIT':\n Message.info(`最多只能上传 ${props.max} 个文件`)\n break\n }\n}\n\n</script>\n\n<template>\n <div class=\"smart-upload\">\n <!-- 图片模式 - 使用 TDesign 默认样式 -->\n <template v-if=\"mode === 'image'\">\n <t-upload\n v-model=\"internalFiles\"\n :action=\"action\"\n :accept=\"acceptString\"\n :max=\"max\"\n :size-limit=\"{ size: maxSize, unit: 'KB' }\"\n :multiple=\"multiple\"\n :disabled=\"disabled\"\n :request-method=\"requestMethod\"\n @success=\"onSuccess\"\n @fail=\"onFail\"\n @remove=\"onRemove\"\n @validate=\"onValidate\"\n />\n </template>\n\n <!-- 文件模式 - 使用 TDesign 默认样式 -->\n <template v-else>\n <t-upload\n v-model=\"internalFiles\"\n :action=\"action\"\n :accept=\"acceptString\"\n :max=\"max\"\n :size-limit=\"{ size: maxSize, unit: 'KB' }\"\n :multiple=\"multiple\"\n :disabled=\"disabled\"\n :request-method=\"requestMethod\"\n @success=\"onSuccess\"\n @fail=\"onFail\"\n @remove=\"onRemove\"\n @validate=\"onValidate\"\n />\n </template>\n </div>\n</template>\n\n<style lang=\"scss\" scoped>\n.smart-upload {\n width: 100%;\n :deep(.t-upload__item) {\n &:has(.t-image){\n background-color: #F1F1F1;\n display: flex;\n align-items: center;\n justify-content: center;\n }\n }\n :deep(.t-upload){\n grid-template-columns: repeat(3,1fr);\n row-gap: 8px;\n }\n}\n</style>\n\n","<script lang=\"ts\">\nexport default {\n name: 'SmartForm',\n}\n</script>\n\n<script setup lang=\"ts\" generic=\"T extends Record<string, unknown>\">\nimport { ref, toRaw, type Component } from 'vue'\nimport {\n Form as TForm,\n FormItem as TFormItem,\n Button as TButton,\n Input as TInput,\n Textarea as TTextarea,\n Switch as TSwitch,\n RadioGroup as TRadioGroup,\n CheckboxGroup as TCheckboxGroup,\n Stepper as TStepper,\n type SubmitContext,\n} from 'tdesign-mobile-vue'\nimport SmartSelect from '../SmartSelect/index.vue'\nimport SmartTimePicker from '../SmartTimePicker/index.vue'\nimport SmartCascader from '../SmartCascader/index.vue'\nimport SmartTreeSelect from '../SmartTreeSelect/index.vue'\nimport SmartUpload from '../SmartUpload/index.vue'\nimport type { FormSchema, SmartFormProps } from './types'\n\ninterface FormInstance {\n validate: (params?: {\n fields?: string[]\n trigger?: 'blur' | 'change' | 'all'\n showErrorMessage?: boolean\n }) => Promise<unknown>\n validateOnly: (params?: { fields?: string[]; trigger?: 'change' }) => Promise<unknown>\n submit: (params?: { showErrorMessage?: boolean }) => Promise<unknown>\n reset: (params?: { type?: 'initial' | 'empty'; fields?: string[] }) => void\n clearValidate: (fields?: string[]) => void\n setValidateMessage: (message: Record<string, unknown>) => void\n}\n\nconst props = withDefaults(defineProps<SmartFormProps<T>>(), {\n labelWidth: '80px',\n labelAlign: 'left',\n showFooter: true,\n submitBtnText: '提交',\n resetBtnText: '重置',\n loading: false,\n disabled: false,\n})\n\nconst emit = defineEmits<{\n (e: 'update:modelValue', value: Record<string, unknown>): void\n (e: 'submit', value: Record<string, unknown>): void\n (e: 'reset'): void\n (e: 'validate-failed', errors: unknown): void\n}>()\n\nconst formRef = ref<FormInstance>()\n\n// 内置组件映射\nconst builtInComponentMap: Record<string, Component> = {\n input: TInput,\n password: TInput,\n number: TInput,\n textarea: TTextarea,\n select: SmartSelect,\n cascader: SmartCascader,\n 'tree-select': SmartTreeSelect,\n date: SmartTimePicker,\n time: SmartTimePicker,\n switch: TSwitch,\n radio: TRadioGroup,\n checkbox: TCheckboxGroup,\n stepper: TStepper,\n upload: SmartUpload,\n}\n\n// 获取组件映射(优先使用用户自定义的 componentMap)\nconst getComponent = (type?: string): Component | null => {\n const targetType = type || 'input'\n\n // 1. 优先从用户自定义 componentMap 中查找\n if (props.componentMap?.[targetType]) {\n return props.componentMap[targetType]\n }\n\n // 2. 回退到内置组件映射\n return builtInComponentMap[targetType] ?? null\n}\n\n// 获取验证规则\nconst getRules = (schema: FormSchema<T>) => {\n const rules = []\n if (schema.required) {\n rules.push({ required: true, message: `${schema.label || '该项'}不能为空` })\n }\n if (schema.rules) {\n rules.push(...schema.rules)\n }\n return rules\n}\n\n// 处理表单项属性\nconst getItemProps = (schema: FormSchema<T>) => {\n const model = props.modelValue\n let itemProps: Record<string, unknown> = {}\n\n // 1. 获取基础 props\n if (typeof schema.props === 'function') {\n itemProps = schema.props(model)\n } else if (schema.props) {\n itemProps = { ...schema.props }\n }\n\n // 2. 处理特殊类型属性\n const type = schema.type || 'input'\n if (type === 'password') {\n Object.assign(itemProps, { type: 'password' })\n } else if (type === 'number') {\n Object.assign(itemProps, { type: 'number' })\n } else if (type === 'date') {\n Object.assign(itemProps, { mode: 'date' })\n } else if (type === 'time') {\n Object.assign(itemProps, { mode: ['hour', 'minute'] })\n }\n\n // 3. 对于 Input/Textarea 类型,仅在用户未显式设置时才应用默认 borderless\n // 这样用户可以通过 schema.props.borderless = false 来覆盖默认行为\n if (['input', 'password', 'number', 'textarea'].includes(type)) {\n // 检查用户是否显式设置了 borderless(包括设置为 false 的情况)\n const userExplicitlySetBorderless =\n typeof schema.props === 'object' &&\n schema.props !== null &&\n Object.prototype.hasOwnProperty.call(schema.props, 'borderless')\n if (!userExplicitlySetBorderless && itemProps.borderless === undefined) {\n itemProps.borderless = true\n }\n\n // 安全防护:防止 Input 组件接收 type=\"file\"\n // 如果 schema.type 默认为 input,但 props 中传入了 type: 'file',会导致 v-model 绑定失败引发 InvalidStateError\n if (itemProps.type === 'file') {\n console.warn(\n `[SmartForm] Detected type=\"file\" on Input component (field: ${schema.name}). Please use type: \"upload\" in your schema instead.`,\n )\n delete itemProps.type\n }\n }\n\n // 4. 全局禁用状态传递\n if (props.disabled) {\n Object.assign(itemProps, { disabled: true })\n } else if (schema.disabled) {\n // 字段级禁用控制\n const isDisabled =\n typeof schema.disabled === 'function' ? schema.disabled(model) : schema.disabled\n Object.assign(itemProps, { disabled: isDisabled })\n }\n\n return itemProps\n}\n\n// 判断表单项是否可见\nconst isVisible = (schema: FormSchema<T>) => {\n if (schema.hidden === undefined) return true\n if (typeof schema.hidden === 'function') {\n return !schema.hidden(props.modelValue)\n }\n return !schema.hidden\n}\n\nconst onSubmit = (context: SubmitContext) => {\n if (context.validateResult === true) {\n emit('submit', toRaw(props.modelValue))\n } else {\n emit('validate-failed', context.validateResult)\n }\n}\n\n// 重置处理\nconst onReset = () => {\n formRef.value?.reset()\n emit('reset')\n}\n\n// 暴露方法\ndefineExpose({\n validate: () => formRef.value?.validate(),\n reset: () => formRef.value?.reset(),\n clearValidate: () => formRef.value?.clearValidate(),\n})\n</script>\n\n<template>\n <div class=\"smart-form\">\n <t-form\n ref=\"formRef\"\n :data=\"modelValue\"\n :label-width=\"labelWidth\"\n :label-align=\"labelAlign\"\n @submit=\"onSubmit\"\n >\n <template v-for=\"schema in schemas\" :key=\"schema.name\">\n <t-form-item\n v-if=\"isVisible(schema)\"\n :name=\"schema.name\"\n :label=\"schema.label\"\n :rules=\"getRules(schema)\"\n :help=\"schema.help\"\n >\n <!-- 自定义插槽 -->\n <template v-if=\"schema.type === 'slot' && schema.slot\">\n <slot :name=\"schema.slot\" :model=\"modelValue\" :schema=\"schema\" />\n </template>\n\n <!-- 动态组件渲染 -->\n <component\n :is=\"getComponent(schema.type)\"\n v-else\n v-model=\"(modelValue as Record<string, any>)[schema.name]\"\n v-bind=\"getItemProps(schema)\"\n />\n </t-form-item>\n </template>\n\n <!-- 底部按钮 -->\n <div v-if=\"showFooter\" class=\"smart-form-footer\">\n <t-button theme=\"primary\" type=\"submit\" block :loading=\"loading\" :disabled=\"disabled\">\n {{ submitBtnText }}\n </t-button>\n <t-button\n v-if=\"resetBtnText\"\n theme=\"default\"\n variant=\"outline\"\n block\n class=\"reset-btn\"\n @click=\"onReset\"\n :disabled=\"disabled || loading\"\n >\n {{ resetBtnText }}\n </t-button>\n </div>\n </t-form>\n </div>\n</template>\n\n<style lang=\"scss\" scoped>\n.smart-form {\n .smart-form-footer {\n padding: 16px;\n display: flex;\n flex-direction: column;\n gap: 12px;\n\n .reset-btn {\n margin-top: 0; // 覆盖 tdesign 默认样式\n }\n }\n}\n</style>\n","<script lang=\"ts\">\nexport default {\n name: 'SmartPage',\n}\n</script>\n\n<script setup lang=\"ts\">\nimport {\n Navbar as TNavbar,\n TabBar as TTabBar,\n TabBarItem as TTabBarItem,\n} from 'tdesign-mobile-vue'\nimport type { SmartPageProps } from './types'\n\n// Props 定义\nconst props = withDefaults(defineProps<SmartPageProps>(), {\n // 核心属性\n showNavbar: true,\n showBack: false,\n showTabBar: false,\n\n // Navbar 属性\n navbarAnimation: true,\n navbarFixed: true,\n navbarPlaceholder: true,\n navbarSafeAreaInsetTop: true,\n navbarVisible: true,\n\n // TabBar 属性\n tabBarBordered: true,\n tabBarFixed: true,\n tabBarPlaceholder: true,\n tabBarSafeAreaInsetBottom: true,\n tabBarShape: 'round',\n tabBarSplit: true,\n tabBarTheme: 'normal',\n})\n\n// 事件定义\nconst emit = defineEmits<{\n /** TabBar 值变更(支持 v-model:tabBarValue) */\n (e: 'update:tabBarValue', value: string | number): void\n /** TabBar 切换事件 */\n (e: 'tab-change', value: string | number): void\n /** Navbar 左侧点击(返回按钮) */\n (e: 'back'): void\n /** Navbar 右侧点击 */\n (e: 'right-click'): void\n}>()\n\n/**\n * 处理返回按钮点击\n * 优先使用自定义 onBack,否则使用原生 History API\n * 不依赖 vue-router,确保 npm 包的兼容性\n */\nconst handleBack = () => {\n emit('back')\n if (props.onBack) {\n props.onBack()\n } else {\n // 使用原生 History API,无需依赖 vue-router\n window.history.back()\n }\n}\n\n/**\n * 处理 TabBar 切换\n */\nconst handleTabChange = (value: string | number) => {\n emit('update:tabBarValue', value)\n emit('tab-change', value)\n}\n</script>\n\n<template>\n <div class=\"smart-page\">\n <!-- 顶部导航栏 -->\n <t-navbar\n v-if=\"showNavbar\"\n :title=\"title\"\n :left-arrow=\"showBack\"\n :animation=\"navbarAnimation\"\n :fixed=\"navbarFixed\"\n :placeholder=\"navbarPlaceholder\"\n :safe-area-inset-top=\"navbarSafeAreaInsetTop\"\n :title-max-length=\"navbarTitleMaxLength\"\n :visible=\"navbarVisible\"\n :z-index=\"navbarZIndex\"\n @left-click=\"handleBack\"\n @right-click=\"emit('right-click')\"\n >\n <!-- 左侧插槽 -->\n <template v-if=\"$slots['navbar-left'] || navbarLeft\" #left>\n <slot name=\"navbar-left\">\n <component :is=\"navbarLeft\" v-if=\"navbarLeft\" />\n </slot>\n </template>\n\n <!-- 标题插槽 -->\n <template v-if=\"$slots['navbar-title']\" #title>\n <slot name=\"navbar-title\" />\n </template>\n\n <!-- 右侧插槽 -->\n <template v-if=\"$slots['navbar-right'] || navbarRight\" #right>\n <slot name=\"navbar-right\">\n <component :is=\"navbarRight\" v-if=\"navbarRight\" />\n </slot>\n </template>\n\n <!-- 胶囊插槽 -->\n <template v-if=\"$slots['navbar-capsule'] || navbarCapsule\" #capsule>\n <slot name=\"navbar-capsule\">\n <component :is=\"navbarCapsule\" v-if=\"navbarCapsule\" />\n </slot>\n </template>\n </t-navbar>\n\n <!-- 主内容区域(flex: 1 自动填满,不处理滚动) -->\n <div class=\"smart-page__content\">\n <slot />\n </div>\n\n <!-- 底部标签栏 -->\n <t-tab-bar\n v-if=\"showTabBar && tabs?.length\"\n :value=\"tabBarValue\"\n :bordered=\"tabBarBordered\"\n :fixed=\"tabBarFixed\"\n :placeholder=\"tabBarPlaceholder\"\n :safe-area-inset-bottom=\"tabBarSafeAreaInsetBottom\"\n :shape=\"tabBarShape\"\n :split=\"tabBarSplit\"\n :theme=\"tabBarTheme\"\n :z-index=\"tabBarZIndex\"\n @change=\"handleTabChange\"\n >\n <t-tab-bar-item\n v-for=\"tab in tabs\"\n :key=\"tab.value\"\n :value=\"tab.value\"\n :badge-props=\"tab.badgeProps\"\n >\n <template v-if=\"tab.icon\" #icon>\n <component :is=\"tab.icon\" />\n </template>\n {{ tab.label }}\n </t-tab-bar-item>\n </t-tab-bar>\n </div>\n</template>\n\n<style lang=\"scss\" scoped>\n.smart-page {\n display: flex;\n flex-direction: column;\n min-height: 100vh;\n height: 100%;\n overflow: hidden;\n\n &__content {\n flex: 1;\n display: flex;\n flex-direction: column;\n overflow: hidden; // 不处理滚动,由子元素自行处理\n\n // 支持子元素 height: 100% 撑满\n > :deep(*) {\n flex: 1;\n min-height: 0; // 防止 flex 子项溢出\n }\n }\n}\n</style>\n"],"names":["usePopupField","options","visible","ref","displayValue","computed","val","foundLabel","__default__","props","__props","emit","__emit","findLabelFromColumns","cols","value","flatColumns","selectedItem","item","openPopup","closePopup","toRef","POPUP_KEYS","popupBindProps","result","propsAny","key","INPUT_KEYS","inputBindProps","onConfirm","context","selectedValue","onCancel","onChange","_openBlock","_createElementBlock","_hoisted_1","_createVNode","_unref","_mergeProps","$attrs","h","Icon","$slots","_","slotName","_withCtx","slotData","_renderSlot","_ctx","_normalizeProps","_guardReactiveProps","$event","TPicker","modelValue","title","inputFormat","others","dateTimePickerBindProps","label","placeholder","rules","required","onTriggerClick","onPick","name","findLabelPath","targetValue","path","option","found","findLabelFromOptions","CASCADER_KEYS","cascaderBindProps","onClose","trigger","TREE_SELECT_KEYS","treeSelectBindProps","isLeafValue","buildValuePath","internalValue","normalizePathValue","watch","newVal","opts","findLabel","lastVal","level","normalizedValue","leafValue","_createElementVNode","_hoisted_2","_createBlock","internalFiles","acceptString","valueType","list","isFullUrl","url","extractUrl","extractName","removeUrlPrefix","parseModelValue","items","index","fileInfo","parsed","currentSuccessUrls","f","parsedUrls","uploadingFiles","syncModelValue","finishedFiles","rawUrl","baseObj","onSuccess","file","response","uploadResult","data","isResultObject","fileUrl","rawResultObj","urlValue","displayUrl","nextTick","fileIndex","onFail","Message","onRemove","onValidate","type","files","TUpload","formRef","builtInComponentMap","TInput","TTextarea","SmartSelect","SmartCascader","SmartTreeSelect","SmartTimePicker","TSwitch","TRadioGroup","TCheckboxGroup","TStepper","SmartUpload","getComponent","targetType","getRules","schema","getItemProps","model","itemProps","isDisabled","isVisible","onSubmit","toRaw","onReset","__expose","TForm","_Fragment","_renderList","TFormItem","_resolveDynamicComponent","TButton","handleBack","handleTabChange","TNavbar","TTabBar","tab","TTabBarItem","_toDisplayString"],"mappings":"uIA6BO,SAASA,EAAoBC,EAA0D,CAC5F,MAAMC,EAAUC,EAAAA,IAAI,EAAK,EAEnBC,EAAeC,EAAAA,SAAS,IAAM,CAClC,MAAMC,EAAML,EAAQ,WAAW,MAC/B,GAAyBK,GAAQ,MAAQA,IAAQ,GAC/C,MAAO,GAIT,MAAMC,EAAaN,EAAQ,UAAUA,EAAQ,QAAQ,MAAOK,CAAG,EAC/D,OAAIC,IAAe,KACVA,EAILN,EAAQ,cAAc,MACjBA,EAAQ,aAAa,MAIvB,OAAOK,CAAG,CACnB,CAAC,EAUD,MAAO,CACL,QAAAJ,EACA,aAAAE,EACA,UAXgB,IAAM,CACtBF,EAAQ,MAAQ,EAClB,EAUE,WARiB,IAAM,CACvBA,EAAQ,MAAQ,EAClB,CAME,CAEJ,gCClEAM,EAAe,CACb,KAAM,aACR,qzCAUA,MAAMC,EAAQC,EAkBRC,EAAOC,EAOPC,EAAuB,CAC3BC,EACAC,IACkB,CAClB,IAAIC,EAAkC,CAAA,EAClC,MAAM,QAAQF,CAAI,IAChBA,EAAK,OAAS,GAAK,MAAM,QAAQA,EAAK,CAAC,CAAC,EAC1CE,EAAeF,EAA8B,KAAA,EAE7CE,EAAcF,GAGlB,MAAMG,EAAeD,EAAY,KAAME,GAASA,EAAK,QAAUH,CAAK,EACpE,OAAOE,EAAeA,EAAa,MAAQ,IAC7C,EAEM,CAAE,QAAAf,EAAS,aAAAE,EAAc,UAAAe,EAAW,WAAAC,CAAA,EAAepB,EAAc,CACrE,WAAYqB,EAAAA,MAAM,IAAMZ,EAAM,UAAU,EACxC,QAASY,EAAAA,MAAM,IAAMZ,EAAM,OAA6B,EACxD,UAAW,CAACK,EAAMR,IAAQO,EAAqBC,EAAMR,CAAgC,EACrF,aAAce,EAAAA,MAAM,IAAMZ,EAAM,YAAY,CAAA,CAC7C,EAEKa,EAAa,CAAC,SAAU,WAAY,sBAAuB,iBAAkB,WAAY,eAAgB,YAAa,uBAAwB,cAAe,iBAAkB,QAAQ,EAEvLC,EAAiBlB,EAAAA,SAAS,IAAM,CACpC,MAAMmB,EAAkC,CAAA,EAClCC,EAAWhB,EACjB,OAAAa,EAAW,QAASI,GAAQ,CACtBD,EAASC,CAAG,IAAM,SACpBF,EAAOE,CAAG,EAAID,EAASC,CAAG,EAE9B,CAAC,EACMF,CACT,CAAC,EAEKG,EAAa,CAAC,QAAS,YAAa,aAAc,YAAa,eAAgB,WAAY,QAAS,SAAU,eAAgB,YAAa,OAAQ,cAAe,aAAc,WAAY,OAAQ,SAAU,SAAU,aAAc,OAAQ,MAAM,EAEpPC,EAAiBvB,EAAAA,SAAS,IAAM,CACpC,MAAMmB,EAAkC,CAAA,EAClCC,EAAWhB,EACjB,OAAAkB,EAAW,QAASD,GAAQ,CACtBD,EAASC,CAAG,IAAM,SACpBF,EAAOE,CAAG,EAAID,EAASC,CAAG,EAE9B,CAAC,EACMF,CACT,CAAC,EAEKK,EAAY,CAACd,EAAsBe,IAAqB,CAC5D,MAAMC,EAAgBhB,EAAM,CAAC,EACzBgB,IAAkB,QAAa,OAAOA,GAAkB,UAC1DpB,EAAK,oBAAqBoB,CAAa,EAEzCpB,EAAK,UAAWI,EAAOe,CAAO,EAC9BV,EAAA,CACF,EAEMY,EAAYF,GAAqB,CACrCnB,EAAK,SAAUmB,CAAO,EACtBV,EAAA,CACF,EAEMa,EAAW,CAAClB,EAAsBe,IAAqB,CAC3DnB,EAAK,SAAUI,EAAOe,CAAO,CAC/B,gBAIEI,YAAA,EAAAC,qBAyBM,MAzBNC,EAyBM,CAxBJC,EAAAA,YAUUC,EAAAA,eAVVC,aAUU,CATP,MAAOD,EAAAA,MAAAlC,CAAA,EACP,QAAOkC,EAAAA,MAAAnB,CAAA,CAAA,EACKqB,CAAAA,GAAAA,EAAAA,UAAWZ,EAAA,OAAc,CACtC,SAAA,GACC,cAAW,IAAQa,EAAAA,EAAEH,EAAAA,MAAAI,EAAAA,IAAA,EAAI,CAAA,KAAA,eAAA,CAAA,CAAA,qCAEQC,EAAAA,OAAM,CAAtBC,EAAGC,WAAsBA,EACzC,GAAAC,EAAAA,QADqDC,GAAQ,CAC7DC,EAAAA,WAAiDC,EAAA,OAApCJ,EAAQK,EAAAA,eAAAC,qBAAUJ,GAAQ,CAAA,CAAA,CAAA,EAAA,OAAA,EAAA,CAAA,gDAI3CV,EAAAA,YAWUC,EAAAA,eAXVC,aAWU,YAXQD,EAAAA,MAAApC,CAAA,kDAAAA,EAAO,MAAAkD,EAAA,MAAE,UAAU,QAAA,EAAiB7B,EAAA,KAAc,EAAA,mBAClE,IASE,CATFc,cASEC,EAAAA,MAAAe,EAAAA,MAAA,EAAA,CARC,OAAQ3C,EAAA,UAAU,EAClB,QAASA,EAAA,QACT,MAAOA,EAAA,MACP,aAAYA,EAAA,UACZ,cAAaA,EAAA,WACb,UAAAmB,EACA,SAAAG,EACA,SAAAC,CAAA,6OChITzB,EAAe,CACb,KAAM,iBACR,0+CAaA,MAAMC,EAAQC,EAyCRC,EAAOC,EAQPV,EAAUC,EAAAA,IAAI,EAAK,EAGnBmB,EAAa,CACjB,SACA,WACA,sBACA,iBACA,WACA,eACA,YACA,uBACA,cACA,iBACA,SACA,UACA,WACA,SACA,UAAA,EAGIG,EAAWhB,EAEXc,EAAiBlB,EAAAA,SAAS,IAAM,CACpC,MAAMmB,EAAkC,CAAA,EACxC,OAAAF,EAAW,QAASI,GAAQ,CACtBD,EAASC,CAAG,IAAM,SACpBF,EAAOE,CAAG,EAAID,EAASC,CAAG,EAE9B,CAAC,EACMF,CACT,CAAC,EAEKI,EAAiBvB,EAAAA,SAAS,IAAM,CACpC,KAAM,CAAE,WAAAiD,EAAY,MAAAC,EAAO,YAAAC,EAAa,GAAGC,GAAWhD,EAChDe,EAAS,CAAE,GAAGiC,CAAA,EACpB,OAAAnC,EAAW,QAASI,GAAQ,CAC1B,OAAOF,EAAOE,CAAG,CACnB,CAAC,EAEmB,CAClB,YACA,aACA,MACA,SACA,SACA,OACA,cACA,WACA,QACA,QACA,QAAA,EAEU,QAASA,GAAQ,OAAOF,EAAOE,CAAG,CAAC,EAG3C8B,IACFhC,EAAO,OAASgC,GAGXhC,CACT,CAAC,EAEKkC,EAA0BrD,EAAAA,SAAS,IAAM,CAC7C,KAAM,CAAE,MAAAsD,EAAO,YAAAC,EAAa,MAAAC,EAAO,SAAAC,EAAU,WAAAR,EAAY,GAAGG,GAAWhD,EACjEe,EAAS,CAAE,GAAGiC,CAAA,EACpB,OAAAnC,EAAW,QAASI,GAAQ,CAC1B,OAAOF,EAAOE,CAAG,CACnB,CAAC,EACMF,CACT,CAAC,EAGKpB,EAAeC,EAAAA,SAAS,IACrB,OAAOI,EAAM,YAAc,EAAE,CACrC,EAEKsD,EAAiB,IAAM,CAC3B7D,EAAQ,MAAQ,EAClB,EAEM2B,EAAad,GAA2B,CAC5CJ,EAAK,oBAAqBI,CAAK,EAC/BJ,EAAK,UAAWI,CAAK,EACrBb,EAAQ,MAAQ,EAClB,EAEM8B,EAAYF,GAA+B,CAC/CnB,EAAK,SAAUmB,CAAO,EACtB5B,EAAQ,MAAQ,EAClB,EAEM+B,EAAYlB,GAA2B,CAC3CJ,EAAK,SAAUI,CAAK,CACtB,EAEMiD,EAAUjD,GAA2B,CACzCJ,EAAK,OAAQI,CAAK,CACpB,gBAIEmB,YAAA,EAAAC,qBAuBM,MAvBNC,EAuBM,CAtBJC,EAAAA,YAUUC,EAAAA,eAVVC,aAUU,CATP,MAAOnC,EAAA,MACP,QAAO2D,CAAA,EACKvB,CAAAA,GAAAA,EAAAA,UAAWZ,EAAA,OAAc,CACtC,SAAA,GACC,cAAW,IAAQa,EAAAA,EAAEH,EAAAA,MAAAI,EAAAA,IAAA,EAAI,CAAA,KAAA,eAAA,CAAA,CAAA,qCAEIC,EAAAA,OAAM,CAAlBC,EAAGqB,aACnB,GAAAnB,EAAAA,QAD6CC,GAAQ,CACrDC,EAAAA,WAA6CC,EAAA,OAAhCgB,EAAIf,EAAAA,eAAAC,qBAAUJ,GAAQ,CAAA,CAAA,CAAA,EAAA,OAAA,EAAA,CAAA,sCAIvCV,EAAAA,YASUC,EAAAA,eATVC,aASU,YATQrC,EAAA,2CAAAA,EAAO,MAAAkD,GAAE,UAAU,QAAA,EAAiB7B,EAAA,KAAc,EAAA,mBAClE,IAOE,CAPFc,EAAAA,YAOEC,EAAAA,wBAPFC,aAOE,CANC,MAAO7B,EAAA,UAAA,EACAgD,EAAA,MAAuB,CAC9B,UAAA7B,EACA,SAAAG,EACA,SAAAC,EACA,OAAA+B,CAAA,0HC1LTxD,EAAe,CACb,KAAM,eACR,q7BAgBA,MAAMC,EAAQC,EAgBRC,EAAOC,EAOPsD,EAAgB,CACpBjE,EACAkE,EACAC,EAAiB,CAAA,IACG,CACpB,UAAWC,KAAUpE,EAAS,CAC5B,MAAMc,EAAQsD,EAAO,OAAUA,EAAO,GAChCV,EAAQU,EAAO,OAASA,EAAO,KACrC,GAAItD,IAAUoD,EACZ,MAAO,CAAC,GAAGC,EAAM,OAAOT,CAAK,CAAC,EAEhC,GAAIU,EAAO,UAAYA,EAAO,SAAS,OAAS,EAAG,CACjD,MAAMC,EAAQJ,EAAcG,EAAO,SAAUF,EAAa,CAAC,GAAGC,EAAM,OAAOT,CAAK,CAAC,CAAC,EAClF,GAAIW,EAAO,OAAOA,CACpB,CACF,CACA,OAAO,IACT,EAEMC,EAAuB,CAACtE,EAA2Bc,IAA0C,CACjG,MAAMqD,EAAOF,EAAcjE,EAASc,CAAK,EACzC,OAAOqD,EAAOA,EAAK,KAAK,KAAK,EAAI,IACnC,EAEM,CAAE,QAAAlE,EAAS,aAAAE,EAAc,UAAAe,EAAW,WAAAC,CAAA,EAAepB,EAAc,CACrE,WAAYqB,EAAAA,MAAM,IAAMZ,EAAM,UAAU,EACxC,QAASY,EAAAA,MAAM,IAAOZ,EAAM,SAAW,CAAA,CAAuB,EAC9D,UAAW8D,EACX,aAAclD,EAAAA,MAAM,IAAMZ,EAAM,YAAY,CAAA,CAC7C,EAEKkB,EAAa,CAAC,QAAS,YAAa,aAAc,YAAa,eAAgB,WAAY,QAAS,SAAU,eAAgB,YAAa,OAAQ,cAAe,aAAc,WAAY,OAAQ,SAAU,SAAU,aAAc,OAAQ,MAAM,EAEpPC,EAAiBvB,EAAAA,SAAS,IAAM,CACpC,MAAMmB,EAAkC,CAAA,EAClCC,EAAWhB,EACjB,OAAAkB,EAAW,QAASD,GAAQ,CACtBD,EAASC,CAAG,IAAM,SACpBF,EAAOE,CAAG,EAAID,EAASC,CAAG,EAE9B,CAAC,EACMF,CACT,CAAC,EAEKgD,EAAgB,CAAC,gBAAiB,WAAY,SAAU,OAAQ,OAAQ,gBAAiB,UAAW,eAAgB,YAAa,QAAS,OAAO,EAEjJC,EAAoBpE,EAAAA,SAAS,IAAM,CACvC,MAAMmB,EAAkC,CAAA,EAClCC,EAAWhB,EACjB,OAAA+D,EAAc,QAAS9C,GAAQ,CACzBD,EAASC,CAAG,IAAM,SACpBF,EAAOE,CAAG,EAAID,EAASC,CAAG,EAE9B,CAAC,EACMF,CACT,CAAC,EAEKS,EAAW,CAAClB,EAAwBe,IAAqB,CAC7DnB,EAAK,oBAAqBI,CAAK,EAC/BJ,EAAK,SAAUI,EAAOe,CAAO,EAC7BV,EAAA,CACF,EAEM4C,EAAUlC,GAAqF,CACnGnB,EAAK,OAAQmB,EAAQ,MAAOA,CAAO,CACrC,EAEM4C,EAAWC,GAAqB,CACpChE,EAAK,QAASgE,CAAO,EACrBvD,EAAA,CACF,gBAIEc,YAAA,EAAAC,qBAqBM,MArBNC,EAqBM,CApBJC,EAAAA,YAUUC,EAAAA,eAVVC,aAUU,CATP,MAAOD,EAAAA,MAAAlC,CAAA,EACP,QAAOkC,EAAAA,MAAAnB,CAAA,CAAA,EACKqB,CAAAA,GAAAA,EAAAA,UAAWZ,EAAA,OAAc,CACtC,SAAA,GACC,cAAW,IAAQa,EAAAA,EAAEH,EAAAA,MAAAI,EAAAA,IAAA,EAAI,CAAA,KAAA,eAAA,CAAA,CAAA,qCAEQC,EAAAA,OAAM,CAAtBC,EAAGC,WAAsBA,EACzC,GAAAC,EAAAA,QADqDC,GAAQ,CAC7DC,EAAAA,WAAiDC,EAAA,OAApCJ,EAAQK,EAAAA,eAAAC,qBAAUJ,GAAQ,CAAA,CAAA,CAAA,EAAA,OAAA,EAAA,CAAA,gDAI3CV,EAAAA,YAOEC,EAAAA,kBAPFC,aAOE,CANQ,QAASD,EAAAA,MAAApC,CAAA,+CAAAA,EAAO,MAAAkD,EAAA,MACvB,MAAO1C,EAAA,UAAA,EACA+D,EAAA,MAAiB,CACxB,SAAAxC,EACA,OAAA+B,EACA,QAAAU,CAAA,6ICtIPlE,EAAe,CACb,KAAM,iBACR,21CAcA,MAAMC,EAAQC,EAmCRC,EAAOC,EAMPV,EAAUC,EAAAA,IAAI,EAAK,EAGnBmB,EAAa,CACjB,SACA,WACA,sBACA,iBACA,WACA,eACA,YACA,uBACA,cACA,iBACA,SACA,UACA,WACA,SACA,UAAA,EAIIsD,EAAmB,CACvB,cACA,aACA,SACA,OACA,WACA,SAAA,EAGInD,EAAWhB,EAEXc,EAAiBlB,EAAAA,SAAS,IAAM,CACpC,MAAMmB,EAAkC,CAAA,EACxC,OAAAF,EAAW,QAASI,GAAQ,CACtBD,EAASC,CAAG,IAAM,SACpBF,EAAOE,CAAG,EAAID,EAASC,CAAG,EAE9B,CAAC,EACMF,CACT,CAAC,EAEKI,EAAiBvB,EAAAA,SAAS,IAAM,CACpC,KAAM,CAAE,WAAAiD,EAAY,GAAGG,CAAA,EAAWhD,EAC5Be,EAAS,CAAE,GAAGiC,CAAA,EAEpB,OAAAnC,EAAW,QAASI,GAAQ,CAC1B,OAAOF,EAAOE,CAAG,CACnB,CAAC,EAEDkD,EAAiB,QAASlD,GAAQ,CAChC,OAAOF,EAAOE,CAAG,CACnB,CAAC,EAED,OAAOF,EAAO,MACd,OAAOA,EAAO,SACd,OAAOA,EAAO,MACPA,CACT,CAAC,EAEKqD,EAAsBxE,EAAAA,SAAS,IAAM,CACzC,MAAMmB,EAAkC,CAAA,EACxC,OAAAoD,EAAiB,QAASlD,GAAQ,CAC5BA,IAAQ,WAAaD,EAASC,CAAG,IAAM,SACzCF,EAAOE,CAAG,EAAID,EAASC,CAAG,EAE9B,CAAC,EAEGD,EAAS,OAAY,SACvBD,EAAO,KAAUC,EAAS,MAErBD,CACT,CAAC,EAaKsD,EAAc,CAAC7E,EAAuBkE,IAA0C,CACpF,UAAWE,KAAUpE,EAAS,CAC5B,GAAIoE,EAAO,QAAUF,EAEnB,MAAO,CAACE,EAAO,UAAYA,EAAO,SAAS,SAAW,EAExD,GAAIA,EAAO,UAAYA,EAAO,SAAS,OAAS,EAAG,CACjD,MAAMC,EAAQQ,EAAYT,EAAO,SAAUF,CAAW,EACtD,GAAIG,IAAU,GAAO,OAAOA,CAC9B,CACF,CACA,MAAO,EACT,EAMMS,EAAiB,CACrB9E,EACAkE,EACAC,EAA4B,CAAA,IACG,CAC/B,UAAWC,KAAUpE,EAAS,CAC5B,GAAIoE,EAAO,QAAUF,EACnB,MAAO,CAAC,GAAGC,EAAMC,EAAO,KAAK,EAE/B,GAAIA,EAAO,UAAYA,EAAO,SAAS,OAAS,EAAG,CACjD,MAAMC,EAAQS,EAAeV,EAAO,SAAUF,EAAa,CAAC,GAAGC,EAAMC,EAAO,KAAM,CAAC,EACnF,GAAIC,EAAO,OAAOA,CACpB,CACF,CACA,OAAO,IACT,EAKMU,EAAgB7E,EAAAA,IAA4B,EAAE,EAE9C8E,EAAsBlE,GACtB,MAAM,QAAQA,CAAK,EACdA,EACJ,QAASG,GAAU,MAAM,QAAQA,CAAI,EAAIA,EAAO,CAACA,CAAI,CAAE,EACvD,OACEA,GAAkC,OAAOA,GAAS,UAAY,OAAOA,GAAS,QAAA,EAGjFH,GAAU,MAA+BA,IAAU,GAC9C,CAAA,EAEF,CAACA,CAAwB,EAIlCmE,EAAAA,MACE,IAAMzE,EAAM,WACX0E,GAAW,CACV,GAAI,MAAM,QAAQA,CAAM,EACtBH,EAAc,MAAQC,EAAmBE,CAAM,UACtCA,IAAW,QAAaA,IAAW,IAAMA,IAAW,KAAM,CAEnE,MAAMC,EAAQ3E,EAAM,SAAW,CAAA,EACzB2D,EAAOW,EAAeK,EAAMD,CAAyB,EAC3DH,EAAc,MAAQZ,GAAQ,CAAA,CAChC,MACEY,EAAc,MAAQ,CAAA,CAE1B,EACA,CAAE,UAAW,EAAA,CAAK,EAIpBE,EAAAA,MACE,IAAMzE,EAAM,QACZ,IAAM,CACJ,MAAMH,EAAMG,EAAM,WAClB,GAAI,CAAC,MAAM,QAAQH,CAAG,GAAKA,IAAQ,QAAaA,IAAQ,IAAMA,IAAQ,KAAM,CAC1E,MAAM8E,EAAQ3E,EAAM,SAAW,CAAA,EACzB2D,EAAOW,EAAeK,EAAM9E,CAAsB,EACxD0E,EAAc,MAAQZ,GAAQ,CAAA,CAChC,CACF,EACA,CAAE,KAAM,EAAA,CAAK,EAGf,MAAMiB,EAAY,CAACpF,EAAuBkE,IAAgD,CACxF,UAAWE,KAAUpE,EAAS,CAC5B,GAAIoE,EAAO,QAAUF,EACnB,OAAOE,EAAO,OAAS,OAAOA,EAAO,KAAK,EAE5C,GAAIA,EAAO,UAAYA,EAAO,SAAS,OAAS,EAAG,CACjD,MAAMC,EAAQe,EAAUhB,EAAO,SAAUF,CAAW,EACpD,GAAIG,EAAO,OAAOA,CACpB,CACF,CACA,OAAO,IACT,EAEMlE,EAAeC,EAAAA,SAAS,IAAM,CAClC,MAAMC,EAAMG,EAAM,WAClB,GAAI,CAACH,GAAOA,IAAQ,EAClB,MAAO,GAGT,MAAM8E,EAAQ3E,EAAM,SAAW,CAAA,EAE/B,GAAI,MAAM,QAAQH,CAAG,EAAG,CAEtB,MAAMgF,EAAUhF,EAAIA,EAAI,OAAS,CAAC,EAClC,OAAIgF,IAAY,OACPD,EAAUD,EAAME,CAA0B,GAAK,OAAOA,CAAO,EAE/D,EACT,CAEA,OAAOD,EAAUD,EAAM9E,CAAsB,GAAK,OAAOA,CAAG,CAC9D,CAAC,EAEKyD,EAAiB,IAAM,CACvBtD,EAAM,WACVP,EAAQ,MAAQ,GAClB,EAGM+B,EAAW,CAAClB,EAAwBwE,IAAqB,CAG7D,GAAI,MAAM,QAAQxE,CAAK,EAAG,CACxB,MAAMyE,EAAkBP,EAAmBlE,CAAK,EAC1C0E,EAAYD,EAAgBA,EAAgB,OAAS,CAAC,EAC5DR,EAAc,MAAQQ,EAGtB,MAAMJ,EAAQ3E,EAAM,SAAW,CAAA,EAChBqE,EAAYM,EAAMK,CAA4B,IAI3D9E,EAAK,oBAAqB8E,CAA4B,EACtD9E,EAAK,SAAU8E,EAA8BF,CAAK,EAE7C9E,EAAM,WACTP,EAAQ,MAAQ,IAGtB,MACE8E,EAAc,MAAQC,EAAmBlE,CAAK,EAC9CJ,EAAK,oBAAqBI,CAAK,EAC/BJ,EAAK,SAAUI,EAAOwE,CAAK,CAE/B,gBAIErD,YAAA,EAAAC,qBAwBM,MAxBNC,EAwBM,CAvBJC,EAAAA,YAUUC,EAAAA,eAVVC,aAUU,CATP,MAAOnC,EAAA,MACP,QAAO2D,CAAA,EACKvB,CAAAA,GAAAA,EAAAA,UAAWZ,EAAA,OAAc,CACtC,SAAA,GACC,cAAW,IAAQa,EAAAA,EAAEH,EAAAA,MAAAI,EAAAA,IAAA,EAAI,CAAA,KAAA,eAAA,CAAA,CAAA,qCAEIC,EAAAA,OAAM,CAAlBC,EAAGqB,aACnB,GAAAnB,EAAAA,QAD6CC,GAAQ,CACrDC,EAAAA,WAA6CC,EAAA,OAAhCgB,EAAIf,EAAAA,eAAAC,qBAAUJ,GAAQ,CAAA,CAAA,CAAA,EAAA,OAAA,EAAA,CAAA,sCAIvCV,EAAAA,YAUUC,EAAAA,eAVVC,aAUU,YAVQrC,EAAA,2CAAAA,EAAO,MAAAkD,GAAE,UAAU,QAAA,EAAiB7B,EAAA,KAAc,EAAA,mBAClE,IAQM,CARNmE,EAAAA,mBAQM,MARNC,EAQM,CANIzF,EAAA,OADRgC,YAAA,EAAA0D,EAAAA,YAMEtD,sBANFC,aAME,OAJC,MAAOyC,EAAA,MACP,QAAStE,EAAA,OAAA,EACFmE,EAAA,MAAmB,CAC1B,SAAA5C,CAAA,CAAgB,EAAA,KAAA,GAAA,CAAA,QAAA,SAAA,CAAA,mIC9T3BzB,EAAe,CACb,KAAM,aACR,ucAcA,MAAMC,EAAQC,EAcRC,EAAOC,EASPiF,EAAgB1F,EAAAA,IAAuB,EAAE,EAGzC2F,EAAezF,EAAAA,SAAS,IACxB,MAAM,QAAQI,EAAM,MAAM,EACrBA,EAAM,OAAO,KAAK,GAAG,EAEvBA,EAAM,MACd,EAMKsF,EAAY1F,EAAAA,SAA4B,IAAM,CAClD,GAAII,EAAM,UAAW,OAAOA,EAAM,UAElC,MAAMuF,EAAOvF,EAAM,WACnB,OAAI,OAAOuF,GAAS,SAAiB,SACjC,MAAM,QAAQA,CAAI,EAChBA,EAAK,SAAW,EAAU,cAC1B,OAAOA,EAAK,CAAC,GAAM,UAAYA,EAAK,CAAC,IAAM,KAAa,cACrD,cAEF,QACT,CAAC,EAKKC,EAAaC,GAAgB,0BAA0B,KAAKA,CAAG,EAK/DC,EAAcjF,GAAoC,CACtD,GAAI,OAAOA,GAAS,SAAU,OAAOA,EACrC,MAAMgF,EAAMhF,EAAKT,EAAM,MAAM,EAC7B,OAAO,OAAOyF,GAAQ,SAAWA,EAAM,EACzC,EAKME,EAAc,CAAClF,EAAyBgF,IAAwB,CACpE,GAAI,OAAOhF,GAAS,UAAYA,EAAKT,EAAM,OAAO,EAAG,CACnD,MAAMwD,EAAO/C,EAAKT,EAAM,OAAO,EAC/B,OAAO,OAAOwD,GAAS,SAAWA,EAAO,OAAOA,CAAI,CACtD,CACA,OAAOiC,EAAI,MAAM,GAAG,EAAE,OAAS,EACjC,EAKMG,EAAmBH,GACnB,CAACzF,EAAM,WAAa,CAACyF,EAAYA,EACjCA,EAAI,WAAWzF,EAAM,SAAS,EACzByF,EAAI,MAAMzF,EAAM,UAAU,MAAM,EAElCyF,EAMHI,EAAmBvF,GAA4C,CACnE,GAAI,CAACA,EAAO,MAAO,CAAA,EAGnB,IAAIwF,EAA+B,CAAA,EACnC,OAAI,OAAOxF,GAAU,SACnBwF,EAAQxF,EAAM,MAAMN,EAAM,SAAS,EAAE,OAAO,OAAO,EAEnD8F,EAAQxF,EAAM,OAAO,OAAO,EAIvBwF,EAAM,IAAI,CAACrF,EAAMsF,IAAU,CAChC,MAAMN,EAAMC,EAAWjF,CAAI,EAC3B,GAAI,CAACgF,EAAK,OAAO,KAKjB,MAAMO,EAA4B,CAChC,IAHiBR,EAAUC,CAAG,EAAIA,EAAOzF,EAAM,UAAYyF,EAI3D,KAAME,EAAYlF,EAAMgF,CAAG,EAC3B,OAAQ,UACR,aAAcA,CAAA,EAIhB,OAAI,OAAOhF,GAAS,WAClBuF,EAAS,cAAgBvF,GAGpBuF,CACT,CAAC,EAAE,OAAO,OAAO,CACnB,EAGAvB,EAAAA,MACE,IAAMzE,EAAM,WACX0E,GAAW,CACV,MAAMuB,EAASJ,EAAgBnB,CAAM,EAC/BwB,EAAqBd,EAAc,MACtC,OAAQe,GAAMA,EAAE,SAAW,SAAS,EACpC,IAAKA,GAAMA,EAAE,cAAgBA,EAAE,GAAG,EAC/BC,EAAaH,EAAO,IAAKE,GAAMA,EAAE,cAAgBA,EAAE,GAAG,EAE5D,GAAI,KAAK,UAAUD,CAAkB,IAAM,KAAK,UAAUE,CAAU,EAAG,CACrE,MAAMC,EAAiBjB,EAAc,MAAM,OAAQe,GAAMA,EAAE,SAAW,SAAS,EAC/Ef,EAAc,MAAQ,CAAC,GAAGa,EAAQ,GAAGI,CAAc,CACrD,CACF,EACA,CAAE,UAAW,EAAA,CAAK,EAOpB,MAAMC,EAAiB,IAAM,CAC3B,MAAMC,EAAgBnB,EAAc,MAAM,OAAQe,GAAMA,EAAE,SAAW,SAAS,EAE9E,IAAIpF,EAEJ,OAAQuE,EAAU,MAAA,CAChB,IAAK,SACHvE,EAASwF,EACN,IAAKJ,GAAMP,EAAgBO,EAAE,cAAgBA,EAAE,KAAO,EAAE,CAAC,EACzD,OAAO,OAAO,EACd,KAAKnG,EAAM,SAAS,EACvB,MAEF,IAAK,cACHe,EAASwF,EAAc,IAAKJ,GAAM,CAEhC,GAAIA,EAAE,eAAiB,OAAOA,EAAE,eAAkB,SAAU,CAC1D,MAAMK,EAASL,EAAE,cAAcnG,EAAM,MAAM,EAC3C,MAAO,CACL,GAAGmG,EAAE,cACL,CAACnG,EAAM,MAAM,EAAG4F,EAAgB,OAAOY,GAAW,SAAWA,EAAUL,EAAE,cAAgBA,EAAE,KAAO,EAAG,CAAA,CAEzG,CAEA,MAAMM,EAAmC,CACvC,CAACzG,EAAM,MAAM,EAAG4F,EAAgBO,EAAE,cAAgBA,EAAE,KAAO,EAAE,CAAA,EAE/D,OAAInG,EAAM,UACRyG,EAAQzG,EAAM,OAAO,EAAImG,EAAE,MAEtBM,CACT,CAAC,EACD,MAGF,QACE1F,EAASwF,EACN,IAAKJ,GAAMP,EAAgBO,EAAE,cAAgBA,EAAE,KAAO,EAAE,CAAC,EACzD,OAAO,OAAO,EACjB,KAAA,CAGJjG,EAAK,oBAAqBa,CAAM,CAClC,EAGM2F,EAAarF,GAA4B,CAC7C,KAAM,CAAE,KAAAsF,EAAM,SAAAC,CAAA,EAAavF,EAI3B,GAFA,QAAQ,IAAI,0BAA2B,CAAE,KAAAsF,EAAM,SAAAC,EAAU,EAErDD,EAAM,CAER,IAAIE,EAAiD,GACrD,GAAI7G,EAAM,eACR6G,EAAe7G,EAAM,eAAe4G,CAAQ,UACnCA,GAAY,OAAOA,GAAa,SAAU,CAEnD,MAAME,EAAO,MAAM,QAAQF,CAAQ,EAAIA,EAAS,CAAC,EAAIA,EACjDE,GAAQ,QAASA,IACnBD,EAAgBC,EAAyB,IAE7C,CAIA,GAFA,QAAQ,IAAI,8BAA+BD,CAAY,EAEnDA,EAAc,CAChB,MAAME,EAAiB,OAAOF,GAAiB,SAE/C,IAAIG,EAAU,GACVC,EAEJ,GAAIF,EAAgB,CAClB,MAAMG,EAAYL,EAAyC7G,EAAM,MAAM,EACvEgH,EAAU,OAAOE,GAAa,SAAWA,EAAW,GACpDD,EAAeJ,CACjB,MACEG,EAAUH,EAGZ,MAAMM,EAAa3B,EAAUwB,CAAO,EAAIA,EAAUhH,EAAM,UAAYgH,EAEpEI,EAAAA,SAAS,IAAM,CACb,MAAMC,EAAYjC,EAAc,MAAM,UAAWe,GAAMA,EAAE,OAASQ,EAAK,IAAI,EAC3E,QAAQ,IAAI,2BAA4BU,CAAS,EAE7CA,GAAa,IACfjC,EAAc,MAAMiC,CAAS,EAAI,CAC/B,GAAGjC,EAAc,MAAMiC,CAAS,EAChC,OAAQ,UACR,IAAKF,EACL,aAAcH,EAEd,cAAeC,CAAA,GAInBX,EAAA,CACF,CAAC,CACH,CACF,CAEApG,EAAK,UAAWmB,CAAO,CACzB,EAGMiG,EAAUjG,GAA+B,CAC7C,KAAM,CAAE,KAAAsF,GAAStF,EAEjB,GAAIsF,EAAM,CACR,MAAMU,EAAYjC,EAAc,MAAM,UAAWe,GAAMA,EAAE,OAASQ,EAAK,IAAI,EACvEU,GAAa,GACfjC,EAAc,MAAM,OAAOiC,EAAW,CAAC,CAE3C,CAEAE,EAAAA,QAAQ,MAAM,UAAU,EACxBrH,EAAK,OAAQmB,CAAO,CACtB,EAGMmG,EAAYnG,GAAiC,CACjD,KAAM,CAAE,MAAA0E,EAAQ,EAAG,KAAAY,CAAA,EAAStF,EAC5BnB,EAAK,SAAUyG,EAAyBZ,CAAK,EAC7CqB,EAAAA,SAAS,IAAM,CACbd,EAAA,CACF,CAAC,CACH,EAGMmB,EAAcpG,GAAgD,CAClE,KAAM,CAAE,KAAAqG,EAAM,MAAAC,CAAA,EAAUtG,EAGxB,OAFA,QAAQ,IAAI,2BAA4B,CAAE,KAAAqG,EAAM,MAAAC,EAAO,EAE/CD,EAAA,CACN,IAAK,wBACHH,EAAAA,QAAQ,KAAK,WAAW,EACxB,MACF,IAAK,uBACHA,EAAAA,QAAQ,MAAM,eAAe,KAAK,MAAMvH,EAAM,QAAU,IAAI,CAAC,KAAK,EAClE,MACF,IAAK,0BACHuH,EAAAA,QAAQ,KAAK,UAAUvH,EAAM,GAAG,MAAM,EACtC,KAAA,CAEN,gBAKEyB,YAAA,EAAAC,qBAoCM,MApCNC,EAoCM,CAlCY1B,EAAA,OAAI,uBAClBkF,cAaEtD,EAAAA,MAAA+F,EAAAA,MAAA,EAAA,kBAZSxC,EAAA,2CAAAA,EAAa,MAAAzC,GACrB,OAAQ1C,EAAA,OACR,OAAQoF,EAAA,MACR,IAAKpF,EAAA,IACL,mBAAoBA,EAAA,QAAO,KAAA,IAAA,EAC3B,SAAUA,EAAA,SACV,SAAUA,EAAA,SACV,iBAAgBA,EAAA,cAChB,UAAAyG,EACA,OAAAY,EACA,SAAAE,EACA,WAAAC,CAAA,qHAMHtC,cAaEtD,EAAAA,MAAA+F,EAAAA,MAAA,EAAA,kBAZSxC,EAAA,2CAAAA,EAAa,MAAAzC,GACrB,OAAQ1C,EAAA,OACR,OAAQoF,EAAA,MACR,IAAKpF,EAAA,IACL,mBAAoBA,EAAA,QAAO,KAAA,IAAA,EAC3B,SAAUA,EAAA,SACV,SAAUA,EAAA,SACV,iBAAgBA,EAAA,cAChB,UAAAyG,EACA,OAAAY,EACA,SAAAE,EACA,WAAAC,CAAA,gNCzVT1H,GAAe,CACb,KAAM,WACR,oYAqCA,MAAMC,EAAQC,EAURC,EAAOC,EAOP0H,EAAUnI,EAAAA,IAAA,EAGVoI,EAAiD,CACrD,MAAOC,EAAAA,MACP,SAAUA,EAAAA,MACV,OAAQA,EAAAA,MACR,SAAUC,EAAAA,SACV,OAAQC,EACR,SAAUC,EACV,cAAeC,EACf,KAAMC,EACN,KAAMA,EACN,OAAQC,EAAAA,OACR,MAAOC,EAAAA,WACP,SAAUC,EAAAA,cACV,QAASC,EAAAA,QACT,OAAQC,CAAA,EAIJC,EAAgBhB,GAAoC,CACxD,MAAMiB,EAAajB,GAAQ,QAG3B,OAAI1H,EAAM,eAAe2I,CAAU,EAC1B3I,EAAM,aAAa2I,CAAU,EAI/Bb,EAAoBa,CAAU,GAAK,IAC5C,EAGMC,EAAYC,GAA0B,CAC1C,MAAMzF,EAAQ,CAAA,EACd,OAAIyF,EAAO,UACTzF,EAAM,KAAK,CAAE,SAAU,GAAM,QAAS,GAAGyF,EAAO,OAAS,IAAI,MAAA,CAAQ,EAEnEA,EAAO,OACTzF,EAAM,KAAK,GAAGyF,EAAO,KAAK,EAErBzF,CACT,EAGM0F,EAAgBD,GAA0B,CAC9C,MAAME,EAAQ/I,EAAM,WACpB,IAAIgJ,EAAqC,CAAA,EAGrC,OAAOH,EAAO,OAAU,WAC1BG,EAAYH,EAAO,MAAME,CAAK,EACrBF,EAAO,QAChBG,EAAY,CAAE,GAAGH,EAAO,KAAA,GAI1B,MAAMnB,EAAOmB,EAAO,MAAQ,QAkC5B,GAjCInB,IAAS,WACX,OAAO,OAAOsB,EAAW,CAAE,KAAM,WAAY,EACpCtB,IAAS,SAClB,OAAO,OAAOsB,EAAW,CAAE,KAAM,SAAU,EAClCtB,IAAS,OAClB,OAAO,OAAOsB,EAAW,CAAE,KAAM,OAAQ,EAChCtB,IAAS,QAClB,OAAO,OAAOsB,EAAW,CAAE,KAAM,CAAC,OAAQ,QAAQ,EAAG,EAKnD,CAAC,QAAS,WAAY,SAAU,UAAU,EAAE,SAAStB,CAAI,IAMvD,EAHF,OAAOmB,EAAO,OAAU,UACxBA,EAAO,QAAU,MACjB,OAAO,UAAU,eAAe,KAAKA,EAAO,MAAO,YAAY,IAC7BG,EAAU,aAAe,SAC3DA,EAAU,WAAa,IAKrBA,EAAU,OAAS,SACrB,QAAQ,KACN,+DAA+DH,EAAO,IAAI,sDAAA,EAE5E,OAAOG,EAAU,OAKjBhJ,EAAM,SACR,OAAO,OAAOgJ,EAAW,CAAE,SAAU,GAAM,UAClCH,EAAO,SAAU,CAE1B,MAAMI,EACJ,OAAOJ,EAAO,UAAa,WAAaA,EAAO,SAASE,CAAK,EAAIF,EAAO,SAC1E,OAAO,OAAOG,EAAW,CAAE,SAAUC,EAAY,CACnD,CAEA,OAAOD,CACT,EAGME,EAAaL,GACbA,EAAO,SAAW,OAAkB,GACpC,OAAOA,EAAO,QAAW,WACpB,CAACA,EAAO,OAAO7I,EAAM,UAAU,EAEjC,CAAC6I,EAAO,OAGXM,EAAY9H,GAA2B,CACvCA,EAAQ,iBAAmB,GAC7BnB,EAAK,SAAUkJ,EAAAA,MAAMpJ,EAAM,UAAU,CAAC,EAEtCE,EAAK,kBAAmBmB,EAAQ,cAAc,CAElD,EAGMgI,EAAU,IAAM,CACpBxB,EAAQ,OAAO,MAAA,EACf3H,EAAK,OAAO,CACd,EAGA,OAAAoJ,EAAa,CACX,SAAU,IAAMzB,EAAQ,OAAO,SAAA,EAC/B,MAAO,IAAMA,EAAQ,OAAO,MAAA,EAC5B,cAAe,IAAMA,EAAQ,OAAO,cAAA,CAAc,CACnD,UAICpG,YAAA,EAAAC,qBAiDM,MAjDNC,EAiDM,CAhDJC,cA+CSC,EAAAA,MAAA0H,EAAAA,IAAA,EAAA,SA9CH,UAAJ,IAAI1B,EACH,KAAM5H,EAAA,WACN,cAAaA,EAAA,WACb,cAAaA,EAAA,WACb,SAAAkJ,CAAA,qBAES,IAAyB,kBAAnCzH,EAAAA,mBAqBW8H,EAAAA,SAAA,KAAAC,EAAAA,WArBgBxJ,EAAA,QAAV4I,mDAAyB,IAAAA,EAAO,IAAA,GAEvCK,EAAUL,CAAM,iBADxB1D,EAAAA,YAmBctD,EAAAA,MAAA6H,EAAAA,QAAA,EAAA,OAjBX,KAAMb,EAAO,KACb,MAAOA,EAAO,MACd,MAAOD,EAASC,CAAM,EACtB,KAAMA,EAAO,IAAA,qBAGd,IAEW,CAFKA,EAAO,OAAI,QAAeA,EAAO,KAC/CtG,EAAAA,WAAiEC,EAAA,OAApDqG,EAAO,KAAI,OAAG,MAAO5I,EAAA,WAAa,OAAA4I,CAAA,cAIjDpH,EAAAA,UAAA,EAAA0D,EAAAA,YAKEwE,0BAJKjB,EAAaG,EAAO,IAAI,GAD/B/G,EAAAA,WAKE,kBAFU7B,EAAA,WAAmC4I,EAAO,IAAI,2BAA9C5I,EAAA,WAAmC4I,EAAO,IAAI,EAAAlG,CAAA,EAChD,CAAA,QAAA,EAAA,EAAAmG,EAAaD,CAAM,CAAA,EAAA,KAAA,GAAA,CAAA,aAAA,qBAAA,CAAA,EAAA,wFAMtB5I,EAAA,YAAXwB,EAAAA,UAAA,EAAAC,EAAAA,mBAeM,MAfNwD,EAeM,CAdJtD,cAEWC,EAAAA,MAAA+H,EAAAA,MAAA,EAAA,CAFD,MAAM,UAAU,KAAK,SAAS,MAAA,GAAO,QAAS3J,EAAA,QAAU,SAAUA,EAAA,QAAA,qBAC1E,IAAmB,qCAAhBA,EAAA,aAAa,EAAA,CAAA,CAAA,kCAGVA,EAAA,4BADRkF,EAAAA,YAUWtD,EAAAA,MAAA+H,EAAAA,MAAA,EAAA,OART,MAAM,UACN,QAAQ,UACR,MAAA,GACA,MAAM,YACL,QAAOP,EACP,SAAUpJ,EAAA,UAAYA,EAAA,OAAA,qBAEvB,IAAkB,qCAAfA,EAAA,YAAY,EAAA,CAAA,CAAA,6OC7OzBF,GAAe,CACb,KAAM,WACR,21BAYA,MAAMC,EAAQC,EAwBRC,EAAOC,EAgBP0J,EAAa,IAAM,CACvB3J,EAAK,MAAM,EACPF,EAAM,OACRA,EAAM,OAAA,EAGN,OAAO,QAAQ,KAAA,CAEnB,EAKM8J,EAAmBxJ,GAA2B,CAClDJ,EAAK,qBAAsBI,CAAK,EAChCJ,EAAK,aAAcI,CAAK,CAC1B,gBAIEmB,YAAA,EAAAC,qBA0EM,MA1ENC,GA0EM,CAvEI1B,EAAA,0BADRkF,EAAAA,YAuCWtD,EAAAA,MAAAkI,EAAAA,MAAA,EAAA,OArCR,MAAO9J,EAAA,MACP,aAAYA,EAAA,SACZ,UAAWA,EAAA,gBACX,MAAOA,EAAA,YACP,YAAaA,EAAA,kBACb,sBAAqBA,EAAA,uBACrB,mBAAkBA,EAAA,qBAClB,QAASA,EAAA,cACT,UAASA,EAAA,aACT,YAAY4J,EACZ,4BAAa3J,EAAI,aAAA,EAAA,uBAGFgC,EAAAA,uBAAyBjC,EAAA,iBAAa,oBACpD,IAEO,CAFPsC,EAAAA,WAEOC,0BAFP,IAEO,CAD6BvC,EAAA,YAAlCwB,EAAAA,UAAA,EAAA0D,EAAAA,YAAgDwE,EAAAA,wBAAhC1J,EAAA,UAAU,EAAA,CAAA,IAAA,CAAA,CAAA,sDAKdiC,EAAAA,OAAM,cAAA,QAAmB,qBACvC,IAA4B,CAA5BK,EAAAA,WAA4BC,EAAA,OAAA,eAAA,CAAA,EAAA,OAAA,EAAA,CAAA,mBAIdN,EAAAA,wBAA0BjC,EAAA,kBAAc,qBACtD,IAEO,CAFPsC,EAAAA,WAEOC,2BAFP,IAEO,CAD8BvC,EAAA,aAAnCwB,EAAAA,UAAA,EAAA0D,EAAAA,YAAkDwE,EAAAA,wBAAlC1J,EAAA,WAAW,EAAA,CAAA,IAAA,CAAA,CAAA,sDAKfiC,EAAAA,0BAA4BjC,EAAA,oBAAgB,uBAC1D,IAEO,CAFPsC,EAAAA,WAEOC,6BAFP,IAEO,CADgCvC,EAAA,eAArCwB,EAAAA,UAAA,EAAA0D,EAAAA,YAAsDwE,EAAAA,wBAAtC1J,EAAA,aAAa,EAAA,CAAA,IAAA,CAAA,CAAA,iNAMnCgF,EAAAA,mBAEM,MAFNC,GAEM,CADJ3C,EAAAA,WAAQC,EAAA,OAAA,UAAA,CAAA,EAAA,OAAA,EAAA,CAAA,GAKFvC,EAAA,YAAcA,EAAA,MAAM,sBAD5BkF,EAAAA,YAwBYtD,QAAAmI,EAAAA,MAAA,EAAA,OAtBT,MAAO/J,EAAA,YACP,SAAUA,EAAA,eACV,MAAOA,EAAA,YACP,YAAaA,EAAA,kBACb,yBAAwBA,EAAA,0BACxB,MAAOA,EAAA,YACP,MAAOA,EAAA,YACP,MAAOA,EAAA,YACP,UAASA,EAAA,aACT,SAAQ6J,CAAA,qBAGP,IAAmB,kBADrBpI,EAAAA,mBAUiB8H,EAAAA,SAAA,KAAAC,EAAAA,WATDxJ,EAAA,KAAPgK,kBADT9E,EAAAA,YAUiBtD,EAAAA,MAAAqI,EAAAA,UAAA,EAAA,CARd,IAAKD,EAAI,MACT,MAAOA,EAAI,MACX,cAAaA,EAAI,UAAA,mCAIP,IACX,mBADW,IACXE,EAAAA,gBAAGF,EAAI,KAAK,EAAA,CAAA,CAAA,SAHIA,EAAI,WAAO,oBACzB,IAA4B,gBAA5B9E,EAAAA,YAA4BwE,EAAAA,wBAAZM,EAAI,IAAI,CAAA,EAAA"}
package/dist/index.d.ts CHANGED
@@ -22,6 +22,7 @@ import { ShallowUnwrapRef } from 'vue';
22
22
  import { StepperProps } from 'tdesign-mobile-vue';
23
23
  import { SuccessContext } from 'tdesign-mobile-vue';
24
24
  import { SwitchProps } from 'tdesign-mobile-vue';
25
+ import { TdBadgeProps } from 'tdesign-mobile-vue';
25
26
  import { TextareaProps } from 'tdesign-mobile-vue';
26
27
  import { TimeModeValues } from 'tdesign-mobile-vue';
27
28
  import { TNode } from 'tdesign-mobile-vue';
@@ -63,6 +64,12 @@ declare type __VLS_WithTemplateSlots_4<T, S> = T & {
63
64
  };
64
65
  };
65
66
 
67
+ declare type __VLS_WithTemplateSlots_5<T, S> = T & {
68
+ new (): {
69
+ $slots: S;
70
+ };
71
+ };
72
+
66
73
  declare type BaseComponentProps<P> = Omit<P, 'modelValue' | 'value' | 'defaultValue' | 'onChange'>;
67
74
 
68
75
  declare interface BaseFormSchema<T = Record<string, unknown>> {
@@ -243,6 +250,93 @@ export declare interface SmartFormProps<T = Record<string, unknown>> {
243
250
  componentMap?: ComponentMapType;
244
251
  }
245
252
 
253
+ export declare const SmartPage: __VLS_WithTemplateSlots_5<DefineComponent<SmartPageProps, {}, {}, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, {} & {
254
+ "update:tabBarValue": (value: string | number) => any;
255
+ "tab-change": (value: string | number) => any;
256
+ back: () => any;
257
+ "right-click": () => any;
258
+ }, string, PublicProps, Readonly<SmartPageProps> & Readonly<{
259
+ "onUpdate:tabBarValue"?: ((value: string | number) => any) | undefined;
260
+ "onTab-change"?: ((value: string | number) => any) | undefined;
261
+ onBack?: (() => any) | undefined;
262
+ "onRight-click"?: (() => any) | undefined;
263
+ }>, {
264
+ showNavbar: boolean;
265
+ showBack: boolean;
266
+ showTabBar: boolean;
267
+ navbarAnimation: boolean;
268
+ navbarFixed: boolean;
269
+ navbarPlaceholder: boolean;
270
+ navbarSafeAreaInsetTop: boolean;
271
+ navbarVisible: boolean;
272
+ tabBarBordered: boolean;
273
+ tabBarFixed: boolean;
274
+ tabBarPlaceholder: boolean;
275
+ tabBarSafeAreaInsetBottom: boolean;
276
+ tabBarShape: "round" | "normal";
277
+ tabBarSplit: boolean;
278
+ tabBarTheme: "normal" | "tag";
279
+ }, {}, {}, {}, string, ComponentProvideOptions, false, {}, HTMLDivElement>, {
280
+ 'navbar-left'?(_: {}): any;
281
+ 'navbar-title'?(_: {}): any;
282
+ 'navbar-right'?(_: {}): any;
283
+ 'navbar-capsule'?(_: {}): any;
284
+ default?(_: {}): any;
285
+ }>;
286
+
287
+ export declare interface SmartPageProps {
288
+ /** 页面标题 */
289
+ title?: string;
290
+ /** 是否显示导航栏,默认 true */
291
+ showNavbar?: boolean;
292
+ /** 是否显示返回箭头,默认 false */
293
+ showBack?: boolean;
294
+ /** 自定义返回操作(不传则默认 router.back()) */
295
+ onBack?: () => void;
296
+ /** 是否显示底部标签栏,默认 false */
297
+ showTabBar?: boolean;
298
+ /** TabBar 标签项配置 */
299
+ tabs?: TabItem[];
300
+ /** 是否添加动画效果,默认 true */
301
+ navbarAnimation?: boolean;
302
+ /** 胶囊区域自定义内容 */
303
+ navbarCapsule?: () => VNode;
304
+ /** 是否固定在顶部,默认 true */
305
+ navbarFixed?: boolean;
306
+ /** 左侧自定义内容 */
307
+ navbarLeft?: () => VNode;
308
+ /** 固定时是否显示占位,默认 true */
309
+ navbarPlaceholder?: boolean;
310
+ /** 右侧自定义内容 */
311
+ navbarRight?: () => VNode;
312
+ /** 是否留出顶部安全距离,默认 true */
313
+ navbarSafeAreaInsetTop?: boolean;
314
+ /** 标题最大长度 */
315
+ navbarTitleMaxLength?: number;
316
+ /** 是否显示导航栏(TDesign 原生),默认 true */
317
+ navbarVisible?: boolean;
318
+ /** z-index 层级 */
319
+ navbarZIndex?: number;
320
+ /** 当前选中值,支持 v-model:tabBarValue */
321
+ tabBarValue?: string | number;
322
+ /** 是否显示外边框,默认 true */
323
+ tabBarBordered?: boolean;
324
+ /** 是否固定在底部,默认 true */
325
+ tabBarFixed?: boolean;
326
+ /** 固定时是否显示占位,默认 true */
327
+ tabBarPlaceholder?: boolean;
328
+ /** 是否留出底部安全距离,默认 true */
329
+ tabBarSafeAreaInsetBottom?: boolean;
330
+ /** 标签栏形状,默认 'round' */
331
+ tabBarShape?: 'round' | 'normal';
332
+ /** 是否显示分割线,默认 true */
333
+ tabBarSplit?: boolean;
334
+ /** 标签栏主题,默认 'normal' */
335
+ tabBarTheme?: 'normal' | 'tag';
336
+ /** z-index 层级 */
337
+ tabBarZIndex?: number;
338
+ }
339
+
246
340
  export declare const SmartSelect: __VLS_WithTemplateSlots<DefineComponent<SmartSelectProps, {}, {}, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, {} & {
247
341
  change: (value: PickerValue[], context: unknown) => any;
248
342
  confirm: (value: PickerValue[], context: unknown) => any;
@@ -641,6 +735,18 @@ export declare interface SwitchFormSchema<T> extends BaseFormSchema<T> {
641
735
  props?: SchemaProps<T, BaseComponentProps<SwitchProps>>;
642
736
  }
643
737
 
738
+ /** TabBar 标签项配置 */
739
+ export declare interface TabItem {
740
+ /** 标签值(必填) */
741
+ value: string | number;
742
+ /** 标签文本 */
743
+ label?: string;
744
+ /** 图标组件,如 TIcon */
745
+ icon?: Component;
746
+ /** 徽标配置 */
747
+ badgeProps?: TdBadgeProps;
748
+ }
749
+
644
750
  export declare interface TextareaFormSchema<T> extends BaseFormSchema<T> {
645
751
  type: 'textarea';
646
752
  props?: SchemaProps<T, BaseComponentProps<TextareaProps>>;