@veltra/desktop 1.1.28 → 1.1.29
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/action/action-group.vue.d.ts +4 -6
- package/dist/components/action/action-group.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/action/action-group.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/action/action.js.map +1 -1
- package/dist/components/action/action.vue.d.ts +4 -7
- package/dist/components/action/di.js.map +1 -1
- package/dist/components/auto-complete/auto-complete.js.map +1 -1
- package/dist/components/auto-complete/auto-complete.vue.d.ts +5 -7
- package/dist/components/auto-complete/use-keyboard.js.map +1 -1
- package/dist/components/auto-complete/use-suggestions.js.map +1 -1
- package/dist/components/badge/badge.js.map +1 -1
- package/dist/components/badge/badge.vue.d.ts +2 -4
- package/dist/components/batch-edit/batch-edit-form.js.map +1 -1
- package/dist/components/batch-edit/batch-edit-list.js.map +1 -1
- package/dist/components/batch-edit/batch-edit.js.map +1 -1
- package/dist/components/batch-edit/batch-edit.vue.d.ts +4 -7
- package/dist/components/batch-edit/di.js.map +1 -1
- package/dist/components/batch-edit/helper.js.map +1 -1
- package/dist/components/batch-edit/use-edit.js.map +1 -1
- package/dist/components/breadcrumb/breadcrumb.js.map +1 -1
- package/dist/components/breadcrumb/breadcrumb.vue.d.ts +3 -5
- package/dist/components/button/button-group.js.map +1 -1
- package/dist/components/button/button-group.vue.d.ts +1 -3
- package/dist/components/button/button.js.map +1 -1
- package/dist/components/button/button.vue.d.ts +4 -6
- package/dist/components/calendar/calendar.js.map +1 -1
- package/dist/components/calendar/calendar.vue.d.ts +3 -5
- package/dist/components/calendar/utils.js.map +1 -1
- package/dist/components/card/card-action.js.map +1 -1
- package/dist/components/card/card-action.vue.d.ts +1 -3
- package/dist/components/card/card-content.js.map +1 -1
- package/dist/components/card/card-content.vue.d.ts +1 -3
- package/dist/components/card/card-cover.js.map +1 -1
- package/dist/components/card/card-cover.vue.d.ts +1 -3
- package/dist/components/card/card-header.js.map +1 -1
- package/dist/components/card/card-header.vue.d.ts +1 -3
- package/dist/components/card/card.js.map +1 -1
- package/dist/components/card/card.vue.d.ts +1 -3
- package/dist/components/card/di.js.map +1 -1
- package/dist/components/cascade/cascade-panel-item.js.map +1 -1
- package/dist/components/cascade/cascade.js.map +1 -1
- package/dist/components/cascade/cascade.vue.d.ts +7 -9
- package/dist/components/cascade/di.js.map +1 -1
- package/dist/components/cascade/node.js.map +1 -1
- package/dist/components/cascade/use-check.js.map +1 -1
- package/dist/components/cascade/use-data-map.js.map +1 -1
- package/dist/components/cascade/use-select.js.map +1 -1
- package/dist/components/check-tag/check-tag.js.map +1 -1
- package/dist/components/check-tag/check-tag.vue.d.ts +3 -5
- package/dist/components/checkbox/checkbox-button.js.map +1 -1
- package/dist/components/checkbox/checkbox-button.vue.d.ts +4 -7
- package/dist/components/checkbox/checkbox.js.map +1 -1
- package/dist/components/checkbox/checkbox.vue.d.ts +3 -5
- package/dist/components/checkbox-group/checkbox-group.js.map +1 -1
- package/dist/components/checkbox-group/checkbox-group.vue.d.ts +5 -7
- package/dist/components/code-editor/code-editor.js.map +1 -1
- package/dist/components/code-editor/code-editor.vue.d.ts +3 -5
- package/dist/components/collapse/collapse-item.js.map +1 -1
- package/dist/components/collapse/collapse-item.vue.d.ts +1 -3
- package/dist/components/collapse/collapse.js.map +1 -1
- package/dist/components/collapse/collapse.vue.d.ts +3 -5
- package/dist/components/collapse/di.js.map +1 -1
- package/dist/components/condition-editor/components/condition-group.js.map +1 -1
- package/dist/components/condition-editor/components/condition-row.js.map +1 -1
- package/dist/components/condition-editor/condition-editor.js.map +1 -1
- package/dist/components/condition-editor/condition-editor.vue.d.ts +3 -5
- package/dist/components/condition-editor/core/evaluator.js.map +1 -1
- package/dist/components/condition-editor/core/operators.js.map +1 -1
- package/dist/components/context-menu/api.js.map +1 -1
- package/dist/components/context-menu/context-menu-item.js.map +1 -1
- package/dist/components/context-menu/context-menu.js.map +1 -1
- package/dist/components/context-menu/context-menu.vue.d.ts +3 -5
- package/dist/components/context-menu/di.js.map +1 -1
- package/dist/components/date-panel/date-panel.js.map +1 -1
- package/dist/components/date-panel/date-panel.vue.d.ts +8 -12
- package/dist/components/date-panel/di.js.map +1 -1
- package/dist/components/date-panel/headers/day.js.map +1 -1
- package/dist/components/date-panel/headers/month.js.map +1 -1
- package/dist/components/date-panel/headers/year.js.map +1 -1
- package/dist/components/date-panel/panels/day.js.map +1 -1
- package/dist/components/date-panel/panels/month.js.map +1 -1
- package/dist/components/date-panel/panels/year.js.map +1 -1
- package/dist/components/date-panel/use-date-select.js.map +1 -1
- package/dist/components/date-panel/use-panel-date.js.map +1 -1
- package/dist/components/date-panel/use-panel.js.map +1 -1
- package/dist/components/date-picker/date-picker.js.map +1 -1
- package/dist/components/date-picker/date-picker.vue.d.ts +5 -7
- package/dist/components/date-range-picker/date-range-picker.js.map +1 -1
- package/dist/components/date-range-picker/date-range-picker.vue.d.ts +5 -7
- package/dist/components/dialog/di.js.map +1 -1
- package/dist/components/dialog/dialog.js.map +1 -1
- package/dist/components/dialog/dialog.vue.d.ts +3 -6
- package/dist/components/dialog/use-maximum.js.map +1 -1
- package/dist/components/drawer/drawer.js.map +1 -1
- package/dist/components/drawer/drawer.vue.d.ts +3 -5
- package/dist/components/dropdown/dropdown.js.map +1 -1
- package/dist/components/dropdown/dropdown.vue.d.ts +3 -6
- package/dist/components/empty/empty.js.map +1 -1
- package/dist/components/empty/empty.vue.d.ts +3 -5
- package/dist/components/expression-editor/components/path-preview.js.map +1 -1
- package/dist/components/expression-editor/components/variable-picker.js.map +1 -1
- package/dist/components/expression-editor/core/chip.js.map +1 -1
- package/dist/components/expression-editor/core/editor.js.map +1 -1
- package/dist/components/expression-editor/core/mention.js.map +1 -1
- package/dist/components/expression-editor/core/model.js.map +1 -1
- package/dist/components/expression-editor/di.js.map +1 -1
- package/dist/components/expression-editor/expression-editor.js.map +1 -1
- package/dist/components/expression-editor/expression-editor.vue.d.ts +3 -5
- package/dist/components/file-picker/file-picker.js.map +1 -1
- package/dist/components/file-picker/file-picker.vue.d.ts +3 -5
- package/dist/components/file-picker/helper.js.map +1 -1
- package/dist/components/file-viewer/file-viewer.js +1 -1
- package/dist/components/file-viewer/file-viewer.js.map +1 -1
- package/dist/components/file-viewer/file-viewer.vue.d.ts +5 -6
- package/dist/components/file-viewer/helper.js.map +1 -1
- package/dist/components/file-viewer/previewers/docx-previewer.js.map +1 -1
- package/dist/components/file-viewer/previewers/image-previewer.js.map +1 -1
- package/dist/components/file-viewer/previewers/pdf-previewer.js.map +1 -1
- package/dist/components/file-viewer/previewers/pdf-viewport-scroll.js.map +1 -1
- package/dist/components/file-viewer/previewers/pdf-zoom-bridge.js.map +1 -1
- package/dist/components/file-viewer/previewers/sheet-previewer.js.map +1 -1
- package/dist/components/file-viewer/previewers/text-previewer.js.map +1 -1
- package/dist/components/file-viewer/previewers/video-previewer.js.map +1 -1
- package/dist/components/float-button/float-button.js.map +1 -1
- package/dist/components/float-button/float-button.vue.d.ts +3 -5
- package/dist/components/form/dynamic-form-model.js.map +1 -1
- package/dist/components/form/form-model.js.map +1 -1
- package/dist/components/form/form.vue.d.ts +3 -4
- package/dist/components/form/form.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/form/form.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/form/helper.js.map +1 -1
- package/dist/components/form/use-node-interceptor.js.map +1 -1
- package/dist/components/form-item/form-item.vue.d.ts +2 -4
- package/dist/components/form-item/form-item.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/form-item/form-item.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/form-item/helper.js.map +1 -1
- package/dist/components/gantt-chart/gantt-chart.js.map +1 -1
- package/dist/components/gantt-chart/gantt-chart.vue.d.ts +1 -3
- package/dist/components/grid/breakpoint.js.map +1 -1
- package/dist/components/grid/di.js.map +1 -1
- package/dist/components/grid/grid-item.js.map +1 -1
- package/dist/components/grid/grid-item.vue.d.ts +2 -4
- package/dist/components/grid/grid.js.map +1 -1
- package/dist/components/grid/grid.vue.d.ts +3 -5
- package/dist/components/grid/use-responsive.js.map +1 -1
- package/dist/components/grid-input/grid-input.js.map +1 -1
- package/dist/components/grid-input/grid-input.vue.d.ts +3 -6
- package/dist/components/group-input/group-input.js.map +1 -1
- package/dist/components/group-input/group-input.vue.d.ts +2 -4
- package/dist/components/group-input/use-group-items.js.map +1 -1
- package/dist/components/icon/icon.js.map +1 -1
- package/dist/components/icon/icon.vue.d.ts +1 -3
- package/dist/components/input/input.vue.d.ts +5 -7
- package/dist/components/input/input.vue_vue_type_script_setup_true_lang.js +3 -3
- package/dist/components/input/input.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/kbd/kbd.js.map +1 -1
- package/dist/components/kbd/kbd.vue.d.ts +1 -3
- package/dist/components/layout/di.js.map +1 -1
- package/dist/components/layout/layout-resizer.js.map +1 -1
- package/dist/components/layout/layout.js.map +1 -1
- package/dist/components/layout/layout.vue.d.ts +2 -4
- package/dist/components/list/list-item.js.map +1 -1
- package/dist/components/list/list-item.vue.d.ts +1 -3
- package/dist/components/list/list.js.map +1 -1
- package/dist/components/list/list.vue.d.ts +1 -3
- package/dist/components/loading/directive.js.map +1 -1
- package/dist/components/loading/loading.js.map +1 -1
- package/dist/components/loading/loading.vue.d.ts +2 -4
- package/dist/components/menu/di.js.map +1 -1
- package/dist/components/menu/helper.js.map +1 -1
- package/dist/components/menu/menu-icon.js.map +1 -1
- package/dist/components/menu/menu-item-collapsed.js.map +1 -1
- package/dist/components/menu/menu-item.js.map +1 -1
- package/dist/components/menu/menu-item.vue.d.ts +1 -3
- package/dist/components/menu/menu-sub-collapsed.js.map +1 -1
- package/dist/components/menu/menu-sub.js.map +1 -1
- package/dist/components/menu/menu-sub.vue.d.ts +1 -3
- package/dist/components/menu/menu.js.map +1 -1
- package/dist/components/menu/menu.vue.d.ts +3 -5
- package/dist/components/menu/use-menu-item.js.map +1 -1
- package/dist/components/menu/walk-menu-path.js.map +1 -1
- package/dist/components/message/helper.js.map +1 -1
- package/dist/components/message/message-box.js.map +1 -1
- package/dist/components/message/message.js.map +1 -1
- package/dist/components/message/message.vue.d.ts +3 -5
- package/dist/components/message/message2.js.map +1 -1
- package/dist/components/message-confirm/message-confirm.js.map +1 -1
- package/dist/components/message-confirm/message-confirm.vue.d.ts +2 -3
- package/dist/components/message-confirm/message-confirm2.js.map +1 -1
- package/dist/components/multi-select/di.js.map +1 -1
- package/dist/components/multi-select/multi-select-option.js.map +1 -1
- package/dist/components/multi-select/multi-select.js.map +1 -1
- package/dist/components/multi-select/multi-select.vue.d.ts +7 -9
- package/dist/components/multi-tree-select/multi-tree-select.js.map +1 -1
- package/dist/components/multi-tree-select/multi-tree-select.vue.d.ts +8 -9
- package/dist/components/node-render/node-render.js.map +1 -1
- package/dist/components/notification/index.js.map +1 -1
- package/dist/components/notification/notification.js.map +1 -1
- package/dist/components/notification/notification.vue.d.ts +3 -6
- package/dist/components/number/number.js.map +1 -1
- package/dist/components/number/number.vue.d.ts +2 -4
- package/dist/components/number-input/number-input.js.map +1 -1
- package/dist/components/number-input/number-input.vue.d.ts +5 -7
- package/dist/components/number-range-input/number-range-input.js.map +1 -1
- package/dist/components/number-range-input/number-range-input.vue.d.ts +4 -6
- package/dist/components/paginator/paginator.js.map +1 -1
- package/dist/components/paginator/paginator.vue.d.ts +3 -5
- package/dist/components/palette/color-transform.js.map +1 -1
- package/dist/components/palette/di.js.map +1 -1
- package/dist/components/palette/palette-alpha.js.map +1 -1
- package/dist/components/palette/palette-color-switch.js.map +1 -1
- package/dist/components/palette/palette-hue.js.map +1 -1
- package/dist/components/palette/palette-sv.js.map +1 -1
- package/dist/components/palette/palette.js.map +1 -1
- package/dist/components/palette/palette.vue.d.ts +3 -5
- package/dist/components/palette/use-hsv.js.map +1 -1
- package/dist/components/password-input/password-input.js.map +1 -1
- package/dist/components/password-input/password-input.vue.d.ts +4 -6
- package/dist/components/pop-confirm/pop-confirm.js.map +1 -1
- package/dist/components/pop-confirm/pop-confirm.vue.d.ts +5 -7
- package/dist/components/progress/progress.js.map +1 -1
- package/dist/components/progress/progress.vue.d.ts +2 -3
- package/dist/components/progress-nodes/progress-nodes.js.map +1 -1
- package/dist/components/progress-nodes/progress-nodes.vue.d.ts +4 -7
- package/dist/components/radio/radio.js.map +1 -1
- package/dist/components/radio/radio.vue.d.ts +3 -5
- package/dist/components/radio-group/radio-group.js.map +1 -1
- package/dist/components/radio-group/radio-group.vue.d.ts +5 -7
- package/dist/components/rich-text-editor/rich-text-editor.js.map +1 -1
- package/dist/components/rich-text-editor/rich-text-editor.vue.d.ts +5 -7
- package/dist/components/rich-text-editor/toolbar.js.map +1 -1
- package/dist/components/scroll/di.js.map +1 -1
- package/dist/components/scroll/scroll-bar.js.map +1 -1
- package/dist/components/scroll/scroll.js.map +1 -1
- package/dist/components/scroll/scroll.vue.d.ts +3 -5
- package/dist/components/select/select.js.map +1 -1
- package/dist/components/select/select.vue.d.ts +7 -9
- package/dist/components/select/use-keyboard.js.map +1 -1
- package/dist/components/select/use-options.js.map +1 -1
- package/dist/components/slider/di.js.map +1 -1
- package/dist/components/slider/slider-thumb.js.map +1 -1
- package/dist/components/slider/slider.js.map +1 -1
- package/dist/components/slider/slider.vue.d.ts +2 -4
- package/dist/components/slider/use-slider.js.map +1 -1
- package/dist/components/steps/steps.js.map +1 -1
- package/dist/components/steps/steps.vue.d.ts +4 -7
- package/dist/components/switch/switch.js.map +1 -1
- package/dist/components/switch/switch.vue.d.ts +3 -5
- package/dist/components/table/di.js.map +1 -1
- package/dist/components/table/node/col.js.map +1 -1
- package/dist/components/table/node/row.js.map +1 -1
- package/dist/components/table/table-body.js.map +1 -1
- package/dist/components/table/table-cell.js.map +1 -1
- package/dist/components/table/table-foot.js.map +1 -1
- package/dist/components/table/table-head.js.map +1 -1
- package/dist/components/table/table-row.js.map +1 -1
- package/dist/components/table/table.js.map +1 -1
- package/dist/components/table/table.vue.d.ts +7 -10
- package/dist/components/table/use-check.js.map +1 -1
- package/dist/components/table/use-col-resize.js.map +1 -1
- package/dist/components/table/use-columns.js.map +1 -1
- package/dist/components/table/use-fixed-columns.js.map +1 -1
- package/dist/components/table/use-rows.js.map +1 -1
- package/dist/components/table/use-table.js.map +1 -1
- package/dist/components/table-editor/table-editor.js.map +1 -1
- package/dist/components/table-editor/table-editor.vue.d.ts +3 -5
- package/dist/components/tabs/tabs-horizontal.js +5 -2
- package/dist/components/tabs/tabs-horizontal.js.map +1 -1
- package/dist/components/tabs/tabs-horizontal.vue.d.ts +5 -7
- package/dist/components/tabs/tabs-vertical.js +5 -2
- package/dist/components/tabs/tabs-vertical.js.map +1 -1
- package/dist/components/tabs/tabs-vertical.vue.d.ts +11 -10
- package/dist/components/tabs/tabs.js.map +1 -1
- package/dist/components/tabs/tabs.vue.d.ts +11 -6
- package/dist/components/tabs/use-tabs-bar.js.map +1 -1
- package/dist/components/tag/tag.js.map +1 -1
- package/dist/components/tag/tag.vue.d.ts +3 -5
- package/dist/components/text/text.js.map +1 -1
- package/dist/components/text/text.vue.d.ts +2 -4
- package/dist/components/textarea/textarea.js.map +1 -1
- package/dist/components/textarea/textarea.vue.d.ts +6 -8
- package/dist/components/textarea/utils.js.map +1 -1
- package/dist/components/theme/schema.js.map +1 -1
- package/dist/components/theme/theme.js.map +1 -1
- package/dist/components/theme/theme.vue.d.ts +1 -3
- package/dist/components/tip/tip.js.map +1 -1
- package/dist/components/tip/tip.vue.d.ts +4 -6
- package/dist/components/tip/use-nest.js.map +1 -1
- package/dist/components/tree/di.js.map +1 -1
- package/dist/components/tree/tree-node.js.map +1 -1
- package/dist/components/tree/tree-node2.js.map +1 -1
- package/dist/components/tree/tree.js.map +1 -1
- package/dist/components/tree/tree.vue.d.ts +3 -5
- package/dist/components/tree/use-check.js.map +1 -1
- package/dist/components/tree/use-filter.js.map +1 -1
- package/dist/components/tree/use-select.js.map +1 -1
- package/dist/components/tree/use-tree-nodes.js.map +1 -1
- package/dist/components/tree-select/tree-select.js.map +1 -1
- package/dist/components/tree-select/tree-select.vue.d.ts +8 -9
- package/dist/components/watermark/watermark.js.map +1 -1
- package/dist/components/watermark/watermark.vue.d.ts +2 -4
- package/dist/index.d.ts +1 -1
- package/dist/install.js.map +1 -1
- package/dist/types/index.d.ts +1 -1
- package/package.json +8 -8
- package/src/components/tabs/tabs-horizontal.vue +2 -2
- package/src/components/tabs/tabs-vertical.vue +1 -1
- package/src/components/tabs/tabs.vue +2 -2
- package/dist/components/kbd/index.d.ts +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"text-previewer.js","names":[],"sources":["../../../../src/components/file-viewer/previewers/text-previewer.vue"],"sourcesContent":["<template>\n <u-scroll tag=\"div\" :class=\"cls.e('text')\">\n <div v-if=\"truncated\" :class=\"cls.e('sheet-note')\">\n ⚠ 文件过大,仅展示前 {{ formatKb(maxBytes) }}\n </div>\n <pre :class=\"cls.e('text-pre')\"><code>{{ text }}</code></pre>\n <div v-if=\"loading\" :class=\"cls.e('loading')\">加载中…</div>\n </u-scroll>\n</template>\n\n<script lang=\"ts\" setup>\nimport { bem } from '@veltra/utils'\nimport { onBeforeUnmount, ref, shallowRef, watch } from 'vue'\n\nimport type { FileViewerItem } from '../../../types/file-viewer'\nimport { UScroll } from '../../scroll'\n\ndefineOptions({ name: 'FileViewerTextPreviewer' })\n\nconst props = withDefaults(\n defineProps<{\n file: FileViewerItem\n /** 单文件最大读取字节数(超出截断),默认 2MB */\n maxBytes?: number\n }>(),\n { maxBytes: 2 * 1024 * 1024 }\n)\n\nconst emit = defineEmits<{ (e: 'error', err: unknown): void }>()\n\nconst cls = bem('file-viewer')\n\nconst text = shallowRef('')\nconst truncated = ref(false)\nconst loading = ref(true)\n\nlet controller: AbortController | undefined\n\nfunction formatKb(bytes: number): string {\n if (bytes >= 1024 * 1024) return `${(bytes / 1024 / 1024).toFixed(1)} MB`\n return `${(bytes / 1024).toFixed(0)} KB`\n}\n\nasync function load() {\n controller?.abort()\n controller = new AbortController()\n loading.value = true\n truncated.value = false\n text.value = ''\n\n try {\n const { toArrayBuffer } = await import('../helper')\n const buf = await toArrayBuffer(props.file.src, controller.signal)\n const max = props.maxBytes\n const view = max > 0 && buf.byteLength > max ? new Uint8Array(buf, 0, max) : new Uint8Array(buf)\n truncated.value = max > 0 && buf.byteLength > max\n text.value = new TextDecoder('utf-8', { fatal: false }).decode(view)\n } catch (err) {\n if ((err as { name?: string })?.name === 'AbortError') return\n emit('error', err)\n } finally {\n loading.value = false\n }\n}\n\nwatch(\n () => props.file,\n () => load(),\n { immediate: true }\n)\n\nonBeforeUnmount(() => {\n controller?.abort()\n text.value = ''\n})\n</script>\n"],"mappings":";;;;;;;;;;;;;EAmBA,MAAM,QAAQ;EASd,MAAM,OAAO;EAEb,MAAM,MAAM,IAAI,
|
|
1
|
+
{"version":3,"file":"text-previewer.js","names":[],"sources":["../../../../src/components/file-viewer/previewers/text-previewer.vue"],"sourcesContent":["<template>\n <u-scroll tag=\"div\" :class=\"cls.e('text')\">\n <div v-if=\"truncated\" :class=\"cls.e('sheet-note')\">\n ⚠ 文件过大,仅展示前 {{ formatKb(maxBytes) }}\n </div>\n <pre :class=\"cls.e('text-pre')\"><code>{{ text }}</code></pre>\n <div v-if=\"loading\" :class=\"cls.e('loading')\">加载中…</div>\n </u-scroll>\n</template>\n\n<script lang=\"ts\" setup>\nimport { bem } from '@veltra/utils'\nimport { onBeforeUnmount, ref, shallowRef, watch } from 'vue'\n\nimport type { FileViewerItem } from '../../../types/file-viewer'\nimport { UScroll } from '../../scroll'\n\ndefineOptions({ name: 'FileViewerTextPreviewer' })\n\nconst props = withDefaults(\n defineProps<{\n file: FileViewerItem\n /** 单文件最大读取字节数(超出截断),默认 2MB */\n maxBytes?: number\n }>(),\n { maxBytes: 2 * 1024 * 1024 }\n)\n\nconst emit = defineEmits<{ (e: 'error', err: unknown): void }>()\n\nconst cls = bem('file-viewer')\n\nconst text = shallowRef('')\nconst truncated = ref(false)\nconst loading = ref(true)\n\nlet controller: AbortController | undefined\n\nfunction formatKb(bytes: number): string {\n if (bytes >= 1024 * 1024) return `${(bytes / 1024 / 1024).toFixed(1)} MB`\n return `${(bytes / 1024).toFixed(0)} KB`\n}\n\nasync function load() {\n controller?.abort()\n controller = new AbortController()\n loading.value = true\n truncated.value = false\n text.value = ''\n\n try {\n const { toArrayBuffer } = await import('../helper')\n const buf = await toArrayBuffer(props.file.src, controller.signal)\n const max = props.maxBytes\n const view = max > 0 && buf.byteLength > max ? new Uint8Array(buf, 0, max) : new Uint8Array(buf)\n truncated.value = max > 0 && buf.byteLength > max\n text.value = new TextDecoder('utf-8', { fatal: false }).decode(view)\n } catch (err) {\n if ((err as { name?: string })?.name === 'AbortError') return\n emit('error', err)\n } finally {\n loading.value = false\n }\n}\n\nwatch(\n () => props.file,\n () => load(),\n { immediate: true }\n)\n\nonBeforeUnmount(() => {\n controller?.abort()\n text.value = ''\n})\n</script>\n"],"mappings":";;;;;;;;;;;;;EAmBA,MAAM,QAAQ;EASd,MAAM,OAAO;EAEb,MAAM,MAAM,IAAI,aAAa;EAE7B,MAAM,OAAO,WAAW,EAAE;EAC1B,MAAM,YAAY,IAAI,KAAK;EAC3B,MAAM,UAAU,IAAI,IAAI;EAExB,IAAI;EAEJ,SAAS,SAAS,OAAuB;GACvC,IAAI,SAAS,OAAO,MAAM,OAAO,IAAI,QAAQ,OAAO,MAAM,QAAQ,CAAC,EAAE;GACrE,OAAO,IAAI,QAAQ,MAAM,QAAQ,CAAC,EAAE;EACtC;EAEA,eAAe,OAAO;GACpB,YAAY,MAAM;GAClB,aAAa,IAAI,gBAAgB;GACjC,QAAQ,QAAQ;GAChB,UAAU,QAAQ;GAClB,KAAK,QAAQ;GAEb,IAAI;IACF,MAAM,EAAE,kBAAkB,MAAM,OAAO;IACvC,MAAM,MAAM,MAAM,cAAc,MAAM,KAAK,KAAK,WAAW,MAAM;IACjE,MAAM,MAAM,MAAM;IAClB,MAAM,OAAO,MAAM,KAAK,IAAI,aAAa,MAAM,IAAI,WAAW,KAAK,GAAG,GAAG,IAAI,IAAI,WAAW,GAAG;IAC/F,UAAU,QAAQ,MAAM,KAAK,IAAI,aAAa;IAC9C,KAAK,QAAQ,IAAI,YAAY,SAAS,EAAE,OAAO,MAAM,CAAC,EAAE,OAAO,IAAI;GACrE,SAAS,KAAK;IACZ,IAAK,KAA2B,SAAS,cAAc;IACvD,KAAK,SAAS,GAAG;GACnB,UAAU;IACR,QAAQ,QAAQ;GAClB;EACF;EAEA,YACQ,MAAM,YACN,KAAK,GACX,EAAE,WAAW,KAAK,CACpB;EAEA,sBAAsB;GACpB,YAAY,MAAM;GAClB,KAAK,QAAQ;EACf,CAAC;;uBAzEC,YAMW,MAAA,WAAA,GAAA;IAND,KAAI;IAAO,OAAK,eAAE,MAAA,GAAA,EAAI,EAAC,MAAA,CAAA;;2BAGzB;KAFK,UAAA,SAAA,UAAA,GAAX,mBAEM,OAAA;;MAFiB,OAAK,eAAE,MAAA,GAAA,EAAI,EAAC,YAAA,CAAA;QAAgB,kBACrC,gBAAG,SAAS,QAAA,QAAQ,CAAA,GAAA,CAAA,KAAA,mBAAA,QAAA,IAAA;KAElC,mBAA6D,OAAA,EAAvD,OAAK,eAAE,MAAA,GAAA,EAAI,EAAC,UAAA,CAAA,EAAA,GAAA,CAAc,mBAAuB,QAAA,MAAA,gBAAd,KAAA,KAAI,GAAA,CAAA,CAAA,GAAA,CAAA;KAClC,QAAA,SAAA,UAAA,GAAX,mBAAwD,OAAA;;MAAnC,OAAK,eAAE,MAAA,GAAA,EAAI,EAAC,SAAA,CAAA;QAAa,QAAI,CAAA,KAAA,mBAAA,QAAA,IAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"video-previewer.js","names":[],"sources":["../../../../src/components/file-viewer/previewers/video-previewer.vue"],"sourcesContent":["<template>\n <div :class=\"cls.e('video')\">\n <video\n v-if=\"url\"\n ref=\"videoRef\"\n :src=\"url\"\n :type=\"file.mime\"\n controls\n preload=\"metadata\"\n playsinline\n @error=\"onVideoError\"\n />\n </div>\n</template>\n\n<script lang=\"ts\" setup>\nimport { bem } from '@veltra/utils'\nimport { onBeforeUnmount, shallowRef, useTemplateRef, watch } from 'vue'\n\nimport type { FileViewerItem } from '../../../types/file-viewer'\nimport { toBlobUrl } from '../helper'\n\ndefineOptions({ name: 'FileViewerVideoPreviewer' })\n\nconst props = defineProps<{ file: FileViewerItem }>()\n\nconst emit = defineEmits<{ (e: 'error', err: unknown): void }>()\n\nconst cls = bem('file-viewer')\n\nconst url = shallowRef<string>('')\nconst videoRef = useTemplateRef<HTMLVideoElement>('videoRef')\n\nlet revoke: (() => void) | undefined\nlet unmounting = false\n\nfunction load() {\n revoke?.()\n const r = toBlobUrl(props.file.src, props.file.mime)\n url.value = r.url\n revoke = r.revoke\n}\n\nfunction onVideoError(e: Event) {\n if (unmounting) return\n const v = e.target as HTMLVideoElement | null\n if (!v?.src) return\n emit('error', e)\n}\n\nwatch(\n () => props.file,\n () => load(),\n { immediate: true }\n)\n\nonBeforeUnmount(() => {\n unmounting = true\n const v = videoRef.value\n if (v) {\n v.pause()\n v.removeAttribute('src')\n try {\n v.load()\n } catch {\n /* noop */\n }\n }\n revoke?.()\n url.value = ''\n})\n</script>\n"],"mappings":";;;;;;;;;;;EAwBA,MAAM,QAAQ;EAEd,MAAM,OAAO;EAEb,MAAM,MAAM,IAAI,
|
|
1
|
+
{"version":3,"file":"video-previewer.js","names":[],"sources":["../../../../src/components/file-viewer/previewers/video-previewer.vue"],"sourcesContent":["<template>\n <div :class=\"cls.e('video')\">\n <video\n v-if=\"url\"\n ref=\"videoRef\"\n :src=\"url\"\n :type=\"file.mime\"\n controls\n preload=\"metadata\"\n playsinline\n @error=\"onVideoError\"\n />\n </div>\n</template>\n\n<script lang=\"ts\" setup>\nimport { bem } from '@veltra/utils'\nimport { onBeforeUnmount, shallowRef, useTemplateRef, watch } from 'vue'\n\nimport type { FileViewerItem } from '../../../types/file-viewer'\nimport { toBlobUrl } from '../helper'\n\ndefineOptions({ name: 'FileViewerVideoPreviewer' })\n\nconst props = defineProps<{ file: FileViewerItem }>()\n\nconst emit = defineEmits<{ (e: 'error', err: unknown): void }>()\n\nconst cls = bem('file-viewer')\n\nconst url = shallowRef<string>('')\nconst videoRef = useTemplateRef<HTMLVideoElement>('videoRef')\n\nlet revoke: (() => void) | undefined\nlet unmounting = false\n\nfunction load() {\n revoke?.()\n const r = toBlobUrl(props.file.src, props.file.mime)\n url.value = r.url\n revoke = r.revoke\n}\n\nfunction onVideoError(e: Event) {\n if (unmounting) return\n const v = e.target as HTMLVideoElement | null\n if (!v?.src) return\n emit('error', e)\n}\n\nwatch(\n () => props.file,\n () => load(),\n { immediate: true }\n)\n\nonBeforeUnmount(() => {\n unmounting = true\n const v = videoRef.value\n if (v) {\n v.pause()\n v.removeAttribute('src')\n try {\n v.load()\n } catch {\n /* noop */\n }\n }\n revoke?.()\n url.value = ''\n})\n</script>\n"],"mappings":";;;;;;;;;;;EAwBA,MAAM,QAAQ;EAEd,MAAM,OAAO;EAEb,MAAM,MAAM,IAAI,aAAa;EAE7B,MAAM,MAAM,WAAmB,EAAE;EACjC,MAAM,WAAW,eAAiC,UAAU;EAE5D,IAAI;EACJ,IAAI,aAAa;EAEjB,SAAS,OAAO;GACd,SAAS;GACT,MAAM,IAAI,UAAU,MAAM,KAAK,KAAK,MAAM,KAAK,IAAI;GACnD,IAAI,QAAQ,EAAE;GACd,SAAS,EAAE;EACb;EAEA,SAAS,aAAa,GAAU;GAC9B,IAAI,YAAY;GAEhB,IAAI,CADM,EAAE,QACJ,KAAK;GACb,KAAK,SAAS,CAAC;EACjB;EAEA,YACQ,MAAM,YACN,KAAK,GACX,EAAE,WAAW,KAAK,CACpB;EAEA,sBAAsB;GACpB,aAAa;GACb,MAAM,IAAI,SAAS;GACnB,IAAI,GAAG;IACL,EAAE,MAAM;IACR,EAAE,gBAAgB,KAAK;IACvB,IAAI;KACF,EAAE,KAAK;IACT,QAAQ,CAER;GACF;GACA,SAAS;GACT,IAAI,QAAQ;EACd,CAAC;;uBArEC,mBAWM,OAAA,EAXA,OAAK,eAAE,MAAA,GAAA,EAAI,EAAC,OAAA,CAAA,EAAA,GAAA,CAER,IAAA,SAAA,UAAA,GADR,mBASE,SAAA;;aAPI;IAAJ,KAAI;IACH,KAAK,IAAA;IACL,MAAM,QAAA,KAAK;IACZ,UAAA;IACA,SAAQ;IACR,aAAA;IACC,SAAO"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"float-button.js","names":[],"sources":["../../../src/components/float-button/float-button.vue"],"sourcesContent":["<template>\n <Teleport to=\"body\">\n <div\n :class=\"cls.b\"\n @mouseenter=\"handleMouseEnter\"\n @mouseleave=\"handleMouseLeave\"\n ref=\"floatButtonRef\"\n >\n <u-button\n v-for=\"(item, index) of items\"\n :key=\"item.key\"\n :class=\"[cls.e('item'), bem.is('first', index === 0)]\"\n circle\n :size=\"size\"\n :type=\"item.type ?? 'primary'\"\n ref=\"itemsRef\"\n :style=\"{ transitionDelay: index * 0.1 + 's' }\"\n @transitionend=\"handleTransitionEnd(index, $event)\"\n @click=\"emit('click', item.key)\"\n :title=\"item.name ?? item.key\"\n >\n <u-icon v-if=\"item.icon\"> <component :is=\"item.icon\" /> </u-icon>\n <span v-else>{{ item.name?.[0] ?? item.key[0] }}</span>\n </u-button>\n </div>\n </Teleport>\n</template>\n\n<script lang=\"ts\" setup>\nimport { bem, removeStyles, setStyles } from '@veltra/utils'\nimport { shallowRef } from 'vue'\n\nimport type { FloatButtonProps, FloatButtonEmits, ButtonExposed } from '../../types'\nimport { UButton } from '../button'\nimport { UIcon } from '../icon'\n\ndefineOptions({ name: 'FloatButton' })\n\ndefineProps<FloatButtonProps>()\n\nconst emit = defineEmits<FloatButtonEmits>()\n\nconst cls = bem('float-button')\nconst hoveredCls = bem.is('hovered')\n\nconst floatButtonRef = shallowRef<HTMLElement>()\nconst itemsRef = shallowRef<ButtonExposed[]>()\n\nconst hovered = shallowRef(false)\n\nconst handleMouseEnter = () => {\n hovered.value = true\n\n itemsRef.value?.forEach((item) => {\n setStyles(item.el!, { display: 'flex' })\n })\n\n requestAnimationFrame(() => {\n requestAnimationFrame(() => {\n itemsRef.value?.forEach((item) => {\n item.el!.classList.add(hoveredCls)\n })\n })\n })\n}\nconst handleMouseLeave = () => {\n hovered.value = false\n itemsRef.value?.forEach((item) => {\n item.el!.classList.remove(hoveredCls)\n })\n}\n\n/**\n * 动画结束回调\n * @param index 发生的元素索引\n * @param e 事件\n */\nconst handleTransitionEnd = (index: number, e: TransitionEvent) => {\n if (index !== 1 || hovered.value) return\n\n itemsRef.value?.forEach((item) => {\n removeStyles(item.el!, ['display'])\n })\n}\n</script>\n"],"mappings":";;;;;;;;;;;;;;;EAwCA,MAAM,OAAO;EAEb,MAAM,MAAM,IAAI,
|
|
1
|
+
{"version":3,"file":"float-button.js","names":[],"sources":["../../../src/components/float-button/float-button.vue"],"sourcesContent":["<template>\n <Teleport to=\"body\">\n <div\n :class=\"cls.b\"\n @mouseenter=\"handleMouseEnter\"\n @mouseleave=\"handleMouseLeave\"\n ref=\"floatButtonRef\"\n >\n <u-button\n v-for=\"(item, index) of items\"\n :key=\"item.key\"\n :class=\"[cls.e('item'), bem.is('first', index === 0)]\"\n circle\n :size=\"size\"\n :type=\"item.type ?? 'primary'\"\n ref=\"itemsRef\"\n :style=\"{ transitionDelay: index * 0.1 + 's' }\"\n @transitionend=\"handleTransitionEnd(index, $event)\"\n @click=\"emit('click', item.key)\"\n :title=\"item.name ?? item.key\"\n >\n <u-icon v-if=\"item.icon\"> <component :is=\"item.icon\" /> </u-icon>\n <span v-else>{{ item.name?.[0] ?? item.key[0] }}</span>\n </u-button>\n </div>\n </Teleport>\n</template>\n\n<script lang=\"ts\" setup>\nimport { bem, removeStyles, setStyles } from '@veltra/utils'\nimport { shallowRef } from 'vue'\n\nimport type { FloatButtonProps, FloatButtonEmits, ButtonExposed } from '../../types'\nimport { UButton } from '../button'\nimport { UIcon } from '../icon'\n\ndefineOptions({ name: 'FloatButton' })\n\ndefineProps<FloatButtonProps>()\n\nconst emit = defineEmits<FloatButtonEmits>()\n\nconst cls = bem('float-button')\nconst hoveredCls = bem.is('hovered')\n\nconst floatButtonRef = shallowRef<HTMLElement>()\nconst itemsRef = shallowRef<ButtonExposed[]>()\n\nconst hovered = shallowRef(false)\n\nconst handleMouseEnter = () => {\n hovered.value = true\n\n itemsRef.value?.forEach((item) => {\n setStyles(item.el!, { display: 'flex' })\n })\n\n requestAnimationFrame(() => {\n requestAnimationFrame(() => {\n itemsRef.value?.forEach((item) => {\n item.el!.classList.add(hoveredCls)\n })\n })\n })\n}\nconst handleMouseLeave = () => {\n hovered.value = false\n itemsRef.value?.forEach((item) => {\n item.el!.classList.remove(hoveredCls)\n })\n}\n\n/**\n * 动画结束回调\n * @param index 发生的元素索引\n * @param e 事件\n */\nconst handleTransitionEnd = (index: number, e: TransitionEvent) => {\n if (index !== 1 || hovered.value) return\n\n itemsRef.value?.forEach((item) => {\n removeStyles(item.el!, ['display'])\n })\n}\n</script>\n"],"mappings":";;;;;;;;;;;;;;;EAwCA,MAAM,OAAO;EAEb,MAAM,MAAM,IAAI,cAAc;EAC9B,MAAM,aAAa,IAAI,GAAG,SAAS;EAEnC,MAAM,iBAAiB,WAAwB;EAC/C,MAAM,WAAW,WAA4B;EAE7C,MAAM,UAAU,WAAW,KAAK;EAEhC,MAAM,yBAAyB;GAC7B,QAAQ,QAAQ;GAEhB,SAAS,OAAO,SAAS,SAAS;IAChC,UAAU,KAAK,IAAK,EAAE,SAAS,OAAO,CAAC;GACzC,CAAC;GAED,4BAA4B;IAC1B,4BAA4B;KAC1B,SAAS,OAAO,SAAS,SAAS;MAChC,KAAK,GAAI,UAAU,IAAI,UAAU;KACnC,CAAC;IACH,CAAC;GACH,CAAC;EACH;EACA,MAAM,yBAAyB;GAC7B,QAAQ,QAAQ;GAChB,SAAS,OAAO,SAAS,SAAS;IAChC,KAAK,GAAI,UAAU,OAAO,UAAU;GACtC,CAAC;EACH;;;;;;EAOA,MAAM,uBAAuB,OAAe,MAAuB;GACjE,IAAI,UAAU,KAAK,QAAQ,OAAO;GAElC,SAAS,OAAO,SAAS,SAAS;IAChC,aAAa,KAAK,IAAK,CAAC,SAAS,CAAC;GACpC,CAAC;EACH;;uBAlFE,YAwBW,UAAA,EAxBD,IAAG,OAAM,GAAA,CACjB,mBAsBM,OAAA;IArBH,OAAK,eAAE,MAAA,GAAA,EAAI,CAAC;IACZ,cAAY;IACZ,cAAY;aACT;IAAJ,KAAI;yBAEJ,mBAeW,UAAA,MAAA,WAde,QAAA,QAAhB,MAAM,UAAK;wBADrB,YAeW,MAAA,WAAA,GAAA;KAbR,KAAK,KAAK;KACV,OAAK,eAAA,CAAG,MAAA,GAAA,EAAI,EAAC,MAAA,GAAU,MAAA,GAAA,EAAI,GAAE,SAAU,UAAK,CAAA,CAAA,CAAA;KAC7C,QAAA;KACC,MAAM,QAAA;KACN,MAAM,KAAK,QAAI;;cACZ;KAAJ,KAAI;KACH,OAAK,eAAA,EAAA,iBAAqB,QAAK,KAAA,IAAA,CAAA;KAC/B,kBAAa,WAAE,oBAAoB,OAAO,MAAM;KAChD,UAAK,WAAE,KAAI,SAAU,KAAK,GAAG;KAC7B,OAAO,KAAK,QAAQ,KAAK;;4BAEuC,CAAnD,KAAK,QAAA,UAAA,GAAnB,YAAiE,MAAA,WAAA,GAAA,EAAA,KAAA,EAAA,GAAA;6BAAV,EAAA,UAAA,GAA7B,YAA6B,wBAAb,KAAK,IAAI,CAAA,EAAA,CAAA;;+BACnD,mBAAuD,QAAA,YAAA,gBAAvC,KAAK,OAAI,MAAS,KAAK,IAAG,EAAA,GAAA,CAAA,EAAA,CAAA"}
|
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
import { FloatButtonProps } from "../../types/float-button.js";
|
|
2
|
-
import * as _$vue from "vue";
|
|
3
|
-
|
|
4
2
|
//#region src/components/float-button/float-button.vue.d.ts
|
|
5
|
-
declare const __VLS_export:
|
|
3
|
+
declare const __VLS_export: import("vue").DefineComponent<FloatButtonProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
|
|
6
4
|
click: (key: string) => any;
|
|
7
|
-
}, string,
|
|
5
|
+
}, string, import("vue").PublicProps, Readonly<FloatButtonProps> & Readonly<{
|
|
8
6
|
onClick?: ((key: string) => any) | undefined;
|
|
9
|
-
}>, {}, {}, {}, {}, string,
|
|
7
|
+
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
10
8
|
declare const _default: typeof __VLS_export;
|
|
11
9
|
//#endregion
|
|
12
10
|
export { _default };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dynamic-form-model.js","names":[],"sources":["../../../src/components/form/dynamic-form-model.ts"],"sourcesContent":["import { o } from '@cat-kit/core'\nimport { Validator } from '@veltra/utils'\nimport { isReactive, reactive, shallowReactive, watch } from 'vue'\n\nimport type { FormModelField, FormModelItem, DataSettingConfig } from '../../types'\n\nfunction flattenFields(fields: Record<string, any>, prefix = ''): Record<string, FormModelItem> {\n const result: Record<string, FormModelItem> = {}\n for (const key in fields) {\n const item = fields[key]\n const fullPath = prefix ? `${prefix}.${key}` : key\n if (item && typeof item === 'object' && '__isNested' in item && item.__isNested) {\n Object.assign(result, flattenFields((item as any).fields, fullPath))\n } else {\n result[fullPath] = item\n }\n }\n return result\n}\n\n/**\n * 动态表单模型\n */\nexport class DynamicFormModel {\n /** 表单数据 */\n private _data: Record<string, any> = reactive({})\n\n set data(v: Record<string, any>) {\n if (!isReactive(v)) {\n console.error(`data不是一个响应式对象`)\n return\n }\n this._data = v\n this.watchData()\n }\n\n get data() {\n return this._data\n }\n\n /** 表单规则 */\n readonly fields: Record<string, FormModelField> = shallowReactive(\n {} as Record<string, FormModelField>\n )\n\n private flatFields: Record<string, FormModelItem>\n\n private validator: Validator\n\n /**\n * 不同表单对应的key\n */\n formKeys: Map<number, string[]> = new Map()\n\n readonly errors: Map<string, string[] | undefined> = shallowReactive(new Map())\n\n /**\n * 是否在表单值更新时校验\n */\n private validateOnFieldChange = true\n\n private modelChangeCallback: Set<(fields: string, val: any) => void> = new Set()\n\n private _allKeys: string[] = []\n\n /** 所有的键 */\n get allKeys(): string[] {\n return this._allKeys\n }\n\n private updateFlatFields(): void {\n for (const key in this.flatFields) {\n delete this.flatFields[key]\n }\n const flatted = flattenFields(this.fields)\n Object.assign(this.flatFields, flatted)\n this.getAllKeys()\n }\n\n private getAllKeys(): void {\n this._allKeys = Object.keys(this.flatFields)\n }\n\n /** 初始数据 */\n readonly initialData: Record<string, any> = {}\n\n /**\n * 变更前的值\n */\n private readonly oldData: Record<string, any> = {}\n\n constructor(fields?: Record<string, FormModelField>) {\n this.flatFields = shallowReactive({} as Record<string, FormModelItem>)\n this.validator = new Validator(this.flatFields)\n this.append(fields ?? {})\n this.watchData()\n }\n\n private watchData(): void {\n const { oldData } = this\n watch(this.data, (data) => {\n let changedKeys: string[] = []\n\n this.allKeys.forEach((key) => {\n const oldVal = o(oldData).get(key)\n const newVal = o(data).get(key)\n if (oldVal !== newVal) {\n this.modelChangeCallback.forEach((cb) => cb(key, newVal))\n changedKeys.push(key)\n o(oldData).set(key, newVal)\n }\n })\n\n if (this.validateOnFieldChange) {\n this.validate(changedKeys)\n } else {\n this.validateOnFieldChange = true\n }\n })\n }\n\n append(fields: Record<string, FormModelField>): void {\n for (const key in fields) {\n this.add(key, fields[key]!)\n }\n }\n\n /**\n * 添加字段\n * @param field 字段\n * @param item 字段配置项\n */\n add(field: string, item: FormModelField): void {\n this.fields[field] = item\n const flatItem = flattenFields({ [field]: item })\n for (const key in flatItem) {\n const fieldItem = flatItem[key]!\n const { value } = fieldItem\n const v = typeof value === 'function' ? value() : value\n if (v !== undefined) {\n o(this.initialData).set(key, JSON.parse(JSON.stringify(v)))\n }\n o(this.data).set(key, v)\n o(this.oldData).set(key, v)\n }\n this.updateFlatFields()\n }\n\n /**\n * 移除字段\n * @param field 字段\n */\n delete(field: string): void {\n delete this.fields[field]\n this.updateFlatFields()\n }\n\n /**\n * 监听值变更\n * @param cb 回调\n */\n onChange(cb: (field: string, val: any) => void): void {\n this.modelChangeCallback.add(cb)\n }\n\n offChange(cb: (field: string, val: any) => void): void {\n this.modelChangeCallback.delete(cb)\n }\n\n async validate(fields?: string | string[]): Promise<boolean> {\n const { errors, validator, data } = this\n\n const results = await validator.validate(data, this.getValidateFields(fields))\n\n // 设置错误提示\n if (!fields) {\n errors.clear()\n for (const field in results) {\n errors.set(field, results[field])\n }\n } else {\n ~(Array.isArray(fields) ? fields : [fields]).forEach((field) => {\n const errs = results[field]\n if (errs?.length) {\n errors.set(field, errs)\n } else {\n errors.delete(field)\n }\n })\n }\n\n return errors.size === 0\n }\n\n private getValidateFields(fields?: string | string[]) {\n if (!fields) {\n if (this.formKeys.size) {\n let _fields: string[] = []\n this.formKeys.forEach((fields) => {\n _fields = _fields.concat(fields)\n })\n return _fields\n } else {\n return this.allKeys\n }\n }\n\n if (!Array.isArray(fields)) {\n return [fields]\n }\n return fields\n }\n\n /**\n * 重置数据\n * @param fields 需要重置的字段\n */\n resetData(keys?: string | string[]): void {\n if (typeof keys === 'string') {\n keys = [keys]\n } else if (Array.isArray(keys)) {\n } else {\n keys = this.allKeys\n }\n\n this.clearValidate()\n\n this.validateOnFieldChange = false\n\n keys.forEach((field) => {\n o(this.data).set(field as string, o(this.initialData).get(field as string))\n })\n }\n\n /**\n * 设置值\n * @param formData 表单值\n * @param options 配置\n */\n setData(formData: Record<string, any>, config?: DataSettingConfig): void {\n const { validate = true } = config || {}\n\n if (!validate) {\n this.validateOnFieldChange = false\n }\n\n this.allKeys.forEach((key) => {\n const value = o(formData).get(key)\n if (value !== undefined) {\n o(this.data).set(key, value)\n }\n })\n }\n\n clearValidate(): void {\n this.errors.clear()\n }\n}\n"],"mappings":";;;;AAMA,SAAS,cAAc,QAA6B,SAAS,IAAmC;CAC9F,MAAM,SAAwC,
|
|
1
|
+
{"version":3,"file":"dynamic-form-model.js","names":[],"sources":["../../../src/components/form/dynamic-form-model.ts"],"sourcesContent":["import { o } from '@cat-kit/core'\nimport { Validator } from '@veltra/utils'\nimport { isReactive, reactive, shallowReactive, watch } from 'vue'\n\nimport type { FormModelField, FormModelItem, DataSettingConfig } from '../../types'\n\nfunction flattenFields(fields: Record<string, any>, prefix = ''): Record<string, FormModelItem> {\n const result: Record<string, FormModelItem> = {}\n for (const key in fields) {\n const item = fields[key]\n const fullPath = prefix ? `${prefix}.${key}` : key\n if (item && typeof item === 'object' && '__isNested' in item && item.__isNested) {\n Object.assign(result, flattenFields((item as any).fields, fullPath))\n } else {\n result[fullPath] = item\n }\n }\n return result\n}\n\n/**\n * 动态表单模型\n */\nexport class DynamicFormModel {\n /** 表单数据 */\n private _data: Record<string, any> = reactive({})\n\n set data(v: Record<string, any>) {\n if (!isReactive(v)) {\n console.error(`data不是一个响应式对象`)\n return\n }\n this._data = v\n this.watchData()\n }\n\n get data() {\n return this._data\n }\n\n /** 表单规则 */\n readonly fields: Record<string, FormModelField> = shallowReactive(\n {} as Record<string, FormModelField>\n )\n\n private flatFields: Record<string, FormModelItem>\n\n private validator: Validator\n\n /**\n * 不同表单对应的key\n */\n formKeys: Map<number, string[]> = new Map()\n\n readonly errors: Map<string, string[] | undefined> = shallowReactive(new Map())\n\n /**\n * 是否在表单值更新时校验\n */\n private validateOnFieldChange = true\n\n private modelChangeCallback: Set<(fields: string, val: any) => void> = new Set()\n\n private _allKeys: string[] = []\n\n /** 所有的键 */\n get allKeys(): string[] {\n return this._allKeys\n }\n\n private updateFlatFields(): void {\n for (const key in this.flatFields) {\n delete this.flatFields[key]\n }\n const flatted = flattenFields(this.fields)\n Object.assign(this.flatFields, flatted)\n this.getAllKeys()\n }\n\n private getAllKeys(): void {\n this._allKeys = Object.keys(this.flatFields)\n }\n\n /** 初始数据 */\n readonly initialData: Record<string, any> = {}\n\n /**\n * 变更前的值\n */\n private readonly oldData: Record<string, any> = {}\n\n constructor(fields?: Record<string, FormModelField>) {\n this.flatFields = shallowReactive({} as Record<string, FormModelItem>)\n this.validator = new Validator(this.flatFields)\n this.append(fields ?? {})\n this.watchData()\n }\n\n private watchData(): void {\n const { oldData } = this\n watch(this.data, (data) => {\n let changedKeys: string[] = []\n\n this.allKeys.forEach((key) => {\n const oldVal = o(oldData).get(key)\n const newVal = o(data).get(key)\n if (oldVal !== newVal) {\n this.modelChangeCallback.forEach((cb) => cb(key, newVal))\n changedKeys.push(key)\n o(oldData).set(key, newVal)\n }\n })\n\n if (this.validateOnFieldChange) {\n this.validate(changedKeys)\n } else {\n this.validateOnFieldChange = true\n }\n })\n }\n\n append(fields: Record<string, FormModelField>): void {\n for (const key in fields) {\n this.add(key, fields[key]!)\n }\n }\n\n /**\n * 添加字段\n * @param field 字段\n * @param item 字段配置项\n */\n add(field: string, item: FormModelField): void {\n this.fields[field] = item\n const flatItem = flattenFields({ [field]: item })\n for (const key in flatItem) {\n const fieldItem = flatItem[key]!\n const { value } = fieldItem\n const v = typeof value === 'function' ? value() : value\n if (v !== undefined) {\n o(this.initialData).set(key, JSON.parse(JSON.stringify(v)))\n }\n o(this.data).set(key, v)\n o(this.oldData).set(key, v)\n }\n this.updateFlatFields()\n }\n\n /**\n * 移除字段\n * @param field 字段\n */\n delete(field: string): void {\n delete this.fields[field]\n this.updateFlatFields()\n }\n\n /**\n * 监听值变更\n * @param cb 回调\n */\n onChange(cb: (field: string, val: any) => void): void {\n this.modelChangeCallback.add(cb)\n }\n\n offChange(cb: (field: string, val: any) => void): void {\n this.modelChangeCallback.delete(cb)\n }\n\n async validate(fields?: string | string[]): Promise<boolean> {\n const { errors, validator, data } = this\n\n const results = await validator.validate(data, this.getValidateFields(fields))\n\n // 设置错误提示\n if (!fields) {\n errors.clear()\n for (const field in results) {\n errors.set(field, results[field])\n }\n } else {\n ~(Array.isArray(fields) ? fields : [fields]).forEach((field) => {\n const errs = results[field]\n if (errs?.length) {\n errors.set(field, errs)\n } else {\n errors.delete(field)\n }\n })\n }\n\n return errors.size === 0\n }\n\n private getValidateFields(fields?: string | string[]) {\n if (!fields) {\n if (this.formKeys.size) {\n let _fields: string[] = []\n this.formKeys.forEach((fields) => {\n _fields = _fields.concat(fields)\n })\n return _fields\n } else {\n return this.allKeys\n }\n }\n\n if (!Array.isArray(fields)) {\n return [fields]\n }\n return fields\n }\n\n /**\n * 重置数据\n * @param fields 需要重置的字段\n */\n resetData(keys?: string | string[]): void {\n if (typeof keys === 'string') {\n keys = [keys]\n } else if (Array.isArray(keys)) {\n } else {\n keys = this.allKeys\n }\n\n this.clearValidate()\n\n this.validateOnFieldChange = false\n\n keys.forEach((field) => {\n o(this.data).set(field as string, o(this.initialData).get(field as string))\n })\n }\n\n /**\n * 设置值\n * @param formData 表单值\n * @param options 配置\n */\n setData(formData: Record<string, any>, config?: DataSettingConfig): void {\n const { validate = true } = config || {}\n\n if (!validate) {\n this.validateOnFieldChange = false\n }\n\n this.allKeys.forEach((key) => {\n const value = o(formData).get(key)\n if (value !== undefined) {\n o(this.data).set(key, value)\n }\n })\n }\n\n clearValidate(): void {\n this.errors.clear()\n }\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"form-model.js","names":[],"sources":["../../../src/components/form/form-model.ts"],"sourcesContent":["import { o } from '@cat-kit/core'\nimport { middleProxy, Validator } from '@veltra/utils'\nimport { nextTick, reactive, shallowReactive, watch, type Reactive } from 'vue'\n\nimport type {\n ModelData,\n DataSettingConfig,\n IFormModel,\n FormModelItem,\n FormModelField\n} from '../../types'\n\n/**\n * 递归展平字段逻辑\n */\nfunction flattenFields(fields: Record<string, any>, prefix = ''): Record<string, FormModelItem> {\n const result: Record<string, FormModelItem> = {}\n for (const key in fields) {\n const item = fields[key]\n const fullPath = prefix ? `${prefix}.${key}` : key\n if (item && typeof item === 'object' && '__isNested' in item && item.__isNested) {\n Object.assign(result, flattenFields((item as any).fields, fullPath))\n } else {\n result[fullPath] = item\n }\n }\n return result\n}\n\n/**\n * 表单模型\n */\nexport class FormModel<\n Fields extends Record<string, FormModelField> = Record<string, FormModelField>\n> implements IFormModel<Fields> {\n /** 表单数据 */\n data!: ModelData<Fields>\n\n /** 表单规则 */\n readonly fields: Fields\n\n /** 所有的键 */\n readonly allKeys: string[]\n\n /**\n * 不同表单所需要校验的字段\n * @description\n * 这个值会在表单组件渲染时由表单设置,因为只有真正渲染的组件才应该被校验\n */\n formKeys: Map<number, string[]> = new Map()\n\n /** 初始数据 */\n readonly initialData: ModelData<Fields>\n\n readonly errors: Map<string, string[] | undefined> = shallowReactive(new Map())\n\n private validator: Validator<Record<string, FormModelItem>>\n\n /**\n * 是否在表单值更新时校验\n */\n private validateOnFieldChange = true\n\n private modelChangeCallback: Set<(fields: string, val: any) => void> = new Set()\n\n constructor(fields: Fields) {\n this.fields = fields\n const flatFields = flattenFields(fields)\n const rawData = {} as ModelData<Fields>\n const allKeys: string[] = []\n\n for (const key in flatFields) {\n const fieldItem = flatFields[key]!\n allKeys.push(key)\n const { value } = fieldItem\n let v = value\n\n if (typeof value === 'function') {\n watch(value, (v) => {\n o(this.initialData).set(key, v)\n })\n v = value()\n }\n\n o(rawData).set(key, v)\n }\n\n this.allKeys = allKeys\n this.initialData = JSON.parse(JSON.stringify(rawData))\n\n this.setProxyData(reactive(rawData))\n\n this.validator = new Validator(flatFields)\n\n return shallowReactive(this)\n }\n\n /**\n * 设置响应式值, 替换掉原有的数据\n * @description 设置响应式值时,会自动监听值的变化,并进行校验\n * @param proxyData 响应式的值\n */\n setProxyData(proxyData: ModelData<Fields> | Reactive<ModelData<Fields>>): void {\n const data = middleProxy(proxyData, {\n set: (field, val) => {\n this.modelChangeCallback.forEach((cb) => cb(field, val))\n },\n\n changed: (fields) => {\n if (!this.validateOnFieldChange) {\n this.validateOnFieldChange = true\n return\n }\n this.validate(fields as any)\n }\n })\n\n this.data = data as ModelData<Fields>\n }\n\n private getValidateFields(fields?: string | string[]) {\n if (!fields) {\n if (this.formKeys.size) {\n let _fields: string[] = []\n this.formKeys.forEach((keys) => {\n _fields = _fields.concat(keys)\n })\n return _fields\n } else {\n return this.allKeys\n }\n }\n\n if (!Array.isArray(fields)) {\n return [fields]\n }\n return fields\n }\n\n /**\n * 模型校验\n * @param fields 需要校验的字段, 不传则校验所有字段\n * @returns\n */\n async validate(fields?: string | string[]): Promise<boolean> {\n const { errors, validator, data } = this\n\n const results = await validator.validate(data, this.getValidateFields(fields))\n\n // 全量校验\n if (!fields) {\n errors.clear()\n\n for (const field in results) {\n errors.set(field as any, results[field])\n }\n }\n // 局部校验\n else {\n ~(Array.isArray(fields) ? fields : [fields]).forEach((field) => {\n const errs = results[field as string]\n if (errs?.length) {\n errors.set(field, errs)\n } else {\n errors.delete(field)\n }\n })\n }\n\n if (errors.size > 0) {\n if (!fields) {\n nextTick(() => {\n document.querySelector('.u-form-item.is-error')?.scrollIntoView({ block: 'nearest' })\n })\n }\n return Promise.reject(false)\n }\n\n return true\n }\n\n /**\n * 重置数据\n * @param fields 需要重置的字段\n */\n resetData(keys?: string | string[]): void {\n if (typeof keys === 'string') {\n keys = [keys]\n } else if (Array.isArray(keys)) {\n } else {\n keys = this.allKeys\n }\n\n this.clearValidate()\n\n this.validateOnFieldChange = false\n\n keys.forEach((field) => {\n o(this.data).set(field as string, o(this.initialData).get(field as string))\n })\n }\n\n /**\n * 设置值\n * @param formData 表单值\n * @param options 配置\n */\n setData(formData: Partial<Record<string, any>>, config?: DataSettingConfig): FormModel<Fields> {\n const { validate = true } = config || {}\n\n if (!validate) {\n this.validateOnFieldChange = false\n }\n\n this.allKeys.forEach((key) => {\n const value = o(formData).get(key)\n if (value !== undefined) {\n o(this.data).set(key, value)\n }\n })\n\n return this\n }\n\n /**\n * 设置初始值\n * @description 初始值在重置数据和查看原始数据时会用到\n * @param data 初始值\n */\n setInitialData(data: Partial<ModelData<Fields>>): FormModel<Fields> {\n this.allKeys.forEach((key) => {\n o(this.initialData).set(key, o(data).get(key))\n })\n\n return this\n }\n\n /** 清除校验 */\n clearValidate(): void {\n this.errors.clear()\n }\n\n /**\n * 监听值变更\n * @param cb 回调\n */\n onChange(cb: (field: string, val: any) => void): void {\n this.modelChangeCallback.add(cb)\n }\n\n /** 关闭监听值变更 */\n offChange(cb: (field: string, val: any) => void): void {\n this.modelChangeCallback.delete(cb)\n }\n}\n"],"mappings":";;;;;;;AAeA,SAAS,cAAc,QAA6B,SAAS,IAAmC;CAC9F,MAAM,SAAwC,
|
|
1
|
+
{"version":3,"file":"form-model.js","names":[],"sources":["../../../src/components/form/form-model.ts"],"sourcesContent":["import { o } from '@cat-kit/core'\nimport { middleProxy, Validator } from '@veltra/utils'\nimport { nextTick, reactive, shallowReactive, watch, type Reactive } from 'vue'\n\nimport type {\n ModelData,\n DataSettingConfig,\n IFormModel,\n FormModelItem,\n FormModelField\n} from '../../types'\n\n/**\n * 递归展平字段逻辑\n */\nfunction flattenFields(fields: Record<string, any>, prefix = ''): Record<string, FormModelItem> {\n const result: Record<string, FormModelItem> = {}\n for (const key in fields) {\n const item = fields[key]\n const fullPath = prefix ? `${prefix}.${key}` : key\n if (item && typeof item === 'object' && '__isNested' in item && item.__isNested) {\n Object.assign(result, flattenFields((item as any).fields, fullPath))\n } else {\n result[fullPath] = item\n }\n }\n return result\n}\n\n/**\n * 表单模型\n */\nexport class FormModel<\n Fields extends Record<string, FormModelField> = Record<string, FormModelField>\n> implements IFormModel<Fields> {\n /** 表单数据 */\n data!: ModelData<Fields>\n\n /** 表单规则 */\n readonly fields: Fields\n\n /** 所有的键 */\n readonly allKeys: string[]\n\n /**\n * 不同表单所需要校验的字段\n * @description\n * 这个值会在表单组件渲染时由表单设置,因为只有真正渲染的组件才应该被校验\n */\n formKeys: Map<number, string[]> = new Map()\n\n /** 初始数据 */\n readonly initialData: ModelData<Fields>\n\n readonly errors: Map<string, string[] | undefined> = shallowReactive(new Map())\n\n private validator: Validator<Record<string, FormModelItem>>\n\n /**\n * 是否在表单值更新时校验\n */\n private validateOnFieldChange = true\n\n private modelChangeCallback: Set<(fields: string, val: any) => void> = new Set()\n\n constructor(fields: Fields) {\n this.fields = fields\n const flatFields = flattenFields(fields)\n const rawData = {} as ModelData<Fields>\n const allKeys: string[] = []\n\n for (const key in flatFields) {\n const fieldItem = flatFields[key]!\n allKeys.push(key)\n const { value } = fieldItem\n let v = value\n\n if (typeof value === 'function') {\n watch(value, (v) => {\n o(this.initialData).set(key, v)\n })\n v = value()\n }\n\n o(rawData).set(key, v)\n }\n\n this.allKeys = allKeys\n this.initialData = JSON.parse(JSON.stringify(rawData))\n\n this.setProxyData(reactive(rawData))\n\n this.validator = new Validator(flatFields)\n\n return shallowReactive(this)\n }\n\n /**\n * 设置响应式值, 替换掉原有的数据\n * @description 设置响应式值时,会自动监听值的变化,并进行校验\n * @param proxyData 响应式的值\n */\n setProxyData(proxyData: ModelData<Fields> | Reactive<ModelData<Fields>>): void {\n const data = middleProxy(proxyData, {\n set: (field, val) => {\n this.modelChangeCallback.forEach((cb) => cb(field, val))\n },\n\n changed: (fields) => {\n if (!this.validateOnFieldChange) {\n this.validateOnFieldChange = true\n return\n }\n this.validate(fields as any)\n }\n })\n\n this.data = data as ModelData<Fields>\n }\n\n private getValidateFields(fields?: string | string[]) {\n if (!fields) {\n if (this.formKeys.size) {\n let _fields: string[] = []\n this.formKeys.forEach((keys) => {\n _fields = _fields.concat(keys)\n })\n return _fields\n } else {\n return this.allKeys\n }\n }\n\n if (!Array.isArray(fields)) {\n return [fields]\n }\n return fields\n }\n\n /**\n * 模型校验\n * @param fields 需要校验的字段, 不传则校验所有字段\n * @returns\n */\n async validate(fields?: string | string[]): Promise<boolean> {\n const { errors, validator, data } = this\n\n const results = await validator.validate(data, this.getValidateFields(fields))\n\n // 全量校验\n if (!fields) {\n errors.clear()\n\n for (const field in results) {\n errors.set(field as any, results[field])\n }\n }\n // 局部校验\n else {\n ~(Array.isArray(fields) ? fields : [fields]).forEach((field) => {\n const errs = results[field as string]\n if (errs?.length) {\n errors.set(field, errs)\n } else {\n errors.delete(field)\n }\n })\n }\n\n if (errors.size > 0) {\n if (!fields) {\n nextTick(() => {\n document.querySelector('.u-form-item.is-error')?.scrollIntoView({ block: 'nearest' })\n })\n }\n return Promise.reject(false)\n }\n\n return true\n }\n\n /**\n * 重置数据\n * @param fields 需要重置的字段\n */\n resetData(keys?: string | string[]): void {\n if (typeof keys === 'string') {\n keys = [keys]\n } else if (Array.isArray(keys)) {\n } else {\n keys = this.allKeys\n }\n\n this.clearValidate()\n\n this.validateOnFieldChange = false\n\n keys.forEach((field) => {\n o(this.data).set(field as string, o(this.initialData).get(field as string))\n })\n }\n\n /**\n * 设置值\n * @param formData 表单值\n * @param options 配置\n */\n setData(formData: Partial<Record<string, any>>, config?: DataSettingConfig): FormModel<Fields> {\n const { validate = true } = config || {}\n\n if (!validate) {\n this.validateOnFieldChange = false\n }\n\n this.allKeys.forEach((key) => {\n const value = o(formData).get(key)\n if (value !== undefined) {\n o(this.data).set(key, value)\n }\n })\n\n return this\n }\n\n /**\n * 设置初始值\n * @description 初始值在重置数据和查看原始数据时会用到\n * @param data 初始值\n */\n setInitialData(data: Partial<ModelData<Fields>>): FormModel<Fields> {\n this.allKeys.forEach((key) => {\n o(this.initialData).set(key, o(data).get(key))\n })\n\n return this\n }\n\n /** 清除校验 */\n clearValidate(): void {\n this.errors.clear()\n }\n\n /**\n * 监听值变更\n * @param cb 回调\n */\n onChange(cb: (field: string, val: any) => void): void {\n this.modelChangeCallback.add(cb)\n }\n\n /** 关闭监听值变更 */\n offChange(cb: (field: string, val: any) => void): void {\n this.modelChangeCallback.delete(cb)\n }\n}\n"],"mappings":"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"}
|
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
import { FormProps, _FormExposed } from "../../types/form.js";
|
|
2
2
|
import { DynamicFormModel } from "./dynamic-form-model.js";
|
|
3
3
|
import { FormModel } from "./form-model.js";
|
|
4
|
-
import * as _$vue from "vue";
|
|
5
4
|
|
|
6
5
|
//#region src/components/form/form.vue.d.ts
|
|
7
6
|
declare const __VLS_export: <Model extends FormModel | DynamicFormModel>(__VLS_props: NonNullable<Awaited<typeof __VLS_setup>>["props"], __VLS_ctx?: __VLS_PrettifyLocal<Pick<NonNullable<Awaited<typeof __VLS_setup>>, "attrs" | "emit" | "slots">>, __VLS_exposed?: NonNullable<Awaited<typeof __VLS_setup>>["expose"], __VLS_setup?: Promise<{
|
|
8
|
-
props:
|
|
7
|
+
props: import("vue").PublicProps & __VLS_PrettifyLocal<FormProps<Model>> & (typeof globalThis extends {
|
|
9
8
|
__VLS_PROPS_FALLBACK: infer P;
|
|
10
9
|
} ? P : {});
|
|
11
|
-
expose: (exposed:
|
|
10
|
+
expose: (exposed: import("vue").ShallowUnwrapRef<_FormExposed>) => void;
|
|
12
11
|
attrs: any;
|
|
13
12
|
slots: {
|
|
14
13
|
default(props: {
|
|
@@ -17,7 +16,7 @@ declare const __VLS_export: <Model extends FormModel | DynamicFormModel>(__VLS_p
|
|
|
17
16
|
}): any;
|
|
18
17
|
};
|
|
19
18
|
emit: {};
|
|
20
|
-
}>) =>
|
|
19
|
+
}>) => import("vue").VNode & {
|
|
21
20
|
__ctx?: Awaited<typeof __VLS_setup>;
|
|
22
21
|
};
|
|
23
22
|
declare const _default: typeof __VLS_export;
|
|
@@ -5,7 +5,7 @@ import { Fragment, createBlock, createCommentVNode, createElementBlock, createEl
|
|
|
5
5
|
import { bem, provideFormContext } from "@veltra/utils";
|
|
6
6
|
import { o } from "@cat-kit/core";
|
|
7
7
|
//#region src/components/form/form.vue?vue&type=script&setup=true&lang.tsx
|
|
8
|
-
var form_vue_vue_type_script_setup_true_lang_default =
|
|
8
|
+
var form_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineComponent({
|
|
9
9
|
name: "Form",
|
|
10
10
|
__name: "form",
|
|
11
11
|
props: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"form.vue_vue_type_script_setup_true_lang.js","names":[],"sources":["../../../src/components/form/form.vue"],"sourcesContent":["<template>\n <u-grid\n tag=\"form\"\n ref=\"gridRef\"\n @submit.prevent\n :cols=\"cols || breakpointCols\"\n :class=\"[cls.b, bem.is('readonly', readonly)]\"\n >\n <template\n v-for=\"{ node, isFormItem, formItemProps, field, modelValue } of getSlotsNodes()\"\n :key=\"node.key\"\n >\n <component v-if=\"isFormItem || !field\" :is=\"node\" />\n\n <u-form-item v-else v-bind=\"formItemProps\">\n <component\n :is=\"node\"\n :model-value=\"modelValue ?? o(model?.data ?? {}).get(field)\"\n @update:model-value=\"handleUpdateValue(field, $event)\"\n />\n\n <div :class=\"cls.e('data-before')\" v-if=\"showInitialNode(field)\">\n <i :class=\"cls.e('changed-tag')\">变更前:</i>\n\n <component :is=\"node\" readonly :model-value=\"o(model?.initialData ?? {}).get(field)\" />\n </div>\n </u-form-item>\n </template>\n </u-grid>\n</template>\n\n<script lang=\"tsx\" setup generic=\"Model extends FormModel | DynamicFormModel\">\nimport { o } from '@cat-kit/core'\nimport { bem } from '@veltra/utils'\nimport { provideFormContext } from '@veltra/utils'\nimport { shallowRef, toRef } from 'vue'\n\nimport type { BreakCols, GridExposed, FormProps, _FormExposed } from '../../types'\nimport { UFormItem } from '../form-item'\nimport { UGrid } from '../grid'\nimport type { DynamicFormModel } from './dynamic-form-model'\nimport type { FormModel } from './form-model'\nimport { useNodeInterceptor } from './use-node-interceptor'\n\ndefineOptions({ name: 'Form' })\n\nconst props = defineProps<FormProps<Model>>()\n\ndefineSlots<{\n default(props: {\n /** 表单数据 */\n data: Model['data']\n /** 表单模型 */\n model: Model\n }): any\n}>()\n\nconst cls = bem('form')\n\nconst breakpointCols: BreakCols = { xs: 1, md: 2, lg: 3, xl: 4, default: 4 }\n\nprovideFormContext(props)\n\nconst { getSlotsNodes } = useNodeInterceptor({ props })\n\nfunction handleUpdateValue(field: string, value: any) {\n const { model } = props\n if (!model) return\n o(model.data).set(field, value)\n}\n\nfunction showInitialNode(field: string) {\n const { data, initialData } = props.model || {}\n\n const currentValue = o(data ?? {}).get(field)\n const initialValue = o(initialData ?? {}).get(field)\n const notEqual = !(initialValue === currentValue || (!initialValue && !currentValue))\n\n return props.showInitialData && notEqual\n}\n\nconst gridRef = shallowRef<GridExposed>()\n\ndefineExpose<_FormExposed>({ el: toRef(() => gridRef.value?.el) })\n</script>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;EA8CA,MAAM,QAAQ;EAWd,MAAM,MAAM,IAAI,
|
|
1
|
+
{"version":3,"file":"form.vue_vue_type_script_setup_true_lang.js","names":[],"sources":["../../../src/components/form/form.vue"],"sourcesContent":["<template>\n <u-grid\n tag=\"form\"\n ref=\"gridRef\"\n @submit.prevent\n :cols=\"cols || breakpointCols\"\n :class=\"[cls.b, bem.is('readonly', readonly)]\"\n >\n <template\n v-for=\"{ node, isFormItem, formItemProps, field, modelValue } of getSlotsNodes()\"\n :key=\"node.key\"\n >\n <component v-if=\"isFormItem || !field\" :is=\"node\" />\n\n <u-form-item v-else v-bind=\"formItemProps\">\n <component\n :is=\"node\"\n :model-value=\"modelValue ?? o(model?.data ?? {}).get(field)\"\n @update:model-value=\"handleUpdateValue(field, $event)\"\n />\n\n <div :class=\"cls.e('data-before')\" v-if=\"showInitialNode(field)\">\n <i :class=\"cls.e('changed-tag')\">变更前:</i>\n\n <component :is=\"node\" readonly :model-value=\"o(model?.initialData ?? {}).get(field)\" />\n </div>\n </u-form-item>\n </template>\n </u-grid>\n</template>\n\n<script lang=\"tsx\" setup generic=\"Model extends FormModel | DynamicFormModel\">\nimport { o } from '@cat-kit/core'\nimport { bem } from '@veltra/utils'\nimport { provideFormContext } from '@veltra/utils'\nimport { shallowRef, toRef } from 'vue'\n\nimport type { BreakCols, GridExposed, FormProps, _FormExposed } from '../../types'\nimport { UFormItem } from '../form-item'\nimport { UGrid } from '../grid'\nimport type { DynamicFormModel } from './dynamic-form-model'\nimport type { FormModel } from './form-model'\nimport { useNodeInterceptor } from './use-node-interceptor'\n\ndefineOptions({ name: 'Form' })\n\nconst props = defineProps<FormProps<Model>>()\n\ndefineSlots<{\n default(props: {\n /** 表单数据 */\n data: Model['data']\n /** 表单模型 */\n model: Model\n }): any\n}>()\n\nconst cls = bem('form')\n\nconst breakpointCols: BreakCols = { xs: 1, md: 2, lg: 3, xl: 4, default: 4 }\n\nprovideFormContext(props)\n\nconst { getSlotsNodes } = useNodeInterceptor({ props })\n\nfunction handleUpdateValue(field: string, value: any) {\n const { model } = props\n if (!model) return\n o(model.data).set(field, value)\n}\n\nfunction showInitialNode(field: string) {\n const { data, initialData } = props.model || {}\n\n const currentValue = o(data ?? {}).get(field)\n const initialValue = o(initialData ?? {}).get(field)\n const notEqual = !(initialValue === currentValue || (!initialValue && !currentValue))\n\n return props.showInitialData && notEqual\n}\n\nconst gridRef = shallowRef<GridExposed>()\n\ndefineExpose<_FormExposed>({ el: toRef(() => gridRef.value?.el) })\n</script>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;EA8CA,MAAM,QAAQ;EAWd,MAAM,MAAM,IAAI,MAAM;EAEtB,MAAM,iBAA4B;GAAE,IAAI;GAAG,IAAI;GAAG,IAAI;GAAG,IAAI;GAAG,SAAS;EAAE;EAE3E,mBAAmB,KAAK;EAExB,MAAM,EAAE,kBAAkB,mBAAmB,EAAE,MAAM,CAAC;EAEtD,SAAS,kBAAkB,OAAe,OAAY;GACpD,MAAM,EAAE,UAAU;GAClB,IAAI,CAAC,OAAO;GACZ,EAAE,MAAM,IAAI,EAAE,IAAI,OAAO,KAAK;EAChC;EAEA,SAAS,gBAAgB,OAAe;GACtC,MAAM,EAAE,MAAM,gBAAgB,MAAM,SAAS,CAAC;GAE9C,MAAM,eAAe,EAAE,QAAQ,CAAC,CAAC,EAAE,IAAI,KAAK;GAC5C,MAAM,eAAe,EAAE,eAAe,CAAC,CAAC,EAAE,IAAI,KAAK;GACnD,MAAM,WAAW,EAAE,iBAAiB,gBAAiB,CAAC,gBAAgB,CAAC;GAEvE,OAAO,MAAM,mBAAmB;EAClC;EAEA,MAAM,UAAU,WAAwB;EAExC,SAA2B,EAAE,IAAI,YAAY,QAAQ,OAAO,EAAE,EAAE,CAAC;;uBAlF/D,YA2BS,MAAA,SAAA,GAAA;IA1BP,KAAI;aACA;IAAJ,KAAI;IACH,UAAM,OAAA,OAAA,OAAA,KAAA,oBAAP,CAAA,GAAe,CAAA,SAAA,CAAA;IACd,MAAM,QAAA,QAAQ;IACd,OAAK,eAAA,CAAG,MAAA,GAAA,EAAI,GAAG,MAAA,GAAA,EAAI,GAAE,YAAa,QAAA,QAAQ,CAAA,CAAA;;2BAGwC,EAAA,UAAA,IAAA,GADnF,mBAmBW,UAAA,MAAA,WAlBwD,MAAA,aAAA,EAAa,IAAA,EAArE,MAAM,YAAY,eAAe,OAAO,iBAAU;6DACrD,KAAK,IAAA,GAAA,CAEM,cAAU,CAAK,SAAA,UAAA,GAAhC,YAAoD,wBAAR,IAAI,GAAA,EAAA,KAAA,EAAA,CAAA,MAAA,UAAA,GAEhD,YAYc,MAAA,iBAAA,GAZd,WAYc;;;QAZc,aAAa,GAAA;6BAKrC,EAAA,UAAA,GAJF,YAIE,wBAHK,IAAI,GAAA;OACR,eAAa,cAAc,MAAA,CAAA,EAAE,QAAA,OAAO,QAAI,CAAA,CAAA,EAAQ,IAAI,KAAK;OACzD,wBAAkB,WAAE,kBAAkB,OAAO,MAAM;4DAGb,gBAAgB,KAAK,KAAA,UAAA,GAA9D,mBAIM,OAAA;;OAJA,OAAK,eAAE,MAAA,GAAA,EAAI,EAAC,aAAA,CAAA;UAChB,mBAAyC,KAAA,EAArC,OAAK,eAAE,MAAA,GAAA,EAAI,EAAC,aAAA,CAAA,EAAA,GAAiB,QAAI,CAAA,IAAA,UAAA,GAErC,YAAuF,wBAAvE,IAAI,GAAA;OAAE,UAAA;OAAU,eAAa,MAAA,CAAA,EAAE,QAAA,OAAO,eAAW,CAAA,CAAA,EAAQ,IAAI,KAAK"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"helper.js","names":[],"sources":["../../../src/components/form/helper.ts"],"sourcesContent":["import type { FormModelItem } from '../../types'\n\n/**\n * 定义表单项\n * @param item 表单项\n * @returns\n */\nexport function formField<Val = unknown>(item?: FormModelItem<Val>): FormModelItem<Val> {\n if (!item) {\n return {}\n }\n\n return item\n}\n\nexport interface NestedFieldMarker<T extends Record<string, any> = Record<string, any>> {\n __isNested: true\n fields: T\n}\n\nexport function nestField<T extends Record<string, any>>(fields: T): NestedFieldMarker<T> {\n return { __isNested: true, fields }\n}\n"],"mappings":";;;;;;AAOA,SAAgB,UAAyB,MAA+C;CACtF,IAAI,CAAC,MACH,OAAO,
|
|
1
|
+
{"version":3,"file":"helper.js","names":[],"sources":["../../../src/components/form/helper.ts"],"sourcesContent":["import type { FormModelItem } from '../../types'\n\n/**\n * 定义表单项\n * @param item 表单项\n * @returns\n */\nexport function formField<Val = unknown>(item?: FormModelItem<Val>): FormModelItem<Val> {\n if (!item) {\n return {}\n }\n\n return item\n}\n\nexport interface NestedFieldMarker<T extends Record<string, any> = Record<string, any>> {\n __isNested: true\n fields: T\n}\n\nexport function nestField<T extends Record<string, any>>(fields: T): NestedFieldMarker<T> {\n return { __isNested: true, fields }\n}\n"],"mappings":";;;;;;AAOA,SAAgB,UAAyB,MAA+C;CACtF,IAAI,CAAC,MACH,OAAO,CAAC;CAGV,OAAO;AACT;AAOA,SAAgB,UAAyC,QAAiC;CACxF,OAAO;EAAE,YAAY;EAAM;CAAO;AACpC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-node-interceptor.js","names":[],"sources":["../../../src/components/form/use-node-interceptor.ts"],"sourcesContent":["import { o } from '@cat-kit/core'\nimport { createIncrease, extractNormalVNodes } from '@veltra/utils'\nimport { onBeforeUnmount, useSlots, type VNode } from 'vue'\n\nimport type { FormProps } from '../../types'\n\ninterface Options {\n props: FormProps\n}\n\nexport type SlotRenderItem =\n | {\n isFormItem: true\n formItemProps: Record<string, any>\n node: VNode\n field: undefined\n modelValue?: any\n }\n | {\n isFormItem: false\n formItemProps: Record<string, any>\n node: VNode\n field: string\n modelValue?: any\n }\n\nconst id = createIncrease(1)\n\n/**\n * 虚拟node拦截\n * @param options 选项\n * @returns\n */\nexport function useNodeInterceptor(options: Options): {\n getSlotsNodes: () => SlotRenderItem[] | null\n} {\n const { props } = options\n const slots = useSlots()\n\n const formId = id()\n\n function getSlotsNodes() {\n const { model } = props\n const nodes = slots.default?.({ model, data: model?.data })\n if (!nodes?.length) return null\n\n const flattedNodes = extractNormalVNodes(nodes)\n\n const results: SlotRenderItem[] = []\n\n // 渲染表单后得到的应当校验的字段\n const fields: string[] = []\n\n let i = 0\n while (i < flattedNodes.length) {\n const node = flattedNodes[i]!\n i++\n\n const { props, type } = node\n const item = {\n isFormItem: (type as any)?.name === 'FormItem',\n formItemProps: o((props ?? {}) as Record<string, any>).pick([\n 'label',\n 'field',\n 'span',\n 'tips',\n 'readonly'\n ]),\n node,\n field: props?.field,\n modelValue: props?.['model-value'] ?? props?.modelValue\n }\n\n item.field && fields.push(item.field)\n results.push(item)\n }\n\n model.formKeys.set(formId, fields)\n return results\n }\n\n onBeforeUnmount(() => {\n props.model?.formKeys.delete(formId)\n })\n\n return { getSlotsNodes }\n}\n"],"mappings":";;;;AA0BA,MAAM,KAAK,eAAe,
|
|
1
|
+
{"version":3,"file":"use-node-interceptor.js","names":[],"sources":["../../../src/components/form/use-node-interceptor.ts"],"sourcesContent":["import { o } from '@cat-kit/core'\nimport { createIncrease, extractNormalVNodes } from '@veltra/utils'\nimport { onBeforeUnmount, useSlots, type VNode } from 'vue'\n\nimport type { FormProps } from '../../types'\n\ninterface Options {\n props: FormProps\n}\n\nexport type SlotRenderItem =\n | {\n isFormItem: true\n formItemProps: Record<string, any>\n node: VNode\n field: undefined\n modelValue?: any\n }\n | {\n isFormItem: false\n formItemProps: Record<string, any>\n node: VNode\n field: string\n modelValue?: any\n }\n\nconst id = createIncrease(1)\n\n/**\n * 虚拟node拦截\n * @param options 选项\n * @returns\n */\nexport function useNodeInterceptor(options: Options): {\n getSlotsNodes: () => SlotRenderItem[] | null\n} {\n const { props } = options\n const slots = useSlots()\n\n const formId = id()\n\n function getSlotsNodes() {\n const { model } = props\n const nodes = slots.default?.({ model, data: model?.data })\n if (!nodes?.length) return null\n\n const flattedNodes = extractNormalVNodes(nodes)\n\n const results: SlotRenderItem[] = []\n\n // 渲染表单后得到的应当校验的字段\n const fields: string[] = []\n\n let i = 0\n while (i < flattedNodes.length) {\n const node = flattedNodes[i]!\n i++\n\n const { props, type } = node\n const item = {\n isFormItem: (type as any)?.name === 'FormItem',\n formItemProps: o((props ?? {}) as Record<string, any>).pick([\n 'label',\n 'field',\n 'span',\n 'tips',\n 'readonly'\n ]),\n node,\n field: props?.field,\n modelValue: props?.['model-value'] ?? props?.modelValue\n }\n\n item.field && fields.push(item.field)\n results.push(item)\n }\n\n model.formKeys.set(formId, fields)\n return results\n }\n\n onBeforeUnmount(() => {\n props.model?.formKeys.delete(formId)\n })\n\n return { getSlotsNodes }\n}\n"],"mappings":";;;;AA0BA,MAAM,KAAK,eAAe,CAAC;;;;;;AAO3B,SAAgB,mBAAmB,SAEjC;CACA,MAAM,EAAE,UAAU;CAClB,MAAM,QAAQ,SAAS;CAEvB,MAAM,SAAS,GAAG;CAElB,SAAS,gBAAgB;EACvB,MAAM,EAAE,UAAU;EAClB,MAAM,QAAQ,MAAM,UAAU;GAAE;GAAO,MAAM,OAAO;EAAK,CAAC;EAC1D,IAAI,CAAC,OAAO,QAAQ,OAAO;EAE3B,MAAM,eAAe,oBAAoB,KAAK;EAE9C,MAAM,UAA4B,CAAC;EAGnC,MAAM,SAAmB,CAAC;EAE1B,IAAI,IAAI;EACR,OAAO,IAAI,aAAa,QAAQ;GAC9B,MAAM,OAAO,aAAa;GAC1B;GAEA,MAAM,EAAE,OAAO,SAAS;GACxB,MAAM,OAAO;IACX,YAAa,MAAc,SAAS;IACpC,eAAe,EAAG,SAAS,CAAC,CAAyB,EAAE,KAAK;KAC1D;KACA;KACA;KACA;KACA;IACF,CAAC;IACD;IACA,OAAO,OAAO;IACd,YAAY,QAAQ,kBAAkB,OAAO;GAC/C;GAEA,KAAK,SAAS,OAAO,KAAK,KAAK,KAAK;GACpC,QAAQ,KAAK,IAAI;EACnB;EAEA,MAAM,SAAS,IAAI,QAAQ,MAAM;EACjC,OAAO;CACT;CAEA,sBAAsB;EACpB,MAAM,OAAO,SAAS,OAAO,MAAM;CACrC,CAAC;CAED,OAAO,EAAE,cAAc;AACzB"}
|
|
@@ -1,14 +1,12 @@
|
|
|
1
1
|
import { FormItemProps } from "../../types/form-item.js";
|
|
2
|
-
import * as _$vue from "vue";
|
|
3
|
-
|
|
4
2
|
//#region src/components/form-item/form-item.vue.d.ts
|
|
5
3
|
type __VLS_Slots = {
|
|
6
4
|
/** 标签插槽 */label?: () => any;
|
|
7
5
|
default?: () => any;
|
|
8
6
|
};
|
|
9
|
-
declare const __VLS_base:
|
|
7
|
+
declare const __VLS_base: import("vue").DefineComponent<FormItemProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<FormItemProps> & Readonly<{}>, {
|
|
10
8
|
readonly: boolean;
|
|
11
|
-
}, {}, {}, {}, string,
|
|
9
|
+
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
12
10
|
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
13
11
|
declare const _default: typeof __VLS_export;
|
|
14
12
|
type __VLS_WithSlots<T, S> = T & {
|
|
@@ -5,7 +5,7 @@ import { Transition, computed, createBlock, createCommentVNode, createElementBlo
|
|
|
5
5
|
import { useConfig, useFallbackProps } from "@veltra/compositions";
|
|
6
6
|
import { bem, injectFormContext, withUnit } from "@veltra/utils";
|
|
7
7
|
//#region src/components/form-item/form-item.vue?vue&type=script&setup=true&lang.tsx
|
|
8
|
-
var form_item_vue_vue_type_script_setup_true_lang_default =
|
|
8
|
+
var form_item_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineComponent({
|
|
9
9
|
name: "FormItem",
|
|
10
10
|
__name: "form-item",
|
|
11
11
|
props: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"form-item.vue_vue_type_script_setup_true_lang.js","names":["$slots"],"sources":["../../../src/components/form-item/form-item.vue"],"sourcesContent":["<template>\n <u-grid-item :span=\"span\" :class=\"className\">\n <label\n v-if=\"props.label || $slots.label\"\n :class=\"[cls.e('label'), bem.is('required', fieldRequired)]\"\n :style=\"labelStyles\"\n >\n <u-tip v-if=\"tips\" :content=\"tips\" :class=\"cls.e('tips')\">\n <span :class=\"cls.e('tip-label')\">\n <slot name=\"label\">{{ label }}:</slot>\n </span>\n </u-tip>\n <template v-else>\n <slot name=\"label\">{{ label }}:</slot>\n </template>\n </label>\n\n <section :class=\"cls.e('wrapper')\">\n <div :class=\"cls.e('content')\">\n <slot></slot>\n </div>\n\n <!-- 只有表单控件处于非只读状态时,才显示错误提示 -->\n <section :class=\"cls.e('error')\" v-if=\"!formProps?.readonly && !formProps?.noTips\">\n <transition name=\"form-item-tips\" mode=\"out-in\">\n <span :class=\"cls.e('error-text')\" v-if=\"!!errorTips\">\n {{ errorTips }}\n </span>\n </transition>\n </section>\n </section>\n </u-grid-item>\n</template>\n\n<script lang=\"tsx\" setup>\nimport { useConfig, useFallbackProps } from '@veltra/compositions'\nimport { bem, withUnit } from '@veltra/utils'\nimport { injectFormContext } from '@veltra/utils'\nimport { type CSSProperties, computed } from 'vue'\n\nimport type { FormItemProps, ComponentSize } from '../../types'\nimport { UGridItem } from '../grid'\nimport { UTip } from '../tip'\nimport { formItemCls as cls } from './helper'\n\ndefineOptions({ name: 'FormItem' })\n\nconst props = withDefaults(defineProps<FormItemProps>(), { readonly: undefined })\n\ndefineSlots<{\n /** 标签插槽 */\n label?: () => any\n default?: () => any\n}>()\n\n/** 表单组件上下文 */\nconst { formProps } = injectFormContext()\n\nconst { config } = useConfig()\n\nconst { size, readonly } = useFallbackProps([formProps ?? {}, props], {\n size: 'default' as ComponentSize,\n readonly: false\n})\n\nconst className = computed(() => {\n return [cls.b, cls.m(size.value), bem.is('error', !!errorTips.value)].join(' ')\n})\n\n/** label样式 */\nconst labelStyles = computed<CSSProperties>(() => {\n return {\n width: withUnit(props.labelWidth ?? formProps?.labelWidth ?? config.form.labelWidth, 'px')\n }\n})\n\n/** 错误提示 */\nconst errorTips = computed<string | undefined>(() => {\n if (!props.field) return undefined\n return formProps?.model?.errors.get(props.field)?.[0]\n})\n\n/** 字段是否必须 */\nconst fieldRequired = computed<boolean>(() => {\n const { field } = props\n if (!field || readonly.value) return false\n const required = formProps?.model?.fields[field]?.required\n return Boolean(required)\n})\n</script>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;EA+CA,MAAM,QAAQ;;EASd,MAAM,EAAE,cAAc,
|
|
1
|
+
{"version":3,"file":"form-item.vue_vue_type_script_setup_true_lang.js","names":["$slots"],"sources":["../../../src/components/form-item/form-item.vue"],"sourcesContent":["<template>\n <u-grid-item :span=\"span\" :class=\"className\">\n <label\n v-if=\"props.label || $slots.label\"\n :class=\"[cls.e('label'), bem.is('required', fieldRequired)]\"\n :style=\"labelStyles\"\n >\n <u-tip v-if=\"tips\" :content=\"tips\" :class=\"cls.e('tips')\">\n <span :class=\"cls.e('tip-label')\">\n <slot name=\"label\">{{ label }}:</slot>\n </span>\n </u-tip>\n <template v-else>\n <slot name=\"label\">{{ label }}:</slot>\n </template>\n </label>\n\n <section :class=\"cls.e('wrapper')\">\n <div :class=\"cls.e('content')\">\n <slot></slot>\n </div>\n\n <!-- 只有表单控件处于非只读状态时,才显示错误提示 -->\n <section :class=\"cls.e('error')\" v-if=\"!formProps?.readonly && !formProps?.noTips\">\n <transition name=\"form-item-tips\" mode=\"out-in\">\n <span :class=\"cls.e('error-text')\" v-if=\"!!errorTips\">\n {{ errorTips }}\n </span>\n </transition>\n </section>\n </section>\n </u-grid-item>\n</template>\n\n<script lang=\"tsx\" setup>\nimport { useConfig, useFallbackProps } from '@veltra/compositions'\nimport { bem, withUnit } from '@veltra/utils'\nimport { injectFormContext } from '@veltra/utils'\nimport { type CSSProperties, computed } from 'vue'\n\nimport type { FormItemProps, ComponentSize } from '../../types'\nimport { UGridItem } from '../grid'\nimport { UTip } from '../tip'\nimport { formItemCls as cls } from './helper'\n\ndefineOptions({ name: 'FormItem' })\n\nconst props = withDefaults(defineProps<FormItemProps>(), { readonly: undefined })\n\ndefineSlots<{\n /** 标签插槽 */\n label?: () => any\n default?: () => any\n}>()\n\n/** 表单组件上下文 */\nconst { formProps } = injectFormContext()\n\nconst { config } = useConfig()\n\nconst { size, readonly } = useFallbackProps([formProps ?? {}, props], {\n size: 'default' as ComponentSize,\n readonly: false\n})\n\nconst className = computed(() => {\n return [cls.b, cls.m(size.value), bem.is('error', !!errorTips.value)].join(' ')\n})\n\n/** label样式 */\nconst labelStyles = computed<CSSProperties>(() => {\n return {\n width: withUnit(props.labelWidth ?? formProps?.labelWidth ?? config.form.labelWidth, 'px')\n }\n})\n\n/** 错误提示 */\nconst errorTips = computed<string | undefined>(() => {\n if (!props.field) return undefined\n return formProps?.model?.errors.get(props.field)?.[0]\n})\n\n/** 字段是否必须 */\nconst fieldRequired = computed<boolean>(() => {\n const { field } = props\n if (!field || readonly.value) return false\n const required = formProps?.model?.fields[field]?.required\n return Boolean(required)\n})\n</script>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;EA+CA,MAAM,QAAQ;;EASd,MAAM,EAAE,cAAc,kBAAkB;EAExC,MAAM,EAAE,WAAW,UAAU;EAE7B,MAAM,EAAE,MAAM,aAAa,iBAAiB,CAAC,aAAa,CAAC,GAAG,KAAK,GAAG;GACpE,MAAM;GACN,UAAU;EACZ,CAAC;EAED,MAAM,YAAY,eAAe;GAC/B,OAAO;IAAC,YAAI;IAAG,YAAI,EAAE,KAAK,KAAK;IAAG,IAAI,GAAG,SAAS,CAAC,CAAC,UAAU,KAAK;GAAC,EAAE,KAAK,GAAG;EAChF,CAAC;;EAGD,MAAM,cAAc,eAA8B;GAChD,OAAO,EACL,OAAO,SAAS,MAAM,cAAc,WAAW,cAAc,OAAO,KAAK,YAAY,IAAI,EAC3F;EACF,CAAC;;EAGD,MAAM,YAAY,eAAmC;GACnD,IAAI,CAAC,MAAM,OAAO,OAAO,KAAA;GACzB,OAAO,WAAW,OAAO,OAAO,IAAI,MAAM,KAAK,IAAI;EACrD,CAAC;;EAGD,MAAM,gBAAgB,eAAwB;GAC5C,MAAM,EAAE,UAAU;GAClB,IAAI,CAAC,SAAS,SAAS,OAAO,OAAO;GACrC,MAAM,WAAW,WAAW,OAAO,OAAO,QAAQ;GAClD,OAAO,QAAQ,QAAQ;EACzB,CAAC;;uBAvFC,YA8Bc,MAAA,WAAA,GAAA;IA9BA,MAAM,QAAA;IAAO,OAAK,eAAE,UAAA,KAAS;;2BAcjC,CAZA,MAAM,SAASA,KAAAA,OAAO,SAAA,UAAA,GAD9B,mBAaQ,SAAA;;KAXL,OAAK,eAAA,CAAG,MAAA,WAAA,EAAI,EAAC,OAAA,GAAW,MAAA,GAAA,EAAI,GAAE,YAAa,cAAA,KAAa,CAAA,CAAA;KACxD,OAAK,eAAE,YAAA,KAAW;QAEN,QAAA,QAAA,UAAA,GAAb,YAIQ,MAAA,SAAA,GAAA;;KAJY,SAAS,QAAA;KAAO,OAAK,eAAE,MAAA,WAAA,EAAI,EAAC,MAAA,CAAA;;4BAGvC,CAFP,mBAEO,QAAA,EAFA,OAAK,eAAE,MAAA,WAAA,EAAI,EAAC,WAAA,CAAA,EAAA,GAAA,CACjB,WAAsC,KAAA,QAAA,SAAA,CAAA,SAAA,CAAA,gBAAA,gBAAhB,QAAA,KAAK,IAAG,KAAC,CAAA,CAAA,CAAA,CAAA,GAAA,CAAA,CAAA,CAAA;;mCAIjC,WAAsC,KAAA,QAAA,SAAA,EAAA,KAAA,EAAA,SAAA,CAAA,gBAAA,gBAAhB,QAAA,KAAK,IAAG,KAAC,CAAA,CAAA,CAAA,CAAA,GAAA,CAAA,KAAA,mBAAA,QAAA,IAAA,GAInC,mBAaU,WAAA,EAbA,OAAK,eAAE,MAAA,WAAA,EAAI,EAAC,SAAA,CAAA,EAAA,GAAA;KACpB,mBAEM,OAAA,EAFA,OAAK,eAAE,MAAA,WAAA,EAAI,EAAC,SAAA,CAAA,EAAA,GAAA,CAChB,WAAa,KAAA,QAAA,SAAA,CAAA,GAAA,CAAA;KAGf,mBAAA,0BAAA;MACwC,MAAA,SAAA,GAAW,YAAQ,CAAK,MAAA,SAAA,GAAW,UAAA,UAAA,GAA3E,mBAMU,WAAA;;MANA,OAAK,eAAE,MAAA,WAAA,EAAI,EAAC,OAAA,CAAA;SACpB,YAIa,YAAA;MAJD,MAAK;MAAiB,MAAK;;6BAG9B,CAAA,CAAA,CAFoC,UAAA,SAAA,UAAA,GAA3C,mBAEO,QAAA;;OAFA,OAAK,eAAE,MAAA,WAAA,EAAI,EAAC,YAAA,CAAA;yBACd,UAAA,KAAS,GAAA,CAAA,KAAA,mBAAA,QAAA,IAAA,CAAA,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"helper.js","names":[],"sources":["../../../src/components/form-item/helper.ts"],"sourcesContent":["import { o } from '@cat-kit/core'\nimport { bem, type BEM, type FormComponentProps } from '@veltra/utils'\n\n/**\n * 获取表单项的属性\n * @param props 表单系列组件的属性\n * @returns\n */\nexport function getFormItemProps(\n props: FormComponentProps\n): Pick<FormComponentProps, 'label' | 'field' | 'readonly' | 'span' | 'tips'> {\n return o(props).pick(['label', 'field', 'readonly', 'span', 'tips']) as Pick<\n FormComponentProps,\n 'label' | 'field' | 'readonly' | 'span' | 'tips'\n >\n}\n\nexport const formItemCls: BEM<'form-item'> = bem('form-item')\n"],"mappings":";;;AAiBA,MAAa,cAAgC,IAAI,
|
|
1
|
+
{"version":3,"file":"helper.js","names":[],"sources":["../../../src/components/form-item/helper.ts"],"sourcesContent":["import { o } from '@cat-kit/core'\nimport { bem, type BEM, type FormComponentProps } from '@veltra/utils'\n\n/**\n * 获取表单项的属性\n * @param props 表单系列组件的属性\n * @returns\n */\nexport function getFormItemProps(\n props: FormComponentProps\n): Pick<FormComponentProps, 'label' | 'field' | 'readonly' | 'span' | 'tips'> {\n return o(props).pick(['label', 'field', 'readonly', 'span', 'tips']) as Pick<\n FormComponentProps,\n 'label' | 'field' | 'readonly' | 'span' | 'tips'\n >\n}\n\nexport const formItemCls: BEM<'form-item'> = bem('form-item')\n"],"mappings":";;;AAiBA,MAAa,cAAgC,IAAI,WAAW"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gantt-chart.js","names":[],"sources":["../../../src/components/gantt-chart/gantt-chart.vue"],"sourcesContent":["<template>\n <div :class=\"cls.b\"></div>\n</template>\n\n<script lang=\"ts\" setup>\nimport { bem } from '@veltra/utils'\n\nimport type { GanttChartProps } from '../../types'\n\ndefineOptions({ name: 'GanttChart' })\n\ndefineProps<GanttChartProps>()\n\nconst cls = bem('gantt-chart')\n</script>\n"],"mappings":";;;;;;;;EAaA,MAAM,MAAM,IAAI,
|
|
1
|
+
{"version":3,"file":"gantt-chart.js","names":[],"sources":["../../../src/components/gantt-chart/gantt-chart.vue"],"sourcesContent":["<template>\n <div :class=\"cls.b\"></div>\n</template>\n\n<script lang=\"ts\" setup>\nimport { bem } from '@veltra/utils'\n\nimport type { GanttChartProps } from '../../types'\n\ndefineOptions({ name: 'GanttChart' })\n\ndefineProps<GanttChartProps>()\n\nconst cls = bem('gantt-chart')\n</script>\n"],"mappings":";;;;;;;;EAaA,MAAM,MAAM,IAAI,aAAa;;uBAZ3B,mBAA0B,OAAA,EAApB,OAAK,eAAE,MAAA,GAAA,EAAI,CAAC,EAAA,GAAA,MAAA,CAAA"}
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import { GanttChartProps } from "../../types/gantt-chart.js";
|
|
2
|
-
import * as _$vue from "vue";
|
|
3
|
-
|
|
4
2
|
//#region src/components/gantt-chart/gantt-chart.vue.d.ts
|
|
5
|
-
declare const __VLS_export:
|
|
3
|
+
declare const __VLS_export: import("vue").DefineComponent<GanttChartProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<GanttChartProps> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
6
4
|
declare const _default: typeof __VLS_export;
|
|
7
5
|
//#endregion
|
|
8
6
|
export { _default };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"breakpoint.js","names":[],"sources":["../../../src/components/grid/breakpoint.ts"],"sourcesContent":["import type { BreakpointName, BreakCols, Breakpoint } from '../../types'\n\nexport const DEFAULT_COLS = 24\n\nconst points: [number, BreakpointName][] = [\n [578, 'xs'],\n [960, 'sm'],\n [1366, 'md'],\n [1920, 'lg'],\n [Infinity, 'xl']\n]\n\n/**\n * 获取容器断点\n * @param width\n */\nexport function getContainerBreakpoint(width: number): Breakpoint {\n for (let i = 0; i < points.length; i++) {\n const point = points[i]!\n if (width < point[0]) {\n return { name: point[1], level: i + 1 }\n }\n }\n return { name: 'xl', level: 5 }\n}\n\n/**\n * 获取断点对应的列数\n * @param colConf 断点配置\n * @param breakpoint 断点\n */\nexport function getBreakpointCols(colConf: BreakCols, breakpoint?: Breakpoint): number {\n if (!breakpoint) return DEFAULT_COLS\n const { name, level } = breakpoint\n const cols = colConf[name]\n if (cols !== undefined) return cols\n\n if (level === 5) return colConf.default ?? DEFAULT_COLS\n\n // 尝试寻找高级断点\n const highLevelPoints = points.slice(level - 1)\n for (let i = 0; i < highLevelPoints.length; i++) {\n const pointName = highLevelPoints[i]![1]\n if (colConf[pointName]) {\n return colConf[pointName]\n }\n }\n return DEFAULT_COLS\n}\n"],"mappings":"AAIA,MAAM,SAAqC;CACzC,CAAC,KAAK,
|
|
1
|
+
{"version":3,"file":"breakpoint.js","names":[],"sources":["../../../src/components/grid/breakpoint.ts"],"sourcesContent":["import type { BreakpointName, BreakCols, Breakpoint } from '../../types'\n\nexport const DEFAULT_COLS = 24\n\nconst points: [number, BreakpointName][] = [\n [578, 'xs'],\n [960, 'sm'],\n [1366, 'md'],\n [1920, 'lg'],\n [Infinity, 'xl']\n]\n\n/**\n * 获取容器断点\n * @param width\n */\nexport function getContainerBreakpoint(width: number): Breakpoint {\n for (let i = 0; i < points.length; i++) {\n const point = points[i]!\n if (width < point[0]) {\n return { name: point[1], level: i + 1 }\n }\n }\n return { name: 'xl', level: 5 }\n}\n\n/**\n * 获取断点对应的列数\n * @param colConf 断点配置\n * @param breakpoint 断点\n */\nexport function getBreakpointCols(colConf: BreakCols, breakpoint?: Breakpoint): number {\n if (!breakpoint) return DEFAULT_COLS\n const { name, level } = breakpoint\n const cols = colConf[name]\n if (cols !== undefined) return cols\n\n if (level === 5) return colConf.default ?? DEFAULT_COLS\n\n // 尝试寻找高级断点\n const highLevelPoints = points.slice(level - 1)\n for (let i = 0; i < highLevelPoints.length; i++) {\n const pointName = highLevelPoints[i]![1]\n if (colConf[pointName]) {\n return colConf[pointName]\n }\n }\n return DEFAULT_COLS\n}\n"],"mappings":"AAIA,MAAM,SAAqC;CACzC,CAAC,KAAK,IAAI;CACV,CAAC,KAAK,IAAI;CACV,CAAC,MAAM,IAAI;CACX,CAAC,MAAM,IAAI;CACX,CAAC,UAAU,IAAI;AACjB;;;;;AAMA,SAAgB,uBAAuB,OAA2B;CAChE,KAAK,IAAI,IAAI,GAAG,IAAI,OAAO,QAAQ,KAAK;EACtC,MAAM,QAAQ,OAAO;EACrB,IAAI,QAAQ,MAAM,IAChB,OAAO;GAAE,MAAM,MAAM;GAAI,OAAO,IAAI;EAAE;CAE1C;CACA,OAAO;EAAE,MAAM;EAAM,OAAO;CAAE;AAChC;;;;;;AAOA,SAAgB,kBAAkB,SAAoB,YAAiC;CACrF,IAAI,CAAC,YAAY,OAAA;CACjB,MAAM,EAAE,MAAM,UAAU;CACxB,MAAM,OAAO,QAAQ;CACrB,IAAI,SAAS,KAAA,GAAW,OAAO;CAE/B,IAAI,UAAU,GAAG,OAAO,QAAQ,WAAA;CAGhC,MAAM,kBAAkB,OAAO,MAAM,QAAQ,CAAC;CAC9C,KAAK,IAAI,IAAI,GAAG,IAAI,gBAAgB,QAAQ,KAAK;EAC/C,MAAM,YAAY,gBAAgB,GAAI;EACtC,IAAI,QAAQ,YACV,OAAO,QAAQ;CAEnB;CACA,OAAA;AACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"di.js","names":[],"sources":["../../../src/components/grid/di.ts"],"sourcesContent":["import type { InjectionKey, ShallowReactive, ShallowRef } from 'vue'\n\nimport type { Breakpoint, GridItemProps } from '../../types'\n\nexport interface GridContext {\n /** 当前断点 */\n currentBreakpoint: ShallowRef<Breakpoint | undefined>\n /** 栅格项属性 */\n gridItemsProps: ShallowReactive<Set<GridItemProps>>\n}\n\nexport const GridDIKey: InjectionKey<GridContext> = Symbol('GridDIKey')\n"],"mappings":";AAWA,MAAa,YAAuC,OAAO,
|
|
1
|
+
{"version":3,"file":"di.js","names":[],"sources":["../../../src/components/grid/di.ts"],"sourcesContent":["import type { InjectionKey, ShallowReactive, ShallowRef } from 'vue'\n\nimport type { Breakpoint, GridItemProps } from '../../types'\n\nexport interface GridContext {\n /** 当前断点 */\n currentBreakpoint: ShallowRef<Breakpoint | undefined>\n /** 栅格项属性 */\n gridItemsProps: ShallowReactive<Set<GridItemProps>>\n}\n\nexport const GridDIKey: InjectionKey<GridContext> = Symbol('GridDIKey')\n"],"mappings":";AAWA,MAAa,YAAuC,OAAO,WAAW"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"grid-item.js","names":[],"sources":["../../../src/components/grid/grid-item.vue"],"sourcesContent":["<template>\n <component :is=\"tag\" :style=\"style\" :class=\"cls.b\" v-if=\"span !== 0\">\n <slot />\n </component>\n</template>\n\n<script lang=\"ts\" setup>\nimport { bem } from '@veltra/utils'\nimport { computed, inject, type CSSProperties, watch } from 'vue'\n\nimport type { GridItemProps } from '../../types'\nimport { GridDIKey } from './di'\n\ndefineOptions({ name: 'GridItem' })\n\nconst props = withDefaults(defineProps<GridItemProps>(), { tag: 'div' })\n\nconst cls = bem('grid-item')\n\nconst { currentBreakpoint, gridItemsProps } = inject(GridDIKey) ?? {}\n\nif (!currentBreakpoint) {\n console.error('GridItem组件仅能在Grid组件中使用')\n}\n\nconst span = computed<number | 'full'>(() => {\n let { span } = props\n if (span === undefined) return 1\n if (span === 'full') return 'full'\n\n if (typeof span === 'number') return span\n\n const breakpoint = currentBreakpoint?.value\n\n if (!breakpoint) return span.default\n return span[breakpoint.name] ?? span.default\n})\n\nconst style = computed<CSSProperties>(() => {\n return { gridColumn: span.value === 'full' ? '1 / -1' : `span ${span.value}` }\n})\n\nwatch(\n () => props.span,\n (span) => {\n if (typeof span === 'object') {\n gridItemsProps?.add(props)\n } else {\n gridItemsProps?.delete(props)\n }\n },\n { immediate: true }\n)\n</script>\n"],"mappings":";;;;;;;;;;;;EAeA,MAAM,QAAQ;EAEd,MAAM,MAAM,IAAI,
|
|
1
|
+
{"version":3,"file":"grid-item.js","names":[],"sources":["../../../src/components/grid/grid-item.vue"],"sourcesContent":["<template>\n <component :is=\"tag\" :style=\"style\" :class=\"cls.b\" v-if=\"span !== 0\">\n <slot />\n </component>\n</template>\n\n<script lang=\"ts\" setup>\nimport { bem } from '@veltra/utils'\nimport { computed, inject, type CSSProperties, watch } from 'vue'\n\nimport type { GridItemProps } from '../../types'\nimport { GridDIKey } from './di'\n\ndefineOptions({ name: 'GridItem' })\n\nconst props = withDefaults(defineProps<GridItemProps>(), { tag: 'div' })\n\nconst cls = bem('grid-item')\n\nconst { currentBreakpoint, gridItemsProps } = inject(GridDIKey) ?? {}\n\nif (!currentBreakpoint) {\n console.error('GridItem组件仅能在Grid组件中使用')\n}\n\nconst span = computed<number | 'full'>(() => {\n let { span } = props\n if (span === undefined) return 1\n if (span === 'full') return 'full'\n\n if (typeof span === 'number') return span\n\n const breakpoint = currentBreakpoint?.value\n\n if (!breakpoint) return span.default\n return span[breakpoint.name] ?? span.default\n})\n\nconst style = computed<CSSProperties>(() => {\n return { gridColumn: span.value === 'full' ? '1 / -1' : `span ${span.value}` }\n})\n\nwatch(\n () => props.span,\n (span) => {\n if (typeof span === 'object') {\n gridItemsProps?.add(props)\n } else {\n gridItemsProps?.delete(props)\n }\n },\n { immediate: true }\n)\n</script>\n"],"mappings":";;;;;;;;;;;;EAeA,MAAM,QAAQ;EAEd,MAAM,MAAM,IAAI,WAAW;EAE3B,MAAM,EAAE,mBAAmB,mBAAmB,OAAO,SAAS,KAAK,CAAC;EAEpE,IAAI,CAAC,mBACH,QAAQ,MAAM,wBAAwB;EAGxC,MAAM,OAAO,eAAgC;GAC3C,IAAI,EAAE,SAAS;GACf,IAAI,SAAS,KAAA,GAAW,OAAO;GAC/B,IAAI,SAAS,QAAQ,OAAO;GAE5B,IAAI,OAAO,SAAS,UAAU,OAAO;GAErC,MAAM,aAAa,mBAAmB;GAEtC,IAAI,CAAC,YAAY,OAAO,KAAK;GAC7B,OAAO,KAAK,WAAW,SAAS,KAAK;EACvC,CAAC;EAED,MAAM,QAAQ,eAA8B;GAC1C,OAAO,EAAE,YAAY,KAAK,UAAU,SAAS,WAAW,QAAQ,KAAK,QAAQ;EAC/E,CAAC;EAED,YACQ,MAAM,OACX,SAAS;GACR,IAAI,OAAO,SAAS,UAClB,gBAAgB,IAAI,KAAK;QAEzB,gBAAgB,OAAO,KAAK;EAEhC,GACA,EAAE,WAAW,KAAK,CACpB;;UAnD2D,KAAA,UAAI,KAAA,UAAA,GAA7D,YAEY,wBAFI,QAAA,GAAG,GAAA;;IAAG,OAAK,eAAE,MAAA,KAAK;IAAG,OAAK,eAAE,MAAA,GAAA,EAAI,CAAC;;2BACvC,CAAR,WAAQ,KAAA,QAAA,SAAA,CAAA,CAAA"}
|
|
@@ -1,14 +1,12 @@
|
|
|
1
1
|
import { GridItemProps } from "../../types/grid.js";
|
|
2
|
-
import * as _$vue from "vue";
|
|
3
|
-
|
|
4
2
|
//#region src/components/grid/grid-item.vue.d.ts
|
|
5
3
|
declare var __VLS_8: {};
|
|
6
4
|
type __VLS_Slots = {} & {
|
|
7
5
|
default?: (props: typeof __VLS_8) => any;
|
|
8
6
|
};
|
|
9
|
-
declare const __VLS_base:
|
|
7
|
+
declare const __VLS_base: import("vue").DefineComponent<GridItemProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<GridItemProps> & Readonly<{}>, {
|
|
10
8
|
tag: string;
|
|
11
|
-
}, {}, {}, {}, string,
|
|
9
|
+
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
12
10
|
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
13
11
|
declare const _default: typeof __VLS_export;
|
|
14
12
|
type __VLS_WithSlots<T, S> = T & {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"grid.js","names":[],"sources":["../../../src/components/grid/grid.vue"],"sourcesContent":["<template>\n <component :is=\"tag\" :class=\"cls.b\" ref=\"grid\">\n <slot />\n </component>\n</template>\n\n<script lang=\"ts\" setup>\nimport { bem, removeStyles, setStyles, withUnit } from '@veltra/utils'\nimport { type CSSProperties, provide, watch, useTemplateRef, computed } from 'vue'\n\nimport type { GridProps, GridEmits, _GridExposed } from '../../types'\nimport { getBreakpointCols } from './breakpoint'\nimport { GridDIKey } from './di'\nimport { useResponsive } from './use-responsive'\n\ndefineOptions({ name: 'Grid' })\n\nconst props = withDefaults(defineProps<GridProps>(), { tag: 'div' })\n\nconst emit = defineEmits<GridEmits>()\n\nconst cls = bem('grid')\n\nconst gridRef = useTemplateRef<HTMLElement>('grid')\n\nconst { currentBreakpoint, gridItemsProps } = useResponsive({ props, emit, gridRef })\n\nconst styles = computed(() => {\n const { gap, cols } = props\n const result: CSSProperties = {}\n\n // 间距\n if (typeof gap === 'number') {\n if (gap > 0) {\n result.rowGap = result.columnGap = gap + 'px'\n }\n } else if (typeof gap === 'string') {\n const [rowGap, columnGap] = gap.split(' ')\n result.columnGap = withUnit(columnGap || rowGap, 'px')\n result.rowGap = withUnit(rowGap, 'px')\n }\n\n const breakpoint = currentBreakpoint.value\n\n switch (typeof cols) {\n case 'number':\n result.gridTemplateColumns = `repeat(${cols}, minmax(0px, 1fr))`\n break\n case 'function':\n if (breakpoint) {\n result.gridTemplateColumns = `repeat(${cols(breakpoint)}, minmax(0px, 1fr))`\n }\n break\n case 'object':\n if (breakpoint) {\n const amount = getBreakpointCols(cols, breakpoint)\n result.gridTemplateColumns = `repeat(${amount}, minmax(0px, 1fr))`\n }\n }\n\n return result\n})\n\nwatch([styles, gridRef], ([styles, dom]) => {\n if (!dom) return\n\n // 重置并移除样式\n removeStyles(dom, ['gridTemplateColumns', 'columnGap', 'rowGap'])\n setStyles(dom, styles)\n})\n\nprovide(GridDIKey, { currentBreakpoint, gridItemsProps })\n\ndefineExpose<_GridExposed>({ el: gridRef })\n</script>\n"],"mappings":";;;;;;;;;;;;;;;;EAiBA,MAAM,QAAQ;EAEd,MAAM,OAAO;EAEb,MAAM,MAAM,IAAI,
|
|
1
|
+
{"version":3,"file":"grid.js","names":[],"sources":["../../../src/components/grid/grid.vue"],"sourcesContent":["<template>\n <component :is=\"tag\" :class=\"cls.b\" ref=\"grid\">\n <slot />\n </component>\n</template>\n\n<script lang=\"ts\" setup>\nimport { bem, removeStyles, setStyles, withUnit } from '@veltra/utils'\nimport { type CSSProperties, provide, watch, useTemplateRef, computed } from 'vue'\n\nimport type { GridProps, GridEmits, _GridExposed } from '../../types'\nimport { getBreakpointCols } from './breakpoint'\nimport { GridDIKey } from './di'\nimport { useResponsive } from './use-responsive'\n\ndefineOptions({ name: 'Grid' })\n\nconst props = withDefaults(defineProps<GridProps>(), { tag: 'div' })\n\nconst emit = defineEmits<GridEmits>()\n\nconst cls = bem('grid')\n\nconst gridRef = useTemplateRef<HTMLElement>('grid')\n\nconst { currentBreakpoint, gridItemsProps } = useResponsive({ props, emit, gridRef })\n\nconst styles = computed(() => {\n const { gap, cols } = props\n const result: CSSProperties = {}\n\n // 间距\n if (typeof gap === 'number') {\n if (gap > 0) {\n result.rowGap = result.columnGap = gap + 'px'\n }\n } else if (typeof gap === 'string') {\n const [rowGap, columnGap] = gap.split(' ')\n result.columnGap = withUnit(columnGap || rowGap, 'px')\n result.rowGap = withUnit(rowGap, 'px')\n }\n\n const breakpoint = currentBreakpoint.value\n\n switch (typeof cols) {\n case 'number':\n result.gridTemplateColumns = `repeat(${cols}, minmax(0px, 1fr))`\n break\n case 'function':\n if (breakpoint) {\n result.gridTemplateColumns = `repeat(${cols(breakpoint)}, minmax(0px, 1fr))`\n }\n break\n case 'object':\n if (breakpoint) {\n const amount = getBreakpointCols(cols, breakpoint)\n result.gridTemplateColumns = `repeat(${amount}, minmax(0px, 1fr))`\n }\n }\n\n return result\n})\n\nwatch([styles, gridRef], ([styles, dom]) => {\n if (!dom) return\n\n // 重置并移除样式\n removeStyles(dom, ['gridTemplateColumns', 'columnGap', 'rowGap'])\n setStyles(dom, styles)\n})\n\nprovide(GridDIKey, { currentBreakpoint, gridItemsProps })\n\ndefineExpose<_GridExposed>({ el: gridRef })\n</script>\n"],"mappings":";;;;;;;;;;;;;;;;EAiBA,MAAM,QAAQ;EAEd,MAAM,OAAO;EAEb,MAAM,MAAM,IAAI,MAAM;EAEtB,MAAM,UAAU,eAA4B,MAAM;EAElD,MAAM,EAAE,mBAAmB,mBAAmB,cAAc;GAAE;GAAO;GAAM;EAAQ,CAAC;EAsCpF,MAAM,CApCS,eAAe;GAC5B,MAAM,EAAE,KAAK,SAAS;GACtB,MAAM,SAAwB,CAAC;GAG/B,IAAI,OAAO,QAAQ;QACb,MAAM,GACR,OAAO,SAAS,OAAO,YAAY,MAAM;GAAA,OAEtC,IAAI,OAAO,QAAQ,UAAU;IAClC,MAAM,CAAC,QAAQ,aAAa,IAAI,MAAM,GAAG;IACzC,OAAO,YAAY,SAAS,aAAa,QAAQ,IAAI;IACrD,OAAO,SAAS,SAAS,QAAQ,IAAI;GACvC;GAEA,MAAM,aAAa,kBAAkB;GAErC,QAAQ,OAAO,MAAf;IACE,KAAK;KACH,OAAO,sBAAsB,UAAU,KAAK;KAC5C;IACF,KAAK;KACH,IAAI,YACF,OAAO,sBAAsB,UAAU,KAAK,UAAU,EAAE;KAE1D;IACF,KAAK,UACH,IAAI,YAEF,OAAO,sBAAsB,UADd,kBAAkB,MAAM,UACA,EAAO;GAEpD;GAEA,OAAO;EACT,CAEO,GAAQ,OAAO,IAAI,CAAC,QAAQ,SAAS;GAC1C,IAAI,CAAC,KAAK;GAGV,aAAa,KAAK;IAAC;IAAuB;IAAa;GAAQ,CAAC;GAChE,UAAU,KAAK,MAAM;EACvB,CAAC;EAED,QAAQ,WAAW;GAAE;GAAmB;EAAe,CAAC;EAExD,SAA2B,EAAE,IAAI,QAAQ,CAAC;;uBAxExC,YAEY,wBAFI,QAAA,GAAG,GAAA;IAAG,OAAK,eAAE,MAAA,GAAA,EAAI,CAAC;IAAE,KAAI;;2BAC9B,CAAR,WAAQ,KAAA,QAAA,SAAA,CAAA,CAAA"}
|
|
@@ -1,20 +1,18 @@
|
|
|
1
1
|
import { Breakpoint, GridProps, _GridExposed } from "../../types/grid.js";
|
|
2
|
-
import * as _$vue from "vue";
|
|
3
|
-
|
|
4
2
|
//#region src/components/grid/grid.vue.d.ts
|
|
5
3
|
declare var __VLS_9: {};
|
|
6
4
|
type __VLS_Slots = {} & {
|
|
7
5
|
default?: (props: typeof __VLS_9) => any;
|
|
8
6
|
};
|
|
9
|
-
declare const __VLS_base:
|
|
7
|
+
declare const __VLS_base: import("vue").DefineComponent<GridProps, _GridExposed, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
|
|
10
8
|
resize: (rect: DOMRect) => any;
|
|
11
9
|
"breakpoint-change": (breakpoint: Breakpoint) => any;
|
|
12
|
-
}, string,
|
|
10
|
+
}, string, import("vue").PublicProps, Readonly<GridProps> & Readonly<{
|
|
13
11
|
onResize?: ((rect: DOMRect) => any) | undefined;
|
|
14
12
|
"onBreakpoint-change"?: ((breakpoint: Breakpoint) => any) | undefined;
|
|
15
13
|
}>, {
|
|
16
14
|
tag: string;
|
|
17
|
-
}, {}, {}, {}, string,
|
|
15
|
+
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
18
16
|
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
19
17
|
declare const _default: typeof __VLS_export;
|
|
20
18
|
type __VLS_WithSlots<T, S> = T & {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-responsive.js","names":[],"sources":["../../../src/components/grid/use-responsive.ts"],"sourcesContent":["import { debounce } from '@cat-kit/core'\nimport type { Undef } from '@veltra/utils'\nimport {\n computed,\n shallowRef,\n watch,\n type ShallowRef,\n shallowReactive,\n onBeforeUnmount,\n type ComputedRef\n} from 'vue'\n\nimport type { Breakpoint, GridEmits, GridItemProps, GridProps } from '../../types'\nimport { getContainerBreakpoint } from './breakpoint'\n\ninterface ResponsiveOptions {\n props: GridProps\n emit: GridEmits\n /** 栅格容器模板引用 */\n gridRef: ShallowRef<HTMLElement | null>\n}\n\ninterface UseResponsiveReturned {\n responsive: ComputedRef<boolean>\n gridItemsProps: Set<GridItemProps>\n currentBreakpoint: ShallowRef<Breakpoint | undefined>\n}\n\nexport function useResponsive(options: ResponsiveOptions): UseResponsiveReturned {\n const { props, gridRef, emit } = options\n\n const gridItemsProps = shallowReactive<Set<GridItemProps>>(new Set())\n\n const responsive = computed(() => {\n return (props.cols && typeof props.cols !== 'number') || !!gridItemsProps.size\n })\n\n const currentBreakpoint = shallowRef<Breakpoint>()\n\n let observer: Undef<ResizeObserver>\n\n watch(\n [responsive, gridRef],\n ([responsive, dom]) => {\n if (!dom) return\n\n observer?.unobserve(dom)\n observer?.disconnect()\n observer = undefined\n\n if (!responsive) {\n currentBreakpoint.value = undefined\n return\n }\n\n observer = new ResizeObserver(\n debounce(([entry]) => {\n const target = entry!.target as HTMLElement\n const rect = target.getBoundingClientRect()\n emit('resize', rect)\n const breakpoint = getContainerBreakpoint(target.offsetWidth)\n const prev = currentBreakpoint.value\n if (\n prev !== undefined &&\n prev.name === breakpoint.name &&\n prev.level === breakpoint.level\n ) {\n return\n }\n currentBreakpoint.value = breakpoint\n emit('breakpoint-change', breakpoint)\n }, 0)\n )\n observer.observe(dom)\n },\n { immediate: true }\n )\n\n onBeforeUnmount(() => {\n gridRef.value && observer?.unobserve(gridRef.value)\n observer?.disconnect()\n })\n\n return { responsive, gridItemsProps, currentBreakpoint }\n}\n"],"mappings":";;;;AA4BA,SAAgB,cAAc,SAAmD;CAC/E,MAAM,EAAE,OAAO,SAAS,SAAS;CAEjC,MAAM,iBAAiB,gCAAoC,IAAI,
|
|
1
|
+
{"version":3,"file":"use-responsive.js","names":[],"sources":["../../../src/components/grid/use-responsive.ts"],"sourcesContent":["import { debounce } from '@cat-kit/core'\nimport type { Undef } from '@veltra/utils'\nimport {\n computed,\n shallowRef,\n watch,\n type ShallowRef,\n shallowReactive,\n onBeforeUnmount,\n type ComputedRef\n} from 'vue'\n\nimport type { Breakpoint, GridEmits, GridItemProps, GridProps } from '../../types'\nimport { getContainerBreakpoint } from './breakpoint'\n\ninterface ResponsiveOptions {\n props: GridProps\n emit: GridEmits\n /** 栅格容器模板引用 */\n gridRef: ShallowRef<HTMLElement | null>\n}\n\ninterface UseResponsiveReturned {\n responsive: ComputedRef<boolean>\n gridItemsProps: Set<GridItemProps>\n currentBreakpoint: ShallowRef<Breakpoint | undefined>\n}\n\nexport function useResponsive(options: ResponsiveOptions): UseResponsiveReturned {\n const { props, gridRef, emit } = options\n\n const gridItemsProps = shallowReactive<Set<GridItemProps>>(new Set())\n\n const responsive = computed(() => {\n return (props.cols && typeof props.cols !== 'number') || !!gridItemsProps.size\n })\n\n const currentBreakpoint = shallowRef<Breakpoint>()\n\n let observer: Undef<ResizeObserver>\n\n watch(\n [responsive, gridRef],\n ([responsive, dom]) => {\n if (!dom) return\n\n observer?.unobserve(dom)\n observer?.disconnect()\n observer = undefined\n\n if (!responsive) {\n currentBreakpoint.value = undefined\n return\n }\n\n observer = new ResizeObserver(\n debounce(([entry]) => {\n const target = entry!.target as HTMLElement\n const rect = target.getBoundingClientRect()\n emit('resize', rect)\n const breakpoint = getContainerBreakpoint(target.offsetWidth)\n const prev = currentBreakpoint.value\n if (\n prev !== undefined &&\n prev.name === breakpoint.name &&\n prev.level === breakpoint.level\n ) {\n return\n }\n currentBreakpoint.value = breakpoint\n emit('breakpoint-change', breakpoint)\n }, 0)\n )\n observer.observe(dom)\n },\n { immediate: true }\n )\n\n onBeforeUnmount(() => {\n gridRef.value && observer?.unobserve(gridRef.value)\n observer?.disconnect()\n })\n\n return { responsive, gridItemsProps, currentBreakpoint }\n}\n"],"mappings":";;;;AA4BA,SAAgB,cAAc,SAAmD;CAC/E,MAAM,EAAE,OAAO,SAAS,SAAS;CAEjC,MAAM,iBAAiB,gCAAoC,IAAI,IAAI,CAAC;CAEpE,MAAM,aAAa,eAAe;EAChC,OAAQ,MAAM,QAAQ,OAAO,MAAM,SAAS,YAAa,CAAC,CAAC,eAAe;CAC5E,CAAC;CAED,MAAM,oBAAoB,WAAuB;CAEjD,IAAI;CAEJ,MACE,CAAC,YAAY,OAAO,IACnB,CAAC,YAAY,SAAS;EACrB,IAAI,CAAC,KAAK;EAEV,UAAU,UAAU,GAAG;EACvB,UAAU,WAAW;EACrB,WAAW,KAAA;EAEX,IAAI,CAAC,YAAY;GACf,kBAAkB,QAAQ,KAAA;GAC1B;EACF;EAEA,WAAW,IAAI,eACb,UAAU,CAAC,WAAW;GACpB,MAAM,SAAS,MAAO;GAEtB,KAAK,UADQ,OAAO,sBACF,CAAC;GACnB,MAAM,aAAa,uBAAuB,OAAO,WAAW;GAC5D,MAAM,OAAO,kBAAkB;GAC/B,IACE,SAAS,KAAA,KACT,KAAK,SAAS,WAAW,QACzB,KAAK,UAAU,WAAW,OAE1B;GAEF,kBAAkB,QAAQ;GAC1B,KAAK,qBAAqB,UAAU;EACtC,GAAG,CAAC,CACN;EACA,SAAS,QAAQ,GAAG;CACtB,GACA,EAAE,WAAW,KAAK,CACpB;CAEA,sBAAsB;EACpB,QAAQ,SAAS,UAAU,UAAU,QAAQ,KAAK;EAClD,UAAU,WAAW;CACvB,CAAC;CAED,OAAO;EAAE;EAAY;EAAgB;CAAkB;AACzD"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"grid-input.js","names":[],"sources":["../../../src/components/grid-input/grid-input.vue"],"sourcesContent":["<template>\n <ul :class=\"[cls.b, cls.m(size)]\">\n <li\n v-for=\"(_, index) in length\"\n :key=\"index\"\n tabindex=\"0\"\n @keydown=\"onKeydown($event, valueArray[index]!, index)\"\n @focus=\"focus(index)\"\n @blur=\"index === position && (blur = true)\"\n ref=\"items\"\n :class=\"[cls.e('item'), bem.is('focus', index === position && !blur)]\"\n >\n <span :class=\"cls.em('item', 'text')\" v-if=\"valueArray[index]\">\n {{ valueArray[index] }}\n </span>\n\n <span :class=\"cls.em('item', 'cursor')\" v-else-if=\"index === position\"></span>\n </li>\n </ul>\n</template>\n\n<script lang=\"ts\" setup>\nimport { useFallbackProps } from '@veltra/compositions'\nimport { bem } from '@veltra/utils'\nimport { computed, ref, getCurrentInstance } from 'vue'\n\nimport type { GridInputProps, GridInputEmits, GridInputExposed } from '../../types'\n\ndefineOptions({ name: 'GridInput' })\n\nconst emit = defineEmits<GridInputEmits>()\n\nconst props = withDefaults(defineProps<GridInputProps>(), {\n length: 6,\n zero: false,\n separator: '-'\n})\n\nconst { size } = useFallbackProps([props], { size: 'default' })\n\nconst cls = bem('grid-input')\n\nconst _numberReg = computed(() => (props.zero ? /^[0-9]$/ : /^[1-9]$/))\n\nconst valueArray = ref<string[]>([])\n\nconst position = ref<number>(-1)\n\nconst blur = ref<boolean>(false)\n\nconst instance = getCurrentInstance()\n\nconst focus = async (index?: number) => {\n if (index === undefined) {\n focus(position.value)\n return\n }\n if (index !== 0 && index > valueArray.value.length) {\n index = valueArray.value.length\n }\n position.value = index\n const items = (instance?.refs as { items?: unknown })?.items as any\n let dom = items?.[index]\n dom?.focus()\n blur.value = false\n}\n\nconst changeValue = (value: string, index: number) => {\n if (position.value === props.length) return\n const currentValue = valueArray.value[index]\n\n if (currentValue) {\n valueArray.value.splice(index, 1, value)\n } else if (index === valueArray.value.length) {\n valueArray.value.push(value)\n } else {\n return\n }\n position.value++\n focus()\n\n emit('input', valueArray.value.filter((v) => v).join(props.separator))\n}\n\nconst baseOperation = {\n Backspace: (value: string, index: number) => {\n if (value) {\n valueArray.value.splice(index, 1)\n } else if (index - 1 >= 0) {\n valueArray.value.splice(index - 1, 1)\n }\n if (index !== 0) {\n focus(index - 1)\n }\n emit('input', valueArray.value.filter((v) => v).join(props.separator))\n },\n ArrowLeft: (value: string, index: number) => {\n if (index === 0) return\n focus(index - 1)\n },\n ArrowRight: (value: string, index: number) => {\n if (index === valueArray.value.length) return\n focus(index + 1)\n }\n}\n\nconst onKeydown = (e: any, value: string, index: number) => {\n if (_numberReg.value.test(e.key)) {\n changeValue(e.key, index)\n return\n }\n baseOperation[e.key](value, index)\n}\n\nconst clear = () => {\n while (valueArray.value.length) {\n valueArray.value.pop()\n }\n}\n\ndefineExpose<GridInputExposed>({ clear })\n</script>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;EA8BA,MAAM,OAAO;EAEb,MAAM,QAAQ;EAMd,MAAM,EAAE,SAAS,iBAAiB,CAAC,
|
|
1
|
+
{"version":3,"file":"grid-input.js","names":[],"sources":["../../../src/components/grid-input/grid-input.vue"],"sourcesContent":["<template>\n <ul :class=\"[cls.b, cls.m(size)]\">\n <li\n v-for=\"(_, index) in length\"\n :key=\"index\"\n tabindex=\"0\"\n @keydown=\"onKeydown($event, valueArray[index]!, index)\"\n @focus=\"focus(index)\"\n @blur=\"index === position && (blur = true)\"\n ref=\"items\"\n :class=\"[cls.e('item'), bem.is('focus', index === position && !blur)]\"\n >\n <span :class=\"cls.em('item', 'text')\" v-if=\"valueArray[index]\">\n {{ valueArray[index] }}\n </span>\n\n <span :class=\"cls.em('item', 'cursor')\" v-else-if=\"index === position\"></span>\n </li>\n </ul>\n</template>\n\n<script lang=\"ts\" setup>\nimport { useFallbackProps } from '@veltra/compositions'\nimport { bem } from '@veltra/utils'\nimport { computed, ref, getCurrentInstance } from 'vue'\n\nimport type { GridInputProps, GridInputEmits, GridInputExposed } from '../../types'\n\ndefineOptions({ name: 'GridInput' })\n\nconst emit = defineEmits<GridInputEmits>()\n\nconst props = withDefaults(defineProps<GridInputProps>(), {\n length: 6,\n zero: false,\n separator: '-'\n})\n\nconst { size } = useFallbackProps([props], { size: 'default' })\n\nconst cls = bem('grid-input')\n\nconst _numberReg = computed(() => (props.zero ? /^[0-9]$/ : /^[1-9]$/))\n\nconst valueArray = ref<string[]>([])\n\nconst position = ref<number>(-1)\n\nconst blur = ref<boolean>(false)\n\nconst instance = getCurrentInstance()\n\nconst focus = async (index?: number) => {\n if (index === undefined) {\n focus(position.value)\n return\n }\n if (index !== 0 && index > valueArray.value.length) {\n index = valueArray.value.length\n }\n position.value = index\n const items = (instance?.refs as { items?: unknown })?.items as any\n let dom = items?.[index]\n dom?.focus()\n blur.value = false\n}\n\nconst changeValue = (value: string, index: number) => {\n if (position.value === props.length) return\n const currentValue = valueArray.value[index]\n\n if (currentValue) {\n valueArray.value.splice(index, 1, value)\n } else if (index === valueArray.value.length) {\n valueArray.value.push(value)\n } else {\n return\n }\n position.value++\n focus()\n\n emit('input', valueArray.value.filter((v) => v).join(props.separator))\n}\n\nconst baseOperation = {\n Backspace: (value: string, index: number) => {\n if (value) {\n valueArray.value.splice(index, 1)\n } else if (index - 1 >= 0) {\n valueArray.value.splice(index - 1, 1)\n }\n if (index !== 0) {\n focus(index - 1)\n }\n emit('input', valueArray.value.filter((v) => v).join(props.separator))\n },\n ArrowLeft: (value: string, index: number) => {\n if (index === 0) return\n focus(index - 1)\n },\n ArrowRight: (value: string, index: number) => {\n if (index === valueArray.value.length) return\n focus(index + 1)\n }\n}\n\nconst onKeydown = (e: any, value: string, index: number) => {\n if (_numberReg.value.test(e.key)) {\n changeValue(e.key, index)\n return\n }\n baseOperation[e.key](value, index)\n}\n\nconst clear = () => {\n while (valueArray.value.length) {\n valueArray.value.pop()\n }\n}\n\ndefineExpose<GridInputExposed>({ clear })\n</script>\n"],"mappings":"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"}
|
|
@@ -1,19 +1,16 @@
|
|
|
1
1
|
import { GridInputProps, _GridInputExposed } from "../../types/grid-input.js";
|
|
2
|
-
import * as _$vue from "vue";
|
|
3
|
-
import * as _$_veltra_utils0 from "@veltra/utils";
|
|
4
|
-
|
|
5
2
|
//#region src/components/grid-input/grid-input.vue.d.ts
|
|
6
|
-
declare const __VLS_export:
|
|
3
|
+
declare const __VLS_export: import("vue").DefineComponent<GridInputProps, import("@veltra/utils").DeconstructValue<_GridInputExposed>, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
|
|
7
4
|
"update:modelValue": (value: string) => any;
|
|
8
5
|
input: (value: string) => any;
|
|
9
|
-
}, string,
|
|
6
|
+
}, string, import("vue").PublicProps, Readonly<GridInputProps> & Readonly<{
|
|
10
7
|
"onUpdate:modelValue"?: ((value: string) => any) | undefined;
|
|
11
8
|
onInput?: ((value: string) => any) | undefined;
|
|
12
9
|
}>, {
|
|
13
10
|
length: number;
|
|
14
11
|
separator: string;
|
|
15
12
|
zero: false;
|
|
16
|
-
}, {}, {}, {}, string,
|
|
13
|
+
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
17
14
|
declare const _default: typeof __VLS_export;
|
|
18
15
|
//#endregion
|
|
19
16
|
export { _default };
|