@v-c/select 0.0.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.
Files changed (111) hide show
  1. package/LICENSE +21 -0
  2. package/dist/BaseSelect/Polite.cjs +37 -0
  3. package/dist/BaseSelect/Polite.d.ts +7 -0
  4. package/dist/BaseSelect/Polite.js +34 -0
  5. package/dist/BaseSelect/index.cjs +763 -0
  6. package/dist/BaseSelect/index.d.ts +133 -0
  7. package/dist/BaseSelect/index.js +759 -0
  8. package/dist/OptGroup.cjs +5 -0
  9. package/dist/OptGroup.d.ts +6 -0
  10. package/dist/OptGroup.js +4 -0
  11. package/dist/Option.cjs +5 -0
  12. package/dist/Option.d.ts +8 -0
  13. package/dist/Option.js +4 -0
  14. package/dist/OptionList.cjs +255 -0
  15. package/dist/OptionList.d.ts +17 -0
  16. package/dist/OptionList.js +249 -0
  17. package/dist/Select.cjs +833 -0
  18. package/dist/Select.d.ts +96 -0
  19. package/dist/Select.js +828 -0
  20. package/dist/SelectContext.cjs +11 -0
  21. package/dist/SelectContext.d.ts +32 -0
  22. package/dist/SelectContext.js +9 -0
  23. package/dist/SelectInput/Affix.cjs +16 -0
  24. package/dist/SelectInput/Affix.d.ts +2 -0
  25. package/dist/SelectInput/Affix.js +13 -0
  26. package/dist/SelectInput/Content/MultipleContent.cjs +142 -0
  27. package/dist/SelectInput/Content/MultipleContent.d.ts +3 -0
  28. package/dist/SelectInput/Content/MultipleContent.js +138 -0
  29. package/dist/SelectInput/Content/Placeholder.cjs +33 -0
  30. package/dist/SelectInput/Content/Placeholder.d.ts +5 -0
  31. package/dist/SelectInput/Content/Placeholder.js +30 -0
  32. package/dist/SelectInput/Content/SingleContent.cjs +80 -0
  33. package/dist/SelectInput/Content/SingleContent.d.ts +3 -0
  34. package/dist/SelectInput/Content/SingleContent.js +77 -0
  35. package/dist/SelectInput/Content/index.cjs +40 -0
  36. package/dist/SelectInput/Content/index.d.ts +6 -0
  37. package/dist/SelectInput/Content/index.js +36 -0
  38. package/dist/SelectInput/Input.cjs +176 -0
  39. package/dist/SelectInput/Input.d.ts +22 -0
  40. package/dist/SelectInput/Input.js +173 -0
  41. package/dist/SelectInput/context.cjs +11 -0
  42. package/dist/SelectInput/context.d.ts +5 -0
  43. package/dist/SelectInput/context.js +9 -0
  44. package/dist/SelectInput/index.cjs +330 -0
  45. package/dist/SelectInput/index.d.ts +44 -0
  46. package/dist/SelectInput/index.js +325 -0
  47. package/dist/SelectTrigger.cjs +189 -0
  48. package/dist/SelectTrigger.d.ts +26 -0
  49. package/dist/SelectTrigger.js +185 -0
  50. package/dist/TransBtn.cjs +69 -0
  51. package/dist/TransBtn.d.ts +22 -0
  52. package/dist/TransBtn.js +66 -0
  53. package/dist/_virtual/rolldown_runtime.cjs +21 -0
  54. package/dist/hooks/index.cjs +23 -0
  55. package/dist/hooks/index.d.ts +17 -0
  56. package/dist/hooks/index.js +12 -0
  57. package/dist/hooks/useAllowClear.cjs +17 -0
  58. package/dist/hooks/useAllowClear.d.ts +9 -0
  59. package/dist/hooks/useAllowClear.js +16 -0
  60. package/dist/hooks/useBaseProps.cjs +12 -0
  61. package/dist/hooks/useBaseProps.d.ts +10 -0
  62. package/dist/hooks/useBaseProps.js +9 -0
  63. package/dist/hooks/useCache.cjs +36 -0
  64. package/dist/hooks/useCache.d.ts +7 -0
  65. package/dist/hooks/useCache.js +34 -0
  66. package/dist/hooks/useComponents.cjs +15 -0
  67. package/dist/hooks/useComponents.d.ts +8 -0
  68. package/dist/hooks/useComponents.js +13 -0
  69. package/dist/hooks/useFilterOptions.cjs +39 -0
  70. package/dist/hooks/useFilterOptions.d.ts +3 -0
  71. package/dist/hooks/useFilterOptions.js +37 -0
  72. package/dist/hooks/useLock.cjs +26 -0
  73. package/dist/hooks/useLock.d.ts +1 -0
  74. package/dist/hooks/useLock.js +24 -0
  75. package/dist/hooks/useOpen.cjs +58 -0
  76. package/dist/hooks/useOpen.d.ts +19 -0
  77. package/dist/hooks/useOpen.js +56 -0
  78. package/dist/hooks/useOptions.cjs +38 -0
  79. package/dist/hooks/useOptions.d.ts +13 -0
  80. package/dist/hooks/useOptions.js +36 -0
  81. package/dist/hooks/useRefFunc.cjs +12 -0
  82. package/dist/hooks/useRefFunc.d.ts +6 -0
  83. package/dist/hooks/useRefFunc.js +10 -0
  84. package/dist/hooks/useSearchConfig.cjs +21 -0
  85. package/dist/hooks/useSearchConfig.d.ts +11 -0
  86. package/dist/hooks/useSearchConfig.js +19 -0
  87. package/dist/hooks/useSelectTriggerControl.cjs +18 -0
  88. package/dist/hooks/useSelectTriggerControl.d.ts +2 -0
  89. package/dist/hooks/useSelectTriggerControl.js +16 -0
  90. package/dist/index.cjs +16 -0
  91. package/dist/index.d.ts +10 -0
  92. package/dist/index.js +8 -0
  93. package/dist/interface.cjs +0 -0
  94. package/dist/interface.d.ts +23 -0
  95. package/dist/interface.js +0 -0
  96. package/dist/utils/commonUtil.cjs +37 -0
  97. package/dist/utils/commonUtil.d.ts +12 -0
  98. package/dist/utils/commonUtil.js +30 -0
  99. package/dist/utils/keyUtil.cjs +36 -0
  100. package/dist/utils/keyUtil.d.ts +2 -0
  101. package/dist/utils/keyUtil.js +34 -0
  102. package/dist/utils/legacyUtil.cjs +32 -0
  103. package/dist/utils/legacyUtil.d.ts +3 -0
  104. package/dist/utils/legacyUtil.js +31 -0
  105. package/dist/utils/platformUtil.cjs +5 -0
  106. package/dist/utils/platformUtil.d.ts +1 -0
  107. package/dist/utils/platformUtil.js +5 -0
  108. package/dist/utils/valueUtil.cjs +79 -0
  109. package/dist/utils/valueUtil.d.ts +18 -0
  110. package/dist/utils/valueUtil.js +75 -0
  111. package/package.json +43 -0
