@veltra/desktop 1.8.3 → 1.8.5

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.
Files changed (200) hide show
  1. package/dist/components/action/action-group.js.map +1 -1
  2. package/dist/components/action/action-group.vue_vue_type_script_setup_true_lang.js.map +1 -1
  3. package/dist/components/action/action.js.map +1 -1
  4. package/dist/components/auto-complete/auto-complete.js.map +1 -1
  5. package/dist/components/badge/badge.js.map +1 -1
  6. package/dist/components/batch-edit/batch-edit-form.js.map +1 -1
  7. package/dist/components/batch-edit/batch-edit-list.js.map +1 -1
  8. package/dist/components/batch-edit/batch-edit.js.map +1 -1
  9. package/dist/components/breadcrumb/breadcrumb.js.map +1 -1
  10. package/dist/components/button/button-group.js.map +1 -1
  11. package/dist/components/button/button.js.map +1 -1
  12. package/dist/components/calendar/calendar.js.map +1 -1
  13. package/dist/components/card/card-action.js.map +1 -1
  14. package/dist/components/card/card-content.js.map +1 -1
  15. package/dist/components/card/card-cover.js.map +1 -1
  16. package/dist/components/card/card-header.js.map +1 -1
  17. package/dist/components/card/card.js.map +1 -1
  18. package/dist/components/cascade/cascade-panel-item.js.map +1 -1
  19. package/dist/components/cascade/cascade.js +1 -0
  20. package/dist/components/cascade/cascade.js.map +1 -1
  21. package/dist/components/cascade/use-select.js +6 -2
  22. package/dist/components/cascade/use-select.js.map +1 -1
  23. package/dist/components/check-tag/check-tag.js.map +1 -1
  24. package/dist/components/checkbox/checkbox-button.js.map +1 -1
  25. package/dist/components/checkbox/checkbox.js.map +1 -1
  26. package/dist/components/checkbox-group/checkbox-group.js.map +1 -1
  27. package/dist/components/code-editor/code-editor.js.map +1 -1
  28. package/dist/components/collapse/collapse-item.js.map +1 -1
  29. package/dist/components/collapse/collapse.js.map +1 -1
  30. package/dist/components/condition-editor/components/condition-group.js.map +1 -1
  31. package/dist/components/condition-editor/components/condition-row.js.map +1 -1
  32. package/dist/components/condition-editor/condition-editor.js.map +1 -1
  33. package/dist/components/contextmenu/contextmenu-item.js.map +1 -1
  34. package/dist/components/contextmenu/contextmenu-panel.js.map +1 -1
  35. package/dist/components/contextmenu/contextmenu-sub.js.map +1 -1
  36. package/dist/components/contextmenu/contextmenu.js.map +1 -1
  37. package/dist/components/date-panel/date-panel.js.map +1 -1
  38. package/dist/components/date-panel/headers/day.js.map +1 -1
  39. package/dist/components/date-panel/headers/month.js.map +1 -1
  40. package/dist/components/date-panel/headers/year.js.map +1 -1
  41. package/dist/components/date-panel/panels/day.js.map +1 -1
  42. package/dist/components/date-panel/panels/month.js.map +1 -1
  43. package/dist/components/date-panel/panels/year.js.map +1 -1
  44. package/dist/components/date-picker/date-picker.js.map +1 -1
  45. package/dist/components/date-range-picker/date-range-picker.js.map +1 -1
  46. package/dist/components/dialog/dialog.js.map +1 -1
  47. package/dist/components/drawer/drawer.js.map +1 -1
  48. package/dist/components/dropdown/dropdown.js.map +1 -1
  49. package/dist/components/dual-nav/dual-nav-app.js.map +1 -1
  50. package/dist/components/dual-nav/dual-nav.js.map +1 -1
  51. package/dist/components/empty/empty.js.map +1 -1
  52. package/dist/components/expression-editor/components/path-preview.js.map +1 -1
  53. package/dist/components/expression-editor/components/variable-picker.js.map +1 -1
  54. package/dist/components/expression-editor/expression-editor.js.map +1 -1
  55. package/dist/components/file-picker/file-picker.js.map +1 -1
  56. package/dist/components/file-viewer/file-viewer.js.map +1 -1
  57. package/dist/components/file-viewer/previewers/docx-previewer.js.map +1 -1
  58. package/dist/components/file-viewer/previewers/image-previewer.js.map +1 -1
  59. package/dist/components/file-viewer/previewers/ofd-previewer.js.map +1 -1
  60. package/dist/components/file-viewer/previewers/pdf-previewer.js +3 -1
  61. package/dist/components/file-viewer/previewers/pdf-previewer.js.map +1 -1
  62. package/dist/components/file-viewer/previewers/pdf-viewport-scroll.js.map +1 -1
  63. package/dist/components/file-viewer/previewers/pdf-zoom-bridge.js.map +1 -1
  64. package/dist/components/file-viewer/previewers/sheet-previewer.js.map +1 -1
  65. package/dist/components/file-viewer/previewers/text-previewer.js.map +1 -1
  66. package/dist/components/file-viewer/previewers/video-previewer.js.map +1 -1
  67. package/dist/components/float-button/float-button.js.map +1 -1
  68. package/dist/components/form/form.js.map +1 -1
  69. package/dist/components/form/form.vue_vue_type_script_setup_true_lang.js.map +1 -1
  70. package/dist/components/form-item/form-item.js.map +1 -1
  71. package/dist/components/form-item/form-item.vue_vue_type_script_setup_true_lang.js.map +1 -1
  72. package/dist/components/gantt-chart/gantt-chart.js.map +1 -1
  73. package/dist/components/grid/grid-item.js.map +1 -1
  74. package/dist/components/grid/grid.js.map +1 -1
  75. package/dist/components/grid-input/grid-input.js.map +1 -1
  76. package/dist/components/group-input/group-input.js.map +1 -1
  77. package/dist/components/group-nav/group-nav-item.js.map +1 -1
  78. package/dist/components/group-nav/group-nav.js.map +1 -1
  79. package/dist/components/icon/icon.js.map +1 -1
  80. package/dist/components/image-cropper/image-cropper.js.map +1 -1
  81. package/dist/components/input/input.js.map +1 -1
  82. package/dist/components/input/input.vue_vue_type_script_setup_true_lang.js.map +1 -1
  83. package/dist/components/kanban/kanban-column.js.map +1 -1
  84. package/dist/components/kanban/kanban.js.map +1 -1
  85. package/dist/components/kbd/kbd.js.map +1 -1
  86. package/dist/components/layout/layout-resizer.js.map +1 -1
  87. package/dist/components/layout/layout.js.map +1 -1
  88. package/dist/components/list/list-item.js.map +1 -1
  89. package/dist/components/list/list.js.map +1 -1
  90. package/dist/components/loading/loading.js.map +1 -1
  91. package/dist/components/message/message-box.js.map +1 -1
  92. package/dist/components/message/message.js.map +1 -1
  93. package/dist/components/message-confirm/message-confirm-box.js.map +1 -1
  94. package/dist/components/message-confirm/message-confirm.js.map +1 -1
  95. package/dist/components/multi-select/multi-select-option.js.map +1 -1
  96. package/dist/components/multi-select/multi-select.js.map +1 -1
  97. package/dist/components/multi-tree-select/multi-tree-select.js.map +1 -1
  98. package/dist/components/nav/nav-icon.js.map +1 -1
  99. package/dist/components/nav/nav-item-collapsed.js.map +1 -1
  100. package/dist/components/nav/nav-item.js.map +1 -1
  101. package/dist/components/nav/nav-sub-collapsed.js.map +1 -1
  102. package/dist/components/nav/nav-sub.js.map +1 -1
  103. package/dist/components/nav/nav.js.map +1 -1
  104. package/dist/components/notification/notification-box.js.map +1 -1
  105. package/dist/components/notification/notification.js.map +1 -1
  106. package/dist/components/number/number.js.map +1 -1
  107. package/dist/components/number-input/number-input.js.map +1 -1
  108. package/dist/components/number-range-input/number-range-input.js.map +1 -1
  109. package/dist/components/paginator/paginator.js.map +1 -1
  110. package/dist/components/palette/palette-alpha.js.map +1 -1
  111. package/dist/components/palette/palette-color-switch.js.map +1 -1
  112. package/dist/components/palette/palette-hue.js.map +1 -1
  113. package/dist/components/palette/palette-sv.js.map +1 -1
  114. package/dist/components/palette/palette.js.map +1 -1
  115. package/dist/components/password-input/password-input.js.map +1 -1
  116. package/dist/components/pop-confirm/pop-confirm.js.map +1 -1
  117. package/dist/components/progress/progress.js.map +1 -1
  118. package/dist/components/progress-nodes/progress-nodes.js.map +1 -1
  119. package/dist/components/radio/radio.js.map +1 -1
  120. package/dist/components/radio-group/radio-group.js.map +1 -1
  121. package/dist/components/rich-text-editor/rich-text-editor.js.map +1 -1
  122. package/dist/components/rich-text-editor/toolbar.js.map +1 -1
  123. package/dist/components/scroll/scroll-bar.js.map +1 -1
  124. package/dist/components/scroll/scroll.js.map +1 -1
  125. package/dist/components/segment/segment.js.map +1 -1
  126. package/dist/components/select/select.js +9 -5
  127. package/dist/components/select/select.js.map +1 -1
  128. package/dist/components/slider/slider-thumb.js.map +1 -1
  129. package/dist/components/slider/slider.js.map +1 -1
  130. package/dist/components/steps/steps.js.map +1 -1
  131. package/dist/components/switch/switch.js.map +1 -1
  132. package/dist/components/table/table-body.js.map +1 -1
  133. package/dist/components/table/table-cell.js.map +1 -1
  134. package/dist/components/table/table-foot.js.map +1 -1
  135. package/dist/components/table/table-head.js.map +1 -1
  136. package/dist/components/table/table-row.js.map +1 -1
  137. package/dist/components/table/table.js.map +1 -1
  138. package/dist/components/table-editor/table-editor.js.map +1 -1
  139. package/dist/components/tabs/tabs-horizontal.js.map +1 -1
  140. package/dist/components/tabs/tabs-vertical.js.map +1 -1
  141. package/dist/components/tabs/tabs.js.map +1 -1
  142. package/dist/components/tag/tag.js.map +1 -1
  143. package/dist/components/text/text.js.map +1 -1
  144. package/dist/components/textarea/textarea.js.map +1 -1
  145. package/dist/components/theme/theme.js.map +1 -1
  146. package/dist/components/tip/tip.js.map +1 -1
  147. package/dist/components/tree/tree-node.js.map +1 -1
  148. package/dist/components/tree/tree.js.map +1 -1
  149. package/dist/components/tree-select/tree-select.js +19 -10
  150. package/dist/components/tree-select/tree-select.js.map +1 -1
  151. package/dist/components/watermark/watermark.js.map +1 -1
  152. package/dist/types/cascade.d.ts +5 -0
  153. package/dist/types/select.d.ts +8 -2
  154. package/dist/types/tree-select.d.ts +8 -2
  155. package/package.json +19 -18
  156. package/src/components/batch-edit/__test__/batch-edit.test.ts +1 -1
  157. package/src/components/button/__test__/button.test.ts +1 -1
  158. package/src/components/cascade/__test__/cascade.test.ts +26 -1
  159. package/src/components/cascade/use-select.ts +5 -5
  160. package/src/components/collapse/__test__/collapse.test.ts +1 -1
  161. package/src/components/condition-editor/__test__/condition-editor.test.ts +1 -1
  162. package/src/components/contextmenu/__test__/contextmenu.test.ts +1 -1
  163. package/src/components/date-picker/__test__/date-picker.test.ts +1 -1
  164. package/src/components/date-range-picker/__test__/date-range-picker.test.ts +1 -1
  165. package/src/components/drawer/__test__/drawer.test.ts +1 -1
  166. package/src/components/expression-editor/__test__/chip.test.ts +1 -1
  167. package/src/components/expression-editor/__test__/editor.test.ts +1 -1
  168. package/src/components/expression-editor/__test__/expression-editor.test.ts +1 -1
  169. package/src/components/expression-editor/__test__/mention.test.ts +1 -1
  170. package/src/components/expression-editor/__test__/model.test.ts +1 -1
  171. package/src/components/file-viewer/__test__/helper.test.ts +1 -1
  172. package/src/components/file-viewer/previewers/pdf-previewer.vue +6 -1
  173. package/src/components/form/__test__/form.test.ts +1 -1
  174. package/src/components/form/__test__/is-field-modified.test.ts +1 -1
  175. package/src/components/form-item/__test__/form-item.test.ts +1 -1
  176. package/src/components/image-cropper/__test__/draw-crop.test.ts +1 -1
  177. package/src/components/image-cropper/__test__/image-cropper.test.ts +1 -1
  178. package/src/components/image-cropper/__test__/use-transform.test.ts +1 -1
  179. package/src/components/kanban/__test__/kanban.test.ts +1 -1
  180. package/src/components/message-confirm/__test__/message-confirm.test.ts +1 -1
  181. package/src/components/multi-tree-select/__test__/multi-tree-select.test.ts +1 -1
  182. package/src/components/number-input/__test__/number-input.test.ts +1 -1
  183. package/src/components/number-range-input/__test__/number-range-input.test.ts +1 -1
  184. package/src/components/palette/__test__/color-transform.test.ts +1 -1
  185. package/src/components/palette/__test__/palette.test.ts +1 -1
  186. package/src/components/password-input/__test__/password-input.test.ts +1 -1
  187. package/src/components/radio-group/__test__/radio-group.test.ts +1 -1
  188. package/src/components/rich-text-editor/__test__/image-node.test.ts +1 -1
  189. package/src/components/segment/__test__/segment.test.ts +1 -1
  190. package/src/components/select/__test__/select.test.ts +68 -1
  191. package/src/components/select/select.vue +15 -5
  192. package/src/components/table/__test__/col-width.test.ts +1 -1
  193. package/src/components/table/__test__/column-style.test.ts +1 -1
  194. package/src/components/table-editor/__test__/table-editor.test.ts +1 -1
  195. package/src/components/tree-select/__test__/tree-select.test.ts +50 -1
  196. package/src/components/tree-select/tree-select.vue +28 -11
  197. package/src/env.d.ts +5 -0
  198. package/src/types/cascade.ts +5 -0
  199. package/src/types/select.ts +8 -2
  200. package/src/types/tree-select.ts +9 -2
