@veltra/desktop 1.1.15 → 1.1.18

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 (284) hide show
  1. package/dist/components/action/action-group.vue.d.ts +2 -2
  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/action/action.vue.d.ts +2 -2
  5. package/dist/components/action/style2.css +0 -4
  6. package/dist/components/auto-complete/auto-complete.js.map +1 -1
  7. package/dist/components/auto-complete/style.js +1 -1
  8. package/dist/components/auto-complete/use-keyboard.js.map +1 -1
  9. package/dist/components/auto-complete/use-suggestions.js.map +1 -1
  10. package/dist/components/badge/badge.js +1 -1
  11. package/dist/components/badge/badge.js.map +1 -1
  12. package/dist/components/batch-edit/batch-edit-form.js.map +1 -1
  13. package/dist/components/batch-edit/batch-edit-list.js.map +1 -1
  14. package/dist/components/batch-edit/batch-edit.js.map +1 -1
  15. package/dist/components/batch-edit/helper.js.map +1 -1
  16. package/dist/components/batch-edit/style.js +1 -1
  17. package/dist/components/batch-edit/use-edit.js.map +1 -1
  18. package/dist/components/breadcrumb/breadcrumb.js.map +1 -1
  19. package/dist/components/button/button-group.js.map +1 -1
  20. package/dist/components/button/button.js.map +1 -1
  21. package/dist/components/calendar/calendar.js.map +1 -1
  22. package/dist/components/calendar/utils.js.map +1 -1
  23. package/dist/components/card/card-action.js.map +1 -1
  24. package/dist/components/card/card-content.js.map +1 -1
  25. package/dist/components/card/card-cover.js.map +1 -1
  26. package/dist/components/card/card-header.js.map +1 -1
  27. package/dist/components/card/card.js.map +1 -1
  28. package/dist/components/cascade/cascade-panel-item.js.map +1 -1
  29. package/dist/components/cascade/cascade.js.map +1 -1
  30. package/dist/components/cascade/cascade.vue.d.ts +6 -6
  31. package/dist/components/cascade/node.js.map +1 -1
  32. package/dist/components/cascade/use-check.js.map +1 -1
  33. package/dist/components/cascade/use-data-map.js.map +1 -1
  34. package/dist/components/cascade/use-select.js +1 -1
  35. package/dist/components/cascade/use-select.js.map +1 -1
  36. package/dist/components/check-tag/check-tag.js.map +1 -1
  37. package/dist/components/checkbox/checkbox-button.js.map +1 -1
  38. package/dist/components/checkbox/checkbox-button.vue.d.ts +1 -1
  39. package/dist/components/checkbox/checkbox.js.map +1 -1
  40. package/dist/components/checkbox/style.js +1 -1
  41. package/dist/components/checkbox-group/checkbox-group.js.map +1 -1
  42. package/dist/components/code-editor/code-editor.js.map +1 -1
  43. package/dist/components/collapse/collapse-item.js.map +1 -1
  44. package/dist/components/collapse/collapse.js.map +1 -1
  45. package/dist/components/condition-editor/components/condition-group.js +138 -103
  46. package/dist/components/condition-editor/components/condition-group.js.map +1 -1
  47. package/dist/components/condition-editor/components/condition-row.js +146 -95
  48. package/dist/components/condition-editor/components/condition-row.js.map +1 -1
  49. package/dist/components/condition-editor/condition-editor.js +18 -40
  50. package/dist/components/condition-editor/condition-editor.js.map +1 -1
  51. package/dist/components/condition-editor/condition-editor.vue.d.ts +0 -2
  52. package/dist/components/condition-editor/core/evaluator.d.ts +22 -0
  53. package/dist/components/condition-editor/core/evaluator.js +111 -50
  54. package/dist/components/condition-editor/core/evaluator.js.map +1 -1
  55. package/dist/components/condition-editor/core/operators.js.map +1 -1
  56. package/dist/components/condition-editor/index.d.ts +2 -1
  57. package/dist/components/condition-editor/style2.css +159 -82
  58. package/dist/components/context-menu/api.js.map +1 -1
  59. package/dist/components/context-menu/context-menu-item.js.map +1 -1
  60. package/dist/components/context-menu/context-menu.js.map +1 -1
  61. package/dist/components/context-menu/style.js +1 -1
  62. package/dist/components/date-panel/date-panel.js.map +1 -1
  63. package/dist/components/date-panel/date-panel.vue.d.ts +1 -1
  64. package/dist/components/date-panel/headers/day.js.map +1 -1
  65. package/dist/components/date-panel/headers/month.js.map +1 -1
  66. package/dist/components/date-panel/headers/year.js.map +1 -1
  67. package/dist/components/date-panel/panels/day.js.map +1 -1
  68. package/dist/components/date-panel/panels/month.js.map +1 -1
  69. package/dist/components/date-panel/panels/year.js.map +1 -1
  70. package/dist/components/date-panel/use-date-select.js.map +1 -1
  71. package/dist/components/date-panel/use-panel-date.js.map +1 -1
  72. package/dist/components/date-panel/use-panel.js.map +1 -1
  73. package/dist/components/date-picker/date-picker.js.map +1 -1
  74. package/dist/components/date-picker/date-picker.vue.d.ts +1 -1
  75. package/dist/components/date-range-picker/date-range-picker.js.map +1 -1
  76. package/dist/components/date-range-picker/date-range-picker.vue.d.ts +1 -1
  77. package/dist/components/dialog/dialog.js.map +1 -1
  78. package/dist/components/dialog/style.js +2 -2
  79. package/dist/components/dialog/use-maximum.js.map +1 -1
  80. package/dist/components/drawer/drawer.js.map +1 -1
  81. package/dist/components/drawer/style.js +1 -1
  82. package/dist/components/dropdown/dropdown.js +1 -0
  83. package/dist/components/dropdown/dropdown.js.map +1 -1
  84. package/dist/components/dropdown/style.js +1 -1
  85. package/dist/components/empty/empty.js.map +1 -1
  86. package/dist/components/expression-editor/components/path-preview.js.map +1 -1
  87. package/dist/components/expression-editor/components/variable-picker.js.map +1 -1
  88. package/dist/components/expression-editor/core/chip.js.map +1 -1
  89. package/dist/components/expression-editor/core/editor.js.map +1 -1
  90. package/dist/components/expression-editor/core/mention.js.map +1 -1
  91. package/dist/components/expression-editor/core/model.js.map +1 -1
  92. package/dist/components/expression-editor/di.js.map +1 -1
  93. package/dist/components/expression-editor/expression-editor.js.map +1 -1
  94. package/dist/components/file-picker/file-picker.js.map +1 -1
  95. package/dist/components/file-picker/helper.js.map +1 -1
  96. package/dist/components/file-viewer/file-viewer.js.map +1 -1
  97. package/dist/components/file-viewer/helper.js.map +1 -1
  98. package/dist/components/file-viewer/previewers/docx-previewer.js.map +1 -1
  99. package/dist/components/file-viewer/previewers/image-previewer.js.map +1 -1
  100. package/dist/components/file-viewer/previewers/pdf-previewer.js.map +1 -1
  101. package/dist/components/file-viewer/previewers/pdf-viewport-scroll.js.map +1 -1
  102. package/dist/components/file-viewer/previewers/pdf-zoom-bridge.js.map +1 -1
  103. package/dist/components/file-viewer/previewers/sheet-previewer.js.map +1 -1
  104. package/dist/components/file-viewer/previewers/text-previewer.js.map +1 -1
  105. package/dist/components/file-viewer/previewers/video-previewer.js.map +1 -1
  106. package/dist/components/float-button/float-button.js.map +1 -1
  107. package/dist/components/form/dynamic-form-model.js.map +1 -1
  108. package/dist/components/form/form-model.js.map +1 -1
  109. package/dist/components/form/form.vue_vue_type_script_setup_true_lang.js.map +1 -1
  110. package/dist/components/form/helper.js.map +1 -1
  111. package/dist/components/form/use-node-interceptor.js.map +1 -1
  112. package/dist/components/form-item/form-item.js.map +1 -1
  113. package/dist/components/form-item/form-item.vue_vue_type_script_setup_true_lang.js +2 -1
  114. package/dist/components/form-item/form-item.vue_vue_type_script_setup_true_lang.js.map +1 -1
  115. package/dist/components/gantt-chart/gantt-chart.js.map +1 -1
  116. package/dist/components/grid/breakpoint.js.map +1 -1
  117. package/dist/components/grid/grid-item.js.map +1 -1
  118. package/dist/components/grid/grid.js.map +1 -1
  119. package/dist/components/grid/use-responsive.js.map +1 -1
  120. package/dist/components/grid-input/grid-input.js.map +1 -1
  121. package/dist/components/group-input/group-input.js.map +1 -1
  122. package/dist/components/group-input/use-group-items.js.map +1 -1
  123. package/dist/components/icon/icon.js.map +1 -1
  124. package/dist/components/index.d.ts +1 -0
  125. package/dist/components/index.js +4 -0
  126. package/dist/components/input/input.vue.d.ts +2 -2
  127. package/dist/components/input/input.vue_vue_type_script_setup_true_lang.js.map +1 -1
  128. package/dist/components/input/style.js +1 -1
  129. package/dist/components/kbd/kbd.js.map +1 -1
  130. package/dist/components/layout/layout-resizer.js.map +1 -1
  131. package/dist/components/layout/layout.js.map +1 -1
  132. package/dist/components/list/list-item.js.map +1 -1
  133. package/dist/components/list/list.js.map +1 -1
  134. package/dist/components/loading/directive.js.map +1 -1
  135. package/dist/components/loading/loading.js.map +1 -1
  136. package/dist/components/loading/style.js +1 -1
  137. package/dist/components/menu/helper.js.map +1 -1
  138. package/dist/components/menu/menu-item-collapsed.js.map +1 -1
  139. package/dist/components/menu/menu-item.js.map +1 -1
  140. package/dist/components/menu/menu-sub-collapsed.js.map +1 -1
  141. package/dist/components/menu/menu-sub.js.map +1 -1
  142. package/dist/components/menu/menu.js.map +1 -1
  143. package/dist/components/menu/use-menu-item.js.map +1 -1
  144. package/dist/components/menu/walk-menu-path.js.map +1 -1
  145. package/dist/components/message/helper.js.map +1 -1
  146. package/dist/components/message/message-box.js.map +1 -1
  147. package/dist/components/message/message.js.map +1 -1
  148. package/dist/components/message/message2.js.map +1 -1
  149. package/dist/components/message-confirm/message-confirm.js.map +1 -1
  150. package/dist/components/message-confirm/message-confirm2.js.map +1 -1
  151. package/dist/components/multi-select/multi-select-option.js.map +1 -1
  152. package/dist/components/multi-select/multi-select.js.map +1 -1
  153. package/dist/components/multi-select/multi-select.vue.d.ts +2 -2
  154. package/dist/components/multi-select/style.js +1 -1
  155. package/dist/components/multi-tree-select/multi-tree-select.js.map +1 -1
  156. package/dist/components/multi-tree-select/multi-tree-select.vue.d.ts +5 -5
  157. package/dist/components/multi-tree-select/style.js +1 -1
  158. package/dist/components/node-render/node-render.js.map +1 -1
  159. package/dist/components/notification/index.js.map +1 -1
  160. package/dist/components/notification/notification.js.map +1 -1
  161. package/dist/components/notification/notification.vue.d.ts +1 -1
  162. package/dist/components/number/number.js.map +1 -1
  163. package/dist/components/number-input/number-input.js.map +1 -1
  164. package/dist/components/number-input/number-input.vue.d.ts +2 -2
  165. package/dist/components/number-range-input/number-range-input.js.map +1 -1
  166. package/dist/components/paginator/paginator.js.map +1 -1
  167. package/dist/components/palette/color-transform.js.map +1 -1
  168. package/dist/components/palette/palette-alpha.js.map +1 -1
  169. package/dist/components/palette/palette-color-switch.js.map +1 -1
  170. package/dist/components/palette/palette-hue.js.map +1 -1
  171. package/dist/components/palette/palette-sv.js.map +1 -1
  172. package/dist/components/palette/palette.js.map +1 -1
  173. package/dist/components/palette/use-hsv.js.map +1 -1
  174. package/dist/components/password-input/password-input.js.map +1 -1
  175. package/dist/components/pop-confirm/pop-confirm.js.map +1 -1
  176. package/dist/components/pop-confirm/pop-confirm.vue.d.ts +1 -1
  177. package/dist/components/progress/progress.js.map +1 -1
  178. package/dist/components/progress-nodes/progress-nodes.js.map +1 -1
  179. package/dist/components/radio/radio.js.map +1 -1
  180. package/dist/components/radio/style.js +1 -1
  181. package/dist/components/radio-group/radio-group.js.map +1 -1
  182. package/dist/components/rich-text-editor/rich-text-editor.js.map +1 -1
  183. package/dist/components/rich-text-editor/toolbar.js.map +1 -1
  184. package/dist/components/scroll/scroll-bar.js +2 -0
  185. package/dist/components/scroll/scroll-bar.js.map +1 -1
  186. package/dist/components/scroll/scroll.js.map +1 -1
  187. package/dist/components/select/select.js.map +1 -1
  188. package/dist/components/select/select.vue.d.ts +2 -2
  189. package/dist/components/select/use-keyboard.js.map +1 -1
  190. package/dist/components/select/use-options.js.map +1 -1
  191. package/dist/components/slider/slider-thumb.js.map +1 -1
  192. package/dist/components/slider/slider.js +1 -1
  193. package/dist/components/slider/slider.js.map +1 -1
  194. package/dist/components/slider/use-slider.js.map +1 -1
  195. package/dist/components/steps/steps.js.map +1 -1
  196. package/dist/components/steps/steps.vue.d.ts +3 -3
  197. package/dist/components/switch/switch.js.map +1 -1
  198. package/dist/components/table/di.js.map +1 -1
  199. package/dist/components/table/node/col.js.map +1 -1
  200. package/dist/components/table/node/row.js.map +1 -1
  201. package/dist/components/table/table-body.js.map +1 -1
  202. package/dist/components/table/table-cell.js.map +1 -1
  203. package/dist/components/table/table-foot.js.map +1 -1
  204. package/dist/components/table/table-head.js.map +1 -1
  205. package/dist/components/table/table-row.js.map +1 -1
  206. package/dist/components/table/table.js.map +1 -1
  207. package/dist/components/table/use-check.js.map +1 -1
  208. package/dist/components/table/use-col-resize.js.map +1 -1
  209. package/dist/components/table/use-columns.js.map +1 -1
  210. package/dist/components/table/use-fixed-columns.js.map +1 -1
  211. package/dist/components/table/use-rows.js.map +1 -1
  212. package/dist/components/table/use-table.js.map +1 -1
  213. package/dist/components/table-editor/table-editor.js.map +1 -1
  214. package/dist/components/tabs/style.js +1 -1
  215. package/dist/components/tabs/tabs-horizontal.js.map +1 -1
  216. package/dist/components/tabs/tabs-horizontal.vue.d.ts +1 -1
  217. package/dist/components/tabs/tabs-vertical.js.map +1 -1
  218. package/dist/components/tabs/tabs.js.map +1 -1
  219. package/dist/components/tabs/tabs.vue.d.ts +1 -1
  220. package/dist/components/tabs/use-tabs-bar.js.map +1 -1
  221. package/dist/components/tag/tag.js.map +1 -1
  222. package/dist/components/text/text.js.map +1 -1
  223. package/dist/components/textarea/style.js +1 -1
  224. package/dist/components/textarea/textarea.js.map +1 -1
  225. package/dist/components/textarea/textarea.vue.d.ts +2 -2
  226. package/dist/components/textarea/utils.js.map +1 -1
  227. package/dist/components/theme/schema.js.map +1 -1
  228. package/dist/components/theme/theme.js.map +1 -1
  229. package/dist/components/tip/tip.js.map +1 -1
  230. package/dist/components/tip/tip.vue.d.ts +1 -1
  231. package/dist/components/tip/use-nest.js.map +1 -1
  232. package/dist/components/tree/tree-node.js.map +1 -1
  233. package/dist/components/tree/tree-node2.js.map +1 -1
  234. package/dist/components/tree/tree.js.map +1 -1
  235. package/dist/components/tree/tree.vue.d.ts +1 -1
  236. package/dist/components/tree/use-check.js.map +1 -1
  237. package/dist/components/tree/use-filter.js.map +1 -1
  238. package/dist/components/tree/use-select.js.map +1 -1
  239. package/dist/components/tree/use-tree-nodes.js.map +1 -1
  240. package/dist/components/tree-select/tree-select.js.map +1 -1
  241. package/dist/components/tree-select/tree-select.vue.d.ts +5 -5
  242. package/dist/components/watermark/watermark.js.map +1 -1
  243. package/dist/index.d.ts +4 -3
  244. package/dist/index.js +2 -1
  245. package/dist/install.js.map +1 -1
  246. package/dist/types/batch-edit.d.ts +2 -2
  247. package/dist/types/condition-editor.d.ts +21 -9
  248. package/dist/types/index.d.ts +2 -2
  249. package/package.json +13 -16
  250. package/src/components/action/style.scss +0 -6
  251. package/src/components/auto-complete/style.scss +0 -1
  252. package/src/components/auto-complete/style.ts +1 -1
  253. package/src/components/badge/badge.vue +1 -1
  254. package/src/components/batch-edit/style.ts +1 -1
  255. package/src/components/button/style.scss +1 -1
  256. package/src/components/cascade/use-select.ts +8 -6
  257. package/src/components/checkbox/style.ts +1 -1
  258. package/src/components/collapse/__test__/collapse.test.ts +3 -3
  259. package/src/components/condition-editor/components/condition-group.vue +118 -87
  260. package/src/components/condition-editor/components/condition-row.vue +137 -89
  261. package/src/components/condition-editor/condition-editor.vue +19 -48
  262. package/src/components/condition-editor/core/evaluator.ts +143 -57
  263. package/src/components/condition-editor/index.ts +6 -0
  264. package/src/components/condition-editor/style.scss +189 -102
  265. package/src/components/context-menu/style.ts +1 -1
  266. package/src/components/dialog/style.ts +2 -2
  267. package/src/components/drawer/style.ts +1 -1
  268. package/src/components/dropdown/style.ts +1 -1
  269. package/src/components/expression-editor/style.scss +1 -1
  270. package/src/components/form-item/form-item.vue +4 -9
  271. package/src/components/input/style.ts +1 -1
  272. package/src/components/loading/style.ts +1 -1
  273. package/src/components/menu/style.scss +1 -1
  274. package/src/components/message/style.scss +1 -1
  275. package/src/components/multi-select/style.ts +1 -1
  276. package/src/components/multi-tree-select/style.ts +1 -1
  277. package/src/components/number-input/__test__/number-input.test.ts +1 -1
  278. package/src/components/radio/style.ts +1 -1
  279. package/src/components/slider/slider.vue +1 -1
  280. package/src/components/table/di.ts +1 -1
  281. package/src/components/tabs/style.ts +1 -1
  282. package/src/components/textarea/style.ts +1 -1
  283. package/src/types/batch-edit.ts +2 -2
  284. package/src/types/condition-editor.ts +22 -8
