@veltra/desktop 1.2.24 → 1.2.25

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 (87) hide show
  1. package/dist/components/action/action-group.vue.d.ts +2 -2
  2. package/dist/components/action/action.vue.d.ts +1 -1
  3. package/dist/components/auto-complete/auto-complete.vue.d.ts +2 -2
  4. package/dist/components/cascade/cascade.js +5 -3
  5. package/dist/components/cascade/cascade.js.map +1 -1
  6. package/dist/components/cascade/cascade.vue.d.ts +3 -3
  7. package/dist/components/cascade/use-data-map.js +2 -1
  8. package/dist/components/cascade/use-data-map.js.map +1 -1
  9. package/dist/components/checkbox/checkbox-button.vue.d.ts +1 -1
  10. package/dist/components/checkbox-group/checkbox-group.js +10 -10
  11. package/dist/components/checkbox-group/checkbox-group.js.map +1 -1
  12. package/dist/components/checkbox-group/checkbox-group.vue.d.ts +2 -2
  13. package/dist/components/code-editor/basic-setup.js +2 -1
  14. package/dist/components/code-editor/basic-setup.js.map +1 -1
  15. package/dist/components/code-editor/code-editor.js +136 -79
  16. package/dist/components/code-editor/code-editor.js.map +1 -1
  17. package/dist/components/code-editor/code-editor.vue.d.ts +10 -2
  18. package/dist/components/code-editor/shell-extension.js +139 -0
  19. package/dist/components/code-editor/shell-extension.js.map +1 -0
  20. package/dist/components/code-editor/style.js +1 -0
  21. package/dist/components/code-editor/style2.css +15 -11
  22. package/dist/components/date-panel/date-panel.vue.d.ts +1 -1
  23. package/dist/components/date-picker/date-picker.vue.d.ts +2 -2
  24. package/dist/components/date-range-picker/date-range-picker.vue.d.ts +2 -2
  25. package/dist/components/empty/empty.vue.d.ts +1 -1
  26. package/dist/components/input/input.vue.d.ts +2 -2
  27. package/dist/components/multi-select/multi-select.js +31 -36
  28. package/dist/components/multi-select/multi-select.js.map +1 -1
  29. package/dist/components/multi-select/multi-select.vue.d.ts +2 -2
  30. package/dist/components/multi-tree-select/multi-tree-select.js +8 -6
  31. package/dist/components/multi-tree-select/multi-tree-select.js.map +1 -1
  32. package/dist/components/multi-tree-select/multi-tree-select.vue.d.ts +2 -2
  33. package/dist/components/number-input/number-input.vue.d.ts +2 -2
  34. package/dist/components/number-range-input/number-range-input.vue.d.ts +1 -1
  35. package/dist/components/password-input/password-input.vue.d.ts +1 -1
  36. package/dist/components/pop-confirm/pop-confirm.vue.d.ts +1 -1
  37. package/dist/components/progress-nodes/progress-nodes.js +6 -4
  38. package/dist/components/progress-nodes/progress-nodes.js.map +1 -1
  39. package/dist/components/radio-group/radio-group.js +8 -6
  40. package/dist/components/radio-group/radio-group.js.map +1 -1
  41. package/dist/components/radio-group/radio-group.vue.d.ts +2 -2
  42. package/dist/components/rich-text-editor/rich-text-editor.vue.d.ts +1 -1
  43. package/dist/components/select/select.js +13 -13
  44. package/dist/components/select/select.js.map +1 -1
  45. package/dist/components/select/select.vue.d.ts +2 -2
  46. package/dist/components/select/use-options.js +7 -4
  47. package/dist/components/select/use-options.js.map +1 -1
  48. package/dist/components/steps/steps.js +3 -2
  49. package/dist/components/steps/steps.js.map +1 -1
  50. package/dist/components/steps/steps.vue.d.ts +2 -2
  51. package/dist/components/textarea/textarea.vue.d.ts +2 -2
  52. package/dist/components/tip/tip.vue.d.ts +1 -1
  53. package/dist/components/tree/use-check.js +2 -1
  54. package/dist/components/tree/use-check.js.map +1 -1
  55. package/dist/components/tree/use-select.js +3 -1
  56. package/dist/components/tree/use-select.js.map +1 -1
  57. package/dist/components/tree/use-tree-nodes.js +4 -1
  58. package/dist/components/tree/use-tree-nodes.js.map +1 -1
  59. package/dist/components/tree-select/tree-select.js +6 -4
  60. package/dist/components/tree-select/tree-select.js.map +1 -1
  61. package/dist/components/tree-select/tree-select.vue.d.ts +2 -2
  62. package/dist/components/watermark/watermark.vue.d.ts +1 -1
  63. package/dist/node_modules/.bun/@codemirror_commands@6.10.4/node_modules/@codemirror/commands/dist/index.js +12 -1
  64. package/dist/node_modules/.bun/@codemirror_commands@6.10.4/node_modules/@codemirror/commands/dist/index.js.map +1 -1
  65. package/dist/style.js +1 -1
  66. package/dist/types/code-editor.d.ts +13 -2
  67. package/package.json +6 -6
  68. package/src/components/cascade/cascade.vue +6 -3
  69. package/src/components/cascade/use-data-map.ts +3 -2
  70. package/src/components/checkbox-group/checkbox-group.vue +10 -8
  71. package/src/components/code-editor/basic-setup.ts +3 -1
  72. package/src/components/code-editor/code-editor.vue +154 -96
  73. package/src/components/code-editor/shell-extension.ts +199 -0
  74. package/src/components/code-editor/style.scss +20 -13
  75. package/src/components/code-editor/style.ts +1 -0
  76. package/src/components/multi-select/multi-select.vue +31 -30
  77. package/src/components/multi-tree-select/multi-tree-select.vue +5 -2
  78. package/src/components/progress-nodes/progress-nodes.vue +7 -4
  79. package/src/components/radio-group/radio-group.vue +5 -1
  80. package/src/components/select/select.vue +13 -11
  81. package/src/components/select/use-options.ts +7 -4
  82. package/src/components/steps/steps.vue +3 -1
  83. package/src/components/tree/use-check.ts +2 -1
  84. package/src/components/tree/use-select.ts +3 -1
  85. package/src/components/tree/use-tree-nodes.ts +5 -9
  86. package/src/components/tree-select/tree-select.vue +7 -4
  87. package/src/types/code-editor.ts +13 -2
@@ -1 +1 @@
1
- {"version":3,"file":"progress-nodes.js","names":[],"sources":["../../../src/components/progress-nodes/progress-nodes.vue"],"sourcesContent":["<template>\n <div ref=\"container\" :class=\"className\" :style=\"containerStyle\" @scroll=\"checkScroll\">\n <ul :class=\"cls.e('list')\">\n <li\n v-for=\"(node, index) in nodes\"\n :key=\"node.key ?? index\"\n :class=\"[\n cls.e('item'),\n bem.is('checked', isChecked(node, index)),\n bem.is('active', isActive(node))\n ]\"\n @click=\"handleClick(node, index)\"\n >\n <div :class=\"cls.e('node')\">\n <!-- 虚线连接 -->\n <div v-if=\"index !== nodes.length - 1\" :class=\"cls.e('link')\"></div>\n\n <!-- 节点圆点 -->\n <span :class=\"cls.e('dot')\">\n <slot name=\"icon\" :node=\"node\" :index=\"index\" />\n </span>\n </div>\n\n <div :class=\"cls.e('label')\">\n <slot :node=\"node\" :index=\"index\">\n {{ getLabel(node) }}\n </slot>\n </div>\n </li>\n </ul>\n </div>\n</template>\n\n<script lang=\"ts\" setup>\nimport { o } from '@cat-kit/core'\nimport { useDrag, useResizeObserver } from '@veltra/compositions'\nimport { bem } from '@veltra/utils'\nimport { computed, shallowRef, toRefs, useTemplateRef, watch, nextTick } from 'vue'\n\nimport type { ProgressNodesProps, ProgressNodesEmits } from '../../types'\n\ndefineOptions({ name: 'UProgressNodes' })\n\nconst props = withDefaults(defineProps<ProgressNodesProps>(), {\n colorType: 'primary',\n labelKey: 'label',\n valueKey: 'value'\n})\n\nconst emit = defineEmits<ProgressNodesEmits>()\n\nconst { nodes } = toRefs(props)\n\nconst cls = bem('progress-nodes')\nconst containerRef = useTemplateRef('container')\nconst isDragging = shallowRef(false)\nconst isScrollable = shallowRef(false)\nconst showMaskStart = shallowRef(false)\nconst showMaskEnd = shallowRef(false)\n\nconst className = computed(() => [\n cls.b,\n cls.m(props.colorType),\n bem.is('scrollable', isScrollable.value),\n bem.is('dragging', isDragging.value),\n bem.is('mask-start', showMaskStart.value),\n bem.is('mask-end', showMaskEnd.value)\n])\n\nconst containerStyle = computed(() => {\n const style: Record<string, string> = {}\n const maxWidth = toCssSize(props.maxWidth)\n if (maxWidth) style.maxWidth = maxWidth\n return style\n})\n\nlet startScrollLeft = 0\n\nuseDrag({\n target: containerRef,\n onDragStart() {\n if (!isScrollable.value) return\n const container = containerRef.value\n if (!container) return\n isDragging.value = true\n startScrollLeft = container.scrollLeft\n },\n onDrag({ x }) {\n if (!isScrollable.value) return\n const container = containerRef.value\n if (!container) return\n container.scrollLeft = startScrollLeft - x\n },\n onDragEnd() {\n isDragging.value = false\n }\n})\n\nuseResizeObserver({ targets: containerRef, onResize: checkScroll })\n\nwatch(\n nodes,\n () => {\n nextTick(checkScroll)\n },\n { deep: true }\n)\n\nfunction checkScroll() {\n const container = containerRef.value\n if (!container) return\n\n const { scrollLeft, scrollWidth, clientWidth } = container\n isScrollable.value = scrollWidth > clientWidth + 1\n showMaskStart.value = scrollLeft > 0\n showMaskEnd.value = scrollLeft + clientWidth < scrollWidth - 1\n}\n\nfunction isChecked(node: Record<string, any>, index: number) {\n return props.check?.(node, index) ?? false\n}\n\nfunction isActive(node: Record<string, any>) {\n const value = o(node).get(props.valueKey)\n return props.modelValue === value\n}\n\nfunction getLabel(node: Record<string, any>) {\n return o(node).get(props.labelKey)\n}\n\nfunction handleClick(node: Record<string, any>, index: number) {\n const value = o(node).get(props.valueKey)\n emit('update:modelValue', value)\n emit('click', node, index)\n}\n\nfunction toCssSize(value?: number | string) {\n if (value === undefined) return undefined\n return typeof value === 'number' ? `${value}px` : value\n}\n</script>\n"],"mappings":"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"}
1
+ {"version":3,"file":"progress-nodes.js","names":[],"sources":["../../../src/components/progress-nodes/progress-nodes.vue"],"sourcesContent":["<template>\n <div ref=\"container\" :class=\"className\" :style=\"containerStyle\" @scroll=\"checkScroll\">\n <ul :class=\"cls.e('list')\">\n <li\n v-for=\"(node, index) in nodes\"\n :key=\"node.key ?? index\"\n :class=\"[\n cls.e('item'),\n bem.is('checked', isChecked(node, index)),\n bem.is('active', isActive(node))\n ]\"\n @click=\"handleClick(node, index)\"\n >\n <div :class=\"cls.e('node')\">\n <!-- 虚线连接 -->\n <div v-if=\"index !== nodes.length - 1\" :class=\"cls.e('link')\"></div>\n\n <!-- 节点圆点 -->\n <span :class=\"cls.e('dot')\">\n <slot name=\"icon\" :node=\"node\" :index=\"index\" />\n </span>\n </div>\n\n <div :class=\"cls.e('label')\">\n <slot :node=\"node\" :index=\"index\">\n {{ getLabel(node) }}\n </slot>\n </div>\n </li>\n </ul>\n </div>\n</template>\n\n<script lang=\"ts\" setup>\nimport { o } from '@cat-kit/core'\nimport { useDrag, useResizeObserver } from '@veltra/compositions'\nimport { bem, fieldKey } from '@veltra/utils'\nimport { computed, shallowRef, toRefs, useTemplateRef, watch, nextTick } from 'vue'\n\nimport type { ProgressNodesProps, ProgressNodesEmits } from '../../types'\n\ndefineOptions({ name: 'UProgressNodes' })\n\nconst props = withDefaults(defineProps<ProgressNodesProps>(), {\n colorType: 'primary',\n labelKey: 'label',\n valueKey: 'value'\n})\n\nconst emit = defineEmits<ProgressNodesEmits>()\n\nconst labelKey = computed(() => fieldKey(props.labelKey, 'label'))\nconst valueKey = computed(() => fieldKey(props.valueKey, 'value'))\n\nconst { nodes } = toRefs(props)\n\nconst cls = bem('progress-nodes')\nconst containerRef = useTemplateRef('container')\nconst isDragging = shallowRef(false)\nconst isScrollable = shallowRef(false)\nconst showMaskStart = shallowRef(false)\nconst showMaskEnd = shallowRef(false)\n\nconst className = computed(() => [\n cls.b,\n cls.m(props.colorType),\n bem.is('scrollable', isScrollable.value),\n bem.is('dragging', isDragging.value),\n bem.is('mask-start', showMaskStart.value),\n bem.is('mask-end', showMaskEnd.value)\n])\n\nconst containerStyle = computed(() => {\n const style: Record<string, string> = {}\n const maxWidth = toCssSize(props.maxWidth)\n if (maxWidth) style.maxWidth = maxWidth\n return style\n})\n\nlet startScrollLeft = 0\n\nuseDrag({\n target: containerRef,\n onDragStart() {\n if (!isScrollable.value) return\n const container = containerRef.value\n if (!container) return\n isDragging.value = true\n startScrollLeft = container.scrollLeft\n },\n onDrag({ x }) {\n if (!isScrollable.value) return\n const container = containerRef.value\n if (!container) return\n container.scrollLeft = startScrollLeft - x\n },\n onDragEnd() {\n isDragging.value = false\n }\n})\n\nuseResizeObserver({ targets: containerRef, onResize: checkScroll })\n\nwatch(\n nodes,\n () => {\n nextTick(checkScroll)\n },\n { deep: true }\n)\n\nfunction checkScroll() {\n const container = containerRef.value\n if (!container) return\n\n const { scrollLeft, scrollWidth, clientWidth } = container\n isScrollable.value = scrollWidth > clientWidth + 1\n showMaskStart.value = scrollLeft > 0\n showMaskEnd.value = scrollLeft + clientWidth < scrollWidth - 1\n}\n\nfunction isChecked(node: Record<string, any>, index: number) {\n return props.check?.(node, index) ?? false\n}\n\nfunction isActive(node: Record<string, any>) {\n const value = o(node).get(valueKey.value)\n return props.modelValue === value\n}\n\nfunction getLabel(node: Record<string, any>) {\n return o(node).get(labelKey.value)\n}\n\nfunction handleClick(node: Record<string, any>, index: number) {\n const value = o(node).get(valueKey.value)\n emit('update:modelValue', value)\n emit('click', node, index)\n}\n\nfunction toCssSize(value?: number | string) {\n if (value === undefined) return undefined\n return typeof value === 'number' ? `${value}px` : value\n}\n</script>\n"],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  import _sfc_main$1 from "../radio/radio.js";
2
- import { Fragment, createBlock, createElementBlock, createTextVNode, defineComponent, mergeModels, mergeProps, openBlock, renderList, toDisplayString, unref, useModel, withCtx } from "vue";
2
+ import { Fragment, computed, createBlock, createElementBlock, createTextVNode, defineComponent, mergeModels, mergeProps, openBlock, renderList, toDisplayString, unref, useModel, withCtx } from "vue";
3
3
  import { useFormFallbackProps } from "@veltra/compositions";
4
- import { FORM_EMPTY_CONTENT, bem, injectFormContext } from "@veltra/utils";
4
+ import { FORM_EMPTY_CONTENT, bem, fieldKey, injectFormContext } from "@veltra/utils";
5
5
  //#region src/components/radio-group/radio-group.vue
6
6
  const _sfc_main = /*@__PURE__*/ defineComponent({
7
7
  name: "URadioGroup",
@@ -44,6 +44,8 @@ const _sfc_main = /*@__PURE__*/ defineComponent({
44
44
  readonly: false
45
45
  });
46
46
  const cls = bem("radio-group");
47
+ const labelKey = computed(() => fieldKey(props.labelKey, "label"));
48
+ const valueKey = computed(() => fieldKey(props.valueKey, "value"));
47
49
  const handleUpdate = (value, item) => {
48
50
  model.value = value;
49
51
  emit("change", item);
@@ -55,14 +57,14 @@ const _sfc_main = /*@__PURE__*/ defineComponent({
55
57
  unref(cls).m(unref(size))
56
58
  ] }), [(openBlock(true), createElementBlock(Fragment, null, renderList(__props.items, (item) => {
57
59
  return openBlock(), createBlock(_sfc_main$1, {
58
- key: item[__props.valueKey],
59
- value: item[__props.valueKey],
60
+ key: item[valueKey.value],
61
+ value: item[valueKey.value],
60
62
  "model-value": model.value,
61
63
  "onUpdate:modelValue": ($event) => handleUpdate($event, item),
62
64
  disabled: __props.disabledItem?.(item) || unref(disabled),
63
65
  size: unref(size)
64
66
  }, {
65
- default: withCtx(() => [createTextVNode(toDisplayString(item[__props.labelKey]), 1)]),
67
+ default: withCtx(() => [createTextVNode(toDisplayString(item[labelKey.value]), 1)]),
66
68
  _: 2
67
69
  }, 1032, [
68
70
  "value",
@@ -71,7 +73,7 @@ const _sfc_main = /*@__PURE__*/ defineComponent({
71
73
  "disabled",
72
74
  "size"
73
75
  ]);
74
- }), 128))], 16)) : (openBlock(), createElementBlock(Fragment, { key: 1 }, [createTextVNode(toDisplayString(__props.items.find((item) => item[__props.valueKey] === model.value)?.[__props.labelKey] || unref(FORM_EMPTY_CONTENT)), 1)], 64));
76
+ }), 128))], 16)) : (openBlock(), createElementBlock(Fragment, { key: 1 }, [createTextVNode(toDisplayString(__props.items.find((item) => item[valueKey.value] === model.value)?.[labelKey.value] || unref(FORM_EMPTY_CONTENT)), 1)], 64));
75
77
  };
