@veltra/desktop 1.8.2 → 1.8.4

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 (207) 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.map +1 -1
  61. package/dist/components/file-viewer/previewers/pdf-viewport-scroll.js.map +1 -1
  62. package/dist/components/file-viewer/previewers/pdf-zoom-bridge.js.map +1 -1
  63. package/dist/components/file-viewer/previewers/sheet-previewer.js.map +1 -1
  64. package/dist/components/file-viewer/previewers/text-previewer.js.map +1 -1
  65. package/dist/components/file-viewer/previewers/video-previewer.js.map +1 -1
  66. package/dist/components/float-button/float-button.js.map +1 -1
  67. package/dist/components/form/form.js.map +1 -1
  68. package/dist/components/form/form.vue_vue_type_script_setup_true_lang.js.map +1 -1
  69. package/dist/components/form-item/form-item.js.map +1 -1
  70. package/dist/components/form-item/form-item.vue_vue_type_script_setup_true_lang.js.map +1 -1
  71. package/dist/components/gantt-chart/gantt-chart.js.map +1 -1
  72. package/dist/components/grid/grid-item.js.map +1 -1
  73. package/dist/components/grid/grid.js.map +1 -1
  74. package/dist/components/grid-input/grid-input.js.map +1 -1
  75. package/dist/components/group-input/group-input.js.map +1 -1
  76. package/dist/components/group-nav/group-nav-item.js.map +1 -1
  77. package/dist/components/group-nav/group-nav.js.map +1 -1
  78. package/dist/components/icon/icon.js.map +1 -1
  79. package/dist/components/image-cropper/image-cropper.js.map +1 -1
  80. package/dist/components/input/input.js.map +1 -1
  81. package/dist/components/input/input.vue_vue_type_script_setup_true_lang.js.map +1 -1
  82. package/dist/components/kanban/kanban-column.js.map +1 -1
  83. package/dist/components/kanban/kanban.js.map +1 -1
  84. package/dist/components/kbd/kbd.js.map +1 -1
  85. package/dist/components/layout/layout-resizer.js.map +1 -1
  86. package/dist/components/layout/layout.js.map +1 -1
  87. package/dist/components/list/list-item.js.map +1 -1
  88. package/dist/components/list/list.js.map +1 -1
  89. package/dist/components/loading/loading.js.map +1 -1
  90. package/dist/components/message/message-box.js.map +1 -1
  91. package/dist/components/message/message.js.map +1 -1
  92. package/dist/components/message-confirm/message-confirm-box.js.map +1 -1
  93. package/dist/components/message-confirm/message-confirm.js.map +1 -1
  94. package/dist/components/multi-select/multi-select-option.js.map +1 -1
  95. package/dist/components/multi-select/multi-select.js.map +1 -1
  96. package/dist/components/multi-tree-select/multi-tree-select.js.map +1 -1
  97. package/dist/components/nav/nav-icon.js.map +1 -1
  98. package/dist/components/nav/nav-item-collapsed.js.map +1 -1
  99. package/dist/components/nav/nav-item.js.map +1 -1
  100. package/dist/components/nav/nav-sub-collapsed.js.map +1 -1
  101. package/dist/components/nav/nav-sub.js.map +1 -1
  102. package/dist/components/nav/nav.js.map +1 -1
  103. package/dist/components/notification/notification-box.js.map +1 -1
  104. package/dist/components/notification/notification.js.map +1 -1
  105. package/dist/components/number/number.js.map +1 -1
  106. package/dist/components/number-input/number-input.js.map +1 -1
  107. package/dist/components/number-range-input/number-range-input.js.map +1 -1
  108. package/dist/components/paginator/paginator.js.map +1 -1
  109. package/dist/components/palette/palette-alpha.js.map +1 -1
  110. package/dist/components/palette/palette-color-switch.js.map +1 -1
  111. package/dist/components/palette/palette-hue.js.map +1 -1
  112. package/dist/components/palette/palette-sv.js.map +1 -1
  113. package/dist/components/palette/palette.js.map +1 -1
  114. package/dist/components/password-input/password-input.js.map +1 -1
  115. package/dist/components/pop-confirm/pop-confirm.js.map +1 -1
  116. package/dist/components/progress/progress.js.map +1 -1
  117. package/dist/components/progress-nodes/progress-nodes.js.map +1 -1
  118. package/dist/components/radio/radio.js.map +1 -1
  119. package/dist/components/radio-group/radio-group.js.map +1 -1
  120. package/dist/components/rich-text-editor/image-node.js +53 -14
  121. package/dist/components/rich-text-editor/image-node.js.map +1 -1
  122. package/dist/components/rich-text-editor/rich-text-editor.js +9 -3
  123. package/dist/components/rich-text-editor/rich-text-editor.js.map +1 -1
  124. package/dist/components/rich-text-editor/style2.css +31 -0
  125. package/dist/components/rich-text-editor/toolbar.js.map +1 -1
  126. package/dist/components/rich-text-editor/use-image-resize.js +118 -0
  127. package/dist/components/rich-text-editor/use-image-resize.js.map +1 -0
  128. package/dist/components/scroll/scroll-bar.js.map +1 -1
  129. package/dist/components/scroll/scroll.js.map +1 -1
  130. package/dist/components/segment/segment.js.map +1 -1
  131. package/dist/components/select/select.js +9 -5
  132. package/dist/components/select/select.js.map +1 -1
  133. package/dist/components/slider/slider-thumb.js.map +1 -1
  134. package/dist/components/slider/slider.js.map +1 -1
  135. package/dist/components/steps/steps.js.map +1 -1
  136. package/dist/components/switch/switch.js.map +1 -1
  137. package/dist/components/table/table-body.js.map +1 -1
  138. package/dist/components/table/table-cell.js.map +1 -1
  139. package/dist/components/table/table-foot.js.map +1 -1
  140. package/dist/components/table/table-head.js.map +1 -1
  141. package/dist/components/table/table-row.js.map +1 -1
  142. package/dist/components/table/table.js.map +1 -1
  143. package/dist/components/table-editor/table-editor.js.map +1 -1
  144. package/dist/components/tabs/tabs-horizontal.js.map +1 -1
  145. package/dist/components/tabs/tabs-vertical.js.map +1 -1
  146. package/dist/components/tabs/tabs.js.map +1 -1
  147. package/dist/components/tag/tag.js.map +1 -1
  148. package/dist/components/text/text.js.map +1 -1
  149. package/dist/components/textarea/textarea.js.map +1 -1
  150. package/dist/components/theme/theme.js.map +1 -1
  151. package/dist/components/tip/tip.js.map +1 -1
  152. package/dist/components/tree/tree-node.js.map +1 -1
  153. package/dist/components/tree/tree.js.map +1 -1
  154. package/dist/components/tree-select/tree-select.js +19 -10
  155. package/dist/components/tree-select/tree-select.js.map +1 -1
  156. package/dist/components/watermark/watermark.js.map +1 -1
  157. package/dist/types/cascade.d.ts +5 -0
  158. package/dist/types/select.d.ts +8 -2
  159. package/dist/types/tree-select.d.ts +8 -2
  160. package/package.json +18 -18
  161. package/src/components/batch-edit/__test__/batch-edit.test.ts +1 -1
  162. package/src/components/button/__test__/button.test.ts +1 -1
  163. package/src/components/cascade/__test__/cascade.test.ts +26 -1
  164. package/src/components/cascade/use-select.ts +5 -5
  165. package/src/components/collapse/__test__/collapse.test.ts +1 -1
  166. package/src/components/condition-editor/__test__/condition-editor.test.ts +1 -1
  167. package/src/components/contextmenu/__test__/contextmenu.test.ts +1 -1
  168. package/src/components/date-picker/__test__/date-picker.test.ts +1 -1
  169. package/src/components/date-range-picker/__test__/date-range-picker.test.ts +1 -1
  170. package/src/components/drawer/__test__/drawer.test.ts +1 -1
  171. package/src/components/expression-editor/__test__/chip.test.ts +1 -1
  172. package/src/components/expression-editor/__test__/editor.test.ts +1 -1
  173. package/src/components/expression-editor/__test__/expression-editor.test.ts +1 -1
  174. package/src/components/expression-editor/__test__/mention.test.ts +1 -1
  175. package/src/components/expression-editor/__test__/model.test.ts +1 -1
  176. package/src/components/file-viewer/__test__/helper.test.ts +1 -1
  177. package/src/components/form/__test__/form.test.ts +1 -1
  178. package/src/components/form/__test__/is-field-modified.test.ts +1 -1
  179. package/src/components/form-item/__test__/form-item.test.ts +1 -1
  180. package/src/components/image-cropper/__test__/draw-crop.test.ts +1 -1
  181. package/src/components/image-cropper/__test__/image-cropper.test.ts +1 -1
  182. package/src/components/image-cropper/__test__/use-transform.test.ts +1 -1
  183. package/src/components/kanban/__test__/kanban.test.ts +1 -1
  184. package/src/components/message-confirm/__test__/message-confirm.test.ts +1 -1
  185. package/src/components/multi-tree-select/__test__/multi-tree-select.test.ts +1 -1
  186. package/src/components/number-input/__test__/number-input.test.ts +1 -1
  187. package/src/components/number-range-input/__test__/number-range-input.test.ts +1 -1
  188. package/src/components/palette/__test__/color-transform.test.ts +1 -1
  189. package/src/components/palette/__test__/palette.test.ts +1 -1
  190. package/src/components/password-input/__test__/password-input.test.ts +1 -1
  191. package/src/components/radio-group/__test__/radio-group.test.ts +1 -1
  192. package/src/components/rich-text-editor/__test__/image-node.test.ts +140 -0
  193. package/src/components/rich-text-editor/image-node.ts +84 -15
  194. package/src/components/rich-text-editor/rich-text-editor.vue +15 -4
  195. package/src/components/rich-text-editor/style.scss +35 -0
  196. package/src/components/rich-text-editor/use-image-resize.ts +168 -0
  197. package/src/components/segment/__test__/segment.test.ts +1 -1
  198. package/src/components/select/__test__/select.test.ts +68 -1
  199. package/src/components/select/select.vue +15 -5
  200. package/src/components/table/__test__/col-width.test.ts +1 -1
  201. package/src/components/table/__test__/column-style.test.ts +1 -1
  202. package/src/components/table-editor/__test__/table-editor.test.ts +1 -1
  203. package/src/components/tree-select/__test__/tree-select.test.ts +50 -1
  204. package/src/components/tree-select/tree-select.vue +28 -11
  205. package/src/types/cascade.ts +5 -0
  206. package/src/types/select.ts +8 -2
  207. package/src/types/tree-select.ts +9 -2