@@ -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 :name=\"`name:${item.key}`\" :item=\"item\">\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: 'TabsVertical' })\n\nconst props = withDefaults(defineProps<TabsVerticalProps>(), {\n position: 'left',\n closable: false,\n rounded: false\n})\n\nconst emit = defineEmits<TabsVerticalEmits>()\n\nconst { size } = useFallbackProps([props], {\n size: 'default' as ComponentSize\n})\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;EAEb,MAAM,EAAE,SAAS,iBAAiB,CAAC,MAAM,EAAE,EACzC,MAAM,WACP,CAAA;EAED,MAAM,MAAM,IAAI,WAAU;EAE1B,MAAM,QAAQ,SAAmB,SAAA,aAAC;EAElC,MAAM,kBAAkB,SAAkB;AACxC,OAAI,KAAK,SAAU,QAAO;AAC1B,UAAO,KAAK,YAAY,MAAM;;EAGhC,MAAM,eAAe,MAAe,UAAkB;AACpD,OAAI,KAAK,SAAU;AACnB,SAAM,QAAQ,KAAK;AACnB,QAAK,SAAS,MAAM,MAAK;;EAG3B,MAAM,eAAe,MAAe,UAAkB;AACpD,OAAI,KAAK,SAAU;AACnB,QAAK,SAAS,MAAM,MAAK;;;uBAzEzB,mBA+BM,OAAA,EA9BH,OAAK,eAAA;IAAG,MAAA,IAAG,CAAC;IAAG,MAAA,IAAG,CAAC,EAAC,WAAA;IAAc,MAAA,IAAG,CAAC,EAAE,QAAA,SAAQ;IAAG,MAAA,IAAG,CAAC,EAAE,MAAA,KAAI,CAAA;IAAG,MAAA,IAAG,CAAC,GAAE,WAAY,QAAA,QAAO;IAAA,CAAA,EAAA,EAAA,EAAA,UAAA,KAAA,EAE1F,mBA2BS,UAAA,MAAA,WAxBiB,QAAA,QAAhB,MAAM,UAAK;wBAHrB,mBA2BS,UAAA;KA1BP,MAAK;KACL,MAAK;KAEJ,KAAK,KAAK;KACV,OAAK,eAAA;MAAY,MAAA,IAAG,CAAC,EAAC,OAAA;MAAkB,MAAA,IAAG,CAAC,GAAE,UAAW,MAAA,UAAU,KAAK,IAAG;MAAW,MAAA,IAAG,CAAC,GAAE,YAAa,KAAK,aAAQ,KAAA;;KAKtH,SAAK,eAAA,WAAO,YAAY,MAAM,MAAK,EAAA,CAAA,OAAA,CAAA;QAEpC,WAEO,KAAA,QAAA,QAFc,KAAK,OAAG,EAAW,MAAI,QAErC,CADL,mBAAqE,QAAA,EAA9D,OAAK,eAAE,MAAA,IAAG,CAAC,EAAC,aAAA,CAAA,EAAA,EAAA,gBAAmB,KAAK,QAAQ,KAAK,IAAG,EAAA,EAAA,CAAA,CAAA,EAGrD,eAAe,KAAI,IAAA,WAAA,EAD3B,mBAWO,QAAA;;KATL,MAAK;KACL,UAAS;KACR,OAAK,eAAE,MAAA,IAAG,CAAC,EAAC,QAAA,CAAA;KACZ,cAAU,SAAW,KAAK,QAAQ,KAAK;KACvC,SAAK,eAAA,WAAO,YAAY,MAAM,MAAK,EAAA,CAAA,OAAA,CAAA;QAEpC,YAES,MAAA,YAAA,EAAA,MAAA;4BADE,CAAT,YAAS,MAAA,MAAA,CAAA,CAAA,CAAA"}
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 :name=\"`name:${item.key}`\" :item=\"item\">\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: 'TabsVertical' })\n\nconst props = withDefaults(defineProps<TabsVerticalProps>(), {\n position: 'left',\n closable: false,\n rounded: false\n})\n\nconst emit = defineEmits<TabsVerticalEmits>()\n\nconst { size } = useFallbackProps([props], {\n size: 'default' as ComponentSize\n})\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;EAEb,MAAM,EAAE,SAAS,iBAAiB,CAAC,MAAK,EAAG,EACzC,MAAM,WACP,CAAA;EAED,MAAM,MAAM,IAAI,WAAU;EAE1B,MAAM,QAAQ,SAAmB,SAAA,aAAC;EAElC,MAAM,kBAAkB,SAAkB;GACxC,IAAI,KAAK,UAAU,OAAO;GAC1B,OAAO,KAAK,YAAY,MAAM;;EAGhC,MAAM,eAAe,MAAe,UAAkB;GACpD,IAAI,KAAK,UAAU;GACnB,MAAM,QAAQ,KAAK;GACnB,KAAK,SAAS,MAAM,MAAK;;EAG3B,MAAM,eAAe,MAAe,UAAkB;GACpD,IAAI,KAAK,UAAU;GACnB,KAAK,SAAS,MAAM,MAAK;;;uBAzEzB,mBA+BM,OAAA,EA9BH,OAAK,eAAA;IAAG,MAAA,IAAA,CAAI;IAAG,MAAA,IAAA,CAAI,EAAC,WAAA;IAAc,MAAA,IAAA,CAAI,EAAE,QAAA,SAAQ;IAAG,MAAA,IAAA,CAAI,EAAE,MAAA,KAAI,CAAA;IAAG,MAAA,IAAA,CAAI,GAAE,WAAY,QAAA,QAAO;IAAA,CAAA,EAAA,EAAA,EAAA,UAAA,KAAA,EAE1F,mBA2BS,UAAA,MAAA,WAxBiB,QAAA,QAAhB,MAAM,UAAK;wBAHrB,mBA2BS,UAAA;KA1BP,MAAK;KACL,MAAK;KAEJ,KAAK,KAAK;KACV,OAAK,eAAA;MAAY,MAAA,IAAA,CAAI,EAAC,OAAA;MAAkB,MAAA,IAAA,CAAI,GAAE,UAAW,MAAA,UAAU,KAAK,IAAG;MAAW,MAAA,IAAA,CAAI,GAAE,YAAa,KAAK,aAAQ,KAAA;;KAKtH,SAAK,eAAA,WAAO,YAAY,MAAM,MAAK,EAAA,CAAA,OAAA,CAAA;QAEpC,WAEO,KAAA,QAAA,QAFc,KAAK,OAAG,EAAW,MAAI,QAErC,CADL,mBAAqE,QAAA,EAA9D,OAAK,eAAE,MAAA,IAAA,CAAI,EAAC,aAAA,CAAA,EAAA,EAAA,gBAAmB,KAAK,QAAQ,KAAK,IAAG,EAAA,EAAA,CAAA,CAAA,EAGrD,eAAe,KAAI,IAAA,WAAA,EAD3B,mBAWO,QAAA;;KATL,MAAK;KACL,UAAS;KACR,OAAK,eAAE,MAAA,IAAA,CAAI,EAAC,QAAA,CAAA;KACZ,cAAU,SAAW,KAAK,QAAQ,KAAK;KACvC,SAAK,eAAA,WAAO,YAAY,MAAM,MAAK,EAAA,CAAA,OAAA,CAAA;QAEpC,YAES,MAAA,YAAA,EAAA,MAAA;4BADE,CAAT,YAAS,MAAA,MAAA,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, useSlots } 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: 'Tabs' })\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 = useSlots() as Record<string, ((props?: any) => any) | undefined>\n\nconst { size } = useFallbackProps([props], {\n size: 'default' as ComponentSize\n})\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,UAAU;EAExB,MAAM,EAAE,SAAS,iBAAiB,CAAC,MAAM,EAAE,EACzC,MAAM,WACP,CAAA;EAED,MAAM,MAAM,IAAI,OAAM;EAEtB,MAAM,QAAQ,SAAmB,SAAA,aAAC;EAElC,MAAM,eAAe,eAAe,MAAM,aAAa,SAAS,MAAM,aAAa,SAAQ;;EAG3F,MAAM,qBAAqB,eACzB,MAAM,aAAa,WAAW,WAAW,MAC3C;EAEA,MAAM,mBAAmB,eACvB,MAAM,aAAa,UAAU,UAAU,OACzC;EAEA,MAAM,WAAW,MAAe,UAAkB,KAAK,SAAS,MAAM,MAAK;EAC3E,MAAM,WAAW,MAAe,UAAkB,KAAK,SAAS,MAAM,MAAK;EAE3E,MAAM,oBAAoB;GACxB,MAAM,MAAM,MAAM;AAClB,OAAI,CAAC,IAAK,QAAO;GACjB,MAAM,QAAQ,MAAM,OAAO,EAAE,KAAK,CAAA;AAClC,OAAI,MAAM,QAAQ,MAAM,CACtB,QAAO,YAAY,aAAS,EAAE,OAAO,IAAI,EAAE,UAAU,EAAE,EAAE,EAAE,eAAe,OAAO,CAAA;AAEnF,UAAO;;;uBAvFP,mBA+BM,OAAA,EA/BA,OAAK,eAAA,CAAG,MAAA,IAAG,CAAC,GAAG,MAAA,IAAG,CAAC,EAAE,QAAA,SAAQ,CAAA,CAAA,EAAA,EAAA,CAEzB,aAAA,SAAA,WAAA,EADR,YAWE,aAAA;;gBATS,MAAA;iEAAA,MAAK,QAAA;IACb,OAAO,QAAA;IACP,UAAU,mBAAA;IACV,MAAM,MAAA,KAAI;IACV,UAAU,QAAA;IACV,OAAO,QAAA;IACP,SAAS,QAAA;IACF;IACA;;;;;;;;;uBAEV,YAUE,aAAA;;gBARS,MAAA;iEAAA,MAAK,QAAA;IACb,OAAO,QAAA;IACP,UAAU,iBAAA;IACV,MAAM,MAAA,KAAI;IACV,UAAU,QAAA;IACV,SAAS,QAAA;IACF;IACA;;;;;;;;QAGV,YAKa,YAAA;IALD,MAAK;IAAO,MAAK;;2BAGf,CAFK,QAAA,aAAA,WAAA,EAAjB,YAEY,WAAA,EAAA,KAAA,GAAA,EAAA,EAAA,WAAA,EADV,YAA8C,wBAAjB,aAAW,CAAA,EAAA,EAA5B,KAAK,MAAA,OAAK,CAAA,EAAA,EAAA,KAAA,KAAA,WAAA,EAExB,YAAqD,wBAAjB,aAAW,CAAA,EAAA,EAA5B,KAAK,MAAA,OAAK,CAAA,EAAA,CAAA"}
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, useSlots } 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: 'Tabs' })\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 = useSlots() as Record<string, ((props?: any) => any) | undefined>\n\nconst { size } = useFallbackProps([props], {\n size: 'default' as ComponentSize\n})\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,UAAS;EAEvB,MAAM,EAAE,SAAS,iBAAiB,CAAC,MAAK,EAAG,EACzC,MAAM,WACP,CAAA;EAED,MAAM,MAAM,IAAI,OAAM;EAEtB,MAAM,QAAQ,SAAmB,SAAA,aAAC;EAElC,MAAM,eAAe,eAAe,MAAM,aAAa,SAAS,MAAM,aAAa,SAAQ;;EAG3F,MAAM,qBAAqB,eACzB,MAAM,aAAa,WAAW,WAAW,MAC3C;EAEA,MAAM,mBAAmB,eACvB,MAAM,aAAa,UAAU,UAAU,OACzC;EAEA,MAAM,WAAW,MAAe,UAAkB,KAAK,SAAS,MAAM,MAAK;EAC3E,MAAM,WAAW,MAAe,UAAkB,KAAK,SAAS,MAAM,MAAK;EAE3E,MAAM,oBAAoB;GACxB,MAAM,MAAM,MAAM;GAClB,IAAI,CAAC,KAAK,OAAO;GACjB,MAAM,QAAQ,MAAM,OAAO,EAAE,KAAK,CAAA;GAClC,IAAI,MAAM,QAAQ,MAAK,EACrB,OAAO,YAAY,aAAS,EAAE,OAAO,IAAI,EAAE,UAAS,EAAE,EAAG,EAAE,eAAe,OAAO,CAAA;GAEnF,OAAO;;;uBAvFP,mBA+BM,OAAA,EA/BA,OAAK,eAAA,CAAG,MAAA,IAAA,CAAI,GAAG,MAAA,IAAA,CAAI,EAAE,QAAA,SAAQ,CAAA,CAAA,EAAA,EAAA,CAEzB,aAAA,SAAA,WAAA,EADR,YAWE,aAAA;;gBATS,MAAA;iEAAA,MAAK,QAAA;IACb,OAAO,QAAA;IACP,UAAU,mBAAA;IACV,MAAM,MAAA,KAAA;IACN,UAAU,QAAA;IACV,OAAO,QAAA;IACP,SAAS,QAAA;IACF;IACA;;;;;;;;;uBAEV,YAUE,aAAA;;gBARS,MAAA;iEAAA,MAAK,QAAA;IACb,OAAO,QAAA;IACP,UAAU,iBAAA;IACV,MAAM,MAAA,KAAA;IACN,UAAU,QAAA;IACV,SAAS,QAAA;IACF;IACA;;;;;;;;QAGV,YAKa,YAAA;IALD,MAAK;IAAO,MAAK;;2BAGf,CAFK,QAAA,aAAA,WAAA,EAAjB,YAEY,WAAA,EAAA,KAAA,GAAA,EAAA,EAAA,WAAA,EADV,YAA8C,wBAAjB,aAAW,CAAA,EAAA,EAA5B,KAAK,MAAA,OAAK,CAAA,EAAA,EAAA,KAAA,KAAA,WAAA,EAExB,YAAqD,wBAAjB,aAAW,CAAA,EAAA,EAA5B,KAAK,MAAA,OAAK,CAAA,EAAA,CAAA"}
@@ -18,10 +18,10 @@ declare const __VLS_export: _$vue.DefineComponent<__VLS_PublicProps, {}, {}, {},
18
18
  onClose?: ((item: TabItem, index: number) => any) | undefined;
