@veltra/desktop 1.0.8 → 1.0.10

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 (220) hide show
  1. package/dist/components/action/action-group.vue.d.ts +2 -2
  2. package/dist/components/action/action.vue.d.ts +3 -3
  3. package/dist/components/auto-complete/auto-complete.vue.d.ts +1 -1
  4. package/dist/components/batch-edit/batch-edit.js.map +1 -1
  5. package/dist/components/batch-edit/batch-edit.vue.d.ts +2 -2
  6. package/dist/components/batch-edit/use-edit.js.map +1 -1
  7. package/dist/components/button/button.js.map +1 -1
  8. package/dist/components/button/button.vue.d.ts +1 -1
  9. package/dist/components/cascade/cascade.js +15 -13
  10. package/dist/components/cascade/cascade.js.map +1 -1
  11. package/dist/components/cascade/cascade.vue.d.ts +7 -7
  12. package/dist/components/cascade/node.js.map +1 -1
  13. package/dist/components/cascade/use-check.js +3 -2
  14. package/dist/components/cascade/use-check.js.map +1 -1
  15. package/dist/components/cascade/use-select.js +3 -3
  16. package/dist/components/cascade/use-select.js.map +1 -1
  17. package/dist/components/checkbox-group/checkbox-group.js.map +1 -1
  18. package/dist/components/checkbox-group/checkbox-group.vue.d.ts +2 -2
  19. package/dist/components/date-panel/date-panel.js.map +1 -1
  20. package/dist/components/date-panel/date-panel.vue.d.ts +1 -1
  21. package/dist/components/date-picker/date-picker.js +9 -9
  22. package/dist/components/date-picker/date-picker.js.map +1 -1
  23. package/dist/components/date-picker/date-picker.vue.d.ts +1 -1
  24. package/dist/components/date-range-picker/date-range-picker.js +9 -9
  25. package/dist/components/date-range-picker/date-range-picker.js.map +1 -1
  26. package/dist/components/date-range-picker/date-range-picker.vue.d.ts +1 -1
  27. package/dist/components/drawer/drawer.js.map +1 -1
  28. package/dist/components/empty/empty.vue.d.ts +1 -1
  29. package/dist/components/expression-editor/expression-editor.js.map +1 -1
  30. package/dist/components/expression-editor/internal/editor-runtime/create-runtime.js.map +1 -1
  31. package/dist/components/expression-editor/internal/features/commands/register-command-packs.js.map +1 -1
  32. package/dist/components/expression-editor/internal/features/insertion/insertion-service.js.map +1 -1
  33. package/dist/components/expression-editor/use-decorators.js.map +1 -1
  34. package/dist/components/expression-editor/use-expression-drag-drop.js.map +1 -1
  35. package/dist/components/file-picker/file-picker.js.map +1 -1
  36. package/dist/components/file-picker/file-picker.vue.d.ts +1 -1
  37. package/dist/components/file-picker/helper.js +19 -7
  38. package/dist/components/file-picker/helper.js.map +1 -1
  39. package/dist/components/file-viewer/file-viewer.js +294 -0
  40. package/dist/components/file-viewer/file-viewer.js.map +1 -0
  41. package/dist/components/file-viewer/file-viewer.vue.d.ts +42 -0
  42. package/dist/components/file-viewer/helper.js +185 -0
  43. package/dist/components/file-viewer/helper.js.map +1 -0
  44. package/dist/components/file-viewer/index.d.ts +1 -0
  45. package/dist/components/file-viewer/previewers/docx-previewer.js +76 -0
  46. package/dist/components/file-viewer/previewers/docx-previewer.js.map +1 -0
  47. package/dist/components/file-viewer/previewers/image-previewer.js +64 -0
  48. package/dist/components/file-viewer/previewers/image-previewer.js.map +1 -0
  49. package/dist/components/file-viewer/previewers/pdf-previewer.js +90 -0
  50. package/dist/components/file-viewer/previewers/pdf-previewer.js.map +1 -0
  51. package/dist/components/file-viewer/previewers/sheet-previewer.js +175 -0
  52. package/dist/components/file-viewer/previewers/sheet-previewer.js.map +1 -0
  53. package/dist/components/file-viewer/previewers/text-previewer.js +74 -0
  54. package/dist/components/file-viewer/previewers/text-previewer.js.map +1 -0
  55. package/dist/components/file-viewer/previewers/video-previewer.js +62 -0
  56. package/dist/components/file-viewer/previewers/video-previewer.js.map +1 -0
  57. package/dist/components/file-viewer/style.d.ts +1 -0
  58. package/dist/components/file-viewer/style.js +4 -0
  59. package/dist/components/file-viewer/style2.css +445 -0
  60. package/dist/components/form/form-model.js +2 -1
  61. package/dist/components/form/form-model.js.map +1 -1
  62. package/dist/components/grid/grid.js.map +1 -1
  63. package/dist/components/grid/use-responsive.js.map +1 -1
  64. package/dist/components/grid-input/grid-input.vue.d.ts +1 -1
  65. package/dist/components/index.d.ts +12 -9
  66. package/dist/components/input/input.vue.d.ts +3 -3
  67. package/dist/components/list/list.js.map +1 -1
  68. package/dist/components/loading/directive.js.map +1 -1
  69. package/dist/components/menu/menu-item.js.map +1 -1
  70. package/dist/components/message/message2.js.map +1 -1
  71. package/dist/components/multi-select/multi-select-option.js +14 -10
  72. package/dist/components/multi-select/multi-select-option.js.map +1 -1
  73. package/dist/components/multi-select/multi-select.js +16 -19
  74. package/dist/components/multi-select/multi-select.js.map +1 -1
  75. package/dist/components/multi-select/multi-select.vue.d.ts +4 -4
  76. package/dist/components/multi-tree-select/multi-tree-select.vue.d.ts +7 -7
  77. package/dist/components/notification/index.js.map +1 -1
  78. package/dist/components/notification/notification.vue.d.ts +1 -1
  79. package/dist/components/number-input/number-input.js.map +1 -1
  80. package/dist/components/number-input/number-input.vue.d.ts +1 -1
  81. package/dist/components/number-range-input/number-range-input.vue.d.ts +1 -1
  82. package/dist/components/palette/color-transform.js.map +1 -1
  83. package/dist/components/palette/di.js.map +1 -1
  84. package/dist/components/palette/palette-alpha.js +7 -10
  85. package/dist/components/palette/palette-alpha.js.map +1 -1
  86. package/dist/components/palette/palette-hue.js +5 -7
  87. package/dist/components/palette/palette-hue.js.map +1 -1
  88. package/dist/components/palette/palette-sv.js +8 -10
  89. package/dist/components/palette/palette-sv.js.map +1 -1
  90. package/dist/components/palette/palette.js +22 -24
  91. package/dist/components/palette/palette.js.map +1 -1
  92. package/dist/components/password-input/password-input.vue.d.ts +1 -1
  93. package/dist/components/pop-confirm/pop-confirm.vue.d.ts +2 -2
  94. package/dist/components/progress/progress.js +1 -1
  95. package/dist/components/progress/progress.js.map +1 -1
  96. package/dist/components/progress-nodes/progress-nodes.js.map +1 -1
  97. package/dist/components/radio-group/radio-group.vue.d.ts +2 -2
  98. package/dist/components/rich-text-editor/rich-text-editor.js.map +1 -1
  99. package/dist/components/rich-text-editor/rich-text-editor.vue.d.ts +1 -1
  100. package/dist/components/rich-text-editor/toolbar.js.map +1 -1
  101. package/dist/components/scroll/scroll.js.map +1 -1
  102. package/dist/components/select/select.js +14 -12
  103. package/dist/components/select/select.js.map +1 -1
  104. package/dist/components/select/select.vue.d.ts +3 -3
  105. package/dist/components/slider/slider-thumb.js +10 -13
  106. package/dist/components/slider/slider-thumb.js.map +1 -1
  107. package/dist/components/slider/slider.js +12 -15
  108. package/dist/components/slider/slider.js.map +1 -1
  109. package/dist/components/table/di.js.map +1 -1
  110. package/dist/components/table/node/row.d.ts +10 -1
  111. package/dist/components/table/node/row.js +9 -0
  112. package/dist/components/table/node/row.js.map +1 -1
  113. package/dist/components/table/table-body.js +25 -26
  114. package/dist/components/table/table-body.js.map +1 -1
  115. package/dist/components/table/table-cell.js +16 -9
  116. package/dist/components/table/table-cell.js.map +1 -1
  117. package/dist/components/table/table-row.js +77 -19
  118. package/dist/components/table/table-row.js.map +1 -1
  119. package/dist/components/table/table.js +75 -34
  120. package/dist/components/table/table.js.map +1 -1
  121. package/dist/components/table/table.vue.d.ts +2 -2
  122. package/dist/components/table/use-columns.js +4 -0
  123. package/dist/components/table/use-columns.js.map +1 -1
  124. package/dist/components/table/use-fixed-columns.js +27 -8
  125. package/dist/components/table/use-fixed-columns.js.map +1 -1
  126. package/dist/components/table/use-rows.js +2 -2
  127. package/dist/components/table/use-rows.js.map +1 -1
  128. package/dist/components/table/use-table.js +50 -3
  129. package/dist/components/table/use-table.js.map +1 -1
  130. package/dist/components/tabs/index.d.ts +3 -1
  131. package/dist/components/tabs/style2.css +170 -107
  132. package/dist/components/tabs/tabs-horizontal.js +133 -0
  133. package/dist/components/tabs/tabs-horizontal.js.map +1 -0
  134. package/dist/components/tabs/tabs-horizontal.vue.d.ts +40 -0
  135. package/dist/components/tabs/tabs-vertical.js +89 -0
  136. package/dist/components/tabs/tabs-vertical.js.map +1 -0
  137. package/dist/components/tabs/tabs-vertical.vue.d.ts +38 -0
  138. package/dist/components/tabs/tabs.js +75 -105
  139. package/dist/components/tabs/tabs.js.map +1 -1
  140. package/dist/components/tabs/tabs.vue.d.ts +9 -23
  141. package/dist/components/tabs/use-tabs-bar.js +105 -0
  142. package/dist/components/tabs/use-tabs-bar.js.map +1 -0
  143. package/dist/components/text/text.js.map +1 -1
  144. package/dist/components/textarea/textarea.js.map +1 -1
  145. package/dist/components/textarea/textarea.vue.d.ts +4 -4
  146. package/dist/components/theme/theme.js.map +1 -1
  147. package/dist/components/tip/tip.vue.d.ts +1 -1
  148. package/dist/components/tree/style2.css +45 -23
  149. package/dist/components/tree/tree-node.js +50 -35
  150. package/dist/components/tree/tree-node.js.map +1 -1
  151. package/dist/components/tree/tree-node2.js.map +1 -1
  152. package/dist/components/tree/tree.js +27 -20
  153. package/dist/components/tree/tree.js.map +1 -1
  154. package/dist/components/tree/tree.vue.d.ts +5 -5
  155. package/dist/components/tree/use-check.js +52 -14
  156. package/dist/components/tree/use-check.js.map +1 -1
  157. package/dist/components/tree/use-tree-nodes.js +51 -24
  158. package/dist/components/tree/use-tree-nodes.js.map +1 -1
  159. package/dist/components/tree-select/tree-select.vue.d.ts +7 -7
  160. package/dist/index.d.ts +57 -53
  161. package/dist/index.js +51 -48
  162. package/dist/types/file-viewer.d.ts +71 -0
  163. package/dist/types/index.d.ts +3 -2
  164. package/dist/types/tabs.d.ts +106 -14
  165. package/dist/types/tree.d.ts +6 -1
  166. package/package.json +32 -31
  167. package/src/components/cascade/cascade.vue +18 -18
  168. package/src/components/cascade/node.ts +4 -1
  169. package/src/components/cascade/use-check.ts +5 -4
  170. package/src/components/cascade/use-select.ts +4 -5
  171. package/src/components/date-picker/date-picker.vue +10 -9
  172. package/src/components/date-range-picker/date-range-picker.vue +12 -12
  173. package/src/components/file-picker/helper.ts +21 -10
  174. package/src/components/file-viewer/file-viewer.vue +311 -0
  175. package/src/components/file-viewer/helper.ts +193 -0
  176. package/src/components/file-viewer/index.ts +1 -0
  177. package/src/components/file-viewer/previewers/docx-previewer.vue +78 -0
  178. package/src/components/file-viewer/previewers/image-previewer.vue +64 -0
  179. package/src/components/file-viewer/previewers/pdf-previewer.vue +90 -0
  180. package/src/components/file-viewer/previewers/sheet-previewer.vue +210 -0
  181. package/src/components/file-viewer/previewers/text-previewer.vue +76 -0
  182. package/src/components/file-viewer/previewers/video-previewer.vue +72 -0
  183. package/src/components/file-viewer/style.scss +504 -0
  184. package/src/components/file-viewer/style.ts +4 -0
  185. package/src/components/index.ts +2 -0
  186. package/src/components/multi-select/multi-select-option.vue +16 -3
  187. package/src/components/multi-select/multi-select.vue +17 -9
  188. package/src/components/palette/di.ts +5 -3
  189. package/src/components/palette/palette-alpha.vue +7 -10
  190. package/src/components/palette/palette-hue.vue +5 -7
  191. package/src/components/palette/palette-sv.vue +12 -14
  192. package/src/components/palette/palette.vue +19 -21
  193. package/src/components/progress/progress.vue +1 -1
  194. package/src/components/select/select.vue +21 -19
  195. package/src/components/slider/slider-thumb.vue +11 -14
  196. package/src/components/slider/slider.vue +15 -15
  197. package/src/components/table/di.ts +58 -43
  198. package/src/components/table/node/row.ts +10 -1
  199. package/src/components/table/table-body.vue +28 -33
  200. package/src/components/table/table-cell.vue +17 -9
  201. package/src/components/table/table-row.tsx +83 -17
  202. package/src/components/table/table.vue +72 -45
  203. package/src/components/table/use-fixed-columns.ts +46 -12
  204. package/src/components/table/use-rows.ts +14 -3
  205. package/src/components/table/use-table.ts +27 -3
  206. package/src/components/tabs/index.ts +2 -0
  207. package/src/components/tabs/style.scss +219 -133
  208. package/src/components/tabs/tabs-horizontal.vue +128 -0
  209. package/src/components/tabs/tabs-vertical.vue +77 -0
  210. package/src/components/tabs/tabs.vue +56 -127
  211. package/src/components/tabs/use-tabs-bar.ts +119 -0
  212. package/src/components/tree/style.scss +74 -29
  213. package/src/components/tree/tree-node.vue +10 -4
  214. package/src/components/tree/tree.vue +39 -12
  215. package/src/components/tree/use-check.ts +79 -23
  216. package/src/components/tree/use-tree-nodes.ts +85 -34
  217. package/src/types/file-viewer.ts +69 -0
  218. package/src/types/index.ts +1 -0
  219. package/src/types/tabs.ts +113 -19
  220. package/src/types/tree.ts +6 -1