@@ -1 +1 @@
1
- {"version":3,"file":"table-head.js","names":[],"sources":["../../../src/components/table/table-head.tsx"],"sourcesContent":["import { bem, withUnit } from '@veltra/utils'\nimport { defineComponent, inject, type DefineComponent } from 'vue'\n\nimport { TableDIKey, TableResizeKey } from './di'\n\nconst TableHead: DefineComponent = defineComponent({\n name: 'TableHead',\n setup() {\n const { cls, columnConfig, getHeaderSlotsNode, getHeaderCellClass } = inject(TableDIKey)!\n const { headers } = columnConfig\n const handleCls = cls.e('resize-handle')\n\n const { handleResizeMousedown, headerRef } = inject(TableResizeKey)!\n\n return () => (\n <thead\n class={[cls.e('head'), bem.is('multistage', headers.value.length > 1)]}\n ref={headerRef}\n >\n {headers.value.map((header, headerIndex) => (\n <tr>\n {header.map((column) => (\n <th\n class={getHeaderCellClass(column)}\n key={column.key}\n colspan={column.leafs}\n rowspan={column.children?.length ? undefined : headers.value.length - headerIndex}\n style={{\n ...column.headerCellStyle,\n left: withUnit(column.style.left, 'px'),\n right: withUnit(column.style.right, 'px')\n }}\n >\n {getHeaderSlotsNode({ column })}\n\n {column.isLeaf && column.resizable ? (\n <span\n class={handleCls}\n onMousedown={(e) => handleResizeMousedown(e, column)}\n ></span>\n ) : null}\n </th>\n ))}\n </tr>\n ))}\n </thead>\n )\n }\n})\n\nexport default TableHead\n"],"mappings":";;;;AAKA,MAAM,YAA6B,gBAAgB;CACjD,MAAM;CACN,QAAQ;EACN,MAAM,EAAE,KAAK,cAAc,oBAAoB,uBAAuB,OAAO,UAAU;EACvF,MAAM,EAAE,YAAY;EACpB,MAAM,YAAY,IAAI,EAAE,eAAe;EAEvC,MAAM,EAAE,uBAAuB,cAAc,OAAO,cAAc;EAElE,aAAO,YAAA,SAAA;GAAA,SAEI,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,cAAc,QAAQ,MAAM,SAAS,CAAC,CAAC;GAAC,OACjE;EAAS,GAAA,CAEb,QAAQ,MAAM,KAAK,QAAQ,gBAAW,YAAA,MAAA,MAAA,CAElC,OAAO,KAAK,WAAM,YAAA,MAAA;GAAA,SAER,mBAAmB,MAAM;GAAC,OAC5B,OAAO;GAAG,WACN,OAAO;GAAK,WACZ,OAAO,UAAU,SAAS,KAAA,IAAY,QAAQ,MAAM,SAAS;GAAW,SAC1E;IACL,GAAG,OAAO;IACV,MAAM,SAAS,OAAO,MAAM,MAAM,IAAI;IACtC,OAAO,SAAS,OAAO,MAAM,OAAO,IAAI;GAC1C;EAAC,GAAA,CAEA,mBAAmB,EAAE,OAAO,CAAC,GAE7B,OAAO,UAAU,OAAO,YAAS,YAAA,QAAA;GAAA,SAEvB;GAAS,gBACF,MAAM,sBAAsB,GAAG,MAAM;EAAC,GAAA,IAAA,IAEpD,IAAI,CAAA,CAEX,CAAC,CAAA,CAEL,CAAC,CAAA;CAGR;AACF,CAAC"}
1
+ {"version":3,"file":"table-head.js","names":["_createVNode"],"sources":["../../../src/components/table/table-head.tsx"],"sourcesContent":["import { bem, withUnit } from '@veltra/utils'\nimport { defineComponent, inject, type DefineComponent } from 'vue'\n\nimport { TableDIKey, TableResizeKey } from './di'\n\nconst TableHead: DefineComponent = defineComponent({\n name: 'TableHead',\n setup() {\n const { cls, columnConfig, getHeaderSlotsNode, getHeaderCellClass } = inject(TableDIKey)!\n const { headers } = columnConfig\n const handleCls = cls.e('resize-handle')\n\n const { handleResizeMousedown, headerRef } = inject(TableResizeKey)!\n\n return () => (\n <thead\n class={[cls.e('head'), bem.is('multistage', headers.value.length > 1)]}\n ref={headerRef}\n >\n {headers.value.map((header, headerIndex) => (\n <tr>\n {header.map((column) => (\n <th\n class={getHeaderCellClass(column)}\n key={column.key}\n colspan={column.leafs}\n rowspan={column.children?.length ? undefined : headers.value.length - headerIndex}\n style={{\n ...column.headerCellStyle,\n left: withUnit(column.style.left, 'px'),\n right: withUnit(column.style.right, 'px')\n }}\n >\n {getHeaderSlotsNode({ column })}\n\n {column.isLeaf && column.resizable ? (\n <span\n class={handleCls}\n onMousedown={(e) => handleResizeMousedown(e, column)}\n ></span>\n ) : null}\n </th>\n ))}\n </tr>\n ))}\n </thead>\n )\n }\n})\n\nexport default TableHead\n"],"mappings":";;;;AAKA,MAAM,YAA6B,gBAAgB;CACjD,MAAM;CACN,QAAQ;EACN,MAAM,EAAE,KAAK,cAAc,oBAAoB,uBAAuB,OAAO,UAAU;EACvF,MAAM,EAAE,YAAY;EACpB,MAAM,YAAY,IAAI,EAAE,eAAe;EAEvC,MAAM,EAAE,uBAAuB,cAAc,OAAO,cAAc;EAElE,aAAOA,YAAA,SAAA;GAAA,SAEI,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,cAAc,QAAQ,MAAM,SAAS,CAAC,CAAC;GAAC,OACjE;EAAS,GAAA,CAEb,QAAQ,MAAM,KAAK,QAAQ,gBAAWA,YAAA,MAAA,MAAA,CAElC,OAAO,KAAK,WAAMA,YAAA,MAAA;GAAA,SAER,mBAAmB,MAAM;GAAC,OAC5B,OAAO;GAAG,WACN,OAAO;GAAK,WACZ,OAAO,UAAU,SAAS,KAAA,IAAY,QAAQ,MAAM,SAAS;GAAW,SAC1E;IACL,GAAG,OAAO;IACV,MAAM,SAAS,OAAO,MAAM,MAAM,IAAI;IACtC,OAAO,SAAS,OAAO,MAAM,OAAO,IAAI;GAC1C;EAAC,GAAA,CAEA,mBAAmB,EAAE,OAAO,CAAC,GAE7B,OAAO,UAAU,OAAO,YAASA,YAAA,QAAA;GAAA,SAEvB;GAAS,gBACF,MAAM,sBAAsB,GAAG,MAAM;EAAC,GAAA,IAAA,IAEpD,IAAI,CAAA,CAEX,CAAC,CAAA,CAEL,CAAC,CAAA;CAGR;AACF,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"table-row.js","names":[],"sources":["../../../src/components/table/table-row.tsx"],"sourcesContent":["import { ArrowRight } from '@veltra/icons/normal'\nimport { defineComponent, type DefineComponent } from 'vue'\nimport { inject, onUnmounted } from 'vue'\nimport type { JSX } from 'vue/jsx-runtime'\n\nimport type { TableRow as ITableRow } from '../../types'\nimport { UButton } from '../button'\nimport { UIcon } from '../icon'\nimport { TableDIKey } from './di'\nimport UTabelCell from './table-cell.vue'\n\n/**\n * A3:行修饰类组合静态查找表。\n *\n * 位模式:bit2 = isCurrent, bit1 = checked, bit0 = expanded。\n * 与 `bem.is('...')` 对于 `'current' | 'checked' | 'expanded'` 的输出完全等价,\n * 直接从 index 读字符串,消除每行渲染期间的字符串拼接和 3 次 bem.is 调用。\n *\n * 放在模块顶层使所有 TableRow 实例共享一份引用(不会随 setup 重建)。\n */\nconst ROW_MOD_CLASS: readonly string[] = [\n '',\n 'is-expanded',\n 'is-checked',\n 'is-checked is-expanded',\n 'is-current',\n 'is-current is-expanded',\n 'is-current is-checked',\n 'is-current is-checked is-expanded'\n] as const\n\nfunction rowModCls(row: ITableRow): string {\n const i = (row.isCurrent ? 4 : 0) | (row.checked ? 2 : 0) | (row.expanded ? 1 : 0)\n return ROW_MOD_CLASS[i]!\n}\n\nexport const UTableRow: DefineComponent<{ row: ITableRow; index: number }> = defineComponent({\n name: 'TableRow',\n\n props: {\n row: { type: Object as () => ITableRow, required: true },\n index: { type: Number, required: true }\n },\n\n setup(props) {\n const {\n cls,\n columnConfig,\n getColumnSlotsNode,\n toggleTreeRowExpand,\n getCellCtx,\n handleRowClick,\n handleCellClick,\n tableProps,\n measureElement,\n getCellClass\n } = inject(TableDIKey)!\n\n // A1:把 cls.e('row') / cls.e('expand-toggle') 等静态字符串提升到 setup 一次性计算,\n // 避免每次 render 重新走 `cls.e` 拼接。\n const rowBaseCls = cls.e('row')\n const expandToggleCls = cls.e('expand-toggle')\n const expandSpaceCls = cls.e('expand-space')\n\n // A2:measureRef 按 index 缓存闭包。\n // 行虚拟化下,同一 TableRow 实例的 props.index 大多稳定,但在虚拟化重排或展开行切换时\n // 仍会发生变化;把 (index) → refFn 缓存起来,既保证引用稳定(利于 Vue 的 ref diff),\n // 又避免在未来可能的\"同实例跨 index 复用\"情形下重复分配闭包。\n const measureRefCache = new Map<number, (el: unknown) => void>()\n const getMeasureRef = (index: number): ((el: unknown) => void) => {\n let ref = measureRefCache.get(index)\n if (ref === undefined) {\n ref = (el: unknown) => {\n measureElement(index, el as Element | null)\n }\n measureRefCache.set(index, ref)\n }\n return ref\n }\n onUnmounted(() => {\n measureRefCache.clear()\n })\n\n const { columns, expandColumn } = columnConfig\n\n return () => {\n const { row } = props\n const _expandColumn = expandColumn.value\n\n let expandCell: JSX.Element | null = null\n if (_expandColumn) {\n const expandCtx = getCellCtx(row, _expandColumn)\n const cellSpan = tableProps.mergeCell?.(expandCtx)\n\n if (!cellSpan || (cellSpan.colspan && cellSpan.rowspan)) {\n const marginLeft = tableProps.tree ? row.depth * 14 : 0\n expandCell = (\n <UTabelCell\n cellClass={getCellClass(_expandColumn)}\n left={_expandColumn.style.left}\n right={_expandColumn.style.right}\n cellStyle={_expandColumn.cellStyle}\n key={row.uid + _expandColumn.key}\n {...tableProps.mergeCell?.(expandCtx)}\n >\n {!row.isLeaf || (tableProps.expandable && !row.isExpandRow) ? (\n <UButton\n text\n class={expandToggleCls}\n type='primary'\n size='small'\n circle\n onClick={(e) => {\n e.stopPropagation()\n toggleTreeRowExpand(row)\n }}\n style={`margin-left: ${marginLeft}px`}\n >\n <UIcon>\n <ArrowRight />\n </UIcon>\n </UButton>\n ) : (\n <i class={expandSpaceCls} style={`margin-left: ${marginLeft}px`}></i>\n )}\n\n {getColumnSlotsNode(expandCtx)}\n </UTabelCell>\n )\n }\n }\n\n // A3:行 class 由 base + 3-bit 组合查找产出,避免 Vue 的 class 数组归一化开销。\n const mod = rowModCls(row)\n const rowCls = mod ? rowBaseCls + ' ' + mod : rowBaseCls\n\n return (\n <tr\n class={rowCls}\n onClick={(e) => handleRowClick(row, e)}\n ref={getMeasureRef(props.index)}\n key={row.uid}\n >\n {expandCell}\n\n {columns.value.map((column) => {\n const cellCtx = getCellCtx(row, column)\n const cellSpan = tableProps.mergeCell?.(cellCtx)\n if (cellSpan && (!cellSpan.colspan || !cellSpan.rowspan)) {\n return null\n }\n\n const cellNode = getColumnSlotsNode(cellCtx)\n\n return (\n <UTabelCell\n cellClass={getCellClass(column)}\n left={column.style.left}\n right={column.style.right}\n cellStyle={column.cellStyle}\n key={row.uid + column.key}\n // @ts-ignore\n onClick={(e) => handleCellClick(row, column, e)}\n {...cellSpan}\n >\n {cellNode}\n </UTabelCell>\n )\n })}\n </tr>\n )\n }\n }\n})\n\nexport const UExpandTableRow = defineComponent({\n name: 'ExpandTableRow',\n props: {\n row: { type: Object as () => ITableRow, required: true },\n index: { type: Number, required: true }\n },\n setup(props) {\n const { getExpandRowSlotsNode, cls, measureElement, columnConfig } = inject(TableDIKey)!\n const { leafColumns } = columnConfig\n\n const rowBaseCls = cls.e('row')\n const cellCls = cls.e('cell')\n\n const measureRef = (el: unknown) => {\n measureElement(props.index, el as Element | null)\n }\n\n return () => {\n const { row } = props\n const node = getExpandRowSlotsNode({\n row,\n index: row.index,\n columns: leafColumns.value,\n rowData: row.data\n })\n return (\n <tr class={rowBaseCls} ref={measureRef}>\n <td colspan={leafColumns.value.length} class={cellCls}>\n {node}\n </td>\n </tr>\n )\n }\n }\n})\n"],"mappings":"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"}
1
+ {"version":3,"file":"table-row.js","names":["_isVNode","_createVNode","UTabelCell","_mergeProps","UButton","UIcon"],"sources":["../../../src/components/table/table-row.tsx"],"sourcesContent":["import { ArrowRight } from '@veltra/icons/normal'\nimport { defineComponent, type DefineComponent } from 'vue'\nimport { inject, onUnmounted } from 'vue'\nimport type { JSX } from 'vue/jsx-runtime'\n\nimport type { TableRow as ITableRow } from '../../types'\nimport { UButton } from '../button'\nimport { UIcon } from '../icon'\nimport { TableDIKey } from './di'\nimport UTabelCell from './table-cell.vue'\n\n/**\n * A3:行修饰类组合静态查找表。\n *\n * 位模式:bit2 = isCurrent, bit1 = checked, bit0 = expanded。\n * 与 `bem.is('...')` 对于 `'current' | 'checked' | 'expanded'` 的输出完全等价,\n * 直接从 index 读字符串,消除每行渲染期间的字符串拼接和 3 次 bem.is 调用。\n *\n * 放在模块顶层使所有 TableRow 实例共享一份引用(不会随 setup 重建)。\n */\nconst ROW_MOD_CLASS: readonly string[] = [\n '',\n 'is-expanded',\n 'is-checked',\n 'is-checked is-expanded',\n 'is-current',\n 'is-current is-expanded',\n 'is-current is-checked',\n 'is-current is-checked is-expanded'\n] as const\n\nfunction rowModCls(row: ITableRow): string {\n const i = (row.isCurrent ? 4 : 0) | (row.checked ? 2 : 0) | (row.expanded ? 1 : 0)\n return ROW_MOD_CLASS[i]!\n}\n\nexport const UTableRow: DefineComponent<{ row: ITableRow; index: number }> = defineComponent({\n name: 'TableRow',\n\n props: {\n row: { type: Object as () => ITableRow, required: true },\n index: { type: Number, required: true }\n },\n\n setup(props) {\n const {\n cls,\n columnConfig,\n getColumnSlotsNode,\n toggleTreeRowExpand,\n getCellCtx,\n handleRowClick,\n handleCellClick,\n tableProps,\n measureElement,\n getCellClass\n } = inject(TableDIKey)!\n\n // A1:把 cls.e('row') / cls.e('expand-toggle') 等静态字符串提升到 setup 一次性计算,\n // 避免每次 render 重新走 `cls.e` 拼接。\n const rowBaseCls = cls.e('row')\n const expandToggleCls = cls.e('expand-toggle')\n const expandSpaceCls = cls.e('expand-space')\n\n // A2:measureRef 按 index 缓存闭包。\n // 行虚拟化下,同一 TableRow 实例的 props.index 大多稳定,但在虚拟化重排或展开行切换时\n // 仍会发生变化;把 (index) → refFn 缓存起来,既保证引用稳定(利于 Vue 的 ref diff),\n // 又避免在未来可能的\"同实例跨 index 复用\"情形下重复分配闭包。\n const measureRefCache = new Map<number, (el: unknown) => void>()\n const getMeasureRef = (index: number): ((el: unknown) => void) => {\n let ref = measureRefCache.get(index)\n if (ref === undefined) {\n ref = (el: unknown) => {\n measureElement(index, el as Element | null)\n }\n measureRefCache.set(index, ref)\n }\n return ref\n }\n onUnmounted(() => {\n measureRefCache.clear()\n })\n\n const { columns, expandColumn } = columnConfig\n\n return () => {\n const { row } = props\n const _expandColumn = expandColumn.value\n\n let expandCell: JSX.Element | null = null\n if (_expandColumn) {\n const expandCtx = getCellCtx(row, _expandColumn)\n const cellSpan = tableProps.mergeCell?.(expandCtx)\n\n if (!cellSpan || (cellSpan.colspan && cellSpan.rowspan)) {\n const marginLeft = tableProps.tree ? row.depth * 14 : 0\n expandCell = (\n <UTabelCell\n cellClass={getCellClass(_expandColumn)}\n left={_expandColumn.style.left}\n right={_expandColumn.style.right}\n cellStyle={_expandColumn.cellStyle}\n key={row.uid + _expandColumn.key}\n {...tableProps.mergeCell?.(expandCtx)}\n >\n {!row.isLeaf || (tableProps.expandable && !row.isExpandRow) ? (\n <UButton\n text\n class={expandToggleCls}\n type='primary'\n size='small'\n circle\n onClick={(e) => {\n e.stopPropagation()\n toggleTreeRowExpand(row)\n }}\n style={`margin-left: ${marginLeft}px`}\n >\n <UIcon>\n <ArrowRight />\n </UIcon>\n </UButton>\n ) : (\n <i class={expandSpaceCls} style={`margin-left: ${marginLeft}px`}></i>\n )}\n\n {getColumnSlotsNode(expandCtx)}\n </UTabelCell>\n )\n }\n }\n\n // A3:行 class 由 base + 3-bit 组合查找产出,避免 Vue 的 class 数组归一化开销。\n const mod = rowModCls(row)\n const rowCls = mod ? rowBaseCls + ' ' + mod : rowBaseCls\n\n return (\n <tr\n class={rowCls}\n onClick={(e) => handleRowClick(row, e)}\n ref={getMeasureRef(props.index)}\n key={row.uid}\n >\n {expandCell}\n\n {columns.value.map((column) => {\n const cellCtx = getCellCtx(row, column)\n const cellSpan = tableProps.mergeCell?.(cellCtx)\n if (cellSpan && (!cellSpan.colspan || !cellSpan.rowspan)) {\n return null\n }\n\n const cellNode = getColumnSlotsNode(cellCtx)\n\n return (\n <UTabelCell\n cellClass={getCellClass(column)}\n left={column.style.left}\n right={column.style.right}\n cellStyle={column.cellStyle}\n key={row.uid + column.key}\n // @ts-ignore\n onClick={(e) => handleCellClick(row, column, e)}\n {...cellSpan}\n >\n {cellNode}\n </UTabelCell>\n )\n })}\n </tr>\n )\n }\n }\n})\n\nexport const UExpandTableRow = defineComponent({\n name: 'ExpandTableRow',\n props: {\n row: { type: Object as () => ITableRow, required: true },\n index: { type: Number, required: true }\n },\n setup(props) {\n const { getExpandRowSlotsNode, cls, measureElement, columnConfig } = inject(TableDIKey)!\n const { leafColumns } = columnConfig\n\n const rowBaseCls = cls.e('row')\n const cellCls = cls.e('cell')\n\n const measureRef = (el: unknown) => {\n measureElement(props.index, el as Element | null)\n }\n\n return () => {\n const { row } = props\n const node = getExpandRowSlotsNode({\n row,\n index: row.index,\n columns: leafColumns.value,\n rowData: row.data\n })\n return (\n <tr class={rowBaseCls} ref={measureRef}>\n <td colspan={leafColumns.value.length} class={cellCls}>\n {node}\n </td>\n </tr>\n )\n }\n }\n})\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"table.js","names":[],"sources":["../../../src/components/table/table.vue"],"sourcesContent":["<template>\n <u-scroll\n :class=\"[\n cls.b,\n cls.m(size),\n bem.is('border', border),\n bem.is('all-expanded', allExpanded),\n bem.is('text-ellipsis', textEllipsis)\n ]\"\n ref=\"scrollRef\"\n :content-class=\"cls.e('content')\"\n @scroll=\"handleScroll\"\n >\n <table :class=\"cls.e('wrap')\">\n <colgroup ref=\"colgroupRef\">\n <col\n v-for=\"column of leafColumns\"\n :key=\"column.key\"\n :class=\"column.fixed\"\n :style=\"{\n width: withUnit(column.width, 'px'),\n minWidth: withUnit(column.minWidth, 'px')\n }\"\n />\n </colgroup>\n <UTableHead />\n\n <!--\n 虚拟滚动上占位:替代 tbody transform,避免 table-layout: fixed 下列宽抖动。\n 高度由 useVirtualizer 命令式写入 `style.height`,不经过模板响应式绑定,\n 因此滚动窗口变化不会引起表格模板重渲染。\n -->\n <tbody v-if=\"virtualEnabled\" aria-hidden=\"true\">\n <tr ref=\"beforeSpacerRef\">\n <td :colspan=\"leafColumns.length\" style=\"padding: 0; border: none\"></td>\n </tr>\n </tbody>\n\n <u-table-body>\n <slot name=\"body\" :columns=\"leafColumns\" :rows=\"rows\" />\n\n <template #empty v-if=\"slots.empty\">\n <slot name=\"empty\" />\n </template>\n </u-table-body>\n\n <!-- 虚拟滚动下占位(高度由 useVirtualizer 命令式写入) -->\n <tbody v-if=\"virtualEnabled\" aria-hidden=\"true\">\n <tr ref=\"afterSpacerRef\">\n <td :colspan=\"leafColumns.length\" style=\"padding: 0; border: none\"></td>\n </tr>\n </tbody>\n\n <u-table-foot ref=\"tableFoot\">\n <slot name=\"foot\" :columns=\"leafColumns\" :rows=\"rows\" />\n </u-table-foot>\n </table>\n\n <slot name=\"append\" />\n\n <div v-if=\"showResizeLine\" :class=\"cls.e('resize-line')\" ref=\"resizeLineRef\"></div>\n\n <!-- <u-tip v-if=\"textEllipsis\" ref=\"tip\"> </u-tip> -->\n </u-scroll>\n</template>\n\n<script lang=\"ts\" setup>\nimport { useFallbackProps, useVirtualizer } from '@veltra/compositions'\nimport { bem, withUnit } from '@veltra/utils'\nimport { computed, provide, shallowRef, toRef, useTemplateRef, watch } from 'vue'\n\nimport type {\n TableProps,\n TableEmits,\n _TableExposed,\n TableColumnSlotsScope,\n ComponentSize,\n ScrollExposed,\n TableRowSlotsScope\n} from '../../types'\nimport { UScroll } from '../scroll'\nimport { TableDIKey } from './di'\nimport type { ColumnNode } from './node/col'\nimport type { TableRowNode } from './node/row'\nimport UTableBody from './table-body.vue'\nimport UTableFoot from './table-foot.vue'\n// import { UTip } from '../tip'\nimport UTableHead from './table-head'\nimport { useCheck } from './use-check'\nimport { useColResize } from './use-col-resize'\nimport { useColumns } from './use-columns'\nimport { useFixedColumns } from './use-fixed-columns'\nimport { useRows } from './use-rows'\nimport { useTable } from './use-table'\n\ndefineOptions({ name: 'UTable' })\n\nconst props = withDefaults(defineProps<TableProps>(), {\n tree: false,\n stripe: true,\n textOverflow: 'line-break',\n virtualThreshold: 80\n})\nconst emit = defineEmits<TableEmits>()\n\nconst slots = defineSlots<{\n [key: `column:${string}`]: (props: TableColumnSlotsScope) => any\n [key: `header:${string}`]: (props: { column: ColumnNode }) => any\n 'row:expand'?: (props: TableRowSlotsScope) => any\n foot?: (props: { columns: ColumnNode[]; rows: TableRowNode[] }) => any\n body?: (props: { columns: ColumnNode[]; rows: TableRowNode[] }) => any\n empty?: () => any\n append?: () => any\n}>()\n\nconst cls = bem('table')\n\nconst { size } = useFallbackProps([props], { size: 'default' as ComponentSize })\n\nconst scrollRef = shallowRef<ScrollExposed>()\n\n// 占位 tr 的 DOM 句柄;交给 useVirtualizer 直接命令式写 style.height。\nconst beforeSpacerRef = useTemplateRef<HTMLElement>('beforeSpacerRef')\nconst afterSpacerRef = useTemplateRef<HTMLElement>('afterSpacerRef')\n\n// 行(useRows / useFixedColumns 需要 isScrolling,而虚拟化 hook 又依赖 rows.length;\n// 先用中继占位,下方 isScrolling 到位后 watch 回灌)。\nconst isScrollingRelay = shallowRef(false)\n\nconst {\n rows,\n toggleTreeRowExpand,\n allExpanded,\n toggleAllTreeRowExpand,\n rowForest,\n handleRowClick,\n handleCellClick,\n getRowByData\n} = useRows({ props, emit, isScrolling: isScrollingRelay })\n\nconst { createCheckColumn, createSelectColumn, clearChecked, clearSelected, checkedRows } =\n useCheck({ size, props, rows, rowForest, emit, cls })\n\nconst columnConfig = useColumns({\n props,\n createCheckColumn,\n createSelectColumn,\n toggleAllTreeRowExpand,\n cls\n})\n\nconst { leafColumns } = columnConfig\n\nconst { handleScroll, leftFixed, rightFixed } = useFixedColumns()\n\nconst {\n getColumnSlotsNode,\n getExpandRowSlotsNode,\n getHeaderSlotsNode,\n getCellClass,\n getCellCtx,\n getHeaderCellClass\n} = useTable({ props, cls, leftFixed, rightFixed })\n\nconst { showResizeLine, resizeLineRef, colgroupRef } = useColResize({ scrollRef, leafColumns })\n\nconst { virtualizer, items, isScrolling } = useVirtualizer({\n count: computed(() => rows.value.length),\n scrollEl: () => scrollRef.value?.containerRef ?? null,\n beforeEl: beforeSpacerRef,\n afterEl: afterSpacerRef,\n estimateSize: () => 41,\n // 注意:getItemKey 在构造期一次性写入底层 Virtualizer;闭包每次读的是当前 rows.value,\n // rows 引用整体替换后 key 仍有效(无需再 setOptions)。\n getItemKey: (i) => rows.value[i]?.uid ?? i\n})\n\nconst virtualEnabled = computed(() => {\n const t = props.virtualThreshold\n return t ? rows.value.length > t : true\n})\n\n// 把虚拟化 isScrolling 回灌到中继,供 useRows / useFixedColumns 读取。\nwatch(isScrolling, (v) => {\n isScrollingRelay.value = v\n})\n\n/**\n * E1:数据替换时的条件置顶。\n *\n * 旧实现无差别地 `scrollTo({ y: 0 })`,在「行内增删 / 排序 / 单行更新」等\n * 场景会把用户当前阅读位置跳走;仅在「翻页 / 显著数据集替换」时才需要复位。\n *\n * 判定阈值:|Δlen| / max(newLen, oldLen) ≥ 0.5,即行数变化量超过更大侧的一半时视为显著变化。\n * 选择 0.5 是因为典型的分页/搜索场景会带来 50% 以上的行数差(通常完全替换数据集),\n * 而行内追加 / 删除个位数通常只带来 <5% 的变化;两者区分度足够宽。\n */\nconst LENGTH_DELTA_RATIO_TO_RESET_SCROLL = 0.5\n\nwatch(\n () => props.data,\n (next, prev) => {\n const nextLen = next?.length ?? 0\n const prevLen = prev?.length ?? 0\n const denom = Math.max(nextLen, prevLen, 1)\n const ratio = Math.abs(nextLen - prevLen) / denom\n if (ratio >= LENGTH_DELTA_RATIO_TO_RESET_SCROLL) {\n scrollRef.value?.scrollTo({ y: 0 })\n }\n }\n)\n\n// const tipRef = useTemplateRef('tip')\n\nprovide(TableDIKey, {\n tableProps: props,\n tableSlots: slots,\n cls,\n rows,\n checkedRows,\n columnConfig,\n handleRowClick,\n handleCellClick,\n getColumnSlotsNode,\n getExpandRowSlotsNode,\n getHeaderSlotsNode,\n getCellClass,\n getCellCtx,\n getHeaderCellClass,\n // tipRef,\n toggleTreeRowExpand,\n virtualList: items,\n virtualEnabled,\n measureElement: (index, el) => virtualizer.measureElement(index, el)\n})\n\nconst tableFootRef = useTemplateRef('tableFoot')\n\ndefineExpose<_TableExposed>({\n el: toRef(() => scrollRef.value?.el),\n clearChecked,\n clearSelected,\n getRowByData,\n getSummaryRow: () => tableFootRef.value!.getSummaryRow()\n})\n</script>\n"],"mappings":"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"}
1
+ {"version":3,"file":"table.js","names":["_useSlots","_openBlock","_createBlock","_unref","UScroll","_normalizeClass","_withCtx","_createElementVNode","_createElementBlock","_Fragment","_renderList","_normalizeStyle","_createVNode","UTableHead","_createCommentVNode","UTableBody","_createSlots","_renderSlot","UTableFoot"],"sources":["../../../src/components/table/table.vue"],"sourcesContent":["<template>\n <u-scroll\n :class=\"[\n cls.b,\n cls.m(size),\n bem.is('border', border),\n bem.is('all-expanded', allExpanded),\n bem.is('text-ellipsis', textEllipsis)\n ]\"\n ref=\"scrollRef\"\n :content-class=\"cls.e('content')\"\n @scroll=\"handleScroll\"\n >\n <table :class=\"cls.e('wrap')\">\n <colgroup ref=\"colgroupRef\">\n <col\n v-for=\"column of leafColumns\"\n :key=\"column.key\"\n :class=\"column.fixed\"\n :style=\"{\n width: withUnit(column.width, 'px'),\n minWidth: withUnit(column.minWidth, 'px')\n }\"\n />\n </colgroup>\n <UTableHead />\n\n <!--\n 虚拟滚动上占位:替代 tbody transform,避免 table-layout: fixed 下列宽抖动。\n 高度由 useVirtualizer 命令式写入 `style.height`,不经过模板响应式绑定,\n 因此滚动窗口变化不会引起表格模板重渲染。\n -->\n <tbody v-if=\"virtualEnabled\" aria-hidden=\"true\">\n <tr ref=\"beforeSpacerRef\">\n <td :colspan=\"leafColumns.length\" style=\"padding: 0; border: none\"></td>\n </tr>\n </tbody>\n\n <u-table-body>\n <slot name=\"body\" :columns=\"leafColumns\" :rows=\"rows\" />\n\n <template #empty v-if=\"slots.empty\">\n <slot name=\"empty\" />\n </template>\n </u-table-body>\n\n <!-- 虚拟滚动下占位(高度由 useVirtualizer 命令式写入) -->\n <tbody v-if=\"virtualEnabled\" aria-hidden=\"true\">\n <tr ref=\"afterSpacerRef\">\n <td :colspan=\"leafColumns.length\" style=\"padding: 0; border: none\"></td>\n </tr>\n </tbody>\n\n <u-table-foot ref=\"tableFoot\">\n <slot name=\"foot\" :columns=\"leafColumns\" :rows=\"rows\" />\n </u-table-foot>\n </table>\n\n <slot name=\"append\" />\n\n <div v-if=\"showResizeLine\" :class=\"cls.e('resize-line')\" ref=\"resizeLineRef\"></div>\n\n <!-- <u-tip v-if=\"textEllipsis\" ref=\"tip\"> </u-tip> -->\n </u-scroll>\n</template>\n\n<script lang=\"ts\" setup>\nimport { useFallbackProps, useVirtualizer } from '@veltra/compositions'\nimport { bem, withUnit } from '@veltra/utils'\nimport { computed, provide, shallowRef, toRef, useTemplateRef, watch } from 'vue'\n\nimport type {\n TableProps,\n TableEmits,\n _TableExposed,\n TableColumnSlotsScope,\n ComponentSize,\n ScrollExposed,\n TableRowSlotsScope\n} from '../../types'\nimport { UScroll } from '../scroll'\nimport { TableDIKey } from './di'\nimport type { ColumnNode } from './node/col'\nimport type { TableRowNode } from './node/row'\nimport UTableBody from './table-body.vue'\nimport UTableFoot from './table-foot.vue'\n// import { UTip } from '../tip'\nimport UTableHead from './table-head'\nimport { useCheck } from './use-check'\nimport { useColResize } from './use-col-resize'\nimport { useColumns } from './use-columns'\nimport { useFixedColumns } from './use-fixed-columns'\nimport { useRows } from './use-rows'\nimport { useTable } from './use-table'\n\ndefineOptions({ name: 'UTable' })\n\nconst props = withDefaults(defineProps<TableProps>(), {\n tree: false,\n stripe: true,\n textOverflow: 'line-break',\n virtualThreshold: 80\n})\nconst emit = defineEmits<TableEmits>()\n\nconst slots = defineSlots<{\n [key: `column:${string}`]: (props: TableColumnSlotsScope) => any\n [key: `header:${string}`]: (props: { column: ColumnNode }) => any\n 'row:expand'?: (props: TableRowSlotsScope) => any\n foot?: (props: { columns: ColumnNode[]; rows: TableRowNode[] }) => any\n body?: (props: { columns: ColumnNode[]; rows: TableRowNode[] }) => any\n empty?: () => any\n append?: () => any\n}>()\n\nconst cls = bem('table')\n\nconst { size } = useFallbackProps([props], { size: 'default' as ComponentSize })\n\nconst scrollRef = shallowRef<ScrollExposed>()\n\n// 占位 tr 的 DOM 句柄;交给 useVirtualizer 直接命令式写 style.height。\nconst beforeSpacerRef = useTemplateRef<HTMLElement>('beforeSpacerRef')\nconst afterSpacerRef = useTemplateRef<HTMLElement>('afterSpacerRef')\n\n// 行(useRows / useFixedColumns 需要 isScrolling,而虚拟化 hook 又依赖 rows.length;\n// 先用中继占位,下方 isScrolling 到位后 watch 回灌)。\nconst isScrollingRelay = shallowRef(false)\n\nconst {\n rows,\n toggleTreeRowExpand,\n allExpanded,\n toggleAllTreeRowExpand,\n rowForest,\n handleRowClick,\n handleCellClick,\n getRowByData\n} = useRows({ props, emit, isScrolling: isScrollingRelay })\n\nconst { createCheckColumn, createSelectColumn, clearChecked, clearSelected, checkedRows } =\n useCheck({ size, props, rows, rowForest, emit, cls })\n\nconst columnConfig = useColumns({\n props,\n createCheckColumn,\n createSelectColumn,\n toggleAllTreeRowExpand,\n cls\n})\n\nconst { leafColumns } = columnConfig\n\nconst { handleScroll, leftFixed, rightFixed } = useFixedColumns()\n\nconst {\n getColumnSlotsNode,\n getExpandRowSlotsNode,\n getHeaderSlotsNode,\n getCellClass,\n getCellCtx,\n getHeaderCellClass\n} = useTable({ props, cls, leftFixed, rightFixed })\n\nconst { showResizeLine, resizeLineRef, colgroupRef } = useColResize({ scrollRef, leafColumns })\n\nconst { virtualizer, items, isScrolling } = useVirtualizer({\n count: computed(() => rows.value.length),\n scrollEl: () => scrollRef.value?.containerRef ?? null,\n beforeEl: beforeSpacerRef,\n afterEl: afterSpacerRef,\n estimateSize: () => 41,\n // 注意:getItemKey 在构造期一次性写入底层 Virtualizer;闭包每次读的是当前 rows.value,\n // rows 引用整体替换后 key 仍有效(无需再 setOptions)。\n getItemKey: (i) => rows.value[i]?.uid ?? i\n})\n\nconst virtualEnabled = computed(() => {\n const t = props.virtualThreshold\n return t ? rows.value.length > t : true\n})\n\n// 把虚拟化 isScrolling 回灌到中继,供 useRows / useFixedColumns 读取。\nwatch(isScrolling, (v) => {\n isScrollingRelay.value = v\n})\n\n/**\n * E1:数据替换时的条件置顶。\n *\n * 旧实现无差别地 `scrollTo({ y: 0 })`,在「行内增删 / 排序 / 单行更新」等\n * 场景会把用户当前阅读位置跳走;仅在「翻页 / 显著数据集替换」时才需要复位。\n *\n * 判定阈值:|Δlen| / max(newLen, oldLen) ≥ 0.5,即行数变化量超过更大侧的一半时视为显著变化。\n * 选择 0.5 是因为典型的分页/搜索场景会带来 50% 以上的行数差(通常完全替换数据集),\n * 而行内追加 / 删除个位数通常只带来 <5% 的变化;两者区分度足够宽。\n */\nconst LENGTH_DELTA_RATIO_TO_RESET_SCROLL = 0.5\n\nwatch(\n () => props.data,\n (next, prev) => {\n const nextLen = next?.length ?? 0\n const prevLen = prev?.length ?? 0\n const denom = Math.max(nextLen, prevLen, 1)\n const ratio = Math.abs(nextLen - prevLen) / denom\n if (ratio >= LENGTH_DELTA_RATIO_TO_RESET_SCROLL) {\n scrollRef.value?.scrollTo({ y: 0 })\n }\n }\n)\n\n// const tipRef = useTemplateRef('tip')\n\nprovide(TableDIKey, {\n tableProps: props,\n tableSlots: slots,\n cls,\n rows,\n checkedRows,\n columnConfig,\n handleRowClick,\n handleCellClick,\n getColumnSlotsNode,\n getExpandRowSlotsNode,\n getHeaderSlotsNode,\n getCellClass,\n getCellCtx,\n getHeaderCellClass,\n // tipRef,\n toggleTreeRowExpand,\n virtualList: items,\n virtualEnabled,\n measureElement: (index, el) => virtualizer.measureElement(index, el)\n})\n\nconst tableFootRef = useTemplateRef('tableFoot')\n\ndefineExpose<_TableExposed>({\n el: toRef(() => scrollRef.value?.el),\n clearChecked,\n clearSelected,\n getRowByData,\n getSummaryRow: () => tableFootRef.value!.getSummaryRow()\n})\n</script>\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"table-editor.js","names":[],"sources":["../../../src/components/table-editor/table-editor.vue"],"sourcesContent":["<template>\n <u-table\n v-bind=\"tableProps\"\n :columns=\"internalColumns\"\n :data=\"modelValue\"\n :class=\"cls.b\"\n :stripe=\"false\"\n show-index\n >\n <!-- 其余插槽(header:* / row:expand / foot / append 等)透传给 u-table;column:* 与 empty 由组件接管 -->\n <template v-for=\"name in passSlotNames\" :key=\"name\" #[name]=\"scope\">\n <slot :name=\"name\" v-bind=\"scope\" />\n </template>\n\n <template #column:__operation=\"{ row }\">\n <div :class=\"cls.e('operations')\">\n <u-button\n text\n size=\"small\"\n type=\"danger\"\n :icon=\"Minus\"\n title=\"移除\"\n @click=\"handleDelete(row.index)\"\n />\n <u-button\n text\n size=\"small\"\n :icon=\"Plus\"\n title=\"新增到下一行\"\n @click=\"handleCreate(row.index)\"\n />\n <u-button text size=\"small\" :icon=\"Copy\" title=\"复制到下一行\" @click=\"handleCopy(row)\" />\n </div>\n </template>\n\n <template #empty>\n <div style=\"text-align: center; padding: 4px 0\">\n <u-button\n v-if=\"!props.readonly\"\n text\n size=\"small\"\n type=\"primary\"\n :icon=\"Plus\"\n @click=\"handleCreate()\"\n >\n 添加\n </u-button>\n </div>\n </template>\n </u-table>\n</template>\n\n<script lang=\"ts\" setup>\nimport { o } from '@cat-kit/core'\nimport { Copy, Minus, Plus, Warning } from '@veltra/icons/normal'\nimport { bem } from '@veltra/utils'\nimport { computed, h, shallowRef, toRaw, triggerRef, useSlots, watch } from 'vue'\n\nimport type {\n TableEditorProps,\n TableEditorEmits,\n TableEditorColumn,\n _TableEditorExposed,\n TableColumn,\n TableColumnNode,\n TableColumnRenderContext,\n TableColumnSlotsScope,\n RenderReturn\n} from '../../types'\nimport { UButton } from '../button'\nimport { validateField } from '../form-item/validate'\nimport { UIcon } from '../icon'\nimport { UTable } from '../table'\nimport type { TableRowNode } from '../table/node/row'\nimport { UTip } from '../tip'\n\ndefineOptions({ name: 'UTableEditor' })\n\ndefineSlots<{\n [key: `column:${string}`]: (props: TableColumnSlotsScope) => any\n [key: `header:${string}`]: (props: { column: TableColumnNode }) => any\n}>()\n\nconst props = defineProps<TableEditorProps>()\nconst emit = defineEmits<TableEditorEmits>()\n\nconst columns = computed(() => props.columns ?? [])\nconst modelValue = computed(() => props.modelValue ?? [])\n\n/** 转发给 u-table 的表格属性;columns / modelValue / readonly 为编辑器自用,stripe / showIndex 被覆盖 */\nconst tableProps = computed(() => {\n const rest: Record<string, any> = { ...props }\n delete rest.columns\n delete rest.modelValue\n delete rest.readonly\n return rest\n})\n\nconst cls = bem('table-editor')\n\nconst slots = useSlots()\n\nconst actionColumn: TableColumn = {\n key: '__operation',\n name: '操作',\n width: 104,\n align: 'center',\n fixed: 'right',\n resizable: false\n}\n\n/**\n * 内部列定义:单元格渲染挂在列的 render 上(用户列自带的 render 优先),\n * 配置了 rules 的列包装 nameRender 追加校验标识,非只读时末尾追加操作列。\n * 列 key 带上只读态后缀:u-table 行内单元格在 props 值相等时可能跳过子组件补丁,\n * 只读切换改用挂载键直接重挂单元格,确保控件在编辑/只读形态间可靠切换。\n */\nconst internalColumns = computed<TableColumn[]>(() => {\n const list = columns.value.map((column) => ({\n ...column,\n key: `${column.key}${props.readonly ? ':ro' : ''}`,\n nameRender: column.rules ? headerCell(column) : column.nameRender,\n render: column.render ?? ((ctx: TableColumnRenderContext) => editCell(column, ctx))\n }))\n return props.readonly ? list : [...list, actionColumn]\n})\n\n/** 透传给 u-table 的插槽名:column:* 经 editCell 注入 model、empty 由组件接管,其余透传 */\nconst passSlotNames = Object.keys(slots).filter(\n (name) => !name.startsWith('column:') && name !== 'empty'\n)\n\n/**\n * 带校验的列表头包装:required 时列名前渲染红星;该列存在未通过项时文字标红并追加\n * 感叹号图标,悬停经 UTip 气泡展示各行错误明细;`#header:key` 插槽 / nameRender 内容替代列名。\n * 渲染函数内读取 columnErrors 建立响应依赖,错误出现/消失即时更新表头。\n */\nfunction headerCell(column: TableEditorColumn) {\n return (ctx: { column: TableColumnNode }): RenderReturn => {\n const messages = columnErrors.value.get(column.key)\n const nodes = [\n h(\n 'span',\n { class: [cls.e('header-text'), bem.is('error', !!messages?.length)] },\n slots[`header:${column.key}`]?.(ctx) ?? column.nameRender?.(ctx) ?? column.name\n )\n ]\n\n if (column.rules?.required) {\n nodes.unshift(h('span', { class: cls.e('required-mark'), 'aria-hidden': 'true' }, '*'))\n }\n\n if (messages?.length) {\n nodes.push(\n h(\n UTip,\n { key: 'header-error-tip' },\n {\n default: () =>\n h(UIcon, { size: 14, class: cls.e('header-icon') }, { default: () => h(Warning) }),\n content: () => messages.map((message) => h('div', { key: message }, message))\n }\n )\n )\n }\n\n return nodes\n }\n}\n\n// --- 按列校验 ---\n\n/** 行数据(以原始对象为键)→ 列 key → 错误信息 */\nconst cellErrors = shallowRef(new Map<Record<string, any>, Map<string, string>>())\n\n/** 行节点 data 可能是响应式代理,统一取原始对象作为键 */\nconst errorRowKey = (rowData: Record<string, any>) => toRaw(rowData) as Record<string, any>\n\nfunction setCellError(rowData: Record<string, any>, key: string, message: string | undefined) {\n const row = errorRowKey(rowData)\n const rowErrors = cellErrors.value.get(row)\n\n if (!message) {\n if (!rowErrors?.delete(key)) return\n // 行错误清空后移除条目,保证「size > 0 即存在错误」可作整体判定\n if (!rowErrors.size) cellErrors.value.delete(row)\n } else {\n if (rowErrors?.get(key) === message) return\n if (rowErrors) rowErrors.set(key, message)\n else cellErrors.value.set(row, new Map([[key, message]]))\n }\n\n triggerRef(cellErrors)\n}\n\n/** 丢弃同一单元格过期的异步校验结果 */\nconst validateSeqs = new WeakMap<Record<string, any>, Map<string, number>>()\n\n/** 单元格级校验:以行数据为 formData、列 key 为 field,结果同步到错误状态 */\nasync function validateCell(\n rowData: Record<string, any>,\n key: string,\n rules: TableEditorColumn['rules']\n) {\n if (!rules) return\n\n const row = errorRowKey(rowData)\n let seqs = validateSeqs.get(row)\n if (!seqs) {\n seqs = new Map()\n validateSeqs.set(row, seqs)\n }\n const seq = (seqs.get(key) ?? 0) + 1\n seqs.set(key, seq)\n\n const message = await validateField(rowData, key, rules)\n if (seqs.get(key) !== seq) return\n // 校验是异步的,期间行可能已被移出模型(整体替换/删除);\n // 把结果写回「死行」会绕过清理 watch 永久残留,直接丢弃\n if (!modelValue.value.some((item) => errorRowKey(item) === row)) return\n\n setCellError(row, key, message)\n}\n\n/**\n * 整表校验:并行校验所有行的规则列(不懒校验),未通过的单元格全部标出。\n * 全部通过 resolve true,否则 resolve false。\n */\nasync function validate() {\n const ruleColumns = columns.value.filter((column) => column.rules)\n\n await Promise.all(\n modelValue.value.map((row) =>\n Promise.all(ruleColumns.map((column) => validateCell(row, column.key, column.rules)))\n )\n )\n\n return cellErrors.value.size === 0\n}\n\n// 行删除(或整体替换)后,同步清理已不存在的行数据上的错误\nwatch(modelValue, (rows) => {\n if (!cellErrors.value.size) return\n\n const aliveRows = new Set(rows.map(errorRowKey))\n const next = new Map<Record<string, any>, Map<string, string>>()\n let changed = false\n\n for (const [row, errors] of cellErrors.value) {\n if (aliveRows.has(row)) next.set(row, errors)\n else changed = true\n }\n\n if (changed) cellErrors.value = next\n})\n\n/** 列 key → 该列全部未通过信息(带行序号),驱动表头错误标识 */\nconst columnErrors = computed(() => {\n const map = new Map<string, string[]>()\n if (!cellErrors.value.size) return map\n\n for (const [row, errors] of cellErrors.value) {\n const index = modelValue.value.findIndex((item) => errorRowKey(item) === row)\n const label = index >= 0 ? `第 ${index + 1} 行:` : ''\n for (const [key, message] of errors) {\n const list = map.get(key) ?? []\n list.push(`${label}${message}`)\n map.set(key, list)\n }\n }\n return map\n})\n\n// --- 单元格渲染 ---\n\n/**\n * 声明了 `#column:key` 插槽的列调用编辑插槽(注入 model),未声明的渲染字段原始值。\n * 配置了 rules 的列在渲染期间读取 cellErrors 建立依赖,错误出现/消失即时更新:\n * 插槽内容常驻包一层容器、仅切换 is-error 类(与表单项错误态同类,不增删 DOM,\n * 控件不因错误态变化重挂丢焦点);纯文本列仅在出错时包一层标红原始值。\n */\nfunction editCell(column: TableEditorColumn, ctx: TableColumnRenderContext): RenderReturn {\n const editSlot = slots[`column:${column.key}`]\n // 内部列 key 带只读态后缀,u-table 按 key 取到的 val 失效,这里按原始列 key 重取\n const val = o(ctx.rowData).get(column.key)\n\n if (!column.rules) {\n if (!editSlot) return val\n const scope = { ...ctx, val }\n return editSlot({ ...scope, model: createCellModel(column, scope) })\n }\n\n const hasError = !!cellErrors.value.get(errorRowKey(ctx.rowData))?.has(column.key)\n if (!editSlot) return hasError ? h('span', { class: bem.is('error') }, val) : val\n\n const scope = { ...ctx, val }\n return h(\n 'span',\n { class: bem.is('error', hasError) },\n editSlot({ ...scope, model: createCellModel(column, scope) })\n )\n}\n\n/**\n * 单元格编辑 model:值先原地写回行数据(行节点与 DOM 得以复用,输入不丢焦点),\n * 再以浅拷贝数组经 update:modelValue 通知宿主,维持 v-model 契约。\n * 只读下注入 readonly: true 且不提供写回通道,值不可修改;\n * 列配置了 rules 时,控件的 change 事件(如失焦提交)触发单元格级校验,输入过程不校验。\n */\nfunction createCellModel(column: TableEditorColumn, ctx: TableColumnRenderContext) {\n const { rowData, val } = ctx\n const key = column.key\n const rules = column.rules\n return {\n modelValue: val,\n ...(props.readonly\n ? { readonly: true }\n : {\n 'onUpdate:modelValue': (value: any) => {\n rowData[key] = value\n emit('update:modelValue', [...modelValue.value])\n }\n }),\n ...(rules ? { onChange: () => void validateCell(rowData, key, rules) } : {})\n }\n}\n\nfunction handleCreate(index?: number) {\n const at = index !== undefined ? index + 1 : modelValue.value.length\n emit('update:modelValue', [...modelValue.value.slice(0, at), {}, ...modelValue.value.slice(at)])\n}\n\nfunction handleCopy(row: TableRowNode) {\n emit('update:modelValue', [\n ...modelValue.value.slice(0, row.index + 1),\n JSON.parse(JSON.stringify(row.data)),\n ...modelValue.value.slice(row.index + 1)\n ])\n}\n\nfunction handleDelete(index: number) {\n emit(\n 'update:modelValue',\n modelValue.value.filter((_, i) => i !== index)\n )\n}\n\ndefineExpose<_TableEditorExposed>({ validate })\n</script>\n"],"mappings":"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"}
1
+ {"version":3,"file":"table-editor.js","names":["UTip","UIcon","_openBlock","_createBlock","_unref","UTable","_mergeProps","_createSlots","_withCtx","_createElementVNode","_normalizeClass","_createVNode","UButton","_createTextVNode","_createCommentVNode","_renderList","_renderSlot","_normalizeProps","_guardReactiveProps"],"sources":["../../../src/components/table-editor/table-editor.vue"],"sourcesContent":["<template>\n <u-table\n v-bind=\"tableProps\"\n :columns=\"internalColumns\"\n :data=\"modelValue\"\n :class=\"cls.b\"\n :stripe=\"false\"\n show-index\n >\n <!-- 其余插槽(header:* / row:expand / foot / append 等)透传给 u-table;column:* 与 empty 由组件接管 -->\n <template v-for=\"name in passSlotNames\" :key=\"name\" #[name]=\"scope\">\n <slot :name=\"name\" v-bind=\"scope\" />\n </template>\n\n <template #column:__operation=\"{ row }\">\n <div :class=\"cls.e('operations')\">\n <u-button\n text\n size=\"small\"\n type=\"danger\"\n :icon=\"Minus\"\n title=\"移除\"\n @click=\"handleDelete(row.index)\"\n />\n <u-button\n text\n size=\"small\"\n :icon=\"Plus\"\n title=\"新增到下一行\"\n @click=\"handleCreate(row.index)\"\n />\n <u-button text size=\"small\" :icon=\"Copy\" title=\"复制到下一行\" @click=\"handleCopy(row)\" />\n </div>\n </template>\n\n <template #empty>\n <div style=\"text-align: center; padding: 4px 0\">\n <u-button\n v-if=\"!props.readonly\"\n text\n size=\"small\"\n type=\"primary\"\n :icon=\"Plus\"\n @click=\"handleCreate()\"\n >\n 添加\n </u-button>\n </div>\n </template>\n </u-table>\n</template>\n\n<script lang=\"ts\" setup>\nimport { o } from '@cat-kit/core'\nimport { Copy, Minus, Plus, Warning } from '@veltra/icons/normal'\nimport { bem } from '@veltra/utils'\nimport { computed, h, shallowRef, toRaw, triggerRef, useSlots, watch } from 'vue'\n\nimport type {\n TableEditorProps,\n TableEditorEmits,\n TableEditorColumn,\n _TableEditorExposed,\n TableColumn,\n TableColumnNode,\n TableColumnRenderContext,\n TableColumnSlotsScope,\n RenderReturn\n} from '../../types'\nimport { UButton } from '../button'\nimport { validateField } from '../form-item/validate'\nimport { UIcon } from '../icon'\nimport { UTable } from '../table'\nimport type { TableRowNode } from '../table/node/row'\nimport { UTip } from '../tip'\n\ndefineOptions({ name: 'UTableEditor' })\n\ndefineSlots<{\n [key: `column:${string}`]: (props: TableColumnSlotsScope) => any\n [key: `header:${string}`]: (props: { column: TableColumnNode }) => any\n}>()\n\nconst props = defineProps<TableEditorProps>()\nconst emit = defineEmits<TableEditorEmits>()\n\nconst columns = computed(() => props.columns ?? [])\nconst modelValue = computed(() => props.modelValue ?? [])\n\n/** 转发给 u-table 的表格属性;columns / modelValue / readonly 为编辑器自用,stripe / showIndex 被覆盖 */\nconst tableProps = computed(() => {\n const rest: Record<string, any> = { ...props }\n delete rest.columns\n delete rest.modelValue\n delete rest.readonly\n return rest\n})\n\nconst cls = bem('table-editor')\n\nconst slots = useSlots()\n\nconst actionColumn: TableColumn = {\n key: '__operation',\n name: '操作',\n width: 104,\n align: 'center',\n fixed: 'right',\n resizable: false\n}\n\n/**\n * 内部列定义:单元格渲染挂在列的 render 上(用户列自带的 render 优先),\n * 配置了 rules 的列包装 nameRender 追加校验标识,非只读时末尾追加操作列。\n * 列 key 带上只读态后缀:u-table 行内单元格在 props 值相等时可能跳过子组件补丁,\n * 只读切换改用挂载键直接重挂单元格,确保控件在编辑/只读形态间可靠切换。\n */\nconst internalColumns = computed<TableColumn[]>(() => {\n const list = columns.value.map((column) => ({\n ...column,\n key: `${column.key}${props.readonly ? ':ro' : ''}`,\n nameRender: column.rules ? headerCell(column) : column.nameRender,\n render: column.render ?? ((ctx: TableColumnRenderContext) => editCell(column, ctx))\n }))\n return props.readonly ? list : [...list, actionColumn]\n})\n\n/** 透传给 u-table 的插槽名:column:* 经 editCell 注入 model、empty 由组件接管,其余透传 */\nconst passSlotNames = Object.keys(slots).filter(\n (name) => !name.startsWith('column:') && name !== 'empty'\n)\n\n/**\n * 带校验的列表头包装:required 时列名前渲染红星;该列存在未通过项时文字标红并追加\n * 感叹号图标,悬停经 UTip 气泡展示各行错误明细;`#header:key` 插槽 / nameRender 内容替代列名。\n * 渲染函数内读取 columnErrors 建立响应依赖,错误出现/消失即时更新表头。\n */\nfunction headerCell(column: TableEditorColumn) {\n return (ctx: { column: TableColumnNode }): RenderReturn => {\n const messages = columnErrors.value.get(column.key)\n const nodes = [\n h(\n 'span',\n { class: [cls.e('header-text'), bem.is('error', !!messages?.length)] },\n slots[`header:${column.key}`]?.(ctx) ?? column.nameRender?.(ctx) ?? column.name\n )\n ]\n\n if (column.rules?.required) {\n nodes.unshift(h('span', { class: cls.e('required-mark'), 'aria-hidden': 'true' }, '*'))\n }\n\n if (messages?.length) {\n nodes.push(\n h(\n UTip,\n { key: 'header-error-tip' },\n {\n default: () =>\n h(UIcon, { size: 14, class: cls.e('header-icon') }, { default: () => h(Warning) }),\n content: () => messages.map((message) => h('div', { key: message }, message))\n }\n )\n )\n }\n\n return nodes\n }\n}\n\n// --- 按列校验 ---\n\n/** 行数据(以原始对象为键)→ 列 key → 错误信息 */\nconst cellErrors = shallowRef(new Map<Record<string, any>, Map<string, string>>())\n\n/** 行节点 data 可能是响应式代理,统一取原始对象作为键 */\nconst errorRowKey = (rowData: Record<string, any>) => toRaw(rowData) as Record<string, any>\n\nfunction setCellError(rowData: Record<string, any>, key: string, message: string | undefined) {\n const row = errorRowKey(rowData)\n const rowErrors = cellErrors.value.get(row)\n\n if (!message) {\n if (!rowErrors?.delete(key)) return\n // 行错误清空后移除条目,保证「size > 0 即存在错误」可作整体判定\n if (!rowErrors.size) cellErrors.value.delete(row)\n } else {\n if (rowErrors?.get(key) === message) return\n if (rowErrors) rowErrors.set(key, message)\n else cellErrors.value.set(row, new Map([[key, message]]))\n }\n\n triggerRef(cellErrors)\n}\n\n/** 丢弃同一单元格过期的异步校验结果 */\nconst validateSeqs = new WeakMap<Record<string, any>, Map<string, number>>()\n\n/** 单元格级校验:以行数据为 formData、列 key 为 field,结果同步到错误状态 */\nasync function validateCell(\n rowData: Record<string, any>,\n key: string,\n rules: TableEditorColumn['rules']\n) {\n if (!rules) return\n\n const row = errorRowKey(rowData)\n let seqs = validateSeqs.get(row)\n if (!seqs) {\n seqs = new Map()\n validateSeqs.set(row, seqs)\n }\n const seq = (seqs.get(key) ?? 0) + 1\n seqs.set(key, seq)\n\n const message = await validateField(rowData, key, rules)\n if (seqs.get(key) !== seq) return\n // 校验是异步的,期间行可能已被移出模型(整体替换/删除);\n // 把结果写回「死行」会绕过清理 watch 永久残留,直接丢弃\n if (!modelValue.value.some((item) => errorRowKey(item) === row)) return\n\n setCellError(row, key, message)\n}\n\n/**\n * 整表校验:并行校验所有行的规则列(不懒校验),未通过的单元格全部标出。\n * 全部通过 resolve true,否则 resolve false。\n */\nasync function validate() {\n const ruleColumns = columns.value.filter((column) => column.rules)\n\n await Promise.all(\n modelValue.value.map((row) =>\n Promise.all(ruleColumns.map((column) => validateCell(row, column.key, column.rules)))\n )\n )\n\n return cellErrors.value.size === 0\n}\n\n// 行删除(或整体替换)后,同步清理已不存在的行数据上的错误\nwatch(modelValue, (rows) => {\n if (!cellErrors.value.size) return\n\n const aliveRows = new Set(rows.map(errorRowKey))\n const next = new Map<Record<string, any>, Map<string, string>>()\n let changed = false\n\n for (const [row, errors] of cellErrors.value) {\n if (aliveRows.has(row)) next.set(row, errors)\n else changed = true\n }\n\n if (changed) cellErrors.value = next\n})\n\n/** 列 key → 该列全部未通过信息(带行序号),驱动表头错误标识 */\nconst columnErrors = computed(() => {\n const map = new Map<string, string[]>()\n if (!cellErrors.value.size) return map\n\n for (const [row, errors] of cellErrors.value) {\n const index = modelValue.value.findIndex((item) => errorRowKey(item) === row)\n const label = index >= 0 ? `第 ${index + 1} 行:` : ''\n for (const [key, message] of errors) {\n const list = map.get(key) ?? []\n list.push(`${label}${message}`)\n map.set(key, list)\n }\n }\n return map\n})\n\n// --- 单元格渲染 ---\n\n/**\n * 声明了 `#column:key` 插槽的列调用编辑插槽(注入 model),未声明的渲染字段原始值。\n * 配置了 rules 的列在渲染期间读取 cellErrors 建立依赖,错误出现/消失即时更新:\n * 插槽内容常驻包一层容器、仅切换 is-error 类(与表单项错误态同类,不增删 DOM,\n * 控件不因错误态变化重挂丢焦点);纯文本列仅在出错时包一层标红原始值。\n */\nfunction editCell(column: TableEditorColumn, ctx: TableColumnRenderContext): RenderReturn {\n const editSlot = slots[`column:${column.key}`]\n // 内部列 key 带只读态后缀,u-table 按 key 取到的 val 失效,这里按原始列 key 重取\n const val = o(ctx.rowData).get(column.key)\n\n if (!column.rules) {\n if (!editSlot) return val\n const scope = { ...ctx, val }\n return editSlot({ ...scope, model: createCellModel(column, scope) })\n }\n\n const hasError = !!cellErrors.value.get(errorRowKey(ctx.rowData))?.has(column.key)\n if (!editSlot) return hasError ? h('span', { class: bem.is('error') }, val) : val\n\n const scope = { ...ctx, val }\n return h(\n 'span',\n { class: bem.is('error', hasError) },\n editSlot({ ...scope, model: createCellModel(column, scope) })\n )\n}\n\n/**\n * 单元格编辑 model:值先原地写回行数据(行节点与 DOM 得以复用,输入不丢焦点),\n * 再以浅拷贝数组经 update:modelValue 通知宿主,维持 v-model 契约。\n * 只读下注入 readonly: true 且不提供写回通道,值不可修改;\n * 列配置了 rules 时,控件的 change 事件(如失焦提交)触发单元格级校验,输入过程不校验。\n */\nfunction createCellModel(column: TableEditorColumn, ctx: TableColumnRenderContext) {\n const { rowData, val } = ctx\n const key = column.key\n const rules = column.rules\n return {\n modelValue: val,\n ...(props.readonly\n ? { readonly: true }\n : {\n 'onUpdate:modelValue': (value: any) => {\n rowData[key] = value\n emit('update:modelValue', [...modelValue.value])\n }\n }),\n ...(rules ? { onChange: () => void validateCell(rowData, key, rules) } : {})\n }\n}\n\nfunction handleCreate(index?: number) {\n const at = index !== undefined ? index + 1 : modelValue.value.length\n emit('update:modelValue', [...modelValue.value.slice(0, at), {}, ...modelValue.value.slice(at)])\n}\n\nfunction handleCopy(row: TableRowNode) {\n emit('update:modelValue', [\n ...modelValue.value.slice(0, row.index + 1),\n JSON.parse(JSON.stringify(row.data)),\n ...modelValue.value.slice(row.index + 1)\n ])\n}\n\nfunction handleDelete(index: number) {\n emit(\n 'update:modelValue',\n modelValue.value.filter((_, i) => i !== index)\n )\n}\n\ndefineExpose<_TableEditorExposed>({ validate })\n</script>\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"tabs-horizontal.js","names":[],"sources":["../../../src/components/tabs/tabs-horizontal.vue"],"sourcesContent":["<template>\n <div\n :class=\"[\n cls.b,\n cls.m('horizontal'),\n cls.m(position),\n cls.m(size),\n bem.is('block', block),\n bem.is('rounded', rounded)\n ]\"\n >\n <button\n v-show=\"showNav\"\n type=\"button\"\n :class=\"[cls.e('nav'), cls.em('nav', 'prev')]\"\n :disabled=\"!canPrev\"\n @click=\"scrollByStep(-1)\"\n >\n <u-icon> <ArrowLeft /> </u-icon>\n </button>\n\n <div ref=\"viewportRef\" :class=\"cls.e('viewport')\">\n <div ref=\"listRef\" :class=\"cls.e('list')\">\n <button\n type=\"button\"\n role=\"tab\"\n v-for=\"(item, index) in items\"\n :key=\"item.key\"\n :class=\"[\n cls.e('item'),\n bem.is('active', model === item.key),\n bem.is('disabled', item.disabled === true)\n ]\"\n @click.stop=\"handleClick(item, index)\"\n >\n <slot v-bind=\"{ item, index }\">\n <span :class=\"cls.e('item-label')\">{{ item.name ?? item.key }}</span>\n </slot>\n\n <span\n v-if=\"isItemClosable(item)\"\n role=\"button\"\n tabindex=\"0\"\n :class=\"cls.e('close')\"\n :aria-label=\"`close ${item.name ?? item.key}`\"\n @click.stop=\"handleClose(item, index)\"\n >\n <u-icon>\n <Close />\n </u-icon>\n </span>\n </button>\n </div>\n </div>\n\n <button\n v-show=\"showNav\"\n type=\"button\"\n :class=\"[cls.e('nav'), cls.em('nav', 'next')]\"\n :disabled=\"!canNext\"\n @click=\"scrollByStep(1)\"\n >\n <u-icon> <ArrowRight /> </u-icon>\n </button>\n </div>\n</template>\n\n<script lang=\"ts\" setup>\nimport { useFallbackProps } from '@veltra/compositions'\nimport { ArrowLeft, ArrowRight, Close } from '@veltra/icons/normal'\nimport { bem } from '@veltra/utils'\nimport { computed, shallowRef } from 'vue'\n\nimport type { ComponentSize, TabItem, TabsHorizontalEmits, TabsHorizontalProps } from '../../types'\nimport { UIcon } from '../icon'\nimport { useTabsBar } from './use-tabs-bar'\n\ndefineOptions({ name: 'UTabsHorizontal' })\n\nconst props = withDefaults(defineProps<TabsHorizontalProps>(), {\n position: 'top',\n closable: false,\n block: false,\n rounded: false\n})\n\nconst emit = defineEmits<TabsHorizontalEmits>()\n\ndefineSlots<{ default: (props: { item: TabItem; index: number }) => any }>()\n\nconst { size } = useFallbackProps([props], { size: 'default' as ComponentSize })\n\nconst cls = bem('tabs-bar')\n\nconst model = defineModel<string>()\n\nconst viewportRef = shallowRef<HTMLElement>()\nconst listRef = shallowRef<HTMLElement>()\n\nconst itemsRef = computed(() => props.items)\n\nconst { showNav, canPrev, canNext, scrollByStep } = useTabsBar({\n viewportRef,\n listRef,\n items: itemsRef,\n model\n})\n\nconst isItemClosable = (item: TabItem) => {\n if (item.disabled) return false\n return item.closable ?? props.closable\n}\n\nconst handleClick = (item: TabItem, index: number) => {\n if (item.disabled) return\n model.value = item.key\n emit('click', item, index)\n}\n\nconst handleClose = (item: TabItem, index: number) => {\n if (item.disabled) return\n emit('close', item, index)\n}\n</script>\n"],"mappings":"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"}
1
+ {"version":3,"file":"tabs-horizontal.js","names":["_useModel","_openBlock","_createElementBlock","_normalizeClass","_unref","_withDirectives","_createElementVNode","_createVNode","UIcon","_withCtx","_vShow","_Fragment","_renderList","_withModifiers","_renderSlot","_mergeProps","_toDisplayString","_createCommentVNode"],"sources":["../../../src/components/tabs/tabs-horizontal.vue"],"sourcesContent":["<template>\n <div\n :class=\"[\n cls.b,\n cls.m('horizontal'),\n cls.m(position),\n cls.m(size),\n bem.is('block', block),\n bem.is('rounded', rounded)\n ]\"\n >\n <button\n v-show=\"showNav\"\n type=\"button\"\n :class=\"[cls.e('nav'), cls.em('nav', 'prev')]\"\n :disabled=\"!canPrev\"\n @click=\"scrollByStep(-1)\"\n >\n <u-icon> <ArrowLeft /> </u-icon>\n </button>\n\n <div ref=\"viewportRef\" :class=\"cls.e('viewport')\">\n <div ref=\"listRef\" :class=\"cls.e('list')\">\n <button\n type=\"button\"\n role=\"tab\"\n v-for=\"(item, index) in items\"\n :key=\"item.key\"\n :class=\"[\n cls.e('item'),\n bem.is('active', model === item.key),\n bem.is('disabled', item.disabled === true)\n ]\"\n @click.stop=\"handleClick(item, index)\"\n >\n <slot v-bind=\"{ item, index }\">\n <span :class=\"cls.e('item-label')\">{{ item.name ?? item.key }}</span>\n </slot>\n\n <span\n v-if=\"isItemClosable(item)\"\n role=\"button\"\n tabindex=\"0\"\n :class=\"cls.e('close')\"\n :aria-label=\"`close ${item.name ?? item.key}`\"\n @click.stop=\"handleClose(item, index)\"\n >\n <u-icon>\n <Close />\n </u-icon>\n </span>\n </button>\n </div>\n </div>\n\n <button\n v-show=\"showNav\"\n type=\"button\"\n :class=\"[cls.e('nav'), cls.em('nav', 'next')]\"\n :disabled=\"!canNext\"\n @click=\"scrollByStep(1)\"\n >\n <u-icon> <ArrowRight /> </u-icon>\n </button>\n </div>\n</template>\n\n<script lang=\"ts\" setup>\nimport { useFallbackProps } from '@veltra/compositions'\nimport { ArrowLeft, ArrowRight, Close } from '@veltra/icons/normal'\nimport { bem } from '@veltra/utils'\nimport { computed, shallowRef } from 'vue'\n\nimport type { ComponentSize, TabItem, TabsHorizontalEmits, TabsHorizontalProps } from '../../types'\nimport { UIcon } from '../icon'\nimport { useTabsBar } from './use-tabs-bar'\n\ndefineOptions({ name: 'UTabsHorizontal' })\n\nconst props = withDefaults(defineProps<TabsHorizontalProps>(), {\n position: 'top',\n closable: false,\n block: false,\n rounded: false\n})\n\nconst emit = defineEmits<TabsHorizontalEmits>()\n\ndefineSlots<{ default: (props: { item: TabItem; index: number }) => any }>()\n\nconst { size } = useFallbackProps([props], { size: 'default' as ComponentSize })\n\nconst cls = bem('tabs-bar')\n\nconst model = defineModel<string>()\n\nconst viewportRef = shallowRef<HTMLElement>()\nconst listRef = shallowRef<HTMLElement>()\n\nconst itemsRef = computed(() => props.items)\n\nconst { showNav, canPrev, canNext, scrollByStep } = useTabsBar({\n viewportRef,\n listRef,\n items: itemsRef,\n model\n})\n\nconst isItemClosable = (item: TabItem) => {\n if (item.disabled) return false\n return item.closable ?? props.closable\n}\n\nconst handleClick = (item: TabItem, index: number) => {\n if (item.disabled) return\n model.value = item.key\n emit('click', item, index)\n}\n\nconst handleClose = (item: TabItem, index: number) => {\n if (item.disabled) return\n emit('close', item, index)\n}\n</script>\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"tabs-vertical.js","names":[],"sources":["../../../src/components/tabs/tabs-vertical.vue"],"sourcesContent":["<template>\n <div\n :class=\"[cls.b, cls.m('vertical'), cls.m(position), cls.m(size), bem.is('rounded', rounded)]\"\n >\n <button\n type=\"button\"\n role=\"tab\"\n v-for=\"(item, index) in items\"\n :key=\"item.key\"\n :class=\"[\n cls.e('item'),\n bem.is('active', model === item.key),\n bem.is('disabled', item.disabled === true)\n ]\"\n @click.stop=\"handleClick(item, index)\"\n >\n <slot v-bind=\"{ item, index }\">\n <span :class=\"cls.e('item-label')\">{{ item.name ?? item.key }}</span>\n </slot>\n <span\n v-if=\"isItemClosable(item)\"\n role=\"button\"\n tabindex=\"0\"\n :class=\"cls.e('close')\"\n :aria-label=\"`close ${item.name ?? item.key}`\"\n @click.stop=\"handleClose(item, index)\"\n >\n <u-icon>\n <Close />\n </u-icon>\n </span>\n </button>\n </div>\n</template>\n\n<script lang=\"ts\" setup>\nimport { useFallbackProps } from '@veltra/compositions'\nimport { Close } from '@veltra/icons/normal'\nimport { bem } from '@veltra/utils'\n\nimport type { ComponentSize, TabItem, TabsVerticalEmits, TabsVerticalProps } from '../../types'\nimport { UIcon } from '../icon'\n\ndefineOptions({ name: 'UTabsVertical' })\n\nconst props = withDefaults(defineProps<TabsVerticalProps>(), {\n position: 'left',\n closable: false,\n rounded: false\n})\n\nconst emit = defineEmits<TabsVerticalEmits>()\n\ndefineSlots<{ default: (props: { item: TabItem; index: number }) => any }>()\n\nconst { size } = useFallbackProps([props], { size: 'default' as ComponentSize })\n\nconst cls = bem('tabs-bar')\n\nconst model = defineModel<string>()\n\nconst isItemClosable = (item: TabItem) => {\n if (item.disabled) return false\n return item.closable ?? props.closable\n}\n\nconst handleClick = (item: TabItem, index: number) => {\n if (item.disabled) return\n model.value = item.key\n emit('click', item, index)\n}\n\nconst handleClose = (item: TabItem, index: number) => {\n if (item.disabled) return\n emit('close', item, index)\n}\n</script>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA6CA,MAAM,QAAQ;EAMd,MAAM,OAAO;EAIb,MAAM,EAAE,SAAS,iBAAiB,CAAC,KAAK,GAAG,EAAE,MAAM,UAA2B,CAAC;EAE/E,MAAM,MAAM,IAAI,UAAU;EAE1B,MAAM,QAAQ,SAAmB,SAAA,YAAC;EAElC,MAAM,kBAAkB,SAAkB;GACxC,IAAI,KAAK,UAAU,OAAO;GAC1B,OAAO,KAAK,YAAY,MAAM;EAChC;EAEA,MAAM,eAAe,MAAe,UAAkB;GACpD,IAAI,KAAK,UAAU;GACnB,MAAM,QAAQ,KAAK;GACnB,KAAK,SAAS,MAAM,KAAK;EAC3B;EAEA,MAAM,eAAe,MAAe,UAAkB;GACpD,IAAI,KAAK,UAAU;GACnB,KAAK,SAAS,MAAM,KAAK;EAC3B;;GA1EE,OAAA,UAAA,GAAA,mBA+BM,OAAA,EA9BH,OAAK,eAAA;IAAG,MAAA,GAAA,CAAG,CAAC;IAAG,MAAA,GAAA,CAAG,CAAC,EAAC,UAAA;IAAc,MAAA,GAAA,CAAG,CAAC,EAAE,QAAA,QAAQ;IAAG,MAAA,GAAA,CAAG,CAAC,EAAE,MAAA,IAAA,CAAI;IAAG,MAAA,GAAA,CAAG,CAAC,GAAE,WAAY,QAAA,OAAO;GAAA,CAAA,EAAA,GAE1F,EAAA,UAAA,IAAA,GAAA,mBA2BS,UAAA,MAAA,WAxBiB,QAAA,QAAhB,MAAM,UAAK;IAHrB,OAAA,UAAA,GAAA,mBA2BS,UAAA;KA1BP,MAAK;KACL,MAAK;KAEJ,KAAK,KAAK;KACV,OAAK,eAAA;MAAY,MAAA,GAAA,CAAG,CAAC,EAAC,MAAA;MAAkB,MAAA,GAAA,CAAG,CAAC,GAAE,UAAW,MAAA,UAAU,KAAK,GAAG;MAAW,MAAA,GAAA,CAAG,CAAC,GAAE,YAAa,KAAK,aAAQ,IAAA;;KAKtH,SAAK,eAAA,WAAO,YAAY,MAAM,KAAK,GAAA,CAAA,MAAA,CAAA;IAEpC,GAAA,CAAA,WAEO,KAAA,QAAA,WAFP,WAEO,EAAA,SAAA,KAAA,GAAA;KAFS;KAAM;IAAK,CAAA,SAEpB,CADL,mBAAqE,QAAA,EAA9D,OAAK,eAAE,MAAA,GAAA,CAAG,CAAC,EAAC,YAAA,CAAA,EAAmB,GAAA,gBAAA,KAAK,QAAQ,KAAK,GAAG,GAAA,CAAA,CAAA,CAAA,GAGrD,eAAe,IAAI,KAD3B,UAAA,GAAA,mBAWO,QAAA;;KATL,MAAK;KACL,UAAS;KACR,OAAK,eAAE,MAAA,GAAA,CAAG,CAAC,EAAC,OAAA,CAAA;KACZ,cAAU,SAAW,KAAK,QAAQ,KAAK;KACvC,SAAK,eAAA,WAAO,YAAY,MAAM,KAAK,GAAA,CAAA,MAAA,CAAA;IAEpC,GAAA,CAAA,YAES,MAAA,WAAA,GAAA,MAAA;KADP,SAAA,cAAS,CAAT,YAAS,MAAA,KAAA,CAAA,CAAA,CAAA"}
1
+ {"version":3,"file":"tabs-vertical.js","names":["_useModel","_openBlock","_createElementBlock","_normalizeClass","_unref","_Fragment","_renderList","_withModifiers","_renderSlot","_mergeProps","_createElementVNode","_toDisplayString","_createVNode","UIcon","_withCtx","_createCommentVNode"],"sources":["../../../src/components/tabs/tabs-vertical.vue"],"sourcesContent":["<template>\n <div\n :class=\"[cls.b, cls.m('vertical'), cls.m(position), cls.m(size), bem.is('rounded', rounded)]\"\n >\n <button\n type=\"button\"\n role=\"tab\"\n v-for=\"(item, index) in items\"\n :key=\"item.key\"\n :class=\"[\n cls.e('item'),\n bem.is('active', model === item.key),\n bem.is('disabled', item.disabled === true)\n ]\"\n @click.stop=\"handleClick(item, index)\"\n >\n <slot v-bind=\"{ item, index }\">\n <span :class=\"cls.e('item-label')\">{{ item.name ?? item.key }}</span>\n </slot>\n <span\n v-if=\"isItemClosable(item)\"\n role=\"button\"\n tabindex=\"0\"\n :class=\"cls.e('close')\"\n :aria-label=\"`close ${item.name ?? item.key}`\"\n @click.stop=\"handleClose(item, index)\"\n >\n <u-icon>\n <Close />\n </u-icon>\n </span>\n </button>\n </div>\n</template>\n\n<script lang=\"ts\" setup>\nimport { useFallbackProps } from '@veltra/compositions'\nimport { Close } from '@veltra/icons/normal'\nimport { bem } from '@veltra/utils'\n\nimport type { ComponentSize, TabItem, TabsVerticalEmits, TabsVerticalProps } from '../../types'\nimport { UIcon } from '../icon'\n\ndefineOptions({ name: 'UTabsVertical' })\n\nconst props = withDefaults(defineProps<TabsVerticalProps>(), {\n position: 'left',\n closable: false,\n rounded: false\n})\n\nconst emit = defineEmits<TabsVerticalEmits>()\n\ndefineSlots<{ default: (props: { item: TabItem; index: number }) => any }>()\n\nconst { size } = useFallbackProps([props], { size: 'default' as ComponentSize })\n\nconst cls = bem('tabs-bar')\n\nconst model = defineModel<string>()\n\nconst isItemClosable = (item: TabItem) => {\n if (item.disabled) return false\n return item.closable ?? props.closable\n}\n\nconst handleClick = (item: TabItem, index: number) => {\n if (item.disabled) return\n model.value = item.key\n emit('click', item, index)\n}\n\nconst handleClose = (item: TabItem, index: number) => {\n if (item.disabled) return\n emit('close', item, index)\n}\n</script>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA6CA,MAAM,QAAQ;EAMd,MAAM,OAAO;EAIb,MAAM,EAAE,SAAS,iBAAiB,CAAC,KAAK,GAAG,EAAE,MAAM,UAA2B,CAAC;EAE/E,MAAM,MAAM,IAAI,UAAU;EAE1B,MAAM,QAAQA,SAAmB,SAAA,YAAC;EAElC,MAAM,kBAAkB,SAAkB;GACxC,IAAI,KAAK,UAAU,OAAO;GAC1B,OAAO,KAAK,YAAY,MAAM;EAChC;EAEA,MAAM,eAAe,MAAe,UAAkB;GACpD,IAAI,KAAK,UAAU;GACnB,MAAM,QAAQ,KAAK;GACnB,KAAK,SAAS,MAAM,KAAK;EAC3B;EAEA,MAAM,eAAe,MAAe,UAAkB;GACpD,IAAI,KAAK,UAAU;GACnB,KAAK,SAAS,MAAM,KAAK;EAC3B;;GA1EE,OAAAC,UAAA,GAAAC,mBA+BM,OAAA,EA9BH,OAAKC,eAAA;IAAGC,MAAA,GAAA,CAAG,CAAC;IAAGA,MAAA,GAAA,CAAG,CAAC,EAAC,UAAA;IAAcA,MAAA,GAAA,CAAG,CAAC,EAAE,QAAA,QAAQ;IAAGA,MAAA,GAAA,CAAG,CAAC,EAAEA,MAAA,IAAA,CAAI;IAAGA,MAAA,GAAA,CAAG,CAAC,GAAE,WAAY,QAAA,OAAO;GAAA,CAAA,EAAA,GAE1F,EAAAH,UAAA,IAAA,GAAAC,mBA2BSG,UAAA,MAAAC,WAxBiB,QAAA,QAAhB,MAAM,UAAK;IAHrB,OAAAL,UAAA,GAAAC,mBA2BS,UAAA;KA1BP,MAAK;KACL,MAAK;KAEJ,KAAK,KAAK;KACV,OAAKC,eAAA;MAAYC,MAAA,GAAA,CAAG,CAAC,EAAC,MAAA;MAAkBA,MAAA,GAAA,CAAG,CAAC,GAAE,UAAW,MAAA,UAAU,KAAK,GAAG;MAAWA,MAAA,GAAA,CAAG,CAAC,GAAE,YAAa,KAAK,aAAQ,IAAA;;KAKtH,SAAKG,eAAA,WAAO,YAAY,MAAM,KAAK,GAAA,CAAA,MAAA,CAAA;IAEpC,GAAA,CAAAC,WAEO,KAAA,QAAA,WAFPC,WAEO,EAAA,SAAA,KAAA,GAAA;KAFS;KAAM;IAAK,CAAA,SAEpB,CADLC,mBAAqE,QAAA,EAA9D,OAAKP,eAAEC,MAAA,GAAA,CAAG,CAAC,EAAC,YAAA,CAAA,EAAmB,GAAAO,gBAAA,KAAK,QAAQ,KAAK,GAAG,GAAA,CAAA,CAAA,CAAA,GAGrD,eAAe,IAAI,KAD3BV,UAAA,GAAAC,mBAWO,QAAA;;KATL,MAAK;KACL,UAAS;KACR,OAAKC,eAAEC,MAAA,GAAA,CAAG,CAAC,EAAC,OAAA,CAAA;KACZ,cAAU,SAAW,KAAK,QAAQ,KAAK;KACvC,SAAKG,eAAA,WAAO,YAAY,MAAM,KAAK,GAAA,CAAA,MAAA,CAAA;IAEpC,GAAA,CAAAK,YAESR,MAAAS,WAAA,GAAA,MAAA;KADP,SAAAC,cAAS,CAATF,YAASR,MAAA,KAAA,CAAA,CAAA,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"tabs.js","names":[],"sources":["../../../src/components/tabs/tabs.vue"],"sourcesContent":["<template>\n <div :class=\"[cls.b, cls.m(position!)]\">\n <u-tabs-horizontal\n v-if=\"isHorizontal\"\n v-model=\"model\"\n :items=\"items\"\n :position=\"horizontalPosition\"\n :size=\"size\"\n :closable=\"closable\"\n :block=\"block\"\n :rounded=\"rounded\"\n @click=\"onClick\"\n @close=\"onClose\"\n />\n <u-tabs-vertical\n v-else\n v-model=\"model\"\n :items=\"items\"\n :position=\"verticalPosition\"\n :size=\"size\"\n :closable=\"closable\"\n :rounded=\"rounded\"\n @click=\"onClick\"\n @close=\"onClose\"\n />\n\n <transition name=\"fade\" mode=\"out-in\">\n <KeepAlive v-if=\"keepAlive\">\n <component :key=\"model\" :is=\"renderSlots()\" />\n </KeepAlive>\n <component v-else :key=\"model\" :is=\"renderSlots()\" />\n </transition>\n </div>\n</template>\n\n<script lang=\"ts\" setup>\nimport { useFallbackProps } from '@veltra/compositions'\nimport { bem } from '@veltra/utils'\nimport { computed, createVNode } from 'vue'\n\nimport type { ComponentSize, TabItem, TabsEmits, TabsProps } from '../../types'\nimport { UScroll } from '../scroll'\nimport UTabsHorizontal from './tabs-horizontal.vue'\nimport UTabsVertical from './tabs-vertical.vue'\n\ndefineOptions({ name: 'UTabs' })\n\nconst props = withDefaults(defineProps<TabsProps>(), {\n position: 'top',\n closable: false,\n block: false,\n rounded: false,\n keepAlive: false\n})\n\nconst emit = defineEmits<TabsEmits>()\n\nconst slots = defineSlots<Record<string, (props: any) => any>>()\n\nconst { size } = useFallbackProps([props], { size: 'default' as ComponentSize })\n\nconst cls = bem('tabs')\n\nconst model = defineModel<string>()\n\nconst isHorizontal = computed(() => props.position === 'top' || props.position === 'bottom')\n\n/** 避免模板中使用类型断言:收敛 position 到水平 / 垂直子组件所需的子集。 */\nconst horizontalPosition = computed<'top' | 'bottom'>(() =>\n props.position === 'bottom' ? 'bottom' : 'top'\n)\n\nconst verticalPosition = computed<'left' | 'right'>(() =>\n props.position === 'right' ? 'right' : 'left'\n)\n\nconst onClick = (item: TabItem, index: number) => emit('click', item, index)\nconst onClose = (item: TabItem, index: number) => emit('close', item, index)\n\nconst renderSlots = () => {\n const key = model.value\n if (!key) return null\n const nodes = slots[key]?.({ key })\n if (Array.isArray(nodes)) {\n return createVNode(UScroll, { class: cls.e('content') }, { default: () => nodes })\n }\n return nodes\n}\n</script>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA+CA,MAAM,QAAQ;EAQd,MAAM,OAAO;EAEb,MAAM,QAAQ,SAAA;EAEd,MAAM,EAAE,SAAS,iBAAiB,CAAC,KAAK,GAAG,EAAE,MAAM,UAA2B,CAAC;EAE/E,MAAM,MAAM,IAAI,MAAM;EAEtB,MAAM,QAAQ,SAAmB,SAAA,YAAC;EAElC,MAAM,eAAe,eAAe,MAAM,aAAa,SAAS,MAAM,aAAa,QAAQ;;EAG3F,MAAM,qBAAqB,eACzB,MAAM,aAAa,WAAW,WAAW,KAC3C;EAEA,MAAM,mBAAmB,eACvB,MAAM,aAAa,UAAU,UAAU,MACzC;EAEA,MAAM,WAAW,MAAe,UAAkB,KAAK,SAAS,MAAM,KAAK;EAC3E,MAAM,WAAW,MAAe,UAAkB,KAAK,SAAS,MAAM,KAAK;EAE3E,MAAM,oBAAoB;GACxB,MAAM,MAAM,MAAM;GAClB,IAAI,CAAC,KAAK,OAAO;GACjB,MAAM,QAAQ,MAAM,IAAI,GAAG,EAAE,IAAI,CAAC;GAClC,IAAI,MAAM,QAAQ,KAAK,GACrB,OAAO,YAAY,aAAS,EAAE,OAAO,IAAI,EAAE,SAAS,EAAE,GAAG,EAAE,eAAe,MAAM,CAAC;GAEnF,OAAO;EACT;;GAtFE,OAAA,UAAA,GAAA,mBA+BM,OAAA,EA/BA,OAAK,eAAA,CAAG,MAAA,GAAA,CAAG,CAAC,GAAG,MAAA,GAAA,CAAG,CAAC,EAAE,QAAA,QAAQ,CAAA,CAAA,EAAA,GAEzB,CAAA,aAAA,SADR,UAAA,GAAA,YAWE,aAAA;;IATS,YAAA,MAAA;IAAA,uBAAA,OAAA,OAAA,OAAA,MAAA,WAAA,MAAK,QAAA;IACb,OAAO,QAAA;IACP,UAAU,mBAAA;IACV,MAAM,MAAA,IAAA;IACN,UAAU,QAAA;IACV,OAAO,QAAA;IACP,SAAS,QAAA;IACF;IACA;;;;;;;;;GAEV,CAAA,MAAA,UAAA,GAAA,YAUE,aAAA;;IARS,YAAA,MAAA;IAAA,uBAAA,OAAA,OAAA,OAAA,MAAA,WAAA,MAAK,QAAA;IACb,OAAO,QAAA;IACP,UAAU,iBAAA;IACV,MAAM,MAAA,IAAA;IACN,UAAU,QAAA;IACV,SAAS,QAAA;IACF;IACA;;;;;;;;GAGV,CAAA,IAAA,YAKa,YAAA;IALD,MAAK;IAAO,MAAK;;IAC3B,SAAA,cAEY,CAFK,QAAA,aAAjB,UAAA,GAAA,YAEY,WAAA,EAAA,KAAA,EAAA,GAAA,EADV,UAAA,GAAA,YAA8C,wBAAjB,YAAW,CAAA,GAAA,EAA5B,KAAK,MAAA,MAAK,CAAA,EAAA,GAAA,IAExB,MAAA,UAAA,GAAA,YAAqD,wBAAjB,YAAW,CAAA,GAAA,EAA5B,KAAK,MAAA,MAAK,CAAA,EAAA,CAAA"}
1
+ {"version":3,"file":"tabs.js","names":["_useSlots","_useModel","UScroll","_openBlock","_createElementBlock","_normalizeClass","_unref","_createBlock","UTabsHorizontal","UTabsVertical","_createVNode","_Transition","_withCtx","_KeepAlive","_resolveDynamicComponent"],"sources":["../../../src/components/tabs/tabs.vue"],"sourcesContent":["<template>\n <div :class=\"[cls.b, cls.m(position!)]\">\n <u-tabs-horizontal\n v-if=\"isHorizontal\"\n v-model=\"model\"\n :items=\"items\"\n :position=\"horizontalPosition\"\n :size=\"size\"\n :closable=\"closable\"\n :block=\"block\"\n :rounded=\"rounded\"\n @click=\"onClick\"\n @close=\"onClose\"\n />\n <u-tabs-vertical\n v-else\n v-model=\"model\"\n :items=\"items\"\n :position=\"verticalPosition\"\n :size=\"size\"\n :closable=\"closable\"\n :rounded=\"rounded\"\n @click=\"onClick\"\n @close=\"onClose\"\n />\n\n <transition name=\"fade\" mode=\"out-in\">\n <KeepAlive v-if=\"keepAlive\">\n <component :key=\"model\" :is=\"renderSlots()\" />\n </KeepAlive>\n <component v-else :key=\"model\" :is=\"renderSlots()\" />\n </transition>\n </div>\n</template>\n\n<script lang=\"ts\" setup>\nimport { useFallbackProps } from '@veltra/compositions'\nimport { bem } from '@veltra/utils'\nimport { computed, createVNode } from 'vue'\n\nimport type { ComponentSize, TabItem, TabsEmits, TabsProps } from '../../types'\nimport { UScroll } from '../scroll'\nimport UTabsHorizontal from './tabs-horizontal.vue'\nimport UTabsVertical from './tabs-vertical.vue'\n\ndefineOptions({ name: 'UTabs' })\n\nconst props = withDefaults(defineProps<TabsProps>(), {\n position: 'top',\n closable: false,\n block: false,\n rounded: false,\n keepAlive: false\n})\n\nconst emit = defineEmits<TabsEmits>()\n\nconst slots = defineSlots<Record<string, (props: any) => any>>()\n\nconst { size } = useFallbackProps([props], { size: 'default' as ComponentSize })\n\nconst cls = bem('tabs')\n\nconst model = defineModel<string>()\n\nconst isHorizontal = computed(() => props.position === 'top' || props.position === 'bottom')\n\n/** 避免模板中使用类型断言:收敛 position 到水平 / 垂直子组件所需的子集。 */\nconst horizontalPosition = computed<'top' | 'bottom'>(() =>\n props.position === 'bottom' ? 'bottom' : 'top'\n)\n\nconst verticalPosition = computed<'left' | 'right'>(() =>\n props.position === 'right' ? 'right' : 'left'\n)\n\nconst onClick = (item: TabItem, index: number) => emit('click', item, index)\nconst onClose = (item: TabItem, index: number) => emit('close', item, index)\n\nconst renderSlots = () => {\n const key = model.value\n if (!key) return null\n const nodes = slots[key]?.({ key })\n if (Array.isArray(nodes)) {\n return createVNode(UScroll, { class: cls.e('content') }, { default: () => nodes })\n }\n return nodes\n}\n</script>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA+CA,MAAM,QAAQ;EAQd,MAAM,OAAO;EAEb,MAAM,QAAQA,SAAA;EAEd,MAAM,EAAE,SAAS,iBAAiB,CAAC,KAAK,GAAG,EAAE,MAAM,UAA2B,CAAC;EAE/E,MAAM,MAAM,IAAI,MAAM;EAEtB,MAAM,QAAQC,SAAmB,SAAA,YAAC;EAElC,MAAM,eAAe,eAAe,MAAM,aAAa,SAAS,MAAM,aAAa,QAAQ;;EAG3F,MAAM,qBAAqB,eACzB,MAAM,aAAa,WAAW,WAAW,KAC3C;EAEA,MAAM,mBAAmB,eACvB,MAAM,aAAa,UAAU,UAAU,MACzC;EAEA,MAAM,WAAW,MAAe,UAAkB,KAAK,SAAS,MAAM,KAAK;EAC3E,MAAM,WAAW,MAAe,UAAkB,KAAK,SAAS,MAAM,KAAK;EAE3E,MAAM,oBAAoB;GACxB,MAAM,MAAM,MAAM;GAClB,IAAI,CAAC,KAAK,OAAO;GACjB,MAAM,QAAQ,MAAM,IAAI,GAAG,EAAE,IAAI,CAAC;GAClC,IAAI,MAAM,QAAQ,KAAK,GACrB,OAAO,YAAYC,aAAS,EAAE,OAAO,IAAI,EAAE,SAAS,EAAE,GAAG,EAAE,eAAe,MAAM,CAAC;GAEnF,OAAO;EACT;;GAtFE,OAAAC,UAAA,GAAAC,mBA+BM,OAAA,EA/BA,OAAKC,eAAA,CAAGC,MAAA,GAAA,CAAG,CAAC,GAAGA,MAAA,GAAA,CAAG,CAAC,EAAE,QAAA,QAAQ,CAAA,CAAA,EAAA,GAEzB,CAAA,aAAA,SADRH,UAAA,GAAAI,YAWEC,aAAA;;IATS,YAAA,MAAA;IAAA,uBAAA,OAAA,OAAA,OAAA,MAAA,WAAA,MAAK,QAAA;IACb,OAAO,QAAA;IACP,UAAU,mBAAA;IACV,MAAMF,MAAA,IAAA;IACN,UAAU,QAAA;IACV,OAAO,QAAA;IACP,SAAS,QAAA;IACF;IACA;;;;;;;;;GAEV,CAAA,MAAAH,UAAA,GAAAI,YAUEE,aAAA;;IARS,YAAA,MAAA;IAAA,uBAAA,OAAA,OAAA,OAAA,MAAA,WAAA,MAAK,QAAA;IACb,OAAO,QAAA;IACP,UAAU,iBAAA;IACV,MAAMH,MAAA,IAAA;IACN,UAAU,QAAA;IACV,SAAS,QAAA;IACF;IACA;;;;;;;;GAGV,CAAA,IAAAI,YAKaC,YAAA;IALD,MAAK;IAAO,MAAK;;IAC3B,SAAAC,cAEY,CAFK,QAAA,aAAjBT,UAAA,GAAAI,YAEYM,WAAA,EAAA,KAAA,EAAA,GAAA,EADVV,UAAA,GAAAI,YAA8CO,wBAAjB,YAAW,CAAA,GAAA,EAA5B,KAAK,MAAA,MAAK,CAAA,EAAA,GAAA,IAExB,MAAAX,UAAA,GAAAI,YAAqDO,wBAAjB,YAAW,CAAA,GAAA,EAA5B,KAAK,MAAA,MAAK,CAAA,EAAA,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"tag.js","names":[],"sources":["../../../src/components/tag/tag.vue"],"sourcesContent":["<template>\n <span :class=\"className\">\n <span :class=\"cls.e('content')\">\n <slot />\n </span>\n\n <u-icon v-if=\"closable\" @click.stop=\"handleClose\" :class=\"cls.e('icon-close')\">\n <Close />\n </u-icon>\n </span>\n</template>\n\n<script lang=\"ts\" setup>\nimport { useFormFallbackProps } from '@veltra/compositions'\nimport { Close } from '@veltra/icons/normal'\nimport { bem } from '@veltra/utils'\nimport { injectFormContext } from '@veltra/utils'\nimport { computed } from 'vue'\n\nimport type { TagEmits, TagProps } from '../../types'\nimport { UIcon } from '../icon'\n\ndefineOptions({ name: 'UTag' })\n\nconst cls = bem('tag')\n\nconst props = defineProps<TagProps>()\n\nconst emit = defineEmits<TagEmits>()\n\nconst { formProps } = injectFormContext()\nconst { size } = useFormFallbackProps([formProps ?? {}, props], { size: 'default' })\n\nconst handleClose = () => {\n emit('close')\n}\n\nconst className = computed(() => {\n const { type } = props\n return [\n cls.b,\n cls.m(size.value),\n type && cls.m('color-' + type),\n bem.is('round', props.round),\n bem.is('dark', props.dark)\n ]\n})\n\n// const classRound = computed(() => {\n// return [bem.is('round', props.round)]\n// })\n</script>\n"],"mappings":";;;;;;;;;;;;;;;;;;EAwBA,MAAM,MAAM,IAAI,KAAK;EAErB,MAAM,QAAQ;EAEd,MAAM,OAAO;EAEb,MAAM,EAAE,cAAc,kBAAkB;EACxC,MAAM,EAAE,SAAS,qBAAqB,CAAC,aAAa,CAAC,GAAG,KAAK,GAAG,EAAE,MAAM,UAAU,CAAC;EAEnF,MAAM,oBAAoB;GACxB,KAAK,OAAO;EACd;EAEA,MAAM,YAAY,eAAe;GAC/B,MAAM,EAAE,SAAS;GACjB,OAAO;IACL,IAAI;IACJ,IAAI,EAAE,KAAK,KAAK;IAChB,QAAQ,IAAI,EAAE,WAAW,IAAI;IAC7B,IAAI,GAAG,SAAS,MAAM,KAAK;IAC3B,IAAI,GAAG,QAAQ,MAAM,IAAI;GAC3B;EACF,CAAC;;GA7CC,OAAA,UAAA,GAAA,mBAQO,QAAA,EARA,OAAK,eAAE,UAAA,KAAS,EAAA,GACrB,CAAA,mBAEO,QAAA,EAFA,OAAK,eAAE,MAAA,GAAA,CAAG,CAAC,EAAC,SAAA,CAAA,EAAA,GACjB,CAAA,WAAQ,KAAA,QAAA,SAAA,CAAA,GAAA,CAGI,GAAA,QAAA,YAAd,UAAA,GAAA,YAES,MAAA,WAAA,GAAA;;IAFgB,SAAK,cAAO,aAAW,CAAA,MAAA,CAAA;IAAG,OAAK,eAAE,MAAA,GAAA,CAAG,CAAC,EAAC,YAAA,CAAA;;IAC7D,SAAA,cAAS,CAAT,YAAS,MAAA,KAAA,CAAA,CAAA,CAAA"}
1
+ {"version":3,"file":"tag.js","names":["_openBlock","_createElementBlock","_normalizeClass","_createElementVNode","_unref","_renderSlot","_createBlock","UIcon","_withModifiers","_withCtx","_createVNode","_createCommentVNode"],"sources":["../../../src/components/tag/tag.vue"],"sourcesContent":["<template>\n <span :class=\"className\">\n <span :class=\"cls.e('content')\">\n <slot />\n </span>\n\n <u-icon v-if=\"closable\" @click.stop=\"handleClose\" :class=\"cls.e('icon-close')\">\n <Close />\n </u-icon>\n </span>\n</template>\n\n<script lang=\"ts\" setup>\nimport { useFormFallbackProps } from '@veltra/compositions'\nimport { Close } from '@veltra/icons/normal'\nimport { bem } from '@veltra/utils'\nimport { injectFormContext } from '@veltra/utils'\nimport { computed } from 'vue'\n\nimport type { TagEmits, TagProps } from '../../types'\nimport { UIcon } from '../icon'\n\ndefineOptions({ name: 'UTag' })\n\nconst cls = bem('tag')\n\nconst props = defineProps<TagProps>()\n\nconst emit = defineEmits<TagEmits>()\n\nconst { formProps } = injectFormContext()\nconst { size } = useFormFallbackProps([formProps ?? {}, props], { size: 'default' })\n\nconst handleClose = () => {\n emit('close')\n}\n\nconst className = computed(() => {\n const { type } = props\n return [\n cls.b,\n cls.m(size.value),\n type && cls.m('color-' + type),\n bem.is('round', props.round),\n bem.is('dark', props.dark)\n ]\n})\n\n// const classRound = computed(() => {\n// return [bem.is('round', props.round)]\n// })\n</script>\n"],"mappings":";;;;;;;;;;;;;;;;;;EAwBA,MAAM,MAAM,IAAI,KAAK;EAErB,MAAM,QAAQ;EAEd,MAAM,OAAO;EAEb,MAAM,EAAE,cAAc,kBAAkB;EACxC,MAAM,EAAE,SAAS,qBAAqB,CAAC,aAAa,CAAC,GAAG,KAAK,GAAG,EAAE,MAAM,UAAU,CAAC;EAEnF,MAAM,oBAAoB;GACxB,KAAK,OAAO;EACd;EAEA,MAAM,YAAY,eAAe;GAC/B,MAAM,EAAE,SAAS;GACjB,OAAO;IACL,IAAI;IACJ,IAAI,EAAE,KAAK,KAAK;IAChB,QAAQ,IAAI,EAAE,WAAW,IAAI;IAC7B,IAAI,GAAG,SAAS,MAAM,KAAK;IAC3B,IAAI,GAAG,QAAQ,MAAM,IAAI;GAC3B;EACF,CAAC;;GA7CC,OAAAA,UAAA,GAAAC,mBAQO,QAAA,EARA,OAAKC,eAAE,UAAA,KAAS,EAAA,GACrB,CAAAC,mBAEO,QAAA,EAFA,OAAKD,eAAEE,MAAA,GAAA,CAAG,CAAC,EAAC,SAAA,CAAA,EAAA,GACjB,CAAAC,WAAQ,KAAA,QAAA,SAAA,CAAA,GAAA,CAGI,GAAA,QAAA,YAAdL,UAAA,GAAAM,YAESF,MAAAG,WAAA,GAAA;;IAFgB,SAAKC,cAAO,aAAW,CAAA,MAAA,CAAA;IAAG,OAAKN,eAAEE,MAAA,GAAA,CAAG,CAAC,EAAC,YAAA,CAAA;;IAC7D,SAAAK,cAAS,CAATC,YAASN,MAAA,KAAA,CAAA,CAAA,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"text.js","names":[],"sources":["../../../src/components/text/text.vue"],"sourcesContent":["<template>\n <p :class=\"classList\" :style=\"style\">\n <UNodeRender :content=\"getTextVNode()\" ref=\"aa\" />\n </p>\n</template>\n\n<script lang=\"ts\" setup>\nimport { bem, withUnit, isTextNode, getHighlightChunks } from '@veltra/utils'\nimport { type CSSProperties, type VNode, computed, useSlots, h, createTextVNode } from 'vue'\n\nimport type { TextProps } from '../../types'\nimport { UNodeRender } from '../node-render'\n\ndefineOptions({ name: 'UText' })\n\nconst props = withDefaults(defineProps<TextProps>(), { as: 'content' })\n\nconst cls = bem('text')\n\nconst classList = computed(() => {\n return [cls.b, bem.is(props.as), bem.is('bold', props.bold), bem.is('italic', props.italic)]\n})\n\nconst style = computed(() => {\n const style: CSSProperties = { fontSize: withUnit(props.fontSize, 'px') }\n const { deleted, underline } = props\n if (deleted) {\n style.textDecoration = 'line-through'\n }\n if (underline) {\n style.textDecoration = 'underline'\n }\n\n return style\n})\n\nconst slots = useSlots()\nconst getTextVNode = () => {\n const nodes = slots.default?.()\n if (!nodes?.length) return undefined\n\n // 只允许渲染文本\n const textNodes = nodes.filter((node) => isTextNode(node))\n\n const { highlight } = props\n\n if (!highlight) {\n return textNodes\n }\n\n return textNodes.reduce((nodes, textNode) => {\n const chunks = getHighlightChunks(\n textNode.children as string,\n Array.isArray(highlight) ? highlight : [highlight]\n )\n\n chunks.forEach((chunk) => {\n if (chunk.highlight) {\n nodes.push(h('mark', chunk.text))\n } else {\n nodes.push(createTextVNode(chunk.text))\n }\n })\n\n return nodes\n }, [] as VNode[])\n}\n</script>\n"],"mappings":";;;;;;;;;;;;;;;;;EAeA,MAAM,QAAQ;EAEd,MAAM,MAAM,IAAI,MAAM;EAEtB,MAAM,YAAY,eAAe;GAC/B,OAAO;IAAC,IAAI;IAAG,IAAI,GAAG,MAAM,EAAE;IAAG,IAAI,GAAG,QAAQ,MAAM,IAAI;IAAG,IAAI,GAAG,UAAU,MAAM,MAAM;GAAC;EAC7F,CAAC;EAED,MAAM,QAAQ,eAAe;GAC3B,MAAM,QAAuB,EAAE,UAAU,SAAS,MAAM,UAAU,IAAI,EAAE;GACxE,MAAM,EAAE,SAAS,cAAc;GAC/B,IAAI,SACF,MAAM,iBAAiB;GAEzB,IAAI,WACF,MAAM,iBAAiB;GAGzB,OAAO;EACT,CAAC;EAED,MAAM,QAAQ,SAAS;EACvB,MAAM,qBAAqB;GACzB,MAAM,QAAQ,MAAM,UAAU;GAC9B,IAAI,CAAC,OAAO,QAAQ,OAAO,KAAA;GAG3B,MAAM,YAAY,MAAM,QAAQ,SAAS,WAAW,IAAI,CAAC;GAEzD,MAAM,EAAE,cAAc;GAEtB,IAAI,CAAC,WACH,OAAO;GAGT,OAAO,UAAU,QAAQ,OAAO,aAAa;IAM3C,mBAJE,SAAS,UACT,MAAM,QAAQ,SAAS,IAAI,YAAY,CAAC,SAAS,CAGnD,CAAA,CAAO,SAAS,UAAU;KACxB,IAAI,MAAM,WACR,MAAM,KAAK,EAAE,QAAQ,MAAM,IAAI,CAAC;UAEhC,MAAM,KAAK,gBAAgB,MAAM,IAAI,CAAC;IAE1C,CAAC;IAED,OAAO;GACT,GAAG,CAAC,CAAY;EAClB;;GAjEE,OAAA,UAAA,GAAA,mBAEI,KAAA;IAFA,OAAK,eAAE,UAAA,KAAS;IAAG,OAAK,eAAE,MAAA,KAAK;GACjC,GAAA,CAAA,YAAkD,MAAA,UAAA,GAAA;IAApC,SAAS,aAAY;IAAI,KAAI"}
1
+ {"version":3,"file":"text.js","names":["_openBlock","_createElementBlock","_normalizeClass","_normalizeStyle","_createVNode","_unref","UNodeRender"],"sources":["../../../src/components/text/text.vue"],"sourcesContent":["<template>\n <p :class=\"classList\" :style=\"style\">\n <UNodeRender :content=\"getTextVNode()\" ref=\"aa\" />\n </p>\n</template>\n\n<script lang=\"ts\" setup>\nimport { bem, withUnit, isTextNode, getHighlightChunks } from '@veltra/utils'\nimport { type CSSProperties, type VNode, computed, useSlots, h, createTextVNode } from 'vue'\n\nimport type { TextProps } from '../../types'\nimport { UNodeRender } from '../node-render'\n\ndefineOptions({ name: 'UText' })\n\nconst props = withDefaults(defineProps<TextProps>(), { as: 'content' })\n\nconst cls = bem('text')\n\nconst classList = computed(() => {\n return [cls.b, bem.is(props.as), bem.is('bold', props.bold), bem.is('italic', props.italic)]\n})\n\nconst style = computed(() => {\n const style: CSSProperties = { fontSize: withUnit(props.fontSize, 'px') }\n const { deleted, underline } = props\n if (deleted) {\n style.textDecoration = 'line-through'\n }\n if (underline) {\n style.textDecoration = 'underline'\n }\n\n return style\n})\n\nconst slots = useSlots()\nconst getTextVNode = () => {\n const nodes = slots.default?.()\n if (!nodes?.length) return undefined\n\n // 只允许渲染文本\n const textNodes = nodes.filter((node) => isTextNode(node))\n\n const { highlight } = props\n\n if (!highlight) {\n return textNodes\n }\n\n return textNodes.reduce((nodes, textNode) => {\n const chunks = getHighlightChunks(\n textNode.children as string,\n Array.isArray(highlight) ? highlight : [highlight]\n )\n\n chunks.forEach((chunk) => {\n if (chunk.highlight) {\n nodes.push(h('mark', chunk.text))\n } else {\n nodes.push(createTextVNode(chunk.text))\n }\n })\n\n return nodes\n }, [] as VNode[])\n}\n</script>\n"],"mappings":";;;;;;;;;;;;;;;;;EAeA,MAAM,QAAQ;EAEd,MAAM,MAAM,IAAI,MAAM;EAEtB,MAAM,YAAY,eAAe;GAC/B,OAAO;IAAC,IAAI;IAAG,IAAI,GAAG,MAAM,EAAE;IAAG,IAAI,GAAG,QAAQ,MAAM,IAAI;IAAG,IAAI,GAAG,UAAU,MAAM,MAAM;GAAC;EAC7F,CAAC;EAED,MAAM,QAAQ,eAAe;GAC3B,MAAM,QAAuB,EAAE,UAAU,SAAS,MAAM,UAAU,IAAI,EAAE;GACxE,MAAM,EAAE,SAAS,cAAc;GAC/B,IAAI,SACF,MAAM,iBAAiB;GAEzB,IAAI,WACF,MAAM,iBAAiB;GAGzB,OAAO;EACT,CAAC;EAED,MAAM,QAAQ,SAAS;EACvB,MAAM,qBAAqB;GACzB,MAAM,QAAQ,MAAM,UAAU;GAC9B,IAAI,CAAC,OAAO,QAAQ,OAAO,KAAA;GAG3B,MAAM,YAAY,MAAM,QAAQ,SAAS,WAAW,IAAI,CAAC;GAEzD,MAAM,EAAE,cAAc;GAEtB,IAAI,CAAC,WACH,OAAO;GAGT,OAAO,UAAU,QAAQ,OAAO,aAAa;IAM3C,mBAJE,SAAS,UACT,MAAM,QAAQ,SAAS,IAAI,YAAY,CAAC,SAAS,CAGnD,CAAA,CAAO,SAAS,UAAU;KACxB,IAAI,MAAM,WACR,MAAM,KAAK,EAAE,QAAQ,MAAM,IAAI,CAAC;UAEhC,MAAM,KAAK,gBAAgB,MAAM,IAAI,CAAC;IAE1C,CAAC;IAED,OAAO;GACT,GAAG,CAAC,CAAY;EAClB;;GAjEE,OAAAA,UAAA,GAAAC,mBAEI,KAAA;IAFA,OAAKC,eAAE,UAAA,KAAS;IAAG,OAAKC,eAAE,MAAA,KAAK;GACjC,GAAA,CAAAC,YAAkDC,MAAAC,UAAA,GAAA;IAApC,SAAS,aAAY;IAAI,KAAI"}
@@ -1 +1 @@
1
- {"version":3,"file":"textarea.js","names":[],"sources":["../../../src/components/textarea/textarea.vue"],"sourcesContent":["<template>\n <div\n v-if=\"!readonly\"\n :class=\"textareaClass\"\n @mouseenter=\"hovered = true\"\n @mouseleave=\"hovered = false\"\n >\n <textarea\n :class=\"cls.e('native')\"\n :placeholder=\"placeholder\"\n v-model=\"model\"\n :maxlength=\"maxlength\"\n :rows=\"rows\"\n :cols=\"cols\"\n @input=\"handleInput\"\n @focus=\"handleFocus\"\n @blur=\"handleBlur\"\n @change=\"handleChange\"\n :disabled=\"disabled\"\n :readonly=\"nativeReadonly\"\n ref=\"textareaRef\"\n />\n <span v-if=\"props.maxlength && props.showCount\" :class=\"cls.m('count')\">\n {{ initNum }}/{{ props.maxlength }}\n </span>\n <Transition name=\"zoom-in\" mode=\"out-in\">\n <u-icon\n v-if=\"props.clearable && model! && hovered && !disabled && !readonly\"\n :class=\"cls.m('clear')\"\n @click.stop=\"handleClear\"\n >\n <Close />\n </u-icon>\n </Transition>\n </div>\n\n <span v-else style=\"white-space: pre-wrap\">\n {{ model || FORM_EMPTY_CONTENT }}\n </span>\n</template>\n\n<script lang=\"ts\" 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, ref, shallowRef, watch } from 'vue'\n\nimport type { TextareaProps, TextareaEmits, ComponentSize } from '../../types'\nimport { UIcon } from '../icon'\nimport { calcTextareaHeight } from './utils'\n\ndefineOptions({ name: 'UTextarea' })\n\nconst props = withDefaults(defineProps<TextareaProps>(), {\n placeholder: '请输入',\n resize: true,\n clearable: true,\n disabled: undefined,\n readonly: undefined,\n autosize: false\n})\n\nconst cls = bem('textarea')\n\nconst { formProps } = injectFormContext()\n\nconst { size, disabled, readonly } = useFormFallbackProps([formProps ?? {}, props], {\n size: 'default' as ComponentSize,\n disabled: false,\n readonly: false\n})\n\nconst emit = defineEmits<TextareaEmits>()\n\nconst textareaRef = ref<HTMLTextAreaElement | null>(null)\n\nconst model = defineModel<string>()\n\nconst hovered = shallowRef(false)\n\nconst { focus, handleBlur, handleFocus } = useFocus((focused) => {\n focused ? emit('focus') : emit('blur')\n})\n\nconst textareaClass = computed(() => {\n return [\n cls.b,\n cls.m(size.value),\n bem.is('resize-none', !props.resize),\n bem.is('disabled', disabled.value),\n bem.is('readonly', readonly.value),\n bem.is('focus', focus.value),\n cls.m('more')\n ]\n})\n\nconst handleInput = (e: Event) => {\n const value = (e.target as HTMLTextAreaElement).value\n if (value.length > props.maxlength!) {\n // 如果输入的字符数超过了最大长度,截取字符串到最大长度\n const truncatedValue = value.slice(0, props.maxlength)\n emit('update:modelValue', truncatedValue)\n } else {\n // 如果没有超过最大长度,则正常更新模型值\n emit('update:modelValue', value)\n }\n}\n\nconst initNum = computed(() => {\n if (!props.maxlength) return 0\n return props.maxlength - (model.value?.length ?? 0)\n})\n\nconst handleClear = () => {\n model.value = ''\n emit('clear')\n}\n\nconst handleChange = (e: Event) => {\n emit('change', (e.target as HTMLTextAreaElement).value)\n}\n\nwatch(\n [model, textareaRef],\n ([model, textareaRef]) => {\n if (!textareaRef) return\n if (!props.autosize) return\n calcTextareaHeight(textareaRef)\n },\n { immediate: true }\n)\n</script>\n"],"mappings":"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"}
1
+ {"version":3,"file":"textarea.js","names":["_useModel","_unref","_openBlock","_createElementBlock","_normalizeClass","_withDirectives","_createElementVNode","_vModelText","_toDisplayString","_createCommentVNode","_createVNode","_Transition","_withCtx","_createBlock","UIcon","_withModifiers"],"sources":["../../../src/components/textarea/textarea.vue"],"sourcesContent":["<template>\n <div\n v-if=\"!readonly\"\n :class=\"textareaClass\"\n @mouseenter=\"hovered = true\"\n @mouseleave=\"hovered = false\"\n >\n <textarea\n :class=\"cls.e('native')\"\n :placeholder=\"placeholder\"\n v-model=\"model\"\n :maxlength=\"maxlength\"\n :rows=\"rows\"\n :cols=\"cols\"\n @input=\"handleInput\"\n @focus=\"handleFocus\"\n @blur=\"handleBlur\"\n @change=\"handleChange\"\n :disabled=\"disabled\"\n :readonly=\"nativeReadonly\"\n ref=\"textareaRef\"\n />\n <span v-if=\"props.maxlength && props.showCount\" :class=\"cls.m('count')\">\n {{ initNum }}/{{ props.maxlength }}\n </span>\n <Transition name=\"zoom-in\" mode=\"out-in\">\n <u-icon\n v-if=\"props.clearable && model! && hovered && !disabled && !readonly\"\n :class=\"cls.m('clear')\"\n @click.stop=\"handleClear\"\n >\n <Close />\n </u-icon>\n </Transition>\n </div>\n\n <span v-else style=\"white-space: pre-wrap\">\n {{ model || FORM_EMPTY_CONTENT }}\n </span>\n</template>\n\n<script lang=\"ts\" 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, ref, shallowRef, watch } from 'vue'\n\nimport type { TextareaProps, TextareaEmits, ComponentSize } from '../../types'\nimport { UIcon } from '../icon'\nimport { calcTextareaHeight } from './utils'\n\ndefineOptions({ name: 'UTextarea' })\n\nconst props = withDefaults(defineProps<TextareaProps>(), {\n placeholder: '请输入',\n resize: true,\n clearable: true,\n disabled: undefined,\n readonly: undefined,\n autosize: false\n})\n\nconst cls = bem('textarea')\n\nconst { formProps } = injectFormContext()\n\nconst { size, disabled, readonly } = useFormFallbackProps([formProps ?? {}, props], {\n size: 'default' as ComponentSize,\n disabled: false,\n readonly: false\n})\n\nconst emit = defineEmits<TextareaEmits>()\n\nconst textareaRef = ref<HTMLTextAreaElement | null>(null)\n\nconst model = defineModel<string>()\n\nconst hovered = shallowRef(false)\n\nconst { focus, handleBlur, handleFocus } = useFocus((focused) => {\n focused ? emit('focus') : emit('blur')\n})\n\nconst textareaClass = computed(() => {\n return [\n cls.b,\n cls.m(size.value),\n bem.is('resize-none', !props.resize),\n bem.is('disabled', disabled.value),\n bem.is('readonly', readonly.value),\n bem.is('focus', focus.value),\n cls.m('more')\n ]\n})\n\nconst handleInput = (e: Event) => {\n const value = (e.target as HTMLTextAreaElement).value\n if (value.length > props.maxlength!) {\n // 如果输入的字符数超过了最大长度,截取字符串到最大长度\n const truncatedValue = value.slice(0, props.maxlength)\n emit('update:modelValue', truncatedValue)\n } else {\n // 如果没有超过最大长度,则正常更新模型值\n emit('update:modelValue', value)\n }\n}\n\nconst initNum = computed(() => {\n if (!props.maxlength) return 0\n return props.maxlength - (model.value?.length ?? 0)\n})\n\nconst handleClear = () => {\n model.value = ''\n emit('clear')\n}\n\nconst handleChange = (e: Event) => {\n emit('change', (e.target as HTMLTextAreaElement).value)\n}\n\nwatch(\n [model, textareaRef],\n ([model, textareaRef]) => {\n if (!textareaRef) return\n if (!props.autosize) return\n calcTextareaHeight(textareaRef)\n },\n { immediate: true }\n)\n</script>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAsDA,MAAM,QAAQ;EASd,MAAM,MAAM,IAAI,UAAU;EAE1B,MAAM,EAAE,cAAc,kBAAkB;EAExC,MAAM,EAAE,MAAM,UAAU,aAAa,qBAAqB,CAAC,aAAa,CAAC,GAAG,KAAK,GAAG;GAClF,MAAM;GACN,UAAU;GACV,UAAU;EACZ,CAAC;EAED,MAAM,OAAO;EAEb,MAAM,cAAc,IAAgC,IAAI;EAExD,MAAM,QAAQA,SAAmB,SAAA,YAAC;EAElC,MAAM,UAAU,WAAW,KAAK;EAEhC,MAAM,EAAE,OAAO,YAAY,gBAAgB,UAAU,YAAY;GAC/D,UAAU,KAAK,OAAO,IAAI,KAAK,MAAM;EACvC,CAAC;EAED,MAAM,gBAAgB,eAAe;GACnC,OAAO;IACL,IAAI;IACJ,IAAI,EAAE,KAAK,KAAK;IAChB,IAAI,GAAG,eAAe,CAAC,MAAM,MAAM;IACnC,IAAI,GAAG,YAAY,SAAS,KAAK;IACjC,IAAI,GAAG,YAAY,SAAS,KAAK;IACjC,IAAI,GAAG,SAAS,MAAM,KAAK;IAC3B,IAAI,EAAE,MAAM;GACd;EACF,CAAC;EAED,MAAM,eAAe,MAAa;GAChC,MAAM,QAAS,EAAE,OAA+B;GAChD,IAAI,MAAM,SAAS,MAAM,WAAY;IAEnC,MAAM,iBAAiB,MAAM,MAAM,GAAG,MAAM,SAAS;IACrD,KAAK,qBAAqB,cAAc;GAC1C,OAEE,KAAK,qBAAqB,KAAK;EAEnC;EAEA,MAAM,UAAU,eAAe;GAC7B,IAAI,CAAC,MAAM,WAAW,OAAO;GAC7B,OAAO,MAAM,aAAa,MAAM,OAAO,UAAU;EACnD,CAAC;EAED,MAAM,oBAAoB;GACxB,MAAM,QAAQ;GACd,KAAK,OAAO;EACd;EAEA,MAAM,gBAAgB,MAAa;GACjC,KAAK,UAAW,EAAE,OAA+B,KAAK;EACxD;EAEA,MACE,CAAC,OAAO,WAAW,IAClB,CAAC,OAAO,iBAAiB;GACxB,IAAI,CAAC,aAAa;GAClB,IAAI,CAAC,MAAM,UAAU;GACrB,mBAAmB,WAAW;EAChC,GACA,EAAE,WAAW,KAAK,CACpB;;GAjIW,OAAA,CAAAC,MAAA,QAAA,KADTC,UAAA,GAAAC,mBAiCM,OAAA;;IA/BH,OAAKC,eAAE,cAAA,KAAa;IACpB,cAAU,OAAA,OAAA,OAAA,MAAA,WAAE,QAAA,QAAO;IACnB,cAAU,OAAA,OAAA,OAAA,MAAA,WAAE,QAAA,QAAO;;IAEpBC,eAAAC,mBAcE,YAAA;KAbC,OAAKF,eAAEH,MAAA,GAAA,CAAG,CAAC,EAAC,QAAA,CAAA;KACZ,aAAa,QAAA;KACL,uBAAA,OAAA,OAAA,OAAA,MAAA,WAAA,MAAK,QAAA;KACb,WAAW,QAAA;KACX,MAAM,QAAA;KACN,MAAM,QAAA;KACN,SAAO;KACP,SAAK,OAAA,OAAA,OAAA,MAAE,GAAA,SAAAA,MAAA,WAAA,KAAAA,MAAA,WAAA,CAAA,CAAA,GAAA,IAAA;KACP,QAAI,OAAA,OAAA,OAAA,MAAE,GAAA,SAAAA,MAAA,UAAA,KAAAA,MAAA,UAAA,CAAA,CAAA,GAAA,IAAA;KACN,UAAQ;KACR,UAAUA,MAAA,QAAA;KACV,UAAU,QAAA;KACP,SAAA;KAAJ,KAAI;IAVK,GAAA,MAAA,IAAA,UAAA,GAAA,CAAA,CAAAM,YAAA,MAAA,KAAK,CAAA,CAAA;IAYJ,MAAM,aAAa,MAAM,aAArCL,UAAA,GAAAC,mBAEO,QAAA;;KAF0C,OAAKC,eAAEH,MAAA,GAAA,CAAG,CAAC,EAAC,OAAA,CAAA;IACxD,GAAAO,gBAAA,QAAA,KAAO,IAAG,MAACA,gBAAG,MAAM,SAAS,GAAA,CAAA,KAAAC,mBAAA,QAAA,IAAA;IAElCC,YAQaC,YAAA;KARD,MAAK;KAAU,MAAK;;KAC9B,SAAAC,cAMS,CALD,MAAM,aAAa,MAAA,SAAU,QAAA,SAAO,CAAKX,MAAA,QAAA,KAAQ,CAAKA,MAAA,QAAA,KAD9DC,UAAA,GAAAW,YAMSZ,MAAAa,WAAA,GAAA;;MAJN,OAAKV,eAAEH,MAAA,GAAA,CAAG,CAAC,EAAC,OAAA,CAAA;MACZ,SAAKc,cAAO,aAAW,CAAA,MAAA,CAAA;;MAExB,SAAAH,cAAS,CAATF,YAAST,MAAA,KAAA,CAAA,CAAA,CAAA;;;;;GAKf,GAAA,EAAA,MAAAC,UAAA,GAAAC,mBAEO,QAFP,YAEOK,gBADF,MAAA,SAASP,MAAA,kBAAA,CAAkB,GAAA,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"theme.js","names":[],"sources":["../../../src/components/theme/theme.vue"],"sourcesContent":["<template>\n <div :class=\"cls.b\">\n <div :class=\"cls.e('header')\">\n <div :class=\"cls.e('header-copy')\">\n <strong>主题变量配置</strong>\n </div>\n <div :class=\"cls.e('tags')\">\n <span :class=\"cls.e('tag')\">基线 {{ baselineLabel }}</span>\n <span :class=\"cls.e('tag')\">{{ changedFieldKeys.size }} 改动</span>\n </div>\n </div>\n\n <div :class=\"cls.e('toolbar')\">\n <u-input\n v-model=\"keyword\"\n :class=\"cls.e('search')\"\n placeholder=\"搜索变量名、中文标签或分组\"\n />\n\n <button\n type=\"button\"\n :class=\"[cls.e('toggle'), bem.is('active', changedOnly)]\"\n @click=\"changedOnly = !changedOnly\"\n >\n {{ changedOnly ? '查看全部' : '仅看改动' }}\n </button>\n </div>\n\n <div :class=\"cls.e('body')\">\n <div :class=\"cls.e('nav')\">\n <button\n v-for=\"section in sectionStates\"\n :key=\"section.key\"\n type=\"button\"\n :class=\"[\n cls.e('nav-item'),\n bem.is('active', activeSection === section.key),\n bem.is('disabled', !section.visibleFields.length)\n ]\"\n @click=\"activeSection = section.key\"\n >\n <span :class=\"cls.e('nav-main')\">{{ section.title }}</span>\n <span :class=\"cls.e('nav-meta')\">\n {{ section.visibleFields.length }}/{{ section.fields.length }}\n <template v-if=\"section.changedCount\"> · {{ section.changedCount }} 改动 </template>\n </span>\n </button>\n </div>\n\n <div :class=\"cls.e('panel')\">\n <div v-if=\"activeState\" :class=\"cls.e('panel-head')\">\n <div>\n <h4 :class=\"cls.e('panel-title')\">{{ activeState.title }}</h4>\n <p :class=\"cls.e('panel-desc')\">{{ activeState.description }}</p>\n </div>\n\n <div :class=\"cls.e('panel-count')\">{{ activeState.visibleFields.length }} 项</div>\n </div>\n\n <div v-if=\"activeState?.visibleFields.length\" :class=\"cls.e('list')\">\n <div\n v-for=\"field in activeState.visibleFields\"\n :key=\"field.key\"\n :class=\"[cls.e('item'), bem.is('changed', isFieldChanged(field))]\"\n >\n <div :class=\"cls.e('item-head')\">\n <div :class=\"cls.e('item-copy')\">\n <label :class=\"cls.e('item-label')\">{{ field.label }}</label>\n <div :class=\"cls.e('item-meta')\">\n <span :class=\"cls.e('item-code-label')\">Theme</span>\n <code :class=\"cls.e('item-code')\">{{ getThemePath(field.path) }}</code>\n </div>\n <div :class=\"cls.e('item-meta')\">\n <span :class=\"cls.e('item-code-label')\">CSS</span>\n <code :class=\"cls.e('item-code')\">{{ getCssVarName(field.path) }}</code>\n </div>\n </div>\n\n <span v-if=\"isFieldChanged(field)\" :class=\"cls.e('item-badge')\"> 已修改 </span>\n </div>\n\n <div v-if=\"field.kind === 'palette'\" :class=\"cls.e('palette-field')\">\n <template v-if=\"field.path[0] === 'color'\">\n <div :class=\"cls.e('palette-custom')\">\n <u-palette\n :model-value=\"String(getFieldValue(field) ?? '')\"\n @update:model-value=\"(value) => updateField(field, value)\"\n />\n <u-input\n :model-value=\"String(getFieldValue(field) ?? '')\"\n placeholder=\"例如:#1E88E5\"\n @update:model-value=\"(value) => updateField(field, value)\"\n />\n </div>\n </template>\n <template v-else>\n <div :class=\"cls.e('palette-custom')\">\n <u-palette\n :model-value=\"\n String(getFieldValue(field) ?? '').startsWith('var')\n ? ''\n : String(getFieldValue(field) ?? '')\n \"\n @update:model-value=\"(value) => updateField(field, value)\"\n />\n <u-input\n :model-value=\"String(getFieldValue(field) ?? '')\"\n placeholder=\"输入颜色或变量\"\n @update:model-value=\"(value) => updateField(field, value)\"\n />\n </div>\n <div :class=\"cls.e('palette-var')\">\n <span :class=\"cls.e('palette-var-label')\">或选择变量</span>\n <u-select\n :model-value=\"\n String(getFieldValue(field) ?? '').startsWith('var')\n ? String(getFieldValue(field) ?? '')\n : ''\n \"\n :options=\"colorVarOptions\"\n clearable\n placeholder=\"选择预设变量\"\n @update:model-value=\"(value) => updateField(field, value ?? '')\"\n >\n <template #default=\"{ option }\">\n <div style=\"display: flex; align-items: center; gap: 8px\">\n <div\n :style=\"`width: 14px; height: 14px; border-radius: 4px; background: ${option.value}`\"\n />\n <span style=\"font-size: 13px\">{{ option.label }}</span>\n </div>\n </template>\n </u-select>\n </div>\n </template>\n </div>\n\n <component\n v-else\n :is=\"getFieldComponent(field)\"\n :model-value=\"getFieldValue(field)\"\n v-bind=\"getFieldProps(field)\"\n @update:model-value=\"(value) => updateField(field, value)\"\n />\n\n <p v-if=\"field.hint || field.placeholder\" :class=\"cls.e('item-hint')\">\n {{ field.hint ?? field.placeholder }}\n </p>\n </div>\n </div>\n\n <div v-else :class=\"cls.e('empty')\">\n <strong>没有匹配项</strong>\n <p>换一个关键字,或关闭“仅看改动”后再继续筛选。</p>\n </div>\n </div>\n </div>\n\n <div :class=\"cls.e('actions')\">\n <div :class=\"cls.e('preset-group')\">\n <button type=\"button\" :class=\"cls.e('preset')\" @click=\"applyPreset('light')\">\n 浅色预设\n </button>\n <button type=\"button\" :class=\"cls.e('preset')\" @click=\"applyPreset('dark')\">\n 深色预设\n </button>\n </div>\n\n <u-button :class=\"cls.e('action-btn')\" @click=\"handleResetTheme\"> 重置 </u-button>\n <u-button :class=\"cls.e('action-btn')\" type=\"primary\" @click=\"handleExportTheme\">\n 导出\n </u-button>\n </div>\n </div>\n</template>\n\n<script lang=\"ts\" setup>\nimport {\n type Theme,\n UITheme,\n currentTheme,\n darkTheme,\n lightTheme,\n loadTheme\n} from '@veltra/styles/theme'\nimport { bem } from '@veltra/utils'\nimport { computed, shallowRef, watch, watchEffect } from 'vue'\n\nimport type { ThemeProps, _ThemeExposed } from '../../types'\nimport { UButton } from '../button'\nimport { UInput } from '../input'\nimport { UNumberInput } from '../number-input'\nimport { UPalette } from '../palette'\nimport { USelect } from '../select'\nimport { THEME_SECTIONS } from './schema'\nimport type { ThemeField } from './schema'\n\ndefineOptions({ name: 'UTheme' })\n\nconst props = defineProps<ThemeProps>()\n\nconst cls = bem('theme')\n\nconst keyword = shallowRef('')\nconst changedOnly = shallowRef(false)\nconst activeSection = shallowRef(THEME_SECTIONS[0]!.key)\n\nconst colorVarOptions = computed(() => {\n const options: { label: string; value: string }[] = []\n THEME_SECTIONS.forEach((section) => {\n section.fields.forEach((field) => {\n if (field.kind === 'palette') {\n const varName = `var(${getCssVarName(field.path)})`\n options.push({ label: `${field.label}`, value: varName })\n }\n })\n })\n return options\n})\n\nconst editorTheme = shallowRef<UITheme>()\nconst baselineTheme = shallowRef<Theme>(createThemeSnapshot(lightTheme.theme))\nconst baselineLabel = shallowRef('浅色预设')\n\nconst lightPreset = createThemeSnapshot(lightTheme.theme)\nconst darkPreset = createThemeSnapshot(darkTheme.theme)\n\nconst sourceTheme = computed(() => {\n return props.theme ?? currentTheme.value ?? lightTheme\n})\n\nwatch(\n sourceTheme,\n (theme) => {\n if (!props.theme && theme === editorTheme.value) return\n\n const nextTheme = props.theme\n ? theme\n : new UITheme(createThemeSnapshot(theme.theme), { series: theme.series })\n\n editorTheme.value = nextTheme\n baselineTheme.value = createThemeSnapshot(nextTheme.theme)\n baselineLabel.value =\n theme === darkTheme\n ? '深色预设'\n : theme === lightTheme\n ? '浅色预设'\n : props.theme\n ? '外部主题'\n : '当前主题'\n\n if (!props.theme && currentTheme.value !== nextTheme) {\n loadTheme(nextTheme)\n }\n },\n { immediate: true }\n)\n\nconst changedFieldKeys = computed(() => {\n const keys = new Set<string>()\n\n THEME_SECTIONS.forEach((section) => {\n section.fields.forEach((field) => {\n if (\n getByPath(editorTheme.value?.theme ?? lightTheme.theme, field.path) !==\n getByPath(baselineTheme.value, field.path)\n ) {\n keys.add(field.key)\n }\n })\n })\n\n return keys\n})\n\nconst sectionStates = computed(() => {\n const normalizedKeyword = keyword.value.trim().toLowerCase()\n\n return THEME_SECTIONS.map((section) => {\n const sectionMatched = `${section.title} ${section.description}`\n .toLowerCase()\n .includes(normalizedKeyword)\n\n const visibleFields = section.fields.filter((field) => {\n const matchesKeyword =\n !normalizedKeyword ||\n sectionMatched ||\n `${field.label} ${field.key} ${getThemePath(field.path)} ${getCssVarName(field.path)}`\n .toLowerCase()\n .includes(normalizedKeyword)\n\n if (!matchesKeyword) return false\n\n if (changedOnly.value && !changedFieldKeys.value.has(field.key)) {\n return false\n }\n\n return true\n })\n\n const changedCount = section.fields.filter((field) => {\n return changedFieldKeys.value.has(field.key)\n }).length\n\n return { ...section, visibleFields, changedCount }\n })\n})\n\nwatchEffect(() => {\n const current = sectionStates.value.find((section) => {\n return section.key === activeSection.value && section.visibleFields.length\n })\n\n if (current) return\n\n activeSection.value =\n sectionStates.value.find((section) => section.visibleFields.length)?.key ??\n THEME_SECTIONS[0]!.key\n})\n\nconst activeState = computed(() => {\n return (\n sectionStates.value.find((section) => section.key === activeSection.value) ??\n sectionStates.value[0]\n )\n})\n\nfunction createThemeSnapshot(theme: Theme): Theme {\n return JSON.parse(JSON.stringify(theme)) as Theme\n}\n\nfunction getByPath(source: Record<string, any>, path: string[]) {\n return path.reduce((current, key) => current?.[key], source)\n}\n\nfunction setByPath(source: Record<string, any>, path: string[], value: any) {\n let current = source\n\n path.slice(0, -1).forEach((key) => {\n current = current[key]\n })\n\n current[path[path.length - 1]!] = value\n}\n\nfunction getCssVarName(path: string[]) {\n return `--u-${path.join('-')}`\n}\n\nfunction getThemePath(path: string[]) {\n return path.reduce((expression, key) => {\n if (/^[A-Za-z_$][\\w$]*$/.test(key)) {\n return `${expression}.${key}`\n }\n\n return `${expression}['${key}']`\n }, 'theme')\n}\n\nfunction getFieldComponent(field: ThemeField) {\n switch (field.kind) {\n case 'number':\n return UNumberInput\n case 'select':\n return USelect\n default:\n return UInput\n }\n}\n\nfunction getFieldValue(field: ThemeField) {\n return getByPath(editorTheme.value?.theme ?? lightTheme.theme, field.path)\n}\n\nfunction getFieldProps(field: ThemeField) {\n switch (field.kind) {\n case 'number':\n return { min: field.min, max: field.max, step: field.step, suffix: field.suffix }\n case 'select':\n return { options: field.options, clearable: false, placeholder: '请选择' }\n case 'input':\n return { placeholder: field.placeholder }\n default:\n return {}\n }\n}\n\nfunction updateField(field: ThemeField, value: string | number | undefined) {\n if (!editorTheme.value) return\n\n const normalizedValue =\n field.kind === 'number'\n ? typeof value === 'number'\n ? value\n : Number(value || 0)\n : String(value ?? '')\n\n setByPath(editorTheme.value.theme, field.path, normalizedValue)\n editorTheme.value.render()\n}\n\nfunction isFieldChanged(field: ThemeField) {\n return changedFieldKeys.value.has(field.key)\n}\n\nfunction applySnapshot(snapshot: Theme, label?: string) {\n if (!editorTheme.value) return\n\n Object.assign(editorTheme.value.theme, createThemeSnapshot(snapshot))\n baselineTheme.value = createThemeSnapshot(editorTheme.value.theme)\n\n if (label) {\n baselineLabel.value = label\n }\n\n editorTheme.value.render()\n}\n\nfunction applyPreset(type: 'light' | 'dark') {\n if (editorTheme.value) {\n editorTheme.value.series = type\n }\n applySnapshot(\n type === 'dark' ? darkPreset : lightPreset,\n type === 'dark' ? '深色预设' : '浅色预设'\n )\n}\n\nfunction handleResetTheme() {\n if (!editorTheme.value) return\n\n Object.assign(editorTheme.value.theme, createThemeSnapshot(baselineTheme.value))\n editorTheme.value.render()\n}\n\nfunction handleExportTheme() {\n if (!editorTheme.value) return\n\n const themeConfig = JSON.stringify(createThemeSnapshot(editorTheme.value.theme), null, 2)\n const blob = new Blob([themeConfig], { type: 'application/json' })\n const url = URL.createObjectURL(blob)\n const a = document.createElement('a')\n a.href = url\n a.download = 'theme-config.json'\n a.click()\n URL.revokeObjectURL(url)\n}\n\ndefineExpose<_ThemeExposed>({\n reset: handleResetTheme,\n exportTheme: handleExportTheme,\n applyLightPreset: () => applyPreset('light'),\n applyDarkPreset: () => applyPreset('dark')\n})\n</script>\n"],"mappings":"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"}
1
+ {"version":3,"file":"theme.js","names":["UNumberInput","USelect","UInput","_openBlock","_createElementBlock","_normalizeClass","_unref","_createElementVNode","_toDisplayString","_createVNode","_Fragment","_renderList","_createTextVNode","_createCommentVNode","UPalette","_withCtx","_normalizeStyle","_createBlock","_resolveDynamicComponent","_mergeProps","UButton"],"sources":["../../../src/components/theme/theme.vue"],"sourcesContent":["<template>\n <div :class=\"cls.b\">\n <div :class=\"cls.e('header')\">\n <div :class=\"cls.e('header-copy')\">\n <strong>主题变量配置</strong>\n </div>\n <div :class=\"cls.e('tags')\">\n <span :class=\"cls.e('tag')\">基线 {{ baselineLabel }}</span>\n <span :class=\"cls.e('tag')\">{{ changedFieldKeys.size }} 改动</span>\n </div>\n </div>\n\n <div :class=\"cls.e('toolbar')\">\n <u-input\n v-model=\"keyword\"\n :class=\"cls.e('search')\"\n placeholder=\"搜索变量名、中文标签或分组\"\n />\n\n <button\n type=\"button\"\n :class=\"[cls.e('toggle'), bem.is('active', changedOnly)]\"\n @click=\"changedOnly = !changedOnly\"\n >\n {{ changedOnly ? '查看全部' : '仅看改动' }}\n </button>\n </div>\n\n <div :class=\"cls.e('body')\">\n <div :class=\"cls.e('nav')\">\n <button\n v-for=\"section in sectionStates\"\n :key=\"section.key\"\n type=\"button\"\n :class=\"[\n cls.e('nav-item'),\n bem.is('active', activeSection === section.key),\n bem.is('disabled', !section.visibleFields.length)\n ]\"\n @click=\"activeSection = section.key\"\n >\n <span :class=\"cls.e('nav-main')\">{{ section.title }}</span>\n <span :class=\"cls.e('nav-meta')\">\n {{ section.visibleFields.length }}/{{ section.fields.length }}\n <template v-if=\"section.changedCount\"> · {{ section.changedCount }} 改动 </template>\n </span>\n </button>\n </div>\n\n <div :class=\"cls.e('panel')\">\n <div v-if=\"activeState\" :class=\"cls.e('panel-head')\">\n <div>\n <h4 :class=\"cls.e('panel-title')\">{{ activeState.title }}</h4>\n <p :class=\"cls.e('panel-desc')\">{{ activeState.description }}</p>\n </div>\n\n <div :class=\"cls.e('panel-count')\">{{ activeState.visibleFields.length }} 项</div>\n </div>\n\n <div v-if=\"activeState?.visibleFields.length\" :class=\"cls.e('list')\">\n <div\n v-for=\"field in activeState.visibleFields\"\n :key=\"field.key\"\n :class=\"[cls.e('item'), bem.is('changed', isFieldChanged(field))]\"\n >\n <div :class=\"cls.e('item-head')\">\n <div :class=\"cls.e('item-copy')\">\n <label :class=\"cls.e('item-label')\">{{ field.label }}</label>\n <div :class=\"cls.e('item-meta')\">\n <span :class=\"cls.e('item-code-label')\">Theme</span>\n <code :class=\"cls.e('item-code')\">{{ getThemePath(field.path) }}</code>\n </div>\n <div :class=\"cls.e('item-meta')\">\n <span :class=\"cls.e('item-code-label')\">CSS</span>\n <code :class=\"cls.e('item-code')\">{{ getCssVarName(field.path) }}</code>\n </div>\n </div>\n\n <span v-if=\"isFieldChanged(field)\" :class=\"cls.e('item-badge')\"> 已修改 </span>\n </div>\n\n <div v-if=\"field.kind === 'palette'\" :class=\"cls.e('palette-field')\">\n <template v-if=\"field.path[0] === 'color'\">\n <div :class=\"cls.e('palette-custom')\">\n <u-palette\n :model-value=\"String(getFieldValue(field) ?? '')\"\n @update:model-value=\"(value) => updateField(field, value)\"\n />\n <u-input\n :model-value=\"String(getFieldValue(field) ?? '')\"\n placeholder=\"例如:#1E88E5\"\n @update:model-value=\"(value) => updateField(field, value)\"\n />\n </div>\n </template>\n <template v-else>\n <div :class=\"cls.e('palette-custom')\">\n <u-palette\n :model-value=\"\n String(getFieldValue(field) ?? '').startsWith('var')\n ? ''\n : String(getFieldValue(field) ?? '')\n \"\n @update:model-value=\"(value) => updateField(field, value)\"\n />\n <u-input\n :model-value=\"String(getFieldValue(field) ?? '')\"\n placeholder=\"输入颜色或变量\"\n @update:model-value=\"(value) => updateField(field, value)\"\n />\n </div>\n <div :class=\"cls.e('palette-var')\">\n <span :class=\"cls.e('palette-var-label')\">或选择变量</span>\n <u-select\n :model-value=\"\n String(getFieldValue(field) ?? '').startsWith('var')\n ? String(getFieldValue(field) ?? '')\n : ''\n \"\n :options=\"colorVarOptions\"\n clearable\n placeholder=\"选择预设变量\"\n @update:model-value=\"(value) => updateField(field, value ?? '')\"\n >\n <template #default=\"{ option }\">\n <div style=\"display: flex; align-items: center; gap: 8px\">\n <div\n :style=\"`width: 14px; height: 14px; border-radius: 4px; background: ${option.value}`\"\n />\n <span style=\"font-size: 13px\">{{ option.label }}</span>\n </div>\n </template>\n </u-select>\n </div>\n </template>\n </div>\n\n <component\n v-else\n :is=\"getFieldComponent(field)\"\n :model-value=\"getFieldValue(field)\"\n v-bind=\"getFieldProps(field)\"\n @update:model-value=\"(value) => updateField(field, value)\"\n />\n\n <p v-if=\"field.hint || field.placeholder\" :class=\"cls.e('item-hint')\">\n {{ field.hint ?? field.placeholder }}\n </p>\n </div>\n </div>\n\n <div v-else :class=\"cls.e('empty')\">\n <strong>没有匹配项</strong>\n <p>换一个关键字,或关闭“仅看改动”后再继续筛选。</p>\n </div>\n </div>\n </div>\n\n <div :class=\"cls.e('actions')\">\n <div :class=\"cls.e('preset-group')\">\n <button type=\"button\" :class=\"cls.e('preset')\" @click=\"applyPreset('light')\">\n 浅色预设\n </button>\n <button type=\"button\" :class=\"cls.e('preset')\" @click=\"applyPreset('dark')\">\n 深色预设\n </button>\n </div>\n\n <u-button :class=\"cls.e('action-btn')\" @click=\"handleResetTheme\"> 重置 </u-button>\n <u-button :class=\"cls.e('action-btn')\" type=\"primary\" @click=\"handleExportTheme\">\n 导出\n </u-button>\n </div>\n </div>\n</template>\n\n<script lang=\"ts\" setup>\nimport {\n type Theme,\n UITheme,\n currentTheme,\n darkTheme,\n lightTheme,\n loadTheme\n} from '@veltra/styles/theme'\nimport { bem } from '@veltra/utils'\nimport { computed, shallowRef, watch, watchEffect } from 'vue'\n\nimport type { ThemeProps, _ThemeExposed } from '../../types'\nimport { UButton } from '../button'\nimport { UInput } from '../input'\nimport { UNumberInput } from '../number-input'\nimport { UPalette } from '../palette'\nimport { USelect } from '../select'\nimport { THEME_SECTIONS } from './schema'\nimport type { ThemeField } from './schema'\n\ndefineOptions({ name: 'UTheme' })\n\nconst props = defineProps<ThemeProps>()\n\nconst cls = bem('theme')\n\nconst keyword = shallowRef('')\nconst changedOnly = shallowRef(false)\nconst activeSection = shallowRef(THEME_SECTIONS[0]!.key)\n\nconst colorVarOptions = computed(() => {\n const options: { label: string; value: string }[] = []\n THEME_SECTIONS.forEach((section) => {\n section.fields.forEach((field) => {\n if (field.kind === 'palette') {\n const varName = `var(${getCssVarName(field.path)})`\n options.push({ label: `${field.label}`, value: varName })\n }\n })\n })\n return options\n})\n\nconst editorTheme = shallowRef<UITheme>()\nconst baselineTheme = shallowRef<Theme>(createThemeSnapshot(lightTheme.theme))\nconst baselineLabel = shallowRef('浅色预设')\n\nconst lightPreset = createThemeSnapshot(lightTheme.theme)\nconst darkPreset = createThemeSnapshot(darkTheme.theme)\n\nconst sourceTheme = computed(() => {\n return props.theme ?? currentTheme.value ?? lightTheme\n})\n\nwatch(\n sourceTheme,\n (theme) => {\n if (!props.theme && theme === editorTheme.value) return\n\n const nextTheme = props.theme\n ? theme\n : new UITheme(createThemeSnapshot(theme.theme), { series: theme.series })\n\n editorTheme.value = nextTheme\n baselineTheme.value = createThemeSnapshot(nextTheme.theme)\n baselineLabel.value =\n theme === darkTheme\n ? '深色预设'\n : theme === lightTheme\n ? '浅色预设'\n : props.theme\n ? '外部主题'\n : '当前主题'\n\n if (!props.theme && currentTheme.value !== nextTheme) {\n loadTheme(nextTheme)\n }\n },\n { immediate: true }\n)\n\nconst changedFieldKeys = computed(() => {\n const keys = new Set<string>()\n\n THEME_SECTIONS.forEach((section) => {\n section.fields.forEach((field) => {\n if (\n getByPath(editorTheme.value?.theme ?? lightTheme.theme, field.path) !==\n getByPath(baselineTheme.value, field.path)\n ) {\n keys.add(field.key)\n }\n })\n })\n\n return keys\n})\n\nconst sectionStates = computed(() => {\n const normalizedKeyword = keyword.value.trim().toLowerCase()\n\n return THEME_SECTIONS.map((section) => {\n const sectionMatched = `${section.title} ${section.description}`\n .toLowerCase()\n .includes(normalizedKeyword)\n\n const visibleFields = section.fields.filter((field) => {\n const matchesKeyword =\n !normalizedKeyword ||\n sectionMatched ||\n `${field.label} ${field.key} ${getThemePath(field.path)} ${getCssVarName(field.path)}`\n .toLowerCase()\n .includes(normalizedKeyword)\n\n if (!matchesKeyword) return false\n\n if (changedOnly.value && !changedFieldKeys.value.has(field.key)) {\n return false\n }\n\n return true\n })\n\n const changedCount = section.fields.filter((field) => {\n return changedFieldKeys.value.has(field.key)\n }).length\n\n return { ...section, visibleFields, changedCount }\n })\n})\n\nwatchEffect(() => {\n const current = sectionStates.value.find((section) => {\n return section.key === activeSection.value && section.visibleFields.length\n })\n\n if (current) return\n\n activeSection.value =\n sectionStates.value.find((section) => section.visibleFields.length)?.key ??\n THEME_SECTIONS[0]!.key\n})\n\nconst activeState = computed(() => {\n return (\n sectionStates.value.find((section) => section.key === activeSection.value) ??\n sectionStates.value[0]\n )\n})\n\nfunction createThemeSnapshot(theme: Theme): Theme {\n return JSON.parse(JSON.stringify(theme)) as Theme\n}\n\nfunction getByPath(source: Record<string, any>, path: string[]) {\n return path.reduce((current, key) => current?.[key], source)\n}\n\nfunction setByPath(source: Record<string, any>, path: string[], value: any) {\n let current = source\n\n path.slice(0, -1).forEach((key) => {\n current = current[key]\n })\n\n current[path[path.length - 1]!] = value\n}\n\nfunction getCssVarName(path: string[]) {\n return `--u-${path.join('-')}`\n}\n\nfunction getThemePath(path: string[]) {\n return path.reduce((expression, key) => {\n if (/^[A-Za-z_$][\\w$]*$/.test(key)) {\n return `${expression}.${key}`\n }\n\n return `${expression}['${key}']`\n }, 'theme')\n}\n\nfunction getFieldComponent(field: ThemeField) {\n switch (field.kind) {\n case 'number':\n return UNumberInput\n case 'select':\n return USelect\n default:\n return UInput\n }\n}\n\nfunction getFieldValue(field: ThemeField) {\n return getByPath(editorTheme.value?.theme ?? lightTheme.theme, field.path)\n}\n\nfunction getFieldProps(field: ThemeField) {\n switch (field.kind) {\n case 'number':\n return { min: field.min, max: field.max, step: field.step, suffix: field.suffix }\n case 'select':\n return { options: field.options, clearable: false, placeholder: '请选择' }\n case 'input':\n return { placeholder: field.placeholder }\n default:\n return {}\n }\n}\n\nfunction updateField(field: ThemeField, value: string | number | undefined) {\n if (!editorTheme.value) return\n\n const normalizedValue =\n field.kind === 'number'\n ? typeof value === 'number'\n ? value\n : Number(value || 0)\n : String(value ?? '')\n\n setByPath(editorTheme.value.theme, field.path, normalizedValue)\n editorTheme.value.render()\n}\n\nfunction isFieldChanged(field: ThemeField) {\n return changedFieldKeys.value.has(field.key)\n}\n\nfunction applySnapshot(snapshot: Theme, label?: string) {\n if (!editorTheme.value) return\n\n Object.assign(editorTheme.value.theme, createThemeSnapshot(snapshot))\n baselineTheme.value = createThemeSnapshot(editorTheme.value.theme)\n\n if (label) {\n baselineLabel.value = label\n }\n\n editorTheme.value.render()\n}\n\nfunction applyPreset(type: 'light' | 'dark') {\n if (editorTheme.value) {\n editorTheme.value.series = type\n }\n applySnapshot(\n type === 'dark' ? darkPreset : lightPreset,\n type === 'dark' ? '深色预设' : '浅色预设'\n )\n}\n\nfunction handleResetTheme() {\n if (!editorTheme.value) return\n\n Object.assign(editorTheme.value.theme, createThemeSnapshot(baselineTheme.value))\n editorTheme.value.render()\n}\n\nfunction handleExportTheme() {\n if (!editorTheme.value) return\n\n const themeConfig = JSON.stringify(createThemeSnapshot(editorTheme.value.theme), null, 2)\n const blob = new Blob([themeConfig], { type: 'application/json' })\n const url = URL.createObjectURL(blob)\n const a = document.createElement('a')\n a.href = url\n a.download = 'theme-config.json'\n a.click()\n URL.revokeObjectURL(url)\n}\n\ndefineExpose<_ThemeExposed>({\n reset: handleResetTheme,\n exportTheme: handleExportTheme,\n applyLightPreset: () => applyPreset('light'),\n applyDarkPreset: () => applyPreset('dark')\n})\n</script>\n"],"mappings":"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"}