@veltra/desktop 1.1.1 → 1.1.3

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 (180) hide show
  1. package/dist/components/action/action-group.vue.d.ts +2 -2
  2. package/dist/components/auto-complete/auto-complete.js +3 -3
  3. package/dist/components/auto-complete/auto-complete.js.map +1 -1
  4. package/dist/components/auto-complete/auto-complete.vue.d.ts +2 -2
  5. package/dist/components/auto-complete/style2.css +2 -2
  6. package/dist/components/batch-edit/batch-edit.vue.d.ts +1 -1
  7. package/dist/components/cascade/cascade.js +3 -3
  8. package/dist/components/cascade/cascade.js.map +1 -1
  9. package/dist/components/cascade/cascade.vue.d.ts +5 -5
  10. package/dist/components/cascade/style2.css +1 -1
  11. package/dist/components/checkbox/checkbox-button.js +3 -3
  12. package/dist/components/checkbox/checkbox-button.js.map +1 -1
  13. package/dist/components/checkbox/checkbox-button.vue.d.ts +1 -1
  14. package/dist/components/checkbox/checkbox.js +3 -3
  15. package/dist/components/checkbox/checkbox.js.map +1 -1
  16. package/dist/components/checkbox/style2.css +2 -2
  17. package/dist/components/checkbox-group/checkbox-group.js +3 -3
  18. package/dist/components/checkbox-group/checkbox-group.js.map +1 -1
  19. package/dist/components/checkbox-group/checkbox-group.vue.d.ts +1 -1
  20. package/dist/components/code-editor/code-editor.js +3 -3
  21. package/dist/components/code-editor/code-editor.js.map +1 -1
  22. package/dist/components/code-editor/style2.css +1 -1
  23. package/dist/components/collapse/collapse-item.js +10 -35
  24. package/dist/components/collapse/collapse-item.js.map +1 -1
  25. package/dist/components/collapse/collapse.js +4 -2
  26. package/dist/components/collapse/collapse.js.map +1 -1
  27. package/dist/components/collapse/di.js +1 -0
  28. package/dist/components/collapse/di.js.map +1 -1
  29. package/dist/components/date-picker/date-picker.js +3 -3
  30. package/dist/components/date-picker/date-picker.js.map +1 -1
  31. package/dist/components/date-picker/date-picker.vue.d.ts +3 -3
  32. package/dist/components/date-range-picker/date-range-picker.js +3 -3
  33. package/dist/components/date-range-picker/date-range-picker.js.map +1 -1
  34. package/dist/components/date-range-picker/date-range-picker.vue.d.ts +3 -3
  35. package/dist/components/date-range-picker/style2.css +1 -1
  36. package/dist/components/dialog/style2.css +1 -1
  37. package/dist/components/drawer/drawer.vue.d.ts +2 -2
  38. package/dist/components/expression-editor/expression-editor.js +3 -3
  39. package/dist/components/expression-editor/expression-editor.js.map +1 -1
  40. package/dist/components/expression-editor/style2.css +5 -5
  41. package/dist/components/file-viewer/file-viewer.vue.d.ts +1 -1
  42. package/dist/components/form/form.js.map +1 -1
  43. package/dist/components/form/form.vue_vue_type_script_setup_true_lang.js +2 -3
  44. package/dist/components/form/form.vue_vue_type_script_setup_true_lang.js.map +1 -1
  45. package/dist/components/form-item/form-item.js.map +1 -1
  46. package/dist/components/form-item/form-item.vue_vue_type_script_setup_true_lang.js +3 -3
  47. package/dist/components/form-item/form-item.vue_vue_type_script_setup_true_lang.js.map +1 -1
  48. package/dist/components/form-item/style2.css +0 -1
  49. package/dist/components/grid-input/style2.css +3 -3
  50. package/dist/components/group-input/group-input.js +3 -3
  51. package/dist/components/group-input/group-input.js.map +1 -1
  52. package/dist/components/input/input.js.map +1 -1
  53. package/dist/components/input/input.vue.d.ts +4 -4
  54. package/dist/components/input/input.vue_vue_type_script_setup_true_lang.js +3 -3
  55. package/dist/components/input/input.vue_vue_type_script_setup_true_lang.js.map +1 -1
  56. package/dist/components/input/style2.css +1 -1
  57. package/dist/components/menu/di.js +1 -0
  58. package/dist/components/menu/di.js.map +1 -1
  59. package/dist/components/menu/menu-sub.js +7 -15
  60. package/dist/components/menu/menu-sub.js.map +1 -1
  61. package/dist/components/menu/menu.js +8 -2
  62. package/dist/components/menu/menu.js.map +1 -1
  63. package/dist/components/multi-select/multi-select.js +3 -3
  64. package/dist/components/multi-select/multi-select.js.map +1 -1
  65. package/dist/components/multi-select/multi-select.vue.d.ts +4 -4
  66. package/dist/components/multi-select/style2.css +2 -2
  67. package/dist/components/multi-tree-select/multi-tree-select.js +3 -3
  68. package/dist/components/multi-tree-select/multi-tree-select.js.map +1 -1
  69. package/dist/components/multi-tree-select/multi-tree-select.vue.d.ts +6 -6
  70. package/dist/components/multi-tree-select/style2.css +2 -2
  71. package/dist/components/notification/notification.vue.d.ts +1 -1
  72. package/dist/components/number/number.vue.d.ts +1 -1
  73. package/dist/components/number-input/number-input.js +3 -3
  74. package/dist/components/number-input/number-input.js.map +1 -1
  75. package/dist/components/number-input/number-input.vue.d.ts +4 -4
  76. package/dist/components/number-range-input/number-range-input.js +3 -3
  77. package/dist/components/number-range-input/number-range-input.js.map +1 -1
  78. package/dist/components/number-range-input/number-range-input.vue.d.ts +1 -1
  79. package/dist/components/palette/palette.js +3 -3
  80. package/dist/components/palette/palette.js.map +1 -1
  81. package/dist/components/password-input/password-input.js +4 -4
  82. package/dist/components/password-input/password-input.js.map +1 -1
  83. package/dist/components/password-input/password-input.vue.d.ts +1 -1
  84. package/dist/components/pop-confirm/pop-confirm.js +3 -3
  85. package/dist/components/pop-confirm/pop-confirm.js.map +1 -1
  86. package/dist/components/pop-confirm/pop-confirm.vue.d.ts +1 -1
  87. package/dist/components/progress-nodes/progress-nodes.vue.d.ts +2 -2
  88. package/dist/components/radio/radio.js +3 -3
  89. package/dist/components/radio/radio.js.map +1 -1
  90. package/dist/components/radio/style2.css +1 -1
  91. package/dist/components/radio-group/radio-group.js +3 -3
  92. package/dist/components/radio-group/radio-group.js.map +1 -1
  93. package/dist/components/radio-group/radio-group.vue.d.ts +1 -1
  94. package/dist/components/radio-group/style2.css +1 -1
  95. package/dist/components/rich-text-editor/rich-text-editor.js +3 -3
  96. package/dist/components/rich-text-editor/rich-text-editor.js.map +1 -1
  97. package/dist/components/rich-text-editor/rich-text-editor.vue.d.ts +1 -1
  98. package/dist/components/rich-text-editor/style2.css +5 -5
  99. package/dist/components/select/select.js +4 -4
  100. package/dist/components/select/select.js.map +1 -1
  101. package/dist/components/select/select.vue.d.ts +3 -3
  102. package/dist/components/slider/slider.js +3 -3
  103. package/dist/components/slider/slider.js.map +1 -1
  104. package/dist/components/steps/steps.vue.d.ts +1 -1
  105. package/dist/components/switch/style2.css +1 -1
  106. package/dist/components/switch/switch.js +3 -3
  107. package/dist/components/switch/switch.js.map +1 -1
  108. package/dist/components/table/table.vue.d.ts +2 -2
  109. package/dist/components/tabs/tabs-horizontal.vue.d.ts +3 -3
  110. package/dist/components/tabs/tabs-vertical.vue.d.ts +3 -3
  111. package/dist/components/tabs/tabs.vue.d.ts +3 -3
  112. package/dist/components/tag/tag.js +3 -3
  113. package/dist/components/tag/tag.js.map +1 -1
  114. package/dist/components/textarea/style2.css +1 -1
  115. package/dist/components/textarea/textarea.js +3 -3
  116. package/dist/components/textarea/textarea.js.map +1 -1
  117. package/dist/components/textarea/textarea.vue.d.ts +4 -4
  118. package/dist/components/tree/tree.js +3 -3
  119. package/dist/components/tree/tree.js.map +1 -1
  120. package/dist/components/tree-select/tree-select.js +3 -3
  121. package/dist/components/tree-select/tree-select.js.map +1 -1
  122. package/dist/components/tree-select/tree-select.vue.d.ts +6 -6
  123. package/package.json +11 -11
  124. package/src/components/auto-complete/auto-complete.vue +3 -2
  125. package/src/components/auto-complete/style.scss +2 -2
  126. package/src/components/cascade/cascade.vue +3 -2
  127. package/src/components/cascade/style.scss +1 -1
  128. package/src/components/checkbox/checkbox-button.vue +3 -2
  129. package/src/components/checkbox/checkbox.vue +3 -2
  130. package/src/components/checkbox/style.scss +2 -2
  131. package/src/components/checkbox-group/checkbox-group.vue +3 -2
  132. package/src/components/code-editor/code-editor.vue +3 -2
  133. package/src/components/code-editor/style.scss +1 -1
  134. package/src/components/collapse/collapse-item.vue +11 -49
  135. package/src/components/collapse/collapse.vue +7 -2
  136. package/src/components/collapse/di.ts +2 -1
  137. package/src/components/collapse/style.scss +1 -1
  138. package/src/components/date-picker/date-picker.vue +3 -2
  139. package/src/components/date-range-picker/date-range-picker.vue +3 -2
  140. package/src/components/date-range-picker/style.scss +1 -1
  141. package/src/components/dialog/style.scss +1 -1
  142. package/src/components/expression-editor/expression-editor.vue +3 -2
  143. package/src/components/expression-editor/style.scss +5 -5
  144. package/src/components/form/form.vue +2 -2
  145. package/src/components/form-item/form-item.vue +3 -2
  146. package/src/components/form-item/style.scss +0 -1
  147. package/src/components/grid-input/style.scss +1 -1
  148. package/src/components/group-input/group-input.vue +3 -2
  149. package/src/components/input/input.vue +3 -2
  150. package/src/components/input/style.scss +1 -1
  151. package/src/components/menu/di.ts +2 -1
  152. package/src/components/menu/menu-sub.vue +6 -9
  153. package/src/components/menu/menu.vue +11 -2
  154. package/src/components/multi-select/multi-select.vue +3 -2
  155. package/src/components/multi-select/style.scss +2 -2
  156. package/src/components/multi-tree-select/multi-tree-select.vue +3 -2
  157. package/src/components/multi-tree-select/style.scss +2 -2
  158. package/src/components/number-input/number-input.vue +3 -2
  159. package/src/components/number-range-input/number-range-input.vue +3 -2
  160. package/src/components/palette/palette.vue +3 -2
  161. package/src/components/password-input/password-input.vue +4 -3
  162. package/src/components/pop-confirm/pop-confirm.vue +3 -2
  163. package/src/components/radio/radio.vue +3 -2
  164. package/src/components/radio/style.scss +1 -1
  165. package/src/components/radio-group/radio-group.vue +3 -2
  166. package/src/components/radio-group/style.scss +1 -1
  167. package/src/components/rich-text-editor/rich-text-editor.vue +3 -2
  168. package/src/components/rich-text-editor/style.scss +5 -5
  169. package/src/components/select/select.vue +4 -3
  170. package/src/components/slider/slider.vue +3 -2
  171. package/src/components/switch/style.scss +1 -1
  172. package/src/components/switch/switch.vue +3 -2
  173. package/src/components/tag/tag.vue +3 -2
  174. package/src/components/textarea/style.scss +1 -1
  175. package/src/components/textarea/textarea.vue +3 -2
  176. package/src/components/tree/tree.vue +3 -2
  177. package/src/components/tree-select/tree-select.vue +3 -2
  178. package/dist/components/menu/use-menu-transition.js +0 -71
  179. package/dist/components/menu/use-menu-transition.js.map +0 -1
  180. package/src/components/menu/use-menu-transition.ts +0 -69