@@ -8,7 +8,7 @@ import { useKeyboard } from "./use-keyboard.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 { o } from "@cat-kit/core";
10
10
  import { FORM_EMPTY_CONTENT, bem, scrollIntoContainerView, withUnit } from "@veltra/utils";
11
- import { useFormComponent, useFormFallbackProps, useVirtual } from "@veltra/compositions";
11
+ import { useFormComponent, useFormFallbackProps, useVirtualizer } from "@veltra/compositions";
12
12
  import { vFocus } from "@veltra/directives";
13
13
  import { ArrowDown, Search } from "@veltra/icons/normal";
14
14
  //#region src/components/select/select.vue
@@ -102,31 +102,34 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
102
102
  selected.value = void 0;
103
103
  }
104
104
  }, { immediate: true });
105
- const { virtualList, totalHeight, virtualEnabled: _virtualEnabled, scrollTo, measureElement } = useVirtual({
105
+ const baseVirtualEnabled = computed(() => options.value.length > 80);
106
+ const virtualEnabled = computed(() => baseVirtualEnabled.value && !props.grid);
107
+ const { virtualizer, items } = useVirtualizer({
106
108
  count: computed(() => options.value.length),
107
- virtualThreshold: 80,
108
- scrollEl: computed(() => scrollRef.value?.containerRef ?? null),
109
+ scrollEl: () => scrollRef.value?.containerRef ?? null,
110
+ contentEl: () => virtualEnabled.value ? scrollRef.value?.contentRef ?? null : null,
109
111
  gap: 4,
110
112
  estimateSize: () => 40
111
113
  });
112
- const virtualEnabled = computed(() => {
113
- return _virtualEnabled.value && !props.grid;
114
- });
115
114
  const virtualOptions = computed(() => {
116
115
  const _options = options.value;
117
116
  const { labelKey, valueKey } = props;
118
- return virtualList.value.map((item) => {
117
+ return items.value.map((item) => {
119
118
  const option = _options[item.index];
120
119
  return {
121
120
  option,
122
121
  index: item.index,
123
122
  label: o(option).get(labelKey),
124
123
  val: o(option).get(valueKey),
125
- key: item.key,
124
+ key: item.index,
126
125
  offset: item.start
127
126
  };
128
127
  });
129
128
  });
129
+ const measureElement = (index, el) => virtualizer.measureElement(index, el);
130
+ function scrollTo(index) {
131
+ virtualizer.scrollToIndex(index, { align: "center" });
132
+ }
130
133
  watch([scrollRef, virtualEnabled], ([scroll, virtualEnabled]) => {
131
134
  if (!scroll || !props.modelValue) return;
132
135
  if (virtualEnabled) {
@@ -238,7 +241,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
238
241
  })]),
239
242
  _: 1
240
243
  }, 8, ["modelValue"])), [[unref(vFocus)]])], 2)) : createCommentVNode("v-if", true),
