@neatui/vue 4.2.0 → 4.2.1
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/package.json +2 -2
- package/src/components/basic/LayerView/Layer.vue +11 -2
- package/src/components/form/MoreSelect.vue +2 -1
- package/src/components/form/SearchMoreSelect.vue +2 -1
- package/src/components/form/SearchSelect.vue +2 -1
- package/src/components/form/Select.vue +2 -1
- package/src/components/form/optionSearch.ts +31 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@neatui/vue",
|
|
3
|
-
"version": "4.2.
|
|
3
|
+
"version": "4.2.1",
|
|
4
4
|
"description": "basic component ui",
|
|
5
5
|
"main": "./src/index.ts",
|
|
6
6
|
"license": "MIT",
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"@fekit/scrollto": "^3.0.3",
|
|
35
35
|
"@fekit/toast": "^2.7.2",
|
|
36
36
|
"@fekit/utils": "^6.0.0",
|
|
37
|
-
"@neatui/css": "^4.2.
|
|
37
|
+
"@neatui/css": "^4.2.1",
|
|
38
38
|
"@rollup/plugin-commonjs": "^26.0.1",
|
|
39
39
|
"@rollup/plugin-node-resolve": "^15.2.3",
|
|
40
40
|
"@vue/compiler-sfc": "^3.4.30",
|
|
@@ -107,7 +107,8 @@
|
|
|
107
107
|
const topId = stack[stack.length - 1];
|
|
108
108
|
if (!topId) return;
|
|
109
109
|
const layer = _tasks[topId];
|
|
110
|
-
|
|
110
|
+
// 禁止 ESC:显式 escClose=false,或禁止暗层关闭时同步禁 ESC
|
|
111
|
+
if (!layer || layer.view !== 3 || layer.escClose === false || layer.darkClickClose === false) return;
|
|
111
112
|
layer.hide();
|
|
112
113
|
ev.preventDefault();
|
|
113
114
|
};
|
|
@@ -333,6 +334,14 @@
|
|
|
333
334
|
{ immediate: true },
|
|
334
335
|
);
|
|
335
336
|
|
|
337
|
+
watch(
|
|
338
|
+
() => props.darkClickClose,
|
|
339
|
+
(darkClickClose) => {
|
|
340
|
+
if (_tasks[props.id]) _tasks[props.id].darkClickClose = darkClickClose;
|
|
341
|
+
},
|
|
342
|
+
{ immediate: true },
|
|
343
|
+
);
|
|
344
|
+
|
|
336
345
|
// 回调合集
|
|
337
346
|
const on: any = {
|
|
338
347
|
show: [],
|
|
@@ -426,7 +435,7 @@
|
|
|
426
435
|
console.error('Layer 有重复 id', id);
|
|
427
436
|
}
|
|
428
437
|
if (id) {
|
|
429
|
-
_tasks[id] = { init, show, hide, open, none, view: state.view, escClose: props.escClose };
|
|
438
|
+
_tasks[id] = { init, show, hide, open, none, view: state.view, escClose: props.escClose, darkClickClose: props.darkClickClose };
|
|
430
439
|
ensureEscapeListener();
|
|
431
440
|
} else {
|
|
432
441
|
console.error('Layer 必须填写全局统一的 id');
|
|
@@ -60,6 +60,7 @@
|
|
|
60
60
|
import { reactive, ref, computed, watch, nextTick } from 'vue';
|
|
61
61
|
import Input from './Input.vue';
|
|
62
62
|
import { IFollowView } from '../basic';
|
|
63
|
+
import { matchOptionSearch } from './optionSearch';
|
|
63
64
|
const ifollow: any = ref(null);
|
|
64
65
|
|
|
65
66
|
const emits = defineEmits(['update:modelValue']);
|
|
@@ -177,7 +178,7 @@
|
|
|
177
178
|
filter: computed(() => {
|
|
178
179
|
if (state.search) {
|
|
179
180
|
return props.options?.filter((item: any) => {
|
|
180
|
-
return item
|
|
181
|
+
return matchOptionSearch(item, state.search);
|
|
181
182
|
});
|
|
182
183
|
} else {
|
|
183
184
|
return props.options;
|
|
@@ -46,6 +46,7 @@
|
|
|
46
46
|
import { reactive, ref, computed } from 'vue';
|
|
47
47
|
import Input from './Input.vue';
|
|
48
48
|
import { IFollowView } from '../basic';
|
|
49
|
+
import { matchOptionSearch } from './optionSearch';
|
|
49
50
|
const ifollow: any = ref(null);
|
|
50
51
|
|
|
51
52
|
const emits = defineEmits(['update:modelValue', 'change', 'request', 'onshow', 'onhide']);
|
|
@@ -118,7 +119,7 @@
|
|
|
118
119
|
filter: computed(() => {
|
|
119
120
|
if (state.search) {
|
|
120
121
|
return props.options?.filter((item) => {
|
|
121
|
-
return item
|
|
122
|
+
return matchOptionSearch(item, state.search);
|
|
122
123
|
});
|
|
123
124
|
} else {
|
|
124
125
|
return props.options;
|
|
@@ -50,6 +50,7 @@
|
|
|
50
50
|
import { reactive, ref, computed } from 'vue';
|
|
51
51
|
import Input from './Input.vue';
|
|
52
52
|
import { IFollowView } from '../basic';
|
|
53
|
+
import { matchOptionSearch } from './optionSearch';
|
|
53
54
|
const ifollow: any = ref(null);
|
|
54
55
|
console.warn('「SearchSelect」 即将废弃,建议使用「Select」 设置参数search为true,示例:<Select v-model="value" :search="true" />');
|
|
55
56
|
const emits = defineEmits(['update:modelValue', 'change', 'onshow', 'onhide']);
|
|
@@ -161,7 +162,7 @@
|
|
|
161
162
|
filter: computed(() => {
|
|
162
163
|
if (state.search) {
|
|
163
164
|
return props.options?.filter((item: any) => {
|
|
164
|
-
return item
|
|
165
|
+
return matchOptionSearch(item, state.search);
|
|
165
166
|
});
|
|
166
167
|
} else {
|
|
167
168
|
return props.options;
|
|
@@ -68,6 +68,7 @@
|
|
|
68
68
|
import { reactive, ref, computed, watch, nextTick } from 'vue';
|
|
69
69
|
import Input from './Input.vue';
|
|
70
70
|
import { IFollowView } from '../basic';
|
|
71
|
+
import { matchOptionSearch } from './optionSearch';
|
|
71
72
|
const ifollow: any = ref(null);
|
|
72
73
|
const customInputRef: any = ref(null);
|
|
73
74
|
|
|
@@ -246,7 +247,7 @@
|
|
|
246
247
|
|
|
247
248
|
if (state.search) {
|
|
248
249
|
filteredOptions = filteredOptions.filter((item: any) => {
|
|
249
|
-
return item
|
|
250
|
+
return matchOptionSearch(item, state.search);
|
|
250
251
|
});
|
|
251
252
|
}
|
|
252
253
|
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 选项搜索:匹配 label / value,以及选项对象上可遍历的全部字段(含嵌套)
|
|
3
|
+
* 大小写不敏感
|
|
4
|
+
*/
|
|
5
|
+
export const matchOptionSearch = (item: any, keyword: unknown): boolean => {
|
|
6
|
+
const q = String(keyword ?? '')
|
|
7
|
+
.trim()
|
|
8
|
+
.toLowerCase();
|
|
9
|
+
if (!q) return true;
|
|
10
|
+
if (item == null) return false;
|
|
11
|
+
|
|
12
|
+
if (typeof item !== 'object') {
|
|
13
|
+
return String(item).toLowerCase().includes(q);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const seen = new WeakSet<object>();
|
|
17
|
+
const walk = (val: any): boolean => {
|
|
18
|
+
if (val == null) return false;
|
|
19
|
+
const t = typeof val;
|
|
20
|
+
if (t === 'string' || t === 'number' || t === 'boolean' || t === 'bigint') {
|
|
21
|
+
return String(val).toLowerCase().includes(q);
|
|
22
|
+
}
|
|
23
|
+
if (t !== 'object') return false;
|
|
24
|
+
if (seen.has(val)) return false;
|
|
25
|
+
seen.add(val);
|
|
26
|
+
if (Array.isArray(val)) return val.some(walk);
|
|
27
|
+
return Object.values(val).some(walk);
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
return walk(item);
|
|
31
|
+
};
|