@@ -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 { useFormComponent, useFormFallbackProps, useVirtualizer } from '@veltra/compositions'\nimport { bem, nextFrame, scrollIntoContainerView } 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 } = useFormComponent()\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":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAqDA,MAAM,QAAQ;EASd,MAAM,OAAO;EAEb,MAAM,MAAM,IAAI,OAAM;EAEtB,MAAM,EAAE,cAAc,mBAAkB;EAExC,MAAM,EAAE,SAAS,qBAAqB,CAAC,aAAa,EAAE,EAAE,MAAM,EAAE,EAC9D,MAAM,WACP,CAAA;EAED,MAAM,YAAY,YAA0B;EAE5C,MAAM,YAAY,eAAe;AAC/B,UAAO;IACL,IAAI;IACJ,IAAI,EAAE,KAAK,MAAM;IACjB,IAAI,GAAG,cAAc,MAAM,WAAW;IACtC,IAAI,GAAG,aAAa,MAAM,UAAS;IACrC;IACD;EAMD,MAAM,QAAQ,UAAS;EAEvB,SAAS,iBAAiB,KAAmD;AAC3E,WAAQ,MAAM,OAAO,WAAW,MAAM,WAAW,IAAI,IAAI,IAAI,KAAK;;EAGpE,MAAM,EAAE,OAAO,QAAQ,iBAAiB,aAAa,aAAa,EAChE,OACD,CAAA;AAED,QACE;SAAO,MAAM;SAAkB,MAAM;GAAW;GAAO,GACtD,CAAC,GAAG,OAAO;AAEV,OAAI,KAAK,EAAG;AACZ,oBAAgB;KAElB,EAAE,WAAW,MAAK,CACpB;EAEA,MAAM,EAAE,WAAW,UAAU;GAAE;GAAQ;GAAiB,CAAA;EAExD,MAAM,EAAE,cAAc,iBAAiB,UAAU;GAC/C;GACA;GACA;GACA;GACD,CAAA;EAED,MAAM,EAAE,aAAa,gBAAgB,SAAS;GAC5C;GACA;GACA;GACA;GACD,CAAA;EAED,MAAM,qBAA6B;AAGjC,WAAQ,KAAK,OAAb;IACE,KAAK,QACH,QAAO;IACT,KAAK,QACH,QAAO;IACT,QACE,QAAO;;;EAKb,MAAM,iBAAiB,eAAe,MAAM,MAAM,SAAS,GAAE;EAE7D,MAAM,EAAE,aAAa,UAAU,eAAe;GAC5C,OAAO,eAAe,MAAM,MAAM,OAAO;GACzC,gBAAgB,UAAU,OAAO,gBAAgB;GAGjD,iBAAkB,eAAe,QAAS,UAAU,OAAO,cAAc,OAAQ;GACjF;GACA,KAAK;GAGL,aAAa,MAAM,MAAM,MAAM,IAAI,OAAO;GAC3C,CAAA;EAID,MAAM,eAAe,eAAe;GAClC,MAAM,SAAS,MAAM;AACrB,UAAO,MAAM,MAAM,KAAK,SAAS;IAC/B,MAAM,OAAO,OAAO,KAAK;AACzB,WAAO;KACL;KACA,KAAK,MAAM,OAAO,KAAK;KACvB,QAAQ,KAAK;KACb,OAAO,KAAK;KACd;KACD;IACF;EAED,MAAM,kBAA+D,OAAO,OAC1E,YAAY,eAAe,OAAO,GAAE;EAEtC,SAAS,SAAS,OAAqB;AACrC,eAAY,cAAc,OAAO,EAAE,OAAO,UAAU,CAAA;;EAGtD,SAAS,iBAAiB;GACxB,MAAM,EAAE,YAAY,WAAW,iBAAiB;AAChD,OAAI,CAAC,gBAAiB,CAAC,cAAc,CAAC,aAAc,CAAC,MAAM,MAAO;GAClE,IAAI,QAAQ;AAEZ,OAAI,YAAY;AACd,QAAI,CAAC,aAAa,MAAO;AACzB,YAAQ,MAAM,MAAM,WAAW,SAAS,KAAK,SAAS,aAAa,MAAK;cAC/D,WAAW;AACpB,QAAI,CAAC,YAAY,KAAM;AACvB,YAAQ,MAAM,MAAM,WAAW,SAAS,YAAY,IAAI,KAAK,KAAK,CAAA;;AAGpE,OAAI,eAAe,MACjB,UAAS,MAAK;QACT;IACL,MAAM,EAAE,YAAY,iBAAiB,UAAU,SAAS,EAAC;IACzD,MAAM,KAAK,YAAY,SAAS;AAChC,UAAM,wBAAwB,IAAmB,gBAAgB,KAAI;;;AAIzE,oBAAkB;AAChB,mBAAgB;AACd,oBAAe;KAChB;IACF;AAED,UAAQ,WAAW;GACjB;GACA;GACA;GACA;GACA;GACA,UAAU;GACV,WAAW;GACE;GACC;GACf,CAAA;AAED,WAA2B;GACzB;GACA;GACA;GACA,WAAW;GACX,YAAY;GACZ,SAAS,OAAgB;AACvB,WAAO,MAAM,MAAM,SAAS,SAAS;AACnC,iBAAY,MAAM,MAAK;MACxB;;GAEH,cAAc;AACZ,WAAO;;GAET,aAAa;AACX,WAAO,MAAM,KAAK,YAAW;;GAE/B;GAEA,YAAY;AACV,WAAO,MAAM,KAAK,SAAS;AACzB,UAAK,WAAW;MACjB;AACD,qBAAgB;;GAElB,cAAc;AACZ,WAAO,MAAM,KAAK,SAAS;AACzB,UAAK,WAAW;MACjB;AACD,qBAAgB;;GAEnB,CAAA;;uBApPC,YA4BW,MAAA,YAAA,EAAA;IA3BR,OAAK,eAAE,UAAA,MAAS;aACb;IAAJ,KAAI;IACH,iBAAa,CAAG,MAAA,IAAG,CAAC,EAAC,OAAA,EAAU,MAAA,IAAG,CAAC,GAAE,WAAY,eAAA,MAAc,CAAA;;2BAYrD,CAVK,eAAA,SAAA,UAAA,KAAA,EACd,mBAQE,UAAA,EAAA,KAAA,GAAA,EAAA,WAPuC,aAAA,QAAY,EAA1C,MAAM,KAAK,QAAQ,YAAK;yBADnC,YAQE,aAAA;MANO;MACD;MACL,OAAK,eAAE,MAAA,IAAG,CAAC,GAAE,YAAa,KAAK,SAAS,MAAA,aAAY,CAAA,CAAA;MAC7C;MACP,mBAAiB;MACjB,OAAK,eAAA,EAAA,WAAA,cAA6B,OAAM,MAAA,CAAA;;;;;;;kCAI3C,mBAKE,UAAA,EAAA,KAAA,GAAA,EAAA,WAJe,MAAA,MAAK,GAAb,SAAI;yBADb,YAKE,aAAA;MAHO;MACN,KAAK,KAAK;MACV,OAAK,eAAE,MAAA,IAAG,CAAC,GAAE,YAAa,KAAK,SAAS,MAAA,aAAY,CAAA,CAAA;;gBAIrB,MAAA,MAAK,CAAC,UAAA,WAAA,EAA1C,mBAEM,OAAA;;KAFA,OAAK,eAAE,MAAA,IAAG,CAAC,EAAC,QAAA,CAAA;QAChB,YAAU,MAAA,YAAA,CAAA,CAAA,EAAA,EAAA,IAAA,mBAAA,QAAA,KAAA,CAAA,CAAA"}
@@ -3,8 +3,8 @@ import _sfc_main$2 from "../tree/tree.js";
3
3
  import _sfc_main$3 from "../dropdown/dropdown.js";