76
78
  }
77
79
  });
@@ -1 +1 @@
1
- {"version":3,"file":"radio-group.js","names":["$attrs"],"sources":["../../../src/components/radio-group/radio-group.vue"],"sourcesContent":["<template>\n <div v-if=\"!readonly\" v-bind=\"$attrs\" :class=\"[cls.b, bem.is('block', block), cls.m(size)]\">\n <u-radio\n v-for=\"item of items\"\n :key=\"item[valueKey]\"\n :value=\"item[valueKey]\"\n :model-value=\"model\"\n @update:model-value=\"handleUpdate($event, item)\"\n :disabled=\"disabledItem?.(item) || disabled\"\n :size=\"size\"\n >\n {{ item[labelKey] }}\n </u-radio>\n </div>\n\n <template v-else>\n {{ items.find((item) => item[valueKey] === model)?.[labelKey] || FORM_EMPTY_CONTENT }}\n </template>\n</template>\n\n<script lang=\"ts\" setup>\nimport { useFormFallbackProps } from '@veltra/compositions'\nimport { bem, FORM_EMPTY_CONTENT } from '@veltra/utils'\nimport { injectFormContext } from '@veltra/utils'\n\nimport type { RadioGroupProps, RadioGroupEmits } from '../../types'\nimport URadio from '../radio/radio.vue'\n\ndefineOptions({ name: 'URadioGroup', inheritAttrs: false })\n\nconst props = withDefaults(defineProps<RadioGroupProps>(), {\n labelKey: 'label',\n valueKey: 'value',\n disabled: undefined,\n readonly: undefined\n})\n\nconst model = defineModel<any>()\n\nconst emit = defineEmits<RadioGroupEmits>()\n\nconst { formProps } = injectFormContext()\n\nconst { size, disabled, readonly } = useFormFallbackProps([formProps ?? {}, props], {\n size: 'default',\n disabled: false,\n readonly: false\n})\n\nconst cls = bem('radio-group')\n\nconst handleUpdate = (value: any, item: Record<string, any>) => {\n model.value = value\n emit('change', item)\n}\n</script>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA8BA,MAAM,QAAQ;EAOd,MAAM,QAAQ,SAAgB,SAAA,YAAC;EAE/B,MAAM,OAAO;EAEb,MAAM,EAAE,cAAc,kBAAkB;EAExC,MAAM,EAAE,MAAM,UAAU,aAAa,qBAAqB,CAAC,aAAa,CAAC,GAAG,KAAK,GAAG;GAClF,MAAM;GACN,UAAU;GACV,UAAU;EACZ,CAAC;EAED,MAAM,MAAM,IAAI,aAAa;EAE7B,MAAM,gBAAgB,OAAY,SAA8B;GAC9D,MAAM,QAAQ;GACd,KAAK,UAAU,IAAI;EACrB;;WArDc,MAAA,QAAA,KAAA,UAAA,GAAZ,mBAYM,OAZN,WAYM,EAAA,KAAA,EAAA,GAZwBA,KAAAA,QAAM,EAAG,OAAK;IAAG,MAAA,GAAA,CAAG,CAAC;IAAG,MAAA,GAAA,CAAG,CAAC,GAAE,SAAU,QAAA,KAAK;IAAG,MAAA,GAAA,CAAG,CAAC,EAAE,MAAA,IAAA,CAAI;GAAA,EAAA,CAAA,GAAA,EAAA,UAAA,IAAA,GACtF,mBAUU,UAAA,MAAA,WATO,QAAA,QAAR,SAAI;wBADb,YAUU,aAAA;KARP,KAAK,KAAK,QAAA;KACV,OAAO,KAAK,QAAA;KACZ,eAAa,MAAA;KACb,wBAAkB,WAAE,aAAa,QAAQ,IAAI;KAC7C,UAAU,QAAA,eAAe,IAAI,KAAK,MAAA,QAAA;KAClC,MAAM,MAAA,IAAA;;4BAEa,CAAA,gBAAA,gBAAjB,KAAK,QAAA,SAAQ,GAAA,CAAA,CAAA,CAAA;;;;;;;;;oCAIpB,mBAEW,UAAA,EAAA,KAAA,EAAA,GAAA,CAAA,gBAAA,gBADN,QAAA,MAAM,MAAM,SAAS,KAAK,QAAA,cAAc,MAAA,KAAK,CAAA,GAAI,QAAA,aAAa,MAAA,kBAAA,CAAkB,GAAA,CAAA,CAAA,GAAA,EAAA"}
1
+ {"version":3,"file":"radio-group.js","names":["$attrs"],"sources":["../../../src/components/radio-group/radio-group.vue"],"sourcesContent":["<template>\n <div v-if=\"!readonly\" v-bind=\"$attrs\" :class=\"[cls.b, bem.is('block', block), cls.m(size)]\">\n <u-radio\n v-for=\"item of items\"\n :key=\"item[valueKey]\"\n :value=\"item[valueKey]\"\n :model-value=\"model\"\n @update:model-value=\"handleUpdate($event, item)\"\n :disabled=\"disabledItem?.(item) || disabled\"\n :size=\"size\"\n >\n {{ item[labelKey] }}\n </u-radio>\n </div>\n\n <template v-else>\n {{ items.find((item) => item[valueKey] === model)?.[labelKey] || FORM_EMPTY_CONTENT }}\n </template>\n</template>\n\n<script lang=\"ts\" setup>\nimport { useFormFallbackProps } from '@veltra/compositions'\nimport { bem, fieldKey, FORM_EMPTY_CONTENT } from '@veltra/utils'\nimport { injectFormContext } from '@veltra/utils'\nimport { computed } from 'vue'\n\nimport type { RadioGroupProps, RadioGroupEmits } from '../../types'\nimport URadio from '../radio/radio.vue'\n\ndefineOptions({ name: 'URadioGroup', inheritAttrs: false })\n\nconst props = withDefaults(defineProps<RadioGroupProps>(), {\n labelKey: 'label',\n valueKey: 'value',\n disabled: undefined,\n readonly: undefined\n})\n\nconst model = defineModel<any>()\n\nconst emit = defineEmits<RadioGroupEmits>()\n\nconst { formProps } = injectFormContext()\n\nconst { size, disabled, readonly } = useFormFallbackProps([formProps ?? {}, props], {\n size: 'default',\n disabled: false,\n readonly: false\n})\n\nconst cls = bem('radio-group')\n\nconst labelKey = computed(() => fieldKey(props.labelKey, 'label'))\nconst valueKey = computed(() => fieldKey(props.valueKey, 'value'))\n\nconst handleUpdate = (value: any, item: Record<string, any>) => {\n model.value = value\n emit('change', item)\n}\n</script>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA+BA,MAAM,QAAQ;EAOd,MAAM,QAAQ,SAAgB,SAAA,YAAC;EAE/B,MAAM,OAAO;EAEb,MAAM,EAAE,cAAc,kBAAkB;EAExC,MAAM,EAAE,MAAM,UAAU,aAAa,qBAAqB,CAAC,aAAa,CAAC,GAAG,KAAK,GAAG;GAClF,MAAM;GACN,UAAU;GACV,UAAU;EACZ,CAAC;EAED,MAAM,MAAM,IAAI,aAAa;EAE7B,MAAM,WAAW,eAAe,SAAS,MAAM,UAAU,OAAO,CAAC;EACjE,MAAM,WAAW,eAAe,SAAS,MAAM,UAAU,OAAO,CAAC;EAEjE,MAAM,gBAAgB,OAAY,SAA8B;GAC9D,MAAM,QAAQ;GACd,KAAK,UAAU,IAAI;EACrB;;WAzDc,MAAA,QAAA,KAAA,UAAA,GAAZ,mBAYM,OAZN,WAYM,EAAA,KAAA,EAAA,GAZwBA,KAAAA,QAAM,EAAG,OAAK;IAAG,MAAA,GAAA,CAAG,CAAC;IAAG,MAAA,GAAA,CAAG,CAAC,GAAE,SAAU,QAAA,KAAK;IAAG,MAAA,GAAA,CAAG,CAAC,EAAE,MAAA,IAAA,CAAI;GAAA,EAAA,CAAA,GAAA,EAAA,UAAA,IAAA,GACtF,mBAUU,UAAA,MAAA,WATO,QAAA,QAAR,SAAI;wBADb,YAUU,aAAA;KARP,KAAK,KAAK,SAAA;KACV,OAAO,KAAK,SAAA;KACZ,eAAa,MAAA;KACb,wBAAkB,WAAE,aAAa,QAAQ,IAAI;KAC7C,UAAU,QAAA,eAAe,IAAI,KAAK,MAAA,QAAA;KAClC,MAAM,MAAA,IAAA;;4BAEa,CAAA,gBAAA,gBAAjB,KAAK,SAAA,MAAQ,GAAA,CAAA,CAAA,CAAA;;;;;;;;;oCAIpB,mBAEW,UAAA,EAAA,KAAA,EAAA,GAAA,CAAA,gBAAA,gBADN,QAAA,MAAM,MAAM,SAAS,KAAK,SAAA,WAAc,MAAA,KAAK,CAAA,GAAI,SAAA,UAAa,MAAA,kBAAA,CAAkB,GAAA,CAAA,CAAA,GAAA,EAAA"}
@@ -14,10 +14,10 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {},
14
14
  "onUpdate:modelValue"?: ((value: any) => any) | undefined;
15
15
  onChange?: ((item: Record<string, any>) => any) | undefined;
16
16
  }>, {
17
- disabled: boolean;
18
- readonly: boolean;
19
17
  labelKey: string;
20
18
  valueKey: string;
19
+ disabled: boolean;
20
+ readonly: boolean;
21
21
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
22
22
  declare const _default: typeof __VLS_export;
23
23
  //#endregion
@@ -10,9 +10,9 @@ declare const __VLS_export: import("vue").DefineComponent<RichTextEditorProps &
10
10
  }> & Readonly<{
11
11
  "onUpdate:modelValue"?: ((value: string | undefined) => any) | undefined;
12
12
  }>, {
13
+ placeholder: string;
13
14
  disabled: boolean;
14
15
  readonly: boolean;
15
- placeholder: string;
16
16
  format: RichTextFormat;
17
17
  toolbar: ToolbarItem[];
18
18
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
@@ -7,7 +7,7 @@ import { useKeyboard } from "./use-keyboard.js";
7
7
  import { useOptions } from "./use-options.js";
8
8
  import { Fragment, computed, createBlock, createCommentVNode, createElementBlock, createSlots, createTextVNode, createVNode, defineComponent, isRef, mergeModels, mergeProps, nextTick, normalizeClass, normalizeStyle, openBlock, renderList, renderSlot, shallowRef, toDisplayString, unref, useModel, watch, withCtx, withDirectives } from "vue";
9
9
  import { useFormFallbackProps, useVirtualizer } from "@veltra/compositions";
10
- import { FORM_EMPTY_CONTENT, bem, injectFormContext, scrollIntoContainerView, withUnit } from "@veltra/utils";
10
+ import { FORM_EMPTY_CONTENT, bem, fieldKey, injectFormContext, scrollIntoContainerView, withUnit } from "@veltra/utils";
11
11
  import { ArrowDown, Search } from "@veltra/icons/normal";
12
12
  import { o } from "@cat-kit/core";
13
13
  import { vFocus } from "@veltra/directives";
@@ -67,6 +67,8 @@ const _sfc_main = /*@__PURE__*/ defineComponent({
67
67
  const props = __props;
68
68
  const emit = __emit;
69
69
  const cls = bem("select");
70
+ const labelKey = computed(() => fieldKey(props.labelKey, "label"));
71
+ const valueKey = computed(() => fieldKey(props.valueKey, "value"));
70
72
  const optionClass = cls.e("option");
71
73
  const { formProps } = injectFormContext();
72
74
  const { size, disabled, readonly } = useFormFallbackProps([formProps ?? {}, props], {
@@ -79,7 +81,7 @@ const _sfc_main = /*@__PURE__*/ defineComponent({
79
81
  const selected = shallowRef();
80
82
  const displayedValue = computed(() => {
81
83
  if (label.value) return label.value;
82
- return selected.value ? o(selected.value).get(props.labelKey) : String(props.modelValue ?? "");
84
+ return selected.value ? o(selected.value).get(labelKey.value) : String(props.modelValue ?? "");
83
85
  });
84
86
  const dropdownRef = shallowRef();
85
87
  const scrollRef = shallowRef();
@@ -99,11 +101,10 @@ const _sfc_main = /*@__PURE__*/ defineComponent({
99
101
  watch([() => props.modelValue, options], ([modelValue, options]) => {
100
102
  if (userSelecting) return;
101
103
  if (!options?.length) return;
102
- const { valueKey, labelKey } = props;
103
104
  if (modelValue !== void 0 && modelValue !== null && modelValue !== "") {
104
- currentIndex.value = options.findIndex((option) => o(option).get(valueKey) === modelValue);
105
+ currentIndex.value = options.findIndex((option) => o(option).get(valueKey.value) === modelValue);
105
106
  selected.value = currentIndex.value >= 0 ? options[currentIndex.value] : void 0;
106
- label.value = selected.value ? o(selected.value).get(labelKey) : void 0;
107
+ label.value = selected.value ? o(selected.value).get(labelKey.value) : void 0;
107
108
  } else {
108
109
  currentIndex.value = -1;
109
110
  selected.value = void 0;
@@ -121,14 +122,13 @@ const _sfc_main = /*@__PURE__*/ defineComponent({
121
122
  });
122
123
  const virtualOptions = computed(() => {
123
124
  const _options = options.value;
124
- const { labelKey, valueKey } = props;
125
125
  return items.value.map((item) => {
126
126
  const option = _options[item.index];
127
127
  return {
128
128
  option,
129
129
  index: item.index,
130
- label: o(option).get(labelKey),
131
- val: o(option).get(valueKey),
130
+ label: o(option).get(labelKey.value),
131
+ val: o(option).get(valueKey.value),
132
132
  key: item.index,
133
133
  offset: item.start
134
134
  };
@@ -159,8 +159,8 @@ const _sfc_main = /*@__PURE__*/ defineComponent({
159
159
  const handleSelect = (option, index) => {
160
160
  lock();
161
161
  selected.value = option;
162
- emit("update:modelValue", option?.[props.valueKey]);
163
- label.value = option?.[props.labelKey];
162
+ emit("update:modelValue", option?.[valueKey.value]);
163
+ label.value = option?.[labelKey.value];
164
164
  emit("change", option);
165
165
  if (option.__isTemp) temOptionsToCreatedOptions();
166
166
  currentIndex.value = index;
@@ -285,12 +285,12 @@ const _sfc_main = /*@__PURE__*/ defineComponent({
285
285
  class: normalizeClass([unref(optionClass), unref(bem).is("selected", index === currentIndex.value)]),
286
286
  onClick: ($event) => handleSelect(option, index),
287
287
  "data-index": index,
288
- title: unref(o)(option).get(__props.labelKey),
289
- key: unref(o)(option).get(__props.valueKey)
288
+ title: unref(o)(option).get(labelKey.value),
289
+ key: unref(o)(option).get(valueKey.value)
290
290
  }, [renderSlot(_ctx.$slots, "default", mergeProps({ ref_for: true }, {
291
291
  option,
292
292
  index
293
- }), () => [createTextVNode(toDisplayString(unref(o)(option).get(__props.labelKey)), 1)])], 10, _hoisted_2);
293
+ }), () => [createTextVNode(toDisplayString(unref(o)(option).get(labelKey.value)), 1)])], 10, _hoisted_2);
294
294
  }), 128))]),
295
295
  _: 3
296
296
  }, 8, [
@@ -1 +1 @@
1
- {"version":3,"file":"select.js","names":["$attrs","$slots"],"sources":["../../../src/components/select/select.vue"],"sourcesContent":["<template>\n <u-dropdown\n v-if=\"!readonly\"\n v-bind=\"$attrs\"\n trigger=\"click\"\n :class=\"[cls.b, bem.is('disabled', disabled)]\"\n ref=\"dropdownRef\"\n v-model:visible=\"dropdownVisible\"\n :content-class=\"[cls.e('panel'), cls.em('panel', size), contentClass]\"\n :content-style=\"contentStyle\"\n :disabled=\"disabled\"\n :min-width=\"minWidth\"\n :width=\"width\"\n @keydown=\"handleKeydown\"\n @update:visible=\"handleDropdownVisible\"\n >\n <!-- 触发 -->\n <template #trigger>\n <u-input\n :size=\"size\"\n :disabled=\"disabled\"\n :placeholder=\"placeholder\"\n :clearable=\"clearable\"\n :model-value=\"displayedValue\"\n @clear=\"handleClear\"\n @keydown=\"handleKeydown\"\n native-readonly\n >\n <template #prefix v-if=\"$slots.prefix\">\n <slot name=\"prefix\" />\n </template>\n\n <template #suffix>\n <u-icon :class=\"cls.e('arrow')\">\n <ArrowDown />\n </u-icon>\n </template>\n </u-input>\n </template>\n\n <!-- 下拉内容 -->\n <template #content>\n <!-- 过滤器 -->\n <div v-if=\"filterable\" :class=\"cls.e('content-filter')\">\n <u-input placeholder=\"输入关键字进行搜索\" tabindex=\"0\" v-focus v-model=\"queryString\">\n <template #suffix>\n <u-icon>\n <Search />\n </u-icon>\n </template>\n </u-input>\n </div>\n\n <!--\n 单选列表。虚拟化启用时,内容容器 height 由 useVirtualizer 命令式写入;\n 此处 content-style 仅承担 grid 相关样式,避免 height 变化触发模板重渲染。\n -->\n <u-scroll\n v-if=\"options.length\"\n tag=\"ul\"\n :class=\"cls.e('options')\"\n ref=\"scrollRef\"\n :content-class=\"[\n cls.e('options-wrap'),\n bem.is('virtual', virtualEnabled),\n bem.is('grid', !!grid)\n ]\"\n :content-style=\"{\n gridTemplateColumns: grid ? `repeat(${grid.cols}, minmax(0px, 1fr))` : undefined,\n gridGap: grid ? withUnit(grid.gap, 'px') : undefined\n }\"\n >\n <template v-if=\"virtualEnabled\">\n <!-- @vue-ignore -->\n <li\n v-for=\"{ option, index, val, label, key, offset } of virtualOptions\"\n :class=\"[optionClass, bem.is('selected', index === currentIndex)]\"\n @click=\"handleSelect(option, index)\"\n :key=\"key\"\n :style=\"{ transform: `translateY(${offset}px)` }\"\n :data-index=\"index\"\n :ref=\"(el) => measureElement(index, el as Element | null)\"\n >\n <slot v-bind=\"{ option, index }\">\n {{ label }}\n </slot>\n </li>\n </template>\n\n <template v-else>\n <li\n v-for=\"(option, index) of options\"\n :class=\"[optionClass, bem.is('selected', index === currentIndex)]\"\n @click=\"handleSelect(option, index)\"\n :data-index=\"index\"\n :title=\"o(option).get(labelKey)\"\n :key=\"o(option).get(valueKey)\"\n >\n <slot v-bind=\"{ option, index }\">\n {{ o(option).get(labelKey) }}\n </slot>\n </li>\n </template>\n </u-scroll>\n\n <div v-else :class=\"cls.e('empty')\">\n <UEmpty />\n </div>\n </template>\n </u-dropdown>\n\n <template v-else>\n {{ displayedValue || FORM_EMPTY_CONTENT }}\n </template>\n</template>\n\n<script lang=\"ts\" setup>\nimport { o } from '@cat-kit/core'\nimport { useFormFallbackProps, useVirtualizer } from '@veltra/compositions'\nimport { vFocus } from '@veltra/directives'\nimport { ArrowDown, Search } from '@veltra/icons/normal'\nimport { bem, FORM_EMPTY_CONTENT, scrollIntoContainerView, withUnit } from '@veltra/utils'\nimport { injectFormContext } from '@veltra/utils'\nimport { computed, nextTick, shallowRef, watch } from 'vue'\n\nimport type {\n SelectEmits,\n SelectProps,\n _SelectExposed,\n DropdownExposed,\n ScrollExposed\n} from '../../types'\nimport { UDropdown } from '../dropdown'\nimport { UEmpty } from '../empty'\nimport { UIcon } from '../icon'\nimport { UInput } from '../input'\nimport { UScroll } from '../scroll'\nimport { useKeyboard } from './use-keyboard'\nimport { useOptions } from './use-options'\n\ndefineOptions({ name: 'USelect', inheritAttrs: false })\n\nconst props = withDefaults(defineProps<SelectProps>(), {\n labelKey: 'label',\n valueKey: 'value',\n placeholder: '请选择',\n clearable: true,\n disabled: undefined,\n readonly: undefined\n})\n\nconst emit = defineEmits<SelectEmits>()\n\ndefineSlots<{\n /** 前缀插槽 */\n prefix?: () => any\n /** 默认插槽 */\n default?: (scope: { option: Record<string, any>; index: number }) => any\n}>()\n\nconst cls = bem('select')\n\nconst optionClass = cls.e('option')\n\nconst { formProps } = injectFormContext()\nconst { size, disabled, readonly } = useFormFallbackProps([formProps ?? {}, props], {\n size: 'default',\n disabled: false,\n readonly: false\n})\n\nconst currentIndex = shallowRef(-1)\nconst label = defineModel('text')\nconst selected = shallowRef<Record<string, any>>()\n\nconst displayedValue = computed(() => {\n if (label.value) return label.value\n\n return selected.value ? o(selected.value).get(props.labelKey) : String(props.modelValue ?? '')\n})\n\nconst dropdownRef = shallowRef<DropdownExposed>()\nconst scrollRef = shallowRef<ScrollExposed>()\n\nconst filterable = computed(() => {\n return props.filterable || typeof props.options === 'function'\n})\n\nconst { queryString, options, temOptionsToCreatedOptions, clearCreatedOptions } = useOptions({\n props\n})\n\n// TODO: 优化\nlet userSelecting = false\nfunction lock() {\n userSelecting = true\n}\n\nfunction unlock() {\n nextTick(() => {\n userSelecting = false\n })\n}\n\n// 回显\nwatch(\n [() => props.modelValue, options],\n ([modelValue, options]) => {\n if (userSelecting) return\n\n if (!options?.length) return\n\n const { valueKey, labelKey } = props\n\n if (modelValue !== undefined && modelValue !== null && modelValue !== '') {\n currentIndex.value = options.findIndex((option) => o(option).get(valueKey) === modelValue)\n selected.value = currentIndex.value >= 0 ? options[currentIndex.value] : undefined\n label.value = selected.value ? o(selected.value).get(labelKey) : undefined\n } else {\n currentIndex.value = -1\n selected.value = undefined\n label.value = undefined\n }\n },\n { immediate: true }\n)\n\nconst baseVirtualEnabled = computed(() => options.value.length > 80)\nconst virtualEnabled = computed(() => baseVirtualEnabled.value && !props.grid)\n\nconst { virtualizer, items } = useVirtualizer({\n count: computed(() => options.value.length),\n scrollEl: () => scrollRef.value?.containerRef ?? null,\n contentEl: () => (virtualEnabled.value ? (scrollRef.value?.contentRef ?? null) : null),\n gap: 4,\n estimateSize: () => 40\n})\n\nconst virtualOptions = computed(() => {\n const _options = options.value\n const { labelKey, valueKey } = props\n return items.value.map((item) => {\n const option = _options[item.index]!\n return {\n option,\n index: item.index,\n label: o(option).get(labelKey),\n val: o(option).get(valueKey),\n key: item.index,\n offset: item.start\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\nwatch([scrollRef, virtualEnabled], ([scroll, virtualEnabled]) => {\n if (!scroll || !props.modelValue) return\n\n if (virtualEnabled) {\n const index = options.value.findIndex((option) => option === selected.value)\n index !== -1 && dropdownVisible.value && nextTick(() => scrollTo(index))\n } else {\n const selectedEl = scroll?.contentRef?.getElementsByClassName('is-selected')[0]\n if (selectedEl) {\n scrollIntoContainerView(selectedEl as HTMLElement, scroll.containerRef ?? null)\n }\n }\n})\n\nconst dropdownVisible = shallowRef(false)\n\nwatch(dropdownVisible, (v) => {\n if (!v) {\n queryString.value = ''\n }\n})\n\nconst handleDropdownVisible = (visible: boolean) => {\n if (!visible) {\n queryString.value = ''\n }\n}\n\n/** 单选 */\nconst handleSelect = (option: Record<string, any>, index: number) => {\n lock()\n selected.value = option\n\n emit('update:modelValue', option?.[props.valueKey])\n label.value = option?.[props.labelKey]\n emit('change', option)\n if (option.__isTemp) {\n temOptionsToCreatedOptions()\n }\n currentIndex.value = index\n dropdownRef.value?.close()\n\n unlock()\n}\n\n/** 清除选项 */\nconst handleClear = () => {\n lock()\n selected.value = undefined\n currentIndex.value = -1\n label.value = undefined\n clearCreatedOptions()\n emit('update:modelValue', undefined)\n emit('change', undefined)\n unlock()\n}\n\nfunction getCurrentEl() {\n return scrollRef.value?.contentRef?.querySelector('li.is-selected') as HTMLElement | undefined\n}\n\nconst { handleKeydown } = useKeyboard({\n options,\n currentIndex,\n selectOption: handleSelect,\n getCurrentEl\n})\n</script>\n"],"mappings":"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"}
1
+ {"version":3,"file":"select.js","names":["$attrs","$slots"],"sources":["../../../src/components/select/select.vue"],"sourcesContent":["<template>\n <u-dropdown\n v-if=\"!readonly\"\n v-bind=\"$attrs\"\n trigger=\"click\"\n :class=\"[cls.b, bem.is('disabled', disabled)]\"\n ref=\"dropdownRef\"\n v-model:visible=\"dropdownVisible\"\n :content-class=\"[cls.e('panel'), cls.em('panel', size), contentClass]\"\n :content-style=\"contentStyle\"\n :disabled=\"disabled\"\n :min-width=\"minWidth\"\n :width=\"width\"\n @keydown=\"handleKeydown\"\n @update:visible=\"handleDropdownVisible\"\n >\n <!-- 触发 -->\n <template #trigger>\n <u-input\n :size=\"size\"\n :disabled=\"disabled\"\n :placeholder=\"placeholder\"\n :clearable=\"clearable\"\n :model-value=\"displayedValue\"\n @clear=\"handleClear\"\n @keydown=\"handleKeydown\"\n native-readonly\n >\n <template #prefix v-if=\"$slots.prefix\">\n <slot name=\"prefix\" />\n </template>\n\n <template #suffix>\n <u-icon :class=\"cls.e('arrow')\">\n <ArrowDown />\n </u-icon>\n </template>\n </u-input>\n </template>\n\n <!-- 下拉内容 -->\n <template #content>\n <!-- 过滤器 -->\n <div v-if=\"filterable\" :class=\"cls.e('content-filter')\">\n <u-input placeholder=\"输入关键字进行搜索\" tabindex=\"0\" v-focus v-model=\"queryString\">\n <template #suffix>\n <u-icon>\n <Search />\n </u-icon>\n </template>\n </u-input>\n </div>\n\n <!--\n 单选列表。虚拟化启用时,内容容器 height 由 useVirtualizer 命令式写入;\n 此处 content-style 仅承担 grid 相关样式,避免 height 变化触发模板重渲染。\n -->\n <u-scroll\n v-if=\"options.length\"\n tag=\"ul\"\n :class=\"cls.e('options')\"\n ref=\"scrollRef\"\n :content-class=\"[\n cls.e('options-wrap'),\n bem.is('virtual', virtualEnabled),\n bem.is('grid', !!grid)\n ]\"\n :content-style=\"{\n gridTemplateColumns: grid ? `repeat(${grid.cols}, minmax(0px, 1fr))` : undefined,\n gridGap: grid ? withUnit(grid.gap, 'px') : undefined\n }\"\n >\n <template v-if=\"virtualEnabled\">\n <!-- @vue-ignore -->\n <li\n v-for=\"{ option, index, val, label, key, offset } of virtualOptions\"\n :class=\"[optionClass, bem.is('selected', index === currentIndex)]\"\n @click=\"handleSelect(option, index)\"\n :key=\"key\"\n :style=\"{ transform: `translateY(${offset}px)` }\"\n :data-index=\"index\"\n :ref=\"(el) => measureElement(index, el as Element | null)\"\n >\n <slot v-bind=\"{ option, index }\">\n {{ label }}\n </slot>\n </li>\n </template>\n\n <template v-else>\n <li\n v-for=\"(option, index) of options\"\n :class=\"[optionClass, bem.is('selected', index === currentIndex)]\"\n @click=\"handleSelect(option, index)\"\n :data-index=\"index\"\n :title=\"o(option).get(labelKey)\"\n :key=\"o(option).get(valueKey)\"\n >\n <slot v-bind=\"{ option, index }\">\n {{ o(option).get(labelKey) }}\n </slot>\n </li>\n </template>\n </u-scroll>\n\n <div v-else :class=\"cls.e('empty')\">\n <UEmpty />\n </div>\n </template>\n </u-dropdown>\n\n <template v-else>\n {{ displayedValue || FORM_EMPTY_CONTENT }}\n </template>\n</template>\n\n<script lang=\"ts\" setup>\nimport { o } from '@cat-kit/core'\nimport { useFormFallbackProps, useVirtualizer } from '@veltra/compositions'\nimport { vFocus } from '@veltra/directives'\nimport { ArrowDown, Search } from '@veltra/icons/normal'\nimport { bem, fieldKey, FORM_EMPTY_CONTENT, scrollIntoContainerView, withUnit } from '@veltra/utils'\nimport { injectFormContext } from '@veltra/utils'\nimport { computed, nextTick, shallowRef, watch } from 'vue'\n\nimport type {\n SelectEmits,\n SelectProps,\n _SelectExposed,\n DropdownExposed,\n ScrollExposed\n} from '../../types'\nimport { UDropdown } from '../dropdown'\nimport { UEmpty } from '../empty'\nimport { UIcon } from '../icon'\nimport { UInput } from '../input'\nimport { UScroll } from '../scroll'\nimport { useKeyboard } from './use-keyboard'\nimport { useOptions } from './use-options'\n\ndefineOptions({ name: 'USelect', inheritAttrs: false })\n\nconst props = withDefaults(defineProps<SelectProps>(), {\n labelKey: 'label',\n valueKey: 'value',\n placeholder: '请选择',\n clearable: true,\n disabled: undefined,\n readonly: undefined\n})\n\nconst emit = defineEmits<SelectEmits>()\n\ndefineSlots<{\n /** 前缀插槽 */\n prefix?: () => any\n /** 默认插槽 */\n default?: (scope: { option: Record<string, any>; index: number }) => any\n}>()\n\nconst cls = bem('select')\n\nconst labelKey = computed(() => fieldKey(props.labelKey, 'label'))\nconst valueKey = computed(() => fieldKey(props.valueKey, 'value'))\n\nconst optionClass = cls.e('option')\n\nconst { formProps } = injectFormContext()\nconst { size, disabled, readonly } = useFormFallbackProps([formProps ?? {}, props], {\n size: 'default',\n disabled: false,\n readonly: false\n})\n\nconst currentIndex = shallowRef(-1)\nconst label = defineModel('text')\nconst selected = shallowRef<Record<string, any>>()\n\nconst displayedValue = computed(() => {\n if (label.value) return label.value\n\n return selected.value ? o(selected.value).get(labelKey.value) : String(props.modelValue ?? '')\n})\n\nconst dropdownRef = shallowRef<DropdownExposed>()\nconst scrollRef = shallowRef<ScrollExposed>()\n\nconst filterable = computed(() => {\n return props.filterable || typeof props.options === 'function'\n})\n\nconst { queryString, options, temOptionsToCreatedOptions, clearCreatedOptions } = useOptions({\n props\n})\n\n// TODO: 优化\nlet userSelecting = false\nfunction lock() {\n userSelecting = true\n}\n\nfunction unlock() {\n nextTick(() => {\n userSelecting = false\n })\n}\n\n// 回显\nwatch(\n [() => props.modelValue, options],\n ([modelValue, options]) => {\n if (userSelecting) return\n\n if (!options?.length) return\n\n if (modelValue !== undefined && modelValue !== null && modelValue !== '') {\n currentIndex.value = options.findIndex(\n (option) => o(option).get(valueKey.value) === modelValue\n )\n selected.value = currentIndex.value >= 0 ? options[currentIndex.value] : undefined\n label.value = selected.value ? o(selected.value).get(labelKey.value) : undefined\n } else {\n currentIndex.value = -1\n selected.value = undefined\n label.value = undefined\n }\n },\n { immediate: true }\n)\n\nconst baseVirtualEnabled = computed(() => options.value.length > 80)\nconst virtualEnabled = computed(() => baseVirtualEnabled.value && !props.grid)\n\nconst { virtualizer, items } = useVirtualizer({\n count: computed(() => options.value.length),\n scrollEl: () => scrollRef.value?.containerRef ?? null,\n contentEl: () => (virtualEnabled.value ? (scrollRef.value?.contentRef ?? null) : null),\n gap: 4,\n estimateSize: () => 40\n})\n\nconst virtualOptions = computed(() => {\n const _options = options.value\n return items.value.map((item) => {\n const option = _options[item.index]!\n return {\n option,\n index: item.index,\n label: o(option).get(labelKey.value),\n val: o(option).get(valueKey.value),\n key: item.index,\n offset: item.start\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\nwatch([scrollRef, virtualEnabled], ([scroll, virtualEnabled]) => {\n if (!scroll || !props.modelValue) return\n\n if (virtualEnabled) {\n const index = options.value.findIndex((option) => option === selected.value)\n index !== -1 && dropdownVisible.value && nextTick(() => scrollTo(index))\n } else {\n const selectedEl = scroll?.contentRef?.getElementsByClassName('is-selected')[0]\n if (selectedEl) {\n scrollIntoContainerView(selectedEl as HTMLElement, scroll.containerRef ?? null)\n }\n }\n})\n\nconst dropdownVisible = shallowRef(false)\n\nwatch(dropdownVisible, (v) => {\n if (!v) {\n queryString.value = ''\n }\n})\n\nconst handleDropdownVisible = (visible: boolean) => {\n if (!visible) {\n queryString.value = ''\n }\n}\n\n/** 单选 */\nconst handleSelect = (option: Record<string, any>, index: number) => {\n lock()\n selected.value = option\n\n emit('update:modelValue', option?.[valueKey.value])\n label.value = option?.[labelKey.value]\n emit('change', option)\n if (option.__isTemp) {\n temOptionsToCreatedOptions()\n }\n currentIndex.value = index\n dropdownRef.value?.close()\n\n unlock()\n}\n\n/** 清除选项 */\nconst handleClear = () => {\n lock()\n selected.value = undefined\n currentIndex.value = -1\n label.value = undefined\n clearCreatedOptions()\n emit('update:modelValue', undefined)\n emit('change', undefined)\n unlock()\n}\n\nfunction getCurrentEl() {\n return scrollRef.value?.contentRef?.querySelector('li.is-selected') as HTMLElement | undefined\n}\n\nconst { handleKeydown } = useKeyboard({\n options,\n currentIndex,\n selectOption: handleSelect,\n getCurrentEl\n})\n</script>\n"],"mappings":"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"}
@@ -24,12 +24,12 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_PublicProps, {}, {
24
24
  "onUpdate:text"?: ((value: any) => any) | undefined;
25
25
  "onUpdate:label"?: ((label?: string | undefined) => any) | undefined;
26
26
  }>, {
27
- disabled: boolean;
28
- readonly: boolean;
29
27
  labelKey: string;
30
28
  valueKey: string;
31
29
  placeholder: string;
32
30
  clearable: boolean;
31
+ disabled: boolean;
32
+ readonly: boolean;
33
33
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
34
34
  declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
35
35
  declare const _default: typeof __VLS_export;
@@ -1,4 +1,5 @@
1
1
  import { computed, shallowRef, watch } from "vue";
2
+ import { fieldKey } from "@veltra/utils";
2
3
  import { debounce, o } from "@cat-kit/core";
3
4
  //#region src/components/select/use-options.ts
4
5
  function useOptions(o$1) {
@@ -25,11 +26,13 @@ function useOptions(o$1) {
25
26
  tempOptions.value = [];
26
27
  return;
27
28
  }
29
+ const labelKey = fieldKey(props.labelKey, "label");
30
+ const valueKey = fieldKey(props.valueKey, "value");
28
31
  if (!(options ? options.some((option) => {
29
- return o(option).get(props.labelKey) === qs;
32
+ return o(option).get(labelKey) === qs;
30
33
  }) : false)) tempOptions.value = [{
31
- [props.labelKey]: qs,
32
- [props.valueKey]: qs,
34
+ [labelKey]: qs,
35
+ [valueKey]: qs,
33
36
  __isTemp: true
34
37
  }];
35
38
  };
@@ -52,7 +55,7 @@ function useOptions(o$1) {
52
55
  remoteOptions.value = options;
53
56
  setTempOption(qs, options);
54
57
  } else {
55
- const { labelKey } = props;
58
+ const labelKey = fieldKey(props.labelKey, "label");
56
59
  if (!qs) {
57
60
  filteredOptions.value = propsOptions ?? [];
58
61
  setTempOption(qs, filteredOptions.value);
@@ -1 +1 @@
1
- {"version":3,"file":"use-options.js","names":["o","chainObj"],"sources":["../../../src/components/select/use-options.ts"],"sourcesContent":["import { debounce, o as chainObj } from '@cat-kit/core'\nimport { computed, shallowRef, watch, type ShallowRef, type ComputedRef } from 'vue'\n\nimport type { SelectProps } from '../../types'\n\ninterface Options {\n props: SelectProps\n}\n\ninterface UseOptionsReturned {\n /** 查询字符串 */\n queryString: ShallowRef<string>\n /** 选项 */\n options: ComputedRef<Record<string, any>[]>\n /** 所有选项 */\n allOptions: ComputedRef<Record<string, any>[]>\n /** 将临时选项转换为创建的选项 */\n temOptionsToCreatedOptions: () => void\n /** 清空用户创建的选项 */\n clearCreatedOptions: () => void\n}\n\n// 允许创建的实现\n// 1. 在过滤时将选项加入待选列表中\n// 2. 如果选择了改临时选项,则取消该选项的临时标记\n// 3. 如果第二次重新选择\n\nexport function useOptions(o: Options): UseOptionsReturned {\n const { props } = o\n\n /** 筛选 */\n const queryString = shallowRef('')\n\n const remoteOptions = shallowRef<Record<string, any>[]>([])\n const filteredOptions = shallowRef<Record<string, any>[]>([])\n // 临时选项\n const tempOptions = shallowRef<({ __isTemp: true } & Record<string, any>)[]>([])\n // 创建的选项\n const createdOptions = shallowRef<({ __isTemp: false } & Record<string, any>)[]>([])\n\n function temOptionsToCreatedOptions() {\n createdOptions.value = tempOptions.value.map((item) => {\n return { ...item, __isTemp: false }\n })\n }\n\n function clearCreatedOptions() {\n createdOptions.value = []\n }\n\n const setTempOption = (qs: string, options?: Record<string, any>[]) => {\n if (!qs?.trim() || !props.creatable) {\n tempOptions.value = []\n return\n }\n const exactMatch = options\n ? options.some((option) => {\n return chainObj(option).get(props.labelKey!) === qs\n })\n : false\n\n if (!exactMatch) {\n tempOptions.value = [{ [props.labelKey!]: qs, [props.valueKey!]: qs, __isTemp: true }]\n }\n }\n\n const allOptions = computed(() => {\n const { options } = props\n if (typeof options === 'function') return remoteOptions.value\n return options ?? []\n })\n\n /** 展示的选项 */\n const options = computed(() => {\n const { options } = props\n\n if (typeof options === 'function') return remoteOptions.value\n\n const prependOptions = tempOptions.value?.length ? tempOptions.value : createdOptions.value\n\n if (!options) {\n return prependOptions\n }\n\n return [...prependOptions, ...filteredOptions.value]\n })\n\n // TODO: 如有性能问题可以考虑优化\n watch(\n [queryString, () => props.options],\n debounce(async ([qs, propsOptions]) => {\n if (typeof propsOptions === 'function') {\n const options = await propsOptions(qs)\n remoteOptions.value = options\n setTempOption(qs, options)\n } else {\n // 当选项不是函数时,可以创建选项\n const { labelKey } = props\n\n if (!qs) {\n filteredOptions.value = propsOptions ?? []\n setTempOption(qs, filteredOptions.value)\n return\n }\n\n const _filteredOptions =\n propsOptions?.filter((item) => {\n return chainObj(item).get(labelKey!)?.includes(qs) ?? false\n }) ?? []\n\n setTempOption(qs, _filteredOptions)\n filteredOptions.value = _filteredOptions\n }\n }, 200),\n { immediate: true }\n )\n\n return { queryString, options, allOptions, temOptionsToCreatedOptions, clearCreatedOptions }\n}\n"],"mappings":";;;AA2BA,SAAgB,WAAW,KAAgC;CACzD,MAAM,EAAE,UAAUA;;CAGlB,MAAM,cAAc,WAAW,EAAE;CAEjC,MAAM,gBAAgB,WAAkC,CAAC,CAAC;CAC1D,MAAM,kBAAkB,WAAkC,CAAC,CAAC;CAE5D,MAAM,cAAc,WAAyD,CAAC,CAAC;CAE/E,MAAM,iBAAiB,WAA0D,CAAC,CAAC;CAEnF,SAAS,6BAA6B;EACpC,eAAe,QAAQ,YAAY,MAAM,KAAK,SAAS;GACrD,OAAO;IAAE,GAAG;IAAM,UAAU;GAAM;EACpC,CAAC;CACH;CAEA,SAAS,sBAAsB;EAC7B,eAAe,QAAQ,CAAC;CAC1B;CAEA,MAAM,iBAAiB,IAAY,YAAoC;EACrE,IAAI,CAAC,IAAI,KAAK,KAAK,CAAC,MAAM,WAAW;GACnC,YAAY,QAAQ,CAAC;GACrB;EACF;EAOA,IAAI,EANe,UACf,QAAQ,MAAM,WAAW;GACvB,OAAOC,EAAS,MAAM,CAAC,CAAC,IAAI,MAAM,QAAS,MAAM;EACnD,CAAC,IACD,QAGF,YAAY,QAAQ,CAAC;IAAG,MAAM,WAAY;IAAK,MAAM,WAAY;GAAI,UAAU;EAAK,CAAC;CAEzF;CAEA,MAAM,aAAa,eAAe;EAChC,MAAM,EAAE,YAAY;EACpB,IAAI,OAAO,YAAY,YAAY,OAAO,cAAc;EACxD,OAAO,WAAW,CAAC;CACrB,CAAC;;CAGD,MAAM,UAAU,eAAe;EAC7B,MAAM,EAAE,YAAY;EAEpB,IAAI,OAAO,YAAY,YAAY,OAAO,cAAc;EAExD,MAAM,iBAAiB,YAAY,OAAO,SAAS,YAAY,QAAQ,eAAe;EAEtF,IAAI,CAAC,SACH,OAAO;EAGT,OAAO,CAAC,GAAG,gBAAgB,GAAG,gBAAgB,KAAK;CACrD,CAAC;CAGD,MACE,CAAC,mBAAmB,MAAM,OAAO,GACjC,SAAS,OAAO,CAAC,IAAI,kBAAkB;EACrC,IAAI,OAAO,iBAAiB,YAAY;GACtC,MAAM,UAAU,MAAM,aAAa,EAAE;GACrC,cAAc,QAAQ;GACtB,cAAc,IAAI,OAAO;EAC3B,OAAO;GAEL,MAAM,EAAE,aAAa;GAErB,IAAI,CAAC,IAAI;IACP,gBAAgB,QAAQ,gBAAgB,CAAC;IACzC,cAAc,IAAI,gBAAgB,KAAK;IACvC;GACF;GAEA,MAAM,mBACJ,cAAc,QAAQ,SAAS;IAC7B,OAAOA,EAAS,IAAI,CAAC,CAAC,IAAI,QAAS,CAAC,EAAE,SAAS,EAAE,KAAK;GACxD,CAAC,KAAK,CAAC;GAET,cAAc,IAAI,gBAAgB;GAClC,gBAAgB,QAAQ;EAC1B;CACF,GAAG,GAAG,GACN,EAAE,WAAW,KAAK,CACpB;CAEA,OAAO;EAAE;EAAa;EAAS;EAAY;EAA4B;CAAoB;AAC7F"}
1
+ {"version":3,"file":"use-options.js","names":["o","chainObj"],"sources":["../../../src/components/select/use-options.ts"],"sourcesContent":["import { debounce, o as chainObj } from '@cat-kit/core'\nimport { fieldKey } from '@veltra/utils'\nimport { computed, shallowRef, watch, type ShallowRef, type ComputedRef } from 'vue'\n\nimport type { SelectProps } from '../../types'\n\ninterface Options {\n props: SelectProps\n}\n\ninterface UseOptionsReturned {\n /** 查询字符串 */\n queryString: ShallowRef<string>\n /** 选项 */\n options: ComputedRef<Record<string, any>[]>\n /** 所有选项 */\n allOptions: ComputedRef<Record<string, any>[]>\n /** 将临时选项转换为创建的选项 */\n temOptionsToCreatedOptions: () => void\n /** 清空用户创建的选项 */\n clearCreatedOptions: () => void\n}\n\n// 允许创建的实现\n// 1. 在过滤时将选项加入待选列表中\n// 2. 如果选择了改临时选项,则取消该选项的临时标记\n// 3. 如果第二次重新选择\n\nexport function useOptions(o: Options): UseOptionsReturned {\n const { props } = o\n\n /** 筛选 */\n const queryString = shallowRef('')\n\n const remoteOptions = shallowRef<Record<string, any>[]>([])\n const filteredOptions = shallowRef<Record<string, any>[]>([])\n // 临时选项\n const tempOptions = shallowRef<({ __isTemp: true } & Record<string, any>)[]>([])\n // 创建的选项\n const createdOptions = shallowRef<({ __isTemp: false } & Record<string, any>)[]>([])\n\n function temOptionsToCreatedOptions() {\n createdOptions.value = tempOptions.value.map((item) => {\n return { ...item, __isTemp: false }\n })\n }\n\n function clearCreatedOptions() {\n createdOptions.value = []\n }\n\n const setTempOption = (qs: string, options?: Record<string, any>[]) => {\n if (!qs?.trim() || !props.creatable) {\n tempOptions.value = []\n return\n }\n const labelKey = fieldKey(props.labelKey, 'label')\n const valueKey = fieldKey(props.valueKey, 'value')\n const exactMatch = options\n ? options.some((option) => {\n return chainObj(option).get(labelKey) === qs\n })\n : false\n\n if (!exactMatch) {\n tempOptions.value = [{ [labelKey]: qs, [valueKey]: qs, __isTemp: true }]\n }\n }\n\n const allOptions = computed(() => {\n const { options } = props\n if (typeof options === 'function') return remoteOptions.value\n return options ?? []\n })\n\n /** 展示的选项 */\n const options = computed(() => {\n const { options } = props\n\n if (typeof options === 'function') return remoteOptions.value\n\n const prependOptions = tempOptions.value?.length ? tempOptions.value : createdOptions.value\n\n if (!options) {\n return prependOptions\n }\n\n return [...prependOptions, ...filteredOptions.value]\n })\n\n // TODO: 如有性能问题可以考虑优化\n watch(\n [queryString, () => props.options],\n debounce(async ([qs, propsOptions]) => {\n if (typeof propsOptions === 'function') {\n const options = await propsOptions(qs)\n remoteOptions.value = options\n setTempOption(qs, options)\n } else {\n // 当选项不是函数时,可以创建选项\n const labelKey = fieldKey(props.labelKey, 'label')\n\n if (!qs) {\n filteredOptions.value = propsOptions ?? []\n setTempOption(qs, filteredOptions.value)\n return\n }\n\n const _filteredOptions =\n propsOptions?.filter((item) => {\n return chainObj(item).get(labelKey)?.includes(qs) ?? false\n }) ?? []\n\n setTempOption(qs, _filteredOptions)\n filteredOptions.value = _filteredOptions\n }\n }, 200),\n { immediate: true }\n )\n\n return { queryString, options, allOptions, temOptionsToCreatedOptions, clearCreatedOptions }\n}\n"],"mappings":";;;;AA4BA,SAAgB,WAAW,KAAgC;CACzD,MAAM,EAAE,UAAUA;;CAGlB,MAAM,cAAc,WAAW,EAAE;CAEjC,MAAM,gBAAgB,WAAkC,CAAC,CAAC;CAC1D,MAAM,kBAAkB,WAAkC,CAAC,CAAC;CAE5D,MAAM,cAAc,WAAyD,CAAC,CAAC;CAE/E,MAAM,iBAAiB,WAA0D,CAAC,CAAC;CAEnF,SAAS,6BAA6B;EACpC,eAAe,QAAQ,YAAY,MAAM,KAAK,SAAS;GACrD,OAAO;IAAE,GAAG;IAAM,UAAU;GAAM;EACpC,CAAC;CACH;CAEA,SAAS,sBAAsB;EAC7B,eAAe,QAAQ,CAAC;CAC1B;CAEA,MAAM,iBAAiB,IAAY,YAAoC;EACrE,IAAI,CAAC,IAAI,KAAK,KAAK,CAAC,MAAM,WAAW;GACnC,YAAY,QAAQ,CAAC;GACrB;EACF;EACA,MAAM,WAAW,SAAS,MAAM,UAAU,OAAO;EACjD,MAAM,WAAW,SAAS,MAAM,UAAU,OAAO;EAOjD,IAAI,EANe,UACf,QAAQ,MAAM,WAAW;GACvB,OAAOC,EAAS,MAAM,CAAC,CAAC,IAAI,QAAQ,MAAM;EAC5C,CAAC,IACD,QAGF,YAAY,QAAQ,CAAC;IAAG,WAAW;IAAK,WAAW;GAAI,UAAU;EAAK,CAAC;CAE3E;CAEA,MAAM,aAAa,eAAe;EAChC,MAAM,EAAE,YAAY;EACpB,IAAI,OAAO,YAAY,YAAY,OAAO,cAAc;EACxD,OAAO,WAAW,CAAC;CACrB,CAAC;;CAGD,MAAM,UAAU,eAAe;EAC7B,MAAM,EAAE,YAAY;EAEpB,IAAI,OAAO,YAAY,YAAY,OAAO,cAAc;EAExD,MAAM,iBAAiB,YAAY,OAAO,SAAS,YAAY,QAAQ,eAAe;EAEtF,IAAI,CAAC,SACH,OAAO;EAGT,OAAO,CAAC,GAAG,gBAAgB,GAAG,gBAAgB,KAAK;CACrD,CAAC;CAGD,MACE,CAAC,mBAAmB,MAAM,OAAO,GACjC,SAAS,OAAO,CAAC,IAAI,kBAAkB;EACrC,IAAI,OAAO,iBAAiB,YAAY;GACtC,MAAM,UAAU,MAAM,aAAa,EAAE;GACrC,cAAc,QAAQ;GACtB,cAAc,IAAI,OAAO;EAC3B,OAAO;GAEL,MAAM,WAAW,SAAS,MAAM,UAAU,OAAO;GAEjD,IAAI,CAAC,IAAI;IACP,gBAAgB,QAAQ,gBAAgB,CAAC;IACzC,cAAc,IAAI,gBAAgB,KAAK;IACvC;GACF;GAEA,MAAM,mBACJ,cAAc,QAAQ,SAAS;IAC7B,OAAOA,EAAS,IAAI,CAAC,CAAC,IAAI,QAAQ,CAAC,EAAE,SAAS,EAAE,KAAK;GACvD,CAAC,KAAK,CAAC;GAET,cAAc,IAAI,gBAAgB;GAClC,gBAAgB,QAAQ;EAC1B;CACF,GAAG,GAAG,GACN,EAAE,WAAW,KAAK,CACpB;CAEA,OAAO;EAAE;EAAa;EAAS;EAAY;EAA4B;CAAoB;AAC7F"}
@@ -3,7 +3,7 @@ import NodeRender from "../node-render/node-render.js";
3
3
  import _sfc_main$2 from "../tip/tip.js";
4
4
  import { Fragment, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createTextVNode, createVNode, defineComponent, normalizeClass, openBlock, renderList, renderSlot, shallowRef, toDisplayString, unref, useSlots, useTemplateRef, watch, withCtx } from "vue";
5
5
  import { useFallbackProps } from "@veltra/compositions";
6
- import { bem } from "@veltra/utils";
6
+ import { bem, fieldKey } from "@veltra/utils";
7
7
  import { Check } from "@veltra/icons/normal";
8
8
  import { n, o } from "@cat-kit/core";
9
9
  //#region src/components/steps/steps.vue
@@ -29,6 +29,7 @@ const _sfc_main = /*@__PURE__*/ defineComponent({
29
29
  const emit = __emit;
30
30
  const slots = useSlots();
31
31
  const cls = bem("steps");
32
+ const labelKey = computed(() => fieldKey(props.labelKey, "label"));
32
33
  const { size } = useFallbackProps([props], { size: "default" });
33
34
  const className = computed(() => {
34
35
  const { direction, currentStepType, finishedStepType } = props;
@@ -126,7 +127,7 @@ const _sfc_main = /*@__PURE__*/ defineComponent({
126
127
  })) : (openBlock(), createElementBlock(Fragment, { key: 1 }, [createTextVNode(toDisplayString(index + 1), 1)], 64))])], 42, _hoisted_2)], 2), createElementVNode("div", { class: normalizeClass(unref(cls).e("content")) }, [renderSlot(_ctx.$slots, "content", {
127
128
  item,
128
129
  index
129
- }, () => [createTextVNode(toDisplayString(unref(o)(item).get(__props.labelKey)), 1)])], 2)], 10, _hoisted_1);
130
+ }, () => [createTextVNode(toDisplayString(unref(o)(item).get(labelKey.value)), 1)])], 2)], 10, _hoisted_1);
130
131
  }), 256)), slots.tip ? (openBlock(), createBlock(unref(_sfc_main$2), {
131
132
  key: 0,
132
133
  ref: "tip",
@@ -1 +1 @@
1
- {"version":3,"file":"steps.js","names":[],"sources":["../../../src/components/steps/steps.vue"],"sourcesContent":["<template>\n <ol :class=\"className\" ref=\"steps\">\n <li\n v-for=\"(item, index) in items\"\n :class=\"[\n cls.e('item'),\n bem.is('current', index === currentIndex),\n bem.is('finished', currentIndex === undefined || index < currentIndex)\n ]\"\n @click=\"handleStepClick(item, index)\"\n >\n <div :class=\"cls.e('node')\">\n <i :class=\"cls.e('link')\" v-if=\"index !== items.length - 1\"></i>\n\n <span\n :class=\"cls.e('icon')\"\n @mouseenter=\"handleStepMouseenter($event, item, index)\"\n @mouseleave=\"handleStepMouseleave\"\n >\n <slot name=\"icon\" :item=\"item\" :index=\"index\">\n <UIcon v-if=\"currentIndex === undefined || index < currentIndex\">\n <Check />\n </UIcon>\n\n <template v-else>\n {{ index + 1 }}\n </template>\n </slot>\n </span>\n </div>\n\n <div :class=\"cls.e('content')\">\n <slot name=\"content\" :item=\"item\" :index=\"index\">\n {{ o(item).get(labelKey) }}\n </slot>\n </div>\n </li>\n\n <u-tip\n v-if=\"slots.tip\"\n ref=\"tip\"\n :trigger-dom=\"tipTriggerDom\"\n v-model:visible=\"tipVisible\"\n @update:visible=\"handleTipUpdateVisible\"\n >\n <template #content>\n <UNodeRender :content=\"tipContent\" />\n </template>\n </u-tip>\n </ol>\n</template>\n\n<script lang=\"ts\" setup>\nimport { n, o } from '@cat-kit/core'\nimport { useFallbackProps } from '@veltra/compositions'\nimport { Check } from '@veltra/icons/normal'\nimport { bem } from '@veltra/utils'\nimport { computed, shallowRef, useTemplateRef, watch } from 'vue'\n\nimport type { StepsProps, StepsEmits, ComponentSize, StepsSlotScope } from '../../types'\nimport { UIcon } from '../icon'\nimport { UNodeRender } from '../node-render'\nimport { UTip } from '../tip'\n\ndefineOptions({ name: 'USteps' })\n\nconst props = withDefaults(defineProps<StepsProps>(), {\n direction: 'horizontal',\n finishedStepType: 'success',\n labelKey: 'label'\n})\n\nconst emit = defineEmits<StepsEmits>()\n\nconst slots = defineSlots<{\n icon?: (scope: StepsSlotScope) => any\n content?: (scope: StepsSlotScope) => any\n tip?: (scope: StepsSlotScope) => any\n}>()\n\nconst cls = bem('steps')\n\nconst { size } = useFallbackProps([props], { size: 'default' as ComponentSize })\n\nconst className = computed(() => {\n const { direction, currentStepType, finishedStepType } = props\n const ret: string[] = [\n cls.b,\n bem.is(direction),\n cls.m(size.value),\n bem.is('align-center', props.alignCenter),\n cls.em('finished', finishedStepType)\n ]\n currentStepType && ret.push(cls.em('current', currentStepType))\n return ret\n})\n\nconst stepsRef = useTemplateRef('steps')\n\nconst currentToIndexMap = computed<Record<string, number> | undefined>(() => {\n const { currentKey, items } = props\n if (!currentKey) return undefined\n return items.reduce(\n (acc, item, index) => {\n acc[o(item).get(currentKey)] = index\n return acc\n },\n {} as Record<string, number>\n )\n})\n\n/** 当前索引 */\nconst currentIndex = computed<number | undefined>(() => {\n const { currentKey, current } = props\n if (current === undefined) return undefined\n\n if (currentKey) {\n return currentToIndexMap.value?.[current]\n }\n\n if (typeof current !== 'number') return undefined\n return n(current).range(0, props.items.length - 1)\n})\n\nwatch(currentIndex, (index) => {\n if (index === undefined || props.direction === 'vertical') return\n const step = stepsRef.value?.children[index]\n if (step) {\n step.scrollIntoView({ behavior: 'smooth', block: 'center' })\n }\n})\n\n// 点击步骤项\nfunction handleStepClick(item: Record<string, any>, index: number) {\n emit('item-click', item, index)\n emit('update:current', props.currentKey ? o(item).get(props.currentKey) : index)\n}\n\n// 提示\nconst tipVisible = shallowRef(false)\nconst tipTriggerDom = shallowRef<HTMLElement>()\nconst tipContent = shallowRef()\n\nfunction handleStepMouseenter(event: MouseEvent, item: Record<string, any>, index: number) {\n if (!slots.tip) return\n tipTriggerDom.value = event.target as HTMLElement\n tipVisible.value = true\n tipContent.value = slots.tip?.({ item, index })\n}\n\nlet timer: number | undefined = undefined\nfunction closeTip() {\n timer = setTimeout(() => {\n tipVisible.value = false\n tipContent.value = undefined\n tipTriggerDom.value = undefined\n }, 250)\n}\n\nfunction handleTipUpdateVisible(visible: boolean) {\n visible && clearTimeout(timer)\n}\n\nfunction handleStepMouseleave() {\n if (!slots.tip) return\n closeTip()\n}\n</script>\n"],"mappings":"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"}
1
+ {"version":3,"file":"steps.js","names":[],"sources":["../../../src/components/steps/steps.vue"],"sourcesContent":["<template>\n <ol :class=\"className\" ref=\"steps\">\n <li\n v-for=\"(item, index) in items\"\n :class=\"[\n cls.e('item'),\n bem.is('current', index === currentIndex),\n bem.is('finished', currentIndex === undefined || index < currentIndex)\n ]\"\n @click=\"handleStepClick(item, index)\"\n >\n <div :class=\"cls.e('node')\">\n <i :class=\"cls.e('link')\" v-if=\"index !== items.length - 1\"></i>\n\n <span\n :class=\"cls.e('icon')\"\n @mouseenter=\"handleStepMouseenter($event, item, index)\"\n @mouseleave=\"handleStepMouseleave\"\n >\n <slot name=\"icon\" :item=\"item\" :index=\"index\">\n <UIcon v-if=\"currentIndex === undefined || index < currentIndex\">\n <Check />\n </UIcon>\n\n <template v-else>\n {{ index + 1 }}\n </template>\n </slot>\n </span>\n </div>\n\n <div :class=\"cls.e('content')\">\n <slot name=\"content\" :item=\"item\" :index=\"index\">\n {{ o(item).get(labelKey) }}\n </slot>\n </div>\n </li>\n\n <u-tip\n v-if=\"slots.tip\"\n ref=\"tip\"\n :trigger-dom=\"tipTriggerDom\"\n v-model:visible=\"tipVisible\"\n @update:visible=\"handleTipUpdateVisible\"\n >\n <template #content>\n <UNodeRender :content=\"tipContent\" />\n </template>\n </u-tip>\n </ol>\n</template>\n\n<script lang=\"ts\" setup>\nimport { n, o } from '@cat-kit/core'\nimport { useFallbackProps } from '@veltra/compositions'\nimport { Check } from '@veltra/icons/normal'\nimport { bem, fieldKey } from '@veltra/utils'\nimport { computed, shallowRef, useTemplateRef, watch } from 'vue'\n\nimport type { StepsProps, StepsEmits, ComponentSize, StepsSlotScope } from '../../types'\nimport { UIcon } from '../icon'\nimport { UNodeRender } from '../node-render'\nimport { UTip } from '../tip'\n\ndefineOptions({ name: 'USteps' })\n\nconst props = withDefaults(defineProps<StepsProps>(), {\n direction: 'horizontal',\n finishedStepType: 'success',\n labelKey: 'label'\n})\n\nconst emit = defineEmits<StepsEmits>()\n\nconst slots = defineSlots<{\n icon?: (scope: StepsSlotScope) => any\n content?: (scope: StepsSlotScope) => any\n tip?: (scope: StepsSlotScope) => any\n}>()\n\nconst cls = bem('steps')\n\nconst labelKey = computed(() => fieldKey(props.labelKey, 'label'))\n\nconst { size } = useFallbackProps([props], { size: 'default' as ComponentSize })\n\nconst className = computed(() => {\n const { direction, currentStepType, finishedStepType } = props\n const ret: string[] = [\n cls.b,\n bem.is(direction),\n cls.m(size.value),\n bem.is('align-center', props.alignCenter),\n cls.em('finished', finishedStepType)\n ]\n currentStepType && ret.push(cls.em('current', currentStepType))\n return ret\n})\n\nconst stepsRef = useTemplateRef('steps')\n\nconst currentToIndexMap = computed<Record<string, number> | undefined>(() => {\n const { currentKey, items } = props\n if (!currentKey) return undefined\n return items.reduce(\n (acc, item, index) => {\n acc[o(item).get(currentKey)] = index\n return acc\n },\n {} as Record<string, number>\n )\n})\n\n/** 当前索引 */\nconst currentIndex = computed<number | undefined>(() => {\n const { currentKey, current } = props\n if (current === undefined) return undefined\n\n if (currentKey) {\n return currentToIndexMap.value?.[current]\n }\n\n if (typeof current !== 'number') return undefined\n return n(current).range(0, props.items.length - 1)\n})\n\nwatch(currentIndex, (index) => {\n if (index === undefined || props.direction === 'vertical') return\n const step = stepsRef.value?.children[index]\n if (step) {\n step.scrollIntoView({ behavior: 'smooth', block: 'center' })\n }\n})\n\n// 点击步骤项\nfunction handleStepClick(item: Record<string, any>, index: number) {\n emit('item-click', item, index)\n emit('update:current', props.currentKey ? o(item).get(props.currentKey) : index)\n}\n\n// 提示\nconst tipVisible = shallowRef(false)\nconst tipTriggerDom = shallowRef<HTMLElement>()\nconst tipContent = shallowRef()\n\nfunction handleStepMouseenter(event: MouseEvent, item: Record<string, any>, index: number) {\n if (!slots.tip) return\n tipTriggerDom.value = event.target as HTMLElement\n tipVisible.value = true\n tipContent.value = slots.tip?.({ item, index })\n}\n\nlet timer: number | undefined = undefined\nfunction closeTip() {\n timer = setTimeout(() => {\n tipVisible.value = false\n tipContent.value = undefined\n tipTriggerDom.value = undefined\n }, 250)\n}\n\nfunction handleTipUpdateVisible(visible: boolean) {\n visible && clearTimeout(timer)\n}\n\nfunction handleStepMouseleave() {\n if (!slots.tip) return\n closeTip()\n}\n</script>\n"],"mappings":"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"}
@@ -6,11 +6,11 @@ type __VLS_Slots = {
6
6
  tip?: (scope: StepsSlotScope) => any;
7
7
  };
8
8
  declare const __VLS_base: import("vue").DefineComponent<StepsProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
9
- "item-click": (item: Record<string, any>, index: number) => any;
10
9
  "update:current": (value?: string | number | undefined) => any;
10
+ "item-click": (item: Record<string, any>, index: number) => any;
11
11
  }, string, import("vue").PublicProps, Readonly<StepsProps> & Readonly<{
12
- "onItem-click"?: ((item: Record<string, any>, index: number) => any) | undefined;
13
12
  "onUpdate:current"?: ((value?: string | number | undefined) => any) | undefined;
13
+ "onItem-click"?: ((item: Record<string, any>, index: number) => any) | undefined;
14
14
  }>, {
15
15
  labelKey: string;
16
16
  direction: "horizontal" | "vertical";
@@ -20,10 +20,10 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {},
20
20
  onFocus?: (() => any) | undefined;
21
21
  onBlur?: (() => any) | undefined;
22
22
  }>, {
23
- disabled: boolean;
24
- readonly: boolean;
25
23
  placeholder: string;
26
24
  clearable: boolean;
25
+ disabled: boolean;
26
+ readonly: boolean;
27
27
  resize: boolean;
28
28
  autosize: boolean;
29
29
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
@@ -9,10 +9,10 @@ declare const __VLS_base: import("vue").DefineComponent<TipProps, {}, {}, {}, {}
9
9
  }, string, import("vue").PublicProps, Readonly<TipProps> & Readonly<{
10
10
  "onUpdate:visible"?: ((value: boolean) => any) | undefined;
11
11
  }>, {
12
- direction: TipDirection;
13
12
  trigger: "hover" | "click";
14
13
  contentTag: string;
15
14
  visible: boolean;
15
+ direction: TipDirection;
16
16
  content: string;
17
17
  alignment: TipAlign;
18
18
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
@@ -1,4 +1,5 @@
1
1
  import { nextTick, watch } from "vue";
2
+ import { fieldKey } from "@veltra/utils";
2
3
  import { dfs, o } from "@cat-kit/core";
3
4
  //#region src/components/tree/use-check.ts
4
5
  /**
@@ -99,7 +100,7 @@ function useCheck(options) {
99
100
  checkedByEvent = true;
100
101
  check ? handleCheck(node, ctrlKey) : handleUncheck(node, ctrlKey);
101
102
  const checkedArr = Array.from(checkedData);
102
- const valueKey = props.valueKey;
103
+ const valueKey = fieldKey(props.valueKey, "value");
103
104
  const nextValues = checkedArr.map((item) => o(item).get(valueKey));
104
105
  lastCheckedSet = new Set(nextValues);
105
106
  emit("update:checked", nextValues, checkedArr);
@@ -1 +1 @@
1
- {"version":3,"file":"use-check.js","names":[],"sources":["../../../src/components/tree/use-check.ts"],"sourcesContent":["import { dfs, o } from '@cat-kit/core'\nimport { nextTick, watch, type ComputedRef } from 'vue'\n\nimport type { TreeEmit, TreeProps } from '../../types'\nimport type { TreeNode } from './tree-node'\n\ninterface Options {\n emit: TreeEmit\n props: TreeProps\n nodeDict: ComputedRef<Map<any, TreeNode>>\n getFlattedNodes: () => void\n}\n\ninterface UseCheckReturned {\n checkedData: Set<Record<string, any>>\n toggleCheck: (node: TreeNode, check: boolean, ctrlKey?: boolean) => void\n}\n\n/**\n * 展开目标节点的所有祖先。返回是否发生了实际展开。\n */\nfunction expandAncestors(node: TreeNode): boolean {\n let changed = false\n node.bubbleSet((n) => {\n if (n.parent) {\n if (n.parent.expanded) return false\n n.parent.expanded = true\n changed = true\n }\n })\n return changed\n}\n\nexport function useCheck(options: Options): UseCheckReturned {\n const { emit, props, nodeDict, getFlattedNodes } = options\n\n const checkedData = new Set<Record<string, any>>()\n\n /**\n * 上一次回显使用的 value 集合(仅限 props.checked)。\n * 用于在相同 `nodeDict` 下走差集回显,避免每次全量清空再重建。\n */\n let lastCheckedSet = new Set<unknown>()\n /** 最近一次参与差集比较的 nodeDict 引用;引用变化时视为整棵树重建。 */\n let lastDict: Map<any, TreeNode> | null = null\n\n function checkNode(node: TreeNode): void {\n if (node.checked) return\n node.checked = true\n if (node.parent) {\n node.parent.childrenCheckCount++\n }\n checkedData.add(node.data)\n }\n\n function uncheckNode(node: TreeNode): void {\n if (!node.checked) return\n node.checked = false\n if (node.parent) {\n node.parent.childrenCheckCount--\n }\n checkedData.delete(node.data)\n }\n\n /**\n * 模型值是否由事件触发\n */\n let checkedByEvent = false\n\n // 回显\n watch(\n [() => props.checked, nodeDict],\n ([c, dict]) => {\n // 事件已经触发模型变更了,所以不再进行下面的计算\n if (checkedByEvent || !props.checkable) return\n if (!dict.size) return\n\n const nextSet = new Set<unknown>(c ?? [])\n\n // 森林重建(dict 引用变化)→ 走全量清空重建路径,\n // 因为所有 TreeNode 实例都是新的,上一轮缓存的 lastCheckedSet 失效。\n const dictChanged = dict !== lastDict\n if (dictChanged) {\n checkedData.clear()\n lastCheckedSet = new Set()\n }\n\n let mutated = false\n\n // 取消:上一轮有但本轮没有的 value\n for (const v of lastCheckedSet) {\n if (!nextSet.has(v)) {\n const node = dict.get(v)\n if (node) {\n uncheckNode(node)\n mutated = true\n }\n }\n }\n\n // 新增:本轮有但上一轮没有的 value\n let ancestorsExpanded = false\n for (const v of nextSet) {\n if (!lastCheckedSet.has(v) || dictChanged) {\n const node = dict.get(v)\n if (node) {\n checkNode(node)\n mutated = true\n if (expandAncestors(node)) {\n ancestorsExpanded = true\n }\n }\n }\n }\n\n lastCheckedSet = nextSet\n lastDict = dict\n\n // 只在真实发生变化时才触发扁平化,避免空转。\n if (mutated || ancestorsExpanded) {\n getFlattedNodes()\n }\n },\n { immediate: true }\n )\n\n function handleCheck(node: TreeNode, ctrlKey?: boolean) {\n const { checkStrictly } = props\n\n if (ctrlKey) {\n checkNode(node)\n } else {\n dfs(\n node as unknown as Record<string, unknown>,\n (n) => {\n const tn = n as unknown as TreeNode\n !tn.disabled && checkNode(tn)\n },\n props.childrenKey ?? 'children'\n )\n }\n\n // 非严格选择时还需要更新祖先节点,\n // 一旦子节点全部选中,父节点也要设置为选中状态\n if (!checkStrictly) {\n node.bubbleSet((node) => {\n const { parent } = node\n\n if (parent) {\n const parentChecked = parent.childrenCheckCount === parent.children!.length\n\n parentChecked ? checkNode(parent) : uncheckNode(parent)\n }\n })\n }\n }\n\n function handleUncheck(node: TreeNode, ctrlKey?: boolean) {\n const { checkStrictly } = props\n if (ctrlKey) {\n uncheckNode(node)\n } else {\n dfs(\n node as unknown as Record<string, unknown>,\n (n) => {\n const tn = n as unknown as TreeNode\n !tn.disabled && uncheckNode(tn)\n },\n props.childrenKey ?? 'children'\n )\n }\n\n // 非严格模式下,取消选中时,需要更新父节点\n if (!checkStrictly) {\n node.bubbleSet((node) => {\n const { parent } = node\n if (parent) {\n uncheckNode(parent)\n }\n })\n }\n }\n\n function toggleCheck(node: TreeNode, check: boolean, ctrlKey?: boolean) {\n checkedByEvent = true\n\n check ? handleCheck(node, ctrlKey) : handleUncheck(node, ctrlKey)\n\n const checkedArr = Array.from(checkedData)\n\n const valueKey = props.valueKey!\n const nextValues = checkedArr.map((item) => o(item).get(valueKey) as unknown)\n\n // 与外部 checked 保持差集缓存同步,避免下一次 watch 回调把刚勾选的值又误判为“新增”。\n lastCheckedSet = new Set(nextValues)\n\n emit('update:checked', nextValues as any[], checkedArr)\n\n nextTick(() => {\n checkedByEvent = false\n })\n }\n\n return { checkedData, toggleCheck }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"use-check.js","names":[],"sources":["../../../src/components/tree/use-check.ts"],"sourcesContent":["import { dfs, o } from '@cat-kit/core'\nimport { fieldKey } from '@veltra/utils'\nimport { nextTick, watch, type ComputedRef } from 'vue'\n\nimport type { TreeEmit, TreeProps } from '../../types'\nimport type { TreeNode } from './tree-node'\n\ninterface Options {\n emit: TreeEmit\n props: TreeProps\n nodeDict: ComputedRef<Map<any, TreeNode>>\n getFlattedNodes: () => void\n}\n\ninterface UseCheckReturned {\n checkedData: Set<Record<string, any>>\n toggleCheck: (node: TreeNode, check: boolean, ctrlKey?: boolean) => void\n}\n\n/**\n * 展开目标节点的所有祖先。返回是否发生了实际展开。\n */\nfunction expandAncestors(node: TreeNode): boolean {\n let changed = false\n node.bubbleSet((n) => {\n if (n.parent) {\n if (n.parent.expanded) return false\n n.parent.expanded = true\n changed = true\n }\n })\n return changed\n}\n\nexport function useCheck(options: Options): UseCheckReturned {\n const { emit, props, nodeDict, getFlattedNodes } = options\n\n const checkedData = new Set<Record<string, any>>()\n\n /**\n * 上一次回显使用的 value 集合(仅限 props.checked)。\n * 用于在相同 `nodeDict` 下走差集回显,避免每次全量清空再重建。\n */\n let lastCheckedSet = new Set<unknown>()\n /** 最近一次参与差集比较的 nodeDict 引用;引用变化时视为整棵树重建。 */\n let lastDict: Map<any, TreeNode> | null = null\n\n function checkNode(node: TreeNode): void {\n if (node.checked) return\n node.checked = true\n if (node.parent) {\n node.parent.childrenCheckCount++\n }\n checkedData.add(node.data)\n }\n\n function uncheckNode(node: TreeNode): void {\n if (!node.checked) return\n node.checked = false\n if (node.parent) {\n node.parent.childrenCheckCount--\n }\n checkedData.delete(node.data)\n }\n\n /**\n * 模型值是否由事件触发\n */\n let checkedByEvent = false\n\n // 回显\n watch(\n [() => props.checked, nodeDict],\n ([c, dict]) => {\n // 事件已经触发模型变更了,所以不再进行下面的计算\n if (checkedByEvent || !props.checkable) return\n if (!dict.size) return\n\n const nextSet = new Set<unknown>(c ?? [])\n\n // 森林重建(dict 引用变化)→ 走全量清空重建路径,\n // 因为所有 TreeNode 实例都是新的,上一轮缓存的 lastCheckedSet 失效。\n const dictChanged = dict !== lastDict\n if (dictChanged) {\n checkedData.clear()\n lastCheckedSet = new Set()\n }\n\n let mutated = false\n\n // 取消:上一轮有但本轮没有的 value\n for (const v of lastCheckedSet) {\n if (!nextSet.has(v)) {\n const node = dict.get(v)\n if (node) {\n uncheckNode(node)\n mutated = true\n }\n }\n }\n\n // 新增:本轮有但上一轮没有的 value\n let ancestorsExpanded = false\n for (const v of nextSet) {\n if (!lastCheckedSet.has(v) || dictChanged) {\n const node = dict.get(v)\n if (node) {\n checkNode(node)\n mutated = true\n if (expandAncestors(node)) {\n ancestorsExpanded = true\n }\n }\n }\n }\n\n lastCheckedSet = nextSet\n lastDict = dict\n\n // 只在真实发生变化时才触发扁平化,避免空转。\n if (mutated || ancestorsExpanded) {\n getFlattedNodes()\n }\n },\n { immediate: true }\n )\n\n function handleCheck(node: TreeNode, ctrlKey?: boolean) {\n const { checkStrictly } = props\n\n if (ctrlKey) {\n checkNode(node)\n } else {\n dfs(\n node as unknown as Record<string, unknown>,\n (n) => {\n const tn = n as unknown as TreeNode\n !tn.disabled && checkNode(tn)\n },\n props.childrenKey ?? 'children'\n )\n }\n\n // 非严格选择时还需要更新祖先节点,\n // 一旦子节点全部选中,父节点也要设置为选中状态\n if (!checkStrictly) {\n node.bubbleSet((node) => {\n const { parent } = node\n\n if (parent) {\n const parentChecked = parent.childrenCheckCount === parent.children!.length\n\n parentChecked ? checkNode(parent) : uncheckNode(parent)\n }\n })\n }\n }\n\n function handleUncheck(node: TreeNode, ctrlKey?: boolean) {\n const { checkStrictly } = props\n if (ctrlKey) {\n uncheckNode(node)\n } else {\n dfs(\n node as unknown as Record<string, unknown>,\n (n) => {\n const tn = n as unknown as TreeNode\n !tn.disabled && uncheckNode(tn)\n },\n props.childrenKey ?? 'children'\n )\n }\n\n // 非严格模式下,取消选中时,需要更新父节点\n if (!checkStrictly) {\n node.bubbleSet((node) => {\n const { parent } = node\n if (parent) {\n uncheckNode(parent)\n }\n })\n }\n }\n\n function toggleCheck(node: TreeNode, check: boolean, ctrlKey?: boolean) {\n checkedByEvent = true\n\n check ? handleCheck(node, ctrlKey) : handleUncheck(node, ctrlKey)\n\n const checkedArr = Array.from(checkedData)\n\n const valueKey = fieldKey(props.valueKey, 'value')\n const nextValues = checkedArr.map((item) => o(item).get(valueKey) as unknown)\n\n // 与外部 checked 保持差集缓存同步,避免下一次 watch 回调把刚勾选的值又误判为“新增”。\n lastCheckedSet = new Set(nextValues)\n\n emit('update:checked', nextValues as any[], checkedArr)\n\n nextTick(() => {\n checkedByEvent = false\n })\n }\n\n return { checkedData, toggleCheck }\n}\n"],"mappings":"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"}
@@ -1,4 +1,5 @@
1
1
  import { nextTick, shallowRef, watch } from "vue";
2
+ import { fieldKey } from "@veltra/utils";
2
3
  //#region src/components/tree/use-select.ts
3
4
  /**
4
5
  * 单选
@@ -28,7 +29,8 @@ function useSelect(options) {
28
29
  selectByEvent = true;
29
30
  if (node.disabled) return;
30
31
  selectedData.value = node.data === selectedData.value ? void 0 : node.data;
31
- emit("update:selected", selectedData.value?.[props.valueKey], selectedData.value, node);
32
+ const valueKey = fieldKey(props.valueKey, "value");
33
+ emit("update:selected", selectedData.value?.[valueKey], selectedData.value, node);
32
34
  nextTick(() => {
33
35
  selectByEvent = false;
34
36
  });
@@ -1 +1 @@
1
- {"version":3,"file":"use-select.js","names":[],"sources":["../../../src/components/tree/use-select.ts"],"sourcesContent":["import { nextTick, shallowRef, watch, type ComputedRef, type ShallowRef } from 'vue'\n\nimport type { TreeEmit, TreeProps } from '../../types'\nimport type { TreeNode } from './tree-node'\n\ninterface Options {\n emit: TreeEmit\n props: TreeProps\n nodeDict: ComputedRef<Map<any, TreeNode>>\n getFlattedNodes: () => void\n}\n\ninterface UseSelectReturned {\n selectedData: ShallowRef<Record<string, any> | undefined>\n handleSelect: (node: TreeNode) => void\n}\n\n/**\n * 单选\n */\nexport function useSelect(options: Options): UseSelectReturned {\n const { emit, props, nodeDict, getFlattedNodes } = options\n let selectedData = shallowRef<Record<string, any>>()\n\n let selectByEvent = false\n watch(\n [() => props.selected, nodeDict],\n ([s, nodeDict]) => {\n if (selectByEvent || !props.selectable) return\n\n if (s) {\n const node = nodeDict.get(s)\n if (node) {\n selectedData.value = node.data\n node.bubbleSet((node) => {\n if (node.parent) {\n if (node.parent.expanded) return false\n node.parent.expanded = true\n }\n })\n }\n } else {\n selectedData.value = undefined\n }\n\n getFlattedNodes()\n\n emit('selected-synced', selectedData.value)\n },\n { immediate: true }\n )\n\n const handleSelect = (node: TreeNode) => {\n selectByEvent = true\n if (node.disabled) return\n selectedData.value = node.data === selectedData.value ? undefined : node.data\n\n emit('update:selected', selectedData.value?.[props.valueKey!], selectedData.value, node)\n\n nextTick(() => {\n selectByEvent = false\n })\n }\n\n return { selectedData, handleSelect }\n}\n"],"mappings":";;;;;AAoBA,SAAgB,UAAU,SAAqC;CAC7D,MAAM,EAAE,MAAM,OAAO,UAAU,oBAAoB;CACnD,IAAI,eAAe,WAAgC;CAEnD,IAAI,gBAAgB;CACpB,MACE,OAAO,MAAM,UAAU,QAAQ,IAC9B,CAAC,GAAG,cAAc;EACjB,IAAI,iBAAiB,CAAC,MAAM,YAAY;EAExC,IAAI,GAAG;GACL,MAAM,OAAO,SAAS,IAAI,CAAC;GAC3B,IAAI,MAAM;IACR,aAAa,QAAQ,KAAK;IAC1B,KAAK,WAAW,SAAS;KACvB,IAAI,KAAK,QAAQ;MACf,IAAI,KAAK,OAAO,UAAU,OAAO;MACjC,KAAK,OAAO,WAAW;KACzB;IACF,CAAC;GACH;EACF,OACE,aAAa,QAAQ,KAAA;EAGvB,gBAAgB;EAEhB,KAAK,mBAAmB,aAAa,KAAK;CAC5C,GACA,EAAE,WAAW,KAAK,CACpB;CAEA,MAAM,gBAAgB,SAAmB;EACvC,gBAAgB;EAChB,IAAI,KAAK,UAAU;EACnB,aAAa,QAAQ,KAAK,SAAS,aAAa,QAAQ,KAAA,IAAY,KAAK;EAEzE,KAAK,mBAAmB,aAAa,QAAQ,MAAM,WAAY,aAAa,OAAO,IAAI;EAEvF,eAAe;GACb,gBAAgB;EAClB,CAAC;CACH;CAEA,OAAO;EAAE;EAAc;CAAa;AACtC"}
1
+ {"version":3,"file":"use-select.js","names":[],"sources":["../../../src/components/tree/use-select.ts"],"sourcesContent":["import { fieldKey } from '@veltra/utils'\nimport { nextTick, shallowRef, watch, type ComputedRef, type ShallowRef } from 'vue'\n\nimport type { TreeEmit, TreeProps } from '../../types'\nimport type { TreeNode } from './tree-node'\n\ninterface Options {\n emit: TreeEmit\n props: TreeProps\n nodeDict: ComputedRef<Map<any, TreeNode>>\n getFlattedNodes: () => void\n}\n\ninterface UseSelectReturned {\n selectedData: ShallowRef<Record<string, any> | undefined>\n handleSelect: (node: TreeNode) => void\n}\n\n/**\n * 单选\n */\nexport function useSelect(options: Options): UseSelectReturned {\n const { emit, props, nodeDict, getFlattedNodes } = options\n let selectedData = shallowRef<Record<string, any>>()\n\n let selectByEvent = false\n watch(\n [() => props.selected, nodeDict],\n ([s, nodeDict]) => {\n if (selectByEvent || !props.selectable) return\n\n if (s) {\n const node = nodeDict.get(s)\n if (node) {\n selectedData.value = node.data\n node.bubbleSet((node) => {\n if (node.parent) {\n if (node.parent.expanded) return false\n node.parent.expanded = true\n }\n })\n }\n } else {\n selectedData.value = undefined\n }\n\n getFlattedNodes()\n\n emit('selected-synced', selectedData.value)\n },\n { immediate: true }\n )\n\n const handleSelect = (node: TreeNode) => {\n selectByEvent = true\n if (node.disabled) return\n selectedData.value = node.data === selectedData.value ? undefined : node.data\n\n const valueKey = fieldKey(props.valueKey, 'value')\n emit('update:selected', selectedData.value?.[valueKey], selectedData.value, node)\n\n nextTick(() => {\n selectByEvent = false\n })\n }\n\n return { selectedData, handleSelect }\n}\n"],"mappings":";;;;;;AAqBA,SAAgB,UAAU,SAAqC;CAC7D,MAAM,EAAE,MAAM,OAAO,UAAU,oBAAoB;CACnD,IAAI,eAAe,WAAgC;CAEnD,IAAI,gBAAgB;CACpB,MACE,OAAO,MAAM,UAAU,QAAQ,IAC9B,CAAC,GAAG,cAAc;EACjB,IAAI,iBAAiB,CAAC,MAAM,YAAY;EAExC,IAAI,GAAG;GACL,MAAM,OAAO,SAAS,IAAI,CAAC;GAC3B,IAAI,MAAM;IACR,aAAa,QAAQ,KAAK;IAC1B,KAAK,WAAW,SAAS;KACvB,IAAI,KAAK,QAAQ;MACf,IAAI,KAAK,OAAO,UAAU,OAAO;MACjC,KAAK,OAAO,WAAW;KACzB;IACF,CAAC;GACH;EACF,OACE,aAAa,QAAQ,KAAA;EAGvB,gBAAgB;EAEhB,KAAK,mBAAmB,aAAa,KAAK;CAC5C,GACA,EAAE,WAAW,KAAK,CACpB;CAEA,MAAM,gBAAgB,SAAmB;EACvC,gBAAgB;EAChB,IAAI,KAAK,UAAU;EACnB,aAAa,QAAQ,KAAK,SAAS,aAAa,QAAQ,KAAA,IAAY,KAAK;EAEzE,MAAM,WAAW,SAAS,MAAM,UAAU,OAAO;EACjD,KAAK,mBAAmB,aAAa,QAAQ,WAAW,aAAa,OAAO,IAAI;EAEhF,eAAe;GACb,gBAAgB;EAClB,CAAC;CACH;CAEA,OAAO;EAAE;EAAc;CAAa;AACtC"}
@@ -1,5 +1,6 @@
1
1
  import { TreeNode as TreeNode$1 } from "./tree-node2.js";
2
2
  import { computed, shallowRef, triggerRef, watch } from "vue";
3
+ import { fieldKey } from "@veltra/utils";
3
4
  import { Forest } from "@cat-kit/core";
4
5
  //#region src/components/tree/use-tree-nodes.ts
5
6
  function useTreeNodes(options) {
@@ -11,8 +12,10 @@ function useTreeNodes(options) {
11
12
  const nodeDictRef = shallowRef(/* @__PURE__ */ new Map());
12
13
  const nodes = shallowRef([]);
13
14
  function buildForest() {
14
- const { disabledNode, expandAll = false, valueKey, labelKey } = props;
15
+ const { disabledNode, expandAll = false } = props;
15
16
  const childrenKey = props.childrenKey ?? "children";
17
+ const valueKey = fieldKey(props.valueKey, "value");
18
+ const labelKey = fieldKey(props.labelKey, "label");
16
19
  function createNode(data, index, depth, parent) {
17
20
  const node = new TreeNode$1({
18
21
  data,