19
19
  onClick?: ((item: TabItem, index: number) => any) | undefined;
20
20
  }>, {
21
+ block: boolean;
21
22
  closable: boolean;
22
23
  rounded: boolean;
23
24
  position: "left" | "right" | "top" | "bottom";
24
- block: boolean;
25
25
  keepAlive: boolean;
26
26
  }, {}, {}, {}, string, _$vue.ComponentProvideOptions, false, {}, any>;
27
27
  declare const _default: typeof __VLS_export;
@@ -1 +1 @@
1
- {"version":3,"file":"use-tabs-bar.js","names":[],"sources":["../../../src/components/tabs/use-tabs-bar.ts"],"sourcesContent":["import { useResizeObserver } from '@veltra/compositions'\nimport {\n type ModelRef,\n type Ref,\n type ShallowRef,\n nextTick,\n onBeforeUnmount,\n onMounted,\n shallowRef,\n watch\n} from 'vue'\n\nimport type { TabItem } from '../../types'\n\ninterface UseTabsBarOptions {\n viewportRef: ShallowRef<HTMLElement | undefined>\n listRef: ShallowRef<HTMLElement | undefined>\n items: Ref<TabItem[]>\n model: ModelRef<string | undefined>\n}\n\n/**\n * 水平标签栏的溢出滚动逻辑:\n * - 计算 nav 按钮显隐与可用状态\n * - 提供按步滚动与活动标签自动滚入视野的方法\n * - 绑定 wheel / scroll / resize 事件\n */\nexport function useTabsBar(options: UseTabsBarOptions) {\n const { viewportRef, listRef, items, model } = options\n\n const showNav = shallowRef(false)\n const canPrev = shallowRef(false)\n const canNext = shallowRef(false)\n\n /** 依据 viewport 与内容尺寸推导滚动按钮可用状态 */\n const updateNavState = () => {\n const vp = viewportRef.value\n if (!vp) return\n const { scrollLeft, scrollWidth, clientWidth } = vp\n const overflowing = scrollWidth - clientWidth > 1\n showNav.value = overflowing\n canPrev.value = overflowing && scrollLeft > 0\n canNext.value = overflowing && scrollLeft + clientWidth < scrollWidth - 1\n }\n\n /** 箭头按钮:按视口宽度 80% 的步长平滑滚动 */\n const scrollByStep = (dir: 1 | -1) => {\n const vp = viewportRef.value\n if (!vp) return\n vp.scrollTo({ left: vp.scrollLeft + dir * vp.clientWidth * 0.8, behavior: 'smooth' })\n }\n\n /** 活动标签自动滚入视野 */\n const ensureActiveVisible = () => {\n const vp = viewportRef.value\n const list = listRef.value\n if (!vp || !list) return\n const activeKey = model.value\n if (!activeKey) return\n const activeIndex = items.value.findIndex((i) => i.key === activeKey)\n if (activeIndex < 0) return\n const el = list.children[activeIndex] as HTMLElement | undefined\n if (!el) return\n\n const vpRect = vp.getBoundingClientRect()\n const elRect = el.getBoundingClientRect()\n if (elRect.left < vpRect.left) {\n vp.scrollTo({ left: vp.scrollLeft + (elRect.left - vpRect.left) - 8, behavior: 'smooth' })\n } else if (elRect.right > vpRect.right) {\n vp.scrollTo({ left: vp.scrollLeft + (elRect.right - vpRect.right) + 8, behavior: 'smooth' })\n }\n }\n\n /** 鼠标滚轮(纵向)驱动水平滚动;触控板横滑(已有 deltaX)不拦截 */\n const handleWheel = (e: WheelEvent) => {\n if (!showNav.value) return\n const vp = viewportRef.value\n if (!vp) return\n if (Math.abs(e.deltaX) > Math.abs(e.deltaY)) return\n if (e.deltaY === 0) return\n e.preventDefault()\n vp.scrollLeft += e.deltaY\n }\n\n useResizeObserver({ targets: [viewportRef, listRef], onResize: () => updateNavState() })\n\n watch(model, async () => {\n await nextTick()\n ensureActiveVisible()\n })\n\n watch(\n items,\n async () => {\n await nextTick()\n updateNavState()\n ensureActiveVisible()\n },\n { deep: false }\n )\n\n onMounted(() => {\n const vp = viewportRef.value\n if (!vp) return\n vp.addEventListener('wheel', handleWheel, { passive: false })\n vp.addEventListener('scroll', updateNavState, { passive: true })\n updateNavState()\n nextTick(ensureActiveVisible)\n })\n\n onBeforeUnmount(() => {\n const vp = viewportRef.value\n if (!vp) return\n vp.removeEventListener('wheel', handleWheel)\n vp.removeEventListener('scroll', updateNavState)\n })\n\n return { showNav, canPrev, canNext, updateNavState, scrollByStep, ensureActiveVisible }\n}\n"],"mappings":";;;;;;;;;AA2BA,SAAgB,WAAW,SAA4B;CACrD,MAAM,EAAE,aAAa,SAAS,OAAO,UAAU;CAE/C,MAAM,UAAU,WAAW,MAAM;CACjC,MAAM,UAAU,WAAW,MAAM;CACjC,MAAM,UAAU,WAAW,MAAM;;CAGjC,MAAM,uBAAuB;EAC3B,MAAM,KAAK,YAAY;AACvB,MAAI,CAAC,GAAI;EACT,MAAM,EAAE,YAAY,aAAa,gBAAgB;EACjD,MAAM,cAAc,cAAc,cAAc;AAChD,UAAQ,QAAQ;AAChB,UAAQ,QAAQ,eAAe,aAAa;AAC5C,UAAQ,QAAQ,eAAe,aAAa,cAAc,cAAc;;;CAI1E,MAAM,gBAAgB,QAAgB;EACpC,MAAM,KAAK,YAAY;AACvB,MAAI,CAAC,GAAI;AACT,KAAG,SAAS;GAAE,MAAM,GAAG,aAAa,MAAM,GAAG,cAAc;GAAK,UAAU;GAAU,CAAC;;;CAIvF,MAAM,4BAA4B;EAChC,MAAM,KAAK,YAAY;EACvB,MAAM,OAAO,QAAQ;AACrB,MAAI,CAAC,MAAM,CAAC,KAAM;EAClB,MAAM,YAAY,MAAM;AACxB,MAAI,CAAC,UAAW;EAChB,MAAM,cAAc,MAAM,MAAM,WAAW,MAAM,EAAE,QAAQ,UAAU;AACrE,MAAI,cAAc,EAAG;EACrB,MAAM,KAAK,KAAK,SAAS;AACzB,MAAI,CAAC,GAAI;EAET,MAAM,SAAS,GAAG,uBAAuB;EACzC,MAAM,SAAS,GAAG,uBAAuB;AACzC,MAAI,OAAO,OAAO,OAAO,KACvB,IAAG,SAAS;GAAE,MAAM,GAAG,cAAc,OAAO,OAAO,OAAO,QAAQ;GAAG,UAAU;GAAU,CAAC;WACjF,OAAO,QAAQ,OAAO,MAC/B,IAAG,SAAS;GAAE,MAAM,GAAG,cAAc,OAAO,QAAQ,OAAO,SAAS;GAAG,UAAU;GAAU,CAAC;;;CAKhG,MAAM,eAAe,MAAkB;AACrC,MAAI,CAAC,QAAQ,MAAO;EACpB,MAAM,KAAK,YAAY;AACvB,MAAI,CAAC,GAAI;AACT,MAAI,KAAK,IAAI,EAAE,OAAO,GAAG,KAAK,IAAI,EAAE,OAAO,CAAE;AAC7C,MAAI,EAAE,WAAW,EAAG;AACpB,IAAE,gBAAgB;AAClB,KAAG,cAAc,EAAE;;AAGrB,mBAAkB;EAAE,SAAS,CAAC,aAAa,QAAQ;EAAE,gBAAgB,gBAAgB;EAAE,CAAC;AAExF,OAAM,OAAO,YAAY;AACvB,QAAM,UAAU;AAChB,uBAAqB;GACrB;AAEF,OACE,OACA,YAAY;AACV,QAAM,UAAU;AAChB,kBAAgB;AAChB,uBAAqB;IAEvB,EAAE,MAAM,OAAO,CAChB;AAED,iBAAgB;EACd,MAAM,KAAK,YAAY;AACvB,MAAI,CAAC,GAAI;AACT,KAAG,iBAAiB,SAAS,aAAa,EAAE,SAAS,OAAO,CAAC;AAC7D,KAAG,iBAAiB,UAAU,gBAAgB,EAAE,SAAS,MAAM,CAAC;AAChE,kBAAgB;AAChB,WAAS,oBAAoB;GAC7B;AAEF,uBAAsB;EACpB,MAAM,KAAK,YAAY;AACvB,MAAI,CAAC,GAAI;AACT,KAAG,oBAAoB,SAAS,YAAY;AAC5C,KAAG,oBAAoB,UAAU,eAAe;GAChD;AAEF,QAAO;EAAE;EAAS;EAAS;EAAS;EAAgB;EAAc;EAAqB"}
1
+ {"version":3,"file":"use-tabs-bar.js","names":[],"sources":["../../../src/components/tabs/use-tabs-bar.ts"],"sourcesContent":["import { useResizeObserver } from '@veltra/compositions'\nimport {\n type ModelRef,\n type Ref,\n type ShallowRef,\n nextTick,\n onBeforeUnmount,\n onMounted,\n shallowRef,\n watch\n} from 'vue'\n\nimport type { TabItem } from '../../types'\n\ninterface UseTabsBarOptions {\n viewportRef: ShallowRef<HTMLElement | undefined>\n listRef: ShallowRef<HTMLElement | undefined>\n items: Ref<TabItem[]>\n model: ModelRef<string | undefined>\n}\n\n/**\n * 水平标签栏的溢出滚动逻辑:\n * - 计算 nav 按钮显隐与可用状态\n * - 提供按步滚动与活动标签自动滚入视野的方法\n * - 绑定 wheel / scroll / resize 事件\n */\nexport function useTabsBar(options: UseTabsBarOptions) {\n const { viewportRef, listRef, items, model } = options\n\n const showNav = shallowRef(false)\n const canPrev = shallowRef(false)\n const canNext = shallowRef(false)\n\n /** 依据 viewport 与内容尺寸推导滚动按钮可用状态 */\n const updateNavState = () => {\n const vp = viewportRef.value\n if (!vp) return\n const { scrollLeft, scrollWidth, clientWidth } = vp\n const overflowing = scrollWidth - clientWidth > 1\n showNav.value = overflowing\n canPrev.value = overflowing && scrollLeft > 0\n canNext.value = overflowing && scrollLeft + clientWidth < scrollWidth - 1\n }\n\n /** 箭头按钮:按视口宽度 80% 的步长平滑滚动 */\n const scrollByStep = (dir: 1 | -1) => {\n const vp = viewportRef.value\n if (!vp) return\n vp.scrollTo({ left: vp.scrollLeft + dir * vp.clientWidth * 0.8, behavior: 'smooth' })\n }\n\n /** 活动标签自动滚入视野 */\n const ensureActiveVisible = () => {\n const vp = viewportRef.value\n const list = listRef.value\n if (!vp || !list) return\n const activeKey = model.value\n if (!activeKey) return\n const activeIndex = items.value.findIndex((i) => i.key === activeKey)\n if (activeIndex < 0) return\n const el = list.children[activeIndex] as HTMLElement | undefined\n if (!el) return\n\n const vpRect = vp.getBoundingClientRect()\n const elRect = el.getBoundingClientRect()\n if (elRect.left < vpRect.left) {\n vp.scrollTo({ left: vp.scrollLeft + (elRect.left - vpRect.left) - 8, behavior: 'smooth' })\n } else if (elRect.right > vpRect.right) {\n vp.scrollTo({ left: vp.scrollLeft + (elRect.right - vpRect.right) + 8, behavior: 'smooth' })\n }\n }\n\n /** 鼠标滚轮(纵向)驱动水平滚动;触控板横滑(已有 deltaX)不拦截 */\n const handleWheel = (e: WheelEvent) => {\n if (!showNav.value) return\n const vp = viewportRef.value\n if (!vp) return\n if (Math.abs(e.deltaX) > Math.abs(e.deltaY)) return\n if (e.deltaY === 0) return\n e.preventDefault()\n vp.scrollLeft += e.deltaY\n }\n\n useResizeObserver({ targets: [viewportRef, listRef], onResize: () => updateNavState() })\n\n watch(model, async () => {\n await nextTick()\n ensureActiveVisible()\n })\n\n watch(\n items,\n async () => {\n await nextTick()\n updateNavState()\n ensureActiveVisible()\n },\n { deep: false }\n )\n\n onMounted(() => {\n const vp = viewportRef.value\n if (!vp) return\n vp.addEventListener('wheel', handleWheel, { passive: false })\n vp.addEventListener('scroll', updateNavState, { passive: true })\n updateNavState()\n nextTick(ensureActiveVisible)\n })\n\n onBeforeUnmount(() => {\n const vp = viewportRef.value\n if (!vp) return\n vp.removeEventListener('wheel', handleWheel)\n vp.removeEventListener('scroll', updateNavState)\n })\n\n return { showNav, canPrev, canNext, updateNavState, scrollByStep, ensureActiveVisible }\n}\n"],"mappings":";;;;;;;;;AA2BA,SAAgB,WAAW,SAA4B;CACrD,MAAM,EAAE,aAAa,SAAS,OAAO,UAAU;CAE/C,MAAM,UAAU,WAAW,MAAM;CACjC,MAAM,UAAU,WAAW,MAAM;CACjC,MAAM,UAAU,WAAW,MAAM;;CAGjC,MAAM,uBAAuB;EAC3B,MAAM,KAAK,YAAY;EACvB,IAAI,CAAC,IAAI;EACT,MAAM,EAAE,YAAY,aAAa,gBAAgB;EACjD,MAAM,cAAc,cAAc,cAAc;EAChD,QAAQ,QAAQ;EAChB,QAAQ,QAAQ,eAAe,aAAa;EAC5C,QAAQ,QAAQ,eAAe,aAAa,cAAc,cAAc;;;CAI1E,MAAM,gBAAgB,QAAgB;EACpC,MAAM,KAAK,YAAY;EACvB,IAAI,CAAC,IAAI;EACT,GAAG,SAAS;GAAE,MAAM,GAAG,aAAa,MAAM,GAAG,cAAc;GAAK,UAAU;GAAU,CAAC;;;CAIvF,MAAM,4BAA4B;EAChC,MAAM,KAAK,YAAY;EACvB,MAAM,OAAO,QAAQ;EACrB,IAAI,CAAC,MAAM,CAAC,MAAM;EAClB,MAAM,YAAY,MAAM;EACxB,IAAI,CAAC,WAAW;EAChB,MAAM,cAAc,MAAM,MAAM,WAAW,MAAM,EAAE,QAAQ,UAAU;EACrE,IAAI,cAAc,GAAG;EACrB,MAAM,KAAK,KAAK,SAAS;EACzB,IAAI,CAAC,IAAI;EAET,MAAM,SAAS,GAAG,uBAAuB;EACzC,MAAM,SAAS,GAAG,uBAAuB;EACzC,IAAI,OAAO,OAAO,OAAO,MACvB,GAAG,SAAS;GAAE,MAAM,GAAG,cAAc,OAAO,OAAO,OAAO,QAAQ;GAAG,UAAU;GAAU,CAAC;OACrF,IAAI,OAAO,QAAQ,OAAO,OAC/B,GAAG,SAAS;GAAE,MAAM,GAAG,cAAc,OAAO,QAAQ,OAAO,SAAS;GAAG,UAAU;GAAU,CAAC;;;CAKhG,MAAM,eAAe,MAAkB;EACrC,IAAI,CAAC,QAAQ,OAAO;EACpB,MAAM,KAAK,YAAY;EACvB,IAAI,CAAC,IAAI;EACT,IAAI,KAAK,IAAI,EAAE,OAAO,GAAG,KAAK,IAAI,EAAE,OAAO,EAAE;EAC7C,IAAI,EAAE,WAAW,GAAG;EACpB,EAAE,gBAAgB;EAClB,GAAG,cAAc,EAAE;;CAGrB,kBAAkB;EAAE,SAAS,CAAC,aAAa,QAAQ;EAAE,gBAAgB,gBAAgB;EAAE,CAAC;CAExF,MAAM,OAAO,YAAY;EACvB,MAAM,UAAU;EAChB,qBAAqB;GACrB;CAEF,MACE,OACA,YAAY;EACV,MAAM,UAAU;EAChB,gBAAgB;EAChB,qBAAqB;IAEvB,EAAE,MAAM,OAAO,CAChB;CAED,gBAAgB;EACd,MAAM,KAAK,YAAY;EACvB,IAAI,CAAC,IAAI;EACT,GAAG,iBAAiB,SAAS,aAAa,EAAE,SAAS,OAAO,CAAC;EAC7D,GAAG,iBAAiB,UAAU,gBAAgB,EAAE,SAAS,MAAM,CAAC;EAChE,gBAAgB;EAChB,SAAS,oBAAoB;GAC7B;CAEF,sBAAsB;EACpB,MAAM,KAAK,YAAY;EACvB,IAAI,CAAC,IAAI;EACT,GAAG,oBAAoB,SAAS,YAAY;EAC5C,GAAG,oBAAoB,UAAU,eAAe;GAChD;CAEF,OAAO;EAAE;EAAS;EAAS;EAAS;EAAgB;EAAc;EAAqB"}
@@ -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({\n name: 'Tag'\n})\n\nconst cls = bem('tag')\n\nconst props = defineProps<TagProps>()\n\nconst emit = defineEmits<TagEmits>()\n\nconst { formProps } = injectFormContext()\nconst { size } = useFormFallbackProps([formProps ?? {}, props], {\n size: 'default'\n})\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":";;;;;;;;;;;;;;;;;;EA0BA,MAAM,MAAM,IAAI,MAAK;EAErB,MAAM,QAAQ;EAEd,MAAM,OAAO;EAEb,MAAM,EAAE,cAAc,mBAAkB;EACxC,MAAM,EAAE,SAAS,qBAAqB,CAAC,aAAa,EAAE,EAAE,MAAM,EAAE,EAC9D,MAAM,WACP,CAAA;EAED,MAAM,oBAAoB;AACxB,QAAK,QAAO;;EAGd,MAAM,YAAY,eAAe;GAC/B,MAAM,EAAE,SAAS;AACjB,UAAO;IACL,IAAI;IACJ,IAAI,EAAE,KAAK,MAAM;IACjB,QAAQ,IAAI,EAAE,WAAW,KAAK;IAC9B,IAAI,GAAG,SAAS,MAAM,MAAM;IAC5B,IAAI,GAAG,QAAQ,MAAM,KAAI;IAC3B;IACD;;uBAjDC,mBAQO,QAAA,EARA,OAAK,eAAE,UAAA,MAAS,EAAA,EAAA,CACrB,mBAEO,QAAA,EAFA,OAAK,eAAE,MAAA,IAAG,CAAC,EAAC,UAAA,CAAA,EAAA,EAAA,CACjB,WAAQ,KAAA,QAAA,UAAA,CAAA,EAAA,EAAA,EAGI,QAAA,YAAA,WAAA,EAAd,YAES,MAAA,YAAA,EAAA;;IAFgB,SAAK,cAAO,aAAW,CAAA,OAAA,CAAA;IAAG,OAAK,eAAE,MAAA,IAAG,CAAC,EAAC,aAAA,CAAA;;2BACpD,CAAT,YAAS,MAAA,MAAA,CAAA,CAAA,CAAA"}
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({\n name: 'Tag'\n})\n\nconst cls = bem('tag')\n\nconst props = defineProps<TagProps>()\n\nconst emit = defineEmits<TagEmits>()\n\nconst { formProps } = injectFormContext()\nconst { size } = useFormFallbackProps([formProps ?? {}, props], {\n size: 'default'\n})\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":";;;;;;;;;;;;;;;;;;EA0BA,MAAM,MAAM,IAAI,MAAK;EAErB,MAAM,QAAQ;EAEd,MAAM,OAAO;EAEb,MAAM,EAAE,cAAc,mBAAkB;EACxC,MAAM,EAAE,SAAS,qBAAqB,CAAC,aAAa,EAAC,EAAG,MAAK,EAAG,EAC9D,MAAM,WACP,CAAA;EAED,MAAM,oBAAoB;GACxB,KAAK,QAAO;;EAGd,MAAM,YAAY,eAAe;GAC/B,MAAM,EAAE,SAAS;GACjB,OAAO;IACL,IAAI;IACJ,IAAI,EAAE,KAAK,MAAK;IAChB,QAAQ,IAAI,EAAE,WAAW,KAAI;IAC7B,IAAI,GAAG,SAAS,MAAM,MAAK;IAC3B,IAAI,GAAG,QAAQ,MAAM,KAAI;IAC3B;IACD;;uBAjDC,mBAQO,QAAA,EARA,OAAK,eAAE,UAAA,MAAS,EAAA,EAAA,CACrB,mBAEO,QAAA,EAFA,OAAK,eAAE,MAAA,IAAA,CAAI,EAAC,UAAA,CAAA,EAAA,EAAA,CACjB,WAAQ,KAAA,QAAA,UAAA,CAAA,EAAA,EAAA,EAGI,QAAA,YAAA,WAAA,EAAd,YAES,MAAA,YAAA,EAAA;;IAFgB,SAAK,cAAO,aAAW,CAAA,OAAA,CAAA;IAAG,OAAK,eAAE,MAAA,IAAA,CAAI,EAAC,aAAA,CAAA;;2BACpD,CAAT,YAAS,MAAA,MAAA,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({\n name: 'Text'\n})\n\nconst props = withDefaults(defineProps<TextProps>(), {\n as: 'content'\n})\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 = {\n fontSize: withUnit(props.fontSize, 'px')\n }\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":";;;;;;;;;;;;;;;;;EAiBA,MAAM,QAAQ;EAId,MAAM,MAAM,IAAI,OAAM;EAEtB,MAAM,YAAY,eAAe;AAC/B,UAAO;IAAC,IAAI;IAAG,IAAI,GAAG,MAAM,GAAG;IAAE,IAAI,GAAG,QAAQ,MAAM,KAAK;IAAE,IAAI,GAAG,UAAU,MAAM,OAAO;IAAA;IAC5F;EAED,MAAM,QAAQ,eAAe;GAC3B,MAAM,QAAuB,EAC3B,UAAU,SAAS,MAAM,UAAU,KAAI,EACzC;GACA,MAAM,EAAE,SAAS,cAAc;AAC/B,OAAI,QACF,OAAM,iBAAiB;AAEzB,OAAI,UACF,OAAM,iBAAiB;AAGzB,UAAO;IACR;EAED,MAAM,QAAQ,UAAS;EACvB,MAAM,qBAAqB;GACzB,MAAM,QAAQ,MAAM,WAAU;AAC9B,OAAI,CAAC,OAAO,OAAQ,QAAO,KAAA;GAG3B,MAAM,YAAY,MAAM,QAAQ,SAAS,WAAW,KAAK,CAAA;GAEzD,MAAM,EAAE,cAAc;AAEtB,OAAI,CAAC,UACH,QAAO;AAGT,UAAO,UAAU,QAAQ,OAAO,aAAa;AAC5B,uBACb,SAAS,UACT,MAAM,QAAQ,UAAU,GAAG,YAAY,CAAC,UAAS,CAGnD,CAAO,SAAS,UAAU;AACxB,SAAI,MAAM,UACR,OAAM,KAAK,EAAE,QAAQ,MAAM,KAAK,CAAA;SAEhC,OAAM,KAAK,gBAAgB,MAAM,KAAK,CAAA;MAEzC;AAED,WAAO;MACN,EAAE,CAAW;;;uBAtEhB,mBAEI,KAAA;IAFA,OAAK,eAAE,UAAA,MAAS;IAAG,OAAK,eAAE,MAAA,MAAK;OACjC,YAAkD,MAAA,WAAA,EAAA;IAApC,SAAS,cAAY;IAAI,KAAI"}
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({\n name: 'Text'\n})\n\nconst props = withDefaults(defineProps<TextProps>(), {\n as: 'content'\n})\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 = {\n fontSize: withUnit(props.fontSize, 'px')\n }\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":";;;;;;;;;;;;;;;;;EAiBA,MAAM,QAAQ;EAId,MAAM,MAAM,IAAI,OAAM;EAEtB,MAAM,YAAY,eAAe;GAC/B,OAAO;IAAC,IAAI;IAAG,IAAI,GAAG,MAAM,GAAE;IAAG,IAAI,GAAG,QAAQ,MAAM,KAAI;IAAG,IAAI,GAAG,UAAU,MAAM,OAAM;IAAC;IAC5F;EAED,MAAM,QAAQ,eAAe;GAC3B,MAAM,QAAuB,EAC3B,UAAU,SAAS,MAAM,UAAU,KAAI,EACzC;GACA,MAAM,EAAE,SAAS,cAAc;GAC/B,IAAI,SACF,MAAM,iBAAiB;GAEzB,IAAI,WACF,MAAM,iBAAiB;GAGzB,OAAO;IACR;EAED,MAAM,QAAQ,UAAS;EACvB,MAAM,qBAAqB;GACzB,MAAM,QAAQ,MAAM,WAAU;GAC9B,IAAI,CAAC,OAAO,QAAQ,OAAO,KAAA;GAG3B,MAAM,YAAY,MAAM,QAAQ,SAAS,WAAW,KAAK,CAAA;GAEzD,MAAM,EAAE,cAAc;GAEtB,IAAI,CAAC,WACH,OAAO;GAGT,OAAO,UAAU,QAAQ,OAAO,aAAa;IAM3C,mBAJE,SAAS,UACT,MAAM,QAAQ,UAAS,GAAI,YAAY,CAAC,UAC1C,CAEA,CAAO,SAAS,UAAU;KACxB,IAAI,MAAM,WACR,MAAM,KAAK,EAAE,QAAQ,MAAM,KAAK,CAAA;UAEhC,MAAM,KAAK,gBAAgB,MAAM,KAAK,CAAA;MAEzC;IAED,OAAO;MACN,EAAa,CAAA;;;uBAtEhB,mBAEI,KAAA;IAFA,OAAK,eAAE,UAAA,MAAS;IAAG,OAAK,eAAE,MAAA,MAAK;OACjC,YAAkD,MAAA,WAAA,EAAA;IAApC,SAAS,cAAY;IAAI,KAAI"}
@@ -1,3 +1,3 @@
1
1
  import "../icon/style.js";