4
4
  import input_default from "../input/input.js";
5
5
  import { Fragment, computed, createBlock, createCommentVNode, createElementBlock, createSlots, createTextVNode, createVNode, defineComponent, mergeModels, mergeProps, nextTick, normalizeClass, openBlock, renderSlot, shallowRef, toDisplayString, unref, useModel, useSlots, watch, withCtx } from "vue";
6
- import { FORM_EMPTY_CONTENT, bem } from "@veltra/utils";
7
- import { useFormComponent, useFormFallbackProps } from "@veltra/compositions";
6
+ import { FORM_EMPTY_CONTENT, bem, injectFormContext } from "@veltra/utils";
7
+ import { useFormFallbackProps } from "@veltra/compositions";
8
8
  import { dfs, o } from "@cat-kit/core";
9
9
  import { ArrowDown, Search } from "@veltra/icons/normal";
10
10
  //#region src/components/tree-select/tree-select.vue
@@ -88,7 +88,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
88
88
  });
89
89
  const model = useModel(__props, "modelValue");
90
90
  const label = shallowRef();
91
- const { formProps } = useFormComponent();
91
+ const { formProps } = injectFormContext();
92
92
  const { size, disabled, readonly } = useFormFallbackProps([formProps ?? {}, props]);
93
93
  const treeRef = shallowRef();
