@v-c/select 1.0.8 → 1.0.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/BaseSelect/index.js +27 -13
- package/dist/SelectInput/Content/SingleContent.js +32 -26
- package/dist/SelectInput/index.js +5 -7
- package/dist/SelectTrigger.d.ts +1 -0
- package/dist/SelectTrigger.js +8 -2
- package/dist/hooks/useBaseProps.d.ts +2 -0
- package/dist/hooks/useOpen.d.ts +3 -3
- package/dist/hooks/useOpen.js +18 -17
- package/dist/hooks/useSelectTriggerControl.d.ts +3 -1
- package/dist/hooks/useSelectTriggerControl.js +6 -2
- package/package.json +6 -6
- package/dist/BaseSelect/Polite.cjs +0 -40
- package/dist/BaseSelect/index.cjs +0 -769
- package/dist/OptGroup.cjs +0 -8
- package/dist/Option.cjs +0 -8
- package/dist/OptionList.cjs +0 -258
- package/dist/Select.cjs +0 -838
- package/dist/SelectContext.cjs +0 -12
- package/dist/SelectInput/Affix.cjs +0 -19
- package/dist/SelectInput/Content/MultipleContent.cjs +0 -145
- package/dist/SelectInput/Content/Placeholder.cjs +0 -36
- package/dist/SelectInput/Content/SingleContent.cjs +0 -83
- package/dist/SelectInput/Content/index.cjs +0 -43
- package/dist/SelectInput/Input.cjs +0 -179
- package/dist/SelectInput/context.cjs +0 -12
- package/dist/SelectInput/index.cjs +0 -343
- package/dist/SelectTrigger.cjs +0 -192
- package/dist/TransBtn.cjs +0 -72
- package/dist/_virtual/rolldown_runtime.cjs +0 -21
- package/dist/hooks/index.cjs +0 -24
- package/dist/hooks/useAllowClear.cjs +0 -18
- package/dist/hooks/useBaseProps.cjs +0 -15
- package/dist/hooks/useCache.cjs +0 -39
- package/dist/hooks/useComponents.cjs +0 -18
- package/dist/hooks/useFilterOptions.cjs +0 -42
- package/dist/hooks/useLock.cjs +0 -29
- package/dist/hooks/useOpen.cjs +0 -62
- package/dist/hooks/useOptions.cjs +0 -41
- package/dist/hooks/useRefFunc.cjs +0 -15
- package/dist/hooks/useSearchConfig.cjs +0 -26
- package/dist/hooks/useSelectTriggerControl.cjs +0 -21
- package/dist/index.cjs +0 -22
- package/dist/interface.cjs +0 -1
- package/dist/utils/commonUtil.cjs +0 -38
- package/dist/utils/keyUtil.cjs +0 -37
- package/dist/utils/legacyUtil.cjs +0 -33
- package/dist/utils/platformUtil.cjs +0 -6
- package/dist/utils/valueUtil.cjs +0 -80
package/dist/BaseSelect/index.js
CHANGED
|
@@ -3,8 +3,8 @@ import { getSeparatedContent, isValidCount } from "../utils/valueUtil.js";
|
|
|
3
3
|
import { useAllowClear } from "../hooks/useAllowClear.js";
|
|
4
4
|
import useComponents from "../hooks/useComponents.js";
|
|
5
5
|
import useLock from "../hooks/useLock.js";
|
|
6
|
-
import useOpen from "../hooks/useOpen.js";
|
|
7
|
-
import useSelectTriggerControl from "../hooks/useSelectTriggerControl.js";
|
|
6
|
+
import useOpen, { macroTask } from "../hooks/useOpen.js";
|
|
7
|
+
import useSelectTriggerControl, { isInside } from "../hooks/useSelectTriggerControl.js";
|
|
8
8
|
import "../hooks/index.js";
|
|
9
9
|
import SelectInput_default from "../SelectInput/index.js";
|
|
10
10
|
import SelectTrigger_default from "../SelectTrigger.js";
|
|
@@ -107,7 +107,7 @@ const BaseSelect = /* @__PURE__ */ defineComponent((props, { expose, attrs }) =>
|
|
|
107
107
|
return props.notFoundContent ?? "Not Found";
|
|
108
108
|
});
|
|
109
109
|
const emptyListContent = computed(() => !props?.notFoundContent && props.emptyOptions);
|
|
110
|
-
const [mergedOpen, triggerOpen] = useOpen(open, (openVal) => {
|
|
110
|
+
const [rawOpen, mergedOpen, triggerOpen, lockOptions] = useOpen(props?.defaultOpen || false, open, (openVal) => {
|
|
111
111
|
props.onPopupVisibleChange?.(openVal);
|
|
112
112
|
}, (nextOpen) => {
|
|
113
113
|
return props.disabled || emptyListContent.value ? false : nextOpen;
|
|
@@ -140,6 +140,9 @@ const BaseSelect = /* @__PURE__ */ defineComponent((props, { expose, attrs }) =>
|
|
|
140
140
|
watch(mergedOpen, () => {
|
|
141
141
|
if (!mergedOpen.value && !multiple.value && mode.value !== "combobox") onInternalSearch("", false, false);
|
|
142
142
|
}, { immediate: true });
|
|
143
|
+
watch(rawOpen, () => {
|
|
144
|
+
if (!rawOpen.value && !multiple.value && mode.value === "combobox") onInternalSearch("", false, false);
|
|
145
|
+
}, { immediate: true });
|
|
143
146
|
watch([disabled, mergedOpen], () => {
|
|
144
147
|
if (disabled.value) {
|
|
145
148
|
triggerOpen(false);
|
|
@@ -152,7 +155,8 @@ const BaseSelect = /* @__PURE__ */ defineComponent((props, { expose, attrs }) =>
|
|
|
152
155
|
const clearLock = getClearLock();
|
|
153
156
|
const { key } = event;
|
|
154
157
|
const isEnterKey = key === KeyCodeStr.Enter;
|
|
155
|
-
|
|
158
|
+
const isSpaceKey = key === KeyCodeStr.Space;
|
|
159
|
+
if (isEnterKey || isSpaceKey) {
|
|
156
160
|
if (mode.value !== "combobox") event.preventDefault();
|
|
157
161
|
if (!mergedOpen.value) triggerOpen(true);
|
|
158
162
|
}
|
|
@@ -173,7 +177,7 @@ const BaseSelect = /* @__PURE__ */ defineComponent((props, { expose, attrs }) =>
|
|
|
173
177
|
values: [removedDisplayValue]
|
|
174
178
|
});
|
|
175
179
|
}
|
|
176
|
-
if (mergedOpen.value && (!isEnterKey || !keyLockRef.value)) {
|
|
180
|
+
if (mergedOpen.value && (!isEnterKey || !keyLockRef.value) && !isSpaceKey) {
|
|
177
181
|
if (isEnterKey) keyLockRef.value = true;
|
|
178
182
|
listRef.value?.onKeyDown?.(event);
|
|
179
183
|
}
|
|
@@ -194,6 +198,9 @@ const BaseSelect = /* @__PURE__ */ defineComponent((props, { expose, attrs }) =>
|
|
|
194
198
|
const onInputBlur = () => {
|
|
195
199
|
keyLockRef.value = false;
|
|
196
200
|
};
|
|
201
|
+
const getSelectElements = () => [getDOM(containerRef), triggerRef.value?.getPopupElement?.()];
|
|
202
|
+
useSelectTriggerControl(getSelectElements, mergedOpen, triggerOpen, computed(() => !!mergedComponents.value.root));
|
|
203
|
+
const internalMouseDownRef = shallowRef(false);
|
|
197
204
|
const onInternalFocus = (event) => {
|
|
198
205
|
focused.value = true;
|
|
199
206
|
if (!disabled.value) {
|
|
@@ -201,27 +208,31 @@ const BaseSelect = /* @__PURE__ */ defineComponent((props, { expose, attrs }) =>
|
|
|
201
208
|
props?.onFocus?.(event);
|
|
202
209
|
}
|
|
203
210
|
};
|
|
211
|
+
const onRootBlur = () => {
|
|
212
|
+
if (mergedOpen.value && !internalMouseDownRef.value) triggerOpen(false, { cancelFun: () => isInside(getSelectElements(), document.activeElement) });
|
|
213
|
+
};
|
|
204
214
|
const onInternalBlur = (event) => {
|
|
205
215
|
focused.value = false;
|
|
206
216
|
if (mergedSearchValue.value) {
|
|
207
217
|
if (mode.value === "tags") props?.onSearch?.(mergedSearchValue.value, { source: "submit" });
|
|
208
218
|
else if (mode.value === "multiple") props?.onSearch?.("", { source: "blur" });
|
|
209
219
|
}
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
props?.onBlur?.(event);
|
|
213
|
-
}
|
|
220
|
+
onRootBlur();
|
|
221
|
+
if (!disabled.value) props?.onBlur?.(event);
|
|
214
222
|
};
|
|
215
223
|
const onInternalMouseDown = (event) => {
|
|
216
224
|
const { target } = event;
|
|
217
|
-
if ((triggerRef?.value?.getPopupElement?.())?.contains?.(target) && triggerOpen) triggerOpen(true
|
|
225
|
+
if ((triggerRef?.value?.getPopupElement?.())?.contains?.(target) && triggerOpen) triggerOpen(true);
|
|
218
226
|
props?.onMouseDown?.(event);
|
|
227
|
+
internalMouseDownRef.value = true;
|
|
228
|
+
macroTask(() => {
|
|
229
|
+
internalMouseDownRef.value = false;
|
|
230
|
+
});
|
|
219
231
|
};
|
|
220
232
|
const forceState = shallowRef({});
|
|
221
233
|
function onPopupMouseEnter() {
|
|
222
234
|
forceState.value = {};
|
|
223
235
|
}
|
|
224
|
-
useSelectTriggerControl(() => [getDOM(containerRef), triggerRef.value?.getPopupElement?.()], mergedOpen, triggerOpen, computed(() => !!mergedComponents.value.root));
|
|
225
236
|
useBaseSelectProvider(computed(() => {
|
|
226
237
|
return {
|
|
227
238
|
...props,
|
|
@@ -229,7 +240,9 @@ const BaseSelect = /* @__PURE__ */ defineComponent((props, { expose, attrs }) =>
|
|
|
229
240
|
open: mergedOpen.value,
|
|
230
241
|
triggerOpen: mergedOpen.value,
|
|
231
242
|
toggleOpen: triggerOpen,
|
|
232
|
-
multiple: multiple.value
|
|
243
|
+
multiple: multiple.value,
|
|
244
|
+
lockOptions: lockOptions.value,
|
|
245
|
+
rawOpen: rawOpen.value
|
|
233
246
|
};
|
|
234
247
|
}));
|
|
235
248
|
const onClearMouseDown = () => {
|
|
@@ -326,7 +339,8 @@ const BaseSelect = /* @__PURE__ */ defineComponent((props, { expose, attrs }) =>
|
|
|
326
339
|
"empty": emptyOptions,
|
|
327
340
|
"onPopupVisibleChange": onTriggerVisibleChange,
|
|
328
341
|
"onPopupMouseEnter": onPopupMouseEnter,
|
|
329
|
-
"onPopupMouseDown": onInternalMouseDown
|
|
342
|
+
"onPopupMouseDown": onInternalMouseDown,
|
|
343
|
+
"onPopupBlur": onRootBlur
|
|
330
344
|
}, _isSlot(renderNode) ? renderNode : { default: () => [_renderNode] });
|
|
331
345
|
return createVNode(Fragment, null, [createVNode(Polite_default, {
|
|
332
346
|
"visible": focused.value && !mergedOpen.value,
|
|
@@ -17,32 +17,30 @@ var SingleContent_default = /* @__PURE__ */ defineComponent((props, { expose })
|
|
|
17
17
|
if (combobox.value && selectInputContext.value?.activeValue && !inputChanged.value && baseProps.value?.triggerOpen) return selectInputContext.value.activeValue;
|
|
18
18
|
return baseProps.value?.showSearch ? selectInputContext.value?.searchValue : "";
|
|
19
19
|
});
|
|
20
|
-
const
|
|
21
|
-
let restProps = {
|
|
22
|
-
class: `${selectInputContext.value?.prefixCls}-content-value`,
|
|
23
|
-
style: { visibility: mergedSearchValue.value ? "hidden" : "visible" }
|
|
24
|
-
};
|
|
20
|
+
const optionClassName = computed(() => {
|
|
25
21
|
if (displayValue.value && selectContext.value?.flattenOptions) {
|
|
26
22
|
const option = selectContext.value.flattenOptions.find((opt) => opt.value === displayValue.value?.value);
|
|
27
|
-
if (option?.data)
|
|
28
|
-
const { label, value, className, style, key, children, ...rest } = option.data;
|
|
29
|
-
restProps = {
|
|
30
|
-
...restProps,
|
|
31
|
-
...rest,
|
|
32
|
-
title: getTitle(option.data),
|
|
33
|
-
class: clsx(restProps.class, className),
|
|
34
|
-
style: {
|
|
35
|
-
...restProps.style,
|
|
36
|
-
...style
|
|
37
|
-
}
|
|
38
|
-
};
|
|
39
|
-
}
|
|
23
|
+
if (option?.data) return option.data.className || option.data.class;
|
|
40
24
|
}
|
|
41
|
-
if (displayValue.value && !restProps.title) restProps.title = getTitle(displayValue.value);
|
|
42
|
-
if (baseProps.value?.title !== void 0) restProps.title = baseProps.value.title;
|
|
43
|
-
return restProps;
|
|
44
25
|
});
|
|
45
|
-
|
|
26
|
+
const optionStyle = computed(() => {
|
|
27
|
+
if (displayValue.value && selectContext.value?.flattenOptions) {
|
|
28
|
+
const option = selectContext.value.flattenOptions.find((opt) => opt.value === displayValue.value?.value);
|
|
29
|
+
if (option?.data) return option.data.style;
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
const optionTitle = computed(() => {
|
|
33
|
+
let titleValue;
|
|
34
|
+
if (displayValue.value && selectContext.value?.flattenOptions) {
|
|
35
|
+
const option = selectContext.value.flattenOptions.find((opt) => opt.value === displayValue.value?.value);
|
|
36
|
+
if (option?.data) titleValue = getTitle(option.data);
|
|
37
|
+
}
|
|
38
|
+
if (displayValue.value && !titleValue) titleValue = getTitle(displayValue.value);
|
|
39
|
+
if (baseProps.value?.title !== void 0) titleValue = baseProps.value.title;
|
|
40
|
+
return titleValue;
|
|
41
|
+
});
|
|
42
|
+
const hasOptionStyle = computed(() => !!optionClassName.value || !!optionStyle.value);
|
|
43
|
+
watch([combobox, () => selectInputContext.value?.activeValue], () => {
|
|
46
44
|
if (combobox.value) inputChanged.value = false;
|
|
47
45
|
}, { immediate: true });
|
|
48
46
|
const inputRef = shallowRef();
|
|
@@ -51,16 +49,24 @@ var SingleContent_default = /* @__PURE__ */ defineComponent((props, { expose })
|
|
|
51
49
|
const { prefixCls, mode, maxLength } = selectInputContext.value ?? {};
|
|
52
50
|
const { classNames, styles } = baseProps.value ?? {};
|
|
53
51
|
const { inputProps } = props;
|
|
52
|
+
const renderValue = displayValue.value ? hasOptionStyle.value ? createVNode("div", {
|
|
53
|
+
"class": clsx(`${prefixCls}-content-value`, optionClassName.value),
|
|
54
|
+
"style": {
|
|
55
|
+
...mergedSearchValue.value ? { visibility: "hidden" } : {},
|
|
56
|
+
...optionStyle.value
|
|
57
|
+
},
|
|
58
|
+
"title": optionTitle.value
|
|
59
|
+
}, [displayValue.value.label]) : displayValue.value.label : createVNode(Placeholder_default, { "show": !mergedSearchValue.value }, null);
|
|
54
60
|
return createVNode("div", {
|
|
55
|
-
"class": clsx(`${prefixCls}-content`, classNames?.content),
|
|
56
|
-
"style": styles?.content
|
|
57
|
-
|
|
61
|
+
"class": clsx(`${prefixCls}-content`, displayValue.value && `${prefixCls}-content-has-value`, mergedSearchValue.value && `${prefixCls}-content-has-search-value`, hasOptionStyle.value && `${prefixCls}-content-has-option-style`, classNames?.content),
|
|
62
|
+
"style": styles?.content,
|
|
63
|
+
"title": hasOptionStyle.value ? void 0 : optionTitle.value
|
|
64
|
+
}, [renderValue, createVNode(Input_default, mergeProps(inputProps, {
|
|
58
65
|
"value": mergedSearchValue.value,
|
|
59
66
|
"maxLength": mode === "combobox" ? maxLength : void 0,
|
|
60
67
|
"onChange": (e) => {
|
|
61
68
|
inputChanged.value = true;
|
|
62
69
|
inputProps.onChange?.(e);
|
|
63
|
-
inputProps.onInput?.(e);
|
|
64
70
|
},
|
|
65
71
|
"ref": inputRef
|
|
66
72
|
}), null)]);
|
|
@@ -57,7 +57,7 @@ var SelectInput_default = /* @__PURE__ */ defineComponent((props, { attrs, expos
|
|
|
57
57
|
KeyCode.LEFT,
|
|
58
58
|
KeyCode.RIGHT
|
|
59
59
|
].includes(keyCode)) return;
|
|
60
|
-
if (isValidateOpenKey(keyCode)) toggleOpen.value?.(true);
|
|
60
|
+
if (!(event.ctrlKey || event.altKey || event.metaKey) && isValidateOpenKey(keyCode)) toggleOpen.value?.(true);
|
|
61
61
|
};
|
|
62
62
|
expose({
|
|
63
63
|
focus: (options) => {
|
|
@@ -70,7 +70,9 @@ var SelectInput_default = /* @__PURE__ */ defineComponent((props, { attrs, expos
|
|
|
70
70
|
});
|
|
71
71
|
const onInternalMouseDown = (event) => {
|
|
72
72
|
if (!disabled.value) {
|
|
73
|
-
|
|
73
|
+
const inputDOM = getDOM(inputRef.value?.input);
|
|
74
|
+
event._ori_target = inputDOM;
|
|
75
|
+
if (inputDOM && event.target !== inputDOM && !inputDOM.contains(event.target)) event.preventDefault();
|
|
74
76
|
const shouldPreventClose = triggerOpen.value && !multiple.value && (mode.value === "combobox" || showSearch.value);
|
|
75
77
|
if (!event._select_lazy) {
|
|
76
78
|
inputRef.value?.input?.focus();
|
|
@@ -79,10 +81,6 @@ var SelectInput_default = /* @__PURE__ */ defineComponent((props, { attrs, expos
|
|
|
79
81
|
}
|
|
80
82
|
props?.onMouseDown?.(event);
|
|
81
83
|
};
|
|
82
|
-
const onInternalBlur = (event) => {
|
|
83
|
-
toggleOpen.value?.(false);
|
|
84
|
-
props?.onBlur?.(event);
|
|
85
|
-
};
|
|
86
84
|
useSelectInputProvider(computed(() => ({
|
|
87
85
|
...props,
|
|
88
86
|
onInputKeyDown: onInternalInputKeyDown
|
|
@@ -114,7 +112,7 @@ var SelectInput_default = /* @__PURE__ */ defineComponent((props, { attrs, expos
|
|
|
114
112
|
"onKeydown": props.onKeyDown,
|
|
115
113
|
"onKeyup": props.onKeyUp,
|
|
116
114
|
"onFocusin": props.onFocus,
|
|
117
|
-
"onFocusout":
|
|
115
|
+
"onFocusout": props.onBlur
|
|
118
116
|
}), [
|
|
119
117
|
createVNode(Affix_default, {
|
|
120
118
|
"class": clsx(`${prefixCls.value}-prefix`, classNamesConfig.value?.prefix),
|
package/dist/SelectTrigger.d.ts
CHANGED
|
@@ -21,6 +21,7 @@ export interface SelectTriggerProps {
|
|
|
21
21
|
onPopupVisibleChange?: ((visible: boolean) => void) | null;
|
|
22
22
|
onPopupMouseEnter: () => void;
|
|
23
23
|
onPopupMouseDown: (event: MouseEvent) => void;
|
|
24
|
+
onPopupBlur?: (event: FocusEvent) => void;
|
|
24
25
|
}
|
|
25
26
|
declare const SelectTrigger: import('vue').DefineSetupFnComponent<SelectTriggerProps, {}, {}, SelectTriggerProps & {}, import('vue').PublicProps>;
|
|
26
27
|
export default SelectTrigger;
|
package/dist/SelectTrigger.js
CHANGED
|
@@ -54,7 +54,7 @@ var SelectTrigger_default = /* @__PURE__ */ defineComponent((props, { slots, att
|
|
|
54
54
|
const triggerPopupRef = shallowRef();
|
|
55
55
|
expose({ getPopupElement: () => triggerPopupRef.value?.popupElement });
|
|
56
56
|
return () => {
|
|
57
|
-
const { prefixCls, popupElement, popupRender, animation, transitionName, popupStyle, popupMatchSelectWidth, onPopupVisibleChange, placement, direction = "ltr", builtinPlacements, onPopupMouseEnter, onPopupMouseDown, popupAlign, visible, getPopupContainer, popupClassName, empty, ...restProps } = props;
|
|
57
|
+
const { prefixCls, popupElement, popupRender, animation, transitionName, popupStyle, popupMatchSelectWidth, onPopupVisibleChange, placement, direction = "ltr", builtinPlacements, onPopupMouseEnter, onPopupMouseDown, onPopupBlur, popupAlign, visible, getPopupContainer, popupClassName, empty, ...restProps } = props;
|
|
58
58
|
let popupNode = popupElement;
|
|
59
59
|
if (popupRender) popupNode = popupRender(popupElement);
|
|
60
60
|
const popupPrefixCls = `${prefixCls}-dropdown`;
|
|
@@ -68,8 +68,9 @@ var SelectTrigger_default = /* @__PURE__ */ defineComponent((props, { slots, att
|
|
|
68
68
|
"builtinPlacements": mergedBuiltinPlacements.value,
|
|
69
69
|
"prefixCls": popupPrefixCls,
|
|
70
70
|
"popup": createVNode("div", {
|
|
71
|
+
"onMouseenter": onPopupMouseEnter,
|
|
71
72
|
"onMousedown": onPopupMouseDown,
|
|
72
|
-
"
|
|
73
|
+
"onBlur": onPopupBlur
|
|
73
74
|
}, [popupNode]),
|
|
74
75
|
"ref": triggerPopupRef,
|
|
75
76
|
"stretch": stretch.value,
|
|
@@ -177,6 +178,11 @@ var SelectTrigger_default = /* @__PURE__ */ defineComponent((props, { slots, att
|
|
|
177
178
|
type: Function,
|
|
178
179
|
required: true,
|
|
179
180
|
default: void 0
|
|
181
|
+
},
|
|
182
|
+
onPopupBlur: {
|
|
183
|
+
type: Function,
|
|
184
|
+
required: false,
|
|
185
|
+
default: void 0
|
|
180
186
|
}
|
|
181
187
|
}, { direction: "ltr" }),
|
|
182
188
|
name: "SelectTrigger",
|
|
@@ -5,6 +5,8 @@ export interface BaseSelectContextProps extends BaseSelectProps {
|
|
|
5
5
|
multiple: boolean;
|
|
6
6
|
toggleOpen: (open?: boolean) => void;
|
|
7
7
|
role?: string;
|
|
8
|
+
lockOptions: boolean;
|
|
9
|
+
rawOpen: boolean;
|
|
8
10
|
}
|
|
9
11
|
export declare function useBaseSelectProvider(context: Ref<BaseSelectContextProps>): void;
|
|
10
12
|
export default function useBaseProps(): Ref<BaseSelectContextProps | null>;
|
package/dist/hooks/useOpen.d.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { Ref } from 'vue';
|
|
2
|
+
export declare function macroTask(fn: VoidFunction, times?: number): void;
|
|
2
3
|
/**
|
|
3
4
|
* Trigger by latest open call, if nextOpen is undefined, means toggle.
|
|
4
5
|
* ignoreNext will skip next call in the macro task queue.
|
|
5
6
|
*/
|
|
6
7
|
export type TriggerOpenType = (nextOpen?: boolean, config?: {
|
|
7
|
-
|
|
8
|
-
lazy?: boolean;
|
|
8
|
+
cancelFun?: () => boolean;
|
|
9
9
|
}) => void;
|
|
10
10
|
/**
|
|
11
11
|
* When `open` is controlled, follow the controlled value;
|
|
@@ -16,4 +16,4 @@ export type TriggerOpenType = (nextOpen?: boolean, config?: {
|
|
|
16
16
|
* SSR handling: During SSR, `open` is always false to avoid Portal issues.
|
|
17
17
|
* On client-side hydration, it syncs with the actual open state.
|
|
18
18
|
*/
|
|
19
|
-
export default function useOpen(propOpen: Ref<boolean>, onOpen: (nextOpen: boolean) => void, postOpen: (nextOpen: boolean) => boolean): readonly [import('vue').ComputedRef<boolean>, TriggerOpenType];
|
|
19
|
+
export default function useOpen(defaultOpen: boolean, propOpen: Ref<boolean>, onOpen: (nextOpen: boolean) => void, postOpen: (nextOpen: boolean) => boolean): readonly [import('vue').ComputedRef<boolean>, import('vue').ComputedRef<boolean>, TriggerOpenType, import('vue').ShallowRef<boolean, boolean>];
|
package/dist/hooks/useOpen.js
CHANGED
|
@@ -13,45 +13,46 @@ function macroTask(fn, times = 1) {
|
|
|
13
13
|
macroTask(fn, times - 1);
|
|
14
14
|
});
|
|
15
15
|
}
|
|
16
|
-
function useOpen(propOpen, onOpen, postOpen) {
|
|
16
|
+
function useOpen(defaultOpen, propOpen, onOpen, postOpen) {
|
|
17
17
|
const rendered = shallowRef(propOpen.value ?? false);
|
|
18
18
|
onMounted(() => {
|
|
19
19
|
rendered.value = true;
|
|
20
20
|
});
|
|
21
|
-
const stateOpen = shallowRef(propOpen.value ?? false);
|
|
21
|
+
const stateOpen = shallowRef(propOpen.value ?? defaultOpen ?? false);
|
|
22
22
|
watch(propOpen, () => {
|
|
23
23
|
stateOpen.value = propOpen.value;
|
|
24
24
|
});
|
|
25
|
+
const lock = shallowRef(false);
|
|
25
26
|
const ssrSafeOpen = computed(() => rendered.value ? stateOpen.value : false);
|
|
26
27
|
const mergedOpen = computed(() => postOpen(ssrSafeOpen.value));
|
|
27
28
|
const taskIdRef = shallowRef(0);
|
|
28
|
-
const taskLockRef = shallowRef(false);
|
|
29
29
|
const triggerEvent = (nextOpen) => {
|
|
30
30
|
if (onOpen && mergedOpen.value !== nextOpen) onOpen(nextOpen);
|
|
31
31
|
if (propOpen.value !== void 0) return;
|
|
32
32
|
stateOpen.value = nextOpen;
|
|
33
33
|
};
|
|
34
34
|
const toggleOpen = (nextOpen, config = {}) => {
|
|
35
|
-
const {
|
|
35
|
+
const { cancelFun } = config;
|
|
36
36
|
taskIdRef.value += 1;
|
|
37
37
|
const id = taskIdRef.value;
|
|
38
38
|
const nextOpenVal = typeof nextOpen === "boolean" ? nextOpen : !mergedOpen.value;
|
|
39
|
-
|
|
40
|
-
|
|
39
|
+
lock.value = !nextOpenVal;
|
|
40
|
+
function triggerUpdate() {
|
|
41
|
+
if (id === taskIdRef.value && !cancelFun?.()) {
|
|
41
42
|
triggerEvent(nextOpenVal);
|
|
42
|
-
|
|
43
|
-
taskLockRef.value = ignoreNext;
|
|
44
|
-
macroTask(() => {
|
|
45
|
-
taskLockRef.value = false;
|
|
46
|
-
}, 2);
|
|
47
|
-
}
|
|
43
|
+
lock.value = false;
|
|
48
44
|
}
|
|
49
|
-
return;
|
|
50
45
|
}
|
|
51
|
-
|
|
52
|
-
|
|
46
|
+
if (nextOpenVal) triggerUpdate();
|
|
47
|
+
else macroTask(() => {
|
|
48
|
+
triggerUpdate();
|
|
53
49
|
});
|
|
54
50
|
};
|
|
55
|
-
return [
|
|
51
|
+
return [
|
|
52
|
+
ssrSafeOpen,
|
|
53
|
+
mergedOpen,
|
|
54
|
+
toggleOpen,
|
|
55
|
+
lock
|
|
56
|
+
];
|
|
56
57
|
}
|
|
57
|
-
export { useOpen as default };
|
|
58
|
+
export { useOpen as default, macroTask };
|
|
@@ -1,2 +1,4 @@
|
|
|
1
1
|
import { Ref } from 'vue';
|
|
2
|
-
|
|
2
|
+
import { TriggerOpenType } from './useOpen';
|
|
3
|
+
export declare function isInside(elements: (HTMLElement | SVGElement | undefined)[], target: HTMLElement): boolean;
|
|
4
|
+
export default function useSelectTriggerControl(elements: () => (HTMLElement | SVGElement | undefined)[], open: Ref<boolean>, triggerOpen: TriggerOpenType, customizedTrigger: Ref<boolean>): void;
|
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
import { onMounted, onUnmounted } from "vue";
|
|
2
|
+
function isInside(elements, target) {
|
|
3
|
+
return elements.filter((element) => element).some((element) => element.contains(target) || element === target);
|
|
4
|
+
}
|
|
2
5
|
function useSelectTriggerControl(elements, open, triggerOpen, customizedTrigger) {
|
|
3
6
|
const onGlobalMouseDown = (event) => {
|
|
4
7
|
if (customizedTrigger.value) return;
|
|
5
8
|
let target = event.target;
|
|
6
9
|
if (target.shadowRoot && event.composed) target = event.composedPath()[0] || target;
|
|
7
|
-
if (
|
|
10
|
+
if (event._ori_target) target = event._ori_target;
|
|
11
|
+
if (open.value && !isInside(elements(), target)) triggerOpen(false);
|
|
8
12
|
};
|
|
9
13
|
onMounted(() => {
|
|
10
14
|
window.addEventListener("mousedown", onGlobalMouseDown);
|
|
@@ -13,4 +17,4 @@ function useSelectTriggerControl(elements, open, triggerOpen, customizedTrigger)
|
|
|
13
17
|
});
|
|
14
18
|
});
|
|
15
19
|
}
|
|
16
|
-
export { useSelectTriggerControl as default };
|
|
20
|
+
export { useSelectTriggerControl as default, isInside };
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@v-c/select",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "1.0.
|
|
4
|
+
"version": "1.0.10",
|
|
5
5
|
"description": "",
|
|
6
6
|
"author": "",
|
|
7
7
|
"license": "MIT",
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
".": {
|
|
16
16
|
"types": "./dist/index.d.ts",
|
|
17
17
|
"import": "./dist/index.js",
|
|
18
|
-
"
|
|
18
|
+
"default": "./dist/index.js"
|
|
19
19
|
},
|
|
20
20
|
"./dist/*": "./dist/*",
|
|
21
21
|
"./package.json": "./package.json"
|
|
@@ -29,10 +29,10 @@
|
|
|
29
29
|
"vue": "^3.0.0"
|
|
30
30
|
},
|
|
31
31
|
"dependencies": {
|
|
32
|
-
"@v-c/overflow": "^1.0.
|
|
33
|
-
"@v-c/trigger": "^1.0.
|
|
34
|
-
"@v-c/util": "^1.0.
|
|
35
|
-
"@v-c/virtual-list": "^1.0.
|
|
32
|
+
"@v-c/overflow": "^1.0.3",
|
|
33
|
+
"@v-c/trigger": "^1.0.11",
|
|
34
|
+
"@v-c/util": "^1.0.14",
|
|
35
|
+
"@v-c/virtual-list": "^1.0.5"
|
|
36
36
|
},
|
|
37
37
|
"scripts": {
|
|
38
38
|
"build": "vite build",
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
Object.defineProperties(exports, {
|
|
2
|
-
__esModule: { value: true },
|
|
3
|
-
[Symbol.toStringTag]: { value: "Module" }
|
|
4
|
-
});
|
|
5
|
-
const require_rolldown_runtime = require("../_virtual/rolldown_runtime.cjs");
|
|
6
|
-
let vue = require("vue");
|
|
7
|
-
var Polite = /* @__PURE__ */ (0, vue.defineComponent)((props) => {
|
|
8
|
-
return () => {
|
|
9
|
-
const { visible, values } = props;
|
|
10
|
-
if (!visible) return null;
|
|
11
|
-
const MAX_COUNT = 50;
|
|
12
|
-
return (0, vue.createVNode)("span", {
|
|
13
|
-
"aria-live": "polite",
|
|
14
|
-
"style": {
|
|
15
|
-
width: 0,
|
|
16
|
-
height: 0,
|
|
17
|
-
position: "absolute",
|
|
18
|
-
overflow: "hidden",
|
|
19
|
-
opacity: 0
|
|
20
|
-
}
|
|
21
|
-
}, [`${values.slice(0, MAX_COUNT).map(({ label, value }) => ["number", "string"].includes(typeof label) ? label : (0, vue.isVNode)(label) || Array.isArray(label) ? label : value).join(", ")}`, values.length > MAX_COUNT ? ", ..." : null]);
|
|
22
|
-
};
|
|
23
|
-
}, {
|
|
24
|
-
props: {
|
|
25
|
-
visible: {
|
|
26
|
-
type: Boolean,
|
|
27
|
-
required: true,
|
|
28
|
-
default: void 0
|
|
29
|
-
},
|
|
30
|
-
values: {
|
|
31
|
-
type: Array,
|
|
32
|
-
required: true,
|
|
33
|
-
default: void 0
|
|
34
|
-
}
|
|
35
|
-
},
|
|
36
|
-
name: "Polite",
|
|
37
|
-
inheritAttrs: false
|
|
38
|
-
});
|
|
39
|
-
var Polite_default = Polite;
|
|
40
|
-
exports.default = Polite_default;
|