@crab-dev/rc-select 0.0.5 → 0.1.0
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 +41 -0
- package/cjs/_wake/src/select.cjs +45 -29
- package/cjs/_wake/src/selectInput.cjs +43 -60
- package/cjs/_wake/src/selectInput.styles.cjs +69 -0
- package/cjs/_wake/src/selectOverlay.cjs +44 -48
- package/cjs/_wake/src/selectOverlay.styles.cjs +68 -0
- package/cjs/_wake/src/token.cjs +2 -2
- package/css/index.css +5 -8
- package/declarations/_wake/src/select.d.ts +43 -3
- package/declarations/_wake/src/token.d.ts +2 -2
- package/declarations/_wake/src/types.d.ts +18 -20
- package/declarations/index.d.ts +1 -1
- package/esm/_wake/src/select.mjs +35 -19
- package/esm/_wake/src/selectInput.mjs +34 -51
- package/esm/_wake/src/selectInput.styles.mjs +20 -0
- package/esm/_wake/src/selectOverlay.mjs +29 -33
- package/esm/_wake/src/selectOverlay.styles.mjs +19 -0
- package/esm/_wake/src/token.mjs +2 -2
- package/package.json +30 -22
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,46 @@
|
|
|
1
1
|
# @crab-dev/rc-select
|
|
2
2
|
|
|
3
|
+
## 0.1.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [`d11001f`](https://github.com/hotlif/crab-dev/commit/d11001fa35d4af4f53d0571c074de4b3e9806903) Thanks [@hotlif](https://github.com/hotlif)! - Rebuild the component library around a single package inventory, independent architecture and usage classifications, and three design systems: MD3 Expressive (md3), Apple (apple), and shadcn/ui (shadcn).
|
|
8
|
+
|
|
9
|
+
This is a breaking pre-1.0 migration: unify controlled/uncontrolled values, selection callbacks, component APIs, sizes, and density contracts; replace legacy theme identifiers and remove old API aliases. Only stored browser appearance preferences are migrated automatically.
|
|
10
|
+
|
|
11
|
+
Declare required React/ReactDOM ^19.2.0 peers through runtime dependency chains while retaining development dependencies. Correct runtime token dependencies, public/internal exports, strict declaration consumption, and independent offline PnP package verification.
|
|
12
|
+
|
|
13
|
+
Correct RTL layout and overlay placement, field validation placement, embedded editor composition and focus, native virtual-scroll synchronization, and composed button feedback. Define independent multiline field geometry and preserve all eight configuration axes across controlled previews and PDF Web Components. Built-in error messages follow locale without replacing application-owned error data.
|
|
14
|
+
|
|
15
|
+
Restore compiled focus and disabled styles by using valid CSS template comments, keep Tree focus indicators inside measured containers and above selected row backgrounds, accommodate localized color-channel labels, preserve physical Table column geometry with RTL content, and accept PDF byte sources from iframe realms without treating them as URLs. Respect reduced motion in the property-driven Canvas animation example and let the pill Tabs example inherit the configured size.
|
|
16
|
+
|
|
17
|
+
Follow .website/docs/guides/migration.mdx before upgrading. All affected packages remain experimental; minor bumps represent the coordinated pre-1.0 breaking release and do not declare a stable 1.0 contract.
|
|
18
|
+
|
|
19
|
+
### Patch Changes
|
|
20
|
+
|
|
21
|
+
- [`ec1f759`](https://github.com/hotlif/crab-dev/commit/ec1f759d51a83a456b4eb7f608f2e4908d4d46da) Thanks [@hotlif](https://github.com/hotlif)! - 补齐选择、导航和浮层的三体系规格、公开示例与包内 Playwright 状态矩阵,覆盖真实键盘、Portal 配置与草稿保留。颜色面板的轨道、宽度与操作间距归入组件令牌,窄屏操作区支持换行,强制颜色下保留清晰的触发器焦点边界。
|
|
22
|
+
|
|
23
|
+
恢复颜色选择器公开的 showEyeDropper 屏幕取色入口,按所属浏览器能力显示,取消或拒绝不改值,卸载中止原生取色会话。
|
|
24
|
+
|
|
25
|
+
补充水平与折叠菜单真实展开、Dialog 确认/取消 pending 动态场景,以及 Drawer 包公开的 iframe/Shadow DOM 组合示例;分别记录共享底层回归与真实浏览器验收范围,保留未运行、未复审部分。
|
|
26
|
+
|
|
27
|
+
- [`d11001f`](https://github.com/hotlif/crab-dev/commit/d11001fa35d4af4f53d0571c074de4b3e9806903) Thanks [@hotlif](https://github.com/hotlif)! - Restore focus after an accepted keyboard tab close, position Select popups outside their own supporting text, preserve design-specific disabled placeholders, and keep menu focus and color trigger feedback visible. Fix the appointment dialog example to retain Form's grid layout.
|
|
28
|
+
|
|
29
|
+
Register dropdown Escape layers when delayed Portal elements actually mount, and preserve explicit close reasons and native events through consumer dispatch.
|
|
30
|
+
|
|
31
|
+
Use the date placeholder for the appointment form's empty state instead of presenting a fake selected value.
|
|
32
|
+
- Updated dependencies [[`d11001f`](https://github.com/hotlif/crab-dev/commit/d11001fa35d4af4f53d0571c074de4b3e9806903), [`ec1f759`](https://github.com/hotlif/crab-dev/commit/ec1f759d51a83a456b4eb7f608f2e4908d4d46da), [`ec1f759`](https://github.com/hotlif/crab-dev/commit/ec1f759d51a83a456b4eb7f608f2e4908d4d46da), [`d11001f`](https://github.com/hotlif/crab-dev/commit/d11001fa35d4af4f53d0571c074de4b3e9806903), [`d11001f`](https://github.com/hotlif/crab-dev/commit/d11001fa35d4af4f53d0571c074de4b3e9806903), [`d11001f`](https://github.com/hotlif/crab-dev/commit/d11001fa35d4af4f53d0571c074de4b3e9806903), [`ec1f759`](https://github.com/hotlif/crab-dev/commit/ec1f759d51a83a456b4eb7f608f2e4908d4d46da), [`d11001f`](https://github.com/hotlif/crab-dev/commit/d11001fa35d4af4f53d0571c074de4b3e9806903), [`ec1f759`](https://github.com/hotlif/crab-dev/commit/ec1f759d51a83a456b4eb7f608f2e4908d4d46da), [`ec1f759`](https://github.com/hotlif/crab-dev/commit/ec1f759d51a83a456b4eb7f608f2e4908d4d46da), [`ec1f759`](https://github.com/hotlif/crab-dev/commit/ec1f759d51a83a456b4eb7f608f2e4908d4d46da), [`ec1f759`](https://github.com/hotlif/crab-dev/commit/ec1f759d51a83a456b4eb7f608f2e4908d4d46da), [`d11001f`](https://github.com/hotlif/crab-dev/commit/d11001fa35d4af4f53d0571c074de4b3e9806903), [`d11001f`](https://github.com/hotlif/crab-dev/commit/d11001fa35d4af4f53d0571c074de4b3e9806903), [`d11001f`](https://github.com/hotlif/crab-dev/commit/d11001fa35d4af4f53d0571c074de4b3e9806903), [`d11001f`](https://github.com/hotlif/crab-dev/commit/d11001fa35d4af4f53d0571c074de4b3e9806903), [`d11001f`](https://github.com/hotlif/crab-dev/commit/d11001fa35d4af4f53d0571c074de4b3e9806903), [`ec1f759`](https://github.com/hotlif/crab-dev/commit/ec1f759d51a83a456b4eb7f608f2e4908d4d46da)]:
|
|
33
|
+
- @crab-dev/rc-dropdown-container@0.1.0
|
|
34
|
+
- @crab-dev/rc-hooks@0.1.0
|
|
35
|
+
- @crab-dev/rc-tag@0.1.0
|
|
36
|
+
- @crab-dev/rc-button@1.0.0
|
|
37
|
+
- @crab-dev/rc-checkbox@0.1.0
|
|
38
|
+
- @crab-dev/rc-config-provider@0.1.0
|
|
39
|
+
- @crab-dev/rc-line-edit@0.1.0
|
|
40
|
+
- @crab-dev/rc-spin@0.1.0
|
|
41
|
+
- @crab-dev/rc-token-semantic@1.0.0
|
|
42
|
+
- @crab-dev/rc-virtual@0.2.0
|
|
43
|
+
|
|
3
44
|
## 0.0.5
|
|
4
45
|
|
|
5
46
|
### Patch Changes
|
package/cjs/_wake/src/select.cjs
CHANGED
|
@@ -2,11 +2,14 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
2
2
|
const __wake_namespace_0 = require("react/jsx-runtime");
|
|
3
3
|
const __wake_namespace_1 = require("@crab-dev/rc-config-provider");
|
|
4
4
|
const __wake_namespace_2 = require("@crab-dev/rc-dropdown-container");
|
|
5
|
-
const __wake_namespace_3 = require("
|
|
6
|
-
|
|
7
|
-
const
|
|
8
|
-
|
|
9
|
-
const
|
|
5
|
+
const __wake_namespace_3 = require("@crab-dev/rc-dropdown-container/internal");
|
|
6
|
+
require("@crab-dev/rc-token-semantic");
|
|
7
|
+
const __wake_namespace_4 = require("react");
|
|
8
|
+
;
|
|
9
|
+
const __wake_namespace_5 = require("@crab-dev/rc-hooks");
|
|
10
|
+
const __wake_namespace_6 = require("./hooks/useKeyboardNavigation.cjs");
|
|
11
|
+
const __wake_namespace_7 = require("./selectInput.cjs");
|
|
12
|
+
const __wake_namespace_8 = require("./selectOverlay.cjs");
|
|
10
13
|
require("./token.cjs");
|
|
11
14
|
;
|
|
12
15
|
const isGroup = (item) => "options" in item && Array.isArray(item.options);
|
|
@@ -61,26 +64,30 @@ const filterOptions = (flatOptions, searchable, searchText) => {
|
|
|
61
64
|
const firstEnabledIndex = (flatOptions) => flatOptions.findIndex((opt) => !opt.disabled && !opt.isGroupLabel);
|
|
62
65
|
const fieldStyle = "rc-select-0f3ecf945b98";
|
|
63
66
|
const supportingStyle = "rc-select-3bd2a27273ad";
|
|
64
|
-
|
|
67
|
+
function SelectField({ children }) {
|
|
68
|
+
const setPositionReference = (0, __wake_namespace_3["useDropdownPositionReference"])();
|
|
69
|
+
return (0, __wake_namespace_0["jsx"])("div", { className: fieldStyle, ref: setPositionReference, children: children });
|
|
70
|
+
}
|
|
71
|
+
function Select({ ref, id, options, placeholder, disabled = false, searchable = false, multiple = false, size: sizeProp, status, appearance = "outlined", label, supportingText, errorText, required, allowClear = false, loading = false, maxTagCount, autoFocus = false, notFoundContent, popupClassName, popupMatchSelectWidth = true, optionRender, tagRender, dropdownRender, value, defaultValue, onValueChange, open, defaultOpen, onOpenChange, onFocus, onBlur, className, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy, "aria-describedby": ariaDescribedBy, ...restProps }) {
|
|
65
72
|
const size = (0, __wake_namespace_1["useComponentSize"])(sizeProp);
|
|
66
|
-
const
|
|
67
|
-
const
|
|
73
|
+
const { messages } = (0, __wake_namespace_1["useLocale"])();
|
|
74
|
+
const listboxId = (0, __wake_namespace_4["useId"])();
|
|
75
|
+
const generatedId = (0, __wake_namespace_4["useId"])();
|
|
68
76
|
const inputId = id ?? generatedId;
|
|
69
77
|
const labelId = `${generatedId}-label`;
|
|
70
78
|
const descriptionId = `${generatedId}-description`;
|
|
71
79
|
const fieldStatus = errorText ? "error" : status;
|
|
72
80
|
const description = errorText || supportingText;
|
|
73
|
-
const [searchText, setSearchText] = (0,
|
|
74
|
-
const [selectedValues, setSelectedValues] = (0,
|
|
75
|
-
const [triggerWidth, setTriggerWidth] = (0,
|
|
76
|
-
const
|
|
77
|
-
onOpenChangeRef.current = onOpenChange;
|
|
81
|
+
const [searchText, setSearchText] = (0, __wake_namespace_4["useState"])("");
|
|
82
|
+
const [selectedValues, setSelectedValues] = (0, __wake_namespace_5["useControllableValue"])({ value: value !== undefined ? asArray(value) : undefined, defaultValue: asArray(defaultValue) });
|
|
83
|
+
const [triggerWidth, setTriggerWidth] = (0, __wake_namespace_4["useState"])(0);
|
|
84
|
+
const controlRef = (0, __wake_namespace_4["useRef"])(null);
|
|
78
85
|
const allPlainOptions = flattenPlainOptions(options);
|
|
79
86
|
const selectedOptions = allPlainOptions.filter((opt) => selectedValues.includes(opt.value));
|
|
80
87
|
const flatOptions = flattenOptions(options);
|
|
81
88
|
const filteredOptions = filterOptions(flatOptions, searchable, searchText);
|
|
82
|
-
const { highlightIndex, highlightedOption, moveHighlight, resetHighlight, setHighlightIndex } = (0,
|
|
83
|
-
const
|
|
89
|
+
const { highlightIndex, highlightedOption, moveHighlight, resetHighlight, setHighlightIndex } = (0, __wake_namespace_6 && __wake_namespace_6.__esModule ? __wake_namespace_6.default : __wake_namespace_6)({ filteredOptions, open: true });
|
|
90
|
+
const syncOpenState = (nextOpen) => {
|
|
84
91
|
if (nextOpen) {
|
|
85
92
|
if (!multiple && selectedValues.length > 0) {
|
|
86
93
|
const selectedIndex = filteredOptions.findIndex((opt) => opt.value === selectedValues[0]);
|
|
@@ -90,49 +97,58 @@ const Select = ({ ref, id, options, placeholder = "请选择", disabled = false,
|
|
|
90
97
|
setSearchText("");
|
|
91
98
|
resetHighlight();
|
|
92
99
|
}
|
|
93
|
-
onOpenChangeRef.current?.(nextOpen);
|
|
94
100
|
};
|
|
95
|
-
const
|
|
101
|
+
const emitOpenChange = (nextOpen, details) => {
|
|
102
|
+
onOpenChange?.(nextOpen, details);
|
|
103
|
+
};
|
|
104
|
+
const openProps = open === undefined ? { defaultOpen } : { open };
|
|
105
|
+
const updateValue = (nextValues, reason, event) => {
|
|
106
|
+
if (disabled) return;
|
|
107
|
+
if (nextValues.length === selectedValues.length && nextValues.every((item, index) => item === selectedValues[index])) return;
|
|
96
108
|
setSelectedValues(nextValues);
|
|
97
109
|
if (multiple) {
|
|
98
110
|
const nextOptions = allPlainOptions.filter((opt) => nextValues.includes(opt.value));
|
|
99
|
-
|
|
111
|
+
onValueChange?.(nextValues, { reason, options: nextOptions, event });
|
|
100
112
|
return;
|
|
101
113
|
}
|
|
102
114
|
const nextValue = nextValues[0] ?? null;
|
|
103
115
|
const nextOption = allPlainOptions.find((opt) => opt.value === nextValue);
|
|
104
|
-
|
|
116
|
+
onValueChange?.(nextValue, { reason, option: nextOption, options: nextOption ? [nextOption] : [], event });
|
|
105
117
|
};
|
|
106
|
-
const handleOptionSelect = (option) => {
|
|
107
|
-
if (option.disabled || option.isGroupLabel) {
|
|
118
|
+
const handleOptionSelect = (option, event) => {
|
|
119
|
+
if (disabled || option.disabled || option.isGroupLabel) {
|
|
108
120
|
return;
|
|
109
121
|
}
|
|
110
122
|
if (multiple) {
|
|
111
123
|
const exists = selectedValues.includes(option.value);
|
|
112
124
|
const nextValues = exists ? selectedValues.filter((v) => v !== option.value) : [...selectedValues, option.value];
|
|
113
|
-
updateValue(nextValues);
|
|
125
|
+
updateValue(nextValues, exists ? "deselect" : "select", event);
|
|
114
126
|
return;
|
|
115
127
|
}
|
|
116
|
-
|
|
128
|
+
controlRef.current?.focus();
|
|
129
|
+
updateValue([option.value], "select", event);
|
|
117
130
|
};
|
|
118
|
-
const handleClear = () => {
|
|
119
|
-
|
|
131
|
+
const handleClear = (event) => {
|
|
132
|
+
if (disabled) return;
|
|
133
|
+
updateValue([], "clear", event);
|
|
120
134
|
setSearchText("");
|
|
121
135
|
};
|
|
122
|
-
const handleRemoveTag = (val) => {
|
|
123
|
-
updateValue(selectedValues.filter((v) => v !== val));
|
|
136
|
+
const handleRemoveTag = (val, event) => {
|
|
137
|
+
updateValue(selectedValues.filter((v) => v !== val), "remove", event);
|
|
124
138
|
};
|
|
125
139
|
const handleTriggerWidthChange = (width) => {
|
|
126
140
|
setTriggerWidth(width);
|
|
127
141
|
};
|
|
128
142
|
const handleSearchTextChange = (text) => {
|
|
143
|
+
if (disabled) return;
|
|
129
144
|
setSearchText(text);
|
|
130
145
|
const nextFiltered = filterOptions(flatOptions, searchable, text);
|
|
131
146
|
setHighlightIndex(firstEnabledIndex(nextFiltered));
|
|
132
147
|
};
|
|
133
148
|
const floatingStyle = popupMatchSelectWidth ? { width: triggerWidth } : { minWidth: triggerWidth };
|
|
134
|
-
return (0, __wake_namespace_0["jsx"])(__wake_namespace_2 && __wake_namespace_2.__esModule ? __wake_namespace_2.default : __wake_namespace_2, { size: size, ...restProps, className: className, overlay: (0, __wake_namespace_0["jsx"])(
|
|
135
|
-
}
|
|
149
|
+
return (0, __wake_namespace_0["jsx"])(__wake_namespace_2 && __wake_namespace_2.__esModule ? __wake_namespace_2.default : __wake_namespace_2, { ...openProps, onOpenChange: emitOpenChange, size: size, ...restProps, className: className, overlay: (0, __wake_namespace_0["jsx"])(__wake_namespace_8 && __wake_namespace_8.__esModule ? __wake_namespace_8.default : __wake_namespace_8, { size: size, multiple: multiple, disabled: disabled, loading: loading, filteredOptions: filteredOptions, selectedValues: selectedValues, triggerWidth: triggerWidth, highlightIndex: highlightIndex, listboxId: listboxId, notFoundContent: notFoundContent, popupClassName: popupClassName, optionRender: optionRender, dropdownRender: dropdownRender, onOptionSelect: handleOptionSelect, onHighlightChange: setHighlightIndex }), floatingContainerProps: { style: floatingStyle }, children: (0, __wake_namespace_0["jsxs"])(SelectField, { children: [(0, __wake_namespace_0["jsx"])(__wake_namespace_7 && __wake_namespace_7.__esModule ? __wake_namespace_7.default : __wake_namespace_7, { ref: ref, controlRef: controlRef, id: inputId, ariaLabel: ariaLabel, ariaLabelledBy: ariaLabelledBy ?? (label ? labelId : undefined), ariaDescribedBy: [ariaDescribedBy, description ? descriptionId : undefined].filter(Boolean).join(" ") || undefined, disabled: disabled, searchable: searchable, multiple: multiple, size: size, status: fieldStatus, appearance: appearance, label: label, labelId: labelId, required: required, allowClear: allowClear, loading: loading, maxTagCount: maxTagCount, autoFocus: autoFocus, placeholder: placeholder ?? messages.select.placeholder, selectedOptions: selectedOptions, searchText: searchText, highlightIndex: highlightIndex, highlightedOption: highlightedOption, listboxId: listboxId, tagRender: tagRender, onSearchTextChange: handleSearchTextChange, onOpenStateChange: syncOpenState, onWidthChange: handleTriggerWidthChange, onMoveHighlight: moveHighlight, onSelectHighlighted: handleOptionSelect, onClear: handleClear, onRemoveTag: handleRemoveTag, onFocus: onFocus, onBlur: onBlur }), description && (0, __wake_namespace_0["jsx"])("div", { id: descriptionId, className: supportingStyle, "data-status": fieldStatus, role: errorText ? "alert" : undefined, children: description })] }) });
|
|
150
|
+
}
|
|
151
|
+
;
|
|
136
152
|
const __wake_default_export = Select;
|
|
137
153
|
Object.defineProperty(exports, "default", { enumerable: true, get: function() {
|
|
138
154
|
return __wake_default_export;
|
|
@@ -6,9 +6,11 @@ const __wake_namespace_3 = require("@crab-dev/rc-button");
|
|
|
6
6
|
const __wake_namespace_4 = require("@crab-dev/rc-spin");
|
|
7
7
|
const __wake_namespace_5 = require("@crab-dev/rc-tag");
|
|
8
8
|
const __wake_namespace_6 = require("@crab-dev/css");
|
|
9
|
-
const __wake_namespace_7 = require("
|
|
9
|
+
const __wake_namespace_7 = require("@crab-dev/rc-config-provider");
|
|
10
|
+
const __wake_namespace_8 = require("react");
|
|
10
11
|
require("./token.cjs");
|
|
11
12
|
;
|
|
13
|
+
const __wake_namespace_9 = require("./selectInput.styles.cjs");
|
|
12
14
|
const setRef = (ref, node) => {
|
|
13
15
|
if (typeof ref === "function") {
|
|
14
16
|
ref(node);
|
|
@@ -16,37 +18,21 @@ const setRef = (ref, node) => {
|
|
|
16
18
|
ref.current = node;
|
|
17
19
|
}
|
|
18
20
|
};
|
|
19
|
-
const
|
|
20
|
-
const
|
|
21
|
-
const
|
|
22
|
-
const controlDisabledStyle = "rc-select-238e884e6a17";
|
|
23
|
-
const controlErrorStyle = "rc-select-e0726e9ad481";
|
|
24
|
-
const controlWarningStyle = "rc-select-79b739b32fcb";
|
|
25
|
-
const valueWrapStyle = "rc-select-1356dfc74a7f";
|
|
26
|
-
const singleValueStyle = "rc-select-52cbc5cc4f0f";
|
|
27
|
-
const placeholderStyle = "rc-select-37ce25dfcd13";
|
|
28
|
-
const searchInputStyle = "rc-select-50dd3c70bcdc";
|
|
29
|
-
const caretStyle = "rc-select-d7edabfe7361";
|
|
30
|
-
const caretOpenStyle = "rc-select-30173f5e3d41";
|
|
31
|
-
const tagLabelStyle = "rc-select-2e4337f305d8";
|
|
32
|
-
const suffixWrapStyle = "rc-select-ee9f2054c459";
|
|
33
|
-
const actionStyle = "rc-select-8504d95b52bc";
|
|
34
|
-
const loadingIconStyle = "rc-select-3ab2c2f8c427";
|
|
35
|
-
const sizeMetricsMap = { large: "rc-select-df4a743b55e1", middle: "rc-select-de4a743b542e", small: "rc-select-dd4a743b527b" };
|
|
36
|
-
const sizeHeightFixedMap = { large: "rc-select-b8fc5925a597", middle: "rc-select-b7fc5925a3e4", small: "rc-select-bafc5925a8fd" };
|
|
37
|
-
const sizeHeightFlexibleMap = { large: "rc-select-5d07f79a2f4a", middle: "rc-select-5e07f79a30fd", small: "rc-select-5b07f79a2be4" };
|
|
21
|
+
const sizeMetricsMap = { large: "rc-select-df4a743b55e1", medium: "rc-select-de4a743b542e", small: "rc-select-dd4a743b527b" };
|
|
22
|
+
const sizeHeightFixedMap = { large: "rc-select-b8fc5925a597", medium: "rc-select-b7fc5925a3e4", small: "rc-select-bafc5925a8fd" };
|
|
23
|
+
const sizeHeightFlexibleMap = { large: "rc-select-5d07f79a2f4a", medium: "rc-select-5e07f79a30fd", small: "rc-select-5b07f79a2be4" };
|
|
38
24
|
const CaretIcon = () => (0, __wake_namespace_0["jsx"])("svg", { "aria-hidden": "true", focusable: "false", viewBox: "0 0 24 24", fill: "currentColor", children: (0, __wake_namespace_0["jsx"])("path", { d: "m7 10 5 5 5-5z" }) });
|
|
39
25
|
const ClearIcon = () => (0, __wake_namespace_0["jsx"])("svg", { "aria-hidden": "true", focusable: "false", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: (0, __wake_namespace_0["jsx"])("path", { d: "m18 6-12 12M6 6l12 12" }) });
|
|
40
26
|
;
|
|
41
|
-
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,
|
|
27
|
+
const SelectInput = ({ ref, controlRef, 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, onOpenStateChange, onWidthChange, onMoveHighlight, onSelectHighlighted, onClear, onRemoveTag, onFocus, onBlur }) => {
|
|
42
28
|
const { state, refs, dispatch } = (0, __wake_namespace_1["useDropdownContext"])();
|
|
43
|
-
const
|
|
44
|
-
const inputRef = (0,
|
|
29
|
+
const { messages } = (0, __wake_namespace_7["useLocale"])();
|
|
30
|
+
const inputRef = (0, __wake_namespace_8["useRef"])(null);
|
|
45
31
|
const open = state.open;
|
|
46
|
-
const [hovered, setHovered] = (0,
|
|
47
|
-
const [actionFocused, setActionFocused] = (0,
|
|
48
|
-
const [withoutHover, setWithoutHover] = (0,
|
|
49
|
-
(0,
|
|
32
|
+
const [hovered, setHovered] = (0, __wake_namespace_8["useState"])(false);
|
|
33
|
+
const [actionFocused, setActionFocused] = (0, __wake_namespace_8["useState"])(false);
|
|
34
|
+
const [withoutHover, setWithoutHover] = (0, __wake_namespace_8["useState"])(false);
|
|
35
|
+
(0, __wake_namespace_8["useEffect"])(() => {
|
|
50
36
|
const media = window.matchMedia?.("(hover: none)");
|
|
51
37
|
if (!media) return;
|
|
52
38
|
const update = () => setWithoutHover(media.matches);
|
|
@@ -54,16 +40,15 @@ const SelectInput = ({ ref, id, ariaLabel, ariaLabelledBy, ariaDescribedBy, disa
|
|
|
54
40
|
media.addEventListener("change", update);
|
|
55
41
|
return () => media.removeEventListener("change", update);
|
|
56
42
|
}, []);
|
|
57
|
-
const
|
|
58
|
-
|
|
59
|
-
const mergeRef = (0, __wake_namespace_7["useCallback"])((node) => {
|
|
43
|
+
const syncOpen = (0, __wake_namespace_8["useEffectEvent"])(onOpenStateChange);
|
|
44
|
+
const mergeRef = (0, __wake_namespace_8["useCallback"])((node) => {
|
|
60
45
|
controlRef.current = node;
|
|
61
46
|
if (typeof refs.setReference === "function") {
|
|
62
47
|
refs.setReference(node);
|
|
63
48
|
}
|
|
64
49
|
setRef(ref, node);
|
|
65
|
-
}, [refs.setReference, ref]);
|
|
66
|
-
(0,
|
|
50
|
+
}, [refs.setReference, ref, controlRef]);
|
|
51
|
+
(0, __wake_namespace_8["useEffect"])(() => {
|
|
67
52
|
const el = controlRef.current;
|
|
68
53
|
if (!el) {
|
|
69
54
|
return;
|
|
@@ -76,23 +61,18 @@ const SelectInput = ({ ref, id, ariaLabel, ariaLabelledBy, ariaDescribedBy, disa
|
|
|
76
61
|
observer.observe(el);
|
|
77
62
|
return () => observer.disconnect();
|
|
78
63
|
}, [onWidthChange]);
|
|
79
|
-
(0,
|
|
80
|
-
if (open && searchable) {
|
|
64
|
+
(0, __wake_namespace_8["useEffect"])(() => {
|
|
65
|
+
if (open && searchable && !disabled) {
|
|
81
66
|
queueMicrotask(() => inputRef.current?.focus());
|
|
82
67
|
}
|
|
83
|
-
}, [open, searchable]);
|
|
84
|
-
(0,
|
|
85
|
-
if (autoFocus && controlRef.current) {
|
|
68
|
+
}, [disabled, open, searchable]);
|
|
69
|
+
(0, __wake_namespace_8["useEffect"])(() => {
|
|
70
|
+
if (autoFocus && !disabled && controlRef.current) {
|
|
86
71
|
controlRef.current.focus();
|
|
87
72
|
}
|
|
88
|
-
}, [autoFocus]);
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
if (isFirstOpenRender.current) {
|
|
92
|
-
isFirstOpenRender.current = false;
|
|
93
|
-
return;
|
|
94
|
-
}
|
|
95
|
-
onOpenChangeRef.current(open);
|
|
73
|
+
}, [autoFocus, disabled]);
|
|
74
|
+
(0, __wake_namespace_8["useEffect"])(() => {
|
|
75
|
+
syncOpen(open);
|
|
96
76
|
}, [open]);
|
|
97
77
|
const handleClick = () => {
|
|
98
78
|
if (disabled) {
|
|
@@ -122,7 +102,7 @@ const SelectInput = ({ ref, id, ariaLabel, ariaLabelledBy, ariaDescribedBy, disa
|
|
|
122
102
|
case "Enter":
|
|
123
103
|
e.preventDefault();
|
|
124
104
|
if (open && highlightedOption) {
|
|
125
|
-
onSelectHighlighted(highlightedOption);
|
|
105
|
+
onSelectHighlighted(highlightedOption, e);
|
|
126
106
|
if (!multiple) {
|
|
127
107
|
dispatch({ type: "setOpen", payload: false });
|
|
128
108
|
}
|
|
@@ -141,29 +121,30 @@ const SelectInput = ({ ref, id, ariaLabel, ariaLabelledBy, ariaDescribedBy, disa
|
|
|
141
121
|
case "Escape":
|
|
142
122
|
if (open) {
|
|
143
123
|
e.preventDefault();
|
|
144
|
-
|
|
124
|
+
controlRef.current?.focus();
|
|
125
|
+
dispatch({ type: "setOpen", payload: false, details: { reason: "escape", event: e.nativeEvent } });
|
|
145
126
|
}
|
|
146
127
|
break;
|
|
147
128
|
case "Backspace":
|
|
148
129
|
if (multiple && searchText === "" && selectedOptions.length > 0) {
|
|
149
130
|
const lastOption = selectedOptions[selectedOptions.length - 1];
|
|
150
|
-
onRemoveTag(lastOption.value);
|
|
131
|
+
onRemoveTag(lastOption.value, e);
|
|
151
132
|
}
|
|
152
133
|
break;
|
|
153
134
|
default:
|
|
154
135
|
break;
|
|
155
136
|
}
|
|
156
137
|
};
|
|
157
|
-
const triggerClear = () => {
|
|
138
|
+
const triggerClear = (event) => {
|
|
158
139
|
controlRef.current?.focus();
|
|
159
|
-
onClear();
|
|
140
|
+
onClear(event);
|
|
160
141
|
if (open) {
|
|
161
142
|
dispatch({ type: "setOpen", payload: false });
|
|
162
143
|
}
|
|
163
144
|
};
|
|
164
145
|
const handleClearClick = (e) => {
|
|
165
146
|
e.stopPropagation();
|
|
166
|
-
triggerClear();
|
|
147
|
+
triggerClear(e);
|
|
167
148
|
};
|
|
168
149
|
const handleClearKeyDown = (e) => {
|
|
169
150
|
if (e.key === "Enter" || e.key === " ") {
|
|
@@ -173,11 +154,13 @@ const SelectInput = ({ ref, id, ariaLabel, ariaLabelledBy, ariaDescribedBy, disa
|
|
|
173
154
|
const canClear = allowClear && !disabled && selectedOptions.length > 0;
|
|
174
155
|
const showClear = canClear && (hovered || actionFocused || withoutHover);
|
|
175
156
|
const renderTag = (opt) => {
|
|
176
|
-
const handleClose = () =>
|
|
157
|
+
const handleClose = (event) => {
|
|
158
|
+
if (!disabled) onRemoveTag(opt.value, event);
|
|
159
|
+
};
|
|
177
160
|
if (tagRender) {
|
|
178
161
|
return (0, __wake_namespace_0["jsx"])("span", { children: tagRender(opt, handleClose) }, opt.value);
|
|
179
162
|
}
|
|
180
|
-
return (0, __wake_namespace_0["jsx"])(__wake_namespace_5 && __wake_namespace_5.__esModule ? __wake_namespace_5.default : __wake_namespace_5, { size: "small", closable:
|
|
163
|
+
return (0, __wake_namespace_0["jsx"])(__wake_namespace_5 && __wake_namespace_5.__esModule ? __wake_namespace_5.default : __wake_namespace_5, { size: "small", closable: !disabled, closeAriaLabel: messages.select.removeTag(typeof opt.label === "string" ? opt.label : opt.value), onClose: handleClose, children: (0, __wake_namespace_0["jsx"])("span", { className: __wake_namespace_9["tagLabelStyle"], children: opt.label }) }, opt.value);
|
|
181
164
|
};
|
|
182
165
|
const renderTags = () => {
|
|
183
166
|
if (maxTagCount !== undefined && selectedOptions.length > maxTagCount) {
|
|
@@ -189,32 +172,32 @@ const SelectInput = ({ ref, id, ariaLabel, ariaLabelledBy, ariaDescribedBy, disa
|
|
|
189
172
|
};
|
|
190
173
|
const renderContent = () => {
|
|
191
174
|
if (searchable && open) {
|
|
192
|
-
return (0, __wake_namespace_0["jsxs"])(__wake_namespace_0["Fragment"], { children: [multiple && renderTags(), (0, __wake_namespace_0["jsx"])(__wake_namespace_2 && __wake_namespace_2.__esModule ? __wake_namespace_2.default : __wake_namespace_2, { ref: inputRef, bordered: false, value: searchText, placeholder: multiple && selectedOptions.length > 0 ? "" : placeholder, onChange: (e) => onSearchTextChange(e.target.value), onClick: (e) => e.stopPropagation(), className: searchInputStyle })] });
|
|
175
|
+
return (0, __wake_namespace_0["jsxs"])(__wake_namespace_0["Fragment"], { children: [multiple && renderTags(), (0, __wake_namespace_0["jsx"])(__wake_namespace_2 && __wake_namespace_2.__esModule ? __wake_namespace_2.default : __wake_namespace_2, { ref: inputRef, "aria-label": ariaLabel ?? label ?? placeholder, bordered: false, disabled: disabled, value: searchText, placeholder: multiple && selectedOptions.length > 0 ? "" : placeholder, onChange: (e) => onSearchTextChange(e.target.value), onClick: (e) => e.stopPropagation(), className: __wake_namespace_9["searchInputStyle"] })] });
|
|
193
176
|
}
|
|
194
177
|
if (multiple) {
|
|
195
178
|
if (selectedOptions.length === 0) {
|
|
196
|
-
return (0, __wake_namespace_0["jsx"])("span", { className: placeholderStyle, children: placeholder });
|
|
179
|
+
return (0, __wake_namespace_0["jsx"])("span", { "data-role": "select-placeholder", className: __wake_namespace_9["placeholderStyle"], children: placeholder });
|
|
197
180
|
}
|
|
198
181
|
return renderTags();
|
|
199
182
|
}
|
|
200
183
|
if (selectedOptions.length === 0) {
|
|
201
|
-
return (0, __wake_namespace_0["jsx"])("span", { className: placeholderStyle, children: placeholder });
|
|
184
|
+
return (0, __wake_namespace_0["jsx"])("span", { "data-role": "select-placeholder", className: __wake_namespace_9["placeholderStyle"], children: placeholder });
|
|
202
185
|
}
|
|
203
|
-
return (0, __wake_namespace_0["jsx"])("span", { className: singleValueStyle, children: selectedOptions[0]?.label });
|
|
186
|
+
return (0, __wake_namespace_0["jsx"])("span", { className: __wake_namespace_9["singleValueStyle"], children: selectedOptions[0]?.label });
|
|
204
187
|
};
|
|
205
188
|
const activeDescendantId = open && highlightIndex >= 0 ? `${listboxId}-option-${highlightIndex}` : undefined;
|
|
206
|
-
return (0, __wake_namespace_0["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: __wake_namespace_6["cx"].call(undefined, controlStyle, sizeMetricsMap[size], multiple ? sizeHeightFlexibleMap[size] : sizeHeightFixedMap[size], disabled && controlDisabledStyle, status === "error" && controlErrorStyle, status === "warning" && controlWarningStyle,
|
|
189
|
+
return (0, __wake_namespace_0["jsxs"])("div", { className: __wake_namespace_9["fieldLayoutStyle"], "data-labeled": Boolean(label), "data-appearance": appearance, "data-floating": Boolean(open || selectedOptions.length > 0 || searchText), "data-open": open, "data-status": status, "data-disabled": disabled || undefined, children: [label && (0, __wake_namespace_0["jsxs"])("span", { "data-role": "select-label", children: [(0, __wake_namespace_0["jsx"])("span", { id: labelId, children: label }), required && (0, __wake_namespace_0["jsx"])("span", { "data-required-marker": "", "aria-hidden": "true", children: "*" })] }), (0, __wake_namespace_0["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: __wake_namespace_6["cx"].call(undefined, __wake_namespace_9["controlStyle"], sizeMetricsMap[size], multiple ? sizeHeightFlexibleMap[size] : sizeHeightFixedMap[size], disabled && __wake_namespace_9["controlDisabledStyle"], status === "error" && __wake_namespace_9["controlErrorStyle"], status === "warning" && __wake_namespace_9["controlWarningStyle"], __wake_namespace_9["fieldControlStyle"]), onClick: handleClick, onKeyDown: handleKeyDown, onFocus: onFocus, onBlur: onBlur, onPointerOver: (event) => {
|
|
207
190
|
if (event.pointerType !== "touch") setHovered(true);
|
|
208
191
|
}, onPointerOut: (event) => {
|
|
209
192
|
if (!(event.relatedTarget instanceof Node) || !event.currentTarget.contains(event.relatedTarget)) {
|
|
210
193
|
setHovered(false);
|
|
211
194
|
}
|
|
212
|
-
}, children: [label && (0, __wake_namespace_0["
|
|
195
|
+
}, children: [label && appearance === "outlined" && (0, __wake_namespace_0["jsx"])("fieldset", { "aria-hidden": "true", children: (0, __wake_namespace_0["jsxs"])("legend", { children: [label, required ? " *" : ""] }) }), (0, __wake_namespace_0["jsx"])("div", { "data-role": "select-value", className: __wake_namespace_9["valueWrapStyle"], children: renderContent() }), (0, __wake_namespace_0["jsxs"])("span", { "data-role": "select-suffix", className: __wake_namespace_9["suffixWrapStyle"], children: [loading ? (0, __wake_namespace_0["jsx"])("span", { "aria-hidden": "true", className: __wake_namespace_9["loadingIconStyle"], children: (0, __wake_namespace_0["jsx"])(__wake_namespace_4["SpinIndicator"], {}) }) : null, (0, __wake_namespace_0["jsx"])(__wake_namespace_3 && __wake_namespace_3.__esModule ? __wake_namespace_3.default : __wake_namespace_3, { "data-role": showClear ? "select-clear" : "select-caret", className: __wake_namespace_9["actionStyle"], type: "button", appearance: "text", shape: "circle", size: size === "small" ? "xs" : size === "large" ? "m" : "s", disabled: disabled, "aria-label": showClear ? messages.common.clear : open ? messages.select.closeOptions : messages.select.openOptions, "aria-expanded": showClear ? undefined : open, icon: showClear ? (0, __wake_namespace_0["jsx"])(ClearIcon, {}) : (0, __wake_namespace_0["jsx"])("span", { "aria-hidden": "true", className: __wake_namespace_6["cx"].call(undefined, __wake_namespace_9["caretStyle"], open && __wake_namespace_9["caretOpenStyle"]), children: (0, __wake_namespace_0["jsx"])(CaretIcon, {}) }), onFocus: () => setActionFocused(true), onBlur: () => setActionFocused(false), onClick: (event) => {
|
|
213
196
|
if (showClear) handleClearClick(event); else {
|
|
214
197
|
event.stopPropagation();
|
|
215
198
|
handleClick();
|
|
216
199
|
}
|
|
217
|
-
}, onKeyDown: handleClearKeyDown })] })] });
|
|
200
|
+
}, onKeyDown: handleClearKeyDown })] })] })] });
|
|
218
201
|
};
|
|
219
202
|
const __wake_default_export = SelectInput;
|
|
220
203
|
Object.defineProperty(exports, "default", { enumerable: true, get: function() {
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
2
|
+
require("@crab-dev/rc-button");
|
|
3
|
+
require("@crab-dev/rc-spin");
|
|
4
|
+
require("@crab-dev/rc-token-semantic");
|
|
5
|
+
require("./token.cjs");
|
|
6
|
+
const controlStyle = "rc-select-5e896678dc89";
|
|
7
|
+
Object.defineProperty(exports, "controlStyle", { enumerable: true, get: function() {
|
|
8
|
+
return controlStyle;
|
|
9
|
+
} });
|
|
10
|
+
const fieldControlStyle = "rc-select-29edc097b42b";
|
|
11
|
+
Object.defineProperty(exports, "fieldControlStyle", { enumerable: true, get: function() {
|
|
12
|
+
return fieldControlStyle;
|
|
13
|
+
} });
|
|
14
|
+
const fieldLayoutStyle = "rc-select-910e459fbbe0";
|
|
15
|
+
Object.defineProperty(exports, "fieldLayoutStyle", { enumerable: true, get: function() {
|
|
16
|
+
return fieldLayoutStyle;
|
|
17
|
+
} });
|
|
18
|
+
const controlDisabledStyle = "rc-select-82fbf3807561";
|
|
19
|
+
Object.defineProperty(exports, "controlDisabledStyle", { enumerable: true, get: function() {
|
|
20
|
+
return controlDisabledStyle;
|
|
21
|
+
} });
|
|
22
|
+
const controlErrorStyle = "rc-select-6d2a034155e7";
|
|
23
|
+
Object.defineProperty(exports, "controlErrorStyle", { enumerable: true, get: function() {
|
|
24
|
+
return controlErrorStyle;
|
|
25
|
+
} });
|
|
26
|
+
const controlWarningStyle = "rc-select-36466465840d";
|
|
27
|
+
Object.defineProperty(exports, "controlWarningStyle", { enumerable: true, get: function() {
|
|
28
|
+
return controlWarningStyle;
|
|
29
|
+
} });
|
|
30
|
+
const valueWrapStyle = "rc-select-f0b8a9c0c369";
|
|
31
|
+
Object.defineProperty(exports, "valueWrapStyle", { enumerable: true, get: function() {
|
|
32
|
+
return valueWrapStyle;
|
|
33
|
+
} });
|
|
34
|
+
const singleValueStyle = "rc-select-bcd33343d38d";
|
|
35
|
+
Object.defineProperty(exports, "singleValueStyle", { enumerable: true, get: function() {
|
|
36
|
+
return singleValueStyle;
|
|
37
|
+
} });
|
|
38
|
+
const placeholderStyle = "rc-select-30719d992205";
|
|
39
|
+
Object.defineProperty(exports, "placeholderStyle", { enumerable: true, get: function() {
|
|
40
|
+
return placeholderStyle;
|
|
41
|
+
} });
|
|
42
|
+
const searchInputStyle = "rc-select-c91210473c12";
|
|
43
|
+
Object.defineProperty(exports, "searchInputStyle", { enumerable: true, get: function() {
|
|
44
|
+
return searchInputStyle;
|
|
45
|
+
} });
|
|
46
|
+
const caretStyle = "rc-select-8ca15a371517";
|
|
47
|
+
Object.defineProperty(exports, "caretStyle", { enumerable: true, get: function() {
|
|
48
|
+
return caretStyle;
|
|
49
|
+
} });
|
|
50
|
+
const caretOpenStyle = "rc-select-72a72768a0ef";
|
|
51
|
+
Object.defineProperty(exports, "caretOpenStyle", { enumerable: true, get: function() {
|
|
52
|
+
return caretOpenStyle;
|
|
53
|
+
} });
|
|
54
|
+
const tagLabelStyle = "rc-select-113a9493f812";
|
|
55
|
+
Object.defineProperty(exports, "tagLabelStyle", { enumerable: true, get: function() {
|
|
56
|
+
return tagLabelStyle;
|
|
57
|
+
} });
|
|
58
|
+
const suffixWrapStyle = "rc-select-5032f5885db7";
|
|
59
|
+
Object.defineProperty(exports, "suffixWrapStyle", { enumerable: true, get: function() {
|
|
60
|
+
return suffixWrapStyle;
|
|
61
|
+
} });
|
|
62
|
+
const actionStyle = "rc-select-aa51540f6a1a";
|
|
63
|
+
Object.defineProperty(exports, "actionStyle", { enumerable: true, get: function() {
|
|
64
|
+
return actionStyle;
|
|
65
|
+
} });
|
|
66
|
+
const loadingIconStyle = "rc-select-14f1c2e4ccd5";
|
|
67
|
+
Object.defineProperty(exports, "loadingIconStyle", { enumerable: true, get: function() {
|
|
68
|
+
return loadingIconStyle;
|
|
69
|
+
} });
|