94
94
  const dropdownRef = shallowRef();
@@ -1 +1 @@
1
- {"version":3,"file":"tree-select.js","names":["$slots"],"sources":["../../../src/components/tree-select/tree-select.vue"],"sourcesContent":["<template>\n <u-dropdown\n v-if=\"!readonly\"\n :class=\"[cls.b, bem.is('disabled', disabled)]\"\n trigger=\"click\"\n :content-class=\"[cls.e('panel'), cls.em('panel', size), contentClass]\"\n :content-style=\"contentStyle\"\n ref=\"dropdownRef\"\n :min-width=\"minWidth\"\n :width=\"width\"\n :disabled=\"disabled\"\n @update:visible=\"handleDropdownVisible\"\n >\n <template #trigger>\n <u-input\n :size=\"size\"\n :disabled=\"disabled\"\n :placeholder=\"placeholder\"\n :clearable=\"clearable\"\n :model-value=\"text ?? (model ? label : undefined)\"\n @clear=\"handleClear\"\n native-readonly\n >\n <template #prefix v-if=\"$slots.prefix\">\n <slot name=\"prefix\" />\n </template>\n <template #suffix>\n <u-icon :class=\"cls.e('arrow')\"><ArrowDown /></u-icon>\n </template>\n </u-input>\n </template>\n <template #content>\n <!-- 过滤器 -->\n <div v-if=\"filterable\" :class=\"[cls.e('content-filter'), cls.m(size)]\">\n <u-input placeholder=\"输入关键字进行过滤\" v-model=\"qs\">\n <template #suffix>\n <u-icon><Search /></u-icon>\n </template>\n </u-input>\n </div>\n <!-- 菜单列表 -->\n\n <u-tree\n v-bind=\"treeProps\"\n :selected=\"model\"\n @update:selected=\"handleSelect\"\n ref=\"treeRef\"\n selectable\n :class=\"cls.e('content-tree')\"\n :slots=\"slots\"\n scroll-to-view\n />\n </template>\n </u-dropdown>\n\n <template v-else>\n {{ text || label || FORM_EMPTY_CONTENT }}\n </template>\n</template>\n\n<script lang=\"ts\" setup>\nimport { dfs, o } from '@cat-kit/core'\nimport { useFormComponent, useFormFallbackProps } from '@veltra/compositions'\nimport { ArrowDown, Search } from '@veltra/icons/normal'\nimport { bem, FORM_EMPTY_CONTENT } from '@veltra/utils'\nimport { computed, nextTick, shallowRef, watch } from 'vue'\n\nimport type { TreeSelectProps, TreeSelectEmits, TreeExposed } from '../../types'\nimport { UDropdown } from '../dropdown'\nimport { UIcon } from '../icon'\nimport { UInput } from '../input'\nimport { UTree } from '../tree'\nimport type { TreeSlotsScope } from '../tree/di'\n\ndefineOptions({ name: 'TreeSelect' })\n\nconst props = withDefaults(defineProps<TreeSelectProps>(), {\n labelKey: 'label',\n valueKey: 'value',\n placeholder: '请选择',\n expandAll: false,\n clearable: true,\n disabled: undefined,\n readonly: undefined,\n filterable: false,\n minWidth: '280px'\n})\n\nconst emit = defineEmits<TreeSelectEmits>()\n\nconst slots = defineSlots<{\n /** 默认插槽 */\n default?: (props: TreeSlotsScope) => any\n /** 前缀插槽 */\n prefix?: () => any\n}>()\n\nconst treeProps = computed(() => {\n return o(props as Record<string, any>).omit([\n 'tips',\n 'field',\n 'placeholder',\n 'disabled',\n 'label',\n 'readonly',\n 'contentClass',\n 'contentStyle',\n 'minWidth',\n 'width'\n ])\n})\n\nconst cls = bem('tree-select')\n\n/**过滤 */\nconst qs = shallowRef('')\nwatch(qs, (qs) => {\n treeRef.value?.filter(qs)\n})\n\nconst model = defineModel<string | number>()\n\nconst label = shallowRef<string>()\n\nconst { formProps } = useFormComponent()\n\nconst { size, disabled, readonly } = useFormFallbackProps([formProps ?? {}, props])\n\nconst treeRef = shallowRef<TreeExposed>()\n\nconst dropdownRef = shallowRef<InstanceType<typeof UDropdown>>()\n\n/**清空 */\nconst handleClear = () => {\n model.value = ''\n label.value = undefined\n emit('clear')\n emit('change', '', undefined)\n emit('update:text', '')\n}\n\nlet changedByEvent = false\nwatch(\n [() => props.data, model],\n ([data, model]) => {\n if (changedByEvent) return\n if (!data?.length || model === undefined) {\n label.value = undefined\n model = undefined\n return\n }\n\n let founded = false\n const childrenKey = props.childrenKey ?? 'children'\n data.some((item) => {\n dfs(\n item,\n (v) => {\n if (v[props.valueKey] === model) {\n label.value = v[props.labelKey]\n founded = true\n return true\n }\n },\n childrenKey\n )\n\n return founded\n })\n },\n { immediate: true }\n)\n\nconst handleSelect = (selected?: string | number, selectedData?: Record<string, any>) => {\n changedByEvent = true\n nextTick(() => {\n changedByEvent = false\n })\n\n model.value = selected ?? ''\n\n if (selectedData) {\n label.value = o(selectedData).get(props.labelKey)\n } else {\n label.value = ''\n }\n\n emit('change', selected, selectedData)\n emit('update:text', label.value)\n dropdownRef.value?.close()\n}\n\nconst handleDropdownVisible = (visible: boolean) => {\n if (!visible) {\n qs.value = ''\n }\n}\n</script>\n"],"mappings":"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"}
1
+ {"version":3,"file":"tree-select.js","names":["$slots"],"sources":["../../../src/components/tree-select/tree-select.vue"],"sourcesContent":["<template>\n <u-dropdown\n v-if=\"!readonly\"\n :class=\"[cls.b, bem.is('disabled', disabled)]\"\n trigger=\"click\"\n :content-class=\"[cls.e('panel'), cls.em('panel', size), contentClass]\"\n :content-style=\"contentStyle\"\n ref=\"dropdownRef\"\n :min-width=\"minWidth\"\n :width=\"width\"\n :disabled=\"disabled\"\n @update:visible=\"handleDropdownVisible\"\n >\n <template #trigger>\n <u-input\n :size=\"size\"\n :disabled=\"disabled\"\n :placeholder=\"placeholder\"\n :clearable=\"clearable\"\n :model-value=\"text ?? (model ? label : undefined)\"\n @clear=\"handleClear\"\n native-readonly\n >\n <template #prefix v-if=\"$slots.prefix\">\n <slot name=\"prefix\" />\n </template>\n <template #suffix>\n <u-icon :class=\"cls.e('arrow')\"><ArrowDown /></u-icon>\n </template>\n </u-input>\n </template>\n <template #content>\n <!-- 过滤器 -->\n <div v-if=\"filterable\" :class=\"[cls.e('content-filter'), cls.m(size)]\">\n <u-input placeholder=\"输入关键字进行过滤\" v-model=\"qs\">\n <template #suffix>\n <u-icon><Search /></u-icon>\n </template>\n </u-input>\n </div>\n <!-- 菜单列表 -->\n\n <u-tree\n v-bind=\"treeProps\"\n :selected=\"model\"\n @update:selected=\"handleSelect\"\n ref=\"treeRef\"\n selectable\n :class=\"cls.e('content-tree')\"\n :slots=\"slots\"\n scroll-to-view\n />\n </template>\n </u-dropdown>\n\n <template v-else>\n {{ text || label || FORM_EMPTY_CONTENT }}\n </template>\n</template>\n\n<script lang=\"ts\" setup>\nimport { dfs, o } from '@cat-kit/core'\nimport { useFormFallbackProps } from '@veltra/compositions'\nimport { ArrowDown, Search } from '@veltra/icons/normal'\nimport { bem, FORM_EMPTY_CONTENT } from '@veltra/utils'\nimport { injectFormContext } from '@veltra/utils'\nimport { computed, nextTick, shallowRef, watch } from 'vue'\n\nimport type { TreeSelectProps, TreeSelectEmits, TreeExposed } from '../../types'\nimport { UDropdown } from '../dropdown'\nimport { UIcon } from '../icon'\nimport { UInput } from '../input'\nimport { UTree } from '../tree'\nimport type { TreeSlotsScope } from '../tree/di'\n\ndefineOptions({ name: 'TreeSelect' })\n\nconst props = withDefaults(defineProps<TreeSelectProps>(), {\n labelKey: 'label',\n valueKey: 'value',\n placeholder: '请选择',\n expandAll: false,\n clearable: true,\n disabled: undefined,\n readonly: undefined,\n filterable: false,\n minWidth: '280px'\n})\n\nconst emit = defineEmits<TreeSelectEmits>()\n\nconst slots = defineSlots<{\n /** 默认插槽 */\n default?: (props: TreeSlotsScope) => any\n /** 前缀插槽 */\n prefix?: () => any\n}>()\n\nconst treeProps = computed(() => {\n return o(props as Record<string, any>).omit([\n 'tips',\n 'field',\n 'placeholder',\n 'disabled',\n 'label',\n 'readonly',\n 'contentClass',\n 'contentStyle',\n 'minWidth',\n 'width'\n ])\n})\n\nconst cls = bem('tree-select')\n\n/**过滤 */\nconst qs = shallowRef('')\nwatch(qs, (qs) => {\n treeRef.value?.filter(qs)\n})\n\nconst model = defineModel<string | number>()\n\nconst label = shallowRef<string>()\n\nconst { formProps } = injectFormContext()\n\nconst { size, disabled, readonly } = useFormFallbackProps([formProps ?? {}, props])\n\nconst treeRef = shallowRef<TreeExposed>()\n\nconst dropdownRef = shallowRef<InstanceType<typeof UDropdown>>()\n\n/**清空 */\nconst handleClear = () => {\n model.value = ''\n label.value = undefined\n emit('clear')\n emit('change', '', undefined)\n emit('update:text', '')\n}\n\nlet changedByEvent = false\nwatch(\n [() => props.data, model],\n ([data, model]) => {\n if (changedByEvent) return\n if (!data?.length || model === undefined) {\n label.value = undefined\n model = undefined\n return\n }\n\n let founded = false\n const childrenKey = props.childrenKey ?? 'children'\n data.some((item) => {\n dfs(\n item,\n (v) => {\n if (v[props.valueKey] === model) {\n label.value = v[props.labelKey]\n founded = true\n return true\n }\n },\n childrenKey\n )\n\n return founded\n })\n },\n { immediate: true }\n)\n\nconst handleSelect = (selected?: string | number, selectedData?: Record<string, any>) => {\n changedByEvent = true\n nextTick(() => {\n changedByEvent = false\n })\n\n model.value = selected ?? ''\n\n if (selectedData) {\n label.value = o(selectedData).get(props.labelKey)\n } else {\n label.value = ''\n }\n\n emit('change', selected, selectedData)\n emit('update:text', label.value)\n dropdownRef.value?.close()\n}\n\nconst handleDropdownVisible = (visible: boolean) => {\n if (!visible) {\n qs.value = ''\n }\n}\n</script>\n"],"mappings":"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"}
@@ -15,24 +15,24 @@ type __VLS_PublicProps = __VLS_Props & __VLS_ModelProps;
15
15
  declare const __VLS_base: _$vue.DefineComponent<__VLS_PublicProps, {}, {}, {}, {}, _$vue.ComponentOptionsMixin, _$vue.ComponentOptionsMixin, {
16
16
  "update:modelValue": (value: string | number | undefined) => any;
17
17
  } & {
18
- clear: () => any;
19
18
  change: (value?: string | number | undefined, selectedData?: Record<string, any> | undefined) => any;
19
+ clear: () => any;
20
20
  "update:text": (text?: string | undefined) => any;
21
21
  }, string, _$vue.PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
