@veltra/desktop 1.2.4 → 1.2.6
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.
- package/dist/components/auto-complete/auto-complete.js +25 -13
- package/dist/components/auto-complete/auto-complete.js.map +1 -1
- package/dist/components/auto-complete/auto-complete.vue.d.ts +3 -2
- package/dist/components/batch-edit/batch-edit-form.js +33 -26
- package/dist/components/batch-edit/batch-edit-form.js.map +1 -1
- package/dist/components/batch-edit/batch-edit-list.js +4 -1
- package/dist/components/batch-edit/batch-edit-list.js.map +1 -1
- package/dist/components/batch-edit/batch-edit.js +29 -50
- package/dist/components/batch-edit/batch-edit.js.map +1 -1
- package/dist/components/batch-edit/batch-edit.vue.d.ts +3 -3
- package/dist/components/batch-edit/di.js.map +1 -1
- package/dist/components/batch-edit/style2.css +3 -0
- package/dist/components/batch-edit/use-edit.js +39 -71
- package/dist/components/batch-edit/use-edit.js.map +1 -1
- package/dist/components/batch-edit/use-features.js +38 -0
- package/dist/components/batch-edit/use-features.js.map +1 -0
- package/dist/components/cascade/cascade.vue.d.ts +1 -1
- package/dist/components/contextmenu/style2.css +7 -7
- package/dist/components/dual-nav/dual-nav-app.js +70 -0
- package/dist/components/dual-nav/dual-nav-app.js.map +1 -0
- package/dist/components/dual-nav/dual-nav.js +128 -0
- package/dist/components/dual-nav/dual-nav.js.map +1 -0
- package/dist/components/dual-nav/dual-nav.vue.d.ts +13 -0
- package/dist/components/dual-nav/helper.js +21 -0
- package/dist/components/dual-nav/helper.js.map +1 -0
- package/dist/components/dual-nav/index.d.ts +1 -0
- package/dist/components/dual-nav/style.js +5 -0
- package/dist/components/dual-nav/style2.css +174 -0
- package/dist/components/index.d.ts +23 -22
- package/dist/components/index.js +28 -26
- package/dist/components/index.js.map +1 -1
- package/dist/components/loading/loading.js +1 -1
- package/dist/components/loading/loading.js.map +1 -1
- package/dist/components/loading/style2.css +61 -81
- package/dist/components/nav/di.js +7 -0
- package/dist/components/nav/di.js.map +1 -0
- package/dist/components/nav/helper.js +18 -0
- package/dist/components/nav/helper.js.map +1 -0
- package/dist/components/nav/index.d.ts +3 -0
- package/dist/components/{menu/menu-icon.js → nav/nav-icon.js} +4 -4
- package/dist/components/nav/nav-icon.js.map +1 -0
- package/dist/components/{menu/menu-item-collapsed.js → nav/nav-item-collapsed.js} +23 -23
- package/dist/components/nav/nav-item-collapsed.js.map +1 -0
- package/dist/components/{menu/menu-item.js → nav/nav-item.js} +13 -13
- package/dist/components/nav/nav-item.js.map +1 -0
- package/dist/components/{menu/menu-item.vue.d.ts → nav/nav-item.vue.d.ts} +4 -4
- package/dist/components/{menu/menu-sub-collapsed.js → nav/nav-sub-collapsed.js} +19 -19
- package/dist/components/nav/nav-sub-collapsed.js.map +1 -0
- package/dist/components/{menu/menu-sub.js → nav/nav-sub.js} +24 -24
- package/dist/components/nav/nav-sub.js.map +1 -0
- package/dist/components/{menu/menu-sub.vue.d.ts → nav/nav-sub.vue.d.ts} +4 -4
- package/dist/components/{menu/menu.js → nav/nav.js} +45 -36
- package/dist/components/nav/nav.js.map +1 -0
- package/dist/components/nav/nav.vue.d.ts +18 -0
- package/dist/components/nav/style.d.ts +1 -0
- package/dist/components/{menu → nav}/style2.css +105 -105
- package/dist/components/{menu/use-menu-item.js → nav/use-nav-item.js} +11 -11
- package/dist/components/nav/use-nav-item.js.map +1 -0
- package/dist/components/{menu/walk-menu-path.js → nav/walk-nav-path.js} +5 -5
- package/dist/components/nav/walk-nav-path.js.map +1 -0
- package/dist/components/number/number.vue.d.ts +1 -1
- package/dist/components/select/style2.css +4 -4
- package/dist/components/steps/steps.vue.d.ts +2 -2
- package/dist/components/tabs/tabs-horizontal.vue.d.ts +2 -2
- package/dist/components/tabs/tabs-vertical.vue.d.ts +2 -2
- package/dist/components/tabs/tabs.vue.d.ts +2 -2
- package/dist/components/watermark/watermark.vue.d.ts +1 -1
- package/dist/index.d.ts +63 -61
- package/dist/index.js +56 -55
- package/dist/style.js +2 -1
- package/dist/types/auto-complete.d.ts +6 -1
- package/dist/types/batch-edit.d.ts +15 -2
- package/dist/types/dual-nav.d.ts +27 -0
- package/dist/types/index.d.ts +4 -3
- package/dist/types/loading.d.ts +1 -1
- package/dist/types/nav.d.ts +48 -0
- package/package.json +6 -6
- package/src/components/auto-complete/auto-complete.vue +24 -13
- package/src/components/batch-edit/batch-edit-form.vue +29 -18
- package/src/components/batch-edit/batch-edit-list.vue +6 -1
- package/src/components/batch-edit/batch-edit.vue +36 -73
- package/src/components/batch-edit/di.ts +3 -1
- package/src/components/batch-edit/style.scss +5 -0
- package/src/components/batch-edit/use-edit.ts +63 -116
- package/src/components/batch-edit/use-features.ts +58 -0
- package/src/components/contextmenu/style.scss +5 -5
- package/src/components/dual-nav/dual-nav-app.vue +61 -0
- package/src/components/dual-nav/dual-nav.vue +156 -0
- package/src/components/dual-nav/helper.ts +25 -0
- package/src/components/dual-nav/index.ts +1 -0
- package/src/components/dual-nav/style.scss +188 -0
- package/src/components/dual-nav/style.ts +5 -0
- package/src/components/index.ts +3 -1
- package/src/components/loading/loading.vue +1 -1
- package/src/components/loading/style.scss +68 -104
- package/src/components/nav/di.ts +17 -0
- package/src/components/nav/helper.ts +22 -0
- package/src/components/nav/index.ts +3 -0
- package/src/components/{menu/menu-icon.vue → nav/nav-icon.vue} +1 -1
- package/src/components/nav/nav-item-collapsed.vue +66 -0
- package/src/components/nav/nav-item.vue +36 -0
- package/src/components/{menu/menu-sub-collapsed.vue → nav/nav-sub-collapsed.vue} +15 -15
- package/src/components/{menu/menu-sub.vue → nav/nav-sub.vue} +19 -19
- package/src/components/{menu/menu.vue → nav/nav.vue} +42 -42
- package/src/components/{menu → nav}/style.scss +16 -14
- package/src/components/{menu/use-menu-item.ts → nav/use-nav-item.ts} +14 -14
- package/src/components/{menu/walk-menu-path.ts → nav/walk-nav-path.ts} +2 -2
- package/src/components/select/style.scss +4 -4
- package/src/style.ts +2 -1
- package/src/types/auto-complete.ts +6 -1
- package/src/types/batch-edit.ts +18 -1
- package/src/types/dual-nav.ts +28 -0
- package/src/types/index.ts +2 -1
- package/src/types/loading.ts +1 -1
- package/src/types/nav.ts +49 -0
- package/dist/components/menu/di.js +0 -7
- package/dist/components/menu/di.js.map +0 -1
- package/dist/components/menu/helper.js +0 -8
- package/dist/components/menu/helper.js.map +0 -1
- package/dist/components/menu/index.d.ts +0 -3
- package/dist/components/menu/menu-icon.js.map +0 -1
- package/dist/components/menu/menu-item-collapsed.js.map +0 -1
- package/dist/components/menu/menu-item.js.map +0 -1
- package/dist/components/menu/menu-sub-collapsed.js.map +0 -1
- package/dist/components/menu/menu-sub.js.map +0 -1
- package/dist/components/menu/menu.js.map +0 -1
- package/dist/components/menu/menu.vue.d.ts +0 -14
- package/dist/components/menu/use-menu-item.js.map +0 -1
- package/dist/components/menu/walk-menu-path.js.map +0 -1
- package/dist/types/menu.d.ts +0 -40
- package/src/components/menu/di.ts +0 -17
- package/src/components/menu/helper.ts +0 -3
- package/src/components/menu/index.ts +0 -3
- package/src/components/menu/menu-item-collapsed.vue +0 -66
- package/src/components/menu/menu-item.vue +0 -36
- package/src/components/menu/menu-node.ts +0 -6
- package/src/types/menu.ts +0 -41
- /package/dist/components/{menu → dual-nav}/style.d.ts +0 -0
- /package/dist/components/{menu → nav}/style.js +0 -0
- /package/src/components/{menu → nav}/style.ts +0 -0
|
@@ -22,6 +22,10 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
22
22
|
type: Boolean,
|
|
23
23
|
default: true
|
|
24
24
|
},
|
|
25
|
+
allowCustom: {
|
|
26
|
+
type: Boolean,
|
|
27
|
+
default: true
|
|
28
|
+
},
|
|
25
29
|
tips: {},
|
|
26
30
|
span: {},
|
|
27
31
|
label: {},
|
|
@@ -41,7 +45,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
41
45
|
"modelModifiers": {}
|
|
42
46
|
}),
|
|
43
47
|
emits: /* @__PURE__ */ mergeModels(["update:modelValue", "select"], ["update:modelValue"]),
|
|
44
|
-
setup(__props, { emit: __emit }) {
|
|
48
|
+
setup(__props, { expose: __expose, emit: __emit }) {
|
|
45
49
|
const props = __props;
|
|
46
50
|
const emit = __emit;
|
|
47
51
|
const slots = useSlots();
|
|
@@ -67,9 +71,13 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
67
71
|
props,
|
|
68
72
|
model
|
|
69
73
|
});
|
|
74
|
+
const displayCachedSuggestion = computed(() => {
|
|
75
|
+
if (!props.allowCustom) return void 0;
|
|
76
|
+
return cachedSuggestion.value;
|
|
77
|
+
});
|
|
70
78
|
const keyboardOptions = computed(() => {
|
|
71
79
|
const currentSuggestions = suggestions.value;
|
|
72
|
-
return
|
|
80
|
+
return displayCachedSuggestion.value ? [displayCachedSuggestion.value, ...currentSuggestions] : currentSuggestions;
|
|
73
81
|
});
|
|
74
82
|
const { point, handleKeydown } = useKeyboard({
|
|
75
83
|
options: keyboardOptions,
|
|
@@ -83,23 +91,23 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
83
91
|
return 0;
|
|
84
92
|
},
|
|
85
93
|
onSelect: (option, index) => {
|
|
86
|
-
if (
|
|
94
|
+
if (displayCachedSuggestion.value && index === 0) {
|
|
87
95
|
handleSelectCachedOption(option);
|
|
88
96
|
return;
|
|
89
97
|
}
|
|
90
98
|
handleSelect(option);
|
|
91
99
|
}
|
|
92
100
|
});
|
|
93
|
-
const isCachedActive = computed(() => !!
|
|
101
|
+
const isCachedActive = computed(() => !!displayCachedSuggestion.value && point.value === 0);
|
|
94
102
|
const isActiveOption = (index) => {
|
|
95
|
-
const offset =
|
|
103
|
+
const offset = displayCachedSuggestion.value ? 1 : 0;
|
|
96
104
|
return point.value === index + offset;
|
|
97
105
|
};
|
|
98
106
|
const handleInputKeydown = (event) => {
|
|
99
|
-
if (!dropdownVisible.value && event.key === "Enter" &&
|
|
107
|
+
if (!dropdownVisible.value && event.key === "Enter" && displayCachedSuggestion.value) {
|
|
100
108
|
event.preventDefault();
|
|
101
109
|
event.stopPropagation();
|
|
102
|
-
handleSelectCachedOption(
|
|
110
|
+
handleSelectCachedOption(displayCachedSuggestion.value);
|
|
103
111
|
return;
|
|
104
112
|
}
|
|
105
113
|
handleKeydown(event);
|
|
@@ -126,6 +134,10 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
126
134
|
appendedSuggestions.value = [...appendedSuggestions.value, cachedOption];
|
|
127
135
|
dropdownRef.value?.close();
|
|
128
136
|
};
|
|
137
|
+
__expose({
|
|
138
|
+
open: () => dropdownRef.value?.open(),
|
|
139
|
+
close: () => dropdownRef.value?.close()
|
|
140
|
+
});
|
|
129
141
|
return (_ctx, _cache) => {
|
|
130
142
|
return !unref(readonly) ? (openBlock(), createBlock(unref(_sfc_main$2), {
|
|
131
143
|
key: 0,
|
|
@@ -171,15 +183,15 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
171
183
|
ref_key: "scrollRef",
|
|
172
184
|
ref: scrollRef
|
|
173
185
|
}, {
|
|
174
|
-
default: withCtx(() => [
|
|
186
|
+
default: withCtx(() => [displayCachedSuggestion.value ? withDirectives((openBlock(), createElementBlock("li", {
|
|
175
187
|
class: normalizeClass([unref(optionClass), unref(bem).is("active", isCachedActive.value)]),
|
|
176
|
-
onClick: _cache[1] || (_cache[1] = ($event) => handleSelectCachedOption(
|
|
177
|
-
"data-key":
|
|
178
|
-
key:
|
|
188
|
+
onClick: _cache[1] || (_cache[1] = ($event) => handleSelectCachedOption(displayCachedSuggestion.value)),
|
|
189
|
+
"data-key": displayCachedSuggestion.value,
|
|
190
|
+
key: displayCachedSuggestion.value
|
|
179
191
|
}, [renderSlot(_ctx.$slots, "default", normalizeProps(guardReactiveProps({
|
|
180
|
-
option:
|
|
192
|
+
option: displayCachedSuggestion.value,
|
|
181
193
|
index: -1
|
|
182
|
-
})), () => [createTextVNode(toDisplayString(
|
|
194
|
+
})), () => [createTextVNode(toDisplayString(displayCachedSuggestion.value), 1)])], 10, _hoisted_1)), [[unref(vRipple), unref(cls).e("ripple")]]) : createCommentVNode("v-if", true), (openBlock(true), createElementBlock(Fragment, null, renderList(unref(suggestions), (option, index) => {
|
|
183
195
|
return withDirectives((openBlock(), createElementBlock("li", {
|
|
184
196
|
class: normalizeClass([
|
|
185
197
|
unref(optionClass),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auto-complete.js","names":[],"sources":["../../../src/components/auto-complete/auto-complete.vue"],"sourcesContent":["<template>\n <u-dropdown\n v-if=\"!readonly\"\n trigger=\"click\"\n :class=\"[cls.b, cls.m(size), bem.is('disabled', disabled)]\"\n ref=\"dropdownRef\"\n v-model:visible=\"dropdownVisible\"\n :content-class=\"[cls.e('panel'), cls.em('panel', size)]\"\n :disabled=\"disabled\"\n >\n <!-- 触发 -->\n <template #trigger>\n <!-- 单选 -->\n <u-input\n :size=\"size\"\n :disabled=\"disabled\"\n :placeholder=\"placeholder\"\n :clearable=\"clearable\"\n v-model=\"model\"\n @keydown=\"handleInputKeydown\"\n >\n <template #suffix v-if=\"slots.suffix\">\n <slot name=\"suffix\" />\n </template>\n\n <template #prefix v-if=\"slots.prefix\">\n <slot name=\"prefix\" />\n </template>\n </u-input>\n </template>\n\n <!-- 下拉内容 -->\n <template #content>\n <u-scroll tag=\"ul\" :class=\"cls.e('options')\" ref=\"scrollRef\">\n <li\n v-if=\"cachedSuggestion\"\n :class=\"[optionClass, bem.is('active', isCachedActive)]\"\n @click=\"handleSelectCachedOption(cachedSuggestion)\"\n v-ripple=\"cls.e('ripple')\"\n :data-key=\"cachedSuggestion\"\n :key=\"cachedSuggestion\"\n >\n <slot v-bind=\"{ option: cachedSuggestion, index: -1 }\">\n {{ cachedSuggestion }}\n </slot>\n </li>\n\n <li\n v-for=\"(option, index) of suggestions\"\n :class=\"[\n optionClass,\n bem.is('selected', option === model),\n bem.is('active', isActiveOption(index))\n ]\"\n @click=\"handleSelect(option)\"\n v-ripple=\"cls.e('ripple')\"\n :data-key=\"option\"\n :key=\"option\"\n >\n <slot v-bind=\"{ option, index }\">\n {{ option }}\n </slot>\n </li>\n </u-scroll>\n </template>\n </u-dropdown>\n\n <template v-else>\n {{ model || FORM_EMPTY_CONTENT }}\n </template>\n</template>\n\n<script lang=\"ts\" setup>\nimport { useFormFallbackProps } from '@veltra/compositions'\nimport { vRipple } from '@veltra/directives'\nimport { bem, FORM_EMPTY_CONTENT, scrollIntoContainerView } from '@veltra/utils'\nimport { injectFormContext } from '@veltra/utils'\nimport { computed, shallowRef, watch } from 'vue'\n\nimport type { AutoCompleteEmits, AutoCompleteProps, _AutoCompleteExposed } from '../../types'\nimport type { DropdownExposed, ScrollExposed } from '../../types'\nimport { UDropdown } from '../dropdown'\nimport { UInput } from '../input'\nimport { UScroll } from '../scroll'\nimport { useKeyboard } from './use-keyboard'\nimport { useSuggestions } from './use-suggestions'\n\ndefineOptions({ name: 'AutoComplete', inheritAttrs: false })\n\nconst props = withDefaults(defineProps<AutoCompleteProps>(), {\n placeholder: '请输入',\n clearable: true,\n disabled: undefined,\n readonly: undefined\n})\n\nconst emit = defineEmits<AutoCompleteEmits>()\n\nconst slots = defineSlots<{\n default?: (props: { option: string; index: number }) => any\n suffix?: () => any\n prefix?: () => any\n}>()\n\n// 当前输入框的值\nconst model = defineModel<string>()\n\nconst cls = bem('auto-complete')\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 dropdownRef = shallowRef<DropdownExposed>()\nconst dropdownVisible = shallowRef(false)\nconst scrollRef = shallowRef<ScrollExposed>()\n\nwatch(scrollRef, (scroll) => {\n if (scroll && model.value !== undefined) {\n const li = scroll.contentRef!.querySelector(`li[data-key=\"${model.value}\"]`) as HTMLElement\n li && scrollIntoContainerView(li, scroll.containerRef ?? null)\n }\n})\n\nconst { suggestions, appendedSuggestions, cachedSuggestion } = useSuggestions({ props, model })\n\nconst keyboardOptions = computed(() => {\n const currentSuggestions = suggestions.value\n return cachedSuggestion.value\n ? [cachedSuggestion.value, ...currentSuggestions]\n : currentSuggestions\n})\n\nconst { point, handleKeydown } = useKeyboard({\n options: keyboardOptions,\n dropdownVisible,\n getDefaultIndex: (options) => {\n if (!options.length) return -1\n if (model.value) {\n const matchIndex = options.indexOf(model.value)\n if (matchIndex > -1) return matchIndex\n }\n return 0\n },\n onSelect: (option, index) => {\n if (cachedSuggestion.value && index === 0) {\n handleSelectCachedOption(option)\n return\n }\n handleSelect(option)\n }\n})\n\nconst isCachedActive = computed(() => !!cachedSuggestion.value && point.value === 0)\n\nconst isActiveOption = (index: number) => {\n const offset = cachedSuggestion.value ? 1 : 0\n return point.value === index + offset\n}\n\nconst handleInputKeydown = (event: KeyboardEvent) => {\n if (!dropdownVisible.value && event.key === 'Enter' && cachedSuggestion.value) {\n event.preventDefault()\n event.stopPropagation()\n handleSelectCachedOption(cachedSuggestion.value)\n return\n }\n handleKeydown(event)\n}\n\nwatch([point, keyboardOptions], ([currentPoint, options]) => {\n if (!scrollRef.value || currentPoint < 0) return\n const currentOption = options[currentPoint]\n if (!currentOption) return\n const target = scrollRef.value.contentRef?.querySelector(\n `li[data-key=\"${currentOption}\"]`\n ) as HTMLElement | null\n if (target) {\n scrollIntoContainerView(target, scrollRef.value.containerRef ?? null)\n }\n})\n\n/** 选中选项 */\nconst handleSelect = (option: string) => {\n model.value = option\n dropdownRef.value?.close()\n saveCache()\n emit('select', option)\n}\n\nfunction saveCache() {\n if (!model.value) return\n appendedSuggestions.value = [...appendedSuggestions.value, model.value]\n}\n\nconst handleSelectCachedOption = (cachedOption: string) => {\n appendedSuggestions.value = [...appendedSuggestions.value, cachedOption]\n dropdownRef.value?.close()\n}\n</script>\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"auto-complete.js","names":[],"sources":["../../../src/components/auto-complete/auto-complete.vue"],"sourcesContent":["<template>\n <u-dropdown\n v-if=\"!readonly\"\n trigger=\"click\"\n :class=\"[cls.b, cls.m(size), bem.is('disabled', disabled)]\"\n ref=\"dropdownRef\"\n v-model:visible=\"dropdownVisible\"\n :content-class=\"[cls.e('panel'), cls.em('panel', size)]\"\n :disabled=\"disabled\"\n >\n <!-- 触发 -->\n <template #trigger>\n <!-- 单选 -->\n <u-input\n :size=\"size\"\n :disabled=\"disabled\"\n :placeholder=\"placeholder\"\n :clearable=\"clearable\"\n v-model=\"model\"\n @keydown=\"handleInputKeydown\"\n >\n <template #suffix v-if=\"slots.suffix\">\n <slot name=\"suffix\" />\n </template>\n\n <template #prefix v-if=\"slots.prefix\">\n <slot name=\"prefix\" />\n </template>\n </u-input>\n </template>\n\n <!-- 下拉内容 -->\n <template #content>\n <u-scroll tag=\"ul\" :class=\"cls.e('options')\" ref=\"scrollRef\">\n <li\n v-if=\"displayCachedSuggestion\"\n :class=\"[optionClass, bem.is('active', isCachedActive)]\"\n @click=\"handleSelectCachedOption(displayCachedSuggestion)\"\n v-ripple=\"cls.e('ripple')\"\n :data-key=\"displayCachedSuggestion\"\n :key=\"displayCachedSuggestion\"\n >\n <slot v-bind=\"{ option: displayCachedSuggestion, index: -1 }\">\n {{ displayCachedSuggestion }}\n </slot>\n </li>\n\n <li\n v-for=\"(option, index) of suggestions\"\n :class=\"[\n optionClass,\n bem.is('selected', option === model),\n bem.is('active', isActiveOption(index))\n ]\"\n @click=\"handleSelect(option)\"\n v-ripple=\"cls.e('ripple')\"\n :data-key=\"option\"\n :key=\"option\"\n >\n <slot v-bind=\"{ option, index }\">\n {{ option }}\n </slot>\n </li>\n </u-scroll>\n </template>\n </u-dropdown>\n\n <template v-else>\n {{ model || FORM_EMPTY_CONTENT }}\n </template>\n</template>\n\n<script lang=\"ts\" setup>\nimport { useFormFallbackProps } from '@veltra/compositions'\nimport { vRipple } from '@veltra/directives'\nimport { bem, FORM_EMPTY_CONTENT, scrollIntoContainerView } from '@veltra/utils'\nimport { injectFormContext } from '@veltra/utils'\nimport { computed, shallowRef, watch } from 'vue'\n\nimport type { AutoCompleteEmits, AutoCompleteProps, _AutoCompleteExposed } from '../../types'\nimport type { DropdownExposed, ScrollExposed } from '../../types'\nimport { UDropdown } from '../dropdown'\nimport { UInput } from '../input'\nimport { UScroll } from '../scroll'\nimport { useKeyboard } from './use-keyboard'\nimport { useSuggestions } from './use-suggestions'\n\ndefineOptions({ name: 'AutoComplete', inheritAttrs: false })\n\nconst props = withDefaults(defineProps<AutoCompleteProps>(), {\n placeholder: '请输入',\n clearable: true,\n allowCustom: true,\n disabled: undefined,\n readonly: undefined\n})\n\nconst emit = defineEmits<AutoCompleteEmits>()\n\nconst slots = defineSlots<{\n default?: (props: { option: string; index: number }) => any\n suffix?: () => any\n prefix?: () => any\n}>()\n\n// 当前输入框的值\nconst model = defineModel<string>()\n\nconst cls = bem('auto-complete')\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 dropdownRef = shallowRef<DropdownExposed>()\nconst dropdownVisible = shallowRef(false)\nconst scrollRef = shallowRef<ScrollExposed>()\n\nwatch(scrollRef, (scroll) => {\n if (scroll && model.value !== undefined) {\n const li = scroll.contentRef!.querySelector(`li[data-key=\"${model.value}\"]`) as HTMLElement\n li && scrollIntoContainerView(li, scroll.containerRef ?? null)\n }\n})\n\nconst { suggestions, appendedSuggestions, cachedSuggestion } = useSuggestions({ props, model })\n\nconst displayCachedSuggestion = computed(() => {\n if (!props.allowCustom) return undefined\n return cachedSuggestion.value\n})\n\nconst keyboardOptions = computed(() => {\n const currentSuggestions = suggestions.value\n return displayCachedSuggestion.value\n ? [displayCachedSuggestion.value, ...currentSuggestions]\n : currentSuggestions\n})\n\nconst { point, handleKeydown } = useKeyboard({\n options: keyboardOptions,\n dropdownVisible,\n getDefaultIndex: (options) => {\n if (!options.length) return -1\n if (model.value) {\n const matchIndex = options.indexOf(model.value)\n if (matchIndex > -1) return matchIndex\n }\n return 0\n },\n onSelect: (option, index) => {\n if (displayCachedSuggestion.value && index === 0) {\n handleSelectCachedOption(option)\n return\n }\n handleSelect(option)\n }\n})\n\nconst isCachedActive = computed(() => !!displayCachedSuggestion.value && point.value === 0)\n\nconst isActiveOption = (index: number) => {\n const offset = displayCachedSuggestion.value ? 1 : 0\n return point.value === index + offset\n}\n\nconst handleInputKeydown = (event: KeyboardEvent) => {\n if (!dropdownVisible.value && event.key === 'Enter' && displayCachedSuggestion.value) {\n event.preventDefault()\n event.stopPropagation()\n handleSelectCachedOption(displayCachedSuggestion.value)\n return\n }\n handleKeydown(event)\n}\n\nwatch([point, keyboardOptions], ([currentPoint, options]) => {\n if (!scrollRef.value || currentPoint < 0) return\n const currentOption = options[currentPoint]\n if (!currentOption) return\n const target = scrollRef.value.contentRef?.querySelector(\n `li[data-key=\"${currentOption}\"]`\n ) as HTMLElement | null\n if (target) {\n scrollIntoContainerView(target, scrollRef.value.containerRef ?? null)\n }\n})\n\n/** 选中选项 */\nconst handleSelect = (option: string) => {\n model.value = option\n dropdownRef.value?.close()\n saveCache()\n emit('select', option)\n}\n\nfunction saveCache() {\n if (!model.value) return\n appendedSuggestions.value = [...appendedSuggestions.value, model.value]\n}\n\nconst handleSelectCachedOption = (cachedOption: string) => {\n appendedSuggestions.value = [...appendedSuggestions.value, cachedOption]\n dropdownRef.value?.close()\n}\n\ndefineExpose<_AutoCompleteExposed>({\n open: () => dropdownRef.value?.open(),\n close: () => dropdownRef.value?.close()\n})\n</script>\n"],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AutoCompleteProps } from "../../types/auto-complete.js";
|
|
1
|
+
import { AutoCompleteProps, _AutoCompleteExposed } from "../../types/auto-complete.js";
|
|
2
2
|
//#region src/components/auto-complete/auto-complete.vue.d.ts
|
|
3
3
|
type __VLS_Props = AutoCompleteProps;
|
|
4
4
|
type __VLS_Slots = {
|
|
@@ -13,7 +13,7 @@ type __VLS_ModelProps = {
|
|
|
13
13
|
modelValue?: string;
|
|
14
14
|
};
|
|
15
15
|
type __VLS_PublicProps = __VLS_Props & __VLS_ModelProps;
|
|
16
|
-
declare const __VLS_base: import("vue").DefineComponent<__VLS_PublicProps,
|
|
16
|
+
declare const __VLS_base: import("vue").DefineComponent<__VLS_PublicProps, _AutoCompleteExposed, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
17
17
|
"update:modelValue": (value: string | undefined) => any;
|
|
18
18
|
} & {
|
|
19
19
|
"update:modelValue": (value: string) => any;
|
|
@@ -26,6 +26,7 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_PublicProps, {}, {
|
|
|
26
26
|
clearable: boolean;
|
|
27
27
|
disabled: boolean;
|
|
28
28
|
readonly: boolean;
|
|
29
|
+
allowCustom: boolean;
|
|
29
30
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
30
31
|
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
31
32
|
declare const _default: typeof __VLS_export;
|
|
@@ -12,7 +12,9 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
12
12
|
name: "BatchEditForm",
|
|
13
13
|
__name: "batch-edit-form",
|
|
14
14
|
setup(__props, { expose: __expose }) {
|
|
15
|
-
const
|
|
15
|
+
const batchEditCtx = inject(BatchEditDIKey);
|
|
16
|
+
const { cls, props, state, insertIndexes, handleSave, handleClose, staticFeatures, dynamicFeatures } = batchEditCtx;
|
|
17
|
+
const focused = toRef(batchEditCtx, "focused");
|
|
16
18
|
const formComponentRef = shallowRef();
|
|
17
19
|
__expose({
|
|
18
20
|
el: toRef(() => formComponentRef.value?.el),
|
|
@@ -26,6 +28,13 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
26
28
|
const updatable = computed(() => {
|
|
27
29
|
return state.type === "update" && (staticFeatures.value.has("update") || dynamicFeatures.value.update?.(state.row));
|
|
28
30
|
});
|
|
31
|
+
const isQuick = computed(() => props.mode === "quick");
|
|
32
|
+
const isNormal = computed(() => props.mode !== "quick");
|
|
33
|
+
const isQuickUpdate = computed(() => isQuick.value && state.type === "update");
|
|
34
|
+
const formModel = computed(() => {
|
|
35
|
+
if (isQuick.value && state.type === "update" && state.row) return state.row.data;
|
|
36
|
+
return props.model;
|
|
37
|
+
});
|
|
29
38
|
const headerInfo = computed(() => {
|
|
30
39
|
if (props.readonly) return {
|
|
31
40
|
icon: View,
|
|
@@ -55,14 +64,8 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
55
64
|
const bodyKey = computed(() => {
|
|
56
65
|
return `${state.type}-${state.row?.uid ?? "create"}-${state.parentRow?.uid ?? "root"}`;
|
|
57
66
|
});
|
|
58
|
-
function handleFormKeydown(e) {
|
|
59
|
-
if ((e.metaKey || e.ctrlKey) && e.key === "Enter") {
|
|
60
|
-
e.preventDefault();
|
|
61
|
-
handleSave();
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
67
|
return (_ctx, _cache) => {
|
|
65
|
-
return unref(state).visible &&
|
|
68
|
+
return unref(state).visible && formModel.value ? (openBlock(), createElementBlock("aside", {
|
|
66
69
|
key: 0,
|
|
67
70
|
class: normalizeClass(unref(cls).e("form"))
|
|
68
71
|
}, [
|
|
@@ -102,9 +105,8 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
102
105
|
default: withCtx(() => [createVNode(unref(form_default), {
|
|
103
106
|
ref_key: "formComponentRef",
|
|
104
107
|
ref: formComponentRef,
|
|
105
|
-
model:
|
|
108
|
+
model: formModel.value,
|
|
106
109
|
readonly: unref(props).readonly,
|
|
107
|
-
onKeydown: handleFormKeydown,
|
|
108
110
|
"label-width": unref(props).labelWidth
|
|
109
111
|
}, {
|
|
110
112
|
default: withCtx(() => [renderSlot(_ctx.$slots, "default", normalizeProps(guardReactiveProps({
|
|
@@ -123,46 +125,51 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
123
125
|
})]),
|
|
124
126
|
_: 3
|
|
125
127
|
}, 8, ["class"])),
|
|
126
|
-
createElementVNode("footer", { class: normalizeClass(unref(cls).e("form-footer")) }, [
|
|
128
|
+
createElementVNode("footer", { class: normalizeClass(unref(cls).e("form-footer")) }, [unref(props).readonly ? (openBlock(), createElementBlock("span", {
|
|
127
129
|
key: 0,
|
|
128
130
|
class: normalizeClass(unref(cls).e("form-hint"))
|
|
129
|
-
}, "
|
|
131
|
+
}, "只读模式", 2)) : isQuickUpdate.value ? (openBlock(), createElementBlock("span", {
|
|
130
132
|
key: 1,
|
|
131
133
|
class: normalizeClass(unref(cls).e("form-hint"))
|
|
132
|
-
}, [
|
|
134
|
+
}, [_cache[3] || (_cache[3] = createTextVNode(" 实时编辑 ", -1)), createElementVNode("span", { class: normalizeClass({ [unref(bem).is("concealed")]: !focused.value }) }, [
|
|
135
|
+
_cache[1] || (_cache[1] = createTextVNode(" · ", -1)),
|
|
133
136
|
createVNode(unref(_sfc_main$4), null, {
|
|
134
|
-
default: withCtx(() => [..._cache[0] || (_cache[0] = [createTextVNode("
|
|
137
|
+
default: withCtx(() => [..._cache[0] || (_cache[0] = [createTextVNode("Esc", -1)])]),
|
|
135
138
|
_: 1
|
|
136
139
|
}),
|
|
137
|
-
_cache[2] || (_cache[2] = createTextVNode("
|
|
140
|
+
_cache[2] || (_cache[2] = createTextVNode(" 关闭", -1))
|
|
141
|
+
], 2)], 2)) : (openBlock(), createElementBlock("span", {
|
|
142
|
+
key: 2,
|
|
143
|
+
class: normalizeClass(unref(cls).e("form-hint"))
|
|
144
|
+
}, [createElementVNode("span", { class: normalizeClass({ [unref(bem).is("concealed")]: !focused.value }) }, [
|
|
138
145
|
createVNode(unref(_sfc_main$4), null, {
|
|
139
|
-
default: withCtx(() => [..._cache[
|
|
146
|
+
default: withCtx(() => [..._cache[4] || (_cache[4] = [createTextVNode("Ctrl + S", -1)])]),
|
|
140
147
|
_: 1
|
|
141
148
|
}),
|
|
142
|
-
_cache[
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
149
|
+
_cache[6] || (_cache[6] = createTextVNode(" 保存 · ", -1)),
|
|
150
|
+
createVNode(unref(_sfc_main$4), null, {
|
|
151
|
+
default: withCtx(() => [..._cache[5] || (_cache[5] = [createTextVNode("Esc", -1)])]),
|
|
152
|
+
_: 1
|
|
153
|
+
}),
|
|
154
|
+
_cache[7] || (_cache[7] = createTextVNode(" 关闭 ", -1))
|
|
155
|
+
], 2)], 2)), createElementVNode("div", { class: normalizeClass(unref(cls).e("form-actions")) }, [createVNode(unref(_sfc_main$3), {
|
|
147
156
|
text: "",
|
|
148
157
|
loading: unref(state).loading,
|
|
149
158
|
onClick: unref(handleClose)
|
|
150
159
|
}, {
|
|
151
|
-
default: withCtx(() => [..._cache[
|
|
160
|
+
default: withCtx(() => [..._cache[8] || (_cache[8] = [createTextVNode(" 取消 ", -1)])]),
|
|
152
161
|
_: 1
|
|
153
|
-
}, 8, ["loading", "onClick"]), !unref(props).readonly && (creatable.value || updatable.value) ? (openBlock(), createBlock(unref(_sfc_main$3), {
|
|
162
|
+
}, 8, ["loading", "onClick"]), !unref(props).readonly && (isNormal.value && (creatable.value || updatable.value) || isQuick.value && creatable.value) ? (openBlock(), createBlock(unref(_sfc_main$3), {
|
|
154
163
|
key: 0,
|
|
155
164
|
type: unref(state).type === "create" ? "success" : "primary",
|
|
156
165
|
loading: unref(state).loading,
|
|
157
|
-
disabled: !unref(state).dataUpdated,
|
|
158
166
|
onClick: unref(handleSave)
|
|
159
167
|
}, {
|
|
160
|
-
default: withCtx(() => [..._cache[
|
|
168
|
+
default: withCtx(() => [..._cache[9] || (_cache[9] = [createTextVNode(" 保存 ", -1)])]),
|
|
161
169
|
_: 1
|
|
162
170
|
}, 8, [
|
|
163
171
|
"type",
|
|
164
172
|
"loading",
|
|
165
|
-
"disabled",
|
|
166
173
|
"onClick"
|
|
167
174
|
])) : createCommentVNode("v-if", true)], 2)], 2)
|
|
168
175
|
], 2)) : createCommentVNode("v-if", true);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"batch-edit-form.js","names":[],"sources":["../../../src/components/batch-edit/batch-edit-form.vue"],"sourcesContent":["<template>\n <aside :class=\"cls.e('form')\" v-if=\"state.visible &&
|
|
1
|
+
{"version":3,"file":"batch-edit-form.js","names":[],"sources":["../../../src/components/batch-edit/batch-edit-form.vue"],"sourcesContent":["<template>\n <aside :class=\"cls.e('form')\" v-if=\"state.visible && formModel\">\n <header :class=\"cls.e('form-header')\">\n <span :class=\"[cls.e('form-icon'), bem.is(headerInfo.tone)]\">\n <u-icon>\n <component :is=\"headerInfo.icon\" />\n </u-icon>\n </span>\n <div :class=\"cls.e('form-title')\">\n <h3 :class=\"cls.e('form-title-text')\">{{ headerInfo.title }}</h3>\n <span v-if=\"headerInfo.chip\" :class=\"cls.e('form-chip')\">\n {{ headerInfo.chip }}\n </span>\n </div>\n <u-button\n :class=\"cls.e('form-close')\"\n :icon=\"Close\"\n text\n circle\n size=\"small\"\n title=\"关闭\"\n @click=\"handleClose\"\n />\n </header>\n\n <u-scroll always :class=\"cls.e('form-body')\" :key=\"bodyKey\">\n <transition name=\"fade\" appear mode=\"out-in\">\n <u-form\n ref=\"formComponentRef\"\n :model=\"formModel\"\n :readonly=\"props.readonly\"\n :label-width=\"props.labelWidth\"\n >\n <slot\n v-bind=\"{\n row: state.row,\n depth: state.depth,\n indexes: insertIndexes,\n index: state.row?.index\n }\"\n />\n </u-form>\n </transition>\n </u-scroll>\n\n <footer :class=\"cls.e('form-footer')\">\n <span :class=\"cls.e('form-hint')\" v-if=\"props.readonly\">只读模式</span>\n <span :class=\"cls.e('form-hint')\" v-else-if=\"isQuickUpdate\">\n 实时编辑\n <span :class=\"{ [bem.is('concealed')]: !focused }\"> · <u-kbd>Esc</u-kbd> 关闭</span>\n </span>\n <span :class=\"cls.e('form-hint')\" v-else>\n <span :class=\"{ [bem.is('concealed')]: !focused }\">\n <u-kbd>Ctrl + S</u-kbd> 保存 · <u-kbd>Esc</u-kbd> 关闭\n </span>\n </span>\n\n <div :class=\"cls.e('form-actions')\">\n <u-button text :loading=\"state.loading\" @click=\"handleClose\"> 取消 </u-button>\n <u-button\n v-if=\"\n !props.readonly && ((isNormal && (creatable || updatable)) || (isQuick && creatable))\n \"\n :type=\"state.type === 'create' ? 'success' : 'primary'\"\n :loading=\"state.loading\"\n @click=\"handleSave\"\n >\n 保存\n </u-button>\n </div>\n </footer>\n </aside>\n</template>\n\n<script lang=\"ts\" setup>\nimport { AddChild, Close, EditPen, Plus, View } from '@veltra/icons/normal'\nimport { bem } from '@veltra/utils'\nimport { computed, inject, shallowRef, toRef, type Component } from 'vue'\n\nimport type { _FormExposed, FormExposed } from '../../types/form'\nimport { UButton } from '../button'\nimport { UForm } from '../form'\nimport { UIcon } from '../icon'\nimport { UKbd } from '../kbd'\nimport { UScroll } from '../scroll'\nimport { BatchEditDIKey } from './di'\n\ndefineOptions({ name: 'BatchEditForm' })\n\nconst batchEditCtx = inject(BatchEditDIKey)!\n\nconst {\n cls,\n props,\n state,\n insertIndexes,\n handleSave,\n handleClose,\n staticFeatures,\n dynamicFeatures\n} = batchEditCtx\n\nconst focused = toRef(batchEditCtx, 'focused')\n\nconst formComponentRef = shallowRef<FormExposed>()\n\ndefineExpose<_FormExposed>({\n el: toRef(() => formComponentRef.value?.el),\n validate: () => formComponentRef.value?.validate() ?? Promise.resolve(true),\n clearValidate: () => formComponentRef.value?.clearValidate(),\n reset: () => formComponentRef.value?.reset()\n})\n\nconst creatable = computed(() => {\n return (\n state.type === 'create' &&\n (staticFeatures.value.has('create') || dynamicFeatures.value.create?.(state.row))\n )\n})\n\nconst updatable = computed(() => {\n return (\n state.type === 'update' &&\n (staticFeatures.value.has('update') || dynamicFeatures.value.update?.(state.row))\n )\n})\n\nconst isQuick = computed(() => props.mode === 'quick')\nconst isNormal = computed(() => props.mode !== 'quick')\nconst isQuickUpdate = computed(() => isQuick.value && state.type === 'update')\n\nconst formModel = computed(() => {\n if (isQuick.value && state.type === 'update' && state.row) {\n return state.row.data\n }\n return props.model\n})\n\ninterface HeaderInfo {\n icon: Component\n title: string\n chip?: string\n tone: 'create' | 'update' | 'view' | 'child'\n}\n\nconst headerInfo = computed<HeaderInfo>(() => {\n if (props.readonly) {\n return {\n icon: View,\n title: '查看详情',\n chip: state.row ? `第 ${state.row.index + 1} 行` : undefined,\n tone: 'view'\n }\n }\n if (state.parentRow) {\n return {\n icon: AddChild,\n title: '新增子级',\n chip: `归属于第 ${state.parentRow.index + 1} 行`,\n tone: 'child'\n }\n }\n if (state.type === 'create') {\n return { icon: Plus, title: '新增', tone: 'create' }\n }\n return {\n icon: EditPen,\n title: '编辑',\n chip: state.row ? `第 ${state.row.index + 1} 行` : undefined,\n tone: 'update'\n }\n})\n\n/** 通过 row 切换 / 类型切换驱动表单内容淡出淡入 */\nconst bodyKey = computed(() => {\n return `${state.type}-${state.row?.uid ?? 'create'}-${state.parentRow?.uid ?? 'root'}`\n})\n</script>\n"],"mappings":"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"}
|
|
@@ -22,7 +22,9 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
22
22
|
"readonly",
|
|
23
23
|
"deleteMethod",
|
|
24
24
|
"saveMethod",
|
|
25
|
-
"features"
|
|
25
|
+
"features",
|
|
26
|
+
"mode",
|
|
27
|
+
"beforeCreate"
|
|
26
28
|
]);
|
|
27
29
|
});
|
|
28
30
|
const hasNot = (value) => value.every((v) => !staticFeatures.value.has(v));
|
|
@@ -48,6 +50,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
48
50
|
});
|
|
49
51
|
function handleUpdateCurrentRow(row) {
|
|
50
52
|
if (allowed("update", row)) {
|
|
53
|
+
if (row) state.type = "update";
|
|
51
54
|
state.row = row;
|
|
52
55
|
state.depth = row?.depth;
|
|
53
56
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"batch-edit-list.js","names":[],"sources":["../../../src/components/batch-edit/batch-edit-list.vue"],"sourcesContent":["<template>\n <u-table\n v-bind=\"tableProps\"\n :slots=\"slots\"\n :class=\"[cls.e('table'), bem.is('editing', state.visible)]\"\n :columns=\"columns\"\n highlight-current\n :current=\"state.row\"\n @update:current=\"handleUpdateCurrentRow\"\n @update:checked=\"emit('update:checked', $event)\"\n @update:selected=\"emit('update:selected', $event)\"\n ref=\"tableRef\"\n >\n <template #column:__action__=\"{ row }\">\n <u-action-group :class=\"cls.e('row-actions')\" :max=\"5\" @click.stop circle>\n <u-action\n v-if=\"allowed('create', row)\"\n :icon=\"InsertToPrev\"\n title=\"在上方插入\"\n @run=\"handleInsertToPrev(row)\"\n />\n <u-action\n v-if=\"allowed('create', row)\"\n :icon=\"InsertToNext\"\n title=\"在下方插入\"\n @run=\"handleInsertToNext(row)\"\n />\n <u-action\n v-if=\"!!props.tree && allowed('createChild', row)\"\n :icon=\"AddChild\"\n title=\"添加子级\"\n @run=\"handleInsertChild(row)\"\n />\n <u-action\n v-if=\"allowed('copy', row)\"\n :icon=\"Copy\"\n title=\"复制此行\"\n @run=\"handleCopy(row)\"\n />\n\n <u-action\n v-if=\"canDelete(row)\"\n :icon=\"Delete\"\n type=\"danger\"\n title=\"删除\"\n @run=\"handleDelete(row)\"\n v-bind=\"props.actionsProps?.delete\"\n />\n </u-action-group>\n </template>\n\n <template #empty v-if=\"!props.readonly\"> {{ null }} </template>\n\n <template\n #append\n v-if=\"\n !props.readonly &&\n (staticFeatures.has('create') || dynamicFeatures.create?.()) &&\n ((state.type === 'create' && !state.visible) || state.type === 'update')\n \"\n >\n <div :class=\"cls.e('add')\">\n <u-button\n :class=\"cls.e('add-btn')\"\n :icon=\"Plus\"\n :loading=\"state.loading\"\n type=\"primary\"\n plain\n @click.stop=\"handleCreate\"\n >\n 新增一行\n </u-button>\n </div>\n </template>\n </u-table>\n</template>\n\n<script setup lang=\"ts\">\nimport { o } from '@cat-kit/core'\nimport { AddChild, Copy, Delete, InsertToNext, InsertToPrev, Plus } from '@veltra/icons/normal'\nimport { bem } from '@veltra/utils'\nimport { computed, inject, type Slots } from 'vue'\n\nimport type { BatchEditFeature, TableRow } from '../../types'\nimport { UAction, UActionGroup } from '../action'\nimport { UButton } from '../button'\nimport { UTable } from '../table'\nimport { BatchEditDIKey } from './di'\n\ndefineOptions({ name: 'BatchEditList' })\n\ndefineProps<{ slots: Slots }>()\n\nconst {\n cls,\n state,\n tableRef,\n props,\n emit,\n staticFeatures,\n dynamicFeatures,\n handleCreate,\n handleCopy,\n handleDelete,\n handleInsertToNext,\n handleInsertToPrev,\n handleInsertChild\n} = inject(BatchEditDIKey)!\n\nconst tableProps = computed(() => {\n return o(props as Record<string, any>).omit([\n 'model',\n 'columns',\n 'cols',\n 'readonly',\n 'deleteMethod',\n 'saveMethod',\n 'features'\n ])\n})\n\nconst hasNot = (value: BatchEditFeature[]) => value.every((v) => !staticFeatures.value.has(v))\n\nconst allowed = (feature: BatchEditFeature, row?: TableRow) => {\n return staticFeatures.value.has(feature) || !!dynamicFeatures.value[feature]?.(row)\n}\n\nconst columns = computed(() => {\n if (props.readonly || hasNot(['create', 'delete', 'createChild', 'update', 'copy']))\n return props.columns\n\n return (props.columns ?? []).concat({\n name: '操作',\n key: '__action__',\n align: 'center',\n width: 180,\n fixed: 'right',\n resizable: false\n })\n})\n\nfunction handleUpdateCurrentRow(row?: TableRow) {\n if (allowed('update', row)) {\n state.row = row\n state.depth = row?.depth\n }\n}\n\nfunction canDelete(row: TableRow) {\n return !props.readonly && allowed('delete', row)\n}\n</script>\n"],"mappings":";;;;;;;;;;;;;;;EA6FA,MAAM,EACJ,KACA,OACA,UACA,OACA,MACA,gBACA,iBACA,cACA,YACA,cACA,oBACA,oBACA,sBACE,OAAO,cAAc;EAEzB,MAAM,aAAa,eAAe;GAChC,OAAO,EAAE,KAA4B,EAAE,KAAK;IAC1C;IACA;IACA;IACA;IACA;IACA;IACA;GACF,CAAC;EACH,CAAC;EAED,MAAM,UAAU,UAA8B,MAAM,OAAO,MAAM,CAAC,eAAe,MAAM,IAAI,CAAC,CAAC;EAE7F,MAAM,WAAW,SAA2B,QAAmB;GAC7D,OAAO,eAAe,MAAM,IAAI,OAAO,KAAK,CAAC,CAAC,gBAAgB,MAAM,WAAW,GAAG;EACpF;EAEA,MAAM,UAAU,eAAe;GAC7B,IAAI,MAAM,YAAY,OAAO;IAAC;IAAU;IAAU;IAAe;IAAU;GAAM,CAAC,GAChF,OAAO,MAAM;GAEf,QAAQ,MAAM,WAAW,CAAC,GAAG,OAAO;IAClC,MAAM;IACN,KAAK;IACL,OAAO;IACP,OAAO;IACP,OAAO;IACP,WAAW;GACb,CAAC;EACH,CAAC;EAED,SAAS,uBAAuB,KAAgB;GAC9C,IAAI,QAAQ,UAAU,GAAG,GAAG;IAC1B,MAAM,MAAM;IACZ,MAAM,QAAQ,KAAK;GACrB;EACF;EAEA,SAAS,UAAU,KAAe;GAChC,OAAO,CAAC,MAAM,YAAY,QAAQ,UAAU,GAAG;EACjD;;
|
|
1
|
+
{"version":3,"file":"batch-edit-list.js","names":[],"sources":["../../../src/components/batch-edit/batch-edit-list.vue"],"sourcesContent":["<template>\n <u-table\n v-bind=\"tableProps\"\n :slots=\"slots\"\n :class=\"[cls.e('table'), bem.is('editing', state.visible)]\"\n :columns=\"columns\"\n highlight-current\n :current=\"state.row\"\n @update:current=\"handleUpdateCurrentRow\"\n @update:checked=\"emit('update:checked', $event)\"\n @update:selected=\"emit('update:selected', $event)\"\n ref=\"tableRef\"\n >\n <template #column:__action__=\"{ row }\">\n <u-action-group :class=\"cls.e('row-actions')\" :max=\"5\" @click.stop circle>\n <u-action\n v-if=\"allowed('create', row)\"\n :icon=\"InsertToPrev\"\n title=\"在上方插入\"\n @run=\"handleInsertToPrev(row)\"\n />\n <u-action\n v-if=\"allowed('create', row)\"\n :icon=\"InsertToNext\"\n title=\"在下方插入\"\n @run=\"handleInsertToNext(row)\"\n />\n <u-action\n v-if=\"!!props.tree && allowed('createChild', row)\"\n :icon=\"AddChild\"\n title=\"添加子级\"\n @run=\"handleInsertChild(row)\"\n />\n <u-action\n v-if=\"allowed('copy', row)\"\n :icon=\"Copy\"\n title=\"复制此行\"\n @run=\"handleCopy(row)\"\n />\n\n <u-action\n v-if=\"canDelete(row)\"\n :icon=\"Delete\"\n type=\"danger\"\n title=\"删除\"\n @run=\"handleDelete(row)\"\n v-bind=\"props.actionsProps?.delete\"\n />\n </u-action-group>\n </template>\n\n <template #empty v-if=\"!props.readonly\"> {{ null }} </template>\n\n <template\n #append\n v-if=\"\n !props.readonly &&\n (staticFeatures.has('create') || dynamicFeatures.create?.()) &&\n ((state.type === 'create' && !state.visible) || state.type === 'update')\n \"\n >\n <div :class=\"cls.e('add')\">\n <u-button\n :class=\"cls.e('add-btn')\"\n :icon=\"Plus\"\n :loading=\"state.loading\"\n type=\"primary\"\n plain\n @click.stop=\"handleCreate\"\n >\n 新增一行\n </u-button>\n </div>\n </template>\n </u-table>\n</template>\n\n<script setup lang=\"ts\">\nimport { o } from '@cat-kit/core'\nimport { AddChild, Copy, Delete, InsertToNext, InsertToPrev, Plus } from '@veltra/icons/normal'\nimport { bem } from '@veltra/utils'\nimport { computed, inject, type Slots } from 'vue'\n\nimport type { BatchEditFeature, TableRow } from '../../types'\nimport { UAction, UActionGroup } from '../action'\nimport { UButton } from '../button'\nimport { UTable } from '../table'\nimport { BatchEditDIKey } from './di'\n\ndefineOptions({ name: 'BatchEditList' })\n\ndefineProps<{ slots: Slots }>()\n\nconst {\n cls,\n state,\n tableRef,\n props,\n emit,\n staticFeatures,\n dynamicFeatures,\n handleCreate,\n handleCopy,\n handleDelete,\n handleInsertToNext,\n handleInsertToPrev,\n handleInsertChild\n} = inject(BatchEditDIKey)!\n\nconst tableProps = computed(() => {\n return o(props as Record<string, any>).omit([\n 'model',\n 'columns',\n 'cols',\n 'readonly',\n 'deleteMethod',\n 'saveMethod',\n 'features',\n 'mode',\n 'beforeCreate'\n ])\n})\n\nconst hasNot = (value: BatchEditFeature[]) => value.every((v) => !staticFeatures.value.has(v))\n\nconst allowed = (feature: BatchEditFeature, row?: TableRow) => {\n return staticFeatures.value.has(feature) || !!dynamicFeatures.value[feature]?.(row)\n}\n\nconst columns = computed(() => {\n if (props.readonly || hasNot(['create', 'delete', 'createChild', 'update', 'copy']))\n return props.columns\n\n return (props.columns ?? []).concat({\n name: '操作',\n key: '__action__',\n align: 'center',\n width: 180,\n fixed: 'right',\n resizable: false\n })\n})\n\nfunction handleUpdateCurrentRow(row?: TableRow) {\n if (allowed('update', row)) {\n if (row) {\n state.type = 'update'\n }\n state.row = row\n state.depth = row?.depth\n }\n}\n\nfunction canDelete(row: TableRow) {\n return !props.readonly && allowed('delete', row)\n}\n</script>\n"],"mappings":"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"}
|
|
@@ -4,6 +4,7 @@ import { BatchEditDIKey } from "./di.js";
|
|
|
4
4
|
import _sfc_main$2 from "./batch-edit-form.js";
|
|
5
5
|
import _sfc_main$3 from "./batch-edit-list.js";
|
|
6
6
|
import { useEdit } from "./use-edit.js";
|
|
7
|
+
import { useFeatures } from "./use-features.js";
|
|
7
8
|
import { computed, createBlock, createCommentVNode, createVNode, defineComponent, guardReactiveProps, inject, normalizeClass, normalizeProps, openBlock, provide, renderSlot, shallowRef, unref, useSlots, watch, withCtx } from "vue";
|
|
8
9
|
import { bem } from "@veltra/utils";
|
|
9
10
|
//#region src/components/batch-edit/batch-edit.vue
|
|
@@ -15,6 +16,8 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
15
16
|
title: {},
|
|
16
17
|
cols: { default: () => ["1fr", "420px"] },
|
|
17
18
|
readonly: { type: Boolean },
|
|
19
|
+
mode: { default: "normal" },
|
|
20
|
+
beforeCreate: {},
|
|
18
21
|
labelWidth: {},
|
|
19
22
|
deleteMethod: {},
|
|
20
23
|
saveMethod: {},
|
|
@@ -54,44 +57,18 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
54
57
|
setup(__props, { emit: __emit }) {
|
|
55
58
|
const props = __props;
|
|
56
59
|
const emit = __emit;
|
|
57
|
-
const staticFeatures = computed(() => {
|
|
58
|
-
const { features } = props;
|
|
59
|
-
if (Array.isArray(features)) return new Set(features);
|
|
60
|
-
const defaultFeatures = new Set([
|
|
61
|
-
"create",
|
|
62
|
-
"delete",
|
|
63
|
-
"update",
|
|
64
|
-
"createChild"
|
|
65
|
-
]);
|
|
66
|
-
if (!features) return defaultFeatures;
|
|
67
|
-
Object.entries(features).forEach(([key, value]) => {
|
|
68
|
-
const k = key;
|
|
69
|
-
if (typeof value === "function" || value === false) defaultFeatures.delete(k);
|
|
70
|
-
else if (value === true) defaultFeatures.add(k);
|
|
71
|
-
});
|
|
72
|
-
return defaultFeatures;
|
|
73
|
-
});
|
|
74
|
-
const dynamicFeatures = computed(() => {
|
|
75
|
-
const { features } = props;
|
|
76
|
-
if (!Array.isArray(features) && typeof features === "object") return Object.entries(features).filter(([_, value]) => {
|
|
77
|
-
return typeof value === "function";
|
|
78
|
-
}).reduce((acc, [key, value]) => {
|
|
79
|
-
acc[key] = value;
|
|
80
|
-
return acc;
|
|
81
|
-
}, {});
|
|
82
|
-
return {};
|
|
83
|
-
});
|
|
84
60
|
const slots = useSlots();
|
|
85
61
|
const cls = bem("batch-edit");
|
|
86
62
|
const tableRef = shallowRef();
|
|
87
63
|
const formRef = shallowRef();
|
|
64
|
+
const focused = shallowRef(false);
|
|
65
|
+
const { staticFeatures, dynamicFeatures } = useFeatures({ props });
|
|
88
66
|
const editCtx = useEdit({
|
|
89
67
|
props,
|
|
90
68
|
emit,
|
|
91
|
-
tableRef,
|
|
92
69
|
formRef
|
|
93
70
|
});
|
|
94
|
-
const { state, handleClose, handleSave
|
|
71
|
+
const { state, handleClose, handleSave } = editCtx;
|
|
95
72
|
provide(BatchEditDIKey, {
|
|
96
73
|
cls,
|
|
97
74
|
props,
|
|
@@ -99,6 +76,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
99
76
|
tableRef,
|
|
100
77
|
staticFeatures,
|
|
101
78
|
dynamicFeatures,
|
|
79
|
+
focused,
|
|
102
80
|
...editCtx
|
|
103
81
|
});
|
|
104
82
|
const dialogCtx = inject(DialogDIKey, void 0);
|
|
@@ -108,14 +86,19 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
108
86
|
const cols = computed(() => {
|
|
109
87
|
return !!state.row || state.visible ? props.cols : void 0;
|
|
110
88
|
});
|
|
89
|
+
function handleFocusIn() {
|
|
90
|
+
focused.value = true;
|
|
91
|
+
}
|
|
92
|
+
function handleFocusOut(e) {
|
|
93
|
+
if (!e.currentTarget.contains(e.relatedTarget)) focused.value = false;
|
|
94
|
+
}
|
|
111
95
|
/**
|
|
112
|
-
*
|
|
113
|
-
* - Esc
|
|
114
|
-
* - ⌘/Ctrl + S
|
|
115
|
-
* - ⌘/Ctrl + Backspace 删除当前编辑行
|
|
116
|
-
* - ⌘/Ctrl + N 新增(仅在不在表单中时)
|
|
96
|
+
* 键盘快捷键(仅组件获焦时生效):
|
|
97
|
+
* - Esc 关闭表单
|
|
98
|
+
* - ⌘/Ctrl + S 保存(快速编辑模式下编辑行时除外)
|
|
117
99
|
*/
|
|
118
100
|
function handleKeydown(e) {
|
|
101
|
+
if (!focused.value) return;
|
|
119
102
|
if (props.readonly && e.key !== "Escape") return;
|
|
120
103
|
if (e.key === "Escape") {
|
|
121
104
|
if (state.visible) {
|
|
@@ -125,20 +108,10 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
125
108
|
return;
|
|
126
109
|
}
|
|
127
110
|
if (!(e.metaKey || e.ctrlKey)) return;
|
|
128
|
-
|
|
129
|
-
|
|
111
|
+
if (e.key.toLowerCase() === "s" && state.visible) {
|
|
112
|
+
if (props.mode === "quick" && state.type === "update") return;
|
|
130
113
|
e.preventDefault();
|
|
131
114
|
handleSave();
|
|
132
|
-
return;
|
|
133
|
-
}
|
|
134
|
-
if (e.key === "Backspace" && state.row && state.type === "update") {
|
|
135
|
-
e.preventDefault();
|
|
136
|
-
handleDelete(state.row);
|
|
137
|
-
return;
|
|
138
|
-
}
|
|
139
|
-
if (key === "n" && !state.visible) {
|
|
140
|
-
e.preventDefault();
|
|
141
|
-
handleCreate();
|
|
142
115
|
}
|
|
143
116
|
}
|
|
144
117
|
return (_ctx, _cache) => {
|
|
@@ -148,18 +121,24 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
148
121
|
rows: "minmax(0, 1fr)",
|
|
149
122
|
gap: "8px",
|
|
150
123
|
resizable: "",
|
|
151
|
-
|
|
152
|
-
|
|
124
|
+
tabindex: "-1",
|
|
125
|
+
onFocusin: handleFocusIn,
|
|
126
|
+
onFocusout: handleFocusOut,
|
|
127
|
+
onKeydownCapture: handleKeydown
|
|
153
128
|
}, {
|
|
154
129
|
default: withCtx(() => [
|
|
155
130
|
createCommentVNode(" 编辑列表 "),
|
|
156
|
-
createVNode(_sfc_main$3, {
|
|
131
|
+
createVNode(_sfc_main$3, {
|
|
132
|
+
slots,
|
|
133
|
+
ref_key: "tableRef",
|
|
134
|
+
ref: tableRef
|
|
135
|
+
}, null, 512),
|
|
157
136
|
createCommentVNode(" 编辑表单 "),
|
|
158
137
|
createVNode(_sfc_main$2, {
|
|
159
138
|
ref_key: "formRef",
|
|
160
139
|
ref: formRef
|
|
161
140
|
}, {
|
|
162
|
-
default: withCtx((scoped) => [
|
|
141
|
+
default: withCtx((scoped) => [renderSlot(_ctx.$slots, "form", normalizeProps(guardReactiveProps(scoped)))]),
|
|
163
142
|
_: 3
|
|
164
143
|
}, 512)
|
|
165
144
|
]),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"batch-edit.js","names":[],"sources":["../../../src/components/batch-edit/batch-edit.vue"],"sourcesContent":["<template>\n <u-layout\n :class=\"cls.b\"\n :cols=\"cols\"\n rows=\"minmax(0, 1fr)\"\n gap=\"8px\"\n resizable\n @
|
|
1
|
+
{"version":3,"file":"batch-edit.js","names":[],"sources":["../../../src/components/batch-edit/batch-edit.vue"],"sourcesContent":["<template>\n <u-layout\n :class=\"cls.b\"\n :cols=\"cols\"\n rows=\"minmax(0, 1fr)\"\n gap=\"8px\"\n resizable\n tabindex=\"-1\"\n @focusin=\"handleFocusIn\"\n @focusout=\"handleFocusOut\"\n @keydown.capture=\"handleKeydown\"\n >\n <!-- 编辑列表 -->\n <BatchEditList :slots=\"slots\" ref=\"tableRef\" />\n\n <!-- 编辑表单 -->\n <BatchEditForm ref=\"formRef\" v-slot=\"scoped\">\n <slot name=\"form\" v-bind=\"scoped\" />\n </BatchEditForm>\n </u-layout>\n</template>\n\n<script lang=\"ts\" setup>\nimport { bem } from '@veltra/utils'\nimport { computed, inject, provide, shallowRef, watch } from 'vue'\n\nimport type {\n BatchEditEmits,\n BatchEditProps,\n TableColumnSlotsScope,\n TableExposed,\n TableRow\n} from '../../types'\nimport type { FormExposed } from '../../types/form'\nimport { DialogDIKey } from '../dialog/di'\nimport { ULayout } from '../layout'\nimport BatchEditForm from './batch-edit-form.vue'\nimport BatchEditList from './batch-edit-list.vue'\nimport { BatchEditDIKey } from './di'\nimport { useEdit } from './use-edit'\nimport { useFeatures } from './use-features'\n\ndefineOptions({ name: 'BatchEdit' })\n\nconst props = withDefaults(defineProps<BatchEditProps>(), {\n cols: () => ['1fr', '420px'],\n mode: 'normal'\n})\n\nconst emit = defineEmits<BatchEditEmits>()\n\nconst slots = defineSlots<\n {\n form?: (props: {\n /** 当前编辑的层级 */\n depth?: number\n /** 当前编辑的行 */\n row?: TableRow\n /** 当前编辑的行索引 */\n index?: number\n /** 操作的目标行索引路径 */\n indexes?: number[]\n }) => any\n\n header?: () => any\n } & Partial<{ [key: `column:${string}`]: (props: TableColumnSlotsScope) => any }>\n>()\n\nconst cls = bem('batch-edit')\n\nconst tableRef = shallowRef<TableExposed>()\nconst formRef = shallowRef<FormExposed>()\nconst focused = shallowRef(false)\n\nconst { staticFeatures, dynamicFeatures } = useFeatures({ props })\n\nconst editCtx = useEdit({ props, emit, formRef })\n\nconst { state, handleClose, handleSave } = editCtx\n\nprovide(BatchEditDIKey, {\n cls,\n props,\n emit,\n tableRef,\n staticFeatures,\n dynamicFeatures,\n focused,\n ...editCtx\n})\n\nconst dialogCtx = inject(DialogDIKey, undefined)\n\ndialogCtx &&\n watch(dialogCtx.visible, (visible) => {\n !visible && editCtx.handleClose()\n })\n\nconst cols = computed(() => {\n return !!state.row || state.visible ? props.cols : undefined\n})\n\nfunction handleFocusIn() {\n focused.value = true\n}\n\nfunction handleFocusOut(e: FocusEvent) {\n const root = e.currentTarget as HTMLElement\n if (!root.contains(e.relatedTarget as Node | null)) {\n focused.value = false\n }\n}\n\n/**\n * 键盘快捷键(仅组件获焦时生效):\n * - Esc 关闭表单\n * - ⌘/Ctrl + S 保存(快速编辑模式下编辑行时除外)\n */\nfunction handleKeydown(e: KeyboardEvent) {\n if (!focused.value) return\n if (props.readonly && e.key !== 'Escape') return\n\n if (e.key === 'Escape') {\n if (state.visible) {\n e.preventDefault()\n handleClose()\n }\n return\n }\n\n const meta = e.metaKey || e.ctrlKey\n if (!meta) return\n\n const key = e.key.toLowerCase()\n\n if (key === 's' && state.visible) {\n if (props.mode === 'quick' && state.type === 'update') return\n e.preventDefault()\n handleSave()\n }\n}\n</script>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA4CA,MAAM,QAAQ;EAKd,MAAM,OAAO;EAEb,MAAM,QAAQ,SAAA;EAiBd,MAAM,MAAM,IAAI,YAAY;EAE5B,MAAM,WAAW,WAAyB;EAC1C,MAAM,UAAU,WAAwB;EACxC,MAAM,UAAU,WAAW,KAAK;EAEhC,MAAM,EAAE,gBAAgB,oBAAoB,YAAY,EAAE,MAAM,CAAC;EAEjE,MAAM,UAAU,QAAQ;GAAE;GAAO;GAAM;EAAQ,CAAC;EAEhD,MAAM,EAAE,OAAO,aAAa,eAAe;EAE3C,QAAQ,gBAAgB;GACtB;GACA;GACA;GACA;GACA;GACA;GACA;GACA,GAAG;EACL,CAAC;EAED,MAAM,YAAY,OAAO,aAAa,KAAA,CAAS;EAE/C,aACE,MAAM,UAAU,UAAU,YAAY;GACpC,CAAC,WAAW,QAAQ,YAAY;EAClC,CAAC;EAEH,MAAM,OAAO,eAAe;GAC1B,OAAO,CAAC,CAAC,MAAM,OAAO,MAAM,UAAU,MAAM,OAAO,KAAA;EACrD,CAAC;EAED,SAAS,gBAAgB;GACvB,QAAQ,QAAQ;EAClB;EAEA,SAAS,eAAe,GAAe;GAErC,IAAI,CADS,EAAE,cACL,SAAS,EAAE,aAA4B,GAC/C,QAAQ,QAAQ;EAEpB;;;;;;EAOA,SAAS,cAAc,GAAkB;GACvC,IAAI,CAAC,QAAQ,OAAO;GACpB,IAAI,MAAM,YAAY,EAAE,QAAQ,UAAU;GAE1C,IAAI,EAAE,QAAQ,UAAU;IACtB,IAAI,MAAM,SAAS;KACjB,EAAE,eAAe;KACjB,YAAY;IACd;IACA;GACF;GAGA,IAAI,EADS,EAAE,WAAW,EAAE,UACjB;GAIX,IAFY,EAAE,IAAI,YAEd,MAAQ,OAAO,MAAM,SAAS;IAChC,IAAI,MAAM,SAAS,WAAW,MAAM,SAAS,UAAU;IACvD,EAAE,eAAe;IACjB,WAAW;GACb;EACF;;uBA3IE,YAkBW,MAAA,WAAA,GAAA;IAjBR,OAAK,eAAE,MAAA,GAAA,EAAI,CAAC;IACZ,MAAM,KAAA;IACP,MAAK;IACL,KAAI;IACJ,WAAA;IACA,UAAS;IACR,WAAS;IACT,YAAU;sBACO;;2BAEL;KAAb,mBAAA,QAAA;KACA,YAA+C,aAAA;MAAxB;eAAW;MAAJ,KAAI;;KAElC,mBAAA,QAAA;KACA,YAEgB,aAAA;eAFG;MAAJ,KAAI;;wBAAkB,WAAM,CACzC,WAAoC,KAAA,QAAA,QAAA,eAAA,mBAAV,MAAM,CAAA,CAAA,CAAA,CAAA"}
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import { TableColumn, TableColumnSlotsScope, TableRow } from "../../types/table.js";
|
|
2
|
-
import { BatchEditProps } from "../../types/batch-edit.js";
|
|
2
|
+
import { BatchEditMode, BatchEditProps } from "../../types/batch-edit.js";
|
|
3
3
|
//#region src/components/batch-edit/batch-edit.vue.d.ts
|
|
4
4
|
type __VLS_Slots = {
|
|
5
5
|
form?: (props: {
|
|
6
|
-
/**
|
|
7
|
-
depth?: number; /** 当前编辑的行 */
|
|
6
|
+
/** 当前编辑的层级 */depth?: number; /** 当前编辑的行 */
|
|
8
7
|
row?: TableRow; /** 当前编辑的行索引 */
|
|
9
8
|
index?: number; /** 操作的目标行索引路径 */
|
|
10
9
|
indexes?: number[];
|
|
@@ -33,6 +32,7 @@ declare const __VLS_base: import("vue").DefineComponent<BatchEditProps, {}, {},
|
|
|
33
32
|
"onRow-click"?: ((row: TableRow, ev: MouseEvent) => any) | undefined;
|
|
34
33
|
}>, {
|
|
35
34
|
cols: string | [string, string];
|
|
35
|
+
mode: BatchEditMode;
|
|
36
36
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
37
37
|
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
38
38
|
declare const _default: typeof __VLS_export;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"di.js","names":[],"sources":["../../../src/components/batch-edit/di.ts"],"sourcesContent":["import type { BEM } from '@veltra/utils'\nimport type { ComputedRef, InjectionKey, ShallowRef } from 'vue'\n\nimport type {\n BatchEditEmits,\n BatchEditFeature,\n BatchEditProps,\n TableExposed,\n TableRow\n} from '../../types'\nimport type { EditReturned } from './use-edit'\nexport const BatchEditDIKey: InjectionKey<\n {\n cls: BEM<'batch-edit', 'u-'>\n props: BatchEditProps\n emit: BatchEditEmits\n tableRef: ShallowRef<TableExposed | undefined>\n staticFeatures: ComputedRef<Set<BatchEditFeature>>\n dynamicFeatures: ComputedRef<\n Record<BatchEditFeature, ((row?: TableRow) => boolean) | undefined>\n >\n } & EditReturned\n> = Symbol('BatchEditDIKey')\n"],"mappings":";AAWA,MAAa,
|
|
1
|
+
{"version":3,"file":"di.js","names":[],"sources":["../../../src/components/batch-edit/di.ts"],"sourcesContent":["import type { BEM } from '@veltra/utils'\nimport type { ComputedRef, InjectionKey, ShallowRef, Ref } from 'vue'\n\nimport type {\n BatchEditEmits,\n BatchEditFeature,\n BatchEditProps,\n TableExposed,\n TableRow\n} from '../../types'\nimport type { EditReturned } from './use-edit'\nexport const BatchEditDIKey: InjectionKey<\n {\n cls: BEM<'batch-edit', 'u-'>\n props: BatchEditProps\n emit: BatchEditEmits\n tableRef: ShallowRef<TableExposed | undefined>\n staticFeatures: ComputedRef<Set<BatchEditFeature>>\n dynamicFeatures: ComputedRef<\n Record<BatchEditFeature, ((row?: TableRow) => boolean) | undefined>\n >\n /** 组件或其子节点是否处于聚焦状态 */\n focused: Ref<boolean>\n } & EditReturned\n> = Symbol('BatchEditDIKey')\n"],"mappings":";AAWA,MAAa,iBAaT,OAAO,gBAAgB"}
|