@rescui/select 0.15.1-RUI-280-Update-select-component-separate-components-e772abaa1.56 → 0.15.1-RUI-280-Update-select-component-downshift-cd2a98813.66
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/lib/_virtual/index.css.js +12 -12
- package/lib/constants.d.ts +0 -1
- package/lib/constants.js +1 -2
- package/lib/hooks/use-a11y.d.ts +29 -0
- package/lib/hooks/use-a11y.js +53 -0
- package/lib/hooks/use-backward-compatible-id.d.ts +4 -0
- package/lib/hooks/use-backward-compatible-id.js +14 -0
- package/lib/hooks/use-label-focus.d.ts +1 -3
- package/lib/hooks/use-label-focus.js +3 -9
- package/lib/hooks/use-multi-handlers.d.ts +11 -0
- package/lib/hooks/use-multi-handlers.js +48 -0
- package/lib/hooks/use-options.d.ts +13 -0
- package/lib/hooks/use-options.js +89 -0
- package/lib/index.css +323 -371
- package/lib/multiselect.d.ts +3 -29
- package/lib/multiselect.js +249 -174
- package/lib/native-select.js +67 -46
- package/lib/parts/hidden-select.d.ts +13 -0
- package/lib/parts/hidden-select.js +45 -0
- package/lib/parts/icons.d.ts +3 -1
- package/lib/parts/icons.js +11 -14
- package/lib/parts/list-box.d.ts +7 -15
- package/lib/parts/list-box.js +50 -82
- package/lib/parts/multi-trigger.d.ts +5 -4
- package/lib/parts/multi-trigger.js +27 -15
- package/lib/parts/native-select-trigger.d.ts +6 -8
- package/lib/parts/native-select-trigger.js +14 -23
- package/lib/select-basic.d.ts +2 -2
- package/lib/select-basic.js +161 -97
- package/lib/select-searchable.d.ts +2 -2
- package/lib/select-searchable.js +208 -122
- package/lib/select.d.ts +1 -1
- package/lib/select.js +38 -31
- package/lib/styles/common.p.module.css.js +25 -24
- package/lib/styles/form-trigger.p.module.css.js +12 -12
- package/lib/styles/list-box.p.module.css.js +11 -13
- package/lib/styles/native-select-trigger.p.module.css.js +15 -14
- package/lib/styles/native-select.p.module.css.js +6 -6
- package/lib/types.d.ts +26 -27
- package/lib/utils/get-real-items-cnt.d.ts +2 -2
- package/lib/utils/get-real-items-cnt.js +8 -10
- package/lib/utils/item-to-string.d.ts +2 -0
- package/lib/utils/item-to-string.js +7 -0
- package/lib/utils/merge-props.d.ts +29 -0
- package/lib/utils/merge-props.js +106 -0
- package/package.json +13 -22
- package/lib/hooks/use-css-context-transfer.d.ts +0 -14
- package/lib/hooks/use-css-context-transfer.js +0 -40
- package/lib/hooks/use-multi-option-serialization.d.ts +0 -10
- package/lib/hooks/use-multi-option-serialization.js +0 -82
- package/lib/hooks/use-observable-force-rerender.d.ts +0 -2
- package/lib/hooks/use-observable-force-rerender.js +0 -16
- package/lib/hooks/use-option-serialization.d.ts +0 -10
- package/lib/hooks/use-option-serialization.js +0 -59
- package/lib/parts/popover.d.ts +0 -12
- package/lib/parts/popover.js +0 -64
- package/lib/parts/popup-content.d.ts +0 -19
- package/lib/parts/popup-content.js +0 -76
- package/lib/styles/popover.p.module.css.js +0 -10
- package/lib/utils/convert-options.d.ts +0 -3
- package/lib/utils/convert-options.js +0 -52
- package/lib/utils/convert-placement.d.ts +0 -3
- package/lib/utils/convert-placement.js +0 -22
- package/lib/utils/css-vars-utils.d.ts +0 -3
- package/lib/utils/css-vars-utils.js +0 -20
package/lib/native-select.js
CHANGED
|
@@ -1,19 +1,18 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import React
|
|
2
|
+
import React from 'react';
|
|
3
3
|
import PropTypes from 'prop-types';
|
|
4
4
|
import cn from 'classnames';
|
|
5
5
|
import { useThemeWithUndefined } from '@rescui/ui-contexts';
|
|
6
6
|
import { ErrorMessage } from '@rescui/form-field';
|
|
7
|
-
import {
|
|
8
|
-
import { useFocusRing } from '@react-aria/focus';
|
|
9
|
-
import { mergeProps } from '@react-aria/utils';
|
|
7
|
+
import { useFocus, useHover } from 'react-aria';
|
|
10
8
|
import { nativeOptionType, nativeOptionsGroupType, noOptionsMessageType } from './common-prop-types.js';
|
|
9
|
+
import { useA11y } from './hooks/use-a11y.js';
|
|
11
10
|
import { FormTriggerWrapper } from './parts/form-trigger-wrapper.js';
|
|
12
|
-
import { isOptionAGroup } from './utils/is-option-a-group.js';
|
|
13
|
-
import { getEmptyMessage } from './utils/get-empty-message.js';
|
|
14
|
-
import { useLabelFocus } from './hooks/use-label-focus.js';
|
|
15
11
|
import { NativeSelectTrigger } from './parts/native-select-trigger.js';
|
|
16
12
|
import { NativeSelectOptionsWithGroups } from './parts/native-select-options-with-groups.js';
|
|
13
|
+
import { isOptionAGroup } from './utils/is-option-a-group.js';
|
|
14
|
+
import { getEmptyMessage } from './utils/get-empty-message.js';
|
|
15
|
+
import { mergeProps } from './utils/merge-props.js';
|
|
17
16
|
import styles from './styles/native-select.p.module.css.js';
|
|
18
17
|
|
|
19
18
|
function findSelectedOption(options, selectedValue) {
|
|
@@ -57,6 +56,7 @@ const NativeSelect = _ref => {
|
|
|
57
56
|
placeholder,
|
|
58
57
|
isLoading = false,
|
|
59
58
|
isDisabled = false,
|
|
59
|
+
isClearable = false,
|
|
60
60
|
trigger,
|
|
61
61
|
label,
|
|
62
62
|
note,
|
|
@@ -65,20 +65,25 @@ const NativeSelect = _ref => {
|
|
|
65
65
|
noOptionsMessage,
|
|
66
66
|
name,
|
|
67
67
|
boldLabel = true,
|
|
68
|
-
...
|
|
68
|
+
...rest
|
|
69
69
|
} = _ref;
|
|
70
|
+
const triggerRef = React.useRef(null);
|
|
70
71
|
const {
|
|
71
72
|
labelProps,
|
|
72
73
|
fieldProps,
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
} =
|
|
76
|
-
|
|
74
|
+
errorMessageProps,
|
|
75
|
+
descriptionProps
|
|
76
|
+
} = useA11y({
|
|
77
|
+
prefix: 'native-select',
|
|
78
|
+
error,
|
|
77
79
|
description: note,
|
|
78
|
-
|
|
80
|
+
label,
|
|
81
|
+
fieldRef: triggerRef
|
|
79
82
|
});
|
|
83
|
+
|
|
84
|
+
const reset = () => onChange(null);
|
|
85
|
+
|
|
80
86
|
const theme = useThemeWithUndefined(themeFromProps);
|
|
81
|
-
const [isHovered, setIsHovered] = useState(false);
|
|
82
87
|
|
|
83
88
|
const handleChange = event => {
|
|
84
89
|
const newValue = event.target.value;
|
|
@@ -87,21 +92,24 @@ const NativeSelect = _ref => {
|
|
|
87
92
|
if (onChange) {
|
|
88
93
|
onChange(selectedOption);
|
|
89
94
|
}
|
|
90
|
-
};
|
|
95
|
+
}; // delete it when triggerFunc is migrated to the css-states instead of js-props for hover/focus
|
|
96
|
+
// replace it with ":focus + &" selector in that case
|
|
91
97
|
|
|
92
|
-
|
|
98
|
+
|
|
99
|
+
const [isFocused, setIsFocused] = React.useState(false);
|
|
93
100
|
const {
|
|
94
|
-
isFocusVisible,
|
|
95
101
|
focusProps
|
|
96
|
-
} =
|
|
97
|
-
|
|
98
|
-
|
|
102
|
+
} = useFocus({
|
|
103
|
+
isDisabled,
|
|
104
|
+
onFocusChange: setIsFocused
|
|
105
|
+
}); // same as above, could be replaced with ":hover + &" selector
|
|
106
|
+
|
|
99
107
|
const {
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
108
|
+
isHovered,
|
|
109
|
+
hoverProps
|
|
110
|
+
} = useHover({
|
|
111
|
+
isDisabled
|
|
112
|
+
});
|
|
105
113
|
const emptyListMessage = getEmptyMessage({
|
|
106
114
|
isLoading,
|
|
107
115
|
isNothingFound: false,
|
|
@@ -117,7 +125,7 @@ const NativeSelect = _ref => {
|
|
|
117
125
|
size: size,
|
|
118
126
|
disabled: isDisabled,
|
|
119
127
|
label: label,
|
|
120
|
-
labelProps: mergeProps(
|
|
128
|
+
labelProps: mergeProps(labelProps),
|
|
121
129
|
boldLabel: boldLabel,
|
|
122
130
|
error: error,
|
|
123
131
|
errorMessageProps: errorMessageProps,
|
|
@@ -126,25 +134,14 @@ const NativeSelect = _ref => {
|
|
|
126
134
|
descriptionProps: descriptionProps
|
|
127
135
|
}, /*#__PURE__*/React.createElement("div", {
|
|
128
136
|
className: styles.wrapper
|
|
129
|
-
},
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
isLoading: isLoading,
|
|
138
|
-
isFocused: isFocused,
|
|
139
|
-
isHovered: isHovered,
|
|
140
|
-
isDisabled: isDisabled,
|
|
141
|
-
size: size,
|
|
142
|
-
theme: theme,
|
|
143
|
-
hasError: Boolean(error),
|
|
144
|
-
placeholder: placeholder
|
|
145
|
-
}), /*#__PURE__*/React.createElement("select", { ...mergeProps(fieldProps, focusProps, labelFocusForTriggerProps, {
|
|
146
|
-
onMouseEnter: () => setIsHovered(true),
|
|
147
|
-
onMouseLeave: () => setIsHovered(false)
|
|
137
|
+
}, /*#__PURE__*/React.createElement("select", { ...rest,
|
|
138
|
+
...mergeProps(fieldProps, focusProps, hoverProps, {
|
|
139
|
+
onKeyDown: event => {
|
|
140
|
+
// backspace and backspace removing the last selected item (when popup is closed)
|
|
141
|
+
if (isClearable && (event.key === 'Backspace' || event.key === 'Delete')) {
|
|
142
|
+
reset();
|
|
143
|
+
}
|
|
144
|
+
}
|
|
148
145
|
}),
|
|
149
146
|
ref: triggerRef,
|
|
150
147
|
"data-test": "native-select_select",
|
|
@@ -158,7 +155,31 @@ const NativeSelect = _ref => {
|
|
|
158
155
|
optionsWithGroups: options,
|
|
159
156
|
placeholder: placeholder,
|
|
160
157
|
emptyListMessage: emptyListMessage
|
|
161
|
-
}))
|
|
158
|
+
})), trigger ? trigger({
|
|
159
|
+
focused: isFocused,
|
|
160
|
+
hovered: isHovered,
|
|
161
|
+
selectedLabel: value === null || value === void 0 ? void 0 : value.label,
|
|
162
|
+
selectedValue: value === null || value === void 0 ? void 0 : value.value,
|
|
163
|
+
placeholder
|
|
164
|
+
}) : /*#__PURE__*/React.createElement(NativeSelectTrigger, {
|
|
165
|
+
value: value,
|
|
166
|
+
isLoading: isLoading,
|
|
167
|
+
isDisabled: isDisabled,
|
|
168
|
+
isClearable: isClearable,
|
|
169
|
+
triggerId: fieldProps.id,
|
|
170
|
+
onClear: () => {
|
|
171
|
+
var _triggerRef$current;
|
|
172
|
+
|
|
173
|
+
reset();
|
|
174
|
+
(_triggerRef$current = triggerRef.current) === null || _triggerRef$current === void 0 || _triggerRef$current.focus({
|
|
175
|
+
focusVisible: false
|
|
176
|
+
});
|
|
177
|
+
},
|
|
178
|
+
size: size,
|
|
179
|
+
theme: theme,
|
|
180
|
+
hasError: Boolean(error),
|
|
181
|
+
placeholder: placeholder
|
|
182
|
+
}))));
|
|
162
183
|
};
|
|
163
184
|
|
|
164
185
|
NativeSelect.propTypes = {
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
import type { SelectOption } from '../types';
|
|
3
|
+
export declare type HiddenSelectProps = {
|
|
4
|
+
name?: string;
|
|
5
|
+
options: SelectOption[];
|
|
6
|
+
} & ({
|
|
7
|
+
value: SelectOption[];
|
|
8
|
+
isMultiple: true;
|
|
9
|
+
} | {
|
|
10
|
+
value: SelectOption;
|
|
11
|
+
isMultiple: false;
|
|
12
|
+
});
|
|
13
|
+
export declare const HiddenSelect: ({ name, options, value, isMultiple }: HiddenSelectProps) => JSX.Element;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import styles from '../styles/common.p.module.css.js';
|
|
3
|
+
|
|
4
|
+
const HiddenSelect = _ref => {
|
|
5
|
+
let {
|
|
6
|
+
name,
|
|
7
|
+
options,
|
|
8
|
+
value,
|
|
9
|
+
isMultiple
|
|
10
|
+
} = _ref;
|
|
11
|
+
const selectProps = {
|
|
12
|
+
name,
|
|
13
|
+
'aria-hidden': true,
|
|
14
|
+
readOnly: true,
|
|
15
|
+
tabIndex: -1
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
if (isMultiple) {
|
|
19
|
+
selectProps.multiple = true;
|
|
20
|
+
|
|
21
|
+
if (value && value.length !== 0) {
|
|
22
|
+
selectProps.value = value.map(v => String(v.value));
|
|
23
|
+
}
|
|
24
|
+
} else if (value) {
|
|
25
|
+
const singleValue = value;
|
|
26
|
+
selectProps.value = singleValue.value;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const arrayValue = isMultiple ? value : [value]; // merge options with value in case the provided value is not included in options
|
|
30
|
+
|
|
31
|
+
const allItems = Array.from( // map will deduplicate options by values
|
|
32
|
+
new Map((!value ? options : [...options, ...arrayValue]).map(item => [item.value, item])).values());
|
|
33
|
+
return /*#__PURE__*/React.createElement("div", {
|
|
34
|
+
className: styles.hiddenSelect
|
|
35
|
+
}, /*#__PURE__*/React.createElement("select", { ...selectProps
|
|
36
|
+
}, /*#__PURE__*/React.createElement("option", {
|
|
37
|
+
value: "",
|
|
38
|
+
label: '\u00A0'
|
|
39
|
+
}, '\u00A0'), allItems.map(option => /*#__PURE__*/React.createElement("option", {
|
|
40
|
+
key: option.value,
|
|
41
|
+
value: option.value
|
|
42
|
+
}, option.label))));
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
export { HiddenSelect };
|
package/lib/parts/icons.d.ts
CHANGED
|
@@ -5,6 +5,7 @@ declare type ClearOrLoadingProps = {
|
|
|
5
5
|
onClearClick: () => void;
|
|
6
6
|
triggerId?: string;
|
|
7
7
|
className?: string;
|
|
8
|
+
customStylesMap?: Record<string, string>;
|
|
8
9
|
};
|
|
9
10
|
export declare const ClearOrLoading: React.FC<ClearOrLoadingProps>;
|
|
10
11
|
export declare type IconsProps = {
|
|
@@ -12,6 +13,7 @@ export declare type IconsProps = {
|
|
|
12
13
|
canHaveClearIcon?: boolean;
|
|
13
14
|
onClear?: () => void;
|
|
14
15
|
triggerId?: string;
|
|
16
|
+
customStylesMap?: Record<string, string>;
|
|
15
17
|
};
|
|
16
|
-
export declare const Icons: ({ isLoading, canHaveClearIcon, onClear, triggerId }: IconsProps) => JSX.Element;
|
|
18
|
+
export declare const Icons: ({ isLoading, canHaveClearIcon, onClear, triggerId, customStylesMap: styles }: IconsProps) => JSX.Element;
|
|
17
19
|
export {};
|
package/lib/parts/icons.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import cn from 'classnames';
|
|
3
|
-
import { useFocusRing } from '@react-aria/focus';
|
|
4
3
|
import CloseOutlineIcon from '../_virtual/close-outline.js';
|
|
5
4
|
import LoadingOutlineIcon from '../_virtual/loading-outline.js';
|
|
6
5
|
import DownOutlineIcon from '../_virtual/down-outline.js';
|
|
@@ -12,26 +11,23 @@ const ClearOrLoading = _ref => {
|
|
|
12
11
|
canHaveClearIcon,
|
|
13
12
|
onClearClick,
|
|
14
13
|
triggerId,
|
|
15
|
-
className
|
|
14
|
+
className,
|
|
15
|
+
customStylesMap: styles$1 = styles
|
|
16
16
|
} = _ref;
|
|
17
|
-
const {
|
|
18
|
-
isFocusVisible,
|
|
19
|
-
focusProps
|
|
20
|
-
} = useFocusRing();
|
|
21
17
|
|
|
22
18
|
if (isLoading) {
|
|
23
19
|
return /*#__PURE__*/React.createElement(LoadingOutlineIcon, {
|
|
24
20
|
style: {
|
|
25
21
|
pointerEvents: 'none'
|
|
26
22
|
},
|
|
27
|
-
className: cn(className, styles.icon),
|
|
23
|
+
className: cn(className, styles$1.icon),
|
|
28
24
|
"data-test": "loading-icon",
|
|
29
25
|
"data-render-all-sizes": true
|
|
30
26
|
});
|
|
31
27
|
} else if (canHaveClearIcon) {
|
|
32
28
|
return /*#__PURE__*/React.createElement("button", {
|
|
33
29
|
type: "button",
|
|
34
|
-
className: cn(className, styles.icon, styles.clearIcon
|
|
30
|
+
className: cn(className, styles$1.icon, styles$1.clearIcon),
|
|
35
31
|
"data-test": "clear-icon",
|
|
36
32
|
onClick: e => {
|
|
37
33
|
e.stopPropagation();
|
|
@@ -41,8 +37,7 @@ const ClearOrLoading = _ref => {
|
|
|
41
37
|
onMouseDown: e => e.stopPropagation(),
|
|
42
38
|
onKeyDown: e => e.stopPropagation(),
|
|
43
39
|
"aria-label": "Clear",
|
|
44
|
-
"aria-controls": triggerId
|
|
45
|
-
...focusProps
|
|
40
|
+
"aria-controls": triggerId
|
|
46
41
|
}, /*#__PURE__*/React.createElement(CloseOutlineIcon, {
|
|
47
42
|
"data-render-all-sizes": true
|
|
48
43
|
}));
|
|
@@ -56,17 +51,19 @@ const Icons = _ref2 => {
|
|
|
56
51
|
isLoading,
|
|
57
52
|
canHaveClearIcon,
|
|
58
53
|
onClear,
|
|
59
|
-
triggerId
|
|
54
|
+
triggerId,
|
|
55
|
+
customStylesMap: styles$1 = styles
|
|
60
56
|
} = _ref2;
|
|
61
57
|
return /*#__PURE__*/React.createElement("div", {
|
|
62
|
-
className: styles.iconsWrapper
|
|
58
|
+
className: styles$1.iconsWrapper
|
|
63
59
|
}, /*#__PURE__*/React.createElement(ClearOrLoading, {
|
|
64
60
|
isLoading: isLoading,
|
|
65
61
|
canHaveClearIcon: canHaveClearIcon,
|
|
66
62
|
onClearClick: onClear,
|
|
67
|
-
triggerId: triggerId
|
|
63
|
+
triggerId: triggerId,
|
|
64
|
+
customStylesMap: styles$1
|
|
68
65
|
}), /*#__PURE__*/React.createElement(DownOutlineIcon, {
|
|
69
|
-
className: styles.toggle,
|
|
66
|
+
className: styles$1.toggle,
|
|
70
67
|
"data-test": "toggle-icon",
|
|
71
68
|
"data-render-all-sizes": true
|
|
72
69
|
}));
|
package/lib/parts/list-box.d.ts
CHANGED
|
@@ -1,19 +1,11 @@
|
|
|
1
|
-
|
|
2
|
-
import
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
listBoxRef?: React.RefObject<HTMLUListElement>;
|
|
7
|
-
state: ListState<T>;
|
|
8
|
-
ariaListBoxProps?: AriaListBoxOptions<T>;
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
import { SelectSize, ListBoxItem, ListBoxState } from '../types';
|
|
3
|
+
export declare type ListBoxProps = {
|
|
4
|
+
state: ListBoxState;
|
|
5
|
+
items: ListBoxItem[];
|
|
9
6
|
size?: SelectSize;
|
|
10
|
-
mode?: SelectMode;
|
|
11
7
|
className?: string;
|
|
12
8
|
maxVisibleItems?: number;
|
|
13
|
-
selectionMode?: 'single' | 'multiple';
|
|
14
|
-
};
|
|
15
|
-
export declare function ListBox<T extends object>({ listBoxRef: listBoxRefFromProps, state, ariaListBoxProps, size, mode, maxVisibleItems, selectionMode }: ListBoxProps<T>): JSX.Element;
|
|
16
|
-
export declare type EmptyListBoxProps<T extends object> = {
|
|
17
9
|
emptyListMessage: string;
|
|
18
|
-
}
|
|
19
|
-
export declare
|
|
10
|
+
};
|
|
11
|
+
export declare function ListBox({ state, items, size, maxVisibleItems, emptyListMessage }: ListBoxProps): JSX.Element;
|
package/lib/parts/list-box.js
CHANGED
|
@@ -1,18 +1,10 @@
|
|
|
1
1
|
import React, { useRef } from 'react';
|
|
2
2
|
import cn from 'classnames';
|
|
3
|
-
import { useListState } from '@react-stately/list';
|
|
4
|
-
import { Item } from '@react-stately/collections';
|
|
5
|
-
import { useListBox, useOption, useListBoxSection } from '@react-aria/listbox';
|
|
6
|
-
import { mergeProps } from '@react-aria/utils';
|
|
7
3
|
import styles from '../styles/list-box.p.module.css.js';
|
|
8
4
|
import { calculateMaxHeightByItems } from '../utils/calculate-max-height-by-items.js';
|
|
9
5
|
import { getRealItemsCnt } from '../utils/get-real-items-cnt.js';
|
|
10
|
-
import {
|
|
6
|
+
import { getTextFromNodes } from '../utils/get-text-from-nodes.js';
|
|
11
7
|
import CheckOutlineIcon from '../_virtual/check-outline.js';
|
|
12
|
-
const MODE_STYLES = {
|
|
13
|
-
classic: styles.modeClassic,
|
|
14
|
-
rock: styles.modeRock
|
|
15
|
-
};
|
|
16
8
|
const SIZE_STYLES = {
|
|
17
9
|
s: styles.sizeS,
|
|
18
10
|
m: styles.sizeM,
|
|
@@ -22,66 +14,65 @@ const SIZE_STYLES = {
|
|
|
22
14
|
function Option(_ref) {
|
|
23
15
|
let {
|
|
24
16
|
item,
|
|
25
|
-
state
|
|
26
|
-
selectionMode
|
|
17
|
+
state
|
|
27
18
|
} = _ref;
|
|
28
19
|
// Get props for the option element
|
|
29
20
|
const ref = useRef(null);
|
|
30
21
|
const {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
} =
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
22
|
+
selectedMap,
|
|
23
|
+
selectionMode,
|
|
24
|
+
getItemProps,
|
|
25
|
+
highlightedIndex
|
|
26
|
+
} = state;
|
|
27
|
+
const index = item.index;
|
|
28
|
+
const isSelected = selectedMap.has(item.key);
|
|
29
|
+
const isHighlighted = highlightedIndex === item.index;
|
|
30
|
+
const isDisabled = item.disabled;
|
|
31
|
+
return /*#__PURE__*/React.createElement("li", { ...getItemProps({
|
|
32
|
+
item,
|
|
33
|
+
index,
|
|
34
|
+
'aria-selected': isSelected,
|
|
35
|
+
'tab-index': isHighlighted ? 0 : -1,
|
|
36
|
+
ref
|
|
37
|
+
}),
|
|
40
38
|
className: cn(styles.item, isSelected && styles.selected, isDisabled && styles.disabled),
|
|
41
39
|
"data-rs-internal": "select-list-box__item",
|
|
42
|
-
"data-focused":
|
|
40
|
+
"data-focused": isHighlighted,
|
|
43
41
|
"data-test": `select-options-list__item_${item.key}`
|
|
44
|
-
}, /*#__PURE__*/React.createElement("span", null, item.
|
|
42
|
+
}, /*#__PURE__*/React.createElement("span", null, item.label), selectionMode === 'multiple' && /*#__PURE__*/React.createElement(CheckOutlineIcon, {
|
|
45
43
|
"data-rs-internal": "select-list-box__check-icon",
|
|
46
44
|
className: cn(styles.checkIcon, isSelected && styles.visible)
|
|
47
45
|
}));
|
|
48
46
|
}
|
|
49
47
|
|
|
50
|
-
function
|
|
48
|
+
function ListBoxGroup(_ref2) {
|
|
51
49
|
let {
|
|
52
|
-
|
|
53
|
-
state,
|
|
50
|
+
item,
|
|
54
51
|
isFirst,
|
|
55
|
-
|
|
52
|
+
state
|
|
56
53
|
} = _ref2;
|
|
57
|
-
const
|
|
58
|
-
itemProps,
|
|
59
|
-
headingProps,
|
|
60
|
-
groupProps
|
|
61
|
-
} = useListBoxSection({
|
|
62
|
-
heading: section.rendered,
|
|
63
|
-
'aria-label': section['aria-label']
|
|
64
|
-
});
|
|
65
|
-
const hasHeading = section.rendered !== null && section.rendered !== undefined;
|
|
54
|
+
const hasHeading = item.label !== null && item.label !== undefined;
|
|
66
55
|
const hasDivider = !isFirst && !hasHeading; // If the section is not the first, add a divider for visual separation
|
|
67
56
|
|
|
68
57
|
return /*#__PURE__*/React.createElement(React.Fragment, null, hasDivider && /*#__PURE__*/React.createElement("hr", {
|
|
69
58
|
className: styles.divider
|
|
70
|
-
}), /*#__PURE__*/React.createElement("li", {
|
|
59
|
+
}), /*#__PURE__*/React.createElement("li", {
|
|
60
|
+
role: "presentation"
|
|
71
61
|
}, hasHeading && /*#__PURE__*/React.createElement("span", {
|
|
72
62
|
className: styles.groupHeader,
|
|
73
|
-
|
|
63
|
+
role: "presentation",
|
|
74
64
|
"data-rs-internal": "select-list-box__group-header"
|
|
75
|
-
},
|
|
65
|
+
}, item.label), /*#__PURE__*/React.createElement("ul", {
|
|
66
|
+
role: "group",
|
|
67
|
+
"aria-label": hasHeading ? getTextFromNodes(item.label) : undefined,
|
|
76
68
|
style: {
|
|
77
69
|
padding: 0,
|
|
78
70
|
listStyle: 'none'
|
|
79
71
|
}
|
|
80
|
-
},
|
|
81
|
-
key:
|
|
82
|
-
item:
|
|
83
|
-
state: state
|
|
84
|
-
selectionMode: selectionMode
|
|
72
|
+
}, item.options.map(option => /*#__PURE__*/React.createElement(Option, {
|
|
73
|
+
key: option.key,
|
|
74
|
+
item: option,
|
|
75
|
+
state: state
|
|
85
76
|
})))));
|
|
86
77
|
}
|
|
87
78
|
|
|
@@ -89,60 +80,37 @@ function ListBox(_ref3) {
|
|
|
89
80
|
var _items$find;
|
|
90
81
|
|
|
91
82
|
let {
|
|
92
|
-
listBoxRef: listBoxRefFromProps,
|
|
93
83
|
state,
|
|
94
|
-
|
|
84
|
+
items,
|
|
95
85
|
size,
|
|
96
|
-
mode,
|
|
97
86
|
maxVisibleItems = 5,
|
|
98
|
-
|
|
87
|
+
emptyListMessage
|
|
99
88
|
} = _ref3;
|
|
100
|
-
const ref = useRef(null);
|
|
101
|
-
const listBoxRef = listBoxRefFromProps ?? ref;
|
|
102
89
|
const {
|
|
103
|
-
|
|
104
|
-
} =
|
|
105
|
-
const
|
|
106
|
-
const
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
className: cn(styles.listBox, MODE_STYLES[mode], SIZE_STYLES[size]),
|
|
110
|
-
ref: listBoxRef,
|
|
90
|
+
menuProps
|
|
91
|
+
} = state;
|
|
92
|
+
const firstGroupKey = (_items$find = items.find(item => item.type === 'group')) === null || _items$find === void 0 ? void 0 : _items$find.key;
|
|
93
|
+
const itemsCount = getRealItemsCnt(items);
|
|
94
|
+
return /*#__PURE__*/React.createElement("ul", { ...menuProps,
|
|
95
|
+
className: cn(styles.listBox, SIZE_STYLES[size]),
|
|
111
96
|
style: {
|
|
112
97
|
'--_rs-select-list-box-max-height-by-items': calculateMaxHeightByItems(itemsCount, maxVisibleItems)
|
|
113
98
|
},
|
|
114
99
|
"data-rs-internal": "select-list-box",
|
|
115
100
|
"data-test": "select-options-list"
|
|
116
|
-
},
|
|
101
|
+
}, itemsCount === 0 ? /*#__PURE__*/React.createElement("li", {
|
|
102
|
+
className: cn(styles.item, styles.disabled),
|
|
103
|
+
"data-rs-internal": "select-list-box__item"
|
|
104
|
+
}, /*#__PURE__*/React.createElement("span", null, emptyListMessage)) : items.map(item => item.type === 'group' ? /*#__PURE__*/React.createElement(ListBoxGroup, {
|
|
117
105
|
key: item.key,
|
|
118
|
-
|
|
106
|
+
item: item,
|
|
119
107
|
state: state,
|
|
120
|
-
isFirst: item.key ===
|
|
121
|
-
selectionMode: selectionMode
|
|
108
|
+
isFirst: item.key === firstGroupKey
|
|
122
109
|
}) : /*#__PURE__*/React.createElement(Option, {
|
|
123
110
|
key: item.key,
|
|
124
111
|
item: item,
|
|
125
|
-
state: state
|
|
126
|
-
selectionMode: selectionMode
|
|
112
|
+
state: state
|
|
127
113
|
})));
|
|
128
114
|
}
|
|
129
115
|
|
|
130
|
-
|
|
131
|
-
let {
|
|
132
|
-
emptyListMessage,
|
|
133
|
-
...props
|
|
134
|
-
} = _ref4;
|
|
135
|
-
const emptyListState = useListState({
|
|
136
|
-
children: [/*#__PURE__*/React.createElement(Item, {
|
|
137
|
-
key: "no-results",
|
|
138
|
-
textValue: emptyListMessage
|
|
139
|
-
}, emptyListMessage)],
|
|
140
|
-
disabledKeys: ['no-results'],
|
|
141
|
-
selectionMode: 'none'
|
|
142
|
-
});
|
|
143
|
-
return /*#__PURE__*/React.createElement(ListBox, { ...props,
|
|
144
|
-
state: emptyListState
|
|
145
|
-
});
|
|
146
|
-
};
|
|
147
|
-
|
|
148
|
-
export { EmptyListBox, ListBox };
|
|
116
|
+
export { ListBox };
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import type {
|
|
3
|
-
export interface MultiTriggerProps
|
|
4
|
-
|
|
2
|
+
import type { SelectOption } from '../types';
|
|
3
|
+
export interface MultiTriggerProps {
|
|
4
|
+
selectedItems: SelectOption[];
|
|
5
|
+
removeSelectedItem: (item: SelectOption) => void;
|
|
5
6
|
valueProps: object;
|
|
6
7
|
isSingleLine: boolean;
|
|
7
8
|
isDisabled: boolean;
|
|
8
9
|
placeholder?: string;
|
|
9
10
|
triggerRef?: React.RefObject<HTMLDivElement>;
|
|
10
11
|
}
|
|
11
|
-
export declare function MultiTrigger
|
|
12
|
+
export declare function MultiTrigger({ selectedItems, valueProps, isSingleLine, isDisabled, placeholder, triggerRef, removeSelectedItem }: MultiTriggerProps): JSX.Element;
|
|
@@ -3,18 +3,20 @@ import cn from 'classnames';
|
|
|
3
3
|
import { RemovableTag, Tag } from '@rescui/tag';
|
|
4
4
|
import styles from '../styles/common.p.module.css.js';
|
|
5
5
|
import { getTextFromNodes } from '../utils/get-text-from-nodes.js';
|
|
6
|
+
import { getOptionValue } from '../utils/get-option-value.js';
|
|
6
7
|
import Foldable from './foldable.js';
|
|
7
8
|
|
|
8
9
|
function MultiTrigger(_ref) {
|
|
9
10
|
let {
|
|
10
|
-
|
|
11
|
+
selectedItems,
|
|
11
12
|
valueProps,
|
|
12
13
|
isSingleLine,
|
|
13
14
|
isDisabled,
|
|
14
15
|
placeholder,
|
|
15
|
-
triggerRef
|
|
16
|
+
triggerRef,
|
|
17
|
+
removeSelectedItem
|
|
16
18
|
} = _ref;
|
|
17
|
-
const hasValue =
|
|
19
|
+
const hasValue = selectedItems.length > 0;
|
|
18
20
|
|
|
19
21
|
if (!hasValue) {
|
|
20
22
|
return /*#__PURE__*/React.createElement("div", { ...valueProps,
|
|
@@ -23,25 +25,35 @@ function MultiTrigger(_ref) {
|
|
|
23
25
|
}, placeholder);
|
|
24
26
|
}
|
|
25
27
|
|
|
26
|
-
const
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
state.setValue([...state.selectedItems].map(item => item.key).filter(itemKey => itemKey !== key));
|
|
30
|
-
(_triggerRef$current = triggerRef.current) === null || _triggerRef$current === void 0 || _triggerRef$current.focus();
|
|
31
|
-
};
|
|
32
|
-
|
|
33
|
-
const tags = [...state.selectedItems].map(item => {
|
|
34
|
-
const key = item.key;
|
|
28
|
+
const tags = selectedItems.map(option => {
|
|
29
|
+
const key = getOptionValue(option);
|
|
35
30
|
return /*#__PURE__*/React.createElement(RemovableTag, {
|
|
36
31
|
key: key,
|
|
32
|
+
tabIndex: -1,
|
|
37
33
|
"data-test": `selected-tag-${key}`,
|
|
38
34
|
className: styles.tag,
|
|
39
35
|
disabled: isDisabled,
|
|
40
|
-
onRemoveClick: () =>
|
|
36
|
+
onRemoveClick: () => {
|
|
37
|
+
var _triggerRef$current;
|
|
38
|
+
|
|
39
|
+
removeSelectedItem(option);
|
|
40
|
+
(_triggerRef$current = triggerRef.current) === null || _triggerRef$current === void 0 || _triggerRef$current.focus({
|
|
41
|
+
focusVisible: false
|
|
42
|
+
});
|
|
43
|
+
},
|
|
41
44
|
"data-rs-internal": "select-trigger__removable-tag",
|
|
42
45
|
wrap: !isSingleLine,
|
|
43
|
-
"aria-label": getTextFromNodes(
|
|
44
|
-
|
|
46
|
+
"aria-label": getTextFromNodes(option.label),
|
|
47
|
+
onFocus: e => {
|
|
48
|
+
if (e.target.getAttribute('tabindex') === '-1') {
|
|
49
|
+
var _triggerRef$current2;
|
|
50
|
+
|
|
51
|
+
(_triggerRef$current2 = triggerRef.current) === null || _triggerRef$current2 === void 0 || _triggerRef$current2.focus({
|
|
52
|
+
focusVisible: false
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}, option.label);
|
|
45
57
|
});
|
|
46
58
|
return /*#__PURE__*/React.createElement("div", { ...valueProps,
|
|
47
59
|
className: styles.multi,
|
|
@@ -1,18 +1,16 @@
|
|
|
1
1
|
/// <reference types="react" />
|
|
2
2
|
import type { Theme } from '@rescui/ui-contexts';
|
|
3
|
-
import {
|
|
3
|
+
import { NativeSelectOption, SelectSize } from '../types';
|
|
4
4
|
export declare type NativeSelectDefaultTriggerProps = {
|
|
5
|
-
isFocused: boolean;
|
|
6
|
-
isHovered: boolean;
|
|
7
5
|
isLoading: boolean;
|
|
8
6
|
isDisabled: boolean;
|
|
7
|
+
isClearable: boolean;
|
|
9
8
|
size: SelectSize;
|
|
10
9
|
theme?: Theme;
|
|
11
10
|
hasError: boolean;
|
|
12
11
|
placeholder?: string;
|
|
13
|
-
value:
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
};
|
|
12
|
+
value: NativeSelectOption;
|
|
13
|
+
onClear?: () => void;
|
|
14
|
+
triggerId?: string;
|
|
17
15
|
};
|
|
18
|
-
export declare const NativeSelectTrigger: ({
|
|
16
|
+
export declare const NativeSelectTrigger: ({ isLoading, isDisabled, isClearable, hasError, size, theme, placeholder, value, onClear, triggerId }: NativeSelectDefaultTriggerProps) => JSX.Element;
|