22
22
  "onUpdate:modelValue"?: ((value: string | number | undefined) => any) | undefined;
23
- onClear?: (() => any) | undefined;
24
23
  onChange?: ((value?: string | number | undefined, selectedData?: Record<string, any> | undefined) => any) | undefined;
24
+ onClear?: (() => any) | undefined;
25
25
  "onUpdate:text"?: ((text?: string | undefined) => any) | undefined;
26
26
  }>, {
27
- minWidth: string;
28
- disabled: boolean;
29
27
  expandAll: boolean;
30
28
  labelKey: string;
31
29
  valueKey: string;
32
- readonly: boolean;
33
- placeholder: string;
34
30
  clearable: boolean;
31
+ placeholder: string;
35
32
  filterable: boolean;
33
+ minWidth: string;
34
+ disabled: boolean;
35
+ readonly: boolean;
36
36
  }, {}, {}, {}, string, _$vue.ComponentProvideOptions, false, {}, any>;
37
37
  declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
38
38
  declare const _default: typeof __VLS_export;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@veltra/desktop",
3
- "version": "1.1.1",
3
+ "version": "1.1.3",
4
4
  "files": [
5
5
  "dist",
6
6
  "src"
@@ -61,22 +61,22 @@
61
61
  "@lexical/rich-text": "^0.43.0",
62
62
  "@lexical/selection": "^0.43.0",
63
63
  "@lexical/utils": "^0.43.0",
64
- "@veltra/compositions": "1.1.1",
65
- "@veltra/directives": "1.1.1",
66
- "@veltra/icons": "1.1.1",
67
- "@veltra/styles": "1.1.1",
68
- "@veltra/utils": "1.1.1",
64
+ "@veltra/compositions": "1.1.3",
65
+ "@veltra/directives": "1.1.3",
66
+ "@veltra/icons": "1.1.3",
67
+ "@veltra/styles": "1.1.3",
68
+ "@veltra/utils": "1.1.3",
69
69
  "@visactor/vtable": "^1.26.0",
70
70
  "codemirror": "^6.0.2",
71
71
  "docx-preview": "^0.3.7",
72
72
  "lexical": "^0.43.0"
73
73
  },
