@crab-dev/rc-select 0.0.2 → 0.0.5
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/CHANGELOG.md +18 -0
- package/README.md +9 -14
- package/cjs/_wake/src/hooks/useKeyboardNavigation.cjs +40 -0
- package/cjs/_wake/src/select.cjs +139 -0
- package/cjs/_wake/src/selectInput.cjs +222 -0
- package/cjs/_wake/src/selectOverlay.cjs +102 -0
- package/cjs/_wake/src/token.cjs +11 -0
- package/cjs/index.cjs +11 -1
- package/css/index.css +8 -42
- package/declarations/_wake/src/select.d.ts +4 -0
- package/declarations/_wake/src/token.d.ts +3 -0
- package/declarations/_wake/src/types.d.ts +81 -0
- package/declarations/index.d.ts +4 -79
- package/esm/_wake/src/hooks/useKeyboardNavigation.mjs +36 -0
- package/esm/_wake/src/select.mjs +135 -0
- package/esm/_wake/src/selectInput.mjs +218 -0
- package/esm/_wake/src/selectOverlay.mjs +98 -0
- package/esm/_wake/src/token.mjs +4 -0
- package/esm/index.mjs +4 -1
- package/package.json +30 -40
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { useDropdownContext } from "@crab-dev/rc-dropdown-container";
|
|
3
|
+
import RcLineEdit from "@crab-dev/rc-line-edit";
|
|
4
|
+
import Button, { TokenVars as buttonVars } from "@crab-dev/rc-button";
|
|
5
|
+
import { SpinIndicator, TokenVars as spinVars } from "@crab-dev/rc-spin";
|
|
6
|
+
import Tag from "@crab-dev/rc-tag";
|
|
7
|
+
import { cx } from "@crab-dev/css";
|
|
8
|
+
import { useCallback, useEffect, useRef, useState } from "react";
|
|
9
|
+
import token, { vars } from "./token.mjs";
|
|
10
|
+
;
|
|
11
|
+
const setRef = (ref, node) => {
|
|
12
|
+
if (typeof ref === "function") {
|
|
13
|
+
ref(node);
|
|
14
|
+
} else if (ref) {
|
|
15
|
+
ref.current = node;
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
const controlStyle = "rc-select-208f8e064cef";
|
|
19
|
+
const materialFieldStyle = "rc-select-de4f87d60f05";
|
|
20
|
+
const fieldLabelStyle = "rc-select-608ca49a02dc";
|
|
21
|
+
const controlDisabledStyle = "rc-select-238e884e6a17";
|
|
22
|
+
const controlErrorStyle = "rc-select-e0726e9ad481";
|
|
23
|
+
const controlWarningStyle = "rc-select-79b739b32fcb";
|
|
24
|
+
const valueWrapStyle = "rc-select-1356dfc74a7f";
|
|
25
|
+
const singleValueStyle = "rc-select-52cbc5cc4f0f";
|
|
26
|
+
const placeholderStyle = "rc-select-37ce25dfcd13";
|
|
27
|
+
const searchInputStyle = "rc-select-50dd3c70bcdc";
|
|
28
|
+
const caretStyle = "rc-select-d7edabfe7361";
|
|
29
|
+
const caretOpenStyle = "rc-select-30173f5e3d41";
|
|
30
|
+
const tagLabelStyle = "rc-select-2e4337f305d8";
|
|
31
|
+
const suffixWrapStyle = "rc-select-ee9f2054c459";
|
|
32
|
+
const actionStyle = "rc-select-8504d95b52bc";
|
|
33
|
+
const loadingIconStyle = "rc-select-3ab2c2f8c427";
|
|
34
|
+
const sizeMetricsMap = { large: "rc-select-df4a743b55e1", middle: "rc-select-de4a743b542e", small: "rc-select-dd4a743b527b" };
|
|
35
|
+
const sizeHeightFixedMap = { large: "rc-select-b8fc5925a597", middle: "rc-select-b7fc5925a3e4", small: "rc-select-bafc5925a8fd" };
|
|
36
|
+
const sizeHeightFlexibleMap = { large: "rc-select-5d07f79a2f4a", middle: "rc-select-5e07f79a30fd", small: "rc-select-5b07f79a2be4" };
|
|
37
|
+
const CaretIcon = () => _jsx("svg", { "aria-hidden": "true", focusable: "false", viewBox: "0 0 24 24", fill: "currentColor", children: _jsx("path", { d: "m7 10 5 5 5-5z" }) });
|
|
38
|
+
const ClearIcon = () => _jsx("svg", { "aria-hidden": "true", focusable: "false", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: _jsx("path", { d: "m18 6-12 12M6 6l12 12" }) });
|
|
39
|
+
;
|
|
40
|
+
const SelectInput = ({ ref, id, ariaLabel, ariaLabelledBy, ariaDescribedBy, disabled, searchable, multiple, size, status, appearance, label, labelId, required, allowClear, loading, maxTagCount, autoFocus, placeholder, selectedOptions, searchText, highlightIndex, highlightedOption, listboxId, tagRender, onSearchTextChange, onOpenChange, onWidthChange, onMoveHighlight, onSelectHighlighted, onClear, onRemoveTag, onFocus, onBlur }) => {
|
|
41
|
+
const { state, refs, dispatch } = useDropdownContext();
|
|
42
|
+
const controlRef = useRef(null);
|
|
43
|
+
const inputRef = useRef(null);
|
|
44
|
+
const open = state.open;
|
|
45
|
+
const [hovered, setHovered] = useState(false);
|
|
46
|
+
const [actionFocused, setActionFocused] = useState(false);
|
|
47
|
+
const [withoutHover, setWithoutHover] = useState(false);
|
|
48
|
+
useEffect(() => {
|
|
49
|
+
const media = window.matchMedia?.("(hover: none)");
|
|
50
|
+
if (!media) return;
|
|
51
|
+
const update = () => setWithoutHover(media.matches);
|
|
52
|
+
update();
|
|
53
|
+
media.addEventListener("change", update);
|
|
54
|
+
return () => media.removeEventListener("change", update);
|
|
55
|
+
}, []);
|
|
56
|
+
const onOpenChangeRef = useRef(onOpenChange);
|
|
57
|
+
onOpenChangeRef.current = onOpenChange;
|
|
58
|
+
const mergeRef = useCallback((node) => {
|
|
59
|
+
controlRef.current = node;
|
|
60
|
+
if (typeof refs.setReference === "function") {
|
|
61
|
+
refs.setReference(node);
|
|
62
|
+
}
|
|
63
|
+
setRef(ref, node);
|
|
64
|
+
}, [refs.setReference, ref]);
|
|
65
|
+
useEffect(() => {
|
|
66
|
+
const el = controlRef.current;
|
|
67
|
+
if (!el) {
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
const observer = new ResizeObserver((entries) => {
|
|
71
|
+
for (const entry of entries) {
|
|
72
|
+
onWidthChange(entry.target.getBoundingClientRect().width);
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
observer.observe(el);
|
|
76
|
+
return () => observer.disconnect();
|
|
77
|
+
}, [onWidthChange]);
|
|
78
|
+
useEffect(() => {
|
|
79
|
+
if (open && searchable) {
|
|
80
|
+
queueMicrotask(() => inputRef.current?.focus());
|
|
81
|
+
}
|
|
82
|
+
}, [open, searchable]);
|
|
83
|
+
useEffect(() => {
|
|
84
|
+
if (autoFocus && controlRef.current) {
|
|
85
|
+
controlRef.current.focus();
|
|
86
|
+
}
|
|
87
|
+
}, [autoFocus]);
|
|
88
|
+
const isFirstOpenRender = useRef(true);
|
|
89
|
+
useEffect(() => {
|
|
90
|
+
if (isFirstOpenRender.current) {
|
|
91
|
+
isFirstOpenRender.current = false;
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
onOpenChangeRef.current(open);
|
|
95
|
+
}, [open]);
|
|
96
|
+
const handleClick = () => {
|
|
97
|
+
if (disabled) {
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
dispatch({ type: "setOpen", payload: !open });
|
|
101
|
+
};
|
|
102
|
+
const handleKeyDown = (e) => {
|
|
103
|
+
if (disabled) {
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
switch (e.key) {
|
|
107
|
+
case "ArrowDown":
|
|
108
|
+
e.preventDefault();
|
|
109
|
+
if (!open) {
|
|
110
|
+
dispatch({ type: "setOpen", payload: true });
|
|
111
|
+
}
|
|
112
|
+
onMoveHighlight(1);
|
|
113
|
+
break;
|
|
114
|
+
case "ArrowUp":
|
|
115
|
+
e.preventDefault();
|
|
116
|
+
if (!open) {
|
|
117
|
+
dispatch({ type: "setOpen", payload: true });
|
|
118
|
+
}
|
|
119
|
+
onMoveHighlight(-1);
|
|
120
|
+
break;
|
|
121
|
+
case "Enter":
|
|
122
|
+
e.preventDefault();
|
|
123
|
+
if (open && highlightedOption) {
|
|
124
|
+
onSelectHighlighted(highlightedOption);
|
|
125
|
+
if (!multiple) {
|
|
126
|
+
dispatch({ type: "setOpen", payload: false });
|
|
127
|
+
}
|
|
128
|
+
} else if (!open) {
|
|
129
|
+
dispatch({ type: "setOpen", payload: true });
|
|
130
|
+
}
|
|
131
|
+
break;
|
|
132
|
+
case " ":
|
|
133
|
+
if (!searchable || !open) {
|
|
134
|
+
e.preventDefault();
|
|
135
|
+
if (!open) {
|
|
136
|
+
dispatch({ type: "setOpen", payload: true });
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
break;
|
|
140
|
+
case "Escape":
|
|
141
|
+
if (open) {
|
|
142
|
+
e.preventDefault();
|
|
143
|
+
dispatch({ type: "setOpen", payload: false });
|
|
144
|
+
}
|
|
145
|
+
break;
|
|
146
|
+
case "Backspace":
|
|
147
|
+
if (multiple && searchText === "" && selectedOptions.length > 0) {
|
|
148
|
+
const lastOption = selectedOptions[selectedOptions.length - 1];
|
|
149
|
+
onRemoveTag(lastOption.value);
|
|
150
|
+
}
|
|
151
|
+
break;
|
|
152
|
+
default:
|
|
153
|
+
break;
|
|
154
|
+
}
|
|
155
|
+
};
|
|
156
|
+
const triggerClear = () => {
|
|
157
|
+
controlRef.current?.focus();
|
|
158
|
+
onClear();
|
|
159
|
+
if (open) {
|
|
160
|
+
dispatch({ type: "setOpen", payload: false });
|
|
161
|
+
}
|
|
162
|
+
};
|
|
163
|
+
const handleClearClick = (e) => {
|
|
164
|
+
e.stopPropagation();
|
|
165
|
+
triggerClear();
|
|
166
|
+
};
|
|
167
|
+
const handleClearKeyDown = (e) => {
|
|
168
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
169
|
+
e.stopPropagation();
|
|
170
|
+
}
|
|
171
|
+
};
|
|
172
|
+
const canClear = allowClear && !disabled && selectedOptions.length > 0;
|
|
173
|
+
const showClear = canClear && (hovered || actionFocused || withoutHover);
|
|
174
|
+
const renderTag = (opt) => {
|
|
175
|
+
const handleClose = () => onRemoveTag(opt.value);
|
|
176
|
+
if (tagRender) {
|
|
177
|
+
return _jsx("span", { children: tagRender(opt, handleClose) }, opt.value);
|
|
178
|
+
}
|
|
179
|
+
return _jsx(Tag, { size: "small", closable: true, closeAriaLabel: `Remove ${typeof opt.label === "string" ? opt.label : opt.value}`, onClose: handleClose, children: _jsx("span", { className: tagLabelStyle, children: opt.label }) }, opt.value);
|
|
180
|
+
};
|
|
181
|
+
const renderTags = () => {
|
|
182
|
+
if (maxTagCount !== undefined && selectedOptions.length > maxTagCount) {
|
|
183
|
+
const visible = selectedOptions.slice(0, maxTagCount);
|
|
184
|
+
const overflowCount = selectedOptions.length - maxTagCount;
|
|
185
|
+
return _jsxs(_Fragment, { children: [visible.map(renderTag), _jsxs(Tag, { size: "small", children: ["+", overflowCount] })] });
|
|
186
|
+
}
|
|
187
|
+
return selectedOptions.map(renderTag);
|
|
188
|
+
};
|
|
189
|
+
const renderContent = () => {
|
|
190
|
+
if (searchable && open) {
|
|
191
|
+
return _jsxs(_Fragment, { children: [multiple && renderTags(), _jsx(RcLineEdit, { ref: inputRef, bordered: false, value: searchText, placeholder: multiple && selectedOptions.length > 0 ? "" : placeholder, onChange: (e) => onSearchTextChange(e.target.value), onClick: (e) => e.stopPropagation(), className: searchInputStyle })] });
|
|
192
|
+
}
|
|
193
|
+
if (multiple) {
|
|
194
|
+
if (selectedOptions.length === 0) {
|
|
195
|
+
return _jsx("span", { className: placeholderStyle, children: placeholder });
|
|
196
|
+
}
|
|
197
|
+
return renderTags();
|
|
198
|
+
}
|
|
199
|
+
if (selectedOptions.length === 0) {
|
|
200
|
+
return _jsx("span", { className: placeholderStyle, children: placeholder });
|
|
201
|
+
}
|
|
202
|
+
return _jsx("span", { className: singleValueStyle, children: selectedOptions[0]?.label });
|
|
203
|
+
};
|
|
204
|
+
const activeDescendantId = open && highlightIndex >= 0 ? `${listboxId}-option-${highlightIndex}` : undefined;
|
|
205
|
+
return _jsxs("div", { id: id, role: "combobox", "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy, "aria-describedby": ariaDescribedBy, "aria-required": required || undefined, "aria-expanded": open, "aria-disabled": disabled, "aria-busy": loading || undefined, "aria-haspopup": "listbox", "aria-controls": open ? listboxId : undefined, "aria-activedescendant": activeDescendantId, "aria-invalid": status === "error" ? true : undefined, "data-appearance": appearance, "data-clearable": canClear, "data-labeled": Boolean(label), "data-floating": Boolean(open || selectedOptions.length > 0 || searchText), "data-status": status, tabIndex: disabled ? -1 : 0, ref: mergeRef, className: cx.call(undefined, controlStyle, sizeMetricsMap[size], multiple ? sizeHeightFlexibleMap[size] : sizeHeightFixedMap[size], disabled && controlDisabledStyle, status === "error" && controlErrorStyle, status === "warning" && controlWarningStyle, materialFieldStyle), onClick: handleClick, onKeyDown: handleKeyDown, onFocus: onFocus, onBlur: onBlur, onPointerOver: (event) => {
|
|
206
|
+
if (event.pointerType !== "touch") setHovered(true);
|
|
207
|
+
}, onPointerOut: (event) => {
|
|
208
|
+
if (!(event.relatedTarget instanceof Node) || !event.currentTarget.contains(event.relatedTarget)) {
|
|
209
|
+
setHovered(false);
|
|
210
|
+
}
|
|
211
|
+
}, children: [label && _jsxs("span", { id: labelId, "data-role": "select-label", className: fieldLabelStyle, children: [label, required ? " *" : ""] }), _jsx("div", { "data-role": "select-value", className: valueWrapStyle, children: renderContent() }), _jsxs("span", { "data-role": "select-suffix", className: suffixWrapStyle, children: [loading ? _jsx("span", { "aria-hidden": "true", className: loadingIconStyle, children: _jsx(SpinIndicator, {}) }) : null, _jsx(Button, { "data-role": showClear ? "select-clear" : "select-caret", className: actionStyle, type: "button", appearance: "text", shape: "circle", size: size, disabled: disabled, "aria-label": showClear ? "Clear" : open ? "Close options" : "Open options", "aria-expanded": showClear ? undefined : open, icon: showClear ? _jsx(ClearIcon, {}) : _jsx("span", { "aria-hidden": "true", className: cx.call(undefined, caretStyle, open && caretOpenStyle), children: _jsx(CaretIcon, {}) }), onFocus: () => setActionFocused(true), onBlur: () => setActionFocused(false), onClick: (event) => {
|
|
212
|
+
if (showClear) handleClearClick(event); else {
|
|
213
|
+
event.stopPropagation();
|
|
214
|
+
handleClick();
|
|
215
|
+
}
|
|
216
|
+
}, onKeyDown: handleClearKeyDown })] })] });
|
|
217
|
+
};
|
|
218
|
+
export default SelectInput;
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import Checkbox, { TokenVars as checkboxVars } from "@crab-dev/rc-checkbox";
|
|
3
|
+
import { SpinIndicator, TokenVars as spinVars } from "@crab-dev/rc-spin";
|
|
4
|
+
import RcVirtual from "@crab-dev/rc-virtual";
|
|
5
|
+
import { useMediaQuery } from "@crab-dev/rc-hooks";
|
|
6
|
+
import { cx } from "@crab-dev/css";
|
|
7
|
+
import { useDropdownContext } from "@crab-dev/rc-dropdown-container";
|
|
8
|
+
import { useEffect, useLayoutEffect, useRef, useState } from "react";
|
|
9
|
+
import token from "./token.mjs";
|
|
10
|
+
;
|
|
11
|
+
const hasGroups = (options) => options.some((opt) => opt.isGroupLabel);
|
|
12
|
+
const overlayStyle = "rc-select-8032ea9d3fcc";
|
|
13
|
+
const optionStyle = "rc-select-41a9c05e6999";
|
|
14
|
+
const optionHighlightStyle = "rc-select-787681543371";
|
|
15
|
+
const measureStyle = "rc-select-9fccdf1a17f8";
|
|
16
|
+
const optionSelectedStyle = "rc-select-afbd832dfa96";
|
|
17
|
+
const optionSelectedSingleStyle = "rc-select-92da46dc013a";
|
|
18
|
+
const optionDisabledStyle = "rc-select-b51a97d11fd1";
|
|
19
|
+
const optionLabelStyle = "rc-select-462ffe03d1f7";
|
|
20
|
+
const checkIconStyle = "rc-select-4d7b259b317b";
|
|
21
|
+
const checkboxIndicatorStyle = "rc-select-8509288b81d2";
|
|
22
|
+
const emptyStyle = "rc-select-742133f23b03";
|
|
23
|
+
const groupLabelStyle = "rc-select-4222a3b1548f";
|
|
24
|
+
const groupedOptionStyle = "rc-select-fa0b905ad8a1";
|
|
25
|
+
const virtualTopSpacerStyle = "rc-select-25c250ff4ce4";
|
|
26
|
+
const virtualBottomSpacerStyle = "rc-select-bf5e0c73c29c";
|
|
27
|
+
const loadingStyle = "rc-select-0ed119f292d0";
|
|
28
|
+
const DROPDOWN_PADDING = 4;
|
|
29
|
+
const ROW_HEIGHT = 48;
|
|
30
|
+
const MAX_VIEWPORT_HEIGHT = 256;
|
|
31
|
+
;
|
|
32
|
+
const SelectOverlay = ({ multiple, loading, filteredOptions, selectedValues, triggerWidth, highlightIndex, listboxId, notFoundContent, popupClassName, optionRender, dropdownRender, onOptionSelect, onOpenChange, onHighlightChange }) => {
|
|
33
|
+
const { dispatch } = useDropdownContext();
|
|
34
|
+
const coarsePointer = useMediaQuery("(pointer: coarse)");
|
|
35
|
+
const overlayRef = useRef(null);
|
|
36
|
+
const [measuredRowHeight, setMeasuredRowHeight] = useState(ROW_HEIGHT);
|
|
37
|
+
const rowHeight = Math.max(coarsePointer ? 48 : ROW_HEIGHT, measuredRowHeight);
|
|
38
|
+
useLayoutEffect(() => {
|
|
39
|
+
const option = overlayRef.current?.querySelector("[data-select-option-measure]");
|
|
40
|
+
if (!option) return;
|
|
41
|
+
const measure = () => {
|
|
42
|
+
const height = option.getBoundingClientRect().height;
|
|
43
|
+
if (height > 0) {
|
|
44
|
+
overlayRef.current?.style.setProperty("--select-option-measured-height", `${height}px`);
|
|
45
|
+
setMeasuredRowHeight(height);
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
measure();
|
|
49
|
+
if (typeof ResizeObserver === "undefined") return;
|
|
50
|
+
const observer = new ResizeObserver(measure);
|
|
51
|
+
observer.observe(option);
|
|
52
|
+
return () => observer.disconnect();
|
|
53
|
+
}, [coarsePointer, filteredOptions.length, loading]);
|
|
54
|
+
const gridRef = useRef(null);
|
|
55
|
+
useEffect(() => {
|
|
56
|
+
if (highlightIndex < 0) {
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
gridRef.current?.scrollToCell({ rowIndex: highlightIndex });
|
|
60
|
+
}, [highlightIndex]);
|
|
61
|
+
const rowCount = filteredOptions.length;
|
|
62
|
+
const contentWidth = Math.max(triggerWidth - DROPDOWN_PADDING * 2, 160);
|
|
63
|
+
const viewportHeight = Math.min(MAX_VIEWPORT_HEIGHT, rowCount * rowHeight);
|
|
64
|
+
const rows = Array(rowCount).fill(rowHeight);
|
|
65
|
+
const columns = [contentWidth];
|
|
66
|
+
if (loading) {
|
|
67
|
+
return _jsx("div", { id: listboxId, role: "listbox", "aria-busy": "true", "data-select-overlay": true, className: cx.call(undefined, overlayStyle, popupClassName), children: _jsx("div", { className: loadingStyle, children: _jsx(SpinIndicator, {}) }) });
|
|
68
|
+
}
|
|
69
|
+
if (filteredOptions.length === 0) {
|
|
70
|
+
return _jsx("div", { id: listboxId, role: "listbox", "data-select-overlay": true, className: cx.call(undefined, overlayStyle, popupClassName), children: _jsx("div", { className: emptyStyle, children: notFoundContent ?? "无匹配选项" }) });
|
|
71
|
+
}
|
|
72
|
+
const isGrouped = hasGroups(filteredOptions);
|
|
73
|
+
const menu = _jsx(RcVirtual, { gridRef: gridRef, viewportWidth: contentWidth, viewportHeight: viewportHeight, gridTemplateColumns: columns, gridTemplateRows: rows, overscanRowCount: 4, renderRows: (rowRange) => {
|
|
74
|
+
const nodes = [_jsx("div", { "data-select-virtual-spacer": "top", className: virtualTopSpacerStyle }, "__select-top-padding__")];
|
|
75
|
+
for (let i = rowRange[0]; i <= rowRange[1]; i += 1) {
|
|
76
|
+
const option = filteredOptions[i];
|
|
77
|
+
if (option.isGroupLabel) {
|
|
78
|
+
nodes.push(_jsx("div", { "data-group-label": true, className: groupLabelStyle, children: option.label }, option.value));
|
|
79
|
+
continue;
|
|
80
|
+
}
|
|
81
|
+
const selected = selectedValues.includes(option.value);
|
|
82
|
+
const highlighted = i === highlightIndex;
|
|
83
|
+
const content = optionRender ? optionRender(option, { selected }) : _jsxs(_Fragment, { children: [multiple ? _jsx(Checkbox, { className: checkboxIndicatorStyle, checked: selected, disabled: option.disabled, tabIndex: -1, "aria-label": typeof option.label === "string" ? option.label : option.value }) : null, _jsx("span", { className: optionLabelStyle, children: option.label }), !multiple && selected ? _jsx("span", { className: checkIconStyle, children: _jsx("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: _jsx("path", { d: "M20 6 9 17l-5-5" }) }) }) : null] });
|
|
84
|
+
const optionAriaLabel = multiple ? typeof option.label === "string" ? option.label : option.value : undefined;
|
|
85
|
+
nodes.push(_jsx("div", { id: `${listboxId}-option-${i}`, role: "option", "aria-selected": selected, "aria-disabled": option.disabled || undefined, "aria-label": optionAriaLabel, className: cx.call(undefined, optionStyle, isGrouped && groupedOptionStyle, selected && (multiple ? optionSelectedStyle : optionSelectedSingleStyle), highlighted && optionHighlightStyle, option.disabled && optionDisabledStyle), onMouseEnter: () => onHighlightChange(i), onClick: () => {
|
|
86
|
+
onOptionSelect(option);
|
|
87
|
+
if (!multiple && !option.disabled) {
|
|
88
|
+
dispatch({ type: "setOpen", payload: false });
|
|
89
|
+
onOpenChange(false);
|
|
90
|
+
}
|
|
91
|
+
}, children: content }, option.value));
|
|
92
|
+
}
|
|
93
|
+
nodes.push(_jsx("div", { "data-select-virtual-spacer": "bottom", className: virtualBottomSpacerStyle }, "__select-bottom-padding__"));
|
|
94
|
+
return nodes;
|
|
95
|
+
} });
|
|
96
|
+
return _jsxs("div", { id: listboxId, ref: overlayRef, "data-select-overlay": true, className: cx.call(undefined, overlayStyle, popupClassName), role: "listbox", "aria-multiselectable": multiple || undefined, children: [_jsx("div", { "aria-hidden": "true", "data-select-option-measure": "", className: cx(optionStyle, measureStyle), children: "M" }), dropdownRender ? dropdownRender(menu) : menu] });
|
|
97
|
+
};
|
|
98
|
+
export default SelectOverlay;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { defineTokens } from "@crab-dev/css";
|
|
2
|
+
export const vars = defineTokens({ "option.checkbox.width": "--select-option-checkbox-width", "option.background-color-hover": "--select-option-background-color-hover", "option.color-selected": "--select-option-color-selected", "option.background-color-selected": "--select-option-background-color-selected", "option.color-disabled": "--select-option-color-disabled", "option.highlight.background-color": "--select-option-highlight-background-color", "option.background-color-active": "--select-option-background-color-active", "option.height": "--select-option-height", "option.padding-block": "--select-option-padding-block", "option.font-size": "--select-option-font-size", "option.line-height": "--select-option-line-height", "root.transition": "--select-root-transition", "root.opacity-disabled": "--select-root-opacity-disabled", "root.touch.min-height": "--select-root-touch-min-height", "root.outline-width-focus": "--select-root-outline-width-focus", "root.outline-offset-focus": "--select-root-outline-offset-focus", "root.border-width": "--select-root-border-width", "root.border-style": "--select-root-border-style", "root.border-color": "--select-root-border-color", "root.border-color-hover": "--select-root-border-color-hover", "root.border-color-focus": "--select-root-border-color-focus", "root.border-color-error": "--select-root-border-color-error", "root.border-color-warning": "--select-root-border-color-warning", "root.border-radius": "--select-root-border-radius", "root.background-color": "--select-root-background-color", "root.background-color-disabled": "--select-root-background-color-disabled", "root.box-shadow": "--select-root-box-shadow", "root.box-shadow-focus": "--select-root-box-shadow-focus", "root.validation.box-shadow-error": "--select-root-validation-box-shadow-error", "root.validation.box-shadow-warning": "--select-root-validation-box-shadow-warning", "root.color-loading": "--select-root-color-loading", "motion.interaction.transition": "--select-motion-interaction-transition", "motion.spatial.transition": "--select-motion-spatial-transition", "text.color": "--select-text-color", "text.color-placeholder": "--select-text-color-placeholder", "text.color-disabled": "--select-text-color-disabled", "tag.background-color": "--select-tag-background-color", "tag.color": "--select-tag-color", "tag.close.color-hover": "--select-tag-close-color-hover", "clear.color": "--select-clear-color", "clear.color-hover": "--select-clear-color-hover", "clear.width": "--select-clear-width", "clear.height": "--select-clear-height", "clear.touch.width": "--select-clear-touch-width", "clear.box-shadow-focus": "--select-clear-box-shadow-focus", "icon.width": "--select-icon-width", "icon.color": "--select-icon-color", "field.gap": "--select-field-gap", "field.padding-inline": "--select-field-padding-inline", "field.label.top": "--select-field-label-top", "field.label.padding-inline": "--select-field-label-padding-inline", "field.label.font-size": "--select-field-label-font-size", "field.label.line-height": "--select-field-label-line-height", "field.label.color": "--select-field-label-color", "field.label.color-focus": "--select-field-label-color-focus", "field.input.padding-top": "--select-field-input-padding-top", "field.transition": "--select-field-transition", "field.filled.background-color": "--select-field-filled-background-color", "field.filled.background-color-hover": "--select-field-filled-background-color-hover", "field.indicator.border-color": "--select-field-indicator-border-color", "field.indicator.box-shadow-focus": "--select-field-indicator-box-shadow-focus", "field.indicator.box-shadow-error": "--select-field-indicator-box-shadow-error", "field.indicator.box-shadow-warning": "--select-field-indicator-box-shadow-warning", "field.color-error": "--select-field-color-error", "field.color-warning": "--select-field-color-warning", "field.support.line-height": "--select-field-support-line-height", "group.color": "--select-group-color", "group.font-size": "--select-group-font-size", "size.large.height": "--select-size-large-height", "size.large.padding": "--select-size-large-padding", "size.large.font-size": "--select-size-large-font-size", "size.large.line-height": "--select-size-large-line-height", "size.large.action.width": "--select-size-large-action-width", "size.middle.height": "--select-size-middle-height", "size.middle.padding": "--select-size-middle-padding", "size.middle.font-size": "--select-size-middle-font-size", "size.middle.line-height": "--select-size-middle-line-height", "size.middle.action.width": "--select-size-middle-action-width", "size.small.height": "--select-size-small-height", "size.small.padding": "--select-size-small-padding", "size.small.font-size": "--select-size-small-font-size", "size.small.line-height": "--select-size-small-line-height", "size.small.action.width": "--select-size-small-action-width", "dropdown.margin": "--select-dropdown-margin", "dropdown.max-height": "--select-dropdown-max-height", "dropdown.padding": "--select-dropdown-padding", "dropdown.option.padding": "--select-dropdown-option-padding", "dropdown.border-radius": "--select-dropdown-border-radius" });
|
|
3
|
+
const token = defineTokens({ "option": { "checkbox": { "width": `var(${vars["option.checkbox.width"]}, 18px)` }, "background-color-hover": `var(${vars["option.background-color-hover"]}, var(--token-semantic-color-state-hover, var(--token-semantic-color-background-hover-subtle, color-mix(in oklch, var(--token-global-material-neutral-10, oklch(0.22652446 0.00999107 303.713695)) calc(var(--token-semantic-state-opacity-hover, var(--token-global-opacity-8, 0.08)) * 100%), var(--token-global-material-neutral-98, oklch(0.98379491 0.01284496 321.893957))))))`, "color-selected": `var(${vars["option.color-selected"]}, var(--token-semantic-color-brand-on-container, var(--token-semantic-color-selection-foreground, var(--token-global-purple-10, oklch(0.24199786 0.14038488 286.089811)))))`, "background-color-selected": `var(${vars["option.background-color-selected"]}, var(--token-semantic-color-brand-container, var(--token-semantic-color-selection-background, var(--token-global-purple-90, oklch(0.91829316 0.04770250 302.827510)))))`, "color-disabled": `var(${vars["option.color-disabled"]}, var(--token-semantic-color-text-disabled, var(--token-global-material-neutral-10, oklch(0.22652446 0.00999107 303.713695))))`, "highlight": { "background-color": `var(${vars["option.highlight.background-color"]}, var(--token-semantic-color-state-hover, var(--token-semantic-color-background-hover-subtle, color-mix(in oklch, var(--token-global-material-neutral-10, oklch(0.22652446 0.00999107 303.713695)) calc(var(--token-semantic-state-opacity-hover, var(--token-global-opacity-8, 0.08)) * 100%), var(--token-global-material-neutral-98, oklch(0.98379491 0.01284496 321.893957))))))` }, "background-color-active": `var(${vars["option.background-color-active"]}, var(--token-semantic-color-state-pressed, var(--token-semantic-color-background-active-subtle, color-mix(in oklch, var(--token-global-material-neutral-10, oklch(0.22652446 0.00999107 303.713695)) calc(var(--token-semantic-state-opacity-pressed, var(--token-global-opacity-12, 0.12)) * 100%), var(--token-global-material-neutral-98, oklch(0.98379491 0.01284496 321.893957))))))`, "height": `var(${vars["option.height"]}, var(--token-semantic-density-item, var(--token-global-size-48, 48px)))`, "padding-block": `var(${vars["option.padding-block"]}, var(--token-semantic-space-component-gap, var(--token-global-space-2, 8px)))`, "font-size": `var(${vars["option.font-size"]}, var(--token-semantic-typography-body-large-font-size, var(--token-global-font-size-md, 16px)))`, "line-height": `var(${vars["option.line-height"]}, var(--token-semantic-typography-body-large-line-height, var(--token-global-line-height-16-24, 1.5)))` }, "root": { "transition": `var(${vars["root.transition"]}, background-color var(--token-semantic-motion-interaction, var(--token-global-duration-150, 150ms) var(--token-global-easing-expressive-effects-fast, cubic-bezier(0.31, 0.94, 0.34, 1.00))), border-color var(--token-semantic-motion-interaction, var(--token-global-duration-150, 150ms) var(--token-global-easing-expressive-effects-fast, cubic-bezier(0.31, 0.94, 0.34, 1.00))), color var(--token-semantic-motion-interaction, var(--token-global-duration-150, 150ms) var(--token-global-easing-expressive-effects-fast, cubic-bezier(0.31, 0.94, 0.34, 1.00))), box-shadow var(--token-semantic-motion-interaction, var(--token-global-duration-150, 150ms) var(--token-global-easing-expressive-effects-fast, cubic-bezier(0.31, 0.94, 0.34, 1.00))))`, "opacity-disabled": `var(${vars["root.opacity-disabled"]}, var(--token-semantic-opacity-disabled, var(--token-global-opacity-38, 0.38)))`, "touch": { "min-height": `var(${vars["root.touch.min-height"]}, var(--token-semantic-size-touch-target, var(--token-global-size-48, 48px)))` }, "outline-width-focus": `var(${vars["root.outline-width-focus"]}, 2px)`, "outline-offset-focus": `var(${vars["root.outline-offset-focus"]}, 2px)`, "border-width": `var(${vars["root.border-width"]}, 1px)`, "border-style": `var(${vars["root.border-style"]}, solid)`, "border-color": `var(${vars["root.border-color"]}, var(--token-semantic-color-border-default, var(--token-global-material-neutral-variant-50, oklch(0.56674707 0.01627446 308.142182))))`, "border-color-hover": `var(${vars["root.border-color-hover"]}, var(--token-semantic-color-border-hover, var(--token-global-material-neutral-10, oklch(0.22652446 0.00999107 303.713695))))`, "border-color-focus": `var(${vars["root.border-color-focus"]}, var(--token-semantic-color-border-focus, var(--token-global-purple-40, oklch(0.49552086 0.13045663 293.709078))))`, "border-color-error": `var(${vars["root.border-color-error"]}, var(--token-semantic-color-feedback-error-border, var(--token-global-material-error-40, oklch(0.50128208 0.17831791 28.704727))))`, "border-color-warning": `var(${vars["root.border-color-warning"]}, var(--token-semantic-color-feedback-warning-border, var(--token-global-amber-700, oklch(0.555 0.163 71))))`, "border-radius": `var(${vars["root.border-radius"]}, var(--token-semantic-shape-extra-small, var(--token-global-radius-2, 4px)))`, "background-color": `var(${vars["root.background-color"]}, var(--token-semantic-color-surface-content, var(--token-semantic-color-background-surface, var(--token-global-material-neutral-98, oklch(0.98379491 0.01284496 321.893957)))))`, "background-color-disabled": `var(${vars["root.background-color-disabled"]}, var(--token-semantic-color-background-disabled, var(--token-global-material-neutral-90, oklch(0.91401081 0.01366394 314.754144))))`, "box-shadow": `var(${vars["root.box-shadow"]}, none)`, "box-shadow-focus": `var(${vars["root.box-shadow-focus"]}, inset 0 0 0 2px var(--token-semantic-color-border-focus, var(--token-global-purple-40, oklch(0.49552086 0.13045663 293.709078))))`, "validation": { "box-shadow-error": `var(${vars["root.validation.box-shadow-error"]}, inset 0 0 0 2px var(--token-semantic-color-feedback-error-border, var(--token-global-material-error-40, oklch(0.50128208 0.17831791 28.704727))))`, "box-shadow-warning": `var(${vars["root.validation.box-shadow-warning"]}, inset 0 0 0 2px var(--token-semantic-color-feedback-warning-border, var(--token-global-amber-700, oklch(0.555 0.163 71))))` }, "color-loading": `var(${vars["root.color-loading"]}, var(--token-semantic-color-text-secondary, var(--token-global-material-neutral-variant-30, oklch(0.39805288 0.01735545 303.720936))))` }, "motion": { "interaction": { "transition": `var(${vars["motion.interaction.transition"]}, var(--token-semantic-motion-interaction, var(--token-global-duration-150, 150ms) var(--token-global-easing-expressive-effects-fast, cubic-bezier(0.31, 0.94, 0.34, 1.00))))` }, "spatial": { "transition": `var(${vars["motion.spatial.transition"]}, var(--token-semantic-motion-spatial-fast, var(--token-global-duration-350, 350ms) var(--token-global-easing-expressive-spatial-fast, cubic-bezier(0.42, 1.67, 0.21, 0.90))))` } }, "text": { "color": `var(${vars["text.color"]}, var(--token-semantic-color-text-primary, var(--token-global-material-neutral-10, oklch(0.22652446 0.00999107 303.713695))))`, "color-placeholder": `var(${vars["text.color-placeholder"]}, var(--token-semantic-color-text-secondary, var(--token-global-material-neutral-variant-30, oklch(0.39805288 0.01735545 303.720936))))`, "color-disabled": `var(${vars["text.color-disabled"]}, var(--token-semantic-color-text-disabled, var(--token-global-material-neutral-10, oklch(0.22652446 0.00999107 303.713695))))` }, "tag": { "background-color": `var(${vars["tag.background-color"]}, var(--token-semantic-color-background-hover-subtle, color-mix(in oklch, var(--token-global-material-neutral-10, oklch(0.22652446 0.00999107 303.713695)) calc(var(--token-semantic-state-opacity-hover, var(--token-global-opacity-8, 0.08)) * 100%), var(--token-global-material-neutral-98, oklch(0.98379491 0.01284496 321.893957)))))`, "color": `var(${vars["tag.color"]}, var(--token-semantic-color-text-primary, var(--token-global-material-neutral-10, oklch(0.22652446 0.00999107 303.713695))))`, "close": { "color-hover": `var(${vars["tag.close.color-hover"]}, var(--token-semantic-color-text-secondary, var(--token-global-material-neutral-variant-30, oklch(0.39805288 0.01735545 303.720936))))` } }, "clear": { "color": `var(${vars["clear.color"]}, var(--token-semantic-color-text-secondary, var(--token-global-material-neutral-variant-30, oklch(0.39805288 0.01735545 303.720936))))`, "color-hover": `var(${vars["clear.color-hover"]}, var(--token-semantic-color-text-primary, var(--token-global-material-neutral-10, oklch(0.22652446 0.00999107 303.713695))))`, "width": `var(${vars["clear.width"]}, var(--token-semantic-size-48, var(--token-global-size-48, 48px)))`, "height": `var(${vars["clear.height"]}, var(--token-semantic-size-48, var(--token-global-size-48, 48px)))`, "touch": { "width": `var(${vars["clear.touch.width"]}, var(--token-semantic-size-touch-target, var(--token-global-size-48, 48px)))` }, "box-shadow-focus": `var(${vars["clear.box-shadow-focus"]}, inset 0 0 0 1px var(--token-semantic-color-focus-ring, var(--token-semantic-color-border-focus, var(--token-global-purple-40, oklch(0.49552086 0.13045663 293.709078)))))` }, "icon": { "width": `var(${vars["icon.width"]}, var(--token-semantic-space-group-gap, var(--token-global-space-6, 24px)))`, "color": `var(${vars["icon.color"]}, var(--token-semantic-color-text-secondary, var(--token-global-material-neutral-variant-30, oklch(0.39805288 0.01735545 303.720936))))` }, "field": { "gap": `var(${vars["field.gap"]}, var(--token-semantic-space-inline-gap, var(--token-global-space-1, 4px)))`, "padding-inline": `var(${vars["field.padding-inline"]}, var(--token-semantic-space-section-gap, var(--token-global-space-4, 16px)))`, "label": { "top": `var(${vars["field.label.top"]}, var(--token-semantic-space-component-gap, var(--token-global-space-2, 8px)))`, "padding-inline": `var(${vars["field.label.padding-inline"]}, var(--token-semantic-space-inline-gap, var(--token-global-space-1, 4px)))`, "font-size": `var(${vars["field.label.font-size"]}, var(--token-semantic-typography-body-small-font-size, var(--token-global-font-size-xs, 12px)))`, "line-height": `var(${vars["field.label.line-height"]}, var(--token-semantic-typography-body-small-line-height, var(--token-global-line-height-12-16, 1.3333333333333333)))`, "color": `var(${vars["field.label.color"]}, var(--token-semantic-color-text-secondary, var(--token-global-material-neutral-variant-30, oklch(0.39805288 0.01735545 303.720936))))`, "color-focus": `var(${vars["field.label.color-focus"]}, var(--token-semantic-color-brand-primary, var(--token-global-purple-40, oklch(0.49552086 0.13045663 293.709078))))` }, "input": { "padding-top": `var(${vars["field.input.padding-top"]}, var(--token-semantic-space-section-gap, var(--token-global-space-4, 16px)))` }, "transition": `var(${vars["field.transition"]}, top var(--token-semantic-motion-interaction, var(--token-global-duration-150, 150ms) var(--token-global-easing-expressive-effects-fast, cubic-bezier(0.31, 0.94, 0.34, 1.00))), font-size var(--token-semantic-motion-interaction, var(--token-global-duration-150, 150ms) var(--token-global-easing-expressive-effects-fast, cubic-bezier(0.31, 0.94, 0.34, 1.00))), color var(--token-semantic-motion-interaction, var(--token-global-duration-150, 150ms) var(--token-global-easing-expressive-effects-fast, cubic-bezier(0.31, 0.94, 0.34, 1.00))), background-color var(--token-semantic-motion-interaction, var(--token-global-duration-150, 150ms) var(--token-global-easing-expressive-effects-fast, cubic-bezier(0.31, 0.94, 0.34, 1.00))))`, "filled": { "background-color": `var(${vars["field.filled.background-color"]}, var(--token-semantic-color-surface-highest, var(--token-global-material-neutral-90, oklch(0.91401081 0.01366394 314.754144))))`, "background-color-hover": `var(${vars["field.filled.background-color-hover"]}, color-mix(in oklch, var(--token-semantic-color-text-primary, var(--token-global-material-neutral-10, oklch(0.22652446 0.00999107 303.713695))) calc(var(--token-semantic-state-opacity-hover, var(--token-global-opacity-8, 0.08)) * 100%), var(--token-semantic-color-surface-highest, var(--token-global-material-neutral-90, oklch(0.91401081 0.01366394 314.754144)))))` }, "indicator": { "border-color": `var(${vars["field.indicator.border-color"]}, var(--token-semantic-color-text-secondary, var(--token-global-material-neutral-variant-30, oklch(0.39805288 0.01735545 303.720936))))`, "box-shadow-focus": `var(${vars["field.indicator.box-shadow-focus"]}, inset 0 -2px 0 var(--token-semantic-color-border-focus, var(--token-global-purple-40, oklch(0.49552086 0.13045663 293.709078))))`, "box-shadow-error": `var(${vars["field.indicator.box-shadow-error"]}, inset 0 -2px 0 var(--token-semantic-color-feedback-error-border, var(--token-global-material-error-40, oklch(0.50128208 0.17831791 28.704727))))`, "box-shadow-warning": `var(${vars["field.indicator.box-shadow-warning"]}, inset 0 -2px 0 var(--token-semantic-color-feedback-warning-border, var(--token-global-amber-700, oklch(0.555 0.163 71))))` }, "color-error": `var(${vars["field.color-error"]}, var(--token-semantic-color-feedback-error-text, var(--token-global-material-error-10, oklch(0.25390329 0.07937181 27.605486))))`, "color-warning": `var(${vars["field.color-warning"]}, var(--token-semantic-color-feedback-warning-text, var(--token-global-amber-900, oklch(0.414 0.112 68))))`, "support": { "line-height": `var(${vars["field.support.line-height"]}, var(--token-semantic-typography-body-small-line-height, var(--token-global-line-height-12-16, 1.3333333333333333)))` } }, "group": { "color": `var(${vars["group.color"]}, var(--token-semantic-color-text-secondary, var(--token-global-material-neutral-variant-30, oklch(0.39805288 0.01735545 303.720936))))`, "font-size": `var(${vars["group.font-size"]}, var(--token-semantic-typography-caption-font-size, var(--token-global-font-size-xs, 12px)))` }, "size": { "large": { "height": `var(${vars["size.large.height"]}, var(--token-semantic-sizing-large-field, var(--token-global-size-64, 64px)))`, "padding": `var(${vars["size.large.padding"]}, var(--token-semantic-space-inline-gap, var(--token-global-space-1, 4px)) var(--token-semantic-space-control-padding-x, var(--token-global-space-3, 12px)))`, "font-size": `var(${vars["size.large.font-size"]}, var(--token-semantic-typography-body-large-font-size, var(--token-global-font-size-md, 16px)))`, "line-height": `var(${vars["size.large.line-height"]}, calc(var(--token-semantic-typography-body-large-font-size, var(--token-global-font-size-md, 16px)) * var(--token-semantic-typography-body-large-line-height, var(--token-global-line-height-16-24, 1.5))))`, "action": { "width": `var(${vars["size.large.action.width"]}, var(--token-semantic-sizing-large-action, var(--token-global-size-48, 48px)))` } }, "middle": { "height": `var(${vars["size.middle.height"]}, var(--token-semantic-sizing-middle-field, var(--token-global-size-56, 56px)))`, "padding": `var(${vars["size.middle.padding"]}, var(--token-semantic-space-inline-gap, var(--token-global-space-1, 4px)) var(--token-semantic-space-control-padding-x, var(--token-global-space-3, 12px)))`, "font-size": `var(${vars["size.middle.font-size"]}, var(--token-semantic-typography-body-large-font-size, var(--token-global-font-size-md, 16px)))`, "line-height": `var(${vars["size.middle.line-height"]}, calc(var(--token-semantic-typography-body-large-font-size, var(--token-global-font-size-md, 16px)) * var(--token-semantic-typography-body-large-line-height, var(--token-global-line-height-16-24, 1.5))))`, "action": { "width": `var(${vars["size.middle.action.width"]}, var(--token-semantic-sizing-middle-action, var(--token-global-size-40, 40px)))` } }, "small": { "height": `var(${vars["size.small.height"]}, var(--token-semantic-sizing-small-field, var(--token-global-size-48, 48px)))`, "padding": `var(${vars["size.small.padding"]}, 0 var(--token-semantic-space-control-padding-x-small, var(--token-global-space-2, 8px)))`, "font-size": `var(${vars["size.small.font-size"]}, var(--token-semantic-typography-body-large-font-size, var(--token-global-font-size-md, 16px)))`, "line-height": `var(${vars["size.small.line-height"]}, calc(var(--token-semantic-typography-body-large-font-size, var(--token-global-font-size-md, 16px)) * var(--token-semantic-typography-body-large-line-height, var(--token-global-line-height-16-24, 1.5))))`, "action": { "width": `var(${vars["size.small.action.width"]}, var(--token-semantic-sizing-small-action, var(--token-global-size-32, 32px)))` } } }, "dropdown": { "margin": `var(${vars["dropdown.margin"]}, 6px)`, "max-height": `var(${vars["dropdown.max-height"]}, 240px)`, "padding": `var(${vars["dropdown.padding"]}, var(--token-semantic-space-inline-gap, var(--token-global-space-1, 4px)))`, "option": { "padding": `var(${vars["dropdown.option.padding"]}, var(--token-semantic-space-component-gap, var(--token-global-space-2, 8px)))` }, "border-radius": `var(${vars["dropdown.border-radius"]}, var(--token-semantic-shape-extra-small, var(--token-global-radius-2, 4px)))` } });
|
|
4
|
+
export default token;
|
package/esm/index.mjs
CHANGED
|
@@ -1 +1,4 @@
|
|
|
1
|
-
import e,{useDropdownContext as l}from"@crab-dev/rc-dropdown-container";import{useState as t,useRef as o,useCallback as r,useEffect as a,useId as n}from"react";import{useControllableValue as i}from"@crab-dev/rc-hooks";import{c as s}from"react/compiler-runtime";import c from"@crab-dev/rc-line-edit";import{SpinIndicator as d}from"@crab-dev/rc-spin";import h from"@crab-dev/rc-tag";import{cx as p}from"@linaria/core";import{jsxDEV as u,Fragment as v}from"react/jsx-dev-runtime";import g from"@crab-dev/rc-checkbox";import m from"@crab-dev/rc-virtual";const f="rc-select-c1dsn6ds",b="rc-select-p1l0d023",y={large:"rc-select-l1ohqr33",middle:"rc-select-mvtp1fw",small:"rc-select-s1n8wm60"},x={large:"rc-select-ls4o1df",middle:"rc-select-mxdjkcj",small:"rc-select-s1qq3fet"},C={large:"rc-select-l11npiub",middle:"rc-select-mnw2jq7",small:"rc-select-s1p8llhq"},w=()=>{const e=s(1);let l;return e[0]===Symbol.for("react.memo_cache_sentinel")?(l=u("svg",{width:"12",height:"12",viewBox:"0 0 1024 1024",fill:"currentColor",children:u("path",{d:"M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3 0.1-12.7-6.4-12.7z"},void 0,!1)},void 0,!1),e[0]=l):l=e[0],l},k=()=>{const e=s(1);let l;return e[0]===Symbol.for("react.memo_cache_sentinel")?(l=u("svg",{width:"12",height:"12",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[u("circle",{cx:"12",cy:"12",r:"10"},void 0,!1),u("path",{d:"m15 9-6 6M9 9l6 6"},void 0,!1)]},void 0,!0),e[0]=l):l=e[0],l},N=({ref:e,ariaLabel:t,disabled:n,searchable:i,multiple:s,size:g,status:m,allowClear:N,loading:O,maxTagCount:R,autoFocus:_,placeholder:I,selectedOptions:L,searchText:q,highlightIndex:H,highlightedOption:T,listboxId:S,tagRender:j,onSearchTextChange:z,onOpenChange:F,onWidthChange:M,onMoveHighlight:B,onSelectHighlighted:D,onClear:W,onRemoveTag:A,onFocus:G,onBlur:$})=>{const{state:E,refs:P,dispatch:V}=l(),K=o(null),U=o(null),J=E.open,Q=o(F);Q.current=F;const X=r(l=>{K.current=l,"function"==typeof P.setReference&&P.setReference(l),((e,l)=>{"function"==typeof e?e(l):e&&(e.current=l)})(e,l)},[P.setReference,e]);a(()=>{const e=K.current;if(!e)return;const l=new ResizeObserver(e=>{for(const l of e)M(l.target.getBoundingClientRect().width)});return l.observe(e),()=>l.disconnect()},[M]),a(()=>{J&&i&&queueMicrotask(()=>U.current?.focus())},[J,i]),a(()=>{_&&K.current&&K.current.focus()},[_]);const Y=o(!0);a(()=>{Y.current?Y.current=!1:Q.current(J)},[J]);const Z=()=>{W(),J&&V({type:"setOpen",payload:!1})},ee=N&&!n&&L.length>0,le=e=>{const l=()=>A(e.value);return j?u("span",{children:j(e,l)},e.value,!1):u(h,{size:"small",closable:!0,closeAriaLabel:`Remove ${"string"==typeof e.label?e.label:e.value}`,onClose:l,children:u("span",{className:"rc-select-tj3q1lh",children:e.label},void 0,!1)},e.value,!1)},te=()=>{if(void 0!==R&&L.length>R){const e=L.slice(0,R),l=L.length-R;return u(v,{children:[e.map(le),u(h,{size:"small",children:["+",l]},void 0,!0)]},void 0,!0)}return L.map(le)};return u("div",{role:"combobox","aria-label":t,"aria-expanded":J,"aria-disabled":n,"aria-busy":O||void 0,"aria-haspopup":"listbox","aria-controls":J?S:void 0,"aria-activedescendant":J&&H>=0?`${S}-option-${H}`:void 0,"aria-invalid":"error"===m||void 0,tabIndex:n?-1:0,ref:X,className:p("rc-select-c1l5vx99",y[g],s?C[g]:x[g],!m&&J&&f,n&&"rc-select-cvb0fm4",m?"error"===m?p("rc-select-c1na8b52",J&&"rc-select-c19mujlp"):p("rc-select-c16epqep",J&&"rc-select-ckhhleb"):J?f:void 0),onClick:()=>{n||V({type:"setOpen",payload:!J})},onKeyDown:e=>{if(!n)switch(e.key){case"ArrowDown":e.preventDefault(),J||V({type:"setOpen",payload:!0}),B(1);break;case"ArrowUp":e.preventDefault(),J||V({type:"setOpen",payload:!0}),B(-1);break;case"Enter":e.preventDefault(),J&&T?(D(T),s||V({type:"setOpen",payload:!1})):J||V({type:"setOpen",payload:!0});break;case" ":i&&J||(e.preventDefault(),J||V({type:"setOpen",payload:!0}));break;case"Escape":J&&(e.preventDefault(),V({type:"setOpen",payload:!1}));break;case"Backspace":if(s&&""===q&&L.length>0){const e=L[L.length-1];A(e.value)}}},onFocus:G,onBlur:$,children:[u("div",{className:"rc-select-v1mxlf89",children:i&&J?u(v,{children:[s&&te(),u(c,{ref:U,bordered:!1,value:q,placeholder:s&&L.length>0?"":I,onChange:e=>z(e.target.value),onClick:e=>e.stopPropagation(),className:"rc-select-s1r0kmh4"},void 0,!1)]},void 0,!0):s?0===L.length?u("span",{className:b,children:I},void 0,!1):te():0===L.length?u("span",{className:b,children:I},void 0,!1):u("span",{className:"rc-select-sfumuma",children:L[0]?.label},void 0,!1)},void 0,!1),O?u("span",{className:"rc-select-l1m17a72",children:u(d,{},void 0,!1)},void 0,!1):null,u("span",{className:"rc-select-s10zhocr",children:[u("span",{"data-role":ee?"select-caret":void 0,className:p("rc-select-c1t4pqsr",J&&"rc-select-c1a799e8"),children:u(w,{},void 0,!1)},void 0,!1),ee?u("span",{"data-role":"select-clear",className:"rc-select-c1i3ciyg",role:"button",tabIndex:0,"aria-label":"Clear",onClick:e=>{e.stopPropagation(),Z()},onKeyDown:e=>{"Enter"!==e.key&&" "!==e.key||(e.preventDefault(),e.stopPropagation(),Z())},children:u(k,{},void 0,!1)},void 0,!1):null]},void 0,!0)]},void 0,!0)},O="rc-select-o197jepe",R=e=>{const t=s(51),{multiple:r,loading:n,filteredOptions:i,selectedValues:c,triggerWidth:h,highlightIndex:f,listboxId:b,notFoundContent:y,popupClassName:x,optionRender:C,dropdownRender:w,onOptionSelect:k,onOpenChange:N,onHighlightChange:R}=e,{dispatch:_}=l(),I=o(null);let L,q;if(t[0]!==f?(L=()=>{f<0||I.current?.scrollToCell({rowIndex:f})},q=[f],t[0]=f,t[1]=L,t[2]=q):(L=t[1],q=t[2]),a(L,q),n){let e,l,o;return t[3]!==x?(e=p(O,x),t[3]=x,t[4]=e):e=t[4],t[5]===Symbol.for("react.memo_cache_sentinel")?(l=u("div",{className:"rc-select-l274z9g",children:u(d,{},void 0,!1)},void 0,!1),t[5]=l):l=t[5],t[6]!==b||t[7]!==e?(o=u("div",{id:b,role:"listbox","aria-busy":"true","data-select-overlay":!0,className:e,children:l},void 0,!1),t[6]=b,t[7]=e,t[8]=o):o=t[8],o}if(0===i.length){let e;t[9]!==x?(e=p(O,x),t[9]=x,t[10]=e):e=t[10];const l=y??"无匹配选项";let o,r;return t[11]!==l?(o=u("div",{className:"rc-select-e198oa40",children:l},void 0,!1),t[11]=l,t[12]=o):o=t[12],t[13]!==b||t[14]!==e||t[15]!==o?(r=u("div",{id:b,role:"listbox","data-select-overlay":!0,className:e,children:o},void 0,!1),t[13]=b,t[14]=e,t[15]=o,t[16]=r):r=t[16],r}const H=i.length,T=Math.max(h-8,160),S=Math.min(256,32*H);let j;t[17]!==H?(j=Array(H).fill(32),t[17]=H,t[18]=j):j=t[18];const z=j;let F;t[19]!==i?(F=i.some(e=>e.isGroupLabel),t[19]=i,t[20]=F):F=t[20];const M=F;let B,D,W;t[21]!==T?(B=[T],t[21]=T,t[22]=B):B=t[22],t[23]!==_||t[24]!==i||t[25]!==f||t[26]!==M||t[27]!==b||t[28]!==r||t[29]!==R||t[30]!==N||t[31]!==k||t[32]!==C||t[33]!==c?(D=e=>{const l=[u("div",{className:"rc-select-d1dli847"},"__select-top-padding__",!1)];for(let t=e[0];t<=e[1];t+=1,t){const e=i[t];if(e.isGroupLabel){l.push(u("div",{"data-group-label":!0,className:"rc-select-g17o4y",children:e.label},e.value,!1));continue}const o=c.includes(e.value),a=t===f,n=C?C(e,{selected:o}):u(v,{children:[r?u(g,{className:"rc-select-c19svz90",checked:o,disabled:e.disabled,tabIndex:-1,"aria-label":"string"==typeof e.label?e.label:e.value},void 0,!1):null,u("span",{className:"rc-select-o1dhqqw2",children:e.label},void 0,!1),!r&&o?u("span",{className:"rc-select-c3deb06",children:u("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:u("path",{d:"M20 6 9 17l-5-5"},void 0,!1)},void 0,!1)},void 0,!1):null]},void 0,!0),s=r?"string"==typeof e.label?e.label:e.value:void 0;l.push(u("div",{id:`${b}-option-${t}`,role:"option","aria-selected":o,"aria-label":s,className:p("rc-select-o8623go",M&&"rc-select-gc4dk9f",o&&(r?"rc-select-oxaegfe":"rc-select-o16p9iym"),a&&"rc-select-o1n324dj",e.disabled&&"rc-select-o1qyr5qv"),onMouseEnter:()=>R(t),onClick:()=>{k(e),r||e.disabled||(_({type:"setOpen",payload:!1}),N(!1))},children:n},e.value,!1))}return l.push(u("div",{className:"rc-select-d1a6h40l"},"__select-bottom-padding__",!1)),l},t[23]=_,t[24]=i,t[25]=f,t[26]=M,t[27]=b,t[28]=r,t[29]=R,t[30]=N,t[31]=k,t[32]=C,t[33]=c,t[34]=D):D=t[34],t[35]!==T||t[36]!==z||t[37]!==B||t[38]!==D||t[39]!==S?(W=u(m,{gridRef:I,viewportWidth:T,viewportHeight:S,gridTemplateColumns:B,gridTemplateRows:z,renderRows:D},void 0,!1),t[35]=T,t[36]=z,t[37]=B,t[38]=D,t[39]=S,t[40]=W):W=t[40];const A=W;let G;t[41]!==x?(G=p(O,x),t[41]=x,t[42]=G):G=t[42];const $=r||void 0;let E,P;return t[43]!==w||t[44]!==A?(E=w?w(A):A,t[43]=w,t[44]=A,t[45]=E):E=t[45],t[46]!==b||t[47]!==E||t[48]!==G||t[49]!==$?(P=u("div",{id:b,"data-select-overlay":!0,className:G,role:"listbox","aria-multiselectable":$,children:E},void 0,!1),t[46]=b,t[47]=E,t[48]=G,t[49]=$,t[50]=P):P=t[50],P},_=e=>"options"in e&&Array.isArray(e.options),I=e=>void 0===e?[]:Array.isArray(e)?e:[e],L=(e,l,t)=>{if(!l||""===t.trim())return e;const o=t.trim().toLowerCase();return e.filter(e=>!e.isGroupLabel&&("string"==typeof e.label?e.label.toLowerCase().includes(o):e.value.toLowerCase().includes(o)))},q=({ref:l,options:r,placeholder:a="请选择",disabled:c=!1,searchable:d=!1,multiple:h=!1,size:p="middle",status:v,allowClear:g=!1,loading:m=!1,maxTagCount:f,autoFocus:b=!1,notFoundContent:y,popupClassName:x,popupMatchSelectWidth:C=!0,optionRender:w,tagRender:k,dropdownRender:O,value:q,defaultValue:H,onChange:T,onOpenChange:S,onFocus:j,onBlur:z,className:F,"aria-label":M,...B})=>{const D=n(),[W,A]=t(""),[G,$]=i({value:void 0!==q?I(q):void 0,defaultValue:I(H)}),[E,P]=t(0),V=o(S);V.current=S;const K=(e=>{const l=[];for(const t of e)if(_(t))for(const e of t.options)l.push(e);else l.push(t);return l})(r),U=K.filter(e=>G.includes(e.value)),J=(e=>{const l=[];return e.forEach((e,t)=>{if(_(e)){l.push({label:e.label,value:`__group_${t}`,isGroupLabel:!0});for(const t of e.options)l.push(t)}else l.push(e)}),l})(r),Q=L(J,d,W),{highlightIndex:X,highlightedOption:Y,moveHighlight:Z,resetHighlight:ee,setHighlightIndex:le}=(e=>{const l=s(10),{filteredOptions:o,open:r}=e,[a,n]=t(-1);let i;l[0]!==o?(i=(e,l)=>{const t=o.length;if(0===t)return-1;let r=e;for(let e=0;e<t;e+=1,e){r=((r+l)%t+t)%t;const e=o[r];if(!e.disabled&&!e.isGroupLabel)return r}return-1},l[0]=o,l[1]=i):i=l[1];const c=i;let d;l[2]!==c||l[3]!==r?(d=e=>{r&&n(l=>c(-1===l?1===e?-1:0:l,e))},l[2]=c,l[3]=r,l[4]=d):d=l[4];const h=d;let p;l[5]===Symbol.for("react.memo_cache_sentinel")?(p=()=>{n(-1)},l[5]=p):p=l[5];const u=p,v=a>=0&&a<o.length?o[a]:void 0;let g;return l[6]!==a||l[7]!==v||l[8]!==h?(g={highlightIndex:a,highlightedOption:v,moveHighlight:h,resetHighlight:u,setHighlightIndex:n},l[6]=a,l[7]=v,l[8]=h,l[9]=g):g=l[9],g})({filteredOptions:Q,open:!0}),te=e=>{if(e){if(!h&&G.length>0){const e=Q.findIndex(e=>e.value===G[0]);le(e)}}else A(""),ee();V.current?.(e)},oe=e=>{if($(e),h){const l=K.filter(l=>e.includes(l.value));return void T?.(e,l)}const l=e[0],t=K.find(e=>e.value===l);T?.(l,t)},re=e=>{if(!e.disabled&&!e.isGroupLabel){if(h){const l=G.includes(e.value)?G.filter(l=>l!==e.value):[...G,e.value];return void oe(l)}oe([e.value])}},ae=C?{width:E}:{minWidth:E};return u(e,{...B,className:F,overlay:u(R,{multiple:h,loading:m,filteredOptions:Q,selectedValues:G,triggerWidth:E,highlightIndex:X,listboxId:D,notFoundContent:y,popupClassName:x,optionRender:w,dropdownRender:O,onOptionSelect:re,onOpenChange:te,onHighlightChange:le},void 0,!1),floatingContainerProps:{style:ae},children:u(N,{ref:l,ariaLabel:M,disabled:c,searchable:d,multiple:h,size:p,status:v,allowClear:g,loading:m,maxTagCount:f,autoFocus:b,placeholder:a,selectedOptions:U,searchText:W,highlightIndex:X,highlightedOption:Y,listboxId:D,tagRender:k,onSearchTextChange:e=>{A(e);const l=L(J,d,e);le((e=>e.findIndex(e=>!e.disabled&&!e.isGroupLabel))(l))},onOpenChange:te,onWidthChange:e=>{P(e)},onMoveHighlight:Z,onSelectHighlighted:re,onClear:()=>{oe([]),A("")},onRemoveTag:e=>{oe(G.filter(l=>l!==e))},onFocus:j,onBlur:z},void 0,!1)},void 0,!1)};export{q as default};
|
|
1
|
+
import Select from "./_wake/src/select.mjs";
|
|
2
|
+
;
|
|
3
|
+
export default Select;
|
|
4
|
+
export { vars as TokenVars } from "./_wake/src/token.mjs";
|
package/package.json
CHANGED
|
@@ -5,21 +5,22 @@
|
|
|
5
5
|
"category": "data-entry"
|
|
6
6
|
},
|
|
7
7
|
"description": "下拉选择器,支持单选、多选和搜索",
|
|
8
|
-
"packageManager": "yarn@4.
|
|
8
|
+
"packageManager": "yarn@4.18.0",
|
|
9
9
|
"type": "module",
|
|
10
|
-
"version": "0.0.
|
|
10
|
+
"version": "0.0.5",
|
|
11
11
|
"repository": {
|
|
12
12
|
"type": "git",
|
|
13
13
|
"url": "https://github.com/hotlif/crab-dev.git",
|
|
14
14
|
"directory": "components/rc-select"
|
|
15
15
|
},
|
|
16
16
|
"scripts": {
|
|
17
|
-
"
|
|
18
|
-
"
|
|
19
|
-
"
|
|
20
|
-
"generate:
|
|
21
|
-
"
|
|
22
|
-
"
|
|
17
|
+
"typecheck": "node ../../scripts/typecheck.mjs --noEmit",
|
|
18
|
+
"start": "yarn generate:token && yarn generate:docgen && wake docs dev . --mode components",
|
|
19
|
+
"build:library": "yarn generate:token && wake library build .",
|
|
20
|
+
"generate:docgen": "wake library docgen .",
|
|
21
|
+
"generate:token": "wake library token .",
|
|
22
|
+
"test": "wake test --serial --coverage",
|
|
23
|
+
"lint": "wake lint --format human --root ../.. components/rc-select/src components/rc-select/docs --env browser --max-warnings 0"
|
|
23
24
|
},
|
|
24
25
|
"files": [
|
|
25
26
|
"esm",
|
|
@@ -40,44 +41,33 @@
|
|
|
40
41
|
"./package.json": "./package.json"
|
|
41
42
|
},
|
|
42
43
|
"devDependencies": {
|
|
43
|
-
"@crab-dev/lignify": "^0.0.4",
|
|
44
|
-
"@crab-dev/packify": "^0.0.5",
|
|
45
44
|
"@crab-dev/rc-component-preview": "^0.0.2",
|
|
46
45
|
"@crab-dev/rc-masonry": "^0.0.2",
|
|
47
|
-
"@crab-dev/rc-menu": "^0.0.
|
|
48
|
-
"@crab-dev/rc-token-semantic": "^0.0.
|
|
49
|
-
"@crab-dev/standards-
|
|
50
|
-
"@crab-dev/
|
|
51
|
-
"@
|
|
52
|
-
"@
|
|
53
|
-
"@
|
|
54
|
-
"
|
|
55
|
-
"
|
|
56
|
-
"
|
|
57
|
-
"
|
|
58
|
-
"@types/react": "^19.2.17",
|
|
59
|
-
"@types/react-dom": "^19.2.3",
|
|
60
|
-
"eslint": "^10.6.0",
|
|
61
|
-
"eslint-plugin-react": "^7.37.5",
|
|
62
|
-
"globals": "^17.7.0",
|
|
63
|
-
"jest": "^30.4.2",
|
|
64
|
-
"jest-environment-jsdom": "30.4.1",
|
|
65
|
-
"react": "^19.2.7",
|
|
66
|
-
"react-dom": "^19.2.7",
|
|
67
|
-
"react-router": "^8.1.0",
|
|
68
|
-
"typescript": "^6.0.3",
|
|
69
|
-
"typescript-eslint": "^8.63.0"
|
|
46
|
+
"@crab-dev/rc-menu": "^0.0.4",
|
|
47
|
+
"@crab-dev/rc-token-semantic": "^0.0.4",
|
|
48
|
+
"@crab-dev/standards-typescript-preset": "^0.0.5",
|
|
49
|
+
"@crab-dev/wake": "0.1.45",
|
|
50
|
+
"@types/node": "^22.20.2",
|
|
51
|
+
"@types/react": "^19.3.0",
|
|
52
|
+
"@types/react-dom": "^19.3.0",
|
|
53
|
+
"react": "19.3.0",
|
|
54
|
+
"react-dom": "19.3.0",
|
|
55
|
+
"react-router": "^8.3.1",
|
|
56
|
+
"typescript": "^7.0.2"
|
|
70
57
|
},
|
|
71
58
|
"engines": {
|
|
72
59
|
"node": ">=22"
|
|
73
60
|
},
|
|
74
61
|
"dependencies": {
|
|
75
|
-
"@crab-dev/
|
|
76
|
-
"@crab-dev/rc-
|
|
77
|
-
"@crab-dev/rc-
|
|
78
|
-
"@crab-dev/rc-
|
|
79
|
-
"@crab-dev/rc-
|
|
80
|
-
"@crab-dev/rc-
|
|
81
|
-
"@crab-dev/rc-
|
|
62
|
+
"@crab-dev/css": "0.1.45",
|
|
63
|
+
"@crab-dev/rc-button": "^0.0.3",
|
|
64
|
+
"@crab-dev/rc-checkbox": "^0.0.4",
|
|
65
|
+
"@crab-dev/rc-config-provider": "^0.0.2",
|
|
66
|
+
"@crab-dev/rc-dropdown-container": "^0.0.5",
|
|
67
|
+
"@crab-dev/rc-hooks": "^0.0.3",
|
|
68
|
+
"@crab-dev/rc-line-edit": "^0.0.5",
|
|
69
|
+
"@crab-dev/rc-spin": "^0.0.4",
|
|
70
|
+
"@crab-dev/rc-tag": "^0.0.3",
|
|
71
|
+
"@crab-dev/rc-virtual": "^0.1.4"
|
|
82
72
|
}
|
|
83
73
|
}
|