@@ -0,0 +1,5 @@
1
+ Object.defineProperty(exports, "__esModule", { value: true });
2
+ var OptGroup = () => null;
3
+ OptGroup.isSelectOptGroup = true;
4
+ var OptGroup_default = OptGroup;
5
+ exports.default = OptGroup_default;
@@ -0,0 +1,6 @@
1
+ import { FunctionalComponent } from 'vue';
2
+ import { DefaultOptionType } from './Select.tsx';
3
+ export interface OptGroupProps extends Omit<DefaultOptionType, 'options'> {
4
+ }
5
+ declare const OptGroup: FunctionalComponent<OptGroupProps>;
6
+ export default OptGroup;
@@ -0,0 +1,4 @@
1
+ var OptGroup = () => null;
2
+ OptGroup.isSelectOptGroup = true;
3
+ var OptGroup_default = OptGroup;
4
+ export { OptGroup_default as default };
@@ -0,0 +1,5 @@
1
+ Object.defineProperty(exports, "__esModule", { value: true });
2
+ var Option = () => null;
3
+ Option.isSelectOption = true;
4
+ var Option_default = Option;
5
+ exports.default = Option_default;
@@ -0,0 +1,8 @@
1
+ import { FunctionalComponent } from 'vue';
2
+ import { DefaultOptionType } from './Select.tsx';
3
+ export interface OptionProps extends Omit<DefaultOptionType, 'label'> {
4
+ /** Save for customize data */
5
+ [prop: string]: any;
6
+ }
7
+ declare const Option: FunctionalComponent<OptionProps>;
8
+ export default Option;
package/dist/Option.js ADDED
@@ -0,0 +1,4 @@
1
+ var Option = () => null;
2
+ Option.isSelectOption = true;
3
+ var Option_default = Option;
4
+ export { Option_default as default };
@@ -0,0 +1,255 @@
1
+ Object.defineProperty(exports, "__esModule", { value: true });
2
+ const require_rolldown_runtime = require("./_virtual/rolldown_runtime.cjs");
3
+ const require_useBaseProps = require("./hooks/useBaseProps.cjs");
4
+ const require_SelectContext = require("./SelectContext.cjs");
5
+ const require_TransBtn = require("./TransBtn.cjs");
6
+ const require_platformUtil = require("./utils/platformUtil.cjs");
7
+ const require_valueUtil = require("./utils/valueUtil.cjs");
8
+ let vue = require("vue");
9
+ let __v_c_util = require("@v-c/util");
10
+ let __v_c_util_dist_KeyCode = require("@v-c/util/dist/KeyCode");
11
+ __v_c_util_dist_KeyCode = require_rolldown_runtime.__toESM(__v_c_util_dist_KeyCode);
12
+ let __v_c_util_dist_pickAttrs = require("@v-c/util/dist/pickAttrs");
13
+ __v_c_util_dist_pickAttrs = require_rolldown_runtime.__toESM(__v_c_util_dist_pickAttrs);
14
+ let __v_c_virtual_list = require("@v-c/virtual-list");
15
+ __v_c_virtual_list = require_rolldown_runtime.__toESM(__v_c_virtual_list);
16
+ function isTitleType(content) {
17
+ return typeof content === "string" || typeof content === "number";
18
+ }
19
+ var OptionList = /* @__PURE__ */ (0, vue.defineComponent)({
20
+ name: "OptionList",
21
+ inheritAttrs: false,
22
+ setup(_, { expose }) {
23
+ const baseProps = require_useBaseProps.default();
24
+ const context = require_SelectContext.useSelectContext();
25
+ const itemPrefixCls = (0, vue.computed)(() => `${baseProps.value?.prefixCls}-item`);
26
+ const memoFlattenOptions = (0, vue.computed)(() => {
27
+ if (!baseProps.value?.open) return context.value?.flattenOptions || [];
28
+ return context.value?.flattenOptions || [];
29
+ });
30
+ const listRef = (0, vue.shallowRef)(null);
31
+ const overMaxCount = (0, vue.computed)(() => {
32
+ const { maxCount, rawValues } = context.value || {};
33
+ return !!(baseProps.value?.multiple && require_valueUtil.isValidCount(maxCount) && rawValues && rawValues.size >= maxCount);
34
+ });
35
+ const onListMouseDown = (event) => {
36
+ event.preventDefault();
37
+ };
38
+ const scrollIntoView = (args) => {
39
+ listRef.value?.scrollTo(typeof args === "number" ? { index: args } : args);
40
+ };
41
+ const isSelected = (value) => {
42
+ if (baseProps.value?.mode === "combobox") return false;
43
+ return context.value?.rawValues?.has(value) || false;
44
+ };
45
+ const getEnabledActiveIndex = (index, offset = 1) => {
46
+ const len = memoFlattenOptions.value.length;
47
+ for (let i = 0; i < len; i += 1) {
48
+ const current = (index + i * offset + len) % len;
49
+ const { group, data } = memoFlattenOptions.value[current] || {};
50
+ if (!group && !data?.disabled && (isSelected(data?.value) || !overMaxCount.value)) return current;
51
+ }
52
+ return -1;
53
+ };
54
+ const activeIndex = (0, vue.shallowRef)(-1);
55
+ const setActive = (index, fromKeyboard = false) => {
56
+ activeIndex.value = index;
57
+ const info = { source: fromKeyboard ? "keyboard" : "mouse" };
58
+ const flattenItem = memoFlattenOptions.value[index];
59
+ if (!flattenItem) {
60
+ context.value?.onActiveValue?.(null, -1, info);
61
+ return;
62
+ }
63
+ context.value?.onActiveValue?.(flattenItem.value, index, info);
64
+ };
65
+ (0, vue.watch)([() => memoFlattenOptions.value.length, () => baseProps.value?.searchValue], () => {
66
+ setActive(context.value?.defaultActiveFirstOption !== false ? getEnabledActiveIndex(0) : -1);
67
+ }, { immediate: true });
68
+ const isAriaSelected = (value) => {
69
+ if (baseProps.value?.mode === "combobox") return String(value).toLowerCase() === (baseProps.value?.searchValue || "").toLowerCase();
70
+ return context.value?.rawValues?.has(value) || false;
71
+ };
72
+ (0, vue.watch)([() => baseProps.value?.open, () => baseProps.value?.searchValue], () => {
73
+ let timeoutId;
74
+ const rawValues = context.value?.rawValues;
75
+ if (!baseProps.value?.multiple && baseProps.value?.open && rawValues?.size === 1) {
76
+ const value = Array.from(rawValues)[0];
77
+ const searchValue = baseProps.value?.searchValue;
78
+ const index = memoFlattenOptions.value.findIndex(({ data }) => searchValue ? String(data.value).startsWith(searchValue) : data.value === value);
79
+ if (index !== -1) {
80
+ setActive(index);
81
+ timeoutId = setTimeout(() => {
82
+ scrollIntoView(index);
83
+ });
84
+ }
85
+ }
86
+ if (baseProps.value?.open) listRef.value?.scrollTo(void 0);
87
+ return () => {
88
+ if (timeoutId) clearTimeout(timeoutId);
89
+ };
90
+ });
91
+ const onSelectValue = (value) => {
92
+ if (value !== void 0) context.value?.onSelect?.(value, { selected: !context.value?.rawValues?.has(value) });
93
+ if (!baseProps.value?.multiple) baseProps.value?.toggleOpen?.(false);
94
+ };
95
+ const onKeyDown = (event) => {
96
+ const { which, ctrlKey } = event;
97
+ switch (which) {
98
+ case __v_c_util_dist_KeyCode.default.N:
99
+ case __v_c_util_dist_KeyCode.default.P:
100
+ case __v_c_util_dist_KeyCode.default.UP:
101
+ case __v_c_util_dist_KeyCode.default.DOWN: {
102
+ let offset = 0;
103
+ if (which === __v_c_util_dist_KeyCode.default.UP) offset = -1;
104
+ else if (which === __v_c_util_dist_KeyCode.default.DOWN) offset = 1;
105
+ else if (require_platformUtil.isPlatformMac() && ctrlKey) {
106
+ if (which === __v_c_util_dist_KeyCode.default.N) offset = 1;
107
+ else if (which === __v_c_util_dist_KeyCode.default.P) offset = -1;
108
+ }
109
+ if (offset !== 0) {
110
+ const nextActiveIndex = getEnabledActiveIndex(activeIndex.value + offset, offset);
111
+ scrollIntoView(nextActiveIndex);
112
+ setActive(nextActiveIndex, true);
113
+ }
114
+ break;
115
+ }
116
+ case __v_c_util_dist_KeyCode.default.TAB:
117
+ case __v_c_util_dist_KeyCode.default.ENTER: {
118
+ const item = memoFlattenOptions.value[activeIndex.value];
119
+ if (!item || item.data.disabled) {
120
+ onSelectValue(void 0);
121
+ return;
122
+ }
123
+ if (!overMaxCount.value || context.value?.rawValues?.has(item.value)) onSelectValue(item.value);
124
+ else onSelectValue(void 0);
125
+ if (baseProps.value?.open) event.preventDefault();
126
+ break;
127
+ }
128
+ case __v_c_util_dist_KeyCode.default.ESC:
129
+ baseProps.value?.toggleOpen?.(false);
130
+ if (baseProps.value?.open) event.stopPropagation();
131
+ }
132
+ };
133
+ const onKeyUp = () => {};
134
+ expose({
135
+ onKeyDown,
136
+ onKeyUp,
137
+ scrollTo: (index) => {
138
+ scrollIntoView(index);
139
+ }
140
+ });
141
+ return () => {
142
+ const { id, notFoundContent, onPopupScroll } = baseProps.value || {};
143
+ const { menuItemSelectedIcon, fieldNames, virtual, direction, listHeight, listItemHeight, optionRender, classNames: contextClassNames, styles: contextStyles } = context.value || {};
144
+ if (memoFlattenOptions.value.length === 0) return (0, vue.createVNode)("div", {
145
+ "role": "listbox",
146
+ "id": `${id}_list`,
147
+ "class": `${itemPrefixCls.value}-empty`,
148
+ "onMousedown": onListMouseDown
149
+ }, [notFoundContent]);
150
+ const omitFieldNameList = Object.keys(fieldNames || {}).map((key) => fieldNames?.[key]);
151
+ const getLabel = (item) => item.label;
152
+ function getItemAriaProps(item, index) {
153
+ const { group } = item;
154
+ return {
155
+ role: group ? "presentation" : "option",
156
+ id: `${id}_list_${index}`
157
+ };
158
+ }
159
+ const renderItem = (index) => {
160
+ const item = memoFlattenOptions.value[index];
161
+ if (!item) return null;
162
+ const itemData = item.data || {};
163
+ const { value } = itemData;
164
+ const { group } = item;
165
+ const attrs = (0, __v_c_util_dist_pickAttrs.default)(itemData, true);
166
+ const mergedLabel = getLabel(item);
167
+ return item ? (0, vue.createVNode)("div", (0, vue.mergeProps)({ "aria-label": typeof mergedLabel === "string" && !group ? mergedLabel : void 0 }, attrs, { "key": index }, getItemAriaProps(item, index), { "aria-selected": isAriaSelected(value) }), [value]) : null;
168
+ };
169
+ const a11yProps = {
170
+ role: "listbox",
171
+ id: `${id}_list`
172
+ };
173
+ return (0, vue.createVNode)(vue.Fragment, null, [virtual && (0, vue.createVNode)("div", (0, vue.mergeProps)(a11yProps, { "style": {
174
+ height: 0,
175
+ width: 0,
176
+ overflow: "hidden"
177
+ } }), [
178
+ renderItem(activeIndex.value - 1),
179
+ renderItem(activeIndex.value),
180
+ renderItem(activeIndex.value + 1)
181
+ ]), (0, vue.createVNode)(__v_c_virtual_list.default, (0, vue.mergeProps)({
182
+ "itemKey": "key",
183
+ "ref": (el) => {
184
+ listRef.value = el;
185
+ },
186
+ "data": memoFlattenOptions.value,
187
+ "height": listHeight,
188
+ "itemHeight": listItemHeight,
189
+ "fullHeight": false
190
+ }, { onMousedown: onListMouseDown }, {
191
+ "onScroll": onPopupScroll,
192
+ "virtual": virtual,
193
+ "direction": direction,
194
+ "innerProps": virtual ? void 0 : a11yProps,
195
+ "class": contextClassNames?.popup?.list,
196
+ "style": contextStyles?.popup?.list
197
+ }), { default: ({ item, index: itemIndex }) => {
198
+ const { group, groupOption, data, label, value } = item;
199
+ const { key } = data;
200
+ if (group) {
201
+ const groupTitle = data.title ?? (isTitleType(label) ? label.toString() : void 0);
202
+ return (0, vue.createVNode)("div", {
203
+ "class": (0, __v_c_util.clsx)(itemPrefixCls.value, `${itemPrefixCls.value}-group`, data.className),
204
+ "title": groupTitle
205
+ }, [label !== void 0 ? label : key]);
206
+ }
207
+ const { disabled, title, children, style, className,...otherProps } = data;
208
+ const passedProps = {};
209
+ Object.keys(otherProps).forEach((propKey) => {
210
+ if (!omitFieldNameList.includes(propKey)) passedProps[propKey] = otherProps[propKey];
211
+ });
212
+ const selected = isSelected(value);
213
+ const mergedDisabled = disabled || !selected && overMaxCount.value;
214
+ const optionPrefixCls = `${itemPrefixCls.value}-option`;
215
+ const optionClassName = (0, __v_c_util.clsx)(itemPrefixCls.value, optionPrefixCls, className, contextClassNames?.popup?.listItem, {
216
+ [`${optionPrefixCls}-grouped`]: groupOption,
217
+ [`${optionPrefixCls}-active`]: activeIndex.value === itemIndex && !mergedDisabled,
218
+ [`${optionPrefixCls}-disabled`]: mergedDisabled,
219
+ [`${optionPrefixCls}-selected`]: selected
220
+ });
221
+ const mergedLabel = getLabel(item);
222
+ const iconVisible = !menuItemSelectedIcon || typeof menuItemSelectedIcon === "function" || selected;
223
+ const content = typeof mergedLabel === "number" ? mergedLabel : mergedLabel || value;
224
+ let optionTitle = isTitleType(content) ? content.toString() : void 0;
225
+ if (title !== void 0) optionTitle = title;
226
+ return (0, vue.createVNode)("div", (0, vue.mergeProps)((0, __v_c_util_dist_pickAttrs.default)(passedProps), !virtual ? getItemAriaProps(item, itemIndex) : {}, {
227
+ "aria-selected": virtual ? void 0 : isAriaSelected(value),
228
+ "class": optionClassName,
229
+ "title": optionTitle,
230
+ "onMousemove": () => {
231
+ if (activeIndex.value === itemIndex || mergedDisabled) return;
232
+ setActive(itemIndex);
233
+ },
234
+ "onClick": () => {
235
+ if (!mergedDisabled) onSelectValue(value);
236
+ },
237
+ "style": {
238
+ ...contextStyles?.popup?.listItem,
239
+ ...style
240
+ }
241
+ }), [(0, vue.createVNode)("div", { "class": `${optionPrefixCls}-content` }, [typeof optionRender === "function" ? optionRender(item, { index: itemIndex }) : content]), iconVisible && (0, vue.createVNode)(require_TransBtn.default, {
242
+ "className": `${itemPrefixCls.value}-option-state`,
243
+ "customizeIcon": menuItemSelectedIcon,
244
+ "customizeIconProps": {
245
+ value,
246
+ disabled: mergedDisabled,
247
+ isSelected: selected
248
+ }
249
+ }, { default: () => [selected ? "✓" : null] })]);
250
+ } })]);
251
+ };
252
+ }
253
+ });
254
+ var OptionList_default = OptionList;
255
+ exports.default = OptionList_default;
@@ -0,0 +1,17 @@
1
+ export interface ScrollConfig {
2
+ index?: number;
3
+ key?: string | number;
4
+ align?: 'top' | 'bottom' | 'auto';
5
+ offset?: number;
6
+ }
7
+ export interface RefOptionListProps {
8
+ onKeyDown: (event: KeyboardEvent) => void;
9
+ onKeyUp: (event: KeyboardEvent) => void;
10
+ scrollTo?: (args: number | ScrollConfig) => void;
11
+ }
12
+ /**
13
+ * Using virtual list of option display.
14
+ * Will fallback to dom if use customize render.
15
+ */
16
+ declare const OptionList: import('vue').DefineComponent<{}, () => import("vue/jsx-runtime").JSX.Element, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, true, {}, any>;
17
+ export default OptionList;
@@ -0,0 +1,249 @@
1
+ import useBaseProps from "./hooks/useBaseProps.js";
2
+ import { useSelectContext } from "./SelectContext.js";
3
+ import TransBtn_default from "./TransBtn.js";
4
+ import { isPlatformMac } from "./utils/platformUtil.js";
5
+ import { isValidCount } from "./utils/valueUtil.js";
6
+ import { Fragment, computed, createVNode, defineComponent, mergeProps, shallowRef, watch } from "vue";
7
+ import { clsx } from "@v-c/util";
8
+ import KeyCode from "@v-c/util/dist/KeyCode";
9
+ import pickAttrs from "@v-c/util/dist/pickAttrs";
10
+ import List from "@v-c/virtual-list";
11
+ function isTitleType(content) {
12
+ return typeof content === "string" || typeof content === "number";
13
+ }
14
+ var OptionList_default = /* @__PURE__ */ defineComponent({
15
+ name: "OptionList",
16
+ inheritAttrs: false,
17
+ setup(_, { expose }) {
18
+ const baseProps = useBaseProps();
19
+ const context = useSelectContext();
20
+ const itemPrefixCls = computed(() => `${baseProps.value?.prefixCls}-item`);
21
+ const memoFlattenOptions = computed(() => {
22
+ if (!baseProps.value?.open) return context.value?.flattenOptions || [];
23
+ return context.value?.flattenOptions || [];
24
+ });
25
+ const listRef = shallowRef(null);
26
+ const overMaxCount = computed(() => {
27
+ const { maxCount, rawValues } = context.value || {};
28
+ return !!(baseProps.value?.multiple && isValidCount(maxCount) && rawValues && rawValues.size >= maxCount);
29
+ });
30
+ const onListMouseDown = (event) => {
31
+ event.preventDefault();
32
+ };
33
+ const scrollIntoView = (args) => {
34
+ listRef.value?.scrollTo(typeof args === "number" ? { index: args } : args);
35
+ };
36
+ const isSelected = (value) => {
37
+ if (baseProps.value?.mode === "combobox") return false;
38
+ return context.value?.rawValues?.has(value) || false;
39
+ };
40
+ const getEnabledActiveIndex = (index, offset = 1) => {
41
+ const len = memoFlattenOptions.value.length;
42
+ for (let i = 0; i < len; i += 1) {
43
+ const current = (index + i * offset + len) % len;
44
+ const { group, data } = memoFlattenOptions.value[current] || {};
45
+ if (!group && !data?.disabled && (isSelected(data?.value) || !overMaxCount.value)) return current;
46
+ }
47
+ return -1;
48
+ };
49
+ const activeIndex = shallowRef(-1);
50
+ const setActive = (index, fromKeyboard = false) => {
51
+ activeIndex.value = index;
52
+ const info = { source: fromKeyboard ? "keyboard" : "mouse" };
53
+ const flattenItem = memoFlattenOptions.value[index];
54
+ if (!flattenItem) {
55
+ context.value?.onActiveValue?.(null, -1, info);
56
+ return;
57
+ }
58
+ context.value?.onActiveValue?.(flattenItem.value, index, info);
59
+ };
60
+ watch([() => memoFlattenOptions.value.length, () => baseProps.value?.searchValue], () => {
61
+ setActive(context.value?.defaultActiveFirstOption !== false ? getEnabledActiveIndex(0) : -1);
62
+ }, { immediate: true });
63
+ const isAriaSelected = (value) => {
64
+ if (baseProps.value?.mode === "combobox") return String(value).toLowerCase() === (baseProps.value?.searchValue || "").toLowerCase();
65
+ return context.value?.rawValues?.has(value) || false;
66
+ };
67
+ watch([() => baseProps.value?.open, () => baseProps.value?.searchValue], () => {
68
+ let timeoutId;
69
+ const rawValues = context.value?.rawValues;
70
+ if (!baseProps.value?.multiple && baseProps.value?.open && rawValues?.size === 1) {
71
+ const value = Array.from(rawValues)[0];
72
+ const searchValue = baseProps.value?.searchValue;
73
+ const index = memoFlattenOptions.value.findIndex(({ data }) => searchValue ? String(data.value).startsWith(searchValue) : data.value === value);
74
+ if (index !== -1) {
75
+ setActive(index);
76
+ timeoutId = setTimeout(() => {
77
+ scrollIntoView(index);
78
+ });
79
+ }
80
+ }
81
+ if (baseProps.value?.open) listRef.value?.scrollTo(void 0);
82
+ return () => {
83
+ if (timeoutId) clearTimeout(timeoutId);
84
+ };
85
+ });
86
+ const onSelectValue = (value) => {
87
+ if (value !== void 0) context.value?.onSelect?.(value, { selected: !context.value?.rawValues?.has(value) });
88
+ if (!baseProps.value?.multiple) baseProps.value?.toggleOpen?.(false);
89
+ };
90
+ const onKeyDown = (event) => {
91
+ const { which, ctrlKey } = event;
92
+ switch (which) {
93
+ case KeyCode.N:
94
+ case KeyCode.P:
95
+ case KeyCode.UP:
96
+ case KeyCode.DOWN: {
97
+ let offset = 0;
98
+ if (which === KeyCode.UP) offset = -1;
99
+ else if (which === KeyCode.DOWN) offset = 1;
100
+ else if (isPlatformMac() && ctrlKey) {
101
+ if (which === KeyCode.N) offset = 1;
102
+ else if (which === KeyCode.P) offset = -1;
103
+ }
104
+ if (offset !== 0) {
105
+ const nextActiveIndex = getEnabledActiveIndex(activeIndex.value + offset, offset);
106
+ scrollIntoView(nextActiveIndex);
107
+ setActive(nextActiveIndex, true);
108
+ }
109
+ break;
110
+ }
111
+ case KeyCode.TAB:
112
+ case KeyCode.ENTER: {
113
+ const item = memoFlattenOptions.value[activeIndex.value];
114
+ if (!item || item.data.disabled) {
115
+ onSelectValue(void 0);
116
+ return;
117
+ }
118
+ if (!overMaxCount.value || context.value?.rawValues?.has(item.value)) onSelectValue(item.value);
119
+ else onSelectValue(void 0);
120
+ if (baseProps.value?.open) event.preventDefault();
121
+ break;
122
+ }
123
+ case KeyCode.ESC:
124
+ baseProps.value?.toggleOpen?.(false);
125
+ if (baseProps.value?.open) event.stopPropagation();
126
+ }
127
+ };
128
+ const onKeyUp = () => {};
129
+ expose({
130
+ onKeyDown,
131
+ onKeyUp,
132
+ scrollTo: (index) => {
133
+ scrollIntoView(index);
134
+ }
135
+ });
136
+ return () => {
137
+ const { id, notFoundContent, onPopupScroll } = baseProps.value || {};
138
+ const { menuItemSelectedIcon, fieldNames, virtual, direction, listHeight, listItemHeight, optionRender, classNames: contextClassNames, styles: contextStyles } = context.value || {};
139
+ if (memoFlattenOptions.value.length === 0) return createVNode("div", {
140
+ "role": "listbox",
141
+ "id": `${id}_list`,
142
+ "class": `${itemPrefixCls.value}-empty`,
143
+ "onMousedown": onListMouseDown
144
+ }, [notFoundContent]);
145
+ const omitFieldNameList = Object.keys(fieldNames || {}).map((key) => fieldNames?.[key]);
146
+ const getLabel = (item) => item.label;
147
+ function getItemAriaProps(item, index) {
148
+ const { group } = item;
149
+ return {
150
+ role: group ? "presentation" : "option",
151
+ id: `${id}_list_${index}`
152
+ };
153
+ }
154
+ const renderItem = (index) => {
155
+ const item = memoFlattenOptions.value[index];
156
+ if (!item) return null;
157
+ const itemData = item.data || {};
158
+ const { value } = itemData;
159
+ const { group } = item;
160
+ const attrs = pickAttrs(itemData, true);
161
+ const mergedLabel = getLabel(item);
162
+ return item ? createVNode("div", mergeProps({ "aria-label": typeof mergedLabel === "string" && !group ? mergedLabel : void 0 }, attrs, { "key": index }, getItemAriaProps(item, index), { "aria-selected": isAriaSelected(value) }), [value]) : null;
163
+ };
164
+ const a11yProps = {
165
+ role: "listbox",
166
+ id: `${id}_list`
167
+ };
168
+ return createVNode(Fragment, null, [virtual && createVNode("div", mergeProps(a11yProps, { "style": {
169
+ height: 0,
170
+ width: 0,
171
+ overflow: "hidden"
172
+ } }), [
173
+ renderItem(activeIndex.value - 1),
174
+ renderItem(activeIndex.value),
175
+ renderItem(activeIndex.value + 1)
176
+ ]), createVNode(List, mergeProps({
177
+ "itemKey": "key",
178
+ "ref": (el) => {
179
+ listRef.value = el;
180
+ },
181
+ "data": memoFlattenOptions.value,
182
+ "height": listHeight,
183
+ "itemHeight": listItemHeight,
184
+ "fullHeight": false
185
+ }, { onMousedown: onListMouseDown }, {
186
+ "onScroll": onPopupScroll,
187
+ "virtual": virtual,
188
+ "direction": direction,
189
+ "innerProps": virtual ? void 0 : a11yProps,
190
+ "class": contextClassNames?.popup?.list,
191
+ "style": contextStyles?.popup?.list
192
+ }), { default: ({ item, index: itemIndex }) => {
193
+ const { group, groupOption, data, label, value } = item;
194
+ const { key } = data;
195
+ if (group) {
196
+ const groupTitle = data.title ?? (isTitleType(label) ? label.toString() : void 0);
197
+ return createVNode("div", {
198
+ "class": clsx(itemPrefixCls.value, `${itemPrefixCls.value}-group`, data.className),
199
+ "title": groupTitle
200
+ }, [label !== void 0 ? label : key]);
201
+ }
202
+ const { disabled, title, children, style, className,...otherProps } = data;
203
+ const passedProps = {};
204
+ Object.keys(otherProps).forEach((propKey) => {
205
+ if (!omitFieldNameList.includes(propKey)) passedProps[propKey] = otherProps[propKey];
206
+ });
207
+ const selected = isSelected(value);
208
+ const mergedDisabled = disabled || !selected && overMaxCount.value;
209
+ const optionPrefixCls = `${itemPrefixCls.value}-option`;
210
+ const optionClassName = clsx(itemPrefixCls.value, optionPrefixCls, className, contextClassNames?.popup?.listItem, {
211
+ [`${optionPrefixCls}-grouped`]: groupOption,
212
+ [`${optionPrefixCls}-active`]: activeIndex.value === itemIndex && !mergedDisabled,
213
+ [`${optionPrefixCls}-disabled`]: mergedDisabled,
214
+ [`${optionPrefixCls}-selected`]: selected
215
+ });
216
+ const mergedLabel = getLabel(item);
217
+ const iconVisible = !menuItemSelectedIcon || typeof menuItemSelectedIcon === "function" || selected;
218
+ const content = typeof mergedLabel === "number" ? mergedLabel : mergedLabel || value;
219
+ let optionTitle = isTitleType(content) ? content.toString() : void 0;
220
+ if (title !== void 0) optionTitle = title;
221
+ return createVNode("div", mergeProps(pickAttrs(passedProps), !virtual ? getItemAriaProps(item, itemIndex) : {}, {
222
+ "aria-selected": virtual ? void 0 : isAriaSelected(value),
223
+ "class": optionClassName,
224
+ "title": optionTitle,
225
+ "onMousemove": () => {
226
+ if (activeIndex.value === itemIndex || mergedDisabled) return;
227
+ setActive(itemIndex);
228
+ },
229
+ "onClick": () => {
230
+ if (!mergedDisabled) onSelectValue(value);
231
+ },
232
+ "style": {
233
+ ...contextStyles?.popup?.listItem,
234
+ ...style
235
+ }
236
+ }), [createVNode("div", { "class": `${optionPrefixCls}-content` }, [typeof optionRender === "function" ? optionRender(item, { index: itemIndex }) : content]), iconVisible && createVNode(TransBtn_default, {
237
+ "className": `${itemPrefixCls.value}-option-state`,
238
+ "customizeIcon": menuItemSelectedIcon,
239
+ "customizeIconProps": {
240
+ value,
241
+ disabled: mergedDisabled,
242
+ isSelected: selected
243
+ }
244
+ }, { default: () => [selected ? "✓" : null] })]);
245
+ } })]);
246
+ };
247
+ }
248
+ });
249
+ export { OptionList_default as default };