@@ -1 +1 @@
1
- {"version":3,"file":"sheet-previewer.js","names":[],"sources":["../../../../src/components/file-viewer/previewers/sheet-previewer.vue"],"sourcesContent":["<template>\n <div :class=\"cls.e('sheet')\">\n <div v-if=\"unavailable\" :class=\"cls.e('empty')\">\n <u-empty text=\"无法预览表格:未安装 @veltra/sheet-core\" :size=\"32\" />\n </div>\n <template v-else>\n <div v-if=\"truncated\" :class=\"cls.e('sheet-note')\">\n 共 {{ totalRows.toLocaleString() }} 行,超出预览上限\n {{ maxRows.toLocaleString() }} 行,已全量加载\n </div>\n <div v-if=\"sheets.length > 1\" :class=\"cls.e('sheet-tabs')\">\n <button\n v-for=\"(s, i) in sheets\"\n :key=\"s.name\"\n :class=\"[cls.e('sheet-tab'), bem.is('active', i === activeSheetIndex)]\"\n @click=\"activeSheetIndex = i\"\n >\n {{ s.name }}\n </button>\n </div>\n <div ref=\"container\" :class=\"cls.e('sheet-stage')\" />\n <div v-if=\"loading\" :class=\"cls.e('loading')\">加载中…</div>\n </template>\n </div>\n</template>\n\n<script lang=\"ts\" setup>\nimport { bem } from '@veltra/utils'\nimport { onBeforeUnmount, ref, shallowRef, useTemplateRef, watch } from 'vue'\n\nimport type { FileViewerItem } from '../../../types/file-viewer'\nimport { UEmpty } from '../../empty'\nimport { getExtension, toArrayBuffer } from '../helper'\n\ndefineOptions({ name: 'UFileViewerSheetPreviewer' })\n\n/** 仅类型查询;运行时通过动态 import 加载,未安装时不炸主入口 */\ntype SheetCoreModule = typeof import('@veltra/sheet-core') &\n typeof import('@veltra/sheet-core/grid')\ntype Sheet = InstanceType<SheetCoreModule['Sheet']>\ntype SheetGrid = InstanceType<SheetCoreModule['SheetGrid']>\n\nconst props = withDefaults(defineProps<{ file: FileViewerItem; maxRows?: number }>(), {\n maxRows: 50_000\n})\n\nconst emit = defineEmits<{ (e: 'error', err: unknown): void }>()\n\nconst cls = bem('file-viewer')\nconst container = useTemplateRef<HTMLDivElement>('container')\nconst loading = ref(true)\nconst unavailable = ref(false)\nconst truncated = ref(false)\nconst totalRows = ref(0)\nconst sheets = shallowRef<Sheet[]>([])\nconst activeSheetIndex = ref(0)\n\nlet controller: AbortController | undefined\n/** 递增 token:importXlsx 无 AbortSignal,靠它防止切文件后旧解析结果落地 */\nlet loadToken = 0\nlet grid: SheetGrid | undefined\nlet sheetCore: SheetCoreModule | undefined\n\nfunction releaseGrid() {\n grid?.release()\n grid = undefined\n}\n\n/** 动态加载 sheet-core;未安装 optional peer 时返回 undefined */\nasync function resolveSheetCore(): Promise<SheetCoreModule | undefined> {\n if (sheetCore) return sheetCore\n try {\n const [core, grid] = await Promise.all([\n import('@veltra/sheet-core'),\n import('@veltra/sheet-core/grid')\n ])\n sheetCore = { ...core, ...grid }\n return sheetCore\n } catch {\n return undefined\n }\n}\n\n/** 解析文件为 Sheet 列表:xlsx 多表(importXlsx 建工作簿);csv 单表,表名取文件名 */\nasync function parseFile(\n core: SheetCoreModule,\n file: FileViewerItem,\n signal?: AbortSignal\n): Promise<Sheet[]> {\n const buf = await toArrayBuffer(file.src, signal)\n if (getExtension(file.name) === 'csv') {\n const text = new TextDecoder('utf-8', { fatal: false }).decode(buf)\n const sheet = new core.Sheet(file.name)\n core.importCsv(text, sheet)\n return [sheet]\n }\n const workbook = await core.importXlsx(buf)\n return workbook.getSheets()\n}\n\nfunction renderActive() {\n const sheet = sheets.value[activeSheetIndex.value]\n const el = container.value\n releaseGrid()\n if (!sheet || !el || !sheetCore) return\n\n // SheetGrid 的 rows 选项是渲染行数下限(构造时数据高水位恒并入渲染尺寸),\n // 不能用作行数上限;deleteRows 硬裁又会让引用被裁区域的公式显示 #REF!,\n // 故 maxRows 只驱动截断提示,不裁模型\n const total = sheet.rowCount\n totalRows.value = total\n truncated.value = props.maxRows > 0 && total > props.maxRows\n\n grid = new sheetCore.SheetGrid({ container: el, sheet, readonly: true })\n}\n\nasync function load() {\n const token = ++loadToken\n controller?.abort()\n controller = new AbortController()\n loading.value = true\n truncated.value = false\n releaseGrid()\n sheets.value = []\n activeSheetIndex.value = 0\n\n try {\n const core = await resolveSheetCore()\n if (token !== loadToken) return\n if (!core) {\n unavailable.value = true\n emit('error', new Error('未安装 @veltra/sheet-core,无法预览 Excel/CSV'))\n return\n }\n unavailable.value = false\n\n const parsed = await parseFile(core, props.file, controller.signal)\n if (token !== loadToken) return\n sheets.value = parsed\n renderActive()\n } catch (err) {\n if (token !== loadToken) return\n if ((err as { name?: string })?.name === 'AbortError') return\n emit('error', err)\n } finally {\n if (token === loadToken) loading.value = false\n }\n}\n\nwatch(() => props.file, load, { immediate: true })\nwatch(activeSheetIndex, renderActive)\n\nonBeforeUnmount(() => {\n controller?.abort()\n releaseGrid()\n sheets.value = []\n})\n</script>\n"],"mappings":"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"}
1
+ {"version":3,"file":"sheet-previewer.js","names":["_openBlock","_createElementBlock","_normalizeClass","_unref","_createVNode","UEmpty","_Fragment","_toDisplayString","_createCommentVNode","_renderList","_createElementVNode"],"sources":["../../../../src/components/file-viewer/previewers/sheet-previewer.vue"],"sourcesContent":["<template>\n <div :class=\"cls.e('sheet')\">\n <div v-if=\"unavailable\" :class=\"cls.e('empty')\">\n <u-empty text=\"无法预览表格:未安装 @veltra/sheet-core\" :size=\"32\" />\n </div>\n <template v-else>\n <div v-if=\"truncated\" :class=\"cls.e('sheet-note')\">\n 共 {{ totalRows.toLocaleString() }} 行,超出预览上限\n {{ maxRows.toLocaleString() }} 行,已全量加载\n </div>\n <div v-if=\"sheets.length > 1\" :class=\"cls.e('sheet-tabs')\">\n <button\n v-for=\"(s, i) in sheets\"\n :key=\"s.name\"\n :class=\"[cls.e('sheet-tab'), bem.is('active', i === activeSheetIndex)]\"\n @click=\"activeSheetIndex = i\"\n >\n {{ s.name }}\n </button>\n </div>\n <div ref=\"container\" :class=\"cls.e('sheet-stage')\" />\n <div v-if=\"loading\" :class=\"cls.e('loading')\">加载中…</div>\n </template>\n </div>\n</template>\n\n<script lang=\"ts\" setup>\nimport { bem } from '@veltra/utils'\nimport { onBeforeUnmount, ref, shallowRef, useTemplateRef, watch } from 'vue'\n\nimport type { FileViewerItem } from '../../../types/file-viewer'\nimport { UEmpty } from '../../empty'\nimport { getExtension, toArrayBuffer } from '../helper'\n\ndefineOptions({ name: 'UFileViewerSheetPreviewer' })\n\n/** 仅类型查询;运行时通过动态 import 加载,未安装时不炸主入口 */\ntype SheetCoreModule = typeof import('@veltra/sheet-core') &\n typeof import('@veltra/sheet-core/grid')\ntype Sheet = InstanceType<SheetCoreModule['Sheet']>\ntype SheetGrid = InstanceType<SheetCoreModule['SheetGrid']>\n\nconst props = withDefaults(defineProps<{ file: FileViewerItem; maxRows?: number }>(), {\n maxRows: 50_000\n})\n\nconst emit = defineEmits<{ (e: 'error', err: unknown): void }>()\n\nconst cls = bem('file-viewer')\nconst container = useTemplateRef<HTMLDivElement>('container')\nconst loading = ref(true)\nconst unavailable = ref(false)\nconst truncated = ref(false)\nconst totalRows = ref(0)\nconst sheets = shallowRef<Sheet[]>([])\nconst activeSheetIndex = ref(0)\n\nlet controller: AbortController | undefined\n/** 递增 token:importXlsx 无 AbortSignal,靠它防止切文件后旧解析结果落地 */\nlet loadToken = 0\nlet grid: SheetGrid | undefined\nlet sheetCore: SheetCoreModule | undefined\n\nfunction releaseGrid() {\n grid?.release()\n grid = undefined\n}\n\n/** 动态加载 sheet-core;未安装 optional peer 时返回 undefined */\nasync function resolveSheetCore(): Promise<SheetCoreModule | undefined> {\n if (sheetCore) return sheetCore\n try {\n const [core, grid] = await Promise.all([\n import('@veltra/sheet-core'),\n import('@veltra/sheet-core/grid')\n ])\n sheetCore = { ...core, ...grid }\n return sheetCore\n } catch {\n return undefined\n }\n}\n\n/** 解析文件为 Sheet 列表:xlsx 多表(importXlsx 建工作簿);csv 单表,表名取文件名 */\nasync function parseFile(\n core: SheetCoreModule,\n file: FileViewerItem,\n signal?: AbortSignal\n): Promise<Sheet[]> {\n const buf = await toArrayBuffer(file.src, signal)\n if (getExtension(file.name) === 'csv') {\n const text = new TextDecoder('utf-8', { fatal: false }).decode(buf)\n const sheet = new core.Sheet(file.name)\n core.importCsv(text, sheet)\n return [sheet]\n }\n const workbook = await core.importXlsx(buf)\n return workbook.getSheets()\n}\n\nfunction renderActive() {\n const sheet = sheets.value[activeSheetIndex.value]\n const el = container.value\n releaseGrid()\n if (!sheet || !el || !sheetCore) return\n\n // SheetGrid 的 rows 选项是渲染行数下限(构造时数据高水位恒并入渲染尺寸),\n // 不能用作行数上限;deleteRows 硬裁又会让引用被裁区域的公式显示 #REF!,\n // 故 maxRows 只驱动截断提示,不裁模型\n const total = sheet.rowCount\n totalRows.value = total\n truncated.value = props.maxRows > 0 && total > props.maxRows\n\n grid = new sheetCore.SheetGrid({ container: el, sheet, readonly: true })\n}\n\nasync function load() {\n const token = ++loadToken\n controller?.abort()\n controller = new AbortController()\n loading.value = true\n truncated.value = false\n releaseGrid()\n sheets.value = []\n activeSheetIndex.value = 0\n\n try {\n const core = await resolveSheetCore()\n if (token !== loadToken) return\n if (!core) {\n unavailable.value = true\n emit('error', new Error('未安装 @veltra/sheet-core,无法预览 Excel/CSV'))\n return\n }\n unavailable.value = false\n\n const parsed = await parseFile(core, props.file, controller.signal)\n if (token !== loadToken) return\n sheets.value = parsed\n renderActive()\n } catch (err) {\n if (token !== loadToken) return\n if ((err as { name?: string })?.name === 'AbortError') return\n emit('error', err)\n } finally {\n if (token === loadToken) loading.value = false\n }\n}\n\nwatch(() => props.file, load, { immediate: true })\nwatch(activeSheetIndex, renderActive)\n\nonBeforeUnmount(() => {\n controller?.abort()\n releaseGrid()\n sheets.value = []\n})\n</script>\n"],"mappings":"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"}
@@ -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: 'UFileViewerTextPreviewer' })\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,SAAa,OAAO,IAAI,QAAQ,OAAO,KAAA,CAAM,QAAQ,CAAC,EAAE;GACrE,OAAO,IAAI,QAAQ,KAAA,CAAM,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,CAAC,CAAC,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;;GAzEC,OAAA,UAAA,GAAA,YAMW,MAAA,WAAA,GAAA;IAND,KAAI;IAAO,OAAK,eAAE,MAAA,GAAA,CAAG,CAAC,EAAC,MAAA,CAAA;;IAC/B,SAAA,cAEM;KAFK,UAAA,SAAX,UAAA,GAAA,mBAEM,OAAA;;MAFiB,OAAK,eAAE,MAAA,GAAA,CAAG,CAAC,EAAC,YAAA,CAAA;KAAgB,GAAA,kBACrC,gBAAG,SAAS,QAAA,QAAQ,CAAA,GAAA,CAAA,KAAA,mBAAA,QAAA,IAAA;KAElC,mBAA6D,OAAA,EAAvD,OAAK,eAAE,MAAA,GAAA,CAAG,CAAC,EAAC,UAAA,CAAA,EAAA,GAAc,CAAA,mBAAuB,QAAA,MAAA,gBAAd,KAAA,KAAI,GAAA,CAAA,CAAA,GAAA,CAAA;KAClC,QAAA,SAAX,UAAA,GAAA,mBAAwD,OAAA;;MAAnC,OAAK,eAAE,MAAA,GAAA,CAAG,CAAC,EAAC,SAAA,CAAA;KAAa,GAAA,QAAI,CAAA,KAAA,mBAAA,QAAA,IAAA"}
1
+ {"version":3,"file":"text-previewer.js","names":["_openBlock","_createBlock","_unref","UScroll","_normalizeClass","_withCtx","_createElementBlock","_toDisplayString","_createCommentVNode","_createElementVNode"],"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: 'UFileViewerTextPreviewer' })\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,SAAa,OAAO,IAAI,QAAQ,OAAO,KAAA,CAAM,QAAQ,CAAC,EAAE;GACrE,OAAO,IAAI,QAAQ,KAAA,CAAM,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,CAAC,CAAC,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;;GAzEC,OAAAA,UAAA,GAAAC,YAMWC,MAAAC,WAAA,GAAA;IAND,KAAI;IAAO,OAAKC,eAAEF,MAAA,GAAA,CAAG,CAAC,EAAC,MAAA,CAAA;;IAC/B,SAAAG,cAEM;KAFK,UAAA,SAAXL,UAAA,GAAAM,mBAEM,OAAA;;MAFiB,OAAKF,eAAEF,MAAA,GAAA,CAAG,CAAC,EAAC,YAAA,CAAA;KAAgB,GAAA,kBACrCK,gBAAG,SAAS,QAAA,QAAQ,CAAA,GAAA,CAAA,KAAAC,mBAAA,QAAA,IAAA;KAElCC,mBAA6D,OAAA,EAAvD,OAAKL,eAAEF,MAAA,GAAA,CAAG,CAAC,EAAC,UAAA,CAAA,EAAA,GAAc,CAAAO,mBAAuB,QAAA,MAAAF,gBAAd,KAAA,KAAI,GAAA,CAAA,CAAA,GAAA,CAAA;KAClC,QAAA,SAAXP,UAAA,GAAAM,mBAAwD,OAAA;;MAAnC,OAAKF,eAAEF,MAAA,GAAA,CAAG,CAAC,EAAC,SAAA,CAAA;KAAa,GAAA,QAAI,CAAA,KAAAM,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: 'UFileViewerVideoPreviewer' })\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;;GArEC,OAAA,UAAA,GAAA,mBAWM,OAAA,EAXA,OAAK,eAAE,MAAA,GAAA,CAAG,CAAC,EAAC,OAAA,CAAA,EAAA,GAER,CAAA,IAAA,SADR,UAAA,GAAA,mBASE,SAAA;;IAPI,SAAA;IAAJ,KAAI;IACH,KAAK,IAAA;IACL,MAAM,QAAA,KAAK;IACZ,UAAA;IACA,SAAQ;IACR,aAAA;IACC,SAAO"}
1
+ {"version":3,"file":"video-previewer.js","names":["_openBlock","_createElementBlock","_normalizeClass","_unref","_createCommentVNode"],"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: 'UFileViewerVideoPreviewer' })\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;;GArEC,OAAAA,UAAA,GAAAC,mBAWM,OAAA,EAXA,OAAKC,eAAEC,MAAA,GAAA,CAAG,CAAC,EAAC,OAAA,CAAA,EAAA,GAER,CAAA,IAAA,SADRH,UAAA,GAAAC,mBASE,SAAA;;IAPI,SAAA;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: 'UFloatButton' })\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;;GAlFE,OAAA,UAAA,GAAA,YAwBW,UAAA,EAxBD,IAAG,OAAM,GAAA,CACjB,mBAsBM,OAAA;IArBH,OAAK,eAAE,MAAA,GAAA,CAAG,CAAC,CAAC;IACZ,cAAY;IACZ,cAAY;IACT,SAAA;IAAJ,KAAI;GAEJ,GAAA,EAAA,UAAA,IAAA,GAAA,mBAeW,UAAA,MAAA,WAde,QAAA,QAAhB,MAAM,UAAK;IADrB,OAAA,UAAA,GAAA,YAeW,MAAA,WAAA,GAAA;KAbR,KAAK,KAAK;KACV,OAAK,eAAA,CAAG,MAAA,GAAA,CAAG,CAAC,EAAC,MAAA,GAAU,MAAA,GAAA,CAAG,CAAC,GAAE,SAAU,UAAK,CAAA,CAAA,CAAA;KAC7C,QAAA;KACC,MAAM,QAAA;KACN,MAAM,KAAK,QAAI;;KACZ,SAAA;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;;KAE1B,SAAA,cAAiE,CAAnD,KAAK,QAAnB,UAAA,GAAA,YAAiE,MAAA,WAAA,GAAA,EAAA,KAAA,EAAA,GAAA;MAAvC,SAAA,cAA6B,EAA7B,UAAA,GAAA,YAA6B,wBAAb,KAAK,IAAI,CAAA,EAAA,CAAA;;KACnD,GAAA,IAAA,MAAA,UAAA,GAAA,mBAAuD,QAAA,YAAA,gBAAvC,KAAK,OAAI,MAAS,KAAK,IAAG,EAAA,GAAA,CAAA,EAAA,CAAA"}
1
+ {"version":3,"file":"float-button.js","names":["_openBlock","_createBlock","_Teleport","_createElementVNode","_normalizeClass","_unref","_createElementBlock","_Fragment","_renderList","UButton","_normalizeStyle","_withCtx","UIcon","_resolveDynamicComponent","_toDisplayString"],"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: 'UFloatButton' })\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;;GAlFE,OAAAA,UAAA,GAAAC,YAwBWC,UAAA,EAxBD,IAAG,OAAM,GAAA,CACjBC,mBAsBM,OAAA;IArBH,OAAKC,eAAEC,MAAA,GAAA,CAAG,CAAC,CAAC;IACZ,cAAY;IACZ,cAAY;IACT,SAAA;IAAJ,KAAI;GAEJ,GAAA,EAAAL,UAAA,IAAA,GAAAM,mBAeWC,UAAA,MAAAC,WAde,QAAA,QAAhB,MAAM,UAAK;IADrB,OAAAR,UAAA,GAAAC,YAeWI,MAAAI,WAAA,GAAA;KAbR,KAAK,KAAK;KACV,OAAKL,eAAA,CAAGC,MAAA,GAAA,CAAG,CAAC,EAAC,MAAA,GAAUA,MAAA,GAAA,CAAG,CAAC,GAAE,SAAU,UAAK,CAAA,CAAA,CAAA;KAC7C,QAAA;KACC,MAAM,QAAA;KACN,MAAM,KAAK,QAAI;;KACZ,SAAA;KAAJ,KAAI;KACH,OAAKK,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;;KAE1B,SAAAC,cAAiE,CAAnD,KAAK,QAAnBX,UAAA,GAAAC,YAAiEI,MAAAO,WAAA,GAAA,EAAA,KAAA,EAAA,GAAA;MAAvC,SAAAD,cAA6B,EAA7BX,UAAA,GAAAC,YAA6BY,wBAAb,KAAK,IAAI,CAAA,EAAA,CAAA;;KACnD,GAAA,IAAA,MAAAb,UAAA,GAAAM,mBAAuD,QAAA,YAAAQ,gBAAvC,KAAK,OAAI,MAAS,KAAK,IAAG,EAAA,GAAA,CAAA,EAAA,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"form.js","names":[],"sources":["../../../src/components/form/form.vue"],"sourcesContent":["<template>\n <u-grid\n tag=\"form\"\n ref=\"grid\"\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, renderKey } of getSlotsNodes()\"\n :key=\"renderKey\"\n >\n <u-form-item v-if=\"!isFormItem && field\" v-bind=\"formItemProps\">\n <component\n :is=\"node\"\n :model-value=\"modelValue ?? o(model ?? {}).get(field)\"\n @update:model-value=\"handleUpdateValue(field, $event)\"\n />\n <div v-if=\"shouldShowModified(field)\" :class=\"cls.e('data-before')\">\n <span :class=\"cls.e('changed-tag')\">{{ modifiedLabel }}</span>\n <component :is=\"createModifiedPreview(node, field)\" />\n </div>\n </u-form-item>\n\n <component v-else :is=\"node\" />\n </template>\n </u-grid>\n</template>\n\n<script lang=\"tsx\" setup>\nimport { o } from '@cat-kit/core'\nimport { bem } from '@veltra/utils'\nimport { provideFormContext } from '@veltra/utils'\nimport { nextTick, toRef, useTemplateRef, type VNode } from 'vue'\n\nimport type { BreakCols, FormProps, _FormExposed, FormEmits } from '../../types'\nimport { UFormItem } from '../form-item'\nimport { UGrid } from '../grid'\nimport { isFieldModified } from './is-field-modified'\nimport { useFormFields } from './use-form-fields'\nimport { forkUnmountedVNode, useNodeInterceptor } from './use-node-interceptor'\n\ndefineOptions({ name: 'UForm' })\n\nconst props = withDefaults(defineProps<FormProps>(), { modifiedLabel: '变更前:' })\n\nconst emit = defineEmits<FormEmits>()\n\ndefineSlots<{ default(props?: { data: Record<string, any> | undefined }): any }>()\n\nconst cls = bem('form')\nconst formItemCls = bem('form-item')\nconst gridRef = useTemplateRef('grid')\n\nconst breakpointCols: BreakCols = { xs: 1, md: 2, lg: 3, xl: 4, default: 4 }\n\nconst {\n validate: runValidate,\n clearValidate,\n reset,\n registerField,\n unregisterField,\n shouldValidate,\n getBaselineModel\n} = useFormFields({ props })\n\nasync function validate(keys?: string[]) {\n const valid = await runValidate(keys)\n if (!valid) {\n await nextTick()\n\n gridRef.value?.el\n ?.querySelector(`.${formItemCls.e('error-text')}`)\n ?.scrollIntoView({ block: 'center' })\n }\n return valid\n}\n\nfunction handleFieldUpdate(field: string, value: any) {\n emit('field:update', field, value)\n}\n\nprovideFormContext({\n formProps: props,\n registerField,\n unregisterField,\n validateFields: validate,\n shouldValidate,\n handleFieldUpdate\n})\n\nconst { getSlotsNodes } = useNodeInterceptor()\n\nfunction handleUpdateValue(field: string, value: any) {\n if (!props.model) return\n o(props.model).set(field, value)\n}\n\nfunction getBaselineFieldValue(field: string) {\n return o(getBaselineModel() ?? {}).get(field)\n}\n\nfunction createModifiedPreview(node: VNode, field: string) {\n return forkUnmountedVNode(node, { readonly: true, modelValue: getBaselineFieldValue(field) })\n}\n\nfunction shouldShowModified(field: string) {\n if (!props.showModified) return false\n const baseline = getBaselineModel()\n if (!baseline || !props.model) return false\n const current = o(props.model).get(field)\n const initial = o(baseline).get(field)\n return isFieldModified(current, initial)\n}\n\ndefineExpose<_FormExposed>({ el: toRef(() => gridRef.value?.el), validate, clearValidate, reset })\n</script>\n"],"mappings":""}
1
+ {"version":3,"file":"form.js","names":["_sfc_main"],"sources":["../../../src/components/form/form.vue"],"sourcesContent":["<template>\n <u-grid\n tag=\"form\"\n ref=\"grid\"\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, renderKey } of getSlotsNodes()\"\n :key=\"renderKey\"\n >\n <u-form-item v-if=\"!isFormItem && field\" v-bind=\"formItemProps\">\n <component\n :is=\"node\"\n :model-value=\"modelValue ?? o(model ?? {}).get(field)\"\n @update:model-value=\"handleUpdateValue(field, $event)\"\n />\n <div v-if=\"shouldShowModified(field)\" :class=\"cls.e('data-before')\">\n <span :class=\"cls.e('changed-tag')\">{{ modifiedLabel }}</span>\n <component :is=\"createModifiedPreview(node, field)\" />\n </div>\n </u-form-item>\n\n <component v-else :is=\"node\" />\n </template>\n </u-grid>\n</template>\n\n<script lang=\"tsx\" setup>\nimport { o } from '@cat-kit/core'\nimport { bem } from '@veltra/utils'\nimport { provideFormContext } from '@veltra/utils'\nimport { nextTick, toRef, useTemplateRef, type VNode } from 'vue'\n\nimport type { BreakCols, FormProps, _FormExposed, FormEmits } from '../../types'\nimport { UFormItem } from '../form-item'\nimport { UGrid } from '../grid'\nimport { isFieldModified } from './is-field-modified'\nimport { useFormFields } from './use-form-fields'\nimport { forkUnmountedVNode, useNodeInterceptor } from './use-node-interceptor'\n\ndefineOptions({ name: 'UForm' })\n\nconst props = withDefaults(defineProps<FormProps>(), { modifiedLabel: '变更前:' })\n\nconst emit = defineEmits<FormEmits>()\n\ndefineSlots<{ default(props?: { data: Record<string, any> | undefined }): any }>()\n\nconst cls = bem('form')\nconst formItemCls = bem('form-item')\nconst gridRef = useTemplateRef('grid')\n\nconst breakpointCols: BreakCols = { xs: 1, md: 2, lg: 3, xl: 4, default: 4 }\n\nconst {\n validate: runValidate,\n clearValidate,\n reset,\n registerField,\n unregisterField,\n shouldValidate,\n getBaselineModel\n} = useFormFields({ props })\n\nasync function validate(keys?: string[]) {\n const valid = await runValidate(keys)\n if (!valid) {\n await nextTick()\n\n gridRef.value?.el\n ?.querySelector(`.${formItemCls.e('error-text')}`)\n ?.scrollIntoView({ block: 'center' })\n }\n return valid\n}\n\nfunction handleFieldUpdate(field: string, value: any) {\n emit('field:update', field, value)\n}\n\nprovideFormContext({\n formProps: props,\n registerField,\n unregisterField,\n validateFields: validate,\n shouldValidate,\n handleFieldUpdate\n})\n\nconst { getSlotsNodes } = useNodeInterceptor()\n\nfunction handleUpdateValue(field: string, value: any) {\n if (!props.model) return\n o(props.model).set(field, value)\n}\n\nfunction getBaselineFieldValue(field: string) {\n return o(getBaselineModel() ?? {}).get(field)\n}\n\nfunction createModifiedPreview(node: VNode, field: string) {\n return forkUnmountedVNode(node, { readonly: true, modelValue: getBaselineFieldValue(field) })\n}\n\nfunction shouldShowModified(field: string) {\n if (!props.showModified) return false\n const baseline = getBaselineModel()\n if (!baseline || !props.model) return false\n const current = o(props.model).get(field)\n const initial = o(baseline).get(field)\n return isFieldModified(current, initial)\n}\n\ndefineExpose<_FormExposed>({ el: toRef(() => gridRef.value?.el), validate, clearValidate, reset })\n</script>\n"],"mappings":""}
@@ -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=\"grid\"\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, renderKey } of getSlotsNodes()\"\n :key=\"renderKey\"\n >\n <u-form-item v-if=\"!isFormItem && field\" v-bind=\"formItemProps\">\n <component\n :is=\"node\"\n :model-value=\"modelValue ?? o(model ?? {}).get(field)\"\n @update:model-value=\"handleUpdateValue(field, $event)\"\n />\n <div v-if=\"shouldShowModified(field)\" :class=\"cls.e('data-before')\">\n <span :class=\"cls.e('changed-tag')\">{{ modifiedLabel }}</span>\n <component :is=\"createModifiedPreview(node, field)\" />\n </div>\n </u-form-item>\n\n <component v-else :is=\"node\" />\n </template>\n </u-grid>\n</template>\n\n<script lang=\"tsx\" setup>\nimport { o } from '@cat-kit/core'\nimport { bem } from '@veltra/utils'\nimport { provideFormContext } from '@veltra/utils'\nimport { nextTick, toRef, useTemplateRef, type VNode } from 'vue'\n\nimport type { BreakCols, FormProps, _FormExposed, FormEmits } from '../../types'\nimport { UFormItem } from '../form-item'\nimport { UGrid } from '../grid'\nimport { isFieldModified } from './is-field-modified'\nimport { useFormFields } from './use-form-fields'\nimport { forkUnmountedVNode, useNodeInterceptor } from './use-node-interceptor'\n\ndefineOptions({ name: 'UForm' })\n\nconst props = withDefaults(defineProps<FormProps>(), { modifiedLabel: '变更前:' })\n\nconst emit = defineEmits<FormEmits>()\n\ndefineSlots<{ default(props?: { data: Record<string, any> | undefined }): any }>()\n\nconst cls = bem('form')\nconst formItemCls = bem('form-item')\nconst gridRef = useTemplateRef('grid')\n\nconst breakpointCols: BreakCols = { xs: 1, md: 2, lg: 3, xl: 4, default: 4 }\n\nconst {\n validate: runValidate,\n clearValidate,\n reset,\n registerField,\n unregisterField,\n shouldValidate,\n getBaselineModel\n} = useFormFields({ props })\n\nasync function validate(keys?: string[]) {\n const valid = await runValidate(keys)\n if (!valid) {\n await nextTick()\n\n gridRef.value?.el\n ?.querySelector(`.${formItemCls.e('error-text')}`)\n ?.scrollIntoView({ block: 'center' })\n }\n return valid\n}\n\nfunction handleFieldUpdate(field: string, value: any) {\n emit('field:update', field, value)\n}\n\nprovideFormContext({\n formProps: props,\n registerField,\n unregisterField,\n validateFields: validate,\n shouldValidate,\n handleFieldUpdate\n})\n\nconst { getSlotsNodes } = useNodeInterceptor()\n\nfunction handleUpdateValue(field: string, value: any) {\n if (!props.model) return\n o(props.model).set(field, value)\n}\n\nfunction getBaselineFieldValue(field: string) {\n return o(getBaselineModel() ?? {}).get(field)\n}\n\nfunction createModifiedPreview(node: VNode, field: string) {\n return forkUnmountedVNode(node, { readonly: true, modelValue: getBaselineFieldValue(field) })\n}\n\nfunction shouldShowModified(field: string) {\n if (!props.showModified) return false\n const baseline = getBaselineModel()\n if (!baseline || !props.model) return false\n const current = o(props.model).get(field)\n const initial = o(baseline).get(field)\n return isFieldModified(current, initial)\n}\n\ndefineExpose<_FormExposed>({ el: toRef(() => gridRef.value?.el), validate, clearValidate, reset })\n</script>\n"],"mappings":"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"}
1
+ {"version":3,"file":"form.vue_vue_type_script_setup_true_lang.js","names":["onUpdate:modelValue","_openBlock","_createBlock","_unref","UGrid","_withModifiers","_normalizeClass","_withCtx","_createElementBlock","_Fragment","_renderList","UFormItem","_mergeProps","_resolveDynamicComponent","_createElementVNode","_toDisplayString","_createCommentVNode"],"sources":["../../../src/components/form/form.vue"],"sourcesContent":["<template>\n <u-grid\n tag=\"form\"\n ref=\"grid\"\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, renderKey } of getSlotsNodes()\"\n :key=\"renderKey\"\n >\n <u-form-item v-if=\"!isFormItem && field\" v-bind=\"formItemProps\">\n <component\n :is=\"node\"\n :model-value=\"modelValue ?? o(model ?? {}).get(field)\"\n @update:model-value=\"handleUpdateValue(field, $event)\"\n />\n <div v-if=\"shouldShowModified(field)\" :class=\"cls.e('data-before')\">\n <span :class=\"cls.e('changed-tag')\">{{ modifiedLabel }}</span>\n <component :is=\"createModifiedPreview(node, field)\" />\n </div>\n </u-form-item>\n\n <component v-else :is=\"node\" />\n </template>\n </u-grid>\n</template>\n\n<script lang=\"tsx\" setup>\nimport { o } from '@cat-kit/core'\nimport { bem } from '@veltra/utils'\nimport { provideFormContext } from '@veltra/utils'\nimport { nextTick, toRef, useTemplateRef, type VNode } from 'vue'\n\nimport type { BreakCols, FormProps, _FormExposed, FormEmits } from '../../types'\nimport { UFormItem } from '../form-item'\nimport { UGrid } from '../grid'\nimport { isFieldModified } from './is-field-modified'\nimport { useFormFields } from './use-form-fields'\nimport { forkUnmountedVNode, useNodeInterceptor } from './use-node-interceptor'\n\ndefineOptions({ name: 'UForm' })\n\nconst props = withDefaults(defineProps<FormProps>(), { modifiedLabel: '变更前:' })\n\nconst emit = defineEmits<FormEmits>()\n\ndefineSlots<{ default(props?: { data: Record<string, any> | undefined }): any }>()\n\nconst cls = bem('form')\nconst formItemCls = bem('form-item')\nconst gridRef = useTemplateRef('grid')\n\nconst breakpointCols: BreakCols = { xs: 1, md: 2, lg: 3, xl: 4, default: 4 }\n\nconst {\n validate: runValidate,\n clearValidate,\n reset,\n registerField,\n unregisterField,\n shouldValidate,\n getBaselineModel\n} = useFormFields({ props })\n\nasync function validate(keys?: string[]) {\n const valid = await runValidate(keys)\n if (!valid) {\n await nextTick()\n\n gridRef.value?.el\n ?.querySelector(`.${formItemCls.e('error-text')}`)\n ?.scrollIntoView({ block: 'center' })\n }\n return valid\n}\n\nfunction handleFieldUpdate(field: string, value: any) {\n emit('field:update', field, value)\n}\n\nprovideFormContext({\n formProps: props,\n registerField,\n unregisterField,\n validateFields: validate,\n shouldValidate,\n handleFieldUpdate\n})\n\nconst { getSlotsNodes } = useNodeInterceptor()\n\nfunction handleUpdateValue(field: string, value: any) {\n if (!props.model) return\n o(props.model).set(field, value)\n}\n\nfunction getBaselineFieldValue(field: string) {\n return o(getBaselineModel() ?? {}).get(field)\n}\n\nfunction createModifiedPreview(node: VNode, field: string) {\n return forkUnmountedVNode(node, { readonly: true, modelValue: getBaselineFieldValue(field) })\n}\n\nfunction shouldShowModified(field: string) {\n if (!props.showModified) return false\n const baseline = getBaselineModel()\n if (!baseline || !props.model) return false\n const current = o(props.model).get(field)\n const initial = o(baseline).get(field)\n return isFieldModified(current, initial)\n}\n\ndefineExpose<_FormExposed>({ el: toRef(() => gridRef.value?.el), validate, clearValidate, reset })\n</script>\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"form-item.js","names":[],"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', !!rules?.required)]\"\n :style=\"labelStyles\"\n >\n <u-tip v-if=\"tips\" :content=\"tips\" :class=\"cls.e('tips')\" :show-delay=\"500\">\n <span :class=\"cls.e('tip-label')\">\n <slot name=\"label\">{{ label }}{{ labelPosition === 'top' ? '' : ':' }}</slot>\n </span>\n </u-tip>\n <template v-else>\n <slot name=\"label\">{{ label }}{{ labelPosition === 'top' ? '' : ':' }}</slot>\n </template>\n </label>\n\n <section :class=\"cls.e('wrapper')\">\n <div :class=\"cls.e('content')\">\n <ContentSlot>\n <slot></slot>\n </ContentSlot>\n </div>\n\n <!-- 只有表单控件处于非只读状态时,才显示错误提示 -->\n <section :class=\"cls.e('error')\" v-if=\"!readonly && !formProps?.noTips\">\n <transition name=\"form-item-tips\" mode=\"out-in\">\n <span :class=\"cls.e('error-text')\" v-if=\"!!errorTip\">\n {{ errorTip }}\n </span>\n </transition>\n </section>\n </section>\n </u-grid-item>\n</template>\n\n<script lang=\"tsx\" setup>\nimport { o } from '@cat-kit/core'\nimport { useConfig, useFallbackProps } from '@veltra/compositions'\nimport { bem, extractNormalVNodes, withUnit } from '@veltra/utils'\nimport { injectFormContext } from '@veltra/utils'\nimport {\n type CSSProperties,\n type SetupContext,\n type VNode,\n cloneVNode,\n computed,\n onBeforeUnmount,\n shallowRef,\n watch\n} from 'vue'\n\nimport type { FormItemEmits, FormItemProps, ComponentSize } from '../../types'\nimport { UGridItem } from '../grid'\nimport { UTip } from '../tip'\nimport { formItemCls as cls, defineField } from './helper'\nimport { validateField } from './validate'\n\ndefineOptions({ name: 'UFormItem' })\n\nconst props = withDefaults(defineProps<FormItemProps>(), { readonly: undefined })\n\nconst emit = defineEmits<FormItemEmits>()\n\ndefineSlots<{\n /** 标签插槽 */\n label?: () => any\n default?: () => any\n}>()\n\n/** 表单组件上下文 */\nconst { formProps, registerField, unregisterField, shouldValidate, handleFieldUpdate } =\n injectFormContext()\n\nfunction wrapControlChange(node: VNode) {\n if (!node || typeof node.type === 'symbol') return node\n\n return cloneVNode(node, {\n onChange: (...args: any[]) => {\n emit('change', ...args)\n }\n })\n}\n\n/**\n * 承载默认插槽并拦截控件 change。\n * 必须经填充插槽接收内容(而非直接读 UFormItem 的 $slots):\n * 读父级 $slots 时组件自身没有更新路径,父级重渲染后动态 props(disabled、data 等)会冻结在首帧。\n */\nfunction ContentSlot(_: unknown, { slots }: SetupContext) {\n return extractNormalVNodes(slots.default?.() ?? []).map(wrapControlChange)\n}\n\nconst { config } = useConfig()\n\nconst { size, readonly } = useFallbackProps([formProps ?? {}, props], {\n size: 'default' as ComponentSize,\n readonly: false\n})\n\nconst errorTip = shallowRef<string>()\n/** 递增序号,丢弃过期的异步校验结果 */\nlet validateSeq = 0\n/** 最近一次 validate 的 Promise,供过期调用等待最新结果 */\nlet latestValidatePromise: Promise<boolean> = Promise.resolve(true)\n\nconst labelPosition = computed(() => props.labelPosition ?? formProps?.labelPosition ?? 'left')\n\nconst className = computed(() => {\n return [\n cls.b,\n cls.m(size.value),\n bem.is('error', !!errorTip.value),\n bem.is('label-top', labelPosition.value === 'top')\n ].join(' ')\n})\n\n/** label样式 */\nconst labelStyles = computed<CSSProperties>(() => {\n if (labelPosition.value === 'top') return {}\n return {\n width: withUnit(props.labelWidth ?? formProps?.labelWidth ?? config.form.labelWidth, 'px')\n }\n})\n\nconst fieldItem = defineField({\n clearValidate() {\n errorTip.value = ''\n },\n async validate() {\n if (!props.field || !formProps?.model || !props.rules || !shouldValidate?.()) return true\n\n const seq = ++validateSeq\n\n latestValidatePromise = validateField(formProps.model!, props.field!, props.rules!).then(\n (tip) => {\n if (seq !== validateSeq) return latestValidatePromise\n\n errorTip.value = tip\n return !errorTip.value\n }\n )\n return latestValidatePromise\n }\n})\n\nwatch(\n () => props.field,\n (field, oldField) => {\n if (oldField) {\n unregisterField?.(oldField)\n }\n if (field) {\n registerField?.(field, fieldItem)\n }\n },\n { immediate: true }\n)\n\nlet stopWatchFieldValue: (() => void) | undefined\n\nwatch(\n [() => formProps?.model, () => props.field],\n ([model, field]) => {\n stopWatchFieldValue?.()\n\n if (!field || !model) return\n\n stopWatchFieldValue = watch(\n () => o(model).get(field),\n (value) => {\n handleFieldUpdate?.(field, value)\n fieldItem.validate()\n }\n )\n },\n { immediate: true }\n)\n\nonBeforeUnmount(() => {\n props.field && unregisterField?.(props.field)\n})\n</script>\n"],"mappings":""}
1
+ {"version":3,"file":"form-item.js","names":["_sfc_main"],"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', !!rules?.required)]\"\n :style=\"labelStyles\"\n >\n <u-tip v-if=\"tips\" :content=\"tips\" :class=\"cls.e('tips')\" :show-delay=\"500\">\n <span :class=\"cls.e('tip-label')\">\n <slot name=\"label\">{{ label }}{{ labelPosition === 'top' ? '' : ':' }}</slot>\n </span>\n </u-tip>\n <template v-else>\n <slot name=\"label\">{{ label }}{{ labelPosition === 'top' ? '' : ':' }}</slot>\n </template>\n </label>\n\n <section :class=\"cls.e('wrapper')\">\n <div :class=\"cls.e('content')\">\n <ContentSlot>\n <slot></slot>\n </ContentSlot>\n </div>\n\n <!-- 只有表单控件处于非只读状态时,才显示错误提示 -->\n <section :class=\"cls.e('error')\" v-if=\"!readonly && !formProps?.noTips\">\n <transition name=\"form-item-tips\" mode=\"out-in\">\n <span :class=\"cls.e('error-text')\" v-if=\"!!errorTip\">\n {{ errorTip }}\n </span>\n </transition>\n </section>\n </section>\n </u-grid-item>\n</template>\n\n<script lang=\"tsx\" setup>\nimport { o } from '@cat-kit/core'\nimport { useConfig, useFallbackProps } from '@veltra/compositions'\nimport { bem, extractNormalVNodes, withUnit } from '@veltra/utils'\nimport { injectFormContext } from '@veltra/utils'\nimport {\n type CSSProperties,\n type SetupContext,\n type VNode,\n cloneVNode,\n computed,\n onBeforeUnmount,\n shallowRef,\n watch\n} from 'vue'\n\nimport type { FormItemEmits, FormItemProps, ComponentSize } from '../../types'\nimport { UGridItem } from '../grid'\nimport { UTip } from '../tip'\nimport { formItemCls as cls, defineField } from './helper'\nimport { validateField } from './validate'\n\ndefineOptions({ name: 'UFormItem' })\n\nconst props = withDefaults(defineProps<FormItemProps>(), { readonly: undefined })\n\nconst emit = defineEmits<FormItemEmits>()\n\ndefineSlots<{\n /** 标签插槽 */\n label?: () => any\n default?: () => any\n}>()\n\n/** 表单组件上下文 */\nconst { formProps, registerField, unregisterField, shouldValidate, handleFieldUpdate } =\n injectFormContext()\n\nfunction wrapControlChange(node: VNode) {\n if (!node || typeof node.type === 'symbol') return node\n\n return cloneVNode(node, {\n onChange: (...args: any[]) => {\n emit('change', ...args)\n }\n })\n}\n\n/**\n * 承载默认插槽并拦截控件 change。\n * 必须经填充插槽接收内容(而非直接读 UFormItem 的 $slots):\n * 读父级 $slots 时组件自身没有更新路径,父级重渲染后动态 props(disabled、data 等)会冻结在首帧。\n */\nfunction ContentSlot(_: unknown, { slots }: SetupContext) {\n return extractNormalVNodes(slots.default?.() ?? []).map(wrapControlChange)\n}\n\nconst { config } = useConfig()\n\nconst { size, readonly } = useFallbackProps([formProps ?? {}, props], {\n size: 'default' as ComponentSize,\n readonly: false\n})\n\nconst errorTip = shallowRef<string>()\n/** 递增序号,丢弃过期的异步校验结果 */\nlet validateSeq = 0\n/** 最近一次 validate 的 Promise,供过期调用等待最新结果 */\nlet latestValidatePromise: Promise<boolean> = Promise.resolve(true)\n\nconst labelPosition = computed(() => props.labelPosition ?? formProps?.labelPosition ?? 'left')\n\nconst className = computed(() => {\n return [\n cls.b,\n cls.m(size.value),\n bem.is('error', !!errorTip.value),\n bem.is('label-top', labelPosition.value === 'top')\n ].join(' ')\n})\n\n/** label样式 */\nconst labelStyles = computed<CSSProperties>(() => {\n if (labelPosition.value === 'top') return {}\n return {\n width: withUnit(props.labelWidth ?? formProps?.labelWidth ?? config.form.labelWidth, 'px')\n }\n})\n\nconst fieldItem = defineField({\n clearValidate() {\n errorTip.value = ''\n },\n async validate() {\n if (!props.field || !formProps?.model || !props.rules || !shouldValidate?.()) return true\n\n const seq = ++validateSeq\n\n latestValidatePromise = validateField(formProps.model!, props.field!, props.rules!).then(\n (tip) => {\n if (seq !== validateSeq) return latestValidatePromise\n\n errorTip.value = tip\n return !errorTip.value\n }\n )\n return latestValidatePromise\n }\n})\n\nwatch(\n () => props.field,\n (field, oldField) => {\n if (oldField) {\n unregisterField?.(oldField)\n }\n if (field) {\n registerField?.(field, fieldItem)\n }\n },\n { immediate: true }\n)\n\nlet stopWatchFieldValue: (() => void) | undefined\n\nwatch(\n [() => formProps?.model, () => props.field],\n ([model, field]) => {\n stopWatchFieldValue?.()\n\n if (!field || !model) return\n\n stopWatchFieldValue = watch(\n () => o(model).get(field),\n (value) => {\n handleFieldUpdate?.(field, value)\n fieldItem.validate()\n }\n )\n },\n { immediate: true }\n)\n\nonBeforeUnmount(() => {\n props.field && unregisterField?.(props.field)\n})\n</script>\n"],"mappings":""}
@@ -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', !!rules?.required)]\"\n :style=\"labelStyles\"\n >\n <u-tip v-if=\"tips\" :content=\"tips\" :class=\"cls.e('tips')\" :show-delay=\"500\">\n <span :class=\"cls.e('tip-label')\">\n <slot name=\"label\">{{ label }}{{ labelPosition === 'top' ? '' : ':' }}</slot>\n </span>\n </u-tip>\n <template v-else>\n <slot name=\"label\">{{ label }}{{ labelPosition === 'top' ? '' : ':' }}</slot>\n </template>\n </label>\n\n <section :class=\"cls.e('wrapper')\">\n <div :class=\"cls.e('content')\">\n <ContentSlot>\n <slot></slot>\n </ContentSlot>\n </div>\n\n <!-- 只有表单控件处于非只读状态时,才显示错误提示 -->\n <section :class=\"cls.e('error')\" v-if=\"!readonly && !formProps?.noTips\">\n <transition name=\"form-item-tips\" mode=\"out-in\">\n <span :class=\"cls.e('error-text')\" v-if=\"!!errorTip\">\n {{ errorTip }}\n </span>\n </transition>\n </section>\n </section>\n </u-grid-item>\n</template>\n\n<script lang=\"tsx\" setup>\nimport { o } from '@cat-kit/core'\nimport { useConfig, useFallbackProps } from '@veltra/compositions'\nimport { bem, extractNormalVNodes, withUnit } from '@veltra/utils'\nimport { injectFormContext } from '@veltra/utils'\nimport {\n type CSSProperties,\n type SetupContext,\n type VNode,\n cloneVNode,\n computed,\n onBeforeUnmount,\n shallowRef,\n watch\n} from 'vue'\n\nimport type { FormItemEmits, FormItemProps, ComponentSize } from '../../types'\nimport { UGridItem } from '../grid'\nimport { UTip } from '../tip'\nimport { formItemCls as cls, defineField } from './helper'\nimport { validateField } from './validate'\n\ndefineOptions({ name: 'UFormItem' })\n\nconst props = withDefaults(defineProps<FormItemProps>(), { readonly: undefined })\n\nconst emit = defineEmits<FormItemEmits>()\n\ndefineSlots<{\n /** 标签插槽 */\n label?: () => any\n default?: () => any\n}>()\n\n/** 表单组件上下文 */\nconst { formProps, registerField, unregisterField, shouldValidate, handleFieldUpdate } =\n injectFormContext()\n\nfunction wrapControlChange(node: VNode) {\n if (!node || typeof node.type === 'symbol') return node\n\n return cloneVNode(node, {\n onChange: (...args: any[]) => {\n emit('change', ...args)\n }\n })\n}\n\n/**\n * 承载默认插槽并拦截控件 change。\n * 必须经填充插槽接收内容(而非直接读 UFormItem 的 $slots):\n * 读父级 $slots 时组件自身没有更新路径,父级重渲染后动态 props(disabled、data 等)会冻结在首帧。\n */\nfunction ContentSlot(_: unknown, { slots }: SetupContext) {\n return extractNormalVNodes(slots.default?.() ?? []).map(wrapControlChange)\n}\n\nconst { config } = useConfig()\n\nconst { size, readonly } = useFallbackProps([formProps ?? {}, props], {\n size: 'default' as ComponentSize,\n readonly: false\n})\n\nconst errorTip = shallowRef<string>()\n/** 递增序号,丢弃过期的异步校验结果 */\nlet validateSeq = 0\n/** 最近一次 validate 的 Promise,供过期调用等待最新结果 */\nlet latestValidatePromise: Promise<boolean> = Promise.resolve(true)\n\nconst labelPosition = computed(() => props.labelPosition ?? formProps?.labelPosition ?? 'left')\n\nconst className = computed(() => {\n return [\n cls.b,\n cls.m(size.value),\n bem.is('error', !!errorTip.value),\n bem.is('label-top', labelPosition.value === 'top')\n ].join(' ')\n})\n\n/** label样式 */\nconst labelStyles = computed<CSSProperties>(() => {\n if (labelPosition.value === 'top') return {}\n return {\n width: withUnit(props.labelWidth ?? formProps?.labelWidth ?? config.form.labelWidth, 'px')\n }\n})\n\nconst fieldItem = defineField({\n clearValidate() {\n errorTip.value = ''\n },\n async validate() {\n if (!props.field || !formProps?.model || !props.rules || !shouldValidate?.()) return true\n\n const seq = ++validateSeq\n\n latestValidatePromise = validateField(formProps.model!, props.field!, props.rules!).then(\n (tip) => {\n if (seq !== validateSeq) return latestValidatePromise\n\n errorTip.value = tip\n return !errorTip.value\n }\n )\n return latestValidatePromise\n }\n})\n\nwatch(\n () => props.field,\n (field, oldField) => {\n if (oldField) {\n unregisterField?.(oldField)\n }\n if (field) {\n registerField?.(field, fieldItem)\n }\n },\n { immediate: true }\n)\n\nlet stopWatchFieldValue: (() => void) | undefined\n\nwatch(\n [() => formProps?.model, () => props.field],\n ([model, field]) => {\n stopWatchFieldValue?.()\n\n if (!field || !model) return\n\n stopWatchFieldValue = watch(\n () => o(model).get(field),\n (value) => {\n handleFieldUpdate?.(field, value)\n fieldItem.validate()\n }\n )\n },\n { immediate: true }\n)\n\nonBeforeUnmount(() => {\n props.field && unregisterField?.(props.field)\n})\n</script>\n"],"mappings":"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"}
1
+ {"version":3,"file":"form-item.vue_vue_type_script_setup_true_lang.js","names":["$slots","cls","_openBlock","_createBlock","_unref","UGridItem","_normalizeClass","_withCtx","_createElementBlock","_normalizeStyle","UTip","_createElementVNode","_renderSlot","_createTextVNode","_toDisplayString","_createCommentVNode","_createVNode","_Transition"],"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', !!rules?.required)]\"\n :style=\"labelStyles\"\n >\n <u-tip v-if=\"tips\" :content=\"tips\" :class=\"cls.e('tips')\" :show-delay=\"500\">\n <span :class=\"cls.e('tip-label')\">\n <slot name=\"label\">{{ label }}{{ labelPosition === 'top' ? '' : ':' }}</slot>\n </span>\n </u-tip>\n <template v-else>\n <slot name=\"label\">{{ label }}{{ labelPosition === 'top' ? '' : ':' }}</slot>\n </template>\n </label>\n\n <section :class=\"cls.e('wrapper')\">\n <div :class=\"cls.e('content')\">\n <ContentSlot>\n <slot></slot>\n </ContentSlot>\n </div>\n\n <!-- 只有表单控件处于非只读状态时,才显示错误提示 -->\n <section :class=\"cls.e('error')\" v-if=\"!readonly && !formProps?.noTips\">\n <transition name=\"form-item-tips\" mode=\"out-in\">\n <span :class=\"cls.e('error-text')\" v-if=\"!!errorTip\">\n {{ errorTip }}\n </span>\n </transition>\n </section>\n </section>\n </u-grid-item>\n</template>\n\n<script lang=\"tsx\" setup>\nimport { o } from '@cat-kit/core'\nimport { useConfig, useFallbackProps } from '@veltra/compositions'\nimport { bem, extractNormalVNodes, withUnit } from '@veltra/utils'\nimport { injectFormContext } from '@veltra/utils'\nimport {\n type CSSProperties,\n type SetupContext,\n type VNode,\n cloneVNode,\n computed,\n onBeforeUnmount,\n shallowRef,\n watch\n} from 'vue'\n\nimport type { FormItemEmits, FormItemProps, ComponentSize } from '../../types'\nimport { UGridItem } from '../grid'\nimport { UTip } from '../tip'\nimport { formItemCls as cls, defineField } from './helper'\nimport { validateField } from './validate'\n\ndefineOptions({ name: 'UFormItem' })\n\nconst props = withDefaults(defineProps<FormItemProps>(), { readonly: undefined })\n\nconst emit = defineEmits<FormItemEmits>()\n\ndefineSlots<{\n /** 标签插槽 */\n label?: () => any\n default?: () => any\n}>()\n\n/** 表单组件上下文 */\nconst { formProps, registerField, unregisterField, shouldValidate, handleFieldUpdate } =\n injectFormContext()\n\nfunction wrapControlChange(node: VNode) {\n if (!node || typeof node.type === 'symbol') return node\n\n return cloneVNode(node, {\n onChange: (...args: any[]) => {\n emit('change', ...args)\n }\n })\n}\n\n/**\n * 承载默认插槽并拦截控件 change。\n * 必须经填充插槽接收内容(而非直接读 UFormItem 的 $slots):\n * 读父级 $slots 时组件自身没有更新路径,父级重渲染后动态 props(disabled、data 等)会冻结在首帧。\n */\nfunction ContentSlot(_: unknown, { slots }: SetupContext) {\n return extractNormalVNodes(slots.default?.() ?? []).map(wrapControlChange)\n}\n\nconst { config } = useConfig()\n\nconst { size, readonly } = useFallbackProps([formProps ?? {}, props], {\n size: 'default' as ComponentSize,\n readonly: false\n})\n\nconst errorTip = shallowRef<string>()\n/** 递增序号,丢弃过期的异步校验结果 */\nlet validateSeq = 0\n/** 最近一次 validate 的 Promise,供过期调用等待最新结果 */\nlet latestValidatePromise: Promise<boolean> = Promise.resolve(true)\n\nconst labelPosition = computed(() => props.labelPosition ?? formProps?.labelPosition ?? 'left')\n\nconst className = computed(() => {\n return [\n cls.b,\n cls.m(size.value),\n bem.is('error', !!errorTip.value),\n bem.is('label-top', labelPosition.value === 'top')\n ].join(' ')\n})\n\n/** label样式 */\nconst labelStyles = computed<CSSProperties>(() => {\n if (labelPosition.value === 'top') return {}\n return {\n width: withUnit(props.labelWidth ?? formProps?.labelWidth ?? config.form.labelWidth, 'px')\n }\n})\n\nconst fieldItem = defineField({\n clearValidate() {\n errorTip.value = ''\n },\n async validate() {\n if (!props.field || !formProps?.model || !props.rules || !shouldValidate?.()) return true\n\n const seq = ++validateSeq\n\n latestValidatePromise = validateField(formProps.model!, props.field!, props.rules!).then(\n (tip) => {\n if (seq !== validateSeq) return latestValidatePromise\n\n errorTip.value = tip\n return !errorTip.value\n }\n )\n return latestValidatePromise\n }\n})\n\nwatch(\n () => props.field,\n (field, oldField) => {\n if (oldField) {\n unregisterField?.(oldField)\n }\n if (field) {\n registerField?.(field, fieldItem)\n }\n },\n { immediate: true }\n)\n\nlet stopWatchFieldValue: (() => void) | undefined\n\nwatch(\n [() => formProps?.model, () => props.field],\n ([model, field]) => {\n stopWatchFieldValue?.()\n\n if (!field || !model) return\n\n stopWatchFieldValue = watch(\n () => o(model).get(field),\n (value) => {\n handleFieldUpdate?.(field, value)\n fieldItem.validate()\n }\n )\n },\n { immediate: true }\n)\n\nonBeforeUnmount(() => {\n props.field && unregisterField?.(props.field)\n})\n</script>\n"],"mappings":"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"}
@@ -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: 'UGanttChart' })\n\ndefineProps<GanttChartProps>()\n\nconst cls = bem('gantt-chart')\n</script>\n"],"mappings":";;;;;;;;EAaA,MAAM,MAAM,IAAI,aAAa;;GAZ3B,OAAA,UAAA,GAAA,mBAA0B,OAAA,EAApB,OAAK,eAAE,MAAA,GAAA,CAAG,CAAC,CAAC,EAAA,GAAA,MAAA,CAAA"}
1
+ {"version":3,"file":"gantt-chart.js","names":["_openBlock","_createElementBlock","_normalizeClass","_unref"],"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: 'UGanttChart' })\n\ndefineProps<GanttChartProps>()\n\nconst cls = bem('gantt-chart')\n</script>\n"],"mappings":";;;;;;;;EAaA,MAAM,MAAM,IAAI,aAAa;;GAZ3B,OAAAA,UAAA,GAAAC,mBAA0B,OAAA,EAApB,OAAKC,eAAEC,MAAA,GAAA,CAAG,CAAC,CAAC,EAAA,GAAA,MAAA,CAAA"}
@@ -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: 'UGridItem' })\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;;GAnD2D,OAAA,KAAA,UAAI,KAA7D,UAAA,GAAA,YAEY,wBAFI,QAAA,GAAG,GAAA;;IAAG,OAAK,eAAE,MAAA,KAAK;IAAG,OAAK,eAAE,MAAA,GAAA,CAAG,CAAC,CAAC;;IAC/C,SAAA,cAAQ,CAAR,WAAQ,KAAA,QAAA,SAAA,CAAA,CAAA"}
1
+ {"version":3,"file":"grid-item.js","names":["_openBlock","_createBlock","_resolveDynamicComponent","_normalizeStyle","_normalizeClass","_unref","_withCtx","_renderSlot","_createCommentVNode"],"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: 'UGridItem' })\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;;GAnD2D,OAAA,KAAA,UAAI,KAA7DA,UAAA,GAAAC,YAEYC,wBAFI,QAAA,GAAG,GAAA;;IAAG,OAAKC,eAAE,MAAA,KAAK;IAAG,OAAKC,eAAEC,MAAA,GAAA,CAAG,CAAC,CAAC;;IAC/C,SAAAC,cAAQ,CAARC,WAAQ,KAAA,QAAA,SAAA,CAAA,CAAA"}
@@ -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: 'UGrid' })\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;EAEpF,MAAM,SAAS,eAAe;GAC5B,MAAM,EAAE,KAAK,SAAS;GACtB,MAAM,SAAwB,CAAC;GAG/B,IAAI,OAAO,QAAQ,UACb;QAAA,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,CAAC;EAED,MAAM,CAAC,QAAQ,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;;GAxExC,OAAA,UAAA,GAAA,YAEY,wBAFI,QAAA,GAAG,GAAA;IAAG,OAAK,eAAE,MAAA,GAAA,CAAG,CAAC,CAAC;IAAE,KAAI;;IACtC,SAAA,cAAQ,CAAR,WAAQ,KAAA,QAAA,SAAA,CAAA,CAAA"}
1
+ {"version":3,"file":"grid.js","names":["_openBlock","_createBlock","_resolveDynamicComponent","_normalizeClass","_unref","_withCtx","_renderSlot"],"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: 'UGrid' })\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;EAEpF,MAAM,SAAS,eAAe;GAC5B,MAAM,EAAE,KAAK,SAAS;GACtB,MAAM,SAAwB,CAAC;GAG/B,IAAI,OAAO,QAAQ,UACb;QAAA,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,CAAC;EAED,MAAM,CAAC,QAAQ,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;;GAxExC,OAAAA,UAAA,GAAAC,YAEYC,wBAFI,QAAA,GAAG,GAAA;IAAG,OAAKC,eAAEC,MAAA,GAAA,CAAG,CAAC,CAAC;IAAE,KAAI;;IACtC,SAAAC,cAAQ,CAARC,WAAQ,KAAA,QAAA,SAAA,CAAA,CAAA"}
@@ -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=\"index < valueArray.length\">\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, watch } from 'vue'\n\nimport type { GridInputProps, GridInputEmits, GridInputExposed } from '../../types'\n\ndefineOptions({ name: 'UGridInput' })\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\n/** 将格子数组拼成对外 modelValue */\nconst joinValue = (cells: string[]) => cells.join(props.separator)\n\n/** 按分隔符解析 modelValue 为格子内容 */\nconst parseValue = (value?: string): string[] => {\n if (!value) return []\n const sep = props.separator\n const parts = sep === '' ? Array.from(value) : value.split(sep)\n return parts.filter((part) => part !== '').slice(0, props.length)\n}\n\n// 外部 modelValue / 分隔符变化时回填格子(支持初始值与回显)\nwatch(\n () => [props.modelValue, props.separator, props.length] as const,\n () => {\n const next = parseValue(props.modelValue)\n if (joinValue(next) === joinValue(valueArray.value)) return\n valueArray.value = next\n },\n { immediate: true }\n)\n\nconst emitValue = () => {\n const value = joinValue(valueArray.value)\n emit('input', value)\n emit('update:modelValue', value)\n}\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\n if (index < valueArray.value.length) {\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 emitValue()\n}\n\nconst baseOperation: Record<string, (value: string, index: number) => void> = {\n Backspace: (_value: string, index: number) => {\n if (index < valueArray.value.length) {\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 emitValue()\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: KeyboardEvent, 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 valueArray.value = []\n position.value = -1\n}\n\ndefineExpose<GridInputExposed>({ clear })\n</script>\n"],"mappings":"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"}
1
+ {"version":3,"file":"grid-input.js","names":["_openBlock","_createElementBlock","_normalizeClass","_unref","_Fragment","_renderList","_toDisplayString","_createCommentVNode"],"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=\"index < valueArray.length\">\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, watch } from 'vue'\n\nimport type { GridInputProps, GridInputEmits, GridInputExposed } from '../../types'\n\ndefineOptions({ name: 'UGridInput' })\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\n/** 将格子数组拼成对外 modelValue */\nconst joinValue = (cells: string[]) => cells.join(props.separator)\n\n/** 按分隔符解析 modelValue 为格子内容 */\nconst parseValue = (value?: string): string[] => {\n if (!value) return []\n const sep = props.separator\n const parts = sep === '' ? Array.from(value) : value.split(sep)\n return parts.filter((part) => part !== '').slice(0, props.length)\n}\n\n// 外部 modelValue / 分隔符变化时回填格子(支持初始值与回显)\nwatch(\n () => [props.modelValue, props.separator, props.length] as const,\n () => {\n const next = parseValue(props.modelValue)\n if (joinValue(next) === joinValue(valueArray.value)) return\n valueArray.value = next\n },\n { immediate: true }\n)\n\nconst emitValue = () => {\n const value = joinValue(valueArray.value)\n emit('input', value)\n emit('update:modelValue', value)\n}\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\n if (index < valueArray.value.length) {\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 emitValue()\n}\n\nconst baseOperation: Record<string, (value: string, index: number) => void> = {\n Backspace: (_value: string, index: number) => {\n if (index < valueArray.value.length) {\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 emitValue()\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: KeyboardEvent, 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 valueArray.value = []\n position.value = -1\n}\n\ndefineExpose<GridInputExposed>({ clear })\n</script>\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"group-input.js","names":["$attrs"],"sources":["../../../src/components/group-input/group-input.vue"],"sourcesContent":["<template>\n <ul v-if=\"!readonly\" v-bind=\"$attrs\" :class=\"[cls.b, cls.m(size)]\">\n <li v-if=\"isEmpty && creatable\">\n <u-button style=\"width: 100%\" :icon=\"Plus\" @click=\"handleAdd(0)\" :size=\"size\">\n 新增\n </u-button>\n </li>\n <li v-for=\"(item, index) of items\" :key=\"item.id\" :class=\"cls.e('item')\" :style=\"itemStyle\">\n <slot v-bind=\"{ item: item.data, index }\" />\n <span :class=\"cls.e('actions')\">\n <u-button\n :icon=\"Minus\"\n circle\n :disabled=\"disabled\"\n :size=\"size\"\n @click=\"handleRemove(index)\"\n />\n <u-button\n :icon=\"Plus\"\n circle\n :disabled=\"disabled\"\n :size=\"size\"\n type=\"primary\"\n @click=\"handleAdd(index)\"\n />\n </span>\n </li>\n </ul>\n\n <template v-else-if=\"items?.length\">\n <ul :class=\"[cls.b, cls.m(size)]\">\n <li v-for=\"item of items\" :key=\"item.id\" :class=\"cls.e('item')\">\n <span v-for=\"v in item.data\">{{ v }}</span>\n </li>\n </ul>\n </template>\n\n <template v-else>\n {{ FORM_EMPTY_CONTENT }}\n </template>\n</template>\n\n<script lang=\"ts\" setup generic=\"GroupItem extends Record<string, any>\">\nimport { useFormFallbackProps } from '@veltra/compositions'\nimport { Minus, Plus } from '@veltra/icons/normal'\nimport { bem, FORM_EMPTY_CONTENT } from '@veltra/utils'\nimport { injectFormContext } from '@veltra/utils'\nimport { computed } from 'vue'\n\nimport type { GroupInputEmits, GroupInputProps } from '../../types'\nimport { UButton } from '../button'\nimport { useGroupItems } from './use-group-items'\n\ndefineOptions({ name: 'UGroupInput', inheritAttrs: false })\n\nconst props = withDefaults(defineProps<GroupInputProps<GroupItem>>(), {\n modelValue: () => [],\n disabled: undefined,\n readonly: undefined,\n creatable: true\n})\n\nconst emit = defineEmits<GroupInputEmits>()\n\nconst cls = bem('group-input')\n\nconst { formProps } = injectFormContext()\nconst { disabled, size, readonly } = useFormFallbackProps([formProps ?? {}, props], {\n size: 'default',\n disabled: false,\n readonly: false\n})\n\nconst { items, createItem, runByEvent } = useGroupItems({ props, emit })\n\nconst isEmpty = computed(() => {\n return !items.value.length\n})\n\nfunction handleAdd(index: number) {\n runByEvent(() => {\n items.value = [\n ...items.value.slice(0, index + 1),\n createItem({}),\n ...items.value.slice(index + 1)\n ]\n })\n}\n\nfunction handleRemove(index: number) {\n runByEvent(() => {\n items.value = [...items.value.slice(0, index), ...items.value.slice(index + 1)]\n })\n}\n</script>\n"],"mappings":"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"}
1
+ {"version":3,"file":"group-input.js","names":["$attrs","_unref","_openBlock","_createElementBlock","_mergeProps","_createVNode","UButton","_withCtx","_createTextVNode","_createCommentVNode","_Fragment","_renderList","_normalizeClass","_normalizeStyle","_renderSlot","_createElementVNode","_toDisplayString"],"sources":["../../../src/components/group-input/group-input.vue"],"sourcesContent":["<template>\n <ul v-if=\"!readonly\" v-bind=\"$attrs\" :class=\"[cls.b, cls.m(size)]\">\n <li v-if=\"isEmpty && creatable\">\n <u-button style=\"width: 100%\" :icon=\"Plus\" @click=\"handleAdd(0)\" :size=\"size\">\n 新增\n </u-button>\n </li>\n <li v-for=\"(item, index) of items\" :key=\"item.id\" :class=\"cls.e('item')\" :style=\"itemStyle\">\n <slot v-bind=\"{ item: item.data, index }\" />\n <span :class=\"cls.e('actions')\">\n <u-button\n :icon=\"Minus\"\n circle\n :disabled=\"disabled\"\n :size=\"size\"\n @click=\"handleRemove(index)\"\n />\n <u-button\n :icon=\"Plus\"\n circle\n :disabled=\"disabled\"\n :size=\"size\"\n type=\"primary\"\n @click=\"handleAdd(index)\"\n />\n </span>\n </li>\n </ul>\n\n <template v-else-if=\"items?.length\">\n <ul :class=\"[cls.b, cls.m(size)]\">\n <li v-for=\"item of items\" :key=\"item.id\" :class=\"cls.e('item')\">\n <span v-for=\"v in item.data\">{{ v }}</span>\n </li>\n </ul>\n </template>\n\n <template v-else>\n {{ FORM_EMPTY_CONTENT }}\n </template>\n</template>\n\n<script lang=\"ts\" setup generic=\"GroupItem extends Record<string, any>\">\nimport { useFormFallbackProps } from '@veltra/compositions'\nimport { Minus, Plus } from '@veltra/icons/normal'\nimport { bem, FORM_EMPTY_CONTENT } from '@veltra/utils'\nimport { injectFormContext } from '@veltra/utils'\nimport { computed } from 'vue'\n\nimport type { GroupInputEmits, GroupInputProps } from '../../types'\nimport { UButton } from '../button'\nimport { useGroupItems } from './use-group-items'\n\ndefineOptions({ name: 'UGroupInput', inheritAttrs: false })\n\nconst props = withDefaults(defineProps<GroupInputProps<GroupItem>>(), {\n modelValue: () => [],\n disabled: undefined,\n readonly: undefined,\n creatable: true\n})\n\nconst emit = defineEmits<GroupInputEmits>()\n\nconst cls = bem('group-input')\n\nconst { formProps } = injectFormContext()\nconst { disabled, size, readonly } = useFormFallbackProps([formProps ?? {}, props], {\n size: 'default',\n disabled: false,\n readonly: false\n})\n\nconst { items, createItem, runByEvent } = useGroupItems({ props, emit })\n\nconst isEmpty = computed(() => {\n return !items.value.length\n})\n\nfunction handleAdd(index: number) {\n runByEvent(() => {\n items.value = [\n ...items.value.slice(0, index + 1),\n createItem({}),\n ...items.value.slice(index + 1)\n ]\n })\n}\n\nfunction handleRemove(index: number) {\n runByEvent(() => {\n items.value = [...items.value.slice(0, index), ...items.value.slice(index + 1)]\n })\n}\n</script>\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"group-nav-item.js","names":[],"sources":["../../../src/components/group-nav/group-nav-item.vue"],"sourcesContent":["<template>\n <li\n :class=\"[cls.e('item'), bem.is('active', active), bem.is('disabled', item.disabled ?? false)]\"\n @click=\"handleClick\"\n >\n <NavIcon v-if=\"item.icon\" :icon=\"item.icon\" :class=\"cls.e('icon')\" />\n\n <span :class=\"cls.e('item-title')\">\n {{ item.title }}\n </span>\n </li>\n</template>\n\n<script setup lang=\"ts\">\nimport { bem } from '@veltra/utils'\n\nimport type { NavItem } from '../../types/nav'\nimport NavIcon from '../nav/nav-icon.vue'\n\ndefineOptions({ name: 'UGroupNavItem' })\n\nconst props = defineProps<{ item: NavItem; active: boolean }>()\n\nconst emit = defineEmits<{ (e: 'click', item: NavItem): void }>()\n\nconst cls = bem('group-nav')\n\nfunction handleClick() {\n if (props.item.disabled) return\n emit('click', props.item)\n}\n</script>\n"],"mappings":";;;;;;;;;;;;;EAqBA,MAAM,QAAQ;EAEd,MAAM,OAAO;EAEb,MAAM,MAAM,IAAI,WAAW;EAE3B,SAAS,cAAc;GACrB,IAAI,MAAM,KAAK,UAAU;GACzB,KAAK,SAAS,MAAM,IAAI;EAC1B;;GA7BE,OAAA,UAAA,GAAA,mBASK,MAAA;IARF,OAAK,eAAA;KAAG,MAAA,GAAA,CAAG,CAAC,EAAC,MAAA;KAAU,MAAA,GAAA,CAAG,CAAC,GAAE,UAAW,QAAA,MAAM;KAAG,MAAA,GAAA,CAAG,CAAC,GAAE,YAAa,QAAA,KAAK,YAAQ,KAAA;IAAA,CAAA;IACjF,SAAO;GAEO,GAAA,CAAA,QAAA,KAAK,QAApB,UAAA,GAAA,YAAqE,aAAA;;IAA1C,MAAM,QAAA,KAAK;IAAO,OAAK,eAAE,MAAA,GAAA,CAAG,CAAC,EAAC,MAAA,CAAA;GAEzD,GAAA,MAAA,GAAA,CAAA,QAAA,OAAA,CAAA,KAAA,mBAAA,QAAA,IAAA,GAAA,mBAEO,QAAA,EAFA,OAAK,eAAE,MAAA,GAAA,CAAG,CAAC,EAAC,YAAA,CAAA,EACd,GAAA,gBAAA,QAAA,KAAK,KAAK,GAAA,CAAA,CAAA,GAAA,CAAA"}
1
+ {"version":3,"file":"group-nav-item.js","names":["_openBlock","_createElementBlock","_normalizeClass","_unref","_createBlock","NavIcon","_createCommentVNode","_createElementVNode","_toDisplayString"],"sources":["../../../src/components/group-nav/group-nav-item.vue"],"sourcesContent":["<template>\n <li\n :class=\"[cls.e('item'), bem.is('active', active), bem.is('disabled', item.disabled ?? false)]\"\n @click=\"handleClick\"\n >\n <NavIcon v-if=\"item.icon\" :icon=\"item.icon\" :class=\"cls.e('icon')\" />\n\n <span :class=\"cls.e('item-title')\">\n {{ item.title }}\n </span>\n </li>\n</template>\n\n<script setup lang=\"ts\">\nimport { bem } from '@veltra/utils'\n\nimport type { NavItem } from '../../types/nav'\nimport NavIcon from '../nav/nav-icon.vue'\n\ndefineOptions({ name: 'UGroupNavItem' })\n\nconst props = defineProps<{ item: NavItem; active: boolean }>()\n\nconst emit = defineEmits<{ (e: 'click', item: NavItem): void }>()\n\nconst cls = bem('group-nav')\n\nfunction handleClick() {\n if (props.item.disabled) return\n emit('click', props.item)\n}\n</script>\n"],"mappings":";;;;;;;;;;;;;EAqBA,MAAM,QAAQ;EAEd,MAAM,OAAO;EAEb,MAAM,MAAM,IAAI,WAAW;EAE3B,SAAS,cAAc;GACrB,IAAI,MAAM,KAAK,UAAU;GACzB,KAAK,SAAS,MAAM,IAAI;EAC1B;;GA7BE,OAAAA,UAAA,GAAAC,mBASK,MAAA;IARF,OAAKC,eAAA;KAAGC,MAAA,GAAA,CAAG,CAAC,EAAC,MAAA;KAAUA,MAAA,GAAA,CAAG,CAAC,GAAE,UAAW,QAAA,MAAM;KAAGA,MAAA,GAAA,CAAG,CAAC,GAAE,YAAa,QAAA,KAAK,YAAQ,KAAA;IAAA,CAAA;IACjF,SAAO;GAEO,GAAA,CAAA,QAAA,KAAK,QAApBH,UAAA,GAAAI,YAAqEC,aAAA;;IAA1C,MAAM,QAAA,KAAK;IAAO,OAAKH,eAAEC,MAAA,GAAA,CAAG,CAAC,EAAC,MAAA,CAAA;GAEzD,GAAA,MAAA,GAAA,CAAA,QAAA,OAAA,CAAA,KAAAG,mBAAA,QAAA,IAAA,GAAAC,mBAEO,QAAA,EAFA,OAAKL,eAAEC,MAAA,GAAA,CAAG,CAAC,EAAC,YAAA,CAAA,EACd,GAAAK,gBAAA,QAAA,KAAK,KAAK,GAAA,CAAA,CAAA,GAAA,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"group-nav.js","names":[],"sources":["../../../src/components/group-nav/group-nav.vue"],"sourcesContent":["<template>\n <u-scroll tag=\"ul\" :class=\"cls.b\" :container-class=\"cls.e('container')\">\n <li v-for=\"(group, index) of groups\" :key=\"group.title || index\" :class=\"cls.e('group')\">\n <div :class=\"cls.e('group-label')\">{{ group.title }}</div>\n <ul :class=\"cls.e('group-list')\">\n <GroupNavItem\n v-for=\"(child, childIndex) of group.children\"\n :key=\"child.path || childIndex\"\n :item=\"child\"\n :active=\"currentPath === child.path\"\n @click=\"handleItemClick\"\n />\n </ul>\n </li>\n </u-scroll>\n</template>\n\n<script lang=\"ts\" setup>\nimport { bem } from '@veltra/utils'\n\nimport type { GroupNavEmits, GroupNavProps } from '../../types/group-nav'\nimport type { NavItem } from '../../types/nav'\nimport { UScroll } from '../scroll'\nimport GroupNavItem from './group-nav-item.vue'\n\ndefineOptions({ name: 'UGroupNav' })\n\ndefineProps<GroupNavProps>()\nconst emit = defineEmits<GroupNavEmits>()\n\nconst cls = bem('group-nav')\n\nfunction handleItemClick(item: NavItem) {\n emit('item-click', item)\n}\n</script>\n"],"mappings":";;;;;;;;;;;;;;EA4BA,MAAM,OAAO;EAEb,MAAM,MAAM,IAAI,WAAW;EAE3B,SAAS,gBAAgB,MAAe;GACtC,KAAK,cAAc,IAAI;EACzB;;GAjCE,OAAA,UAAA,GAAA,YAaW,MAAA,WAAA,GAAA;IAbD,KAAI;IAAM,OAAK,eAAE,MAAA,GAAA,CAAG,CAAC,CAAC;IAAG,mBAAiB,MAAA,GAAA,CAAG,CAAC,EAAC,WAAA;;IACnD,SAAA,cAAgC,EAApC,UAAA,IAAA,GAAA,mBAWK,UAAA,MAAA,WAXwB,QAAA,SAAjB,OAAO,UAAK;KAAxB,OAAA,UAAA,GAAA,mBAWK,MAAA;MAXiC,KAAK,MAAM,SAAS;MAAQ,OAAK,eAAE,MAAA,GAAA,CAAG,CAAC,EAAC,OAAA,CAAA;KAC5E,GAAA,CAAA,mBAA0D,OAAA,EAApD,OAAK,eAAE,MAAA,GAAA,CAAG,CAAC,EAAC,aAAA,CAAA,EAAoB,GAAA,gBAAA,MAAM,KAAK,GAAA,CAAA,GACjD,mBAQK,MAAA,EARA,OAAK,eAAE,MAAA,GAAA,CAAG,CAAC,EAAC,YAAA,CAAA,EAAA,GACf,EAAA,UAAA,IAAA,GAAA,mBAME,UAAA,MAAA,WAL8B,MAAM,WAA5B,OAAO,eAAU;MAD3B,OAAA,UAAA,GAAA,YAME,aAAA;OAJC,KAAK,MAAM,QAAQ;OACnB,MAAM;OACN,QAAQ,QAAA,gBAAgB,MAAM;OAC9B,SAAO"}
1
+ {"version":3,"file":"group-nav.js","names":["_openBlock","_createBlock","_unref","UScroll","_normalizeClass","_withCtx","_createElementBlock","_Fragment","_renderList","_createElementVNode","_toDisplayString","GroupNavItem"],"sources":["../../../src/components/group-nav/group-nav.vue"],"sourcesContent":["<template>\n <u-scroll tag=\"ul\" :class=\"cls.b\" :container-class=\"cls.e('container')\">\n <li v-for=\"(group, index) of groups\" :key=\"group.title || index\" :class=\"cls.e('group')\">\n <div :class=\"cls.e('group-label')\">{{ group.title }}</div>\n <ul :class=\"cls.e('group-list')\">\n <GroupNavItem\n v-for=\"(child, childIndex) of group.children\"\n :key=\"child.path || childIndex\"\n :item=\"child\"\n :active=\"currentPath === child.path\"\n @click=\"handleItemClick\"\n />\n </ul>\n </li>\n </u-scroll>\n</template>\n\n<script lang=\"ts\" setup>\nimport { bem } from '@veltra/utils'\n\nimport type { GroupNavEmits, GroupNavProps } from '../../types/group-nav'\nimport type { NavItem } from '../../types/nav'\nimport { UScroll } from '../scroll'\nimport GroupNavItem from './group-nav-item.vue'\n\ndefineOptions({ name: 'UGroupNav' })\n\ndefineProps<GroupNavProps>()\nconst emit = defineEmits<GroupNavEmits>()\n\nconst cls = bem('group-nav')\n\nfunction handleItemClick(item: NavItem) {\n emit('item-click', item)\n}\n</script>\n"],"mappings":";;;;;;;;;;;;;;EA4BA,MAAM,OAAO;EAEb,MAAM,MAAM,IAAI,WAAW;EAE3B,SAAS,gBAAgB,MAAe;GACtC,KAAK,cAAc,IAAI;EACzB;;GAjCE,OAAAA,UAAA,GAAAC,YAaWC,MAAAC,WAAA,GAAA;IAbD,KAAI;IAAM,OAAKC,eAAEF,MAAA,GAAA,CAAG,CAAC,CAAC;IAAG,mBAAiBA,MAAA,GAAA,CAAG,CAAC,EAAC,WAAA;;IACnD,SAAAG,cAAgC,EAApCL,UAAA,IAAA,GAAAM,mBAWKC,UAAA,MAAAC,WAXwB,QAAA,SAAjB,OAAO,UAAK;KAAxB,OAAAR,UAAA,GAAAM,mBAWK,MAAA;MAXiC,KAAK,MAAM,SAAS;MAAQ,OAAKF,eAAEF,MAAA,GAAA,CAAG,CAAC,EAAC,OAAA,CAAA;KAC5E,GAAA,CAAAO,mBAA0D,OAAA,EAApD,OAAKL,eAAEF,MAAA,GAAA,CAAG,CAAC,EAAC,aAAA,CAAA,EAAoB,GAAAQ,gBAAA,MAAM,KAAK,GAAA,CAAA,GACjDD,mBAQK,MAAA,EARA,OAAKL,eAAEF,MAAA,GAAA,CAAG,CAAC,EAAC,YAAA,CAAA,EAAA,GACf,EAAAF,UAAA,IAAA,GAAAM,mBAMEC,UAAA,MAAAC,WAL8B,MAAM,WAA5B,OAAO,eAAU;MAD3B,OAAAR,UAAA,GAAAC,YAMEU,aAAA;OAJC,KAAK,MAAM,QAAQ;OACnB,MAAM;OACN,QAAQ,QAAA,gBAAgB,MAAM;OAC9B,SAAO"}
@@ -1 +1 @@
1
- {"version":3,"file":"icon.js","names":[],"sources":["../../../src/components/icon/icon.vue"],"sourcesContent":["<template>\n <i :class=\"cls.b\" :style=\"style\">\n <slot></slot>\n </i>\n</template>\n\n<script lang=\"ts\" setup>\nimport { bem, withUnit } from '@veltra/utils'\nimport { type CSSProperties, computed } from 'vue'\n\nimport type { IconProps } from '../../types'\n\ndefineOptions({ name: 'UIcon' })\n\nconst props = defineProps<IconProps>()\n\nconst cls = bem('icon')\n\nconst style = computed<CSSProperties>(() => {\n return { fontSize: withUnit(props.size, 'px') }\n})\n</script>\n"],"mappings":";;;;;;;;EAcA,MAAM,QAAQ;EAEd,MAAM,MAAM,IAAI,MAAM;EAEtB,MAAM,QAAQ,eAA8B;GAC1C,OAAO,EAAE,UAAU,SAAS,MAAM,MAAM,IAAI,EAAE;EAChD,CAAC;;GAnBC,OAAA,UAAA,GAAA,mBAEI,KAAA;IAFA,OAAK,eAAE,MAAA,GAAA,CAAG,CAAC,CAAC;IAAG,OAAK,eAAE,MAAA,KAAK;GAC7B,GAAA,CAAA,WAAa,KAAA,QAAA,SAAA,CAAA,GAAA,CAAA"}
1
+ {"version":3,"file":"icon.js","names":["_openBlock","_createElementBlock","_normalizeClass","_unref","_normalizeStyle","_renderSlot"],"sources":["../../../src/components/icon/icon.vue"],"sourcesContent":["<template>\n <i :class=\"cls.b\" :style=\"style\">\n <slot></slot>\n </i>\n</template>\n\n<script lang=\"ts\" setup>\nimport { bem, withUnit } from '@veltra/utils'\nimport { type CSSProperties, computed } from 'vue'\n\nimport type { IconProps } from '../../types'\n\ndefineOptions({ name: 'UIcon' })\n\nconst props = defineProps<IconProps>()\n\nconst cls = bem('icon')\n\nconst style = computed<CSSProperties>(() => {\n return { fontSize: withUnit(props.size, 'px') }\n})\n</script>\n"],"mappings":";;;;;;;;EAcA,MAAM,QAAQ;EAEd,MAAM,MAAM,IAAI,MAAM;EAEtB,MAAM,QAAQ,eAA8B;GAC1C,OAAO,EAAE,UAAU,SAAS,MAAM,MAAM,IAAI,EAAE;EAChD,CAAC;;GAnBC,OAAAA,UAAA,GAAAC,mBAEI,KAAA;IAFA,OAAKC,eAAEC,MAAA,GAAA,CAAG,CAAC,CAAC;IAAG,OAAKC,eAAE,MAAA,KAAK;GAC7B,GAAA,CAAAC,WAAa,KAAA,QAAA,SAAA,CAAA,GAAA,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"image-cropper.js","names":[],"sources":["../../../src/components/image-cropper/image-cropper.vue"],"sourcesContent":["<template>\n <div :class=\"cls.b\">\n <div v-if=\"showToolbar\" :class=\"cls.e('toolbar')\">\n <slot\n name=\"toolbar\"\n :zoom-in=\"zoomIn\"\n :zoom-out=\"zoomOut\"\n :rotate=\"rotate\"\n :flip=\"flip\"\n :reset=\"resetTransform\"\n :set-aspect-ratio=\"setAspectRatio\"\n :aspect-ratio=\"currentRatio\"\n >\n <!-- 宽高比预设 -->\n <div :class=\"cls.e('tool-group')\">\n <button\n v-for=\"preset in RATIO_PRESETS\"\n :key=\"preset.label\"\n type=\"button\"\n :class=\"[cls.e('tool'), bem.is('active', preset.value === currentRatio)]\"\n @click=\"setAspectRatio(preset.value)\"\n >\n {{ preset.label }}\n </button>\n </div>\n\n <!-- 缩放 / 旋转 / 翻转 / 重置 -->\n <div :class=\"cls.e('tool-group')\">\n <button\n type=\"button\"\n :class=\"[cls.e('tool'), cls.em('tool', 'icon')]\"\n aria-label=\"缩小\"\n title=\"缩小\"\n @click=\"zoomOut()\"\n >\n <u-icon :size=\"15\"><ZoomOut /></u-icon>\n </button>\n <button\n type=\"button\"\n :class=\"[cls.e('tool'), cls.em('tool', 'icon')]\"\n aria-label=\"放大\"\n title=\"放大\"\n @click=\"zoomIn()\"\n >\n <u-icon :size=\"15\"><ZoomIn /></u-icon>\n </button>\n <button\n type=\"button\"\n :class=\"[cls.e('tool'), cls.em('tool', 'icon')]\"\n aria-label=\"逆时针旋转 90°\"\n title=\"逆时针旋转 90°\"\n @click=\"rotate(-1)\"\n >\n <u-icon :size=\"15\"><RotateLeft /></u-icon>\n </button>\n <button\n type=\"button\"\n :class=\"[cls.e('tool'), cls.em('tool', 'icon')]\"\n aria-label=\"顺时针旋转 90°\"\n title=\"顺时针旋转 90°\"\n @click=\"rotate(1)\"\n >\n <u-icon :size=\"15\"><RotateRight /></u-icon>\n </button>\n <button\n type=\"button\"\n :class=\"[cls.e('tool'), cls.em('tool', 'icon')]\"\n aria-label=\"水平翻转\"\n title=\"水平翻转\"\n @click=\"flip('horizontal')\"\n >\n <u-icon :size=\"15\" :class=\"cls.e('flip-icon')\"><ArrowUpdown /></u-icon>\n </button>\n <button\n type=\"button\"\n :class=\"[cls.e('tool'), cls.em('tool', 'icon')]\"\n aria-label=\"垂直翻转\"\n title=\"垂直翻转\"\n @click=\"flip('vertical')\"\n >\n <u-icon :size=\"15\"><ArrowUpdown /></u-icon>\n </button>\n <button\n type=\"button\"\n :class=\"[cls.e('tool'), cls.em('tool', 'icon')]\"\n aria-label=\"重置\"\n title=\"重置\"\n @click=\"resetTransform()\"\n >\n <u-icon :size=\"15\"><Refresh /></u-icon>\n </button>\n </div>\n </slot>\n </div>\n\n <div :class=\"cls.e('canvas')\" ref=\"canvasRef\">\n <div v-if=\"loaded\" :class=\"cls.e('stage')\" :style=\"stageStyle\">\n <img :class=\"cls.e('image')\" :src=\"imageUrl\" draggable=\"false\" alt=\"\" />\n\n <template v-if=\"selection\">\n <!-- 选区外半透明遮罩 -->\n <div v-for=\"(style, i) in maskStyles\" :key=\"i\" :class=\"cls.e('mask')\" :style=\"style\" />\n\n <!-- 裁剪选区:整体拖动 + 8 个手柄调整大小 -->\n <div :class=\"cls.e('selection')\" ref=\"selectionRef\" :style=\"selectionStyle\">\n <!-- 3×3 网格线,顺序对应 style.scss 中 nth-child 的定位 -->\n <i v-for=\"i in 4\" :key=\"i\" :class=\"cls.e('grid-line')\" />\n <i\n v-for=\"handle in SELECTION_HANDLES\"\n :key=\"handle\"\n :class=\"cls.e('handle')\"\n :data-handle=\"handle\"\n />\n </div>\n </template>\n </div>\n </div>\n\n <div v-if=\"showPreview && loaded\" :class=\"cls.e('preview')\">\n <canvas :class=\"cls.e('preview-canvas')\" ref=\"previewCanvasRef\" />\n </div>\n </div>\n</template>\n\n<script lang=\"ts\" setup>\nimport { useResizeObserver } from '@veltra/compositions'\nimport {\n ArrowUpdown,\n Refresh,\n RotateLeft,\n RotateRight,\n ZoomIn,\n ZoomOut\n} from '@veltra/icons/normal'\nimport { bem } from '@veltra/utils'\nimport { computed, reactive, shallowRef, watch } from 'vue'\n\nimport type {\n ImageCropperProps,\n ImageCropperEmits,\n ImageCropperResult,\n ImageCropperResultOptions,\n _ImageCropperExposed\n} from '../../types'\nimport { UIcon } from '../icon'\nimport { cropToResult } from './draw-crop'\nimport { useImageLoader } from './use-image-loader'\nimport { usePreview } from './use-preview'\nimport { SELECTION_HANDLES, useSelection } from './use-selection'\nimport { useTransform } from './use-transform'\n\ndefineOptions({ name: 'ImageCropper' })\n\nconst props = withDefaults(defineProps<ImageCropperProps>(), {\n showToolbar: true,\n showPreview: true\n})\n\nconst emit = defineEmits<ImageCropperEmits>()\n\nconst cls = bem('image-cropper')\n\nconst canvasRef = shallowRef<HTMLElement>()\nconst selectionRef = shallowRef<HTMLElement>()\nconst previewCanvasRef = shallowRef<HTMLCanvasElement>()\n\nconst { imageUrl, loaded, naturalWidth, naturalHeight, imageEl } = useImageLoader({\n src: () => props.src\n})\n\nconst canvasSize = reactive({ width: 0, height: 0 })\n\n/** 宽高比预设,value 为 undefined 表示自由比例 */\nconst RATIO_PRESETS: { label: string; value?: number }[] = [\n { label: '自由', value: undefined },\n { label: '1:1', value: 1 },\n { label: '4:3', value: 4 / 3 },\n { label: '16:9', value: 16 / 9 }\n]\n\n/** 当前生效的宽高比:工具栏预设可覆盖 prop,prop 变化时同步回来 */\nconst currentRatio = shallowRef(props.aspectRatio)\n\nfunction setAspectRatio(ratio: number | undefined) {\n currentRatio.value = ratio\n}\n\nconst { transform, fit, reset, resetTransform, zoomIn, zoomOut, rotate, flip, toImageDelta } =\n useTransform({\n target: canvasRef,\n canvasSize: () => canvasSize,\n imageWidth: () => naturalWidth.value,\n imageHeight: () => naturalHeight.value,\n onReset: () => initSelection()\n })\n\nconst { selection, initSelection, clearSelection } = useSelection({\n target: selectionRef,\n imageWidth: () => naturalWidth.value,\n imageHeight: () => naturalHeight.value,\n toImageDelta,\n aspectRatio: () => currentRatio.value\n})\n\nusePreview({\n canvas: previewCanvasRef,\n image: imageEl,\n selection,\n transform,\n canvasSize: () => canvasSize\n})\n\nuseResizeObserver({\n targets: canvasRef,\n onResize([entry]) {\n if (!entry) return\n canvasSize.width = entry.contentRect.width\n canvasSize.height = entry.contentRect.height\n if (loaded.value) fit()\n }\n})\n\nwatch(\n () => props.src,\n () => {\n reset()\n clearSelection()\n }\n)\n\nwatch(\n () => props.aspectRatio,\n (ratio) => {\n currentRatio.value = ratio\n }\n)\n\nwatch(loaded, (isLoaded) => {\n if (!isLoaded) return\n fit()\n initSelection()\n})\n\n// 选区或图片变换变化时发出裁剪变化事件,载荷为当前选区(图片像素坐标)与变换摘要\nwatch([selection, () => ({ ...transform })], () => {\n const sel = selection.value\n if (!sel) return\n emit('crop-change', {\n selection: { ...sel },\n transform: { rotation: transform.rotation, flipX: transform.flipX, flipY: transform.flipY }\n })\n})\n\n/** 输出当前选区裁剪结果:默认原图选区像素,options 传入目标宽 / 高时按该尺寸缩放 */\nasync function getResult(options?: ImageCropperResultOptions): Promise<ImageCropperResult> {\n const img = imageEl.value\n const sel = selection.value\n if (!img || !sel) throw new Error('Export crop result failed: image not loaded or no selection')\n return cropToResult(img, sel, transform, options)\n}\n\ndefineExpose<_ImageCropperExposed>({ getResult })\n\n/** 舞台样式:图片与选区层共用同一变换,选区以图片像素坐标定位 */\nconst stageStyle = computed(() => {\n const { translateX, translateY, rotation, scale, flipX, flipY } = transform\n return {\n width: `${naturalWidth.value}px`,\n height: `${naturalHeight.value}px`,\n transform: `translate(${translateX}px, ${translateY}px) rotate(${rotation}deg) scale(${(flipX ? -1 : 1) * scale}, ${(flipY ? -1 : 1) * scale})`,\n // 逆缩放系数:选区边框 / 网格线 / 手柄在缩放后保持屏幕恒定尺寸\n '--u-image-cropper-inv-scale': String(1 / scale)\n }\n})\n\nconst selectionStyle = computed(() => {\n const sel = selection.value\n if (!sel) return {}\n return {\n left: `${sel.x}px`,\n top: `${sel.y}px`,\n width: `${sel.width}px`,\n height: `${sel.height}px`\n }\n})\n\n/** 选区外上 / 下 / 左 / 右四向遮罩 */\nconst maskStyles = computed(() => {\n const sel = selection.value\n if (!sel) return []\n const W = naturalWidth.value\n const H = naturalHeight.value\n const right = sel.x + sel.width\n const bottom = sel.y + sel.height\n return [\n { left: '0px', top: '0px', width: `${W}px`, height: `${sel.y}px` },\n { left: '0px', top: `${bottom}px`, width: `${W}px`, height: `${H - bottom}px` },\n { left: '0px', top: `${sel.y}px`, width: `${sel.x}px`, height: `${sel.height}px` },\n { left: `${right}px`, top: `${sel.y}px`, width: `${W - right}px`, height: `${sel.height}px` }\n ]\n})\n</script>\n"],"mappings":"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"}
1
+ {"version":3,"file":"image-cropper.js","names":["_openBlock","_createElementBlock","_normalizeClass","_unref","_renderSlot","_createCommentVNode","_createElementVNode","_Fragment","_renderList","_toDisplayString","_createVNode","UIcon","_withCtx","_normalizeStyle"],"sources":["../../../src/components/image-cropper/image-cropper.vue"],"sourcesContent":["<template>\n <div :class=\"cls.b\">\n <div v-if=\"showToolbar\" :class=\"cls.e('toolbar')\">\n <slot\n name=\"toolbar\"\n :zoom-in=\"zoomIn\"\n :zoom-out=\"zoomOut\"\n :rotate=\"rotate\"\n :flip=\"flip\"\n :reset=\"resetTransform\"\n :set-aspect-ratio=\"setAspectRatio\"\n :aspect-ratio=\"currentRatio\"\n >\n <!-- 宽高比预设 -->\n <div :class=\"cls.e('tool-group')\">\n <button\n v-for=\"preset in RATIO_PRESETS\"\n :key=\"preset.label\"\n type=\"button\"\n :class=\"[cls.e('tool'), bem.is('active', preset.value === currentRatio)]\"\n @click=\"setAspectRatio(preset.value)\"\n >\n {{ preset.label }}\n </button>\n </div>\n\n <!-- 缩放 / 旋转 / 翻转 / 重置 -->\n <div :class=\"cls.e('tool-group')\">\n <button\n type=\"button\"\n :class=\"[cls.e('tool'), cls.em('tool', 'icon')]\"\n aria-label=\"缩小\"\n title=\"缩小\"\n @click=\"zoomOut()\"\n >\n <u-icon :size=\"15\"><ZoomOut /></u-icon>\n </button>\n <button\n type=\"button\"\n :class=\"[cls.e('tool'), cls.em('tool', 'icon')]\"\n aria-label=\"放大\"\n title=\"放大\"\n @click=\"zoomIn()\"\n >\n <u-icon :size=\"15\"><ZoomIn /></u-icon>\n </button>\n <button\n type=\"button\"\n :class=\"[cls.e('tool'), cls.em('tool', 'icon')]\"\n aria-label=\"逆时针旋转 90°\"\n title=\"逆时针旋转 90°\"\n @click=\"rotate(-1)\"\n >\n <u-icon :size=\"15\"><RotateLeft /></u-icon>\n </button>\n <button\n type=\"button\"\n :class=\"[cls.e('tool'), cls.em('tool', 'icon')]\"\n aria-label=\"顺时针旋转 90°\"\n title=\"顺时针旋转 90°\"\n @click=\"rotate(1)\"\n >\n <u-icon :size=\"15\"><RotateRight /></u-icon>\n </button>\n <button\n type=\"button\"\n :class=\"[cls.e('tool'), cls.em('tool', 'icon')]\"\n aria-label=\"水平翻转\"\n title=\"水平翻转\"\n @click=\"flip('horizontal')\"\n >\n <u-icon :size=\"15\" :class=\"cls.e('flip-icon')\"><ArrowUpdown /></u-icon>\n </button>\n <button\n type=\"button\"\n :class=\"[cls.e('tool'), cls.em('tool', 'icon')]\"\n aria-label=\"垂直翻转\"\n title=\"垂直翻转\"\n @click=\"flip('vertical')\"\n >\n <u-icon :size=\"15\"><ArrowUpdown /></u-icon>\n </button>\n <button\n type=\"button\"\n :class=\"[cls.e('tool'), cls.em('tool', 'icon')]\"\n aria-label=\"重置\"\n title=\"重置\"\n @click=\"resetTransform()\"\n >\n <u-icon :size=\"15\"><Refresh /></u-icon>\n </button>\n </div>\n </slot>\n </div>\n\n <div :class=\"cls.e('canvas')\" ref=\"canvasRef\">\n <div v-if=\"loaded\" :class=\"cls.e('stage')\" :style=\"stageStyle\">\n <img :class=\"cls.e('image')\" :src=\"imageUrl\" draggable=\"false\" alt=\"\" />\n\n <template v-if=\"selection\">\n <!-- 选区外半透明遮罩 -->\n <div v-for=\"(style, i) in maskStyles\" :key=\"i\" :class=\"cls.e('mask')\" :style=\"style\" />\n\n <!-- 裁剪选区:整体拖动 + 8 个手柄调整大小 -->\n <div :class=\"cls.e('selection')\" ref=\"selectionRef\" :style=\"selectionStyle\">\n <!-- 3×3 网格线,顺序对应 style.scss 中 nth-child 的定位 -->\n <i v-for=\"i in 4\" :key=\"i\" :class=\"cls.e('grid-line')\" />\n <i\n v-for=\"handle in SELECTION_HANDLES\"\n :key=\"handle\"\n :class=\"cls.e('handle')\"\n :data-handle=\"handle\"\n />\n </div>\n </template>\n </div>\n </div>\n\n <div v-if=\"showPreview && loaded\" :class=\"cls.e('preview')\">\n <canvas :class=\"cls.e('preview-canvas')\" ref=\"previewCanvasRef\" />\n </div>\n </div>\n</template>\n\n<script lang=\"ts\" setup>\nimport { useResizeObserver } from '@veltra/compositions'\nimport {\n ArrowUpdown,\n Refresh,\n RotateLeft,\n RotateRight,\n ZoomIn,\n ZoomOut\n} from '@veltra/icons/normal'\nimport { bem } from '@veltra/utils'\nimport { computed, reactive, shallowRef, watch } from 'vue'\n\nimport type {\n ImageCropperProps,\n ImageCropperEmits,\n ImageCropperResult,\n ImageCropperResultOptions,\n _ImageCropperExposed\n} from '../../types'\nimport { UIcon } from '../icon'\nimport { cropToResult } from './draw-crop'\nimport { useImageLoader } from './use-image-loader'\nimport { usePreview } from './use-preview'\nimport { SELECTION_HANDLES, useSelection } from './use-selection'\nimport { useTransform } from './use-transform'\n\ndefineOptions({ name: 'ImageCropper' })\n\nconst props = withDefaults(defineProps<ImageCropperProps>(), {\n showToolbar: true,\n showPreview: true\n})\n\nconst emit = defineEmits<ImageCropperEmits>()\n\nconst cls = bem('image-cropper')\n\nconst canvasRef = shallowRef<HTMLElement>()\nconst selectionRef = shallowRef<HTMLElement>()\nconst previewCanvasRef = shallowRef<HTMLCanvasElement>()\n\nconst { imageUrl, loaded, naturalWidth, naturalHeight, imageEl } = useImageLoader({\n src: () => props.src\n})\n\nconst canvasSize = reactive({ width: 0, height: 0 })\n\n/** 宽高比预设,value 为 undefined 表示自由比例 */\nconst RATIO_PRESETS: { label: string; value?: number }[] = [\n { label: '自由', value: undefined },\n { label: '1:1', value: 1 },\n { label: '4:3', value: 4 / 3 },\n { label: '16:9', value: 16 / 9 }\n]\n\n/** 当前生效的宽高比:工具栏预设可覆盖 prop,prop 变化时同步回来 */\nconst currentRatio = shallowRef(props.aspectRatio)\n\nfunction setAspectRatio(ratio: number | undefined) {\n currentRatio.value = ratio\n}\n\nconst { transform, fit, reset, resetTransform, zoomIn, zoomOut, rotate, flip, toImageDelta } =\n useTransform({\n target: canvasRef,\n canvasSize: () => canvasSize,\n imageWidth: () => naturalWidth.value,\n imageHeight: () => naturalHeight.value,\n onReset: () => initSelection()\n })\n\nconst { selection, initSelection, clearSelection } = useSelection({\n target: selectionRef,\n imageWidth: () => naturalWidth.value,\n imageHeight: () => naturalHeight.value,\n toImageDelta,\n aspectRatio: () => currentRatio.value\n})\n\nusePreview({\n canvas: previewCanvasRef,\n image: imageEl,\n selection,\n transform,\n canvasSize: () => canvasSize\n})\n\nuseResizeObserver({\n targets: canvasRef,\n onResize([entry]) {\n if (!entry) return\n canvasSize.width = entry.contentRect.width\n canvasSize.height = entry.contentRect.height\n if (loaded.value) fit()\n }\n})\n\nwatch(\n () => props.src,\n () => {\n reset()\n clearSelection()\n }\n)\n\nwatch(\n () => props.aspectRatio,\n (ratio) => {\n currentRatio.value = ratio\n }\n)\n\nwatch(loaded, (isLoaded) => {\n if (!isLoaded) return\n fit()\n initSelection()\n})\n\n// 选区或图片变换变化时发出裁剪变化事件,载荷为当前选区(图片像素坐标)与变换摘要\nwatch([selection, () => ({ ...transform })], () => {\n const sel = selection.value\n if (!sel) return\n emit('crop-change', {\n selection: { ...sel },\n transform: { rotation: transform.rotation, flipX: transform.flipX, flipY: transform.flipY }\n })\n})\n\n/** 输出当前选区裁剪结果:默认原图选区像素,options 传入目标宽 / 高时按该尺寸缩放 */\nasync function getResult(options?: ImageCropperResultOptions): Promise<ImageCropperResult> {\n const img = imageEl.value\n const sel = selection.value\n if (!img || !sel) throw new Error('Export crop result failed: image not loaded or no selection')\n return cropToResult(img, sel, transform, options)\n}\n\ndefineExpose<_ImageCropperExposed>({ getResult })\n\n/** 舞台样式:图片与选区层共用同一变换,选区以图片像素坐标定位 */\nconst stageStyle = computed(() => {\n const { translateX, translateY, rotation, scale, flipX, flipY } = transform\n return {\n width: `${naturalWidth.value}px`,\n height: `${naturalHeight.value}px`,\n transform: `translate(${translateX}px, ${translateY}px) rotate(${rotation}deg) scale(${(flipX ? -1 : 1) * scale}, ${(flipY ? -1 : 1) * scale})`,\n // 逆缩放系数:选区边框 / 网格线 / 手柄在缩放后保持屏幕恒定尺寸\n '--u-image-cropper-inv-scale': String(1 / scale)\n }\n})\n\nconst selectionStyle = computed(() => {\n const sel = selection.value\n if (!sel) return {}\n return {\n left: `${sel.x}px`,\n top: `${sel.y}px`,\n width: `${sel.width}px`,\n height: `${sel.height}px`\n }\n})\n\n/** 选区外上 / 下 / 左 / 右四向遮罩 */\nconst maskStyles = computed(() => {\n const sel = selection.value\n if (!sel) return []\n const W = naturalWidth.value\n const H = naturalHeight.value\n const right = sel.x + sel.width\n const bottom = sel.y + sel.height\n return [\n { left: '0px', top: '0px', width: `${W}px`, height: `${sel.y}px` },\n { left: '0px', top: `${bottom}px`, width: `${W}px`, height: `${H - bottom}px` },\n { left: '0px', top: `${sel.y}px`, width: `${sel.x}px`, height: `${sel.height}px` },\n { left: `${right}px`, top: `${sel.y}px`, width: `${W - right}px`, height: `${sel.height}px` }\n ]\n})\n</script>\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"input.js","names":[],"sources":["../../../src/components/input/input.vue"],"sourcesContent":["<template>\n <div\n v-if=\"!readonly\"\n v-bind=\"$attrs\"\n :class=\"inputClass\"\n @mouseenter=\"handleMouseEnter\"\n @mouseleave=\"handleMouseLeave\"\n >\n <span v-if=\"$slots.prefix || prefix\" :class=\"prefixClass\" @click=\"handlePrefixClick\">\n {{ prefix }}\n <slot name=\"prefix\"></slot>\n </span>\n\n <input\n :class=\"cls.e('native')\"\n :placeholder=\"props.placeholder\"\n type=\"text\"\n :value=\"model\"\n @input=\"handleInput\"\n @change=\"handleChange\"\n @focus=\"handleFocus\"\n @blur=\"handleBlur\"\n @compositionstart=\"handleCompositionStart\"\n @compositionend=\"handleCompositionEnd\"\n autocomplete=\"off\"\n ref=\"el\"\n :disabled=\"disabled\"\n :readonly=\"nativeReadonly\"\n />\n\n <span :class=\"suffixClass\" v-if=\"hasSuffix\">\n <Transition name=\"zoom-in\" mode=\"out-in\">\n <UIcon\n v-if=\"showClear\"\n :class=\"cls.e('clear')\"\n title=\"清除\"\n @click.stop=\"clearModelValue\"\n key=\"clear\"\n >\n <Close />\n </UIcon>\n\n <span v-else :class=\"cls.e('suffix-content')\" @click=\"handleSuffixClick\" key=\"suffix\">\n {{ suffix }}\n <slot name=\"suffix\"></slot>\n </span>\n </Transition>\n </span>\n </div>\n\n <template v-else>\n {{ generateModel || FORM_EMPTY_CONTENT }}\n </template>\n</template>\n\n<script lang=\"tsx\" setup>\nimport { useFocus, useFormFallbackProps } from '@veltra/compositions'\nimport { Close } from '@veltra/icons/normal'\nimport { bem, FORM_EMPTY_CONTENT } from '@veltra/utils'\nimport { injectFormContext } from '@veltra/utils'\nimport { computed, getCurrentInstance, ref, shallowRef, nextTick } from 'vue'\n\nimport type { InputEmits, InputProps, _InputExposed } from '../../types'\nimport { UIcon } from '../icon'\n\ndefineOptions({ name: 'UInput', inheritAttrs: false })\n\nconst props = withDefaults(defineProps<InputProps>(), {\n placeholder: '请输入',\n clearable: true,\n disabled: undefined,\n readonly: undefined\n})\n\nconst emit = defineEmits<InputEmits>()\n\nconst model = defineModel<string>()\n\nconst inst = getCurrentInstance()\n\nconst cls = bem('input')\n\nconst { formProps } = injectFormContext()\n\nconst { size, disabled, readonly } = useFormFallbackProps([formProps ?? {}, props])\n\nconst { focus, handleBlur, handleFocus } = useFocus((focused) => {\n if (focused) {\n emit('focus')\n } else {\n emit('blur')\n }\n})\n\nconst inputClass = computed(() => {\n return [\n cls.b,\n cls.m(size.value),\n bem.is('disabled', disabled.value),\n bem.is('readonly', readonly.value),\n bem.is('focus', focus.value)\n ]\n})\n\nconst prefixClass = [cls.e('prefix'), bem.is('clickable', !!inst?.vnode.props?.['onPrefix:click'])]\n\nconst suffixClass = [cls.e('suffix'), bem.is('clickable', !!inst?.vnode.props?.['onSuffix:click'])]\n\nlet isComposing = false\n\nfunction handleCompositionStart() {\n isComposing = true\n}\n\nfunction handleCompositionEnd(e: Event) {\n isComposing = false\n handleInput(e)\n}\n\nconst handleInput = (e: Event) => {\n if (isComposing) return\n\n const inputVal = (e.target as HTMLInputElement).value\n emit('native:input', e)\n\n const valid = props.pattern?.test(inputVal) ?? true\n\n if (!valid) return\n model.value = inputVal\n}\n\nconst handlePrefixClick = () => {\n emit('prefix:click', model.value)\n}\n\nconst handleSuffixClick = () => {\n emit('suffix:click', model.value)\n}\n\nconst clearModelValue = () => {\n model.value = ''\n emit('clear')\n}\n\nconst hovered = ref(false)\nconst handleMouseEnter = () => {\n hovered.value = true\n}\n\nconst handleMouseLeave = () => {\n hovered.value = false\n}\n\nconst showClear = computed(() => {\n return props.clearable && !disabled.value && !!model.value && hovered.value\n})\n\nconst hasSuffixContent = computed(() => {\n return !!inst?.slots.suffix || !!props.suffix\n})\n\nconst hasSuffix = computed(() => {\n return hasSuffixContent.value || showClear.value\n})\n\nconst handleChange = (e: Event) => {\n const target = e.target as HTMLInputElement\n\n const valid = props.pattern?.test(target.value) ?? true\n\n if (valid) {\n emit('change', target.value)\n } else {\n nextTick(() => {\n target.value = model.value ?? ''\n })\n }\n}\n\nconst el = shallowRef<HTMLInputElement>()\n\nconst generateModel = computed(() => {\n if (!model.value) return ''\n\n return `${props.prefix ?? ''}${model.value}${props.suffix ?? ''}`\n})\n\ndefineExpose<_InputExposed>({ el })\n</script>\n"],"mappings":""}
1
+ {"version":3,"file":"input.js","names":["_sfc_main"],"sources":["../../../src/components/input/input.vue"],"sourcesContent":["<template>\n <div\n v-if=\"!readonly\"\n v-bind=\"$attrs\"\n :class=\"inputClass\"\n @mouseenter=\"handleMouseEnter\"\n @mouseleave=\"handleMouseLeave\"\n >\n <span v-if=\"$slots.prefix || prefix\" :class=\"prefixClass\" @click=\"handlePrefixClick\">\n {{ prefix }}\n <slot name=\"prefix\"></slot>\n </span>\n\n <input\n :class=\"cls.e('native')\"\n :placeholder=\"props.placeholder\"\n type=\"text\"\n :value=\"model\"\n @input=\"handleInput\"\n @change=\"handleChange\"\n @focus=\"handleFocus\"\n @blur=\"handleBlur\"\n @compositionstart=\"handleCompositionStart\"\n @compositionend=\"handleCompositionEnd\"\n autocomplete=\"off\"\n ref=\"el\"\n :disabled=\"disabled\"\n :readonly=\"nativeReadonly\"\n />\n\n <span :class=\"suffixClass\" v-if=\"hasSuffix\">\n <Transition name=\"zoom-in\" mode=\"out-in\">\n <UIcon\n v-if=\"showClear\"\n :class=\"cls.e('clear')\"\n title=\"清除\"\n @click.stop=\"clearModelValue\"\n key=\"clear\"\n >\n <Close />\n </UIcon>\n\n <span v-else :class=\"cls.e('suffix-content')\" @click=\"handleSuffixClick\" key=\"suffix\">\n {{ suffix }}\n <slot name=\"suffix\"></slot>\n </span>\n </Transition>\n </span>\n </div>\n\n <template v-else>\n {{ generateModel || FORM_EMPTY_CONTENT }}\n </template>\n</template>\n\n<script lang=\"tsx\" setup>\nimport { useFocus, useFormFallbackProps } from '@veltra/compositions'\nimport { Close } from '@veltra/icons/normal'\nimport { bem, FORM_EMPTY_CONTENT } from '@veltra/utils'\nimport { injectFormContext } from '@veltra/utils'\nimport { computed, getCurrentInstance, ref, shallowRef, nextTick } from 'vue'\n\nimport type { InputEmits, InputProps, _InputExposed } from '../../types'\nimport { UIcon } from '../icon'\n\ndefineOptions({ name: 'UInput', inheritAttrs: false })\n\nconst props = withDefaults(defineProps<InputProps>(), {\n placeholder: '请输入',\n clearable: true,\n disabled: undefined,\n readonly: undefined\n})\n\nconst emit = defineEmits<InputEmits>()\n\nconst model = defineModel<string>()\n\nconst inst = getCurrentInstance()\n\nconst cls = bem('input')\n\nconst { formProps } = injectFormContext()\n\nconst { size, disabled, readonly } = useFormFallbackProps([formProps ?? {}, props])\n\nconst { focus, handleBlur, handleFocus } = useFocus((focused) => {\n if (focused) {\n emit('focus')\n } else {\n emit('blur')\n }\n})\n\nconst inputClass = computed(() => {\n return [\n cls.b,\n cls.m(size.value),\n bem.is('disabled', disabled.value),\n bem.is('readonly', readonly.value),\n bem.is('focus', focus.value)\n ]\n})\n\nconst prefixClass = [cls.e('prefix'), bem.is('clickable', !!inst?.vnode.props?.['onPrefix:click'])]\n\nconst suffixClass = [cls.e('suffix'), bem.is('clickable', !!inst?.vnode.props?.['onSuffix:click'])]\n\nlet isComposing = false\n\nfunction handleCompositionStart() {\n isComposing = true\n}\n\nfunction handleCompositionEnd(e: Event) {\n isComposing = false\n handleInput(e)\n}\n\nconst handleInput = (e: Event) => {\n if (isComposing) return\n\n const inputVal = (e.target as HTMLInputElement).value\n emit('native:input', e)\n\n const valid = props.pattern?.test(inputVal) ?? true\n\n if (!valid) return\n model.value = inputVal\n}\n\nconst handlePrefixClick = () => {\n emit('prefix:click', model.value)\n}\n\nconst handleSuffixClick = () => {\n emit('suffix:click', model.value)\n}\n\nconst clearModelValue = () => {\n model.value = ''\n emit('clear')\n}\n\nconst hovered = ref(false)\nconst handleMouseEnter = () => {\n hovered.value = true\n}\n\nconst handleMouseLeave = () => {\n hovered.value = false\n}\n\nconst showClear = computed(() => {\n return props.clearable && !disabled.value && !!model.value && hovered.value\n})\n\nconst hasSuffixContent = computed(() => {\n return !!inst?.slots.suffix || !!props.suffix\n})\n\nconst hasSuffix = computed(() => {\n return hasSuffixContent.value || showClear.value\n})\n\nconst handleChange = (e: Event) => {\n const target = e.target as HTMLInputElement\n\n const valid = props.pattern?.test(target.value) ?? true\n\n if (valid) {\n emit('change', target.value)\n } else {\n nextTick(() => {\n target.value = model.value ?? ''\n })\n }\n}\n\nconst el = shallowRef<HTMLInputElement>()\n\nconst generateModel = computed(() => {\n if (!model.value) return ''\n\n return `${props.prefix ?? ''}${model.value}${props.suffix ?? ''}`\n})\n\ndefineExpose<_InputExposed>({ el })\n</script>\n"],"mappings":""}