241
- createCommentVNode(" 单选列表 "),
244
+ createCommentVNode("\n 单选列表。虚拟化启用时,内容容器 height 由 useVirtualizer 命令式写入;\n 此处 content-style 仅承担 grid 相关样式,避免 height 变化触发模板重渲染。\n "),
242
245
  unref(options).length ? (openBlock(), createBlock(unref(_sfc_main$3), {
243
246
  key: 1,
244
247
  tag: "ul",
@@ -251,7 +254,6 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
251
254
  unref(bem).is("grid", !!__props.grid)
252
255
  ],
253
256
  "content-style": {
254
- height: virtualEnabled.value ? unref(withUnit)(unref(totalHeight), "px") : void 0,
255
257
  gridTemplateColumns: __props.grid ? `repeat(${__props.grid.cols}, minmax(0px, 1fr))` : void 0,
256
258
  gridGap: __props.grid ? unref(withUnit)(__props.grid.gap, "px") : void 0
257
259
  }
@@ -264,7 +266,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
264
266
  style: normalizeStyle({ transform: `translateY(${offset}px)` }),
265
267
  "data-index": index,
266
268
  ref_for: true,
267
- ref: unref(measureElement)
269
+ ref: (el) => measureElement(index, el)
268
270
  }, [renderSlot(_ctx.$slots, "default", mergeProps({ ref_for: true }, {
269
271
  option,
270
272
  index
@@ -1 +1 @@
1
- {"version":3,"file":"select.js","names":["$slots"],"sources":["../../../src/components/select/select.vue"],"sourcesContent":["<template>\n <u-dropdown\n v-if=\"!readonly\"\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=\"selected ? (o(selected).get(labelKey) ?? label) : modelValue\"\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 <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 height: virtualEnabled ? withUnit(totalHeight, 'px') : undefined,\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=\"measureElement\"\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 {{ label || selected?.[labelKey] || FORM_EMPTY_CONTENT }}\n </template>\n</template>\n\n<script lang=\"ts\" setup>\nimport { o } from '@cat-kit/core'\nimport { useFormComponent, useFormFallbackProps, useVirtual } 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 { 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: 'Select' })\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 } = useFormComponent()\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 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) {\n const { valueKey } = props\n currentIndex.value = options.findIndex((option) => o(option).get(valueKey) === modelValue)\n selected.value = options[currentIndex.value]\n } else {\n currentIndex.value = -1\n selected.value = undefined\n }\n },\n { immediate: true }\n)\n\nconst {\n virtualList,\n totalHeight,\n virtualEnabled: _virtualEnabled,\n scrollTo,\n measureElement\n} = useVirtual({\n count: computed(() => options.value.length),\n virtualThreshold: 80,\n scrollEl: computed(() => scrollRef.value?.containerRef ?? null),\n gap: 4,\n estimateSize: () => 40\n})\n\nconst virtualEnabled = computed(() => {\n return _virtualEnabled.value && !props.grid\n})\n\nconst virtualOptions = computed(() => {\n const _options = options.value\n const { labelKey, valueKey } = props\n return virtualList.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.key,\n offset: item.start\n }\n })\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 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":["$slots"],"sources":["../../../src/components/select/select.vue"],"sourcesContent":["<template>\n <u-dropdown\n v-if=\"!readonly\"\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=\"selected ? (o(selected).get(labelKey) ?? label) : modelValue\"\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 {{ label || selected?.[labelKey] || FORM_EMPTY_CONTENT }}\n </template>\n</template>\n\n<script lang=\"ts\" setup>\nimport { o } from '@cat-kit/core'\nimport { useFormComponent, 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 { 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: 'Select' })\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 } = useFormComponent()\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 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) {\n const { valueKey } = props\n currentIndex.value = options.findIndex((option) => o(option).get(valueKey) === modelValue)\n selected.value = options[currentIndex.value]\n } else {\n currentIndex.value = -1\n selected.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 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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"}
@@ -26,12 +26,12 @@ declare const __VLS_base: _$vue.DefineComponent<__VLS_PublicProps, {}, {}, {}, {
26
26
  "onUpdate:text"?: ((value: any) => any) | undefined;
27
27
  "onUpdate:label"?: ((label?: string | undefined) => any) | undefined;
28
28
  }>, {
29
+ labelKey: string;
30
+ valueKey: string;
29
31
  disabled: boolean;
32
+ readonly: boolean;
30
33
  placeholder: string;
31
34
  clearable: boolean;
32
- readonly: boolean;
33
- labelKey: string;
34
- valueKey: string;
35
35
  }, {}, {}, {}, string, _$vue.ComponentProvideOptions, false, {}, any>;
36
36
  declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
37
37
  declare const _default: typeof __VLS_export;
@@ -1,6 +1,6 @@
1
1
  import { sliderContextKey } from "./di.js";
2
2
  import { computed, createElementBlock, defineComponent, inject, normalizeClass, normalizeStyle, openBlock, unref, useTemplateRef, watch } from "vue";
3
- import { useDrag, useUpdateLock } from "@veltra/compositions";
3
+ import { useDrag, useUserAction } from "@veltra/compositions";
4
4
  //#region src/components/slider/slider-thumb.vue
5
5
  const _sfc_main = /* @__PURE__ */ defineComponent({
6
6
  __name: "slider-thumb",
@@ -15,7 +15,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
15
15
  if (sliderProps.vertical) return { transform: `translate(0, ${props.modelValue}px)` };
16
16
  return { transform: `translate(${props.modelValue}px, 0)` };
17
17
  });
18
- const { updateAndLock, update } = useUpdateLock();
18
+ const { userAction, isUserActive } = useUserAction();
19
19
  function updateModel(offset) {
20
20
  offset = getOffsetByStep(offset);
21
21
  emit("update:modelValue", offset);
@@ -23,25 +23,22 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
23
23
  }
24
24
  const dragger = useDrag({
25
25
  target: computed(() => disabled.value ? null : thumbRef.value),
26
- onDrag({ offsetX, offsetY }) {
27
- updateAndLock(() => {
28
- updateModel(sliderProps.vertical ? offsetY : offsetX);
29
- });
30
- },
26
+ onDrag: userAction(({ offsetX, offsetY }) => {
27
+ updateModel(sliderProps.vertical ? offsetY : offsetX);
28
+ }),
31
29
  rangeX: range,
32
30
  rangeY: range,
33
- onDragEnd({ offsetX, offsetY }) {
34
- updateAndLock(() => {
35
- updateDragger(updateModel(sliderProps.vertical ? offsetY : offsetX));
36
- });
37
- }
31
+ onDragEnd: userAction(({ offsetX, offsetY }) => {
32
+ updateDragger(updateModel(sliderProps.vertical ? offsetY : offsetX));
33
+ })
38
34
  });
39
35
  function updateDragger(offset) {
40
36
  if (sliderProps.vertical) dragger.update({ offsetY: offset });
41
37
  else dragger.update({ offsetX: offset });
42
38
  }
43
39
  watch(() => props.modelValue, (offset) => {
44
- update(() => updateDragger(offset));
40
+ if (isUserActive()) return;
41
+ updateDragger(offset);
45
42
  });
46
43
  return (_ctx, _cache) => {
47
44
  return openBlock(), createElementBlock("div", {
@@ -1 +1 @@
1
- {"version":3,"file":"slider-thumb.js","names":[],"sources":["../../../src/components/slider/slider-thumb.vue"],"sourcesContent":["<template>\n <div ref=\"thumb\" :class=\"cls.e('thumb')\" :style></div>\n</template>\n<script lang=\"ts\" setup>\nimport { useDrag, useUpdateLock } from '@veltra/compositions'\nimport { computed, inject, useTemplateRef, watch } from 'vue'\n\nimport { sliderContextKey } from './di'\n\nconst props = defineProps<{\n modelValue: number\n}>()\n\nconst emit = defineEmits<{\n (e: 'update:modelValue', value: number): void\n}>()\n\nconst { cls, range, disabled, sliderProps, getOffsetByStep } = inject(sliderContextKey)!\n\nconst thumbRef = useTemplateRef('thumb')\n\nconst style = computed(() => {\n if (sliderProps.vertical) {\n return {\n transform: `translate(0, ${props.modelValue}px)`\n }\n }\n return {\n transform: `translate(${props.modelValue}px, 0)`\n }\n})\n\nconst { updateAndLock, update } = useUpdateLock()\n\nfunction updateModel(offset: number) {\n offset = getOffsetByStep(offset)\n emit('update:modelValue', offset)\n return offset\n}\n\nconst dragger = useDrag({\n target: computed(() => (disabled.value ? null : thumbRef.value)),\n\n onDrag({ offsetX, offsetY }) {\n updateAndLock(() => {\n updateModel(sliderProps.vertical ? offsetY : offsetX)\n })\n },\n rangeX: range,\n rangeY: range,\n onDragEnd({ offsetX, offsetY }) {\n updateAndLock(() => {\n const offset = updateModel(sliderProps.vertical ? offsetY : offsetX)\n updateDragger(offset)\n })\n }\n})\n\nfunction updateDragger(offset: number) {\n if (sliderProps.vertical) {\n dragger.update({ offsetY: offset })\n } else {\n dragger.update({ offsetX: offset })\n }\n}\n\nwatch(\n () => props.modelValue,\n (offset) => {\n update(() => updateDragger(offset))\n }\n)\n</script>\n"],"mappings":";;;;;;;;;EASA,MAAM,QAAQ;EAId,MAAM,OAAO;EAIb,MAAM,EAAE,KAAK,OAAO,UAAU,aAAa,oBAAoB,OAAO,iBAAiB;EAEvF,MAAM,WAAW,eAAe,QAAO;EAEvC,MAAM,QAAQ,eAAe;AAC3B,OAAI,YAAY,SACd,QAAO,EACL,WAAW,gBAAgB,MAAM,WAAW,MAC9C;AAEF,UAAO,EACL,WAAW,aAAa,MAAM,WAAW,SAC3C;IACD;EAED,MAAM,EAAE,eAAe,WAAW,eAAc;EAEhD,SAAS,YAAY,QAAgB;AACnC,YAAS,gBAAgB,OAAM;AAC/B,QAAK,qBAAqB,OAAM;AAChC,UAAO;;EAGT,MAAM,UAAU,QAAQ;GACtB,QAAQ,eAAgB,SAAS,QAAQ,OAAO,SAAS,MAAO;GAEhE,OAAO,EAAE,SAAS,WAAW;AAC3B,wBAAoB;AAClB,iBAAY,YAAY,WAAW,UAAU,QAAO;MACrD;;GAEH,QAAQ;GACR,QAAQ;GACR,UAAU,EAAE,SAAS,WAAW;AAC9B,wBAAoB;AAElB,mBADe,YAAY,YAAY,WAAW,UAAU,QAAO,CAC/C;MACrB;;GAEJ,CAAA;EAED,SAAS,cAAc,QAAgB;AACrC,OAAI,YAAY,SACd,SAAQ,OAAO,EAAE,SAAS,QAAQ,CAAA;OAElC,SAAQ,OAAO,EAAE,SAAS,QAAQ,CAAA;;AAItC,cACQ,MAAM,aACX,WAAW;AACV,gBAAa,cAAc,OAAO,CAAA;IAEtC;;uBAtEE,mBAAsD,OAAA;IAAjD,KAAI;IAAS,OAAK,eAAE,MAAA,IAAG,CAAC,EAAC,QAAA,CAAA;IAAY,OAAK,eAAL,MAAA,MAAK"}
1
+ {"version":3,"file":"slider-thumb.js","names":[],"sources":["../../../src/components/slider/slider-thumb.vue"],"sourcesContent":["<template>\n <div ref=\"thumb\" :class=\"cls.e('thumb')\" :style></div>\n</template>\n<script lang=\"ts\" setup>\nimport { useDrag, useUserAction } from '@veltra/compositions'\nimport { computed, inject, useTemplateRef, watch } from 'vue'\n\nimport { sliderContextKey } from './di'\n\nconst props = defineProps<{\n modelValue: number\n}>()\n\nconst emit = defineEmits<{\n (e: 'update:modelValue', value: number): void\n}>()\n\nconst { cls, range, disabled, sliderProps, getOffsetByStep } = inject(sliderContextKey)!\n\nconst thumbRef = useTemplateRef('thumb')\n\nconst style = computed(() => {\n if (sliderProps.vertical) {\n return {\n transform: `translate(0, ${props.modelValue}px)`\n }\n }\n return {\n transform: `translate(${props.modelValue}px, 0)`\n }\n})\n\nconst { userAction, isUserActive } = useUserAction()\n\nfunction updateModel(offset: number) {\n offset = getOffsetByStep(offset)\n emit('update:modelValue', offset)\n return offset\n}\n\nconst dragger = useDrag({\n target: computed(() => (disabled.value ? null : thumbRef.value)),\n\n onDrag: userAction(({ offsetX, offsetY }) => {\n updateModel(sliderProps.vertical ? offsetY : offsetX)\n }),\n rangeX: range,\n rangeY: range,\n onDragEnd: userAction(({ offsetX, offsetY }) => {\n const offset = updateModel(sliderProps.vertical ? offsetY : offsetX)\n updateDragger(offset)\n })\n})\n\nfunction updateDragger(offset: number) {\n if (sliderProps.vertical) {\n dragger.update({ offsetY: offset })\n } else {\n dragger.update({ offsetX: offset })\n }\n}\n\nwatch(\n () => props.modelValue,\n (offset) => {\n if (isUserActive()) return\n updateDragger(offset)\n }\n)\n</script>\n"],"mappings":";;;;;;;;;EASA,MAAM,QAAQ;EAId,MAAM,OAAO;EAIb,MAAM,EAAE,KAAK,OAAO,UAAU,aAAa,oBAAoB,OAAO,iBAAiB;EAEvF,MAAM,WAAW,eAAe,QAAO;EAEvC,MAAM,QAAQ,eAAe;AAC3B,OAAI,YAAY,SACd,QAAO,EACL,WAAW,gBAAgB,MAAM,WAAW,MAC9C;AAEF,UAAO,EACL,WAAW,aAAa,MAAM,WAAW,SAC3C;IACD;EAED,MAAM,EAAE,YAAY,iBAAiB,eAAc;EAEnD,SAAS,YAAY,QAAgB;AACnC,YAAS,gBAAgB,OAAM;AAC/B,QAAK,qBAAqB,OAAM;AAChC,UAAO;;EAGT,MAAM,UAAU,QAAQ;GACtB,QAAQ,eAAgB,SAAS,QAAQ,OAAO,SAAS,MAAO;GAEhE,QAAQ,YAAY,EAAE,SAAS,cAAc;AAC3C,gBAAY,YAAY,WAAW,UAAU,QAAO;KACpD;GACF,QAAQ;GACR,QAAQ;GACR,WAAW,YAAY,EAAE,SAAS,cAAc;AAE9C,kBADe,YAAY,YAAY,WAAW,UAAU,QAC9C,CAAM;KACrB;GACF,CAAA;EAED,SAAS,cAAc,QAAgB;AACrC,OAAI,YAAY,SACd,SAAQ,OAAO,EAAE,SAAS,QAAQ,CAAA;OAElC,SAAQ,OAAO,EAAE,SAAS,QAAQ,CAAA;;AAItC,cACQ,MAAM,aACX,WAAW;AACV,OAAI,cAAc,CAAE;AACpB,iBAAc,OAAM;IAExB;;uBAnEE,mBAAsD,OAAA;IAAjD,KAAI;IAAS,OAAK,eAAE,MAAA,IAAG,CAAC,EAAC,QAAA,CAAA;IAAY,OAAK,eAAL,MAAA,MAAK"}
@@ -3,7 +3,7 @@ import _sfc_main$1 from "./slider-thumb.js";
3
3
  import { useSlider } from "./use-slider.js";
4
4
  import { Fragment, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createVNode, defineComponent, isRef, normalizeClass, normalizeStyle, openBlock, provide, renderList, toDisplayString, unref, watch, withModifiers } from "vue";
5
5
  import { bem } from "@veltra/utils";
6
- import { useFormComponent, useFormFallbackProps, useUpdateLock } from "@veltra/compositions";
6
+ import { useFormComponent, useFormFallbackProps, useUserAction } from "@veltra/compositions";
7
7
  //#region src/components/slider/slider.vue
8
8
  const _hoisted_1 = { key: 1 };
9
9
  const _sfc_main = /* @__PURE__ */ defineComponent({
@@ -61,7 +61,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
61
61
  [sizeProp]: `${Math.abs(offset1.value - offset2.value)}px`
62
62
  };
63
63
  });
64
- const { updateAndLock, update } = useUpdateLock();
64
+ const { userAction, isUserActive } = useUserAction();
65
65
  watch([sliderSize, ...[
66
66
  "modelValue",
67
67
  "range",
@@ -69,13 +69,12 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
69
69
  "min",
70
70
  "vertical"
71
71
  ].map((k) => () => props[k])], ([size, value, range]) => {
72
- update(() => {
73
- if (value === void 0 || size === 0) return;
74
- if (range) {
75
- offset1.value = value2SliderOffset(value[0]);
76
- offset2.value = value2SliderOffset(value[1]);
77
- } else offset1.value = value2SliderOffset(value);
78
- });
72
+ if (isUserActive()) return;
73
+ if (value === void 0 || size === 0) return;
74
+ if (range) {
75
+ offset1.value = value2SliderOffset(value[0]);
76
+ offset2.value = value2SliderOffset(value[1]);
77
+ } else offset1.value = value2SliderOffset(value);
79
78
  }, { immediate: true });
80
79
  const ticks = computed(() => {
81
80
  const { step, min, max } = props;
@@ -84,12 +83,10 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
84
83
  const offsetPercent = step / (max - min) * 100;
85
84
  return [...Array.from({ length: tickLength }, (_, i) => i * offsetPercent), 100];
86
85
  });
87
- watch([offset1, offset2], (v) => {
88
- updateAndLock(() => {
89
- if (props.range) emit("update:modelValue", v.map(sliderOffset2Value).sort());
90
- else emit("update:modelValue", sliderOffset2Value(v[0]));
91
- });
92
- });
86
+ watch([offset1, offset2], userAction((v) => {
87
+ if (props.range) emit("update:modelValue", v.map(sliderOffset2Value).sort());
88
+ else emit("update:modelValue", sliderOffset2Value(v[0]));
89
+ }));
93
90
  function handleClickSlider(e) {
94
91
  if (disabled.value || props.range) return;
95
92
  const rect = e.currentTarget.getBoundingClientRect();
@@ -1 +1 @@
1
- {"version":3,"file":"slider.js","names":[],"sources":["../../../src/components/slider/slider.vue"],"sourcesContent":["<template>\n <div v-if=\"!readonly\" :class=\"className\">\n <div :class=\"cls.e('track')\" ref=\"sliderRef\" @click=\"handleClickSlider\">\n <div :class=\"cls.e('bar')\" :style=\"barStyles\" />\n\n <slider-thumb v-model=\"offset1\" @click.stop />\n <slider-thumb v-if=\"range\" v-model=\"offset2\" @click.stop />\n\n <div\n v-for=\"tick in ticks\"\n :style=\"{ [vertical ? 'bottom' : 'left']: `${tick}%` }\"\n :class=\"cls.e('tick')\"\n />\n </div>\n </div>\n\n <div v-else>\n {{ props.modelValue }}\n </div>\n</template>\n\n<script lang=\"ts\" setup generic=\"T extends number | [number, number]\">\nimport { useFormComponent, useFormFallbackProps, useUpdateLock } from '@veltra/compositions'\nimport { bem } from '@veltra/utils'\nimport { computed, provide, watch } from 'vue'\n\nimport type { SliderProps, SliderEmits } from '../../types'\nimport { sliderContextKey } from './di'\nimport SliderThumb from './slider-thumb.vue'\nimport { useSlider } from './use-slider'\n\ndefineOptions({\n name: 'Slider'\n})\n\nconst props = withDefaults(defineProps<SliderProps<T>>(), {\n min: 0,\n max: 100,\n disabled: undefined,\n readonly: undefined\n})\n\nconst emit = defineEmits<SliderEmits<T>>()\n\nconst cls = bem('slider')\n\nconst { formProps } = useFormComponent()\n\nconst { size, disabled, readonly } = useFormFallbackProps([formProps ?? {}, props])\n\nconst className = computed(() => {\n return [\n cls.b,\n cls.m(size.value),\n bem.is('disabled', disabled.value),\n bem.is('range', props.range),\n bem.is('horizontal', !props.vertical),\n bem.is('vertical', props.vertical)\n ]\n})\n\nconst {\n offset1,\n offset2,\n sliderRef,\n slideRange,\n sliderSize,\n sliderOffset2Value,\n value2SliderOffset,\n getOffsetByStep\n} = useSlider(props)\n\nconst barStyles = computed(() => {\n const { vertical } = props\n const offsetProp = vertical ? 'bottom' : 'left'\n const sizeProp = vertical ? 'height' : 'width'\n\n if (!props.range) {\n return {\n [offsetProp]: 0,\n [sizeProp]: `${Math.abs(offset1.value)}px`\n }\n }\n return {\n [offsetProp]: `${Math.min(Math.abs(offset1.value), Math.abs(offset2.value))}px`,\n [sizeProp]: `${Math.abs(offset1.value - offset2.value)}px`\n }\n})\n\nconst { updateAndLock, update } = useUpdateLock()\n\nwatch(\n [sliderSize, ...['modelValue', 'range', 'max', 'min', 'vertical'].map((k) => () => props[k])],\n ([size, value, range]) => {\n update(() => {\n if (value === undefined || size === 0) return\n\n if (range) {\n offset1.value = value2SliderOffset((value as [number, number])[0])\n offset2.value = value2SliderOffset((value as [number, number])[1])\n } else {\n offset1.value = value2SliderOffset(value as number)\n }\n })\n },\n { immediate: true }\n)\n\nconst ticks = computed(() => {\n const { step, min, max } = props\n if (!step) return []\n const tickLength = Math.ceil((max! - min!) / step)\n const offsetPercent = (step / (max! - min!)) * 100\n\n return [...Array.from({ length: tickLength }, (_, i) => i * offsetPercent), 100]\n})\n\nwatch([offset1, offset2], (v) => {\n updateAndLock(() => {\n if (props.range) {\n emit('update:modelValue', v.map(sliderOffset2Value).sort() as T)\n } else {\n emit('update:modelValue', sliderOffset2Value(v[0]) as T)\n }\n })\n})\n\nfunction handleClickSlider(e: MouseEvent) {\n if (disabled.value || props.range) return\n\n // 获取点击位置相对于滑块的偏移量\n const rect = (e.currentTarget as HTMLElement).getBoundingClientRect()\n\n offset1.value = getOffsetByStep(e.clientX - rect.left)\n}\n\nprovide(sliderContextKey, {\n sliderProps: props,\n disabled,\n range: slideRange,\n cls,\n getOffsetByStep\n})\n</script>\n"],"mappings":"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"}
1
+ {"version":3,"file":"slider.js","names":[],"sources":["../../../src/components/slider/slider.vue"],"sourcesContent":["<template>\n <div v-if=\"!readonly\" :class=\"className\">\n <div :class=\"cls.e('track')\" ref=\"sliderRef\" @click=\"handleClickSlider\">\n <div :class=\"cls.e('bar')\" :style=\"barStyles\" />\n\n <slider-thumb v-model=\"offset1\" @click.stop />\n <slider-thumb v-if=\"range\" v-model=\"offset2\" @click.stop />\n\n <div\n v-for=\"tick in ticks\"\n :style=\"{ [vertical ? 'bottom' : 'left']: `${tick}%` }\"\n :class=\"cls.e('tick')\"\n />\n </div>\n </div>\n\n <div v-else>\n {{ props.modelValue }}\n </div>\n</template>\n\n<script lang=\"ts\" setup generic=\"T extends number | [number, number]\">\nimport { useFormComponent, useFormFallbackProps, useUserAction } from '@veltra/compositions'\nimport { bem } from '@veltra/utils'\nimport { computed, provide, watch } from 'vue'\n\nimport type { SliderProps, SliderEmits } from '../../types'\nimport { sliderContextKey } from './di'\nimport SliderThumb from './slider-thumb.vue'\nimport { useSlider } from './use-slider'\n\ndefineOptions({\n name: 'Slider'\n})\n\nconst props = withDefaults(defineProps<SliderProps<T>>(), {\n min: 0,\n max: 100,\n disabled: undefined,\n readonly: undefined\n})\n\nconst emit = defineEmits<SliderEmits<T>>()\n\nconst cls = bem('slider')\n\nconst { formProps } = useFormComponent()\n\nconst { size, disabled, readonly } = useFormFallbackProps([formProps ?? {}, props])\n\nconst className = computed(() => {\n return [\n cls.b,\n cls.m(size.value),\n bem.is('disabled', disabled.value),\n bem.is('range', props.range),\n bem.is('horizontal', !props.vertical),\n bem.is('vertical', props.vertical)\n ]\n})\n\nconst {\n offset1,\n offset2,\n sliderRef,\n slideRange,\n sliderSize,\n sliderOffset2Value,\n value2SliderOffset,\n getOffsetByStep\n} = useSlider(props)\n\nconst barStyles = computed(() => {\n const { vertical } = props\n const offsetProp = vertical ? 'bottom' : 'left'\n const sizeProp = vertical ? 'height' : 'width'\n\n if (!props.range) {\n return {\n [offsetProp]: 0,\n [sizeProp]: `${Math.abs(offset1.value)}px`\n }\n }\n return {\n [offsetProp]: `${Math.min(Math.abs(offset1.value), Math.abs(offset2.value))}px`,\n [sizeProp]: `${Math.abs(offset1.value - offset2.value)}px`\n }\n})\n\nconst { userAction, isUserActive } = useUserAction()\n\nwatch(\n [sliderSize, ...['modelValue', 'range', 'max', 'min', 'vertical'].map((k) => () => props[k])],\n ([size, value, range]) => {\n if (isUserActive()) return\n if (value === undefined || size === 0) return\n\n if (range) {\n offset1.value = value2SliderOffset((value as [number, number])[0])\n offset2.value = value2SliderOffset((value as [number, number])[1])\n } else {\n offset1.value = value2SliderOffset(value as number)\n }\n },\n { immediate: true }\n)\n\nconst ticks = computed(() => {\n const { step, min, max } = props\n if (!step) return []\n const tickLength = Math.ceil((max! - min!) / step)\n const offsetPercent = (step / (max! - min!)) * 100\n\n return [...Array.from({ length: tickLength }, (_, i) => i * offsetPercent), 100]\n})\n\nwatch(\n [offset1, offset2],\n userAction((v) => {\n if (props.range) {\n emit('update:modelValue', v.map(sliderOffset2Value).sort() as T)\n } else {\n emit('update:modelValue', sliderOffset2Value(v[0]) as T)\n }\n })\n)\n\nfunction handleClickSlider(e: MouseEvent) {\n if (disabled.value || props.range) return\n\n // 获取点击位置相对于滑块的偏移量\n const rect = (e.currentTarget as HTMLElement).getBoundingClientRect()\n\n offset1.value = getOffsetByStep(e.clientX - rect.left)\n}\n\nprovide(sliderContextKey, {\n sliderProps: props,\n disabled,\n range: slideRange,\n cls,\n getOffsetByStep\n})\n</script>\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"di.js","names":[],"sources":["../../../src/components/table/di.ts"],"sourcesContent":["import type { VirtualReturned } from '@veltra/compositions'\nimport type { BEM } from '@veltra/utils'\nimport type { InjectionKey, ShallowRef, Slots } from 'vue'\n\nimport type {\n TableProps,\n TableColumnSlotsScope,\n TableColumnRenderContext,\n TableRow,\n RenderReturn,\n TableColumn,\n TableRowSlotsScope\n} from '../../types'\nimport type { ColumnNode } from './node/col'\nimport type { ColumnConfig } from './use-columns'\n\nexport const TableDIKey: InjectionKey<\n {\n /** 表格属性 */\n tableProps: TableProps\n /** 表格插槽 */\n tableSlots: Slots\n /** 类 */\n cls: BEM<'table'>\n /** 行 */\n rows: ShallowRef<TableRow[]>\n /** 选中行 */\n checkedRows: ShallowRef<Set<TableRow>>\n /** 结构化列 */\n columnConfig: ColumnConfig\n /** 事件处理方法 */\n handleRowClick: (row: TableRow, ev: MouseEvent) => void\n /** 单元格点击 */\n handleCellClick: (row: TableRow, column: TableColumn, ev: MouseEvent) => void\n /** 表格列插槽node */\n getColumnSlotsNode: (ctx: TableColumnSlotsScope | TableColumnRenderContext) => RenderReturn\n /** 展开行插槽node */\n getExpandRowSlotsNode: (ctx: TableRowSlotsScope) => RenderReturn\n /** 表头插槽node */\n getHeaderSlotsNode: (ctx: { column: ColumnNode }) => RenderReturn\n\n /** 展开/隐藏子节点 */\n toggleTreeRowExpand: (row: TableRow) => void\n\n /** 获取单元格的类 */\n getCellClass: (column: ColumnNode) => string\n\n /** 获取表头单元格的类 */\n getHeaderCellClass: (column: ColumnNode) => string\n\n /** 获取单元格上下文 */\n getCellCtx: (\n row: TableRow,\n column: ColumnNode\n ) => TableColumnSlotsScope | TableColumnRenderContext\n } & VirtualReturned\n> = Symbol('TableDIKey')\n\nexport const TableResizeKey: InjectionKey<{\n handleResizeMousedown: (e: MouseEvent, resizeColumn: ColumnNode) => void\n headerRef: ShallowRef<HTMLElement | undefined>\n}> = Symbol('TableResizeKey')\n"],"mappings":";AAgBA,MAAa,aAwCT,OAAO,aAAa;AAExB,MAAa,iBAGR,OAAO,iBAAiB"}
1
+ {"version":3,"file":"di.js","names":[],"sources":["../../../src/components/table/di.ts"],"sourcesContent":["import type { VirtualItem } from '@veltra/compositions'\nimport type { BEM } from '@veltra/utils'\nimport type { ComputedRef, InjectionKey, ShallowRef, Slots } from 'vue'\n\nimport type {\n TableProps,\n TableColumnSlotsScope,\n TableColumnRenderContext,\n TableRow,\n RenderReturn,\n TableColumn,\n TableRowSlotsScope\n} from '../../types'\nimport type { ColumnNode } from './node/col'\nimport type { ColumnConfig } from './use-columns'\n\nexport const TableDIKey: InjectionKey<{\n /** 表格属性 */\n tableProps: TableProps\n /** 表格插槽 */\n tableSlots: Slots\n /** 类 */\n cls: BEM<'table'>\n /** 行 */\n rows: ShallowRef<TableRow[]>\n /** 选中行 */\n checkedRows: ShallowRef<Set<TableRow>>\n /** 结构化列 */\n columnConfig: ColumnConfig\n /** 事件处理方法 */\n handleRowClick: (row: TableRow, ev: MouseEvent) => void\n /** 单元格点击 */\n handleCellClick: (row: TableRow, column: TableColumn, ev: MouseEvent) => void\n /** 表格列插槽node */\n getColumnSlotsNode: (ctx: TableColumnSlotsScope | TableColumnRenderContext) => RenderReturn\n /** 展开行插槽node */\n getExpandRowSlotsNode: (ctx: TableRowSlotsScope) => RenderReturn\n /** 表头插槽node */\n getHeaderSlotsNode: (ctx: { column: ColumnNode }) => RenderReturn\n\n /** 展开/隐藏子节点 */\n toggleTreeRowExpand: (row: TableRow) => void\n\n /** 获取单元格的类 */\n getCellClass: (column: ColumnNode) => string\n\n /** 获取表头单元格的类 */\n getHeaderCellClass: (column: ColumnNode) => string\n\n /** 获取单元格上下文 */\n getCellCtx: (\n row: TableRow,\n column: ColumnNode\n ) => TableColumnSlotsScope | TableColumnRenderContext\n\n /**\n * 当前渲染窗口的虚拟项列表。\n *\n * 由 `useVirtualizer` 拆分出的 `items` shallowRef:仅在底层 `items`\n * 引用变化时才更新,`isScrolling` / 纯尺寸变化不会导致此 ref 更新。\n */\n virtualList: ShallowRef<VirtualItem[]>\n /** 是否启用虚拟列表 */\n virtualEnabled: ComputedRef<boolean>\n /**\n * 测量行元素尺寸(参数顺序与底层 `Virtualizer.measureElement` 一致)。\n *\n * 元素卸载(`el === null`)时会从底层解绑,避免被移除的 `<tr>` 继续触发\n * size=0 测量回调。\n */\n measureElement: (index: number, el: Element | null) => void\n}> = Symbol('TableDIKey')\n\nexport const TableResizeKey: InjectionKey<{\n handleResizeMousedown: (e: MouseEvent, resizeColumn: ColumnNode) => void\n headerRef: ShallowRef<HTMLElement | undefined>\n}> = Symbol('TableResizeKey')\n"],"mappings":";AAgBA,MAAa,aAuDR,OAAO,aAAa;AAEzB,MAAa,iBAGR,OAAO,iBAAiB"}
@@ -16,7 +16,16 @@ declare class TableRowNode<Data extends Record<string, any> = Record<string, any
16
16
  isCurrent: boolean;
17
17
  /** 是否选中 */
18
18
  checked: boolean;
19
- uid: number | string;
19
+ /**
20
+ * 行的稳定唯一标识。
21
+ *
22
+ * E2 不变式:`uid` 在单个 `TableRowNode` 实例的生命周期内不可变更。
23
+ * `useVirtualizer` 的 `getItemKey: i => rows[i].uid` 依赖该不变式来复用测量缓存;
24
+ * 若 uid 在运行时变更,虚拟列表的尺寸表会错配导致滚动抖动。
25
+ * 当前代码路径(`createRow` / `copy`)始终为每个新节点分配一次 uid,
26
+ * 所以该不变式天然成立;此处使用 `readonly` 做编译期锁定。
27
+ */
28
+ readonly uid: number | string;
20
29
  children?: TableRowNode<Data>[];
21
30
  /**
22
31
  *
@@ -19,6 +19,15 @@ var TableRowNode = class TableRowNode extends TreeNode {
19
19
  isCurrent = false;
20
20
  /** 是否选中 */
21
21
  checked = false;
22
+ /**
23
+ * 行的稳定唯一标识。
24
+ *
25
+ * E2 不变式:`uid` 在单个 `TableRowNode` 实例的生命周期内不可变更。
26
+ * `useVirtualizer` 的 `getItemKey: i => rows[i].uid` 依赖该不变式来复用测量缓存;
27
+ * 若 uid 在运行时变更,虚拟列表的尺寸表会错配导致滚动抖动。
28
+ * 当前代码路径(`createRow` / `copy`)始终为每个新节点分配一次 uid,
29
+ * 所以该不变式天然成立;此处使用 `readonly` 做编译期锁定。
30
+ */
22
31
  uid;
23
32
  children = void 0;
24
33
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"row.js","names":[],"sources":["../../../../src/components/table/node/row.ts"],"sourcesContent":["import { TreeNode } from '@cat-kit/core'\nimport { isReactive, shallowReactive } from 'vue'\n\n/**\n * TODO: 优化参数,对大数据量来说,对象字面量参数会使内存占用过高\n */\nexport class TableRowNode<Data extends Record<string, any> = Record<string, any>> extends TreeNode<\n Data,\n TableRowNode<Data>\n> {\n /** 索引路径 */\n get indexes(): number[] {\n if (!this.parent) return [this.index]\n return this.parent.indexes.concat(this.index)\n }\n\n isExpandRow = false\n\n /** 是否操作中 */\n operating = false\n\n /** 是否展开 */\n expanded = false\n\n /** 是否为当前的点击行 */\n isCurrent = false\n\n /** 是否选中 */\n checked = false\n\n uid: number | string\n\n override children?: TableRowNode<Data>[] = undefined\n\n /**\n *\n * @param data 一个普通对象或者一个响应式对象\n * @param index 索引值\n * @param depth 深度(根为 0)\n * @param parent 父行节点\n * @param uid 行唯一标识\n * @returns\n */\n constructor(options: {\n data: Data\n index: number\n depth: number\n parent?: TableRowNode<Data>\n uid: number | string\n }) {\n const { data, index, depth, parent, uid } = options\n\n if (!data) {\n super(data as Data, index, depth, parent)\n } else {\n super(isReactive(data) ? data : shallowReactive(data), index, depth, parent)\n }\n this.uid = uid\n return shallowReactive(this)\n }\n\n copy() {\n const row = new TableRowNode({\n data: this.data,\n index: this.index,\n depth: this.depth,\n parent: this.parent ?? undefined,\n uid: `expand_${this.uid}`\n })\n\n row.isExpandRow = true\n\n return row\n }\n}\n"],"mappings":";;;;;;AAMA,IAAa,eAAb,MAAa,qBAA6E,SAGxF;;CAEA,IAAI,UAAoB;AACtB,MAAI,CAAC,KAAK,OAAQ,QAAO,CAAC,KAAK,MAAM;AACrC,SAAO,KAAK,OAAO,QAAQ,OAAO,KAAK,MAAM;;CAG/C,cAAc;;CAGd,YAAY;;CAGZ,WAAW;;CAGX,YAAY;;CAGZ,UAAU;CAEV;CAEA,WAA2C,KAAA;;;;;;;;;;CAW3C,YAAY,SAMT;EACD,MAAM,EAAE,MAAM,OAAO,OAAO,QAAQ,QAAQ;AAE5C,MAAI,CAAC,KACH,OAAM,MAAc,OAAO,OAAO,OAAO;MAEzC,OAAM,WAAW,KAAK,GAAG,OAAO,gBAAgB,KAAK,EAAE,OAAO,OAAO,OAAO;AAE9E,OAAK,MAAM;AACX,SAAO,gBAAgB,KAAK;;CAG9B,OAAO;EACL,MAAM,MAAM,IAAI,aAAa;GAC3B,MAAM,KAAK;GACX,OAAO,KAAK;GACZ,OAAO,KAAK;GACZ,QAAQ,KAAK,UAAU,KAAA;GACvB,KAAK,UAAU,KAAK;GACrB,CAAC;AAEF,MAAI,cAAc;AAElB,SAAO"}
1
+ {"version":3,"file":"row.js","names":[],"sources":["../../../../src/components/table/node/row.ts"],"sourcesContent":["import { TreeNode } from '@cat-kit/core'\nimport { isReactive, shallowReactive } from 'vue'\n\n/**\n * TODO: 优化参数,对大数据量来说,对象字面量参数会使内存占用过高\n */\nexport class TableRowNode<Data extends Record<string, any> = Record<string, any>> extends TreeNode<\n Data,\n TableRowNode<Data>\n> {\n /** 索引路径 */\n get indexes(): number[] {\n if (!this.parent) return [this.index]\n return this.parent.indexes.concat(this.index)\n }\n\n isExpandRow = false\n\n /** 是否操作中 */\n operating = false\n\n /** 是否展开 */\n expanded = false\n\n /** 是否为当前的点击行 */\n isCurrent = false\n\n /** 是否选中 */\n checked = false\n\n /**\n * 行的稳定唯一标识。\n *\n * E2 不变式:`uid` 在单个 `TableRowNode` 实例的生命周期内不可变更。\n * `useVirtualizer` 的 `getItemKey: i => rows[i].uid` 依赖该不变式来复用测量缓存;\n * 若 uid 在运行时变更,虚拟列表的尺寸表会错配导致滚动抖动。\n * 当前代码路径(`createRow` / `copy`)始终为每个新节点分配一次 uid,\n * 所以该不变式天然成立;此处使用 `readonly` 做编译期锁定。\n */\n readonly uid: number | string\n\n override children?: TableRowNode<Data>[] = undefined\n\n /**\n *\n * @param data 一个普通对象或者一个响应式对象\n * @param index 索引值\n * @param depth 深度(根为 0)\n * @param parent 父行节点\n * @param uid 行唯一标识\n * @returns\n */\n constructor(options: {\n data: Data\n index: number\n depth: number\n parent?: TableRowNode<Data>\n uid: number | string\n }) {\n const { data, index, depth, parent, uid } = options\n\n if (!data) {\n super(data as Data, index, depth, parent)\n } else {\n super(isReactive(data) ? data : shallowReactive(data), index, depth, parent)\n }\n this.uid = uid\n return shallowReactive(this)\n }\n\n copy() {\n const row = new TableRowNode({\n data: this.data,\n index: this.index,\n depth: this.depth,\n parent: this.parent ?? undefined,\n uid: `expand_${this.uid}`\n })\n\n row.isExpandRow = true\n\n return row\n }\n}\n"],"mappings":";;;;;;AAMA,IAAa,eAAb,MAAa,qBAA6E,SAGxF;;CAEA,IAAI,UAAoB;AACtB,MAAI,CAAC,KAAK,OAAQ,QAAO,CAAC,KAAK,MAAM;AACrC,SAAO,KAAK,OAAO,QAAQ,OAAO,KAAK,MAAM;;CAG/C,cAAc;;CAGd,YAAY;;CAGZ,WAAW;;CAGX,YAAY;;CAGZ,UAAU;;;;;;;;;;CAWV;CAEA,WAA2C,KAAA;;;;;;;;;;CAW3C,YAAY,SAMT;EACD,MAAM,EAAE,MAAM,OAAO,OAAO,QAAQ,QAAQ;AAE5C,MAAI,CAAC,KACH,OAAM,MAAc,OAAO,OAAO,OAAO;MAEzC,OAAM,WAAW,KAAK,GAAG,OAAO,gBAAgB,KAAK,EAAE,OAAO,OAAO,OAAO;AAE9E,OAAK,MAAM;AACX,SAAO,gBAAgB,KAAK;;CAG9B,OAAO;EACL,MAAM,MAAM,IAAI,aAAa;GAC3B,MAAM,KAAK;GACX,OAAO,KAAK;GACZ,OAAO,KAAK;GACZ,QAAQ,KAAK,UAAU,KAAA;GACvB,KAAK,UAAU,KAAK;GACrB,CAAC;AAEF,MAAI,cAAc;AAElB,SAAO"}
@@ -1,19 +1,30 @@
1
1
  import { TableDIKey } from "./di.js";
2
2
  import _sfc_main$1 from "../empty/empty.js";
3
3
  import { UExpandTableRow, UTableRow } from "./table-row.js";
4
- import { Fragment, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createVNode, defineComponent, inject, normalizeClass, openBlock, renderList, renderSlot, shallowRef, unref, watch } from "vue";
5
- import { bem, setStyles } from "@veltra/utils";
4
+ import { Fragment, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createVNode, defineComponent, inject, normalizeClass, openBlock, renderList, renderSlot, unref } from "vue";
5
+ import { bem } from "@veltra/utils";
6
6
  //#region src/components/table/table-body.vue
7
7
  const _hoisted_1 = ["colspan"];
8
8
  const _sfc_main = /* @__PURE__ */ defineComponent({
9
9
  name: "TableBody",
10
10
  __name: "table-body",
11
- setup(__props, { expose: __expose }) {
11
+ setup(__props) {
12
12
  const { cls, rows, virtualList, columnConfig, tableProps, virtualEnabled } = inject(TableDIKey);
13
13
  const { leafColumns } = columnConfig;
14
- const getStripeCls = computed(() => {
15
- return tableProps.stripe ? (index) => bem.is("stripe", index % 2 === 1) : () => "";
16
- });
14
+ const bodyCls = cls.e("body");
15
+ const emptyRowCls = cls.e("row");
16
+ const emptyCls = cls.e("empty");
17
+ /**
18
+ * C1:stripe class 查找表。
19
+ *
20
+ * `bem.is('stripe', true) === 'is-stripe'`,`bem.is('stripe', false) === ''`。
21
+ * 两种输出是全局常量,无需每次调用 `bem.is`;按奇偶直接查表即可。
22
+ * 非 stripe 模式下两个位置均返回空串。
23
+ */
24
+ const STRIPE_CLS_ON = [bem.is("stripe", false), bem.is("stripe", true)];
25
+ const STRIPE_CLS_OFF = ["", ""];
26
+ const stripeTable = computed(() => tableProps.stripe ? STRIPE_CLS_ON : STRIPE_CLS_OFF);
27
+ const getStripeCls = (index) => stripeTable.value[index & 1];
17
28
  const tableRows = computed(() => {
18
29
  if (!virtualEnabled.value) return rows.value.map((row, index) => {
19
30
  return {
@@ -30,41 +41,29 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
30
41
  };
31
42
  });
32
43
  });
33
- const bodyRef = shallowRef();
34
- function setBodyTransform(transformY) {
35
- bodyRef.value && setStyles(bodyRef.value, { transform: `translate3d(0, ${transformY}px, 0)` });
36
- }
37
- watch(virtualList, (list) => {
38
- setBodyTransform(list[0]?.start ?? 0);
39
- });
40
- __expose({ setBodyTransform });
41
44
  return (_ctx, _cache) => {
42
- return openBlock(), createElementBlock("tbody", {
43
- class: normalizeClass(unref(cls).e("body")),
44
- ref_key: "bodyRef",
45
- ref: bodyRef
46
- }, [
45
+ return openBlock(), createElementBlock("tbody", { class: normalizeClass(unref(bodyCls)) }, [
47
46
  (openBlock(true), createElementBlock(Fragment, null, renderList(tableRows.value, ({ row, index, stripeIndex }) => {
48
47
  return openBlock(), createElementBlock(Fragment, { key: row.uid }, [row.isExpandRow ? (openBlock(), createBlock(unref(UExpandTableRow), {
49
48
  key: 0,
50
49
  row,
51
- "data-index": index
52
- }, null, 8, ["row", "data-index"])) : (openBlock(), createBlock(unref(UTableRow), {
50
+ index
51
+ }, null, 8, ["row", "index"])) : (openBlock(), createBlock(unref(UTableRow), {
53
52
  key: 1,
54
53
  row,
55
- "data-index": index,
56
- class: normalizeClass([unref(bem).is("current", row.isCurrent), getStripeCls.value(stripeIndex)])
54
+ index,
55
+ class: normalizeClass(getStripeCls(stripeIndex))
57
56
  }, null, 8, [
58
57
  "row",
59
- "data-index",
58
+ "index",
60
59
  "class"
61
60
  ]))], 64);
62
61
  }), 128)),
63
62
  createCommentVNode(" 空 "),
64
63
  !unref(rows).length ? (openBlock(), createElementBlock("tr", {
65
64
  key: 0,
66
- class: normalizeClass(unref(cls).e("row"))
67
- }, [createElementVNode("td", { colspan: unref(leafColumns).length }, [renderSlot(_ctx.$slots, "empty", {}, () => [createVNode(unref(_sfc_main$1), { class: normalizeClass(unref(cls).e("empty")) }, null, 8, ["class"])])], 8, _hoisted_1)], 2)) : createCommentVNode("v-if", true),
65
+ class: normalizeClass(unref(emptyRowCls))
66
+ }, [createElementVNode("td", { colspan: unref(leafColumns).length }, [renderSlot(_ctx.$slots, "empty", {}, () => [createVNode(unref(_sfc_main$1), { class: normalizeClass(unref(emptyCls)) }, null, 8, ["class"])])], 8, _hoisted_1)], 2)) : createCommentVNode("v-if", true),
68
67
  renderSlot(_ctx.$slots, "default")
69
68
  ], 2);
70
69
  };
@@ -1 +1 @@
1
- {"version":3,"file":"table-body.js","names":[],"sources":["../../../src/components/table/table-body.vue"],"sourcesContent":["<template>\n <tbody :class=\"cls.e('body')\" ref=\"bodyRef\">\n <template v-for=\"{ row, index, stripeIndex } of tableRows\" :key=\"row.uid\">\n <UExpandTableRow v-if=\"row.isExpandRow\" :row=\"row\" :data-index=\"index\" />\n <UTableRow\n v-else\n :row=\"row\"\n :data-index=\"index\"\n :class=\"[bem.is('current', row.isCurrent), getStripeCls(stripeIndex)]\"\n />\n </template>\n\n <!-- 空 -->\n <tr v-if=\"!rows.length\" :class=\"cls.e('row')\">\n <td :colspan=\"leafColumns.length\">\n <slot name=\"empty\">\n <UEmpty :class=\"cls.e('empty')\" />\n </slot>\n </td>\n </tr>\n\n <slot></slot>\n </tbody>\n</template>\n\n<script lang=\"ts\" setup>\nimport { bem, setStyles } from '@veltra/utils'\nimport { computed, inject, shallowRef, watch } from 'vue'\n\nimport { UEmpty } from '../empty'\nimport { TableDIKey } from './di'\nimport { UTableRow, UExpandTableRow } from './table-row'\n\ndefineOptions({\n name: 'TableBody'\n})\n\nconst { cls, rows, virtualList, columnConfig, tableProps, virtualEnabled } = inject(TableDIKey)!\nconst { leafColumns } = columnConfig\n\nconst getStripeCls = computed(() => {\n return tableProps.stripe ? (index: number) => bem.is('stripe', index % 2 === 1) : () => ''\n})\n\nconst tableRows = computed(() => {\n if (!virtualEnabled.value) {\n return rows.value.map((row, index) => {\n return {\n row,\n stripeIndex: row.index,\n index\n }\n })\n }\n\n // 虚拟列表\n return virtualList.value.map((item) => {\n return {\n row: rows.value[item.index]!,\n stripeIndex: rows.value[item.index]!.index,\n index: item.index\n }\n })\n})\n\nconst bodyRef = shallowRef<HTMLElement>()\n\nfunction setBodyTransform(transformY: number) {\n bodyRef.value &&\n setStyles(bodyRef.value, {\n transform: `translate3d(0, ${transformY}px, 0)`\n })\n}\n\nwatch(virtualList, (list) => {\n setBodyTransform(list[0]?.start ?? 0)\n})\n\ndefineExpose({\n setBodyTransform\n})\n</script>\n"],"mappings":";;;;;;;;;;;EAqCA,MAAM,EAAE,KAAK,MAAM,aAAa,cAAc,YAAY,mBAAmB,OAAO,WAAW;EAC/F,MAAM,EAAE,gBAAgB;EAExB,MAAM,eAAe,eAAe;AAClC,UAAO,WAAW,UAAU,UAAkB,IAAI,GAAG,UAAU,QAAQ,MAAM,EAAE,SAAS;IACzF;EAED,MAAM,YAAY,eAAe;AAC/B,OAAI,CAAC,eAAe,MAClB,QAAO,KAAK,MAAM,KAAK,KAAK,UAAU;AACpC,WAAO;KACL;KACA,aAAa,IAAI;KACjB;KACF;KACD;AAIH,UAAO,YAAY,MAAM,KAAK,SAAS;AACrC,WAAO;KACL,KAAK,KAAK,MAAM,KAAK;KACrB,aAAa,KAAK,MAAM,KAAK,OAAQ;KACrC,OAAO,KAAK;KACd;KACD;IACF;EAED,MAAM,UAAU,YAAwB;EAExC,SAAS,iBAAiB,YAAoB;AAC5C,WAAQ,SACN,UAAU,QAAQ,OAAO,EACvB,WAAW,kBAAkB,WAAW,SACzC,CAAA;;AAGL,QAAM,cAAc,SAAS;AAC3B,oBAAiB,KAAK,IAAI,SAAS,EAAC;IACrC;AAED,WAAa,EACX,kBACD,CAAA;;uBA/EC,mBAqBQ,SAAA;IArBA,OAAK,eAAE,MAAA,IAAG,CAAC,EAAC,OAAA,CAAA;aAAc;IAAJ,KAAI;;sBAChC,mBAQW,UAAA,MAAA,WARqC,UAAA,QAAS,EAAtC,KAAK,OAAO,kBAAW;6DAAuB,IAAI,KAAA,EAAA,CAC5C,IAAI,eAAA,WAAA,EAA3B,YAAyE,MAAA,gBAAA,EAAA;;MAA3B;MAAM,cAAY;yDAChE,YAKE,MAAA,UAAA,EAAA;;MAHM;MACL,cAAY;MACZ,OAAK,eAAA,CAAG,MAAA,IAAG,CAAC,GAAE,WAAY,IAAI,UAAS,EAAG,aAAA,MAAa,YAAW,CAAA,CAAA;;;;;;;IAIvE,mBAAA,MAAU;KACC,MAAA,KAAI,CAAC,UAAA,WAAA,EAAhB,mBAMK,MAAA;;KANoB,OAAK,eAAE,MAAA,IAAG,CAAC,EAAC,MAAA,CAAA;QACnC,mBAIK,MAAA,EAJA,SAAS,MAAA,YAAW,CAAC,QAAA,EAAA,CACxB,WAEO,KAAA,QAAA,SAAA,EAAA,QAAA,CADL,YAAkC,MAAA,YAAA,EAAA,EAAzB,OAAK,eAAE,MAAA,IAAG,CAAC,EAAC,QAAA,CAAA,EAAA,EAAA,MAAA,GAAA,CAAA,QAAA,CAAA,CAAA,CAAA,CAAA,EAAA,GAAA,WAAA,CAAA,EAAA,EAAA,IAAA,mBAAA,QAAA,KAAA;IAK3B,WAAa,KAAA,QAAA,UAAA"}
1
+ {"version":3,"file":"table-body.js","names":[],"sources":["../../../src/components/table/table-body.vue"],"sourcesContent":["<template>\n <tbody :class=\"bodyCls\">\n <template v-for=\"{ row, index, stripeIndex } of tableRows\" :key=\"row.uid\">\n <UExpandTableRow v-if=\"row.isExpandRow\" :row=\"row\" :index=\"index\" />\n <UTableRow v-else :row=\"row\" :index=\"index\" :class=\"getStripeCls(stripeIndex)\" />\n </template>\n\n <!-- 空 -->\n <tr v-if=\"!rows.length\" :class=\"emptyRowCls\">\n <td :colspan=\"leafColumns.length\">\n <slot name=\"empty\">\n <UEmpty :class=\"emptyCls\" />\n </slot>\n </td>\n </tr>\n\n <slot></slot>\n </tbody>\n</template>\n\n<script lang=\"ts\" setup>\nimport { bem } from '@veltra/utils'\nimport { computed, inject } from 'vue'\n\nimport { UEmpty } from '../empty'\nimport { TableDIKey } from './di'\nimport { UTableRow, UExpandTableRow } from './table-row'\n\ndefineOptions({\n name: 'TableBody'\n})\n\nconst { cls, rows, virtualList, columnConfig, tableProps, virtualEnabled } = inject(TableDIKey)!\nconst { leafColumns } = columnConfig\n\n// A1 的同族优化:把 body / empty / empty-row 等静态 class 一次性取出,\n// 避免每次 render 触发 `cls.e` 的字符串拼接。\nconst bodyCls = cls.e('body')\nconst emptyRowCls = cls.e('row')\nconst emptyCls = cls.e('empty')\n\n/**\n * C1:stripe class 查找表。\n *\n * `bem.is('stripe', true) === 'is-stripe'`,`bem.is('stripe', false) === ''`。\n * 两种输出是全局常量,无需每次调用 `bem.is`;按奇偶直接查表即可。\n * 非 stripe 模式下两个位置均返回空串。\n */\nconst STRIPE_CLS_ON: readonly [string, string] = [bem.is('stripe', false), bem.is('stripe', true)]\nconst STRIPE_CLS_OFF: readonly [string, string] = ['', '']\n\nconst stripeTable = computed<readonly [string, string]>(() =>\n tableProps.stripe ? STRIPE_CLS_ON : STRIPE_CLS_OFF\n)\nconst getStripeCls = (index: number): string => stripeTable.value[index & 1]!\n\nconst tableRows = computed(() => {\n if (!virtualEnabled.value) {\n return rows.value.map((row, index) => {\n return {\n row,\n stripeIndex: row.index,\n index\n }\n })\n }\n\n // 虚拟列表:仅渲染可视窗口内的行,位置由 table.vue 中的 before/after 占位 tbody 撑开\n return virtualList.value.map((item) => {\n return {\n row: rows.value[item.index]!,\n stripeIndex: rows.value[item.index]!.index,\n index: item.index\n }\n })\n})\n</script>\n"],"mappings":";;;;;;;;;;;EAgCA,MAAM,EAAE,KAAK,MAAM,aAAa,cAAc,YAAY,mBAAmB,OAAO,WAAW;EAC/F,MAAM,EAAE,gBAAgB;EAIxB,MAAM,UAAU,IAAI,EAAE,OAAM;EAC5B,MAAM,cAAc,IAAI,EAAE,MAAK;EAC/B,MAAM,WAAW,IAAI,EAAE,QAAO;;;;;;;;EAS9B,MAAM,gBAA2C,CAAC,IAAI,GAAG,UAAU,MAAM,EAAE,IAAI,GAAG,UAAU,KAAK,CAAA;EACjG,MAAM,iBAA4C,CAAC,IAAI,GAAE;EAEzD,MAAM,cAAc,eAClB,WAAW,SAAS,gBAAgB,eACtC;EACA,MAAM,gBAAgB,UAA0B,YAAY,MAAM,QAAQ;EAE1E,MAAM,YAAY,eAAe;AAC/B,OAAI,CAAC,eAAe,MAClB,QAAO,KAAK,MAAM,KAAK,KAAK,UAAU;AACpC,WAAO;KACL;KACA,aAAa,IAAI;KACjB;KACF;KACD;AAIH,UAAO,YAAY,MAAM,KAAK,SAAS;AACrC,WAAO;KACL,KAAK,KAAK,MAAM,KAAK;KACrB,aAAa,KAAK,MAAM,KAAK,OAAQ;KACrC,OAAO,KAAK;KACd;KACD;IACF;;uBA1EC,mBAgBQ,SAAA,EAhBA,OAAK,eAAE,MAAA,QAAO,CAAA,EAAA,EAAA;sBACpB,mBAGW,UAAA,MAAA,WAHqC,UAAA,QAAS,EAAtC,KAAK,OAAO,kBAAW;6DAAuB,IAAI,KAAA,EAAA,CAC5C,IAAI,eAAA,WAAA,EAA3B,YAAoE,MAAA,gBAAA,EAAA;;MAAtB;MAAa;oDAC3D,YAAiF,MAAA,UAAA,EAAA;;MAAzD;MAAa;MAAQ,OAAK,eAAE,aAAa,YAAW,CAAA;;;;;;;IAG9E,mBAAA,MAAU;KACC,MAAA,KAAI,CAAC,UAAA,WAAA,EAAhB,mBAMK,MAAA;;KANoB,OAAK,eAAE,MAAA,YAAW,CAAA;QACzC,mBAIK,MAAA,EAJA,SAAS,MAAA,YAAW,CAAC,QAAA,EAAA,CACxB,WAEO,KAAA,QAAA,SAAA,EAAA,QAAA,CADL,YAA4B,MAAA,YAAA,EAAA,EAAnB,OAAK,eAAE,MAAA,SAAQ,CAAA,EAAA,EAAA,MAAA,GAAA,CAAA,QAAA,CAAA,CAAA,CAAA,CAAA,EAAA,GAAA,WAAA,CAAA,EAAA,EAAA,IAAA,mBAAA,QAAA,KAAA;IAK9B,WAAa,KAAA,QAAA,UAAA"}
@@ -1,5 +1,4 @@
1
- import { TableDIKey } from "./di.js";
2
- import { createCommentVNode, createElementBlock, defineComponent, inject, normalizeClass, normalizeStyle, openBlock, renderSlot, unref } from "vue";
1
+ import { computed, createCommentVNode, createElementBlock, defineComponent, normalizeClass, normalizeStyle, openBlock, renderSlot } from "vue";
3
2
  import { withUnit } from "@veltra/utils";
4
3
  //#region src/components/table/table-cell.vue
5
4
  const _hoisted_1 = ["rowspan", "colspan"];
@@ -7,22 +6,30 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
7
6
  name: "TableCell",
8
7
  __name: "table-cell",
9
8
  props: {
10
- column: {},
9
+ cellClass: {},
11
10
  left: {},
12
11
  right: {},
13
12
  rowspan: {},
14
13
  colspan: {}
15
14
  },
16
15
  setup(__props) {
17
- const { getCellClass } = inject(TableDIKey);
16
+ /**
17
+ * B2: TableCell 去 inject 化。
18
+ *
19
+ * 原先每个可见单元格都会执行 `inject(TableDIKey)` 并在模板中调用 `getCellClass(column)`,
20
+ * 在 30 列场景下每次滚动每行产生 30 次 inject / 30 次类名拼接。
21
+ * 父组件 `TableRow` 已经持有注入上下文,直接把 `cellClass` 传下来即可;
22
+ * 这里变成「完全受控」的纯渲染单元。
23
+ */
24
+ const style = computed(() => ({
25
+ left: withUnit(__props.left, "px"),
26
+ right: withUnit(__props.right, "px")
27
+ }));
18
28
  return (_ctx, _cache) => {
19
29
  return __props.rowspan !== 0 && __props.colspan !== 0 ? (openBlock(), createElementBlock("td", {
20
30
  key: 0,
21
- class: normalizeClass(unref(getCellClass)(__props.column)),
22
- style: normalizeStyle({
23
- left: unref(withUnit)(__props.left, "px"),
24
- right: unref(withUnit)(__props.right, "px")
25
- }),
31
+ class: normalizeClass(__props.cellClass),
32
+ style: normalizeStyle(style.value),
26
33
  rowspan: __props.rowspan,
27
34
  colspan: __props.colspan
28
35
  }, [renderSlot(_ctx.$slots, "default")], 14, _hoisted_1)) : createCommentVNode("v-if", true);
@@ -1 +1 @@
1
- {"version":3,"file":"table-cell.js","names":[],"sources":["../../../src/components/table/table-cell.vue"],"sourcesContent":["<template>\n <td\n :class=\"getCellClass(column)\"\n :style=\"{ left: withUnit(left, 'px'), right: withUnit(right, 'px') }\"\n :rowspan=\"rowspan\"\n :colspan=\"colspan\"\n v-if=\"rowspan !== 0 && colspan !== 0\"\n >\n <slot />\n </td>\n</template>\n\n<script lang=\"ts\" setup>\nimport { withUnit } from '@veltra/utils'\nimport { inject } from 'vue'\n\nimport { TableDIKey } from './di'\nimport type { ColumnNode } from './node/col'\n\ndefineOptions({\n name: 'TableCell'\n})\n\nconst { column } = defineProps<{\n column: ColumnNode\n left?: number\n right?: number\n rowspan?: number\n colspan?: number\n}>()\n\nconst { getCellClass } = inject(TableDIKey)!\n</script>\n"],"mappings":";;;;;;;;;;;;;;;;EA+BA,MAAM,EAAE,iBAAiB,OAAO,WAAW;;UAzBjC,QAAA,YAAO,KAAU,QAAA,YAAO,KAAA,WAAA,EALhC,mBAQK,MAAA;;IAPF,OAAK,eAAE,MAAA,aAAY,CAAC,QAAA,OAAM,CAAA;IAC1B,OAAK,eAAA;KAAA,MAAU,MAAA,SAAQ,CAAC,QAAA,MAAI,KAAA;KAAA,OAAgB,MAAA,SAAQ,CAAC,QAAA,OAAK,KAAA;KAAA,CAAA;IAC1D,SAAS,QAAA;IACT,SAAS,QAAA;OAGV,WAAQ,KAAA,QAAA,UAAA,CAAA,EAAA,IAAA,WAAA,IAAA,mBAAA,QAAA,KAAA"}
1
+ {"version":3,"file":"table-cell.js","names":[],"sources":["../../../src/components/table/table-cell.vue"],"sourcesContent":["<template>\n <td\n :class=\"cellClass\"\n :style=\"style\"\n :rowspan=\"rowspan\"\n :colspan=\"colspan\"\n v-if=\"rowspan !== 0 && colspan !== 0\"\n >\n <slot />\n </td>\n</template>\n\n<script lang=\"ts\" setup>\nimport { withUnit } from '@veltra/utils'\nimport { computed } from 'vue'\n\ndefineOptions({\n name: 'TableCell'\n})\n\n/**\n * B2: TableCell 去 inject 化。\n *\n * 原先每个可见单元格都会执行 `inject(TableDIKey)` 并在模板中调用 `getCellClass(column)`,\n * 在 30 列场景下每次滚动每行产生 30 次 inject / 30 次类名拼接。\n * 父组件 `TableRow` 已经持有注入上下文,直接把 `cellClass` 传下来即可;\n * 这里变成「完全受控」的纯渲染单元。\n */\nconst { left, right } = defineProps<{\n cellClass: string\n left?: number\n right?: number\n rowspan?: number\n colspan?: number\n}>()\n\nconst style = computed(() => ({\n left: withUnit(left, 'px'),\n right: withUnit(right, 'px')\n}))\n</script>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;EAoCA,MAAM,QAAQ,gBAAgB;GAC5B,MAAM,SAAS,QAAA,MAAM,KAAK;GAC1B,OAAO,SAAS,QAAA,OAAO,KAAI;GAC5B,EAAC;;UAjCQ,QAAA,YAAO,KAAU,QAAA,YAAO,KAAA,WAAA,EALhC,mBAQK,MAAA;;IAPF,OAAK,eAAE,QAAA,UAAS;IAChB,OAAK,eAAE,MAAA,MAAK;IACZ,SAAS,QAAA;IACT,SAAS,QAAA;OAGV,WAAQ,KAAA,QAAA,UAAA,CAAA,EAAA,IAAA,WAAA,IAAA,mBAAA,QAAA,KAAA"}