@veltra/desktop 1.3.4 → 1.3.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/action/action-group.vue.d.ts +2 -2
- package/dist/components/action/action.vue.d.ts +1 -1
- package/dist/components/auto-complete/auto-complete.vue.d.ts +2 -2
- package/dist/components/cascade/cascade.js +8 -2
- package/dist/components/cascade/cascade.js.map +1 -1
- package/dist/components/cascade/cascade.vue.d.ts +4 -4
- package/dist/components/cascade/style2.css +4 -0
- package/dist/components/checkbox/checkbox-button.vue.d.ts +1 -1
- package/dist/components/checkbox-group/checkbox-group.vue.d.ts +2 -2
- package/dist/components/code-editor/code-editor.vue.d.ts +2 -2
- package/dist/components/date-panel/date-panel.vue.d.ts +1 -1
- package/dist/components/date-picker/date-picker.vue.d.ts +2 -2
- package/dist/components/date-range-picker/date-range-picker.js +5 -2
- package/dist/components/date-range-picker/date-range-picker.js.map +1 -1
- package/dist/components/date-range-picker/date-range-picker.vue.d.ts +2 -2
- package/dist/components/date-range-picker/style2.css +4 -0
- package/dist/components/empty/empty.vue.d.ts +1 -1
- package/dist/components/form-item/form-item.js.map +1 -1
- package/dist/components/form-item/form-item.vue_vue_type_script_setup_true_lang.js +2 -2
- package/dist/components/form-item/form-item.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/form-item/style2.css +2 -1
- package/dist/components/grid-input/style2.css +3 -0
- package/dist/components/input/input.vue.d.ts +4 -4
- package/dist/components/multi-select/multi-select.js +67 -40
- package/dist/components/multi-select/multi-select.js.map +1 -1
- package/dist/components/multi-select/multi-select.vue.d.ts +6 -6
- package/dist/components/multi-select/style2.css +23 -10
- package/dist/components/multi-tree-select/multi-tree-select.js +52 -35
- package/dist/components/multi-tree-select/multi-tree-select.js.map +1 -1
- package/dist/components/multi-tree-select/multi-tree-select.vue.d.ts +4 -4
- package/dist/components/multi-tree-select/style2.css +26 -16
- package/dist/components/number-input/number-input.vue.d.ts +4 -4
- package/dist/components/number-range-input/number-range-input.vue.d.ts +1 -1
- package/dist/components/password-input/password-input.vue.d.ts +1 -1
- package/dist/components/pop-confirm/pop-confirm.vue.d.ts +1 -1
- package/dist/components/radio-group/radio-group.vue.d.ts +2 -2
- package/dist/components/rich-text-editor/rich-text-editor.vue.d.ts +1 -1
- package/dist/components/select/select.js +159 -95
- package/dist/components/select/select.js.map +1 -1
- package/dist/components/select/select.vue.d.ts +2 -2
- package/dist/components/select/style2.css +4 -17
- package/dist/components/select/use-options.js +67 -26
- package/dist/components/select/use-options.js.map +1 -1
- package/dist/components/steps/steps.vue.d.ts +2 -2
- package/dist/components/textarea/style2.css +1 -0
- package/dist/components/textarea/textarea.vue.d.ts +5 -5
- package/dist/components/tip/tip.vue.d.ts +1 -1
- package/dist/components/tree/use-tree-nodes.js +14 -17
- package/dist/components/tree/use-tree-nodes.js.map +1 -1
- package/dist/components/tree-select/style2.css +6 -15
- package/dist/components/tree-select/tree-select.js +95 -41
- package/dist/components/tree-select/tree-select.js.map +1 -1
- package/dist/components/tree-select/tree-select.vue.d.ts +4 -4
- package/dist/types/tree.d.ts +4 -1
- package/package.json +6 -6
- package/src/components/cascade/cascade.vue +15 -2
- package/src/components/cascade/style.scss +5 -0
- package/src/components/date-range-picker/date-range-picker.vue +9 -1
- package/src/components/date-range-picker/style.scss +5 -0
- package/src/components/form-item/form-item.vue +2 -2
- package/src/components/form-item/style.scss +2 -1
- package/src/components/grid-input/style.scss +1 -0
- package/src/components/multi-select/multi-select.vue +50 -19
- package/src/components/multi-select/style.scss +27 -4
- package/src/components/multi-tree-select/multi-tree-select.vue +34 -14
- package/src/components/multi-tree-select/style.scss +28 -9
- package/src/components/select/__test__/select.test.ts +110 -0
- package/src/components/select/select.vue +130 -46
- package/src/components/select/style.scss +5 -14
- package/src/components/select/use-options.ts +83 -39
- package/src/components/textarea/style.scss +1 -0
- package/src/components/tree/use-tree-nodes.ts +19 -24
- package/src/components/tree-select/style.scss +4 -8
- package/src/components/tree-select/tree-select.vue +90 -17
- package/src/types/tree.ts +4 -1
|
@@ -27,12 +27,12 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_PublicProps, {}, {
|
|
|
27
27
|
"onUpdate:text"?: ((value: any) => any) | undefined;
|
|
28
28
|
"onUpdate:label"?: ((label?: string | undefined) => any) | undefined;
|
|
29
29
|
}>, {
|
|
30
|
-
disabled: boolean;
|
|
31
|
-
readonly: boolean;
|
|
32
30
|
labelKey: string;
|
|
33
31
|
valueKey: string;
|
|
34
32
|
placeholder: string;
|
|
35
33
|
clearable: boolean;
|
|
34
|
+
disabled: boolean;
|
|
35
|
+
readonly: boolean;
|
|
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;
|
|
@@ -18,19 +18,15 @@
|
|
|
18
18
|
.u-select {
|
|
19
19
|
width: 100%;
|
|
20
20
|
}
|
|
21
|
-
.u-select__content-filter {
|
|
22
|
-
border-bottom: 1px solid var(--u-border-color);
|
|
23
|
-
background-color: var(--u-bg-color-middle);
|
|
24
|
-
}
|
|
25
|
-
.u-select__content-filter .u-input {
|
|
26
|
-
box-shadow: none;
|
|
27
|
-
}
|
|
28
21
|
.u-select__options {
|
|
29
|
-
max-height:
|
|
22
|
+
max-height: 240px;
|
|
30
23
|
}
|
|
31
24
|
.u-select.is-disabled .u-select__arrow {
|
|
32
25
|
color: var(--u-text-color-disabled);
|
|
33
26
|
}
|
|
27
|
+
.u-select__clear {
|
|
28
|
+
cursor: pointer;
|
|
29
|
+
}
|
|
34
30
|
.u-select__options-wrap {
|
|
35
31
|
list-style: none;
|
|
36
32
|
margin: 0;
|
|
@@ -92,9 +88,6 @@
|
|
|
92
88
|
.u-select__empty {
|
|
93
89
|
color: var(--u-text-color-main);
|
|
94
90
|
}
|
|
95
|
-
.u-select__panel--small .u-select__content-filter {
|
|
96
|
-
padding: calc(var(--u-gap-small) / 2) var(--u-gap-small);
|
|
97
|
-
}
|
|
98
91
|
.u-select__panel--small .u-select__options {
|
|
99
92
|
padding: var(--u-gap-small);
|
|
100
93
|
}
|
|
@@ -104,9 +97,6 @@
|
|
|
104
97
|
height: var(--u-form-component-height-small);
|
|
105
98
|
line-height: var(--u-form-component-height-small);
|
|
106
99
|
}
|
|
107
|
-
.u-select__panel--default .u-select__content-filter {
|
|
108
|
-
padding: calc(var(--u-gap-default) / 2) var(--u-gap-default);
|
|
109
|
-
}
|
|
110
100
|
.u-select__panel--default .u-select__options {
|
|
111
101
|
padding: var(--u-gap-default);
|
|
112
102
|
}
|
|
@@ -116,9 +106,6 @@
|
|
|
116
106
|
height: var(--u-form-component-height-default);
|
|
117
107
|
line-height: var(--u-form-component-height-default);
|
|
118
108
|
}
|
|
119
|
-
.u-select__panel--large .u-select__content-filter {
|
|
120
|
-
padding: calc(var(--u-gap-large) / 2) var(--u-gap-large);
|
|
121
|
-
}
|
|
122
109
|
.u-select__panel--large .u-select__options {
|
|
123
110
|
padding: var(--u-gap-large);
|
|
124
111
|
}
|
|
@@ -10,16 +10,33 @@ function useOptions(o$1) {
|
|
|
10
10
|
const filteredOptions = shallowRef([]);
|
|
11
11
|
const tempOptions = shallowRef([]);
|
|
12
12
|
const createdOptions = shallowRef([]);
|
|
13
|
+
function getSourceOptions(propsOptions) {
|
|
14
|
+
if (typeof propsOptions === "function") return remoteOptions.value;
|
|
15
|
+
return [...createdOptions.value, ...propsOptions ?? []];
|
|
16
|
+
}
|
|
17
|
+
/** 无查询时同步展示完整列表(含已创建项),避免选择后等高亮索引错位 */
|
|
18
|
+
function resetToSourceOptions() {
|
|
19
|
+
const sourceOptions = getSourceOptions(props.options);
|
|
20
|
+
if (typeof props.options === "function") {
|
|
21
|
+
setTempOption("", remoteOptions.value);
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
filteredOptions.value = sourceOptions;
|
|
25
|
+
tempOptions.value = [];
|
|
26
|
+
}
|
|
13
27
|
function temOptionsToCreatedOptions() {
|
|
14
|
-
|
|
28
|
+
if (!tempOptions.value.length) return;
|
|
29
|
+
createdOptions.value = [...createdOptions.value, ...tempOptions.value.map((item) => {
|
|
15
30
|
return {
|
|
16
31
|
...item,
|
|
17
32
|
__isTemp: false
|
|
18
33
|
};
|
|
19
|
-
});
|
|
34
|
+
})];
|
|
35
|
+
resetToSourceOptions();
|
|
20
36
|
}
|
|
21
37
|
function clearCreatedOptions() {
|
|
22
38
|
createdOptions.value = [];
|
|
39
|
+
resetToSourceOptions();
|
|
23
40
|
}
|
|
24
41
|
const setTempOption = (qs, options) => {
|
|
25
42
|
if (!qs?.trim() || !props.creatable) {
|
|
@@ -28,9 +45,10 @@ function useOptions(o$1) {
|
|
|
28
45
|
}
|
|
29
46
|
const labelKey = fieldKey(props.labelKey, "label");
|
|
30
47
|
const valueKey = fieldKey(props.valueKey, "value");
|
|
31
|
-
|
|
48
|
+
const exactMatch = options ? options.some((option) => {
|
|
32
49
|
return o(option).get(labelKey) === qs;
|
|
33
|
-
}) : false
|
|
50
|
+
}) : false;
|
|
51
|
+
tempOptions.value = exactMatch ? [] : [{
|
|
34
52
|
[labelKey]: qs,
|
|
35
53
|
[valueKey]: qs,
|
|
36
54
|
__isTemp: true
|
|
@@ -39,35 +57,58 @@ function useOptions(o$1) {
|
|
|
39
57
|
const allOptions = computed(() => {
|
|
40
58
|
const { options } = props;
|
|
41
59
|
if (typeof options === "function") return remoteOptions.value;
|
|
42
|
-
return options ?? [];
|
|
60
|
+
return [...createdOptions.value, ...options ?? []];
|
|
43
61
|
});
|
|
44
|
-
/**
|
|
62
|
+
/**
|
|
63
|
+
* 展示的选项
|
|
64
|
+
* @description 已创建选项并入过滤数据源参与匹配;临时选项(待创建)固定置顶
|
|
65
|
+
*/
|
|
45
66
|
const options = computed(() => {
|
|
46
67
|
const { options } = props;
|
|
47
68
|
if (typeof options === "function") return remoteOptions.value;
|
|
48
|
-
|
|
49
|
-
if (!options) return prependOptions;
|
|
50
|
-
return [...prependOptions, ...filteredOptions.value];
|
|
69
|
+
return [...tempOptions.value, ...filteredOptions.value];
|
|
51
70
|
});
|
|
52
|
-
|
|
71
|
+
const applyLocalFilter = (qs, propsOptions) => {
|
|
72
|
+
const labelKey = fieldKey(props.labelKey, "label");
|
|
73
|
+
const sourceOptions = [...createdOptions.value, ...propsOptions ?? []];
|
|
74
|
+
if (!qs) {
|
|
75
|
+
filteredOptions.value = sourceOptions;
|
|
76
|
+
setTempOption(qs, filteredOptions.value);
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
const _filteredOptions = sourceOptions.filter((item) => {
|
|
80
|
+
return o(item).get(labelKey)?.includes(qs) ?? false;
|
|
81
|
+
});
|
|
82
|
+
setTempOption(qs, _filteredOptions);
|
|
83
|
+
filteredOptions.value = _filteredOptions;
|
|
84
|
+
};
|
|
85
|
+
const debouncedLocalFilter = debounce((qs, propsOptions) => {
|
|
86
|
+
if (!queryString.value) {
|
|
87
|
+
applyLocalFilter("", propsOptions);
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
applyLocalFilter(qs, propsOptions);
|
|
91
|
+
}, 200);
|
|
92
|
+
const debouncedRemoteFilter = debounce(async (qs, propsOptions) => {
|
|
93
|
+
const options = await propsOptions(queryString.value);
|
|
94
|
+
remoteOptions.value = options;
|
|
95
|
+
setTempOption(queryString.value, options);
|
|
96
|
+
}, 200);
|
|
97
|
+
watch([
|
|
98
|
+
queryString,
|
|
99
|
+
() => props.options,
|
|
100
|
+
createdOptions
|
|
101
|
+
], ([qs, propsOptions]) => {
|
|
53
102
|
if (typeof propsOptions === "function") {
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
filteredOptions.value = propsOptions ?? [];
|
|
61
|
-
setTempOption(qs, filteredOptions.value);
|
|
62
|
-
return;
|
|
63
|
-
}
|
|
64
|
-
const _filteredOptions = propsOptions?.filter((item) => {
|
|
65
|
-
return o(item).get(labelKey)?.includes(qs) ?? false;
|
|
66
|
-
}) ?? [];
|
|
67
|
-
setTempOption(qs, _filteredOptions);
|
|
68
|
-
filteredOptions.value = _filteredOptions;
|
|
103
|
+
debouncedRemoteFilter(qs, propsOptions);
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
if (!qs) {
|
|
107
|
+
applyLocalFilter("", propsOptions);
|
|
108
|
+
return;
|
|
69
109
|
}
|
|
70
|
-
|
|
110
|
+
debouncedLocalFilter(qs, propsOptions);
|
|
111
|
+
}, { immediate: true });
|
|
71
112
|
return {
|
|
72
113
|
queryString,
|
|
73
114
|
options,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-options.js","names":["o","chainObj"],"sources":["../../../src/components/select/use-options.ts"],"sourcesContent":["import { debounce, o as chainObj } from '@cat-kit/core'\nimport { fieldKey } from '@veltra/utils'\nimport { computed, shallowRef, watch, type ShallowRef, type ComputedRef } from 'vue'\n\nimport type { SelectProps } from '../../types'\n\ninterface Options {\n props: SelectProps\n}\n\ninterface UseOptionsReturned {\n /** 查询字符串 */\n queryString: ShallowRef<string>\n /** 选项 */\n options: ComputedRef<Record<string, any>[]>\n /** 所有选项 */\n allOptions: ComputedRef<Record<string, any>[]>\n /** 将临时选项转换为创建的选项 */\n temOptionsToCreatedOptions: () => void\n /** 清空用户创建的选项 */\n clearCreatedOptions: () => void\n}\n\n// 允许创建的实现\n// 1. 在过滤时将选项加入待选列表中\n// 2.
|
|
1
|
+
{"version":3,"file":"use-options.js","names":["o","chainObj"],"sources":["../../../src/components/select/use-options.ts"],"sourcesContent":["import { debounce, o as chainObj } from '@cat-kit/core'\nimport { fieldKey } from '@veltra/utils'\nimport { computed, shallowRef, watch, type ShallowRef, type ComputedRef } from 'vue'\n\nimport type { SelectProps } from '../../types'\n\ninterface Options {\n props: SelectProps\n}\n\ninterface UseOptionsReturned {\n /** 查询字符串 */\n queryString: ShallowRef<string>\n /** 选项 */\n options: ComputedRef<Record<string, any>[]>\n /** 所有选项 */\n allOptions: ComputedRef<Record<string, any>[]>\n /** 将临时选项转换为创建的选项 */\n temOptionsToCreatedOptions: () => void\n /** 清空用户创建的选项 */\n clearCreatedOptions: () => void\n}\n\n// 允许创建的实现\n// 1. 在过滤时将选项加入待选列表中\n// 2. 如果选择了该临时选项,则取消该选项的临时标记并并入已创建列表\n// 3. 多次创建累计保留,已创建项参与后续过滤匹配\n\nexport function useOptions(o: Options): UseOptionsReturned {\n const { props } = o\n\n /** 筛选 */\n const queryString = shallowRef('')\n\n const remoteOptions = shallowRef<Record<string, any>[]>([])\n const filteredOptions = shallowRef<Record<string, any>[]>([])\n // 临时选项\n const tempOptions = shallowRef<({ __isTemp: true } & Record<string, any>)[]>([])\n // 创建的选项\n const createdOptions = shallowRef<({ __isTemp: false } & Record<string, any>)[]>([])\n\n function getSourceOptions(propsOptions: SelectProps['options']) {\n if (typeof propsOptions === 'function') return remoteOptions.value\n return [...createdOptions.value, ...(propsOptions ?? [])]\n }\n\n /** 无查询时同步展示完整列表(含已创建项),避免选择后等高亮索引错位 */\n function resetToSourceOptions() {\n const sourceOptions = getSourceOptions(props.options)\n if (typeof props.options === 'function') {\n setTempOption('', remoteOptions.value)\n return\n }\n filteredOptions.value = sourceOptions\n tempOptions.value = []\n }\n\n function temOptionsToCreatedOptions() {\n if (!tempOptions.value.length) return\n\n createdOptions.value = [\n ...createdOptions.value,\n ...tempOptions.value.map((item) => {\n return { ...item, __isTemp: false as const }\n })\n ]\n // 立即清掉临时项并回到完整列表,不等待过滤防抖\n resetToSourceOptions()\n }\n\n function clearCreatedOptions() {\n createdOptions.value = []\n resetToSourceOptions()\n }\n\n const setTempOption = (qs: string, options?: Record<string, any>[]) => {\n if (!qs?.trim() || !props.creatable) {\n tempOptions.value = []\n return\n }\n const labelKey = fieldKey(props.labelKey, 'label')\n const valueKey = fieldKey(props.valueKey, 'value')\n const exactMatch = options\n ? options.some((option) => {\n return chainObj(option).get(labelKey) === qs\n })\n : false\n\n tempOptions.value = exactMatch ? [] : [{ [labelKey]: qs, [valueKey]: qs, __isTemp: true }]\n }\n\n const allOptions = computed(() => {\n const { options } = props\n if (typeof options === 'function') return remoteOptions.value\n return [...createdOptions.value, ...(options ?? [])]\n })\n\n /**\n * 展示的选项\n * @description 已创建选项并入过滤数据源参与匹配;临时选项(待创建)固定置顶\n */\n const options = computed(() => {\n const { options } = props\n\n if (typeof options === 'function') return remoteOptions.value\n\n return [...tempOptions.value, ...filteredOptions.value]\n })\n\n const applyLocalFilter = (qs: string, propsOptions: Record<string, any>[] | undefined) => {\n const labelKey = fieldKey(props.labelKey, 'label')\n const sourceOptions = [...createdOptions.value, ...(propsOptions ?? [])]\n\n if (!qs) {\n filteredOptions.value = sourceOptions\n setTempOption(qs, filteredOptions.value)\n return\n }\n\n const _filteredOptions = sourceOptions.filter((item) => {\n return chainObj(item).get(labelKey)?.includes(qs) ?? false\n })\n\n setTempOption(qs, _filteredOptions)\n filteredOptions.value = _filteredOptions\n }\n\n // 仅对「有查询词」的本地过滤做防抖;清空查询同步生效,避免选中后列表延迟重建\n const debouncedLocalFilter = debounce(\n (qs: string, propsOptions: Record<string, any>[] | undefined) => {\n // 防抖回调可能晚于清空查询到达,以当前 queryString 为准\n if (!queryString.value) {\n applyLocalFilter('', propsOptions)\n return\n }\n applyLocalFilter(qs, propsOptions)\n },\n 200\n )\n\n const debouncedRemoteFilter = debounce(async (qs: string, propsOptions: Function) => {\n const options = await propsOptions(queryString.value)\n remoteOptions.value = options\n setTempOption(queryString.value, options)\n }, 200)\n\n watch(\n [queryString, () => props.options, createdOptions],\n ([qs, propsOptions]) => {\n if (typeof propsOptions === 'function') {\n debouncedRemoteFilter(qs, propsOptions)\n return\n }\n\n if (!qs) {\n applyLocalFilter('', propsOptions)\n return\n }\n\n debouncedLocalFilter(qs, propsOptions)\n },\n { immediate: true }\n )\n\n return { queryString, options, allOptions, temOptionsToCreatedOptions, clearCreatedOptions }\n}\n"],"mappings":"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"}
|
|
@@ -7,11 +7,11 @@ type __VLS_Slots = {
|
|
|
7
7
|
tip?: (scope: StepsSlotScope) => any;
|
|
8
8
|
};
|
|
9
9
|
declare const __VLS_base: import("vue").DefineComponent<StepsProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
|
|
10
|
-
"item-click": (item: Record<string, any>, index: number) => any;
|
|
11
10
|
"update:current": (value?: string | number | undefined) => any;
|
|
11
|
+
"item-click": (item: Record<string, any>, index: number) => any;
|
|
12
12
|
}, string, import("vue").PublicProps, Readonly<StepsProps> & Readonly<{
|
|
13
|
-
"onItem-click"?: ((item: Record<string, any>, index: number) => any) | undefined;
|
|
14
13
|
"onUpdate:current"?: ((value?: string | number | undefined) => any) | undefined;
|
|
14
|
+
"onItem-click"?: ((item: Record<string, any>, index: number) => any) | undefined;
|
|
15
15
|
}>, {
|
|
16
16
|
labelKey: string;
|
|
17
17
|
direction: "horizontal" | "vertical";
|
|
@@ -10,22 +10,22 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {},
|
|
|
10
10
|
"update:modelValue": (value: string | undefined) => any;
|
|
11
11
|
} & {
|
|
12
12
|
"update:modelValue": (value: string) => any;
|
|
13
|
-
change: (value: string) => any;
|
|
14
13
|
clear: () => any;
|
|
14
|
+
change: (value: string) => any;
|
|
15
15
|
focus: () => any;
|
|
16
16
|
blur: () => any;
|
|
17
17
|
}, string, import("vue").PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
|
|
18
18
|
"onUpdate:modelValue"?: ((value: string) => any) | undefined;
|
|
19
|
-
onChange?: ((value: string) => any) | undefined;
|
|
20
19
|
onClear?: (() => any) | undefined;
|
|
20
|
+
onChange?: ((value: string) => any) | undefined;
|
|
21
21
|
onFocus?: (() => any) | undefined;
|
|
22
22
|
onBlur?: (() => any) | undefined;
|
|
23
23
|
}>, {
|
|
24
|
-
|
|
25
|
-
readonly: boolean;
|
|
24
|
+
resize: boolean;
|
|
26
25
|
placeholder: string;
|
|
27
26
|
clearable: boolean;
|
|
28
|
-
|
|
27
|
+
disabled: boolean;
|
|
28
|
+
readonly: boolean;
|
|
29
29
|
autosize: boolean;
|
|
30
30
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
31
31
|
declare const _default: typeof __VLS_export;
|
|
@@ -11,10 +11,10 @@ declare const __VLS_base: import("vue").DefineComponent<TipProps, {}, {}, {}, {}
|
|
|
11
11
|
}, string, import("vue").PublicProps, Readonly<TipProps> & Readonly<{
|
|
12
12
|
"onUpdate:visible"?: ((value: boolean) => any) | undefined;
|
|
13
13
|
}>, {
|
|
14
|
-
direction: TipDirection;
|
|
15
14
|
trigger: "hover" | "click";
|
|
16
15
|
contentTag: string;
|
|
17
16
|
visible: boolean;
|
|
17
|
+
direction: TipDirection;
|
|
18
18
|
content: string;
|
|
19
19
|
alignment: TipAlign;
|
|
20
20
|
showDelay: number;
|
|
@@ -12,36 +12,33 @@ function useTreeNodes(options) {
|
|
|
12
12
|
const nodeDictRef = shallowRef(/* @__PURE__ */ new Map());
|
|
13
13
|
const nodes = shallowRef([]);
|
|
14
14
|
function buildForest() {
|
|
15
|
-
const {
|
|
15
|
+
const { expandAll = false } = props;
|
|
16
16
|
const childrenKey = props.childrenKey ?? "children";
|
|
17
17
|
const valueKey = fieldKey(props.valueKey, "value");
|
|
18
18
|
const labelKey = fieldKey(props.labelKey, "label");
|
|
19
|
-
function createNode(data, index, depth, parent) {
|
|
20
|
-
const node = new TreeNode$1({
|
|
21
|
-
data,
|
|
22
|
-
index,
|
|
23
|
-
depth,
|
|
24
|
-
parent,
|
|
25
|
-
valueKey,
|
|
26
|
-
labelKey
|
|
27
|
-
});
|
|
28
|
-
node.expanded = expandAll;
|
|
29
|
-
return node;
|
|
30
|
-
}
|
|
31
19
|
return new Forest({
|
|
32
20
|
data: props.data ?? [],
|
|
33
21
|
childrenKey,
|
|
34
|
-
createNode:
|
|
35
|
-
const node =
|
|
36
|
-
|
|
22
|
+
createNode: (data, index, depth, _f, parent) => {
|
|
23
|
+
const node = new TreeNode$1({
|
|
24
|
+
data,
|
|
25
|
+
index,
|
|
26
|
+
depth,
|
|
27
|
+
parent,
|
|
28
|
+
valueKey,
|
|
29
|
+
labelKey
|
|
30
|
+
});
|
|
31
|
+
node.expanded = expandAll;
|
|
37
32
|
return node;
|
|
38
|
-
}
|
|
33
|
+
}
|
|
39
34
|
});
|
|
40
35
|
}
|
|
41
36
|
function rebuildForest() {
|
|
42
37
|
const nextForest = buildForest();
|
|
43
38
|
const nextDict = /* @__PURE__ */ new Map();
|
|
39
|
+
const { disabledNode } = props;
|
|
44
40
|
nextForest.dfs((node) => {
|
|
41
|
+
if (disabledNode && node.data) node.disabled = disabledNode(node.data, node) ?? false;
|
|
45
42
|
nextDict.set(node.key, node);
|
|
46
43
|
});
|
|
47
44
|
forestRef.value = nextForest;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-tree-nodes.js","names":["TreeNode"],"sources":["../../../src/components/tree/use-tree-nodes.ts"],"sourcesContent":["import { Forest } from '@cat-kit/core'\nimport { fieldKey } from '@veltra/utils'\nimport { computed, shallowRef, triggerRef, watch, type ShallowRef, type ComputedRef } from 'vue'\n\nimport type { TreeProps } from '../../types'\nimport { TreeNode } from './tree-node'\n\ninterface Options {\n props: TreeProps\n}\n\ninterface UseTreeNodesReturned {\n nodes: ShallowRef<TreeNode[]>\n forest: ComputedRef<Forest<Record<string, unknown>, any>>\n getFlattedNodes: () => void\n nodeDict: ComputedRef<Map<string | number, TreeNode>>\n /** 强制刷新 `nodes` 的订阅者(供字段级别变化但列表引用不变时手动触发)。 */\n triggerNodes: () => void\n}\n\nexport function useTreeNodes(options: Options): UseTreeNodesReturned {\n const { props } = options\n\n // forest / nodeDict 保持为 shallowRef 而非 computed:\n // - computed 会因为任一 prop 变化(尤其是内联 disabledNode 函数)而整棵重建,\n // 丢失 expanded/checked/visible 等运行时状态;\n // - 显式 watch 仅在真正影响结构的输入变化时才重建,行为可控、可测量。\n const forestRef = shallowRef<Forest<Record<string, unknown>, any>>(\n new Forest<Record<string, unknown>, any>({\n data: [],\n childrenKey: props.childrenKey ?? 'children'\n })\n )\n\n const nodeDictRef = shallowRef<Map<string | number, TreeNode>>(new Map())\n\n const nodes = shallowRef<TreeNode[]>([])\n\n function buildForest(): Forest<Record<string, unknown>, any> {\n const {
|
|
1
|
+
{"version":3,"file":"use-tree-nodes.js","names":["TreeNode"],"sources":["../../../src/components/tree/use-tree-nodes.ts"],"sourcesContent":["import { Forest } from '@cat-kit/core'\nimport { fieldKey } from '@veltra/utils'\nimport { computed, shallowRef, triggerRef, watch, type ShallowRef, type ComputedRef } from 'vue'\n\nimport type { TreeProps } from '../../types'\nimport { TreeNode } from './tree-node'\n\ninterface Options {\n props: TreeProps\n}\n\ninterface UseTreeNodesReturned {\n nodes: ShallowRef<TreeNode[]>\n forest: ComputedRef<Forest<Record<string, unknown>, any>>\n getFlattedNodes: () => void\n nodeDict: ComputedRef<Map<string | number, TreeNode>>\n /** 强制刷新 `nodes` 的订阅者(供字段级别变化但列表引用不变时手动触发)。 */\n triggerNodes: () => void\n}\n\nexport function useTreeNodes(options: Options): UseTreeNodesReturned {\n const { props } = options\n\n // forest / nodeDict 保持为 shallowRef 而非 computed:\n // - computed 会因为任一 prop 变化(尤其是内联 disabledNode 函数)而整棵重建,\n // 丢失 expanded/checked/visible 等运行时状态;\n // - 显式 watch 仅在真正影响结构的输入变化时才重建,行为可控、可测量。\n const forestRef = shallowRef<Forest<Record<string, unknown>, any>>(\n new Forest<Record<string, unknown>, any>({\n data: [],\n childrenKey: props.childrenKey ?? 'children'\n })\n )\n\n const nodeDictRef = shallowRef<Map<string | number, TreeNode>>(new Map())\n\n const nodes = shallowRef<TreeNode[]>([])\n\n function buildForest(): Forest<Record<string, unknown>, any> {\n const { expandAll = false } = props\n const childrenKey = props.childrenKey ?? 'children'\n const valueKey = fieldKey(props.valueKey, 'value')\n const labelKey = fieldKey(props.labelKey, 'label')\n\n return new Forest<Record<string, unknown>, any>({\n data: (props.data ?? []) as Record<string, unknown>[],\n childrenKey,\n createNode: (data, index, depth, _f, parent) => {\n const node = new TreeNode({\n data: data as Record<string, any>,\n index,\n depth,\n parent: parent as TreeNode | undefined,\n valueKey,\n labelKey\n })\n node.expanded = expandAll\n return node\n }\n })\n }\n\n function rebuildForest(): void {\n const nextForest = buildForest()\n const nextDict = new Map<string | number, TreeNode>()\n const { disabledNode } = props\n\n // Forest 的 createNode 返回时 children 尚未挂载,因此 disabledNode 必须在\n // 整棵树构建完成后再调用,才能安全访问 node.children / node.isLeaf。\n nextForest.dfs((node) => {\n if (disabledNode && node.data) {\n node.disabled = disabledNode(node.data as Record<string, any>, node) ?? false\n }\n nextDict.set(node.key, node)\n })\n\n forestRef.value = nextForest\n nodeDictRef.value = nextDict\n\n getFlattedNodes()\n }\n\n /** 按展开与可见性扁平化:仅一次 DFS。 */\n function getFlattedNodes(): void {\n const result: TreeNode[] = []\n const roots = forestRef.value.roots as TreeNode[]\n\n const stack: TreeNode[] = []\n for (let i = roots.length - 1; i >= 0; i--) {\n stack.push(roots[i]!)\n }\n\n while (stack.length) {\n const node = stack.pop()!\n if (!node.visible) continue\n result.push(node)\n if (node.expanded && node.children && node.children.length) {\n for (let i = node.children.length - 1; i >= 0; i--) {\n stack.push(node.children[i]!)\n }\n }\n }\n\n nodes.value = result\n }\n\n function triggerNodes(): void {\n triggerRef(nodes)\n }\n\n watch(\n [\n () => props.data,\n () => props.disabledNode,\n () => props.childrenKey,\n () => props.valueKey,\n () => props.labelKey,\n () => props.expandAll\n ],\n () => {\n rebuildForest()\n },\n { immediate: true }\n )\n\n const forest = computed(() => forestRef.value)\n const nodeDict = computed(() => nodeDictRef.value)\n\n return { nodes, forest, getFlattedNodes, nodeDict, triggerNodes }\n}\n"],"mappings":";;;;;AAoBA,SAAgB,aAAa,SAAwC;CACnE,MAAM,EAAE,UAAU;CAMlB,MAAM,YAAY,WAChB,IAAI,OAAqC;EACvC,MAAM,CAAC;EACP,aAAa,MAAM,eAAe;CACpC,CAAC,CACH;CAEA,MAAM,cAAc,2BAA2C,IAAI,IAAI,CAAC;CAExE,MAAM,QAAQ,WAAuB,CAAC,CAAC;CAEvC,SAAS,cAAoD;EAC3D,MAAM,EAAE,YAAY,UAAU;EAC9B,MAAM,cAAc,MAAM,eAAe;EACzC,MAAM,WAAW,SAAS,MAAM,UAAU,OAAO;EACjD,MAAM,WAAW,SAAS,MAAM,UAAU,OAAO;EAEjD,OAAO,IAAI,OAAqC;GAC9C,MAAO,MAAM,QAAQ,CAAC;GACtB;GACA,aAAa,MAAM,OAAO,OAAO,IAAI,WAAW;IAC9C,MAAM,OAAO,IAAIA,WAAS;KAClB;KACN;KACA;KACQ;KACR;KACA;IACF,CAAC;IACD,KAAK,WAAW;IAChB,OAAO;GACT;EACF,CAAC;CACH;CAEA,SAAS,gBAAsB;EAC7B,MAAM,aAAa,YAAY;EAC/B,MAAM,2BAAW,IAAI,IAA+B;EACpD,MAAM,EAAE,iBAAiB;EAIzB,WAAW,KAAK,SAAS;GACvB,IAAI,gBAAgB,KAAK,MACvB,KAAK,WAAW,aAAa,KAAK,MAA6B,IAAI,KAAK;GAE1E,SAAS,IAAI,KAAK,KAAK,IAAI;EAC7B,CAAC;EAED,UAAU,QAAQ;EAClB,YAAY,QAAQ;EAEpB,gBAAgB;CAClB;;CAGA,SAAS,kBAAwB;EAC/B,MAAM,SAAqB,CAAC;EAC5B,MAAM,QAAQ,UAAU,MAAM;EAE9B,MAAM,QAAoB,CAAC;EAC3B,KAAK,IAAI,IAAI,MAAM,SAAS,GAAG,KAAK,GAAG,KACrC,MAAM,KAAK,MAAM,EAAG;EAGtB,OAAO,MAAM,QAAQ;GACnB,MAAM,OAAO,MAAM,IAAI;GACvB,IAAI,CAAC,KAAK,SAAS;GACnB,OAAO,KAAK,IAAI;GAChB,IAAI,KAAK,YAAY,KAAK,YAAY,KAAK,SAAS,QAClD,KAAK,IAAI,IAAI,KAAK,SAAS,SAAS,GAAG,KAAK,GAAG,KAC7C,MAAM,KAAK,KAAK,SAAS,EAAG;EAGlC;EAEA,MAAM,QAAQ;CAChB;CAEA,SAAS,eAAqB;EAC5B,WAAW,KAAK;CAClB;CAEA,MACE;QACQ,MAAM;QACN,MAAM;QACN,MAAM;QACN,MAAM;QACN,MAAM;QACN,MAAM;CACd,SACM;EACJ,cAAc;CAChB,GACA,EAAE,WAAW,KAAK,CACpB;CAKA,OAAO;EAAE;EAAO,QAHD,eAAe,UAAU,KAGnB;EAAG;EAAiB,UAFxB,eAAe,YAAY,KAEI;EAAG;CAAa;AAClE"}
|
|
@@ -35,8 +35,8 @@
|
|
|
35
35
|
padding: 0;
|
|
36
36
|
background: none;
|
|
37
37
|
}
|
|
38
|
-
.u-tree-
|
|
39
|
-
|
|
38
|
+
.u-tree-select__clear {
|
|
39
|
+
cursor: pointer;
|
|
40
40
|
}
|
|
41
41
|
.u-tree-select__content-header {
|
|
42
42
|
padding: 4px 12px;
|
|
@@ -48,35 +48,26 @@
|
|
|
48
48
|
flex-wrap: nowrap;
|
|
49
49
|
}
|
|
50
50
|
.u-tree-select__content-tree {
|
|
51
|
-
max-height:
|
|
52
|
-
}
|
|
53
|
-
.u-tree-select__panel--small .u-tree-select__content-filter {
|
|
54
|
-
padding: calc(var(--u-gap-small) / 2) var(--u-gap-small);
|
|
51
|
+
max-height: 240px;
|
|
55
52
|
}
|
|
56
53
|
.u-tree-select__panel--small .u-tree-select__content-tree {
|
|
57
|
-
padding:
|
|
54
|
+
padding: var(--u-gap-small);
|
|
58
55
|
}
|
|
59
56
|
.u-tree-select__panel--small .u-tree-select__empty {
|
|
60
57
|
height: var(--u-form-component-height-small);
|
|
61
58
|
line-height: var(--u-form-component-height-small);
|
|
62
59
|
padding: 0 var(--u-gap-small);
|
|
63
60
|
}
|
|
64
|
-
.u-tree-select__panel--default .u-tree-select__content-filter {
|
|
65
|
-
padding: calc(var(--u-gap-default) / 2) var(--u-gap-default);
|
|
66
|
-
}
|
|
67
61
|
.u-tree-select__panel--default .u-tree-select__content-tree {
|
|
68
|
-
padding:
|
|
62
|
+
padding: var(--u-gap-default);
|
|
69
63
|
}
|
|
70
64
|
.u-tree-select__panel--default .u-tree-select__empty {
|
|
71
65
|
height: var(--u-form-component-height-default);
|
|
72
66
|
line-height: var(--u-form-component-height-default);
|
|
73
67
|
padding: 0 var(--u-gap-default);
|
|
74
68
|
}
|
|
75
|
-
.u-tree-select__panel--large .u-tree-select__content-filter {
|
|
76
|
-
padding: calc(var(--u-gap-large) / 2) var(--u-gap-large);
|
|
77
|
-
}
|
|
78
69
|
.u-tree-select__panel--large .u-tree-select__content-tree {
|
|
79
|
-
padding:
|
|
70
|
+
padding: var(--u-gap-large);
|
|
80
71
|
}
|
|
81
72
|
.u-tree-select__panel--large .u-tree-select__empty {
|
|
82
73
|
height: var(--u-form-component-height-large);
|
|
@@ -2,10 +2,10 @@ import _sfc_main$1 from "../icon/icon.js";
|
|
|
2
2
|
import _sfc_main$2 from "../dropdown/dropdown.js";
|
|
3
3
|
import input_default from "../input/input.js";
|
|
4
4
|
import _sfc_main$3 from "../tree/tree.js";
|
|
5
|
-
import { Fragment, computed, createBlock, createCommentVNode, createElementBlock, createSlots, createTextVNode, createVNode, defineComponent, mergeModels, mergeProps, nextTick, normalizeClass, openBlock, renderSlot, shallowRef, toDisplayString, unref, useModel, useSlots, watch, withCtx } from "vue";
|
|
5
|
+
import { Fragment, Transition, computed, createBlock, createCommentVNode, createElementBlock, createSlots, createTextVNode, createVNode, defineComponent, mergeModels, mergeProps, nextTick, normalizeClass, openBlock, renderSlot, shallowRef, toDisplayString, unref, useModel, useSlots, useTemplateRef, watch, withCtx, withModifiers } from "vue";
|
|
6
6
|
import { useFormFallbackProps } from "@veltra/compositions";
|
|
7
7
|
import { FORM_EMPTY_CONTENT, bem, fieldKey, injectFormContext } from "@veltra/utils";
|
|
8
|
-
import { ArrowDown,
|
|
8
|
+
import { ArrowDown, Close } from "@veltra/icons/normal";
|
|
9
9
|
import { dfs, o } from "@cat-kit/core";
|
|
10
10
|
//#region src/components/tree-select/tree-select.vue
|
|
11
11
|
const _sfc_main = /*@__PURE__*/ defineComponent({
|
|
@@ -93,6 +93,52 @@ const _sfc_main = /*@__PURE__*/ defineComponent({
|
|
|
93
93
|
});
|
|
94
94
|
const model = useModel(__props, "modelValue");
|
|
95
95
|
const label = shallowRef();
|
|
96
|
+
const dropdownVisible = shallowRef(false);
|
|
97
|
+
/**
|
|
98
|
+
* 是否处于查询态:决定触发输入框显示查询串还是选中标签。
|
|
99
|
+
* 与面板可见状态解耦 —— 选择后立即退出查询态,
|
|
100
|
+
* 不等面板关闭动画结束(否则显示值会延迟一个动画时长才恢复)。
|
|
101
|
+
*/
|
|
102
|
+
const querying = shallowRef(false);
|
|
103
|
+
const inputRef = useTemplateRef("inputRef");
|
|
104
|
+
/** 触发输入框的值:查询态下承载查询串,否则展示选中标签 */
|
|
105
|
+
const inputValue = computed(() => {
|
|
106
|
+
if (props.filterable && querying.value) return qs.value;
|
|
107
|
+
return props.text ?? (model.value ? label.value : void 0);
|
|
108
|
+
});
|
|
109
|
+
/** 查询态下已选标签降级为占位提示 */
|
|
110
|
+
const inputPlaceholder = computed(() => {
|
|
111
|
+
const display = props.text ?? (model.value ? label.value : void 0);
|
|
112
|
+
if (props.filterable && querying.value && display) return display;
|
|
113
|
+
return props.placeholder;
|
|
114
|
+
});
|
|
115
|
+
function handleQueryInput(value) {
|
|
116
|
+
if (!props.filterable) return;
|
|
117
|
+
qs.value = value;
|
|
118
|
+
}
|
|
119
|
+
const hovered = shallowRef(false);
|
|
120
|
+
/** 悬停且存在选中值时展示清除按钮(替代下拉箭头) */
|
|
121
|
+
const showClear = computed(() => {
|
|
122
|
+
if (!props.clearable || disabled.value || !hovered.value) return false;
|
|
123
|
+
return !!(props.text ?? (model.value ? label.value : void 0));
|
|
124
|
+
});
|
|
125
|
+
/**
|
|
126
|
+
* 过滤模式下拦截输入区域的点击:
|
|
127
|
+
* 阻止 dropdown 的 trigger 开合切换,保持面板展开以不中断输入。
|
|
128
|
+
* 非输入区域(箭头、留白)放行,维持原开合行为。
|
|
129
|
+
*/
|
|
130
|
+
function handleTriggerClickCapture(e) {
|
|
131
|
+
if (!props.filterable || disabled.value) return;
|
|
132
|
+
if (!(e.target instanceof HTMLInputElement)) return;
|
|
133
|
+
e.stopPropagation();
|
|
134
|
+
if (!dropdownVisible.value) dropdownRef.value?.open();
|
|
135
|
+
}
|
|
136
|
+
watch(dropdownVisible, (visible) => {
|
|
137
|
+
if (visible && props.filterable) {
|
|
138
|
+
querying.value = true;
|
|
139
|
+
nextTick(() => inputRef.value?.el?.focus());
|
|
140
|
+
} else if (!visible) querying.value = false;
|
|
141
|
+
});
|
|
96
142
|
const { formProps } = injectFormContext();
|
|
97
143
|
const { size, disabled, readonly } = useFormFallbackProps([formProps ?? {}, props]);
|
|
98
144
|
const treeRef = shallowRef();
|
|
@@ -136,6 +182,8 @@ const _sfc_main = /*@__PURE__*/ defineComponent({
|
|
|
136
182
|
else label.value = "";
|
|
137
183
|
emit("change", selectedData);
|
|
138
184
|
emit("update:text", label.value);
|
|
185
|
+
querying.value = false;
|
|
186
|
+
qs.value = "";
|
|
139
187
|
dropdownRef.value?.close();
|
|
140
188
|
};
|
|
141
189
|
const handleDropdownVisible = (visible) => {
|
|
@@ -153,24 +201,47 @@ const _sfc_main = /*@__PURE__*/ defineComponent({
|
|
|
153
201
|
"content-style": __props.contentStyle,
|
|
154
202
|
ref_key: "dropdownRef",
|
|
155
203
|
ref: dropdownRef,
|
|
204
|
+
visible: dropdownVisible.value,
|
|
205
|
+
"onUpdate:visible": [_cache[0] || (_cache[0] = ($event) => dropdownVisible.value = $event), handleDropdownVisible],
|
|
156
206
|
"min-width": __props.minWidth,
|
|
157
207
|
width: __props.width,
|
|
158
208
|
disabled: unref(disabled),
|
|
159
|
-
|
|
209
|
+
onMouseenter: _cache[1] || (_cache[1] = ($event) => hovered.value = true),
|
|
210
|
+
onMouseleave: _cache[2] || (_cache[2] = ($event) => hovered.value = false)
|
|
160
211
|
}), {
|
|
161
212
|
trigger: withCtx(() => [createVNode(unref(input_default), {
|
|
213
|
+
ref_key: "inputRef",
|
|
214
|
+
ref: inputRef,
|
|
162
215
|
size: unref(size),
|
|
163
216
|
disabled: unref(disabled),
|
|
164
|
-
placeholder:
|
|
165
|
-
clearable:
|
|
166
|
-
"model-value":
|
|
167
|
-
|
|
168
|
-
"native-readonly":
|
|
217
|
+
placeholder: inputPlaceholder.value,
|
|
218
|
+
clearable: false,
|
|
219
|
+
"model-value": inputValue.value,
|
|
220
|
+
"onUpdate:modelValue": handleQueryInput,
|
|
221
|
+
"native-readonly": !__props.filterable || !querying.value,
|
|
222
|
+
onClickCapture: handleTriggerClickCapture
|
|
169
223
|
}, createSlots({
|
|
170
|
-
suffix: withCtx(() => [createVNode(
|
|
171
|
-
|
|
224
|
+
suffix: withCtx(() => [createVNode(Transition, {
|
|
225
|
+
name: "zoom-in",
|
|
226
|
+
mode: "out-in"
|
|
227
|
+
}, {
|
|
228
|
+
default: withCtx(() => [showClear.value ? (openBlock(), createBlock(unref(_sfc_main$1), {
|
|
229
|
+
class: normalizeClass(unref(cls).e("clear")),
|
|
230
|
+
title: "清除",
|
|
231
|
+
key: "clear",
|
|
232
|
+
onClick: withModifiers(handleClear, ["stop"])
|
|
233
|
+
}, {
|
|
234
|
+
default: withCtx(() => [createVNode(unref(Close))]),
|
|
235
|
+
_: 1
|
|
236
|
+
}, 8, ["class"])) : (openBlock(), createBlock(unref(_sfc_main$1), {
|
|
237
|
+
class: normalizeClass(unref(cls).e("arrow")),
|
|
238
|
+
key: "arrow"
|
|
239
|
+
}, {
|
|
240
|
+
default: withCtx(() => [createVNode(unref(ArrowDown))]),
|
|
241
|
+
_: 1
|
|
242
|
+
}, 8, ["class"]))]),
|
|
172
243
|
_: 1
|
|
173
|
-
}
|
|
244
|
+
})]),
|
|
174
245
|
_: 2
|
|
175
246
|
}, [_ctx.$slots.prefix ? {
|
|
176
247
|
name: "prefix",
|
|
@@ -180,42 +251,25 @@ const _sfc_main = /*@__PURE__*/ defineComponent({
|
|
|
180
251
|
"size",
|
|
181
252
|
"disabled",
|
|
182
253
|
"placeholder",
|
|
183
|
-
"
|
|
184
|
-
"
|
|
254
|
+
"model-value",
|
|
255
|
+
"native-readonly"
|
|
185
256
|
])]),
|
|
186
|
-
content: withCtx(() => [
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
suffix: withCtx(() => [createVNode(unref(_sfc_main$1), null, {
|
|
197
|
-
default: withCtx(() => [createVNode(unref(Search))]),
|
|
198
|
-
_: 1
|
|
199
|
-
})]),
|
|
200
|
-
_: 1
|
|
201
|
-
}, 8, ["modelValue"])], 2)) : createCommentVNode("v-if", true),
|
|
202
|
-
createCommentVNode(" 菜单列表 "),
|
|
203
|
-
createVNode(unref(_sfc_main$3), mergeProps(treeProps.value, {
|
|
204
|
-
selected: model.value,
|
|
205
|
-
"onUpdate:selected": handleSelect,
|
|
206
|
-
ref_key: "treeRef",
|
|
207
|
-
ref: treeRef,
|
|
208
|
-
selectable: "",
|
|
209
|
-
class: unref(cls).e("content-tree"),
|
|
210
|
-
slots,
|
|
211
|
-
"scroll-to-view": ""
|
|
212
|
-
}), null, 16, ["selected", "class"])
|
|
213
|
-
]),
|
|
257
|
+
content: withCtx(() => [createCommentVNode(" 菜单列表 "), createVNode(unref(_sfc_main$3), mergeProps(treeProps.value, {
|
|
258
|
+
selected: model.value,
|
|
259
|
+
"onUpdate:selected": handleSelect,
|
|
260
|
+
ref_key: "treeRef",
|
|
261
|
+
ref: treeRef,
|
|
262
|
+
selectable: "",
|
|
263
|
+
class: unref(cls).e("content-tree"),
|
|
264
|
+
slots,
|
|
265
|
+
"scroll-to-view": ""
|
|
266
|
+
}), null, 16, ["selected", "class"])]),
|
|
214
267
|
_: 3
|
|
215
268
|
}, 16, [
|
|
216
269
|
"class",
|
|
217
270
|
"content-class",
|
|
218
271
|
"content-style",
|
|
272
|
+
"visible",
|
|
219
273
|
"min-width",
|
|
220
274
|
"width",
|
|
221
275
|
"disabled"
|