2
2
  import "./style2.css";
3
- import "@veltra/styles/anime/zoom-in.scss";
3
+ import "@veltra/styles/transitions/zoom-in.scss";
@@ -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({\n name: 'Textarea'\n})\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":[],"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({\n name: 'Textarea'\n})\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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"}
@@ -11,15 +11,15 @@ declare const __VLS_export: _$vue.DefineComponent<__VLS_PublicProps, {}, {}, {},
11
11
  "update:modelValue": (value: string | undefined) => any;
12
12
  } & {
13
13
  "update:modelValue": (value: string) => any;
14
- clear: () => any;
15
14
  change: (value: string) => any;
16
15
  focus: () => any;
16
+ clear: () => any;
17
17
  blur: () => any;
18
18
  }, string, _$vue.PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
19
19
  "onUpdate:modelValue"?: ((value: string) => any) | undefined;
20
- onClear?: (() => any) | undefined;
21
20
  onChange?: ((value: string) => any) | undefined;
22
21
  onFocus?: (() => any) | undefined;
22
+ onClear?: (() => any) | undefined;
23
23
  onBlur?: (() => any) | undefined;
24
24
  }>, {
25
25
  disabled: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","names":[],"sources":["../../../src/components/textarea/utils.ts"],"sourcesContent":["import { setStyles } from '@veltra/utils'\nimport { nextTick } from 'vue'\n\nexport function calcTextareaHeight(el: HTMLTextAreaElement): void {\n setStyles(el, { height: 'auto' })\n nextTick(() => {\n const { scrollHeight } = el\n\n setStyles(el, { overflow: 'hidden', height: scrollHeight + 'px' })\n })\n}\n"],"mappings":";;;AAGA,SAAgB,mBAAmB,IAA+B;AAChE,WAAU,IAAI,EAAE,QAAQ,QAAQ,CAAC;AACjC,gBAAe;EACb,MAAM,EAAE,iBAAiB;AAEzB,YAAU,IAAI;GAAE,UAAU;GAAU,QAAQ,eAAe;GAAM,CAAC;GAClE"}
1
+ {"version":3,"file":"utils.js","names":[],"sources":["../../../src/components/textarea/utils.ts"],"sourcesContent":["import { setStyles } from '@veltra/utils'\nimport { nextTick } from 'vue'\n\nexport function calcTextareaHeight(el: HTMLTextAreaElement): void {\n setStyles(el, { height: 'auto' })\n nextTick(() => {\n const { scrollHeight } = el\n\n setStyles(el, { overflow: 'hidden', height: scrollHeight + 'px' })\n })\n}\n"],"mappings":";;;AAGA,SAAgB,mBAAmB,IAA+B;CAChE,UAAU,IAAI,EAAE,QAAQ,QAAQ,CAAC;CACjC,eAAe;EACb,MAAM,EAAE,iBAAiB;EAEzB,UAAU,IAAI;GAAE,UAAU;GAAU,QAAQ,eAAe;GAAM,CAAC;GAClE"}
@@ -1 +1 @@
1
- {"version":3,"file":"schema.js","names":[],"sources":["../../../src/components/theme/schema.ts"],"sourcesContent":["export type ThemeFieldKind = 'palette' | 'input' | 'number' | 'select'\n\nexport interface ThemeFieldOption {\n label: string\n value: string\n}\n\nexport interface ThemeField {\n key: string\n label: string\n path: string[]\n kind: ThemeFieldKind\n hint?: string\n placeholder?: string\n min?: number\n max?: number\n step?: number\n suffix?: string\n options?: ThemeFieldOption[]\n}\n\nexport interface ThemeSection {\n key: string\n title: string\n description: string\n fields: ThemeField[]\n}\n\nconst borderStyleOptions: ThemeFieldOption[] = [\n { label: '实线', value: 'solid' },\n { label: '虚线', value: 'dashed' },\n { label: '点线', value: 'dotted' },\n { label: '双线', value: 'double' }\n]\n\nfunction paletteField(key: string, label: string, path: string[], hint?: string): ThemeField {\n return { key, label, path, kind: 'palette', hint }\n}\n\nfunction inputField(\n key: string,\n label: string,\n path: string[],\n placeholder?: string,\n hint?: string\n): ThemeField {\n return { key, label, path, kind: 'input', placeholder, hint }\n}\n\nfunction numberField(\n key: string,\n label: string,\n path: string[],\n options: Pick<ThemeField, 'min' | 'max' | 'step' | 'suffix' | 'hint'>\n): ThemeField {\n return {\n key,\n label,\n path,\n kind: 'number',\n min: options.min,\n max: options.max,\n step: options.step,\n suffix: options.suffix,\n hint: options.hint\n }\n}\n\nfunction pxField(\n key: string,\n label: string,\n path: string[],\n min: number,\n max: number,\n hint?: string\n): ThemeField {\n return numberField(key, label, path, { min, max, step: 1, suffix: 'px', hint })\n}\n\nfunction selectField(\n key: string,\n label: string,\n path: string[],\n options: ThemeFieldOption[],\n hint?: string\n): ThemeField {\n return { key, label, path, kind: 'select', options, hint }\n}\n\nexport const THEME_SECTIONS: ThemeSection[] = [\n {\n key: 'color',\n title: '综合色板',\n description: '品牌色与语义状态色,决定按钮、标签与反馈态的主视觉。',\n fields: [\n paletteField('color.primary', '主要颜色', ['color', 'primary']),\n paletteField('color.success', '成功颜色', ['color', 'success']),\n paletteField('color.warning', '警告颜色', ['color', 'warning']),\n paletteField('color.danger', '危险颜色', ['color', 'danger']),\n paletteField('color.info', '信息颜色', ['color', 'info']),\n paletteField('color.disabled', '禁用颜色', ['color', 'disabled']),\n paletteField('color.default', '默认颜色', ['color', 'default'])\n ]\n },\n {\n key: 'surface',\n title: '表面层次',\n description: '控制背景、文字、边框与阴影,决定整个界面的空气感与对比度。',\n fields: [\n paletteField('bg.color.top', '顶部背景', ['bg', 'color', 'top']),\n paletteField('bg.color.middle', '中部背景', ['bg', 'color', 'middle']),\n paletteField('bg.color.bottom', '底部背景', ['bg', 'color', 'bottom']),\n paletteField('bg.color.hover', '悬停背景', ['bg', 'color', 'hover']),\n paletteField('bg.color.black', '黑色背景', ['bg', 'color', 'black']),\n inputField('bg.filter.blur', '背景模糊', ['bg', 'filter', 'blur'], '例如:blur(16px)'),\n inputField(\n 'bg.filter.saturate',\n '背景饱和度',\n ['bg', 'filter', 'saturate'],\n '例如:saturate(180%)'\n ),\n paletteField('text-color.title', '标题文字', ['text-color', 'title']),\n paletteField('text-color.main', '主要文字', ['text-color', 'main']),\n paletteField('text-color.placeholder', '占位文字', ['text-color', 'placeholder']),\n paletteField('text-color.second', '次要文字', ['text-color', 'second']),\n paletteField('text-color.assist', '辅助文字', ['text-color', 'assist']),\n paletteField('text-color.disabled', '禁用文字', ['text-color', 'disabled']),\n paletteField('text-color.white', '白色文字', ['text-color', 'white']),\n paletteField('border.color', '边框颜色', ['border', 'color']),\n pxField('border.width', '边框宽度', ['border', 'width'], 0, 10),\n selectField('border.style', '边框样式', ['border', 'style'], borderStyleOptions),\n paletteField('shadow.color', '阴影颜色', ['shadow', 'color']),\n pxField('shadow.x', '水平偏移', ['shadow', 'x'], -24, 24),\n pxField('shadow.y', '垂直偏移', ['shadow', 'y'], -24, 24),\n pxField('shadow.blur', '模糊半径', ['shadow', 'blur'], 0, 64),\n pxField('shadow.spread', '扩散半径', ['shadow', 'spread'], -12, 24)\n ]\n },\n {\n key: 'control',\n title: '表单尺度',\n description: '统一基础控件的边角、尺寸和节奏,让组件家族看起来更一致。',\n fields: [\n pxField('radius.small', '小圆角', ['radius', 'small'], 0, 24),\n pxField('radius.default', '默认圆角', ['radius', 'default'], 0, 24),\n pxField('radius.large', '大圆角', ['radius', 'large'], 0, 32),\n pxField(\n 'form-component-height.small',\n '小表单高度',\n ['form-component-height', 'small'],\n 16,\n 40\n ),\n pxField(\n 'form-component-height.default',\n '默认表单高度',\n ['form-component-height', 'default'],\n 20,\n 52\n ),\n pxField(\n 'form-component-height.large',\n '大表单高度',\n ['form-component-height', 'large'],\n 24,\n 64\n ),\n pxField('gap.small', '小间距', ['gap', 'small'], 0, 20),\n pxField('gap.default', '默认间距', ['gap', 'default'], 0, 24),\n pxField('gap.large', '大间距', ['gap', 'large'], 0, 32)\n ]\n },\n {\n key: 'typography',\n title: '字体系统',\n description: '管理字体族与标题、正文、辅助文本的层级尺寸。',\n fields: [\n inputField(\n 'font-family',\n '字体族',\n ['font-family'],\n '例如:\"IBM Plex Sans\", \"PingFang SC\", sans-serif'\n ),\n pxField('font-size-title.small', '小标题字号', ['font-size-title', 'small'], 8, 28),\n pxField('font-size-title.default', '默认标题字号', ['font-size-title', 'default'], 8, 32),\n pxField('font-size-title.large', '大标题字号', ['font-size-title', 'large'], 10, 40),\n pxField('font-size-main.small', '小正文字号', ['font-size-main', 'small'], 8, 20),\n pxField('font-size-main.default', '默认正文字号', ['font-size-main', 'default'], 8, 24),\n pxField('font-size-main.large', '大正文字号', ['font-size-main', 'large'], 10, 28),\n pxField('font-size-assist.small', '小辅助字号', ['font-size-assist', 'small'], 8, 18),\n pxField('font-size-assist.default', '默认辅助字号', ['font-size-assist', 'default'], 8, 20),\n pxField('font-size-assist.large', '大辅助字号', ['font-size-assist', 'large'], 8, 24)\n ]\n },\n {\n key: 'responsive',\n title: '响应断点',\n description: '维护布局与响应式行为使用的断点变量。',\n fields: [\n pxField('breakpoint.xs', '超小屏幕', ['breakpoint', 'xs'], 320, 900),\n pxField('breakpoint.sm', '小屏幕', ['breakpoint', 'sm'], 480, 1200),\n pxField('breakpoint.md', '中屏幕', ['breakpoint', 'md'], 768, 1600),\n pxField('breakpoint.lg', '大屏幕', ['breakpoint', 'lg'], 1024, 2560)\n ]\n }\n]\n\nexport const THEME_FIELD_COUNT = THEME_SECTIONS.reduce((count, section) => {\n return count + section.fields.length\n}, 0)\n"],"mappings":"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"}
1
+ {"version":3,"file":"schema.js","names":[],"sources":["../../../src/components/theme/schema.ts"],"sourcesContent":["export type ThemeFieldKind = 'palette' | 'input' | 'number' | 'select'\n\nexport interface ThemeFieldOption {\n label: string\n value: string\n}\n\nexport interface ThemeField {\n key: string\n label: string\n path: string[]\n kind: ThemeFieldKind\n hint?: string\n placeholder?: string\n min?: number\n max?: number\n step?: number\n suffix?: string\n options?: ThemeFieldOption[]\n}\n\nexport interface ThemeSection {\n key: string\n title: string\n description: string\n fields: ThemeField[]\n}\n\nconst borderStyleOptions: ThemeFieldOption[] = [\n { label: '实线', value: 'solid' },\n { label: '虚线', value: 'dashed' },\n { label: '点线', value: 'dotted' },\n { label: '双线', value: 'double' }\n]\n\nfunction paletteField(key: string, label: string, path: string[], hint?: string): ThemeField {\n return { key, label, path, kind: 'palette', hint }\n}\n\nfunction inputField(\n key: string,\n label: string,\n path: string[],\n placeholder?: string,\n hint?: string\n): ThemeField {\n return { key, label, path, kind: 'input', placeholder, hint }\n}\n\nfunction numberField(\n key: string,\n label: string,\n path: string[],\n options: Pick<ThemeField, 'min' | 'max' | 'step' | 'suffix' | 'hint'>\n): ThemeField {\n return {\n key,\n label,\n path,\n kind: 'number',\n min: options.min,\n max: options.max,\n step: options.step,\n suffix: options.suffix,\n hint: options.hint\n }\n}\n\nfunction pxField(\n key: string,\n label: string,\n path: string[],\n min: number,\n max: number,\n hint?: string\n): ThemeField {\n return numberField(key, label, path, { min, max, step: 1, suffix: 'px', hint })\n}\n\nfunction selectField(\n key: string,\n label: string,\n path: string[],\n options: ThemeFieldOption[],\n hint?: string\n): ThemeField {\n return { key, label, path, kind: 'select', options, hint }\n}\n\nexport const THEME_SECTIONS: ThemeSection[] = [\n {\n key: 'color',\n title: '综合色板',\n description: '品牌色与语义状态色,决定按钮、标签与反馈态的主视觉。',\n fields: [\n paletteField('color.primary', '主要颜色', ['color', 'primary']),\n paletteField('color.success', '成功颜色', ['color', 'success']),\n paletteField('color.warning', '警告颜色', ['color', 'warning']),\n paletteField('color.danger', '危险颜色', ['color', 'danger']),\n paletteField('color.info', '信息颜色', ['color', 'info']),\n paletteField('color.disabled', '禁用颜色', ['color', 'disabled']),\n paletteField('color.default', '默认颜色', ['color', 'default'])\n ]\n },\n {\n key: 'surface',\n title: '表面层次',\n description: '控制背景、文字、边框与阴影,决定整个界面的空气感与对比度。',\n fields: [\n paletteField('bg.color.top', '顶部背景', ['bg', 'color', 'top']),\n paletteField('bg.color.middle', '中部背景', ['bg', 'color', 'middle']),\n paletteField('bg.color.bottom', '底部背景', ['bg', 'color', 'bottom']),\n paletteField('bg.color.hover', '悬停背景', ['bg', 'color', 'hover']),\n paletteField('bg.color.black', '黑色背景', ['bg', 'color', 'black']),\n inputField('bg.filter.blur', '背景模糊', ['bg', 'filter', 'blur'], '例如:blur(16px)'),\n inputField(\n 'bg.filter.saturate',\n '背景饱和度',\n ['bg', 'filter', 'saturate'],\n '例如:saturate(180%)'\n ),\n paletteField('text-color.title', '标题文字', ['text-color', 'title']),\n paletteField('text-color.main', '主要文字', ['text-color', 'main']),\n paletteField('text-color.placeholder', '占位文字', ['text-color', 'placeholder']),\n paletteField('text-color.second', '次要文字', ['text-color', 'second']),\n paletteField('text-color.assist', '辅助文字', ['text-color', 'assist']),\n paletteField('text-color.disabled', '禁用文字', ['text-color', 'disabled']),\n paletteField('text-color.white', '白色文字', ['text-color', 'white']),\n paletteField('border.color', '边框颜色', ['border', 'color']),\n pxField('border.width', '边框宽度', ['border', 'width'], 0, 10),\n selectField('border.style', '边框样式', ['border', 'style'], borderStyleOptions),\n paletteField('shadow.color', '阴影颜色', ['shadow', 'color']),\n pxField('shadow.x', '水平偏移', ['shadow', 'x'], -24, 24),\n pxField('shadow.y', '垂直偏移', ['shadow', 'y'], -24, 24),\n pxField('shadow.blur', '模糊半径', ['shadow', 'blur'], 0, 64),\n pxField('shadow.spread', '扩散半径', ['shadow', 'spread'], -12, 24)\n ]\n },\n {\n key: 'control',\n title: '表单尺度',\n description: '统一基础控件的边角、尺寸和节奏,让组件家族看起来更一致。',\n fields: [\n pxField('radius.small', '小圆角', ['radius', 'small'], 0, 24),\n pxField('radius.default', '默认圆角', ['radius', 'default'], 0, 24),\n pxField('radius.large', '大圆角', ['radius', 'large'], 0, 32),\n pxField(\n 'form-component-height.small',\n '小表单高度',\n ['form-component-height', 'small'],\n 16,\n 40\n ),\n pxField(\n 'form-component-height.default',\n '默认表单高度',\n ['form-component-height', 'default'],\n 20,\n 52\n ),\n pxField(\n 'form-component-height.large',\n '大表单高度',\n ['form-component-height', 'large'],\n 24,\n 64\n ),\n pxField('gap.small', '小间距', ['gap', 'small'], 0, 20),\n pxField('gap.default', '默认间距', ['gap', 'default'], 0, 24),\n pxField('gap.large', '大间距', ['gap', 'large'], 0, 32)\n ]\n },\n {\n key: 'typography',\n title: '字体系统',\n description: '管理字体族与标题、正文、辅助文本的层级尺寸。',\n fields: [\n inputField(\n 'font-family',\n '字体族',\n ['font-family'],\n '例如:\"IBM Plex Sans\", \"PingFang SC\", sans-serif'\n ),\n pxField('font-size-title.small', '小标题字号', ['font-size-title', 'small'], 8, 28),\n pxField('font-size-title.default', '默认标题字号', ['font-size-title', 'default'], 8, 32),\n pxField('font-size-title.large', '大标题字号', ['font-size-title', 'large'], 10, 40),\n pxField('font-size-main.small', '小正文字号', ['font-size-main', 'small'], 8, 20),\n pxField('font-size-main.default', '默认正文字号', ['font-size-main', 'default'], 8, 24),\n pxField('font-size-main.large', '大正文字号', ['font-size-main', 'large'], 10, 28),\n pxField('font-size-assist.small', '小辅助字号', ['font-size-assist', 'small'], 8, 18),\n pxField('font-size-assist.default', '默认辅助字号', ['font-size-assist', 'default'], 8, 20),\n pxField('font-size-assist.large', '大辅助字号', ['font-size-assist', 'large'], 8, 24)\n ]\n },\n {\n key: 'responsive',\n title: '响应断点',\n description: '维护布局与响应式行为使用的断点变量。',\n fields: [\n pxField('breakpoint.xs', '超小屏幕', ['breakpoint', 'xs'], 320, 900),\n pxField('breakpoint.sm', '小屏幕', ['breakpoint', 'sm'], 480, 1200),\n pxField('breakpoint.md', '中屏幕', ['breakpoint', 'md'], 768, 1600),\n pxField('breakpoint.lg', '大屏幕', ['breakpoint', 'lg'], 1024, 2560)\n ]\n }\n]\n\nexport const THEME_FIELD_COUNT = THEME_SECTIONS.reduce((count, section) => {\n return count + section.fields.length\n}, 0)\n"],"mappings":"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"}
@@ -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({\n name: 'UTheme'\n})\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({\n label: `${field.label}`,\n value: varName\n })\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 ? theme : new UITheme(createThemeSnapshot(theme.theme))\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 {\n ...section,\n visibleFields,\n changedCount\n }\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 {\n min: field.min,\n max: field.max,\n step: field.step,\n suffix: field.suffix\n }\n case 'select':\n return {\n options: field.options,\n clearable: false,\n placeholder: '请选择'\n }\n case 'input':\n return {\n placeholder: field.placeholder\n }\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 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":[],"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({\n name: 'UTheme'\n})\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({\n label: `${field.label}`,\n value: varName\n })\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 ? theme : new UITheme(createThemeSnapshot(theme.theme))\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 {\n ...section,\n visibleFields,\n changedCount\n }\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 {\n min: field.min,\n max: field.max,\n step: field.step,\n suffix: field.suffix\n }\n case 'select':\n return {\n options: field.options,\n clearable: false,\n placeholder: '请选择'\n }\n case 'input':\n return {\n placeholder: field.placeholder\n }\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 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 +1 @@
1
- {"version":3,"file":"tip.js","names":[],"sources":["../../../src/components/tip/tip.vue"],"sourcesContent":["<template>\n <!-- 触发 -->\n <UNodeRender v-bind=\"eventsHandlers\" :content=\"renderDefaultSlotTrigger()\" ref=\"triggerRef\" />\n\n <!-- 弹出内容 -->\n <teleport :to=\"`#${popperContainerId}`\">\n <transition name=\"tip\">\n <component\n v-if=\"tipVisible\"\n :is=\"contentTag\"\n :class=\"contentClass\"\n :style=\"[style, { zIndex: zIndex() }]\"\n ref=\"contentRef\"\n @mouseenter=\"eventsHandlers.onMouseenter\"\n @mouseleave=\"eventsHandlers.onMouseleave\"\n @click.stop\n v-click-outside=\"handleClickOutside\"\n >\n <UNodeRender v-if=\"externalNode\" :content=\"externalNode\" />\n\n <slot name=\"content\">{{ content }}</slot>\n\n <div :class=\"cls.e('arrow')\" v-if=\"!hideArrow\" ref=\"arrowRef\"></div>\n </component>\n </transition>\n </teleport>\n</template>\n\n<script lang=\"ts\" setup>\nimport { useFallbackProps, usePop } from '@veltra/compositions'\nimport { vClickOutside } from '@veltra/directives'\nimport { bem, extractNormalVNodes, zIndex } from '@veltra/utils'\nimport { shallowRef, computed, useSlots, onBeforeUnmount, toRef, watch, nextTick } from 'vue'\n\nimport type { TipProps, ComponentSize, TipEmits } from '../../types'\nimport { UNodeRender } from '../node-render'\nimport { useNest } from './use-nest'\n\ndefineOptions({ name: 'Tip' })\n\nconst props = withDefaults(defineProps<TipProps>(), {\n content: '',\n trigger: 'hover',\n direction: 'top',\n alignment: 'center',\n contentTag: 'div',\n visible: undefined\n})\n\nconst emit = defineEmits<TipEmits>()\n\nconst cls = bem('tip')\nconst slots = useSlots()\nconst { size } = useFallbackProps([props], {\n size: 'default' as ComponentSize\n})\n\nconst contentClass = computed(() => {\n const fixed = [cls.e('content'), cls.m(size.value)]\n const className = props.class\n if (!Array.isArray(className)) {\n return [...fixed, className]\n }\n return [...fixed, ...className]\n})\n\nconst triggerRef = shallowRef<InstanceType<typeof UNodeRender>>()\nconst contentRef = shallowRef<HTMLElement>()\nconst arrowRef = shallowRef<HTMLElement>()\n\nconst _visible = shallowRef(false)\n\nconst visible = computed(() => {\n return props.visible !== undefined ? props.visible : _visible.value\n})\n\nfunction updateVisible(v: boolean) {\n if (props.visible === undefined) {\n _visible.value = v\n } else {\n emit('update:visible', v)\n }\n}\n\nconst tipVisible = useNest(visible)\n\nfunction renderDefaultSlotTrigger() {\n const nodes = slots.default?.()\n if (!nodes?.length) return null\n return extractNormalVNodes(nodes)[0]\n}\n\nconst eventsHandlers = computed(() => {\n const { trigger, disabled } = props\n\n const handlers: Record<string, Function> = {}\n\n if (disabled) return handlers\n\n if (trigger === 'click') {\n handlers.onClick = open\n } else if (trigger === 'hover') {\n handlers.onMouseenter = open\n handlers.onMouseleave = close\n }\n\n return handlers\n})\n\nconst handleClickOutside = (e: MouseEvent) => {\n if (props.trigger === 'hover') return\n\n // 点击的元素在触发元素中则啥也\n if (props.trigger === 'click' && triggerDom.value.contains(e.target as Node)) {\n return\n }\n close()\n}\n\nlet closeTimer: number | undefined = undefined\n\n/** 弹出 */\nconst open = (e?: PointerEvent) => {\n e?.stopPropagation()\n closeTimer !== undefined && clearTimeout(closeTimer)\n\n updateVisible(true)\n}\n/** 关闭 */\nconst close = () => {\n if (props.trigger === 'hover') {\n closeTimer = setTimeout(() => {\n updateVisible(false)\n }, 250)\n } else {\n updateVisible(false)\n }\n}\n\nconst triggerDom = computed(() => {\n return props.triggerDom || triggerRef.value?.$el\n})\n\nconst { update, popperContainerId } = usePop({\n triggerRef: triggerDom,\n contentRef,\n arrowRef,\n direction: toRef(() => props.direction),\n alignment: toRef(() => props.alignment),\n onTriggerPositionChange() {\n close()\n }\n})\n\nwatch(triggerDom, (dom) => {\n // TODO: 看起来不是很优雅\n if (dom?.nodeType === Node.ELEMENT_NODE && visible.value) {\n nextTick(() => {\n void update()\n })\n }\n})\n\n/** 外部节点 */\nconst externalNode = shallowRef<any>()\n\nonBeforeUnmount(() => {\n clearTimeout(closeTimer)\n})\n</script>\n"],"mappings":"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"}
1
+ {"version":3,"file":"tip.js","names":[],"sources":["../../../src/components/tip/tip.vue"],"sourcesContent":["<template>\n <!-- 触发 -->\n <UNodeRender v-bind=\"eventsHandlers\" :content=\"renderDefaultSlotTrigger()\" ref=\"triggerRef\" />\n\n <!-- 弹出内容 -->\n <teleport :to=\"`#${popperContainerId}`\">\n <transition name=\"tip\">\n <component\n v-if=\"tipVisible\"\n :is=\"contentTag\"\n :class=\"contentClass\"\n :style=\"[style, { zIndex: zIndex() }]\"\n ref=\"contentRef\"\n @mouseenter=\"eventsHandlers.onMouseenter\"\n @mouseleave=\"eventsHandlers.onMouseleave\"\n @click.stop\n v-click-outside=\"handleClickOutside\"\n >\n <UNodeRender v-if=\"externalNode\" :content=\"externalNode\" />\n\n <slot name=\"content\">{{ content }}</slot>\n\n <div :class=\"cls.e('arrow')\" v-if=\"!hideArrow\" ref=\"arrowRef\"></div>\n </component>\n </transition>\n </teleport>\n</template>\n\n<script lang=\"ts\" setup>\nimport { useFallbackProps, usePop } from '@veltra/compositions'\nimport { vClickOutside } from '@veltra/directives'\nimport { bem, extractNormalVNodes, zIndex } from '@veltra/utils'\nimport { shallowRef, computed, useSlots, onBeforeUnmount, toRef, watch, nextTick } from 'vue'\n\nimport type { TipProps, ComponentSize, TipEmits } from '../../types'\nimport { UNodeRender } from '../node-render'\nimport { useNest } from './use-nest'\n\ndefineOptions({ name: 'Tip' })\n\nconst props = withDefaults(defineProps<TipProps>(), {\n content: '',\n trigger: 'hover',\n direction: 'top',\n alignment: 'center',\n contentTag: 'div',\n visible: undefined\n})\n\nconst emit = defineEmits<TipEmits>()\n\nconst cls = bem('tip')\nconst slots = useSlots()\nconst { size } = useFallbackProps([props], {\n size: 'default' as ComponentSize\n})\n\nconst contentClass = computed(() => {\n const fixed = [cls.e('content'), cls.m(size.value)]\n const className = props.class\n if (!Array.isArray(className)) {\n return [...fixed, className]\n }\n return [...fixed, ...className]\n})\n\nconst triggerRef = shallowRef<InstanceType<typeof UNodeRender>>()\nconst contentRef = shallowRef<HTMLElement>()\nconst arrowRef = shallowRef<HTMLElement>()\n\nconst _visible = shallowRef(false)\n\nconst visible = computed(() => {\n return props.visible !== undefined ? props.visible : _visible.value\n})\n\nfunction updateVisible(v: boolean) {\n if (props.visible === undefined) {\n _visible.value = v\n } else {\n emit('update:visible', v)\n }\n}\n\nconst tipVisible = useNest(visible)\n\nfunction renderDefaultSlotTrigger() {\n const nodes = slots.default?.()\n if (!nodes?.length) return null\n return extractNormalVNodes(nodes)[0]\n}\n\nconst eventsHandlers = computed(() => {\n const { trigger, disabled } = props\n\n const handlers: Record<string, Function> = {}\n\n if (disabled) return handlers\n\n if (trigger === 'click') {\n handlers.onClick = open\n } else if (trigger === 'hover') {\n handlers.onMouseenter = open\n handlers.onMouseleave = close\n }\n\n return handlers\n})\n\nconst handleClickOutside = (e: MouseEvent) => {\n if (props.trigger === 'hover') return\n\n // 点击的元素在触发元素中则啥也\n if (props.trigger === 'click' && triggerDom.value.contains(e.target as Node)) {\n return\n }\n close()\n}\n\nlet closeTimer: number | undefined = undefined\n\n/** 弹出 */\nconst open = (e?: PointerEvent) => {\n e?.stopPropagation()\n closeTimer !== undefined && clearTimeout(closeTimer)\n\n updateVisible(true)\n}\n/** 关闭 */\nconst close = () => {\n if (props.trigger === 'hover') {\n closeTimer = setTimeout(() => {\n updateVisible(false)\n }, 250)\n } else {\n updateVisible(false)\n }\n}\n\nconst triggerDom = computed(() => {\n return props.triggerDom || triggerRef.value?.$el\n})\n\nconst { update, popperContainerId } = usePop({\n triggerRef: triggerDom,\n contentRef,\n arrowRef,\n direction: toRef(() => props.direction),\n alignment: toRef(() => props.alignment),\n onTriggerPositionChange() {\n close()\n }\n})\n\nwatch(triggerDom, (dom) => {\n // TODO: 看起来不是很优雅\n if (dom?.nodeType === Node.ELEMENT_NODE && visible.value) {\n nextTick(() => {\n void update()\n })\n }\n})\n\n/** 外部节点 */\nconst externalNode = shallowRef<any>()\n\nonBeforeUnmount(() => {\n clearTimeout(closeTimer)\n})\n</script>\n"],"mappings":"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"}
@@ -11,11 +11,11 @@ declare const __VLS_base: _$vue.DefineComponent<TipProps, {}, {}, {}, {}, _$vue.
11
11
  }, string, _$vue.PublicProps, Readonly<TipProps> & Readonly<{
12
12
  "onUpdate:visible"?: ((value: boolean) => any) | undefined;
13
13
  }>, {
14
- direction: TipDirection;
15
14
  trigger: "hover" | "click";
16
15
  contentTag: string;
17
16
  visible: boolean;
18
17
  content: string;
18
+ direction: TipDirection;
19
19
  alignment: TipAlign;
20
20
  }, {}, {}, {}, string, _$vue.ComponentProvideOptions, false, {}, any>;