74
74
  "peerDependencies": {
75
- "@veltra/compositions": "1.1.1",
76
- "@veltra/directives": "1.1.1",
77
- "@veltra/icons": "1.1.1",
78
- "@veltra/styles": "1.1.1",
79
- "@veltra/utils": "1.1.1",
75
+ "@veltra/compositions": "1.1.3",
76
+ "@veltra/directives": "1.1.3",
77
+ "@veltra/icons": "1.1.3",
78
+ "@veltra/styles": "1.1.3",
79
+ "@veltra/utils": "1.1.3",
80
80
  "vue": "^3.5.33"
81
81
  }
82
82
  }
@@ -71,9 +71,10 @@
71
71
  </template>
72
72
 
73
73
  <script lang="ts" setup>
74
- import { useFormComponent, useFormFallbackProps } from '@veltra/compositions'
74
+ import { useFormFallbackProps } from '@veltra/compositions'
75
75
  import { vRipple } from '@veltra/directives'
76
76
  import { bem, FORM_EMPTY_CONTENT, scrollIntoContainerView } from '@veltra/utils'
77
+ import { injectFormContext } from '@veltra/utils'
77
78
  import { computed, shallowRef, watch } from 'vue'
78
79
 
79
80
  import type { AutoCompleteEmits, AutoCompleteProps, _AutoCompleteExposed } from '../../types'
@@ -108,7 +109,7 @@ const cls = bem('auto-complete')
108
109
 
109
110
  const optionClass = cls.e('option')
110
111
 
111
- const { formProps } = useFormComponent()
112
+ const { formProps } = injectFormContext()
112
113
  const { size, disabled, readonly } = useFormFallbackProps([formProps ?? {}, props], {
113
114
  size: 'default',
114
115
  disabled: false,
@@ -22,7 +22,7 @@ $root-name: auto-complete;
22
22
  }
23
23
 
24
24
  @include m.bem(tag) {
25
- border: fn.use-var(border);
25
+ border: fn.use-var(border-muted);
26
26
  }
27
27
  }
28
28
 
@@ -68,7 +68,7 @@ $root-name: auto-complete;
68
68
 
69
69
  @include m.is(multiple) {
70
70
  line-height: 1;
71
- border: fn.use-var(border);
71
+ border: fn.use-var(border-muted);
72
72
  box-shadow: fn.use-var(shadow, emboss);
73
73
  transition: border-color 0.25s ease, box-shadow 0.25s ease;
74
74
  overflow: hidden;
@@ -105,9 +105,10 @@
105
105
 
106
106
  <script lang="ts" setup>
107
107
  import { Forest, o } from '@cat-kit/core'
108
- import { useFormComponent, useFormFallbackProps, useUserAction } from '@veltra/compositions'
108
+ import { useFormFallbackProps, useUserAction } from '@veltra/compositions'
109
109
  import { ArrowDown, Close, Search } from '@veltra/icons/normal'
110
110
  import { bem, FORM_EMPTY_CONTENT } from '@veltra/utils'
111
+ import { injectFormContext } from '@veltra/utils'
111
112
  import { computed, provide, shallowRef, triggerRef, watch } from 'vue'
112
113
 
113
114
  import type { CascadeProps, CascadeEmits, DropdownExposed } from '../../types'
@@ -145,7 +146,7 @@ const emit = defineEmits<CascadeEmits>()
145
146
 
146
147
  const cls = bem('cascade')
147
148
 
148
- const { formProps } = useFormComponent()
149
+ const { formProps } = injectFormContext()
149
150
 
150
151
  const { size, disabled, readonly } = useFormFallbackProps([formProps ?? {}, props], {
151
152
  size: 'default',
@@ -10,7 +10,7 @@ $menu-name: $root-name + '-panel-item';
10
10
  width: 100%;
11
11
 
12
12
  @include m.is(multiple) {
13
- border: fn.use-var(border);
13
+ border: fn.use-var(border-muted);
14
14
  box-shadow: fn.use-var(shadow, emboss);
15
15
  transition: border-color 0.25s ease, box-shadow 0.25s ease;
16
16
  overflow: hidden;
@@ -13,8 +13,9 @@
13
13
  </template>
14
14
 
15
15
  <script lang="ts" setup>
16
- import { useFormComponent, useFormFallbackProps } from '@veltra/compositions'
16
+ import { useFormFallbackProps } from '@veltra/compositions'
17
17
  import { bem, FORM_EMPTY_CONTENT } from '@veltra/utils'
18
+ import { injectFormContext } from '@veltra/utils'
18
19
  import { computed } from 'vue'
19
20
 
20
21
  import type { CheckboxButtonProps, CheckboxButtonEmits } from '../../types'
@@ -41,7 +42,7 @@ const cls = bem('checkbox-button')
41
42
 
42
43
  const checked = defineModel<boolean>()
43
44
 
44
- const { formProps } = useFormComponent()
45
+ const { formProps } = injectFormContext()
45
46
 
46
47
  const { size, disabled, readonly } = useFormFallbackProps([formProps ?? {}, props], {
47
48
  size: 'default',
@@ -18,8 +18,9 @@
18
18
  </template>
19
19
 
20
20
  <script lang="ts" setup>
21
- import { useFormComponent, useFormFallbackProps } from '@veltra/compositions'
21
+ import { useFormFallbackProps } from '@veltra/compositions'
22
22
  import { bem } from '@veltra/utils'
23
+ import { injectFormContext } from '@veltra/utils'
23
24
  import { computed } from 'vue'
24
25
 
25
26
  import type { CheckboxProps, CheckboxEmits } from '../../types'
@@ -37,7 +38,7 @@ const cls = bem('checkbox')
37
38
 
38
39
  const checked = defineModel<boolean>()
39
40
 
40
- const { formProps } = useFormComponent()
41
+ const { formProps } = injectFormContext()
41
42
 
42
43
  const { size, disabled, readonly } = useFormFallbackProps([formProps ?? {}, props], {
43
44
  size: 'default',
@@ -19,7 +19,7 @@ $root-name: checkbox;
19
19
  @include m.is(disabled) {
20
20
  @include m.bem($root-name, wrap) {
21
21
  background-color: fn.use-var(text-color, disabled);
22
- border-color: fn.use-var(border, color);
22
+ border-color: fn.use-var(border, muted-color);
23
23
  }
24
24
  }
25
25
  }
@@ -72,7 +72,7 @@ $root-name: checkbox;
72
72
 
73
73
  $button-name: checkbox-button;
74
74
  @include m.b($button-name) {
75
- border: fn.use-var(border);
75
+ border: fn.use-var(border-muted);
76
76
  vertical-align: middle;
77
77
  display: inline-flex;
78
78
  align-items: center;
@@ -26,8 +26,9 @@
26
26
  </template>
27
27
 
28
28
  <script lang="ts" setup>
29
- import { useFormComponent, useFormFallbackProps } from '@veltra/compositions'
29
+ import { useFormFallbackProps } from '@veltra/compositions'
30
30
  import { bem, FORM_EMPTY_CONTENT } from '@veltra/utils'
31
+ import { injectFormContext } from '@veltra/utils'
31
32
 
32
33
  import type { CheckboxGroupProps, CheckboxGroupEmits } from '../../types'
33
34
  import { UCheckbox } from '../checkbox'
@@ -50,7 +51,7 @@ const model = defineModel<any[]>()
50
51
 
51
52
  const cls = bem('checkbox-group')
52
53
 
53
- const { formProps } = useFormComponent()
54
+ const { formProps } = injectFormContext()
54
55
 
55
56
  const { size, disabled, readonly } = useFormFallbackProps([formProps ?? {}, props], {
56
57
  size: 'default',
@@ -8,8 +8,9 @@
8
8
  import { Compartment, EditorState, type Extension } from '@codemirror/state'
9
9
  import { oneDark } from '@codemirror/theme-one-dark'
10
10
  import { ViewPlugin, tooltips, type ViewUpdate } from '@codemirror/view'
11
- import { useFormComponent, useFormFallbackProps } from '@veltra/compositions'
11
+ import { useFormFallbackProps } from '@veltra/compositions'
12
12
  import { bem, zIndex } from '@veltra/utils'
13
+ import { injectFormContext } from '@veltra/utils'
13
14
  import { EditorView, basicSetup } from 'codemirror'
14
15
  import {
15
16
  computed,
@@ -36,7 +37,7 @@ const model = defineModel<string>()
36
37
 
37
38
  const cls = bem('code-editor')
38
39
 
39
- const { formProps } = useFormComponent()
40
+ const { formProps } = injectFormContext()
40
41
 
41
42
  const { disabled, readonly } = useFormFallbackProps([formProps ?? {}, props], {
42
43
  disabled: false,
@@ -11,7 +11,7 @@ $root-name: code-editor;
11
11
  --u-code-editor-padding-block: 6px;
12
12
  --u-code-editor-bg: #{fn.use-var(bg, color, top)};
13
13
  --u-code-editor-fg: #{fn.use-var(text-color, main)};
14
- --u-code-editor-border: #{fn.use-var(border, color)};
14
+ --u-code-editor-border: #{fn.use-var(border, muted-color)};
15
15
  --u-code-editor-gutter-fg: #{fn.use-var(text-color, placeholder)};
16
16
  --u-code-editor-active-bg: rgba(30, 136, 229, 0.06);
17
17
  --u-code-editor-selection-bg: rgba(30, 136, 229, 0.18);
@@ -49,7 +49,7 @@ defineOptions({
49
49
 
50
50
  const props = defineProps<CollapseItemProps>()
51
51
 
52
- const context = inject(CollapseDIKey)
52
+ const context = inject(CollapseDIKey)!
53
53
 
54
54
  const cls = context?.cls ?? bem('collapse')
55
55
 
@@ -80,59 +80,21 @@ const handleClick = () => {
80
80
  }
81
81
 
82
82
  const wrapperEl = ref<HTMLElement>()
83
- let cleanupTransition: (() => void) | null = null
84
83
 
85
- const cancelTransition = () => {
86
- cleanupTransition?.()
87
- cleanupTransition = null
88
- }
89
-
90
- // 用 height 数值过渡替代 grid-template-rows,避免每帧 grid 重排带来的卡顿。
91
- const animateHeight = (active: boolean) => {
92
- const el = wrapperEl.value
93
- if (!el) return
94
-
95
- cancelTransition()
96
-
97
- const startHeight = el.offsetHeight
98
- const endHeight = active ? el.scrollHeight : 0
99
-
100
- if (startHeight === endHeight) {
101
- el.style.height = active ? 'auto' : '0px'
102
- return
103
- }
104
-
105
- el.style.height = `${startHeight}px`
106
- // 强制 reflow,确保起始高度被采纳,避免 0 → auto 直接跳变。
107
- void el.offsetHeight
108
- el.style.height = `${endHeight}px`
109
-
110
- const onEnd = (e: TransitionEvent) => {
111
- if (e.target !== el || e.propertyName !== 'height') return
112
- cleanup()
113
- if (active) {
114
- // 回归 auto,让后续内容动态变化时不被锁死高度。
115
- el.style.height = 'auto'
116
- }
117
- }
118
-
119
- const cleanup = () => {
120
- el.removeEventListener('transitionend', onEnd)
121
- el.removeEventListener('transitioncancel', onEnd)
122
- cleanupTransition = null
123
- }
124
-
125
- el.addEventListener('transitionend', onEnd)
126
- el.addEventListener('transitioncancel', onEnd)
127
- cleanupTransition = cleanup
128
- }
84
+ const { expandTransition } = context
129
85
 
130
86
  onMounted(() => {
131
87
  if (!wrapperEl.value) return
132
- wrapperEl.value.style.height = isActive.value ? 'auto' : '0px'
88
+ expandTransition.setExpanded(wrapperEl.value, isActive.value)
133
89
  })
134
90
 
135
- watch(isActive, animateHeight)
91
+ watch(isActive, (active) => {
92
+ if (!wrapperEl.value) return
93
+ active ? expandTransition.expand(wrapperEl.value) : expandTransition.collapse(wrapperEl.value)
94
+ })
136
95
 
137
- onBeforeUnmount(cancelTransition)
96
+ onBeforeUnmount(() => {
97
+ if (!wrapperEl.value) return
98
+ expandTransition.cancel(wrapperEl.value)
99
+ })
138
100
  </script>
@@ -6,7 +6,7 @@
6
6
 
7
7
  <script lang="ts" setup>
8
8
  import { useFormFallbackProps, useModel } from '@veltra/compositions'
9
- import { bem } from '@veltra/utils'
9
+ import { bem, ExpandTransition } from '@veltra/utils'
10
10
  import { computed, provide } from 'vue'
11
11
 
12
12
  import type {
@@ -31,6 +31,10 @@ const emit = defineEmits<CollapseEmits>()
31
31
 
32
32
  const cls = bem('collapse')
33
33
 
34
+ const expandTransition = new ExpandTransition({
35
+ transition: 'height 0.24s cubic-bezier(0.4, 0, 0.2, 1)'
36
+ })
37
+
34
38
  const { size } = useFormFallbackProps([props], { size: 'default' })
35
39
 
36
40
  const iconPosition = computed(() => props.iconPosition ?? 'right')
@@ -109,7 +113,8 @@ provide(CollapseDIKey, {
109
113
  iconPosition,
110
114
  expandIcon,
111
115
  activeValues,
112
- toggle
116
+ toggle,
117
+ expandTransition
113
118
  })
114
119
 
115
120
  defineExpose<_CollapseExposed>({
@@ -1,4 +1,4 @@
1
- import type { BEM, ComponentSize } from '@veltra/utils'
1
+ import { type BEM, type ComponentSize, ExpandTransition } from '@veltra/utils'
2
2
  import type { Component, ComputedRef, InjectionKey } from 'vue'
3
3
 
4
4
  import type { CollapseIconPosition, CollapseValue } from '../../types'
@@ -10,6 +10,7 @@ export interface CollapseContext {
10
10
  expandIcon: ComputedRef<Component | undefined>
11
11
  activeValues: ComputedRef<CollapseValue[]>
12
12
  toggle: (value: CollapseValue) => void
13
+ expandTransition: ExpandTransition
13
14
  }
14
15
 
15
16
  export const CollapseDIKey: InjectionKey<CollapseContext> = Symbol('Collapse')
@@ -124,7 +124,7 @@ $header-padding-y: (
124
124
  }
125
125
 
126
126
  // ===== Content wrapper =====
127
- // 高度由 collapse-item.vue 的 JS 在 isActive 切换时驱动:
127
+ // 高度由共享 expand transition hook 在 isActive 切换时驱动:
128
128
  // 未挂载前 → CSS 兜底 height: 0
129
129
  // 未激活 → 0px(带 transition)
130
130
  // 激活中 → 0 → scrollHeight(CSS transition: height)
@@ -36,9 +36,10 @@
36
36
 
37
37
  <script lang="ts" setup>
38
38
  import { date, type Dater } from '@cat-kit/core'
39
- import { useFormComponent, useFormFallbackProps, useUserAction } from '@veltra/compositions'
39
+ import { useFormFallbackProps, useUserAction } from '@veltra/compositions'
40
40
  import { Calendar } from '@veltra/icons/normal'
41
41
  import { bem, FORM_EMPTY_CONTENT } from '@veltra/utils'
42
+ import { injectFormContext } from '@veltra/utils'
42
43
  import { computed, shallowRef, watch } from 'vue'
43
44
 
44
45
  import type { DatePickerEmits, DatePickerProps } from '../../types'
@@ -64,7 +65,7 @@ const emit = defineEmits<DatePickerEmits>()
64
65
 
65
66
  const cls = bem('date-picker')
66
67
 
67
- const { formProps } = useFormComponent()
68
+ const { formProps } = injectFormContext()
68
69
 
69
70
  const { size, disabled, readonly } = useFormFallbackProps([formProps ?? {}, props], {
70
71
  size: 'default',
@@ -61,9 +61,10 @@
61
61
 
62
62
  <script lang="ts" setup>
63
63
  import { date, type Dater } from '@cat-kit/core'
64
- import { useFormComponent, useFormFallbackProps, useUserAction } from '@veltra/compositions'
64
+ import { useFormFallbackProps, useUserAction } from '@veltra/compositions'
65
65
  import { Calendar, Close } from '@veltra/icons/normal'
66
66
  import { bem, FORM_EMPTY_CONTENT } from '@veltra/utils'
67
+ import { injectFormContext } from '@veltra/utils'
67
68
  import { computed, shallowRef, watch } from 'vue'
68
69
 
69
70
  import type { DateRangePickerEmits, DateRangePickerProps, DropdownExposed } from '../../types'
@@ -91,7 +92,7 @@ const className = computed(() => {
91
92
  return [cls.b, cls.m(size.value), bem.is('disabled', disabled.value)]
92
93
  })
93
94
 
94
- const { formProps } = useFormComponent()
95
+ const { formProps } = injectFormContext()
95
96
 
96
97
  const { size, disabled, readonly } = useFormFallbackProps([formProps ?? {}, props], {
97
98
  size: 'default',
@@ -9,7 +9,7 @@ $root-name: date-range-picker;
9
9
  width: 100%;
10
10
  vertical-align: middle;
11
11
  line-height: 1;
12
- border: fn.use-var(border);
12
+ border: fn.use-var(border-muted);
13
13
  box-shadow: fn.use-var(shadow, emboss);
14
14
  transition: border-color 0.25s ease, box-shadow 0.25s ease;
15
15
  overflow: hidden;
@@ -41,7 +41,6 @@ $root-name: dialog;
41
41
  overflow: hidden;
42
42
  background-color: fn.use-var(bg-color, middle);
43
43
  backdrop-filter: fn.use-var(bg-filter);
44
- -webkit-backdrop-filter: fn.use-var(bg-filter);
45
44
  }
46
45
 
47
46
  // 弹框头
@@ -66,6 +65,7 @@ $root-name: dialog;
66
65
  @include m.e(body) {
67
66
  padding: 8px;
68
67
  background-color: fn.use-var(bg-color, top);
68
+ backdrop-filter: fn.use-var(bg-filter);
69
69
  flex-grow: 1;
70
70
  }
71
71
 
@@ -29,8 +29,9 @@
29
29
  </template>
30
30
 
31
31
  <script lang="ts" setup>
32
- import { useFormComponent, useFormFallbackProps } from '@veltra/compositions'
32
+ import { useFormFallbackProps } from '@veltra/compositions'
33
33
  import { bem } from '@veltra/utils'
34
+ import { injectFormContext } from '@veltra/utils'
34
35
  import {
35
36
  computed,
36
37
  nextTick,
@@ -62,7 +63,7 @@ const emit = defineEmits<{
62
63
  }>()
63
64
 
64
65
  const cls = bem('expression-editor')
65
- const { formProps } = useFormComponent()
66
+ const { formProps } = injectFormContext()
66
67
  const { size, disabled, readonly } = useFormFallbackProps([formProps ?? {}, props])
67
68
 
68
69
  const containerRef = useTemplateRef<HTMLDivElement>('container')
@@ -9,7 +9,7 @@ $root-name: expression-editor;
9
9
  background-color: fn.use-var(bg-color, top);
10
10
  border-width: fn.use-var(border, width);
11
11
  border-style: fn.use-var(border, style);
12
- border-color: fn.use-var(border, color);
12
+ border-color: fn.use-var(border, muted-color);
13
13
  border-radius: fn.use-var(radius, default);
14
14
 
15
15
  @include m.is-not(disabled, readonly) {
@@ -26,21 +26,21 @@ $root-name: expression-editor;
26
26
  @include m.is('disabled') {
27
27
  background-color: fn.use-var(color, disabled);
28
28
  cursor: not-allowed;
29
- border-color: fn.use-var(border, color);
29
+ border-color: fn.use-var(border, muted-color);
30
30
 
31
31
  &:hover {
32
- border-color: fn.use-var(border, color);
32
+ border-color: fn.use-var(border, muted-color);
33
33
  }
34
34
  }
35
35
 
36
36
  @include m.is('readonly') {
37
37
  background-color: fn.use-var(bg-color, middle);
38
38
  cursor: default;
39
- border-color: fn.use-var(border, color);
39
+ border-color: fn.use-var(border, muted-color);
40
40
  user-select: text;
41
41
 
42
42
  &:hover {
43
- border-color: fn.use-var(border, color);
43
+ border-color: fn.use-var(border, muted-color);
44
44
  }
45
45
  }
46
46