21
21
  declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
@@ -1 +1 @@
1
- {"version":3,"file":"use-nest.js","names":[],"sources":["../../../src/components/tip/use-nest.ts"],"sourcesContent":["import type { InjectionKey, Ref, ShallowRef } from 'vue'\nimport { shallowReactive, computed, provide, inject, onBeforeUnmount } from 'vue'\n\nconst TipNestDIKey: InjectionKey<{\n addChild(visible: ShallowRef<boolean>): void\n removeChild(visible: ShallowRef<boolean>): void\n}> = Symbol('TipNestDIKey')\n\n/**\n * tip嵌套\n * @param visible 当前tip显示变量\n * @returns\n */\nexport function useNest(\n visible: Ref<boolean | undefined> | { __v_isRef: boolean; value: boolean }\n): Ref<boolean> {\n /**\n * 子级提示框\n */\n const childrenTips = shallowReactive(new Set<ShallowRef<boolean>>())\n /**\n * 是否有子级提示框正在显示中\n */\n const anyChildrenVisible = computed(() => {\n return Array.from(childrenTips).some((tip) => tip.value)\n })\n\n const tipVisible = computed(() => {\n return visible.value || anyChildrenVisible.value\n })\n\n provide(TipNestDIKey, {\n addChild(v) {\n childrenTips.add(v)\n },\n removeChild(v) {\n childrenTips.delete(v)\n }\n })\n\n const { addChild, removeChild } = inject(TipNestDIKey, undefined) || {}\n addChild?.(tipVisible)\n\n onBeforeUnmount(() => {\n removeChild?.(tipVisible)\n })\n\n return tipVisible\n}\n"],"mappings":";;AAGA,MAAM,eAGD,OAAO,eAAe;;;;;;AAO3B,SAAgB,QACd,SACc;;;;CAId,MAAM,eAAe,gCAAgB,IAAI,KAA0B,CAAC;;;;CAIpE,MAAM,qBAAqB,eAAe;AACxC,SAAO,MAAM,KAAK,aAAa,CAAC,MAAM,QAAQ,IAAI,MAAM;GACxD;CAEF,MAAM,aAAa,eAAe;AAChC,SAAO,QAAQ,SAAS,mBAAmB;GAC3C;AAEF,SAAQ,cAAc;EACpB,SAAS,GAAG;AACV,gBAAa,IAAI,EAAE;;EAErB,YAAY,GAAG;AACb,gBAAa,OAAO,EAAE;;EAEzB,CAAC;CAEF,MAAM,EAAE,UAAU,gBAAgB,OAAO,cAAc,KAAA,EAAU,IAAI,EAAE;AACvE,YAAW,WAAW;AAEtB,uBAAsB;AACpB,gBAAc,WAAW;GACzB;AAEF,QAAO"}
1
+ {"version":3,"file":"use-nest.js","names":[],"sources":["../../../src/components/tip/use-nest.ts"],"sourcesContent":["import type { InjectionKey, Ref, ShallowRef } from 'vue'\nimport { shallowReactive, computed, provide, inject, onBeforeUnmount } from 'vue'\n\nconst TipNestDIKey: InjectionKey<{\n addChild(visible: ShallowRef<boolean>): void\n removeChild(visible: ShallowRef<boolean>): void\n}> = Symbol('TipNestDIKey')\n\n/**\n * tip嵌套\n * @param visible 当前tip显示变量\n * @returns\n */\nexport function useNest(\n visible: Ref<boolean | undefined> | { __v_isRef: boolean; value: boolean }\n): Ref<boolean> {\n /**\n * 子级提示框\n */\n const childrenTips = shallowReactive(new Set<ShallowRef<boolean>>())\n /**\n * 是否有子级提示框正在显示中\n */\n const anyChildrenVisible = computed(() => {\n return Array.from(childrenTips).some((tip) => tip.value)\n })\n\n const tipVisible = computed(() => {\n return visible.value || anyChildrenVisible.value\n })\n\n provide(TipNestDIKey, {\n addChild(v) {\n childrenTips.add(v)\n },\n removeChild(v) {\n childrenTips.delete(v)\n }\n })\n\n const { addChild, removeChild } = inject(TipNestDIKey, undefined) || {}\n addChild?.(tipVisible)\n\n onBeforeUnmount(() => {\n removeChild?.(tipVisible)\n })\n\n return tipVisible\n}\n"],"mappings":";;AAGA,MAAM,eAGD,OAAO,eAAe;;;;;;AAO3B,SAAgB,QACd,SACc;;;;CAId,MAAM,eAAe,gCAAgB,IAAI,KAA0B,CAAC;;;;CAIpE,MAAM,qBAAqB,eAAe;EACxC,OAAO,MAAM,KAAK,aAAa,CAAC,MAAM,QAAQ,IAAI,MAAM;GACxD;CAEF,MAAM,aAAa,eAAe;EAChC,OAAO,QAAQ,SAAS,mBAAmB;GAC3C;CAEF,QAAQ,cAAc;EACpB,SAAS,GAAG;GACV,aAAa,IAAI,EAAE;;EAErB,YAAY,GAAG;GACb,aAAa,OAAO,EAAE;;EAEzB,CAAC;CAEF,MAAM,EAAE,UAAU,gBAAgB,OAAO,cAAc,KAAA,EAAU,IAAI,EAAE;CACvE,WAAW,WAAW;CAEtB,sBAAsB;EACpB,cAAc,WAAW;GACzB;CAEF,OAAO"}
@@ -1 +1 @@
1
- {"version":3,"file":"tree-node.js","names":[],"sources":["../../../src/components/tree/tree-node.vue"],"sourcesContent":["<template>\n <div\n :class=\"[cls.e('node'), bem.is('expanded', node.expanded), bem.is('disabled', node.disabled)]\"\n :ref=\"measureRef\"\n >\n <span v-for=\"i in node.depth\" :key=\"i\" :class=\"cls.e('indent')\" aria-hidden=\"true\"></span>\n\n <u-icon v-if=\"!node.isLeaf\" :class=\"cls.e('expand-icon')\" @click.stop=\"toggleExpand\">\n <ArrowRight />\n </u-icon>\n <u-icon v-else :class=\"cls.e('leaf-icon')\" aria-hidden=\"true\">\n <Dot />\n </u-icon>\n\n <div\n :class=\"cls.e('node-content')\"\n @click=\"handleClick\"\n @contextmenu=\"treeEmit('node-contextmenu', $event, node)\"\n v-ripple=\"\n (treeProps.checkable || treeProps.selectable) && !node.disabled ? cls.e('ripple') : false\n \"\n >\n <u-checkbox\n v-if=\"treeProps.checkable\"\n :class=\"cls.e('checkbox')\"\n :model-value=\"node.checked\"\n :indeterminate=\"node.indeterminate\"\n :disabled=\"node.disabled\"\n @change=\"handleChange\"\n @click.stop\n />\n\n <u-node-render :content=\"getTreeSlotsNode({ node, data: node.data })\" />\n </div>\n </div>\n</template>\n\n<script lang=\"ts\" setup>\nimport { vRipple } from '@veltra/directives'\nimport { ArrowRight, Dot } from '@veltra/icons/normal'\nimport { bem } from '@veltra/utils'\nimport { inject } from 'vue'\n\nimport type { TreeNodeProps } from '../../types'\nimport UCheckbox from '../checkbox/checkbox.vue'\nimport { UIcon } from '../icon'\nimport { UNodeRender } from '../node-render'\nimport { TreeDIKey } from './di'\n\ndefineOptions({\n name: 'TreeNode'\n})\n\nconst props = defineProps<TreeNodeProps>()\n\nconst { treeProps, treeEmit, cls, getTreeSlotsNode, getFlattedNodes, toggleCheck, handleSelect } =\n inject(TreeDIKey)!\n\nfunction measureRef(el: unknown) {\n if (typeof props.index !== 'number' || !props.measureElement) return\n props.measureElement(props.index, el as Element | null)\n}\n\nfunction toggleExpand() {\n const { node } = props\n node.expanded = !node.expanded\n getFlattedNodes()\n\n treeEmit('expand', node)\n}\n\nfunction handleChange(checked: boolean, e: MouseEvent) {\n toggleCheck(props.node, checked, e.ctrlKey)\n}\n\nfunction handleClick(e: MouseEvent) {\n const { node } = props\n treeEmit('node-click', node)\n\n treeProps.selectable && handleSelect(node)\n treeProps.expandOnClickNode && toggleExpand()\n treeProps.checkable &&\n !node.disabled &&\n !treeProps.expandOnClickNode &&\n toggleCheck(node, !node.checked, e.ctrlKey)\n}\n</script>\n"],"mappings":";;;;;;;;;;;;;;;;;;EAqDA,MAAM,QAAQ;EAEd,MAAM,EAAE,WAAW,UAAU,KAAK,kBAAkB,iBAAiB,aAAa,iBAChF,OAAO,UAAU;EAEnB,SAAS,WAAW,IAAa;AAC/B,OAAI,OAAO,MAAM,UAAU,YAAY,CAAC,MAAM,eAAgB;AAC9D,SAAM,eAAe,MAAM,OAAO,GAAoB;;EAGxD,SAAS,eAAe;GACtB,MAAM,EAAE,SAAS;AACjB,QAAK,WAAW,CAAC,KAAK;AACtB,oBAAgB;AAEhB,YAAS,UAAU,KAAI;;EAGzB,SAAS,aAAa,SAAkB,GAAe;AACrD,eAAY,MAAM,MAAM,SAAS,EAAE,QAAO;;EAG5C,SAAS,YAAY,GAAe;GAClC,MAAM,EAAE,SAAS;AACjB,YAAS,cAAc,KAAI;AAE3B,aAAU,cAAc,aAAa,KAAI;AACzC,aAAU,qBAAqB,cAAa;AAC5C,aAAU,aACR,CAAC,KAAK,YACN,CAAC,UAAU,qBACX,YAAY,MAAM,CAAC,KAAK,SAAS,EAAE,QAAO;;;uBAnF5C,mBAiCM,OAAA;IAhCH,OAAK,eAAA;KAAG,MAAA,IAAG,CAAC,EAAC,OAAA;KAAU,MAAA,IAAG,CAAC,GAAE,YAAa,QAAA,KAAK,SAAQ;KAAG,MAAA,IAAG,CAAC,GAAE,YAAa,QAAA,KAAK,SAAQ;KAAA,CAAA;IAC1F,KAAK;;sBAEN,mBAA0F,UAAA,MAAA,WAAxE,QAAA,KAAK,QAAV,MAAC;yBAAd,mBAA0F,QAAA;MAA3D,KAAK;MAAI,OAAK,eAAE,MAAA,IAAG,CAAC,EAAC,SAAA,CAAA;MAAY,eAAY;;;KAE7D,QAAA,KAAK,UAAA,WAAA,EAApB,YAES,MAAA,YAAA,EAAA;;KAFoB,OAAK,eAAE,MAAA,IAAG,CAAC,EAAC,cAAA,CAAA;KAAkB,SAAK,cAAO,cAAY,CAAA,OAAA,CAAA;;4BACnE,CAAd,YAAc,MAAA,WAAA,CAAA,CAAA,CAAA;;sCAEhB,YAES,MAAA,YAAA,EAAA;;KAFO,OAAK,eAAE,MAAA,IAAG,CAAC,EAAC,YAAA,CAAA;KAAe,eAAY;;4BAC9C,CAAP,YAAO,MAAA,IAAA,CAAA,CAAA,CAAA;;;iCAGT,mBAmBM,OAAA;KAlBH,OAAK,eAAE,MAAA,IAAG,CAAC,EAAC,eAAA,CAAA;KACZ,SAAO;KACP,eAAW,OAAA,OAAA,OAAA,MAAA,WAAE,MAAA,SAAQ,CAAA,oBAAqB,QAAQ,QAAA,KAAI;QAM/C,MAAA,UAAS,CAAC,aAAA,WAAA,EADlB,YAQE,aAAA;;KANC,OAAK,eAAE,MAAA,IAAG,CAAC,EAAC,WAAA,CAAA;KACZ,eAAa,QAAA,KAAK;KAClB,eAAe,QAAA,KAAK;KACpB,UAAU,QAAA,KAAK;KACf,UAAQ;KACR,SAAK,OAAA,OAAA,OAAA,KAAA,oBAAN,IAAW,CAAA,OAAA,CAAA;;;;;;4CAGb,YAAwE,MAAA,WAAA,EAAA,EAAxD,SAAS,MAAA,iBAAgB,CAAA;KAAA,MAAG,QAAA;KAAI,MAAQ,QAAA,KAAK;KAAI,CAAA,EAAA,EAAA,MAAA,GAAA,CAAA,UAAA,CAAA,CAAA,EAAA,GAAA,GAAA,CAAA,CAAA,MAAA,QAAA,GAd7C,MAAA,UAAS,CAAC,aAAa,MAAA,UAAS,CAAC,eAAU,CAAM,QAAA,KAAK,WAAW,MAAA,IAAG,CAAC,EAAC,SAAA,GAAA,MAAA,CAAA,CAAA"}
1
+ {"version":3,"file":"tree-node.js","names":[],"sources":["../../../src/components/tree/tree-node.vue"],"sourcesContent":["<template>\n <div\n :class=\"[cls.e('node'), bem.is('expanded', node.expanded), bem.is('disabled', node.disabled)]\"\n :ref=\"measureRef\"\n >\n <span v-for=\"i in node.depth\" :key=\"i\" :class=\"cls.e('indent')\" aria-hidden=\"true\"></span>\n\n <u-icon v-if=\"!node.isLeaf\" :class=\"cls.e('expand-icon')\" @click.stop=\"toggleExpand\">\n <ArrowRight />\n </u-icon>\n <u-icon v-else :class=\"cls.e('leaf-icon')\" aria-hidden=\"true\">\n <Dot />\n </u-icon>\n\n <div\n :class=\"cls.e('node-content')\"\n @click=\"handleClick\"\n @contextmenu=\"treeEmit('node-contextmenu', $event, node)\"\n v-ripple=\"\n (treeProps.checkable || treeProps.selectable) && !node.disabled ? cls.e('ripple') : false\n \"\n >\n <u-checkbox\n v-if=\"treeProps.checkable\"\n :class=\"cls.e('checkbox')\"\n :model-value=\"node.checked\"\n :indeterminate=\"node.indeterminate\"\n :disabled=\"node.disabled\"\n @change=\"handleChange\"\n @click.stop\n />\n\n <u-node-render :content=\"getTreeSlotsNode({ node, data: node.data })\" />\n </div>\n </div>\n</template>\n\n<script lang=\"ts\" setup>\nimport { vRipple } from '@veltra/directives'\nimport { ArrowRight, Dot } from '@veltra/icons/normal'\nimport { bem } from '@veltra/utils'\nimport { inject } from 'vue'\n\nimport type { TreeNodeProps } from '../../types'\nimport UCheckbox from '../checkbox/checkbox.vue'\nimport { UIcon } from '../icon'\nimport { UNodeRender } from '../node-render'\nimport { TreeDIKey } from './di'\n\ndefineOptions({\n name: 'TreeNode'\n})\n\nconst props = defineProps<TreeNodeProps>()\n\nconst { treeProps, treeEmit, cls, getTreeSlotsNode, getFlattedNodes, toggleCheck, handleSelect } =\n inject(TreeDIKey)!\n\nfunction measureRef(el: unknown) {\n if (typeof props.index !== 'number' || !props.measureElement) return\n props.measureElement(props.index, el as Element | null)\n}\n\nfunction toggleExpand() {\n const { node } = props\n node.expanded = !node.expanded\n getFlattedNodes()\n\n treeEmit('expand', node)\n}\n\nfunction handleChange(checked: boolean, e: MouseEvent) {\n toggleCheck(props.node, checked, e.ctrlKey)\n}\n\nfunction handleClick(e: MouseEvent) {\n const { node } = props\n treeEmit('node-click', node)\n\n treeProps.selectable && handleSelect(node)\n treeProps.expandOnClickNode && toggleExpand()\n treeProps.checkable &&\n !node.disabled &&\n !treeProps.expandOnClickNode &&\n toggleCheck(node, !node.checked, e.ctrlKey)\n}\n</script>\n"],"mappings":";;;;;;;;;;;;;;;;;;EAqDA,MAAM,QAAQ;EAEd,MAAM,EAAE,WAAW,UAAU,KAAK,kBAAkB,iBAAiB,aAAa,iBAChF,OAAO,UAAS;EAElB,SAAS,WAAW,IAAa;GAC/B,IAAI,OAAO,MAAM,UAAU,YAAY,CAAC,MAAM,gBAAgB;GAC9D,MAAM,eAAe,MAAM,OAAO,GAAoB;;EAGxD,SAAS,eAAe;GACtB,MAAM,EAAE,SAAS;GACjB,KAAK,WAAW,CAAC,KAAK;GACtB,iBAAgB;GAEhB,SAAS,UAAU,KAAI;;EAGzB,SAAS,aAAa,SAAkB,GAAe;GACrD,YAAY,MAAM,MAAM,SAAS,EAAE,QAAO;;EAG5C,SAAS,YAAY,GAAe;GAClC,MAAM,EAAE,SAAS;GACjB,SAAS,cAAc,KAAI;GAE3B,UAAU,cAAc,aAAa,KAAI;GACzC,UAAU,qBAAqB,cAAa;GAC5C,UAAU,aACR,CAAC,KAAK,YACN,CAAC,UAAU,qBACX,YAAY,MAAM,CAAC,KAAK,SAAS,EAAE,QAAO;;;uBAnF5C,mBAiCM,OAAA;IAhCH,OAAK,eAAA;KAAG,MAAA,IAAA,CAAI,EAAC,OAAA;KAAU,MAAA,IAAA,CAAI,GAAE,YAAa,QAAA,KAAK,SAAQ;KAAG,MAAA,IAAA,CAAI,GAAE,YAAa,QAAA,KAAK,SAAQ;KAAA,CAAA;IAC1F,KAAK;;sBAEN,mBAA0F,UAAA,MAAA,WAAxE,QAAA,KAAK,QAAV,MAAC;yBAAd,mBAA0F,QAAA;MAA3D,KAAK;MAAI,OAAK,eAAE,MAAA,IAAA,CAAI,EAAC,SAAA,CAAA;MAAY,eAAY;;;KAE7D,QAAA,KAAK,UAAA,WAAA,EAApB,YAES,MAAA,YAAA,EAAA;;KAFoB,OAAK,eAAE,MAAA,IAAA,CAAI,EAAC,cAAA,CAAA;KAAkB,SAAK,cAAO,cAAY,CAAA,OAAA,CAAA;;4BACnE,CAAd,YAAc,MAAA,WAAA,CAAA,CAAA,CAAA;;sCAEhB,YAES,MAAA,YAAA,EAAA;;KAFO,OAAK,eAAE,MAAA,IAAA,CAAI,EAAC,YAAA,CAAA;KAAe,eAAY;;4BAC9C,CAAP,YAAO,MAAA,IAAA,CAAA,CAAA,CAAA;;;iCAGT,mBAmBM,OAAA;KAlBH,OAAK,eAAE,MAAA,IAAA,CAAI,EAAC,eAAA,CAAA;KACZ,SAAO;KACP,eAAW,OAAA,OAAA,OAAA,MAAA,WAAE,MAAA,SAAA,CAAQ,oBAAqB,QAAQ,QAAA,KAAI;QAM/C,MAAA,UAAA,CAAU,aAAA,WAAA,EADlB,YAQE,aAAA;;KANC,OAAK,eAAE,MAAA,IAAA,CAAI,EAAC,WAAA,CAAA;KACZ,eAAa,QAAA,KAAK;KAClB,eAAe,QAAA,KAAK;KACpB,UAAU,QAAA,KAAK;KACf,UAAQ;KACR,SAAK,OAAA,OAAA,OAAA,KAAA,oBAAN,IAAW,CAAA,OAAA,CAAA;;;;;;4CAGb,YAAwE,MAAA,WAAA,EAAA,EAAxD,SAAS,MAAA,iBAAA,CAAgB;KAAA,MAAG,QAAA;KAAI,MAAQ,QAAA,KAAK;KAAI,CAAA,EAAA,EAAA,MAAA,GAAA,CAAA,UAAA,CAAA,CAAA,EAAA,GAAA,GAAA,CAAA,CAAA,MAAA,QAAA,GAd7C,MAAA,UAAA,CAAU,aAAa,MAAA,UAAA,CAAU,eAAU,CAAM,QAAA,KAAK,WAAW,MAAA,IAAA,CAAI,EAAC,SAAA,GAAA,MAAA,CAAA,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"tree-node2.js","names":["TreeNode","CoreTreeNode"],"sources":["../../../src/components/tree/tree-node.ts"],"sourcesContent":["import { TreeNode as CoreTreeNode, o } from '@cat-kit/core'\nimport { shallowReactive } from 'vue'\n\nexport class TreeNode<Val extends Record<string, any> = Record<string, any>> extends CoreTreeNode<\n Val,\n TreeNode<Val>\n> {\n declare parent?: TreeNode<Val>\n\n declare children?: TreeNode<Val>[]\n\n expanded = false\n loading = false\n loaded = false\n /** 多选是否选中 */\n checked = false\n disabled = false\n visible = true\n /** 子节点选中数量 */\n childrenCheckCount = 0\n\n get indeterminate(): boolean {\n if (!this.children) return false\n return (\n this.childrenCheckCount > 0\n // && this.childrenCheckCount < this.children.length\n )\n }\n\n labelKey: string\n valueKey: string\n\n constructor(params: {\n data: Val\n index: number\n depth: number\n parent?: TreeNode<Val>\n labelKey: string\n valueKey: string\n }) {\n const { data, index, depth, parent, labelKey, valueKey } = params\n super(data, index, depth, parent)\n this.labelKey = labelKey\n this.valueKey = valueKey\n\n return shallowReactive(this)\n }\n\n get label(): string {\n return String(o(this.data).get(this.labelKey))\n }\n\n get key(): string | number {\n return o(this.data).get(this.valueKey) as string | number\n }\n\n /**\n * 向上冒泡设置\n * @param setter 设置函数, 返回 false 则停止冒泡\n */\n bubbleSet(setter: (node: TreeNode<Val>) => boolean | void): void {\n const ret = setter(this)\n ret !== false && this.parent?.bubbleSet(setter)\n }\n}\n"],"mappings":";;;AAGA,IAAaA,aAAb,cAAqFC,SAGnF;CAKA,WAAW;CACX,UAAU;CACV,SAAS;;CAET,UAAU;CACV,WAAW;CACX,UAAU;;CAEV,qBAAqB;CAErB,IAAI,gBAAyB;AAC3B,MAAI,CAAC,KAAK,SAAU,QAAO;AAC3B,SACE,KAAK,qBAAqB;;CAK9B;CACA;CAEA,YAAY,QAOT;EACD,MAAM,EAAE,MAAM,OAAO,OAAO,QAAQ,UAAU,aAAa;AAC3D,QAAM,MAAM,OAAO,OAAO,OAAO;AACjC,OAAK,WAAW;AAChB,OAAK,WAAW;AAEhB,SAAO,gBAAgB,KAAK;;CAG9B,IAAI,QAAgB;AAClB,SAAO,OAAO,EAAE,KAAK,KAAK,CAAC,IAAI,KAAK,SAAS,CAAC;;CAGhD,IAAI,MAAuB;AACzB,SAAO,EAAE,KAAK,KAAK,CAAC,IAAI,KAAK,SAAS;;;;;;CAOxC,UAAU,QAAuD;AACnD,SAAO,KAChB,KAAK,SAAS,KAAK,QAAQ,UAAU,OAAO"}
1
+ {"version":3,"file":"tree-node2.js","names":["TreeNode","CoreTreeNode"],"sources":["../../../src/components/tree/tree-node.ts"],"sourcesContent":["import { TreeNode as CoreTreeNode, o } from '@cat-kit/core'\nimport { shallowReactive } from 'vue'\n\nexport class TreeNode<Val extends Record<string, any> = Record<string, any>> extends CoreTreeNode<\n Val,\n TreeNode<Val>\n> {\n declare parent?: TreeNode<Val>\n\n declare children?: TreeNode<Val>[]\n\n expanded = false\n loading = false\n loaded = false\n /** 多选是否选中 */\n checked = false\n disabled = false\n visible = true\n /** 子节点选中数量 */\n childrenCheckCount = 0\n\n get indeterminate(): boolean {\n if (!this.children) return false\n return (\n this.childrenCheckCount > 0\n // && this.childrenCheckCount < this.children.length\n )\n }\n\n labelKey: string\n valueKey: string\n\n constructor(params: {\n data: Val\n index: number\n depth: number\n parent?: TreeNode<Val>\n labelKey: string\n valueKey: string\n }) {\n const { data, index, depth, parent, labelKey, valueKey } = params\n super(data, index, depth, parent)\n this.labelKey = labelKey\n this.valueKey = valueKey\n\n return shallowReactive(this)\n }\n\n get label(): string {\n return String(o(this.data).get(this.labelKey))\n }\n\n get key(): string | number {\n return o(this.data).get(this.valueKey) as string | number\n }\n\n /**\n * 向上冒泡设置\n * @param setter 设置函数, 返回 false 则停止冒泡\n */\n bubbleSet(setter: (node: TreeNode<Val>) => boolean | void): void {\n const ret = setter(this)\n ret !== false && this.parent?.bubbleSet(setter)\n }\n}\n"],"mappings":";;;AAGA,IAAaA,aAAb,cAAqFC,SAGnF;CAKA,WAAW;CACX,UAAU;CACV,SAAS;;CAET,UAAU;CACV,WAAW;CACX,UAAU;;CAEV,qBAAqB;CAErB,IAAI,gBAAyB;EAC3B,IAAI,CAAC,KAAK,UAAU,OAAO;EAC3B,OACE,KAAK,qBAAqB;;CAK9B;CACA;CAEA,YAAY,QAOT;EACD,MAAM,EAAE,MAAM,OAAO,OAAO,QAAQ,UAAU,aAAa;EAC3D,MAAM,MAAM,OAAO,OAAO,OAAO;EACjC,KAAK,WAAW;EAChB,KAAK,WAAW;EAEhB,OAAO,gBAAgB,KAAK;;CAG9B,IAAI,QAAgB;EAClB,OAAO,OAAO,EAAE,KAAK,KAAK,CAAC,IAAI,KAAK,SAAS,CAAC;;CAGhD,IAAI,MAAuB;EACzB,OAAO,EAAE,KAAK,KAAK,CAAC,IAAI,KAAK,SAAS;;;;;;CAOxC,UAAU,QAAuD;EAE/D,OADmB,KAChB,KAAK,SAAS,KAAK,QAAQ,UAAU,OAAO"}
@@ -1 +1 @@
1
- {"version":3,"file":"tree.js","names":[],"sources":["../../../src/components/tree/tree.vue"],"sourcesContent":["<template>\n <u-scroll\n :class=\"className\"\n ref=\"scrollRef\"\n :content-class=\"[cls.e('wrap'), bem.is('virtual', virtualEnabled)]\"\n >\n <template v-if=\"virtualEnabled\">\n <UTreeNode\n v-for=\"{ node, key, offset, index } of virtualNodes\"\n :node=\"node\"\n :key=\"key\"\n :class=\"bem.is('selected', node.data === selectedData)\"\n :index=\"index\"\n :measure-element=\"measureElement\"\n :style=\"{ transform: `translateY(${offset}px)` }\"\n />\n </template>\n <template v-else>\n <UTreeNode\n v-for=\"node of nodes\"\n :node=\"node\"\n :key=\"node.key\"\n :class=\"bem.is('selected', node.data === selectedData)\"\n />\n </template>\n\n <div :class=\"cls.e('empty')\" v-if=\"!nodes.length\">\n <UEmpty />\n </div>\n </u-scroll>\n</template>\n\n<script lang=\"ts\" setup>\nimport { useFormFallbackProps, useVirtualizer } from '@veltra/compositions'\nimport { bem, nextFrame, scrollIntoContainerView } from '@veltra/utils'\nimport { injectFormContext } from '@veltra/utils'\nimport { computed, provide, shallowRef, useSlots, watch, watchEffect, type VNode } from 'vue'\n\nimport type { TreeProps, TreeEmit, _TreeExposed } from '../../types'\nimport type { ScrollExposed } from '../../types'\nimport { UEmpty } from '../empty'\nimport { UScroll } from '../scroll'\nimport { TreeDIKey, type TreeConText, type TreeSlotsScope } from './di'\nimport UTreeNode from './tree-node.vue'\nimport { useCheck } from './use-check'\nimport { useFilter } from './use-filter'\nimport { useSelect } from './use-select'\nimport { useTreeNodes } from './use-tree-nodes'\n\ndefineOptions({\n name: 'Tree'\n})\n\nconst props = withDefaults(defineProps<TreeProps>(), {\n labelKey: 'label',\n valueKey: 'value',\n childrenKey: 'children',\n expandOnClickNode: false,\n checkStrictly: false,\n data: () => []\n})\n\nconst emit = defineEmits<TreeEmit>()\n\nconst cls = bem('tree')\n\nconst { formProps } = injectFormContext()\n\nconst { size } = useFormFallbackProps([formProps ?? {}, props], {\n size: 'default'\n})\n\nconst scrollRef = shallowRef<ScrollExposed>()\n\nconst className = computed(() => {\n return [\n cls.b,\n cls.m(size.value),\n bem.is('selectable', props.selectable),\n bem.is('checkable', props.checkable)\n ]\n})\n\ndefineSlots<{\n default: (props: TreeSlotsScope) => any\n}>()\n\nconst slots = useSlots()\n\nfunction getTreeSlotsNode(ctx: TreeSlotsScope): VNode[] | string | undefined {\n return (props.slots?.default ?? slots.default)?.(ctx) ?? ctx.node.label\n}\n\nconst { nodes, forest, getFlattedNodes, nodeDict } = useTreeNodes({\n props\n})\n\nwatch(\n [() => props.selectable, () => props.checkable, forest],\n ([s, c]) => {\n // 如果选择或勾选,则不更新节点\n if (s || c) return\n getFlattedNodes()\n },\n { immediate: true }\n)\n\nconst { filter } = useFilter({ forest, getFlattedNodes })\n\nconst { handleSelect, selectedData } = useSelect({\n props,\n emit,\n nodeDict,\n getFlattedNodes\n})\n\nconst { checkedData, toggleCheck } = useCheck({\n props,\n emit,\n nodeDict,\n getFlattedNodes\n})\n\nconst estimateSize = (): number => {\n // 基于 style.scss 中节点稳态高度推算的默认值;\n // 实际高度仍由 `measureElement` 通过 ResizeObserver 回填覆盖。\n switch (size.value) {\n case 'small':\n return 32\n case 'large':\n return 44\n default:\n return 36\n }\n}\n\n// 80 阈值内化为消费者侧语义;低于此值时不启用虚拟化。\nconst virtualEnabled = computed(() => nodes.value.length > 80)\n\nconst { virtualizer, items } = useVirtualizer({\n count: computed(() => nodes.value.length),\n scrollEl: () => scrollRef.value?.containerRef ?? null,\n // 仅在虚拟化启用时把内容容器的 height 撑开到 totalSize;\n // 关闭时传 null,hook 会清除此前写入的内联 height,回到 CSS 默认。\n contentEl: () => (virtualEnabled.value ? (scrollRef.value?.contentRef ?? null) : null),\n estimateSize,\n gap: 2,\n // 以节点稳定 key 作为虚拟项身份,展开 / 收起 / 过滤引起的 nodes 数组变更\n // 保留未移动节点的真实测量值,避免再次滚动首屏抖动。\n getItemKey: (i) => nodes.value[i]?.key ?? i\n})\n\n// 身份稳定性已由底层 `getItemKey` 保证;直接以 `node.key` 作为 Vue 层 key。\n// `item.index` 仅作为 nodes / snapshot 竞态边缘的 fallback。\nconst virtualNodes = computed(() => {\n const _nodes = nodes.value\n return items.value.map((item) => {\n const node = _nodes[item.index]!\n return {\n node,\n key: node?.key ?? item.index,\n offset: item.start,\n index: item.index\n }\n })\n})\n\nconst measureElement: (index: number, el: Element | null) => void = (index, el) =>\n virtualizer.measureElement(index, el)\n\nfunction scrollTo(index: number): void {\n virtualizer.scrollToIndex(index, { align: 'center' })\n}\n\nfunction scrollIntoView() {\n const { selectable, checkable, scrollToView } = props\n if (!scrollToView || (!selectable && !checkable) || !nodes.value) return\n let index = -1\n\n if (selectable) {\n if (!selectedData.value) return\n index = nodes.value.findIndex((node) => node.data === selectedData.value)\n } else if (checkable) {\n if (!checkedData.size) return\n index = nodes.value.findIndex((node) => checkedData.has(node.data))\n }\n\n if (virtualEnabled.value) {\n scrollTo(index)\n } else {\n const { contentRef, containerRef } = scrollRef.value ?? {}\n const el = contentRef?.children[index]\n el && scrollIntoContainerView(el as HTMLElement, containerRef ?? null)\n }\n}\n\nwatchEffect(() => {\n nextFrame(() => {\n scrollIntoView()\n })\n})\n\nprovide(TreeDIKey, {\n cls,\n selectedData,\n checkedData,\n getFlattedNodes,\n getTreeSlotsNode,\n treeEmit: emit as TreeEmit,\n treeProps: props as TreeProps,\n toggleCheck: toggleCheck as TreeConText['toggleCheck'],\n handleSelect: handleSelect as TreeConText['handleSelect']\n})\n\ndefineExpose<_TreeExposed>({\n filter,\n forest,\n nodes,\n checkNode: toggleCheck,\n selectNode: handleSelect,\n checkAll(check: boolean) {\n forest.value.roots.forEach((node) => {\n toggleCheck(node, check)\n })\n },\n getSelected() {\n return selectedData\n },\n getChecked() {\n return Array.from(checkedData)\n },\n scrollTo,\n\n expandAll() {\n forest.value.dfs((node) => {\n node.expanded = true\n })\n getFlattedNodes()\n },\n collapseAll() {\n forest.value.dfs((node) => {\n node.expanded = false\n })\n getFlattedNodes()\n }\n})\n</script>\n"],"mappings":"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"}
1
+ {"version":3,"file":"tree.js","names":[],"sources":["../../../src/components/tree/tree.vue"],"sourcesContent":["<template>\n <u-scroll\n :class=\"className\"\n ref=\"scrollRef\"\n :content-class=\"[cls.e('wrap'), bem.is('virtual', virtualEnabled)]\"\n >\n <template v-if=\"virtualEnabled\">\n <UTreeNode\n v-for=\"{ node, key, offset, index } of virtualNodes\"\n :node=\"node\"\n :key=\"key\"\n :class=\"bem.is('selected', node.data === selectedData)\"\n :index=\"index\"\n :measure-element=\"measureElement\"\n :style=\"{ transform: `translateY(${offset}px)` }\"\n />\n </template>\n <template v-else>\n <UTreeNode\n v-for=\"node of nodes\"\n :node=\"node\"\n :key=\"node.key\"\n :class=\"bem.is('selected', node.data === selectedData)\"\n />\n </template>\n\n <div :class=\"cls.e('empty')\" v-if=\"!nodes.length\">\n <UEmpty />\n </div>\n </u-scroll>\n</template>\n\n<script lang=\"ts\" setup>\nimport { useFormFallbackProps, useVirtualizer } from '@veltra/compositions'\nimport { bem, nextFrame, scrollIntoContainerView } from '@veltra/utils'\nimport { injectFormContext } from '@veltra/utils'\nimport { computed, provide, shallowRef, useSlots, watch, watchEffect, type VNode } from 'vue'\n\nimport type { TreeProps, TreeEmit, _TreeExposed } from '../../types'\nimport type { ScrollExposed } from '../../types'\nimport { UEmpty } from '../empty'\nimport { UScroll } from '../scroll'\nimport { TreeDIKey, type TreeConText, type TreeSlotsScope } from './di'\nimport UTreeNode from './tree-node.vue'\nimport { useCheck } from './use-check'\nimport { useFilter } from './use-filter'\nimport { useSelect } from './use-select'\nimport { useTreeNodes } from './use-tree-nodes'\n\ndefineOptions({\n name: 'Tree'\n})\n\nconst props = withDefaults(defineProps<TreeProps>(), {\n labelKey: 'label',\n valueKey: 'value',\n childrenKey: 'children',\n expandOnClickNode: false,\n checkStrictly: false,\n data: () => []\n})\n\nconst emit = defineEmits<TreeEmit>()\n\nconst cls = bem('tree')\n\nconst { formProps } = injectFormContext()\n\nconst { size } = useFormFallbackProps([formProps ?? {}, props], {\n size: 'default'\n})\n\nconst scrollRef = shallowRef<ScrollExposed>()\n\nconst className = computed(() => {\n return [\n cls.b,\n cls.m(size.value),\n bem.is('selectable', props.selectable),\n bem.is('checkable', props.checkable)\n ]\n})\n\ndefineSlots<{\n default: (props: TreeSlotsScope) => any\n}>()\n\nconst slots = useSlots()\n\nfunction getTreeSlotsNode(ctx: TreeSlotsScope): VNode[] | string | undefined {\n return (props.slots?.default ?? slots.default)?.(ctx) ?? ctx.node.label\n}\n\nconst { nodes, forest, getFlattedNodes, nodeDict } = useTreeNodes({\n props\n})\n\nwatch(\n [() => props.selectable, () => props.checkable, forest],\n ([s, c]) => {\n // 如果选择或勾选,则不更新节点\n if (s || c) return\n getFlattedNodes()\n },\n { immediate: true }\n)\n\nconst { filter } = useFilter({ forest, getFlattedNodes })\n\nconst { handleSelect, selectedData } = useSelect({\n props,\n emit,\n nodeDict,\n getFlattedNodes\n})\n\nconst { checkedData, toggleCheck } = useCheck({\n props,\n emit,\n nodeDict,\n getFlattedNodes\n})\n\nconst estimateSize = (): number => {\n // 基于 style.scss 中节点稳态高度推算的默认值;\n // 实际高度仍由 `measureElement` 通过 ResizeObserver 回填覆盖。\n switch (size.value) {\n case 'small':\n return 32\n case 'large':\n return 44\n default:\n return 36\n }\n}\n\n// 80 阈值内化为消费者侧语义;低于此值时不启用虚拟化。\nconst virtualEnabled = computed(() => nodes.value.length > 80)\n\nconst { virtualizer, items } = useVirtualizer({\n count: computed(() => nodes.value.length),\n scrollEl: () => scrollRef.value?.containerRef ?? null,\n // 仅在虚拟化启用时把内容容器的 height 撑开到 totalSize;\n // 关闭时传 null,hook 会清除此前写入的内联 height,回到 CSS 默认。\n contentEl: () => (virtualEnabled.value ? (scrollRef.value?.contentRef ?? null) : null),\n estimateSize,\n gap: 2,\n // 以节点稳定 key 作为虚拟项身份,展开 / 收起 / 过滤引起的 nodes 数组变更\n // 保留未移动节点的真实测量值,避免再次滚动首屏抖动。\n getItemKey: (i) => nodes.value[i]?.key ?? i\n})\n\n// 身份稳定性已由底层 `getItemKey` 保证;直接以 `node.key` 作为 Vue 层 key。\n// `item.index` 仅作为 nodes / snapshot 竞态边缘的 fallback。\nconst virtualNodes = computed(() => {\n const _nodes = nodes.value\n return items.value.map((item) => {\n const node = _nodes[item.index]!\n return {\n node,\n key: node?.key ?? item.index,\n offset: item.start,\n index: item.index\n }\n })\n})\n\nconst measureElement: (index: number, el: Element | null) => void = (index, el) =>\n virtualizer.measureElement(index, el)\n\nfunction scrollTo(index: number): void {\n virtualizer.scrollToIndex(index, { align: 'center' })\n}\n\nfunction scrollIntoView() {\n const { selectable, checkable, scrollToView } = props\n if (!scrollToView || (!selectable && !checkable) || !nodes.value) return\n let index = -1\n\n if (selectable) {\n if (!selectedData.value) return\n index = nodes.value.findIndex((node) => node.data === selectedData.value)\n } else if (checkable) {\n if (!checkedData.size) return\n index = nodes.value.findIndex((node) => checkedData.has(node.data))\n }\n\n if (virtualEnabled.value) {\n scrollTo(index)\n } else {\n const { contentRef, containerRef } = scrollRef.value ?? {}\n const el = contentRef?.children[index]\n el && scrollIntoContainerView(el as HTMLElement, containerRef ?? null)\n }\n}\n\nwatchEffect(() => {\n nextFrame(() => {\n scrollIntoView()\n })\n})\n\nprovide(TreeDIKey, {\n cls,\n selectedData,\n checkedData,\n getFlattedNodes,\n getTreeSlotsNode,\n treeEmit: emit as TreeEmit,\n treeProps: props as TreeProps,\n toggleCheck: toggleCheck as TreeConText['toggleCheck'],\n handleSelect: handleSelect as TreeConText['handleSelect']\n})\n\ndefineExpose<_TreeExposed>({\n filter,\n forest,\n nodes,\n checkNode: toggleCheck,\n selectNode: handleSelect,\n checkAll(check: boolean) {\n forest.value.roots.forEach((node) => {\n toggleCheck(node, check)\n })\n },\n getSelected() {\n return selectedData\n },\n getChecked() {\n return Array.from(checkedData)\n },\n scrollTo,\n\n expandAll() {\n forest.value.dfs((node) => {\n node.expanded = true\n })\n getFlattedNodes()\n },\n collapseAll() {\n forest.value.dfs((node) => {\n node.expanded = false\n })\n getFlattedNodes()\n }\n})\n</script>\n"],"mappings":"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"}