@rescui/select 0.15.1 → 0.16.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.
Files changed (95) hide show
  1. package/lib/_virtual/index.css.js +12 -12
  2. package/lib/common-prop-types.d.ts +8 -14
  3. package/lib/common-prop-types.js +4 -3
  4. package/lib/constants.d.ts +6 -0
  5. package/lib/constants.js +7 -0
  6. package/lib/hooks/use-a11y.d.ts +30 -0
  7. package/lib/hooks/use-a11y.js +56 -0
  8. package/lib/hooks/use-actual-size-from-css.d.ts +10 -0
  9. package/lib/hooks/use-actual-size-from-css.js +27 -0
  10. package/lib/hooks/use-focus.d.ts +10 -0
  11. package/lib/hooks/use-focus.js +17 -0
  12. package/lib/hooks/use-hover.d.ts +10 -0
  13. package/lib/hooks/use-hover.js +17 -0
  14. package/lib/hooks/use-label-focus.d.ts +9 -0
  15. package/lib/hooks/use-label-focus.js +22 -0
  16. package/lib/hooks/use-multi-handlers.d.ts +11 -0
  17. package/lib/hooks/use-multi-handlers.js +44 -0
  18. package/lib/hooks/use-options.d.ts +14 -0
  19. package/lib/hooks/use-options.js +90 -0
  20. package/lib/hooks/use-primary-contrast-css-var-transfer.d.ts +11 -0
  21. package/lib/hooks/use-primary-contrast-css-var-transfer.js +29 -0
  22. package/lib/hooks/use-safe-id.d.ts +6 -0
  23. package/lib/hooks/use-safe-id.js +15 -0
  24. package/lib/index.css +713 -304
  25. package/lib/index.d.ts +4 -6
  26. package/lib/index.js +3 -3
  27. package/lib/multiselect.d.ts +3 -0
  28. package/lib/multiselect.js +308 -0
  29. package/lib/native-select.d.ts +4 -0
  30. package/lib/native-select.js +208 -0
  31. package/lib/parts/foldable.js +5 -7
  32. package/lib/parts/form-trigger-wrapper.d.ts +7 -7
  33. package/lib/parts/form-trigger-wrapper.js +16 -34
  34. package/lib/parts/hidden-select.d.ts +13 -0
  35. package/lib/parts/hidden-select.js +45 -0
  36. package/lib/parts/icons.d.ts +17 -0
  37. package/lib/parts/icons.js +69 -0
  38. package/lib/parts/list-box.d.ts +13 -0
  39. package/lib/parts/list-box.js +120 -0
  40. package/lib/parts/multi-trigger.d.ts +12 -0
  41. package/lib/parts/multi-trigger.js +70 -0
  42. package/lib/parts/native-select-options-with-groups.d.ts +8 -0
  43. package/lib/parts/native-select-options-with-groups.js +76 -0
  44. package/lib/parts/popup-content.d.ts +20 -0
  45. package/lib/parts/popup-content.js +68 -0
  46. package/lib/public-api.p.css +543 -307
  47. package/lib/public-api.pcss +543 -307
  48. package/lib/select-basic.d.ts +3 -0
  49. package/lib/select-basic.js +204 -0
  50. package/lib/select-searchable.d.ts +3 -0
  51. package/lib/select-searchable.js +245 -0
  52. package/lib/select.d.ts +27 -91
  53. package/lib/select.js +51 -351
  54. package/lib/styles/common.p.module.css.js +32 -0
  55. package/lib/styles/form-trigger.p.module.css.js +15 -0
  56. package/lib/styles/list-box.p.module.css.js +16 -0
  57. package/lib/types.d.ts +172 -4
  58. package/lib/utils/calculate-max-height-by-items.d.ts +13 -0
  59. package/lib/utils/calculate-max-height-by-items.js +22 -0
  60. package/lib/utils/get-empty-message.d.ts +6 -0
  61. package/lib/utils/get-empty-message.js +32 -0
  62. package/lib/utils/get-option-value.d.ts +2 -0
  63. package/lib/utils/get-option-value.js +11 -0
  64. package/lib/utils/get-real-items-cnt.d.ts +2 -0
  65. package/lib/utils/get-real-items-cnt.js +19 -0
  66. package/lib/utils/get-text-from-nodes.d.ts +2 -0
  67. package/lib/utils/get-text-from-nodes.js +26 -0
  68. package/lib/utils/is-option-a-group.d.ts +2 -0
  69. package/lib/utils/is-option-a-group.js +5 -0
  70. package/lib/utils/item-to-string.d.ts +2 -0
  71. package/lib/utils/item-to-string.js +7 -0
  72. package/lib/utils/merge-props.d.ts +19 -0
  73. package/lib/utils/merge-props.js +104 -0
  74. package/lib/utils/throttle.d.ts +1 -0
  75. package/package.json +8 -8
  76. package/lib/key-codes.d.ts +0 -7
  77. package/lib/key-codes.js +0 -8
  78. package/lib/parts/common-select.p.module.css.js +0 -15
  79. package/lib/parts/form-trigger.p.module.css.js +0 -15
  80. package/lib/parts/multiselect.d.ts +0 -86
  81. package/lib/parts/multiselect.js +0 -455
  82. package/lib/parts/native-select.d.ts +0 -36
  83. package/lib/parts/native-select.js +0 -257
  84. package/lib/parts/native-select.p.module.css.js +0 -9
  85. package/lib/parts/throttle.d.ts +0 -1
  86. package/lib/parts/trigger.d.ts +0 -37
  87. package/lib/parts/trigger.js +0 -255
  88. package/lib/parts/trigger.p.module.css.js +0 -31
  89. package/lib/parts/use-backward-compatible-id.d.ts +0 -4
  90. package/lib/parts/use-backward-compatible-id.js +0 -14
  91. package/lib/parts/use-observable-force-rerender.d.ts +0 -2
  92. package/lib/parts/use-observable-force-rerender.js +0 -16
  93. package/lib/utils.d.ts +0 -22
  94. package/lib/utils.js +0 -201
  95. /package/lib/{parts → utils}/throttle.js +0 -0
package/lib/index.d.ts CHANGED
@@ -1,6 +1,4 @@
1
- export { default as Select } from './select';
2
- export type { SelectProps } from './select';
3
- export { default as NativeSelect } from './parts/native-select';
4
- export type { NativeSelectProps } from './parts/native-select';
5
- export { default as Multiselect } from './parts/multiselect';
6
- export type { MultiselectProps } from './parts/multiselect';
1
+ export { Select } from './select';
2
+ export { Multiselect } from './multiselect';
3
+ export { NativeSelect } from './native-select';
4
+ export type { SelectProps, MultiselectProps, NativeSelectProps, SelectOption, Key } from './types';
package/lib/index.js CHANGED
@@ -1,4 +1,4 @@
1
1
  import './index.css';
2
- export { default as Select } from './select.js';
3
- export { default as NativeSelect } from './parts/native-select.js';
4
- export { default as Multiselect } from './parts/multiselect.js';
2
+ export { Select } from './select.js';
3
+ export { Multiselect } from './multiselect.js';
4
+ export { NativeSelect } from './native-select.js';
@@ -0,0 +1,3 @@
1
+ /// <reference types="react" />
2
+ import type { MultiselectProps } from './types';
3
+ export declare function Multiselect({ options, value, onChange, error, label, note, size, mode, theme: themeFromProps, placement, isSingleLine, boldLabel, reserveErrorLine, maxVisibleItems, isClearable, isLoading, isDisabled, name, noOptionsMessage, className, id, style, placeholder, ...rest }: MultiselectProps): JSX.Element;
@@ -0,0 +1,308 @@
1
+ "use client";
2
+ import React, { useMemo, useRef } from 'react';
3
+ import cn from 'classnames';
4
+ import { useSelect } from 'downshift';
5
+ import { useThemeWithUndefined } from '@rescui/ui-contexts';
6
+ import scrollIntoView from 'scroll-into-view-if-needed';
7
+ import { useLabelFocus } from './hooks/use-label-focus.js';
8
+ import { useOptions } from './hooks/use-options.js';
9
+ import { useMultiHandlers } from './hooks/use-multi-handlers.js';
10
+ import { useA11y } from './hooks/use-a11y.js';
11
+ import { Icons } from './parts/icons.js';
12
+ import { MultiTrigger } from './parts/multi-trigger.js';
13
+ import { HiddenSelect } from './parts/hidden-select.js';
14
+ import { FormTriggerWrapper } from './parts/form-trigger-wrapper.js';
15
+ import { PopupContent } from './parts/popup-content.js';
16
+ import { getEmptyMessage } from './utils/get-empty-message.js';
17
+ import { mergeProps } from './utils/merge-props.js';
18
+ import { itemToString } from './utils/item-to-string.js';
19
+ import { getOptionValue } from './utils/get-option-value.js';
20
+ import { getRealItemsCnt } from './utils/get-real-items-cnt.js';
21
+ import styles from './styles/common.p.module.css.js';
22
+ const THEME_STYLES = {
23
+ light: styles.themeLight,
24
+ dark: styles.themeDark
25
+ };
26
+ const SIZE_STYLES = {
27
+ s: styles.sizeS,
28
+ m: styles.sizeM,
29
+ l: styles.sizeL
30
+ };
31
+ const MODE_STYLES = {
32
+ classic: styles.classic,
33
+ rock: styles.rock
34
+ };
35
+
36
+ const stateReducer = (state, actionAndChanges) => {
37
+ const {
38
+ changes,
39
+ type
40
+ } = actionAndChanges;
41
+
42
+ switch (type) {
43
+ case useSelect.stateChangeTypes.ToggleButtonKeyDownEnter:
44
+ case useSelect.stateChangeTypes.ToggleButtonKeyDownSpaceButton:
45
+ case useSelect.stateChangeTypes.ItemClick:
46
+ return { ...changes,
47
+ isOpen: true,
48
+ highlightedIndex: state.highlightedIndex
49
+ };
50
+
51
+ default:
52
+ return { ...changes,
53
+ selectedItem: null
54
+ };
55
+ }
56
+ }; // eslint-disable-next-line complexity
57
+
58
+
59
+ function Multiselect(_ref) {
60
+ let {
61
+ options = [],
62
+ value,
63
+ onChange,
64
+ error,
65
+ label,
66
+ note,
67
+ size = 'm',
68
+ mode = 'classic',
69
+ theme: themeFromProps,
70
+ placement = 'bottom',
71
+ isSingleLine = false,
72
+ boldLabel = true,
73
+ reserveErrorLine = false,
74
+ maxVisibleItems = 5,
75
+ isClearable = false,
76
+ isLoading = false,
77
+ isDisabled = false,
78
+ name,
79
+ noOptionsMessage,
80
+ className,
81
+ id,
82
+ style,
83
+ placeholder,
84
+ ...rest
85
+ } = _ref;
86
+ const selectedItems = useMemo(() => value ?? [], [value]);
87
+ const theme = useThemeWithUndefined(themeFromProps);
88
+ const triggerRef = useRef(null);
89
+ const menuRef = useRef(null);
90
+ const dropdownRef = useRef(null);
91
+ const {
92
+ selectedMap,
93
+ removeItem: removeSelectedItem,
94
+ addItem: addSelectedItem,
95
+ removeAllItems: reset
96
+ } = useMultiHandlers({
97
+ selectedItems,
98
+ onChange
99
+ });
100
+ const {
101
+ flattenedOptions,
102
+ listBoxItems
103
+ } = useOptions(options);
104
+ const isListBoxEmpty = getRealItemsCnt(listBoxItems) === 0;
105
+ const {
106
+ fieldProps,
107
+ errorMessageProps,
108
+ descriptionProps,
109
+ baseId
110
+ } = useA11y({
111
+ prefix: 'multiselect',
112
+ error,
113
+ description: note,
114
+ isDisabled
115
+ });
116
+ const {
117
+ isOpen,
118
+ getToggleButtonProps,
119
+ getLabelProps,
120
+ getMenuProps,
121
+ highlightedIndex,
122
+ getItemProps,
123
+ setHighlightedIndex
124
+ } = useSelect({
125
+ items: flattenedOptions,
126
+ itemToString,
127
+ itemToKey: getOptionValue,
128
+ id: baseId,
129
+
130
+ onIsOpenChange(newIsOpen) {
131
+ if (newIsOpen) {
132
+ // set the first selected item as a highlighted item if the popup is opened
133
+ const firstSelectedKey = [...selectedMap.keys()][0];
134
+
135
+ if (firstSelectedKey) {
136
+ setHighlightedIndex(flattenedOptions.findIndex(item => firstSelectedKey === getOptionValue(item)));
137
+ }
138
+ }
139
+ },
140
+
141
+ stateReducer,
142
+ // there's no actual selection happening in the hook, we're doing it custom via controlled props.
143
+ selectedItem: null,
144
+ // defining our scroll behavior because on the first menu render the hook
145
+ // doesn't know menuRef and use page as the scroll boundary
146
+ scrollIntoView: (listItemEl, listEl) => {
147
+ scrollIntoView(listItemEl, {
148
+ scrollMode: 'if-needed',
149
+ block: 'nearest',
150
+ boundary: listEl ?? menuRef.current
151
+ });
152
+ },
153
+ onSelectedItemChange: _ref2 => {
154
+ let {
155
+ selectedItem
156
+ } = _ref2;
157
+
158
+ if (!selectedItem) {
159
+ return;
160
+ }
161
+
162
+ const changedValue = getOptionValue(selectedItem);
163
+
164
+ if (selectedMap.has(changedValue)) {
165
+ removeSelectedItem(selectedItem);
166
+ } else {
167
+ addSelectedItem(selectedItem);
168
+ }
169
+ },
170
+
171
+ isItemDisabled(item) {
172
+ return item && item.disabled;
173
+ }
174
+
175
+ });
176
+ const menuProps = getMenuProps({
177
+ ref: menuRef,
178
+ 'aria-multiselectable': isListBoxEmpty ? undefined : 'true'
179
+ }, {
180
+ suppressRefError: true
181
+ });
182
+ const triggerProps = getToggleButtonProps({
183
+ ref: triggerRef,
184
+ // eslint-disable-next-line complexity
185
+ onKeyDown: event => {
186
+ // prevent default behavior of Downshift when pressing Ctrl
187
+ if (event.ctrlKey || event.metaKey) {
188
+ event.preventDownshiftDefault = true;
189
+ return;
190
+ } // shift + arrow up/down selection (when popup is open)
191
+
192
+
193
+ if (isOpen && event.shiftKey && (event.key === 'ArrowUp' || event.key === 'ArrowDown')) {
194
+ const newHighlightedIndex = event.key === 'ArrowUp' ? Math.max(highlightedIndex - 1, 0) : Math.min(highlightedIndex + 1, flattenedOptions.length - 1);
195
+
196
+ if (newHighlightedIndex === highlightedIndex) {
197
+ return;
198
+ }
199
+
200
+ addSelectedItem(flattenedOptions[newHighlightedIndex]);
201
+ } // backspace removing the last selected item (when popup is closed)
202
+
203
+
204
+ if (!isOpen && event.key === 'Backspace') {
205
+ removeSelectedItem(selectedItems[selectedItems.length - 1]);
206
+ } // delete removing all selected items (when popup is closed)
207
+
208
+
209
+ if (!isOpen && event.key === 'Delete') {
210
+ reset();
211
+ }
212
+ },
213
+ // fix screen-reader focus on an opened popup with an empty list
214
+ ...(isOpen && isListBoxEmpty ? {
215
+ 'aria-activedescendant': menuProps.id
216
+ } : {})
217
+ });
218
+ const {
219
+ isFocusedByLabel,
220
+ labelClickProps,
221
+ triggerFocusProps: labelFocusForTriggerProps
222
+ } = useLabelFocus();
223
+ const emptyListMessage = getEmptyMessage({
224
+ isLoading,
225
+ isNothingFound: false,
226
+ noOptionsMessage
227
+ });
228
+ const listBoxState = {
229
+ selectedMap,
230
+ highlightedIndex,
231
+ getItemProps,
232
+ menuProps
233
+ };
234
+ return /*#__PURE__*/React.createElement("div", {
235
+ className: cn(className, styles.root, THEME_STYLES[theme], SIZE_STYLES[size], MODE_STYLES[mode], isDisabled ? styles.disabled : styles.enabled, Boolean(error) && styles.error),
236
+ id: id,
237
+ style: style,
238
+ "data-test": "multiselect"
239
+ }, /*#__PURE__*/React.createElement(FormTriggerWrapper, {
240
+ theme: theme,
241
+ size: size,
242
+ disabled: isDisabled,
243
+ label: label,
244
+ labelProps: mergeProps(getLabelProps(), labelClickProps),
245
+ boldLabel: boldLabel,
246
+ error: error,
247
+ reserveErrorLine: reserveErrorLine,
248
+ errorMessageProps: errorMessageProps,
249
+ note: note,
250
+ descriptionProps: descriptionProps
251
+ }, /*#__PURE__*/React.createElement(HiddenSelect, {
252
+ name: name,
253
+ value: selectedItems,
254
+ isMultiple: true,
255
+ options: flattenedOptions
256
+ }), /*#__PURE__*/React.createElement(PopupContent, {
257
+ theme: theme,
258
+ size: size,
259
+ mode: mode,
260
+ dropdownRef: dropdownRef,
261
+ triggerRef: triggerRef,
262
+ placement: placement,
263
+ isOpen: isOpen,
264
+ listBoxState: listBoxState,
265
+ maxVisibleItems: maxVisibleItems,
266
+ emptyListMessage: emptyListMessage,
267
+ listBoxItems: listBoxItems,
268
+ dropdownUpdateDeps: [selectedItems],
269
+ trigger: _ref3 => {
270
+ let {
271
+ ref: triggerRefForDropdown
272
+ } = _ref3;
273
+ return /*#__PURE__*/React.createElement("div", {
274
+ className: styles.triggerContainer,
275
+ "data-open": isOpen,
276
+ "data-label-focused": isFocusedByLabel
277
+ }, /*#__PURE__*/React.createElement("div", { ...rest,
278
+ ...mergeProps(fieldProps, // aria-invalid & aria-describedby, rest are overridden by triggerProps
279
+ triggerProps, labelFocusForTriggerProps, {
280
+ ref: triggerRefForDropdown
281
+ }),
282
+ tabIndex: isDisabled ? undefined : 0,
283
+ className: cn(styles.trigger, !isSingleLine && styles.canBeMultiline),
284
+ "data-test": "multiselect__trigger"
285
+ }, /*#__PURE__*/React.createElement(MultiTrigger, {
286
+ selectedItems: selectedItems,
287
+ valueProps: {},
288
+ isSingleLine: isSingleLine,
289
+ isDisabled: isDisabled,
290
+ placeholder: placeholder,
291
+ triggerRef: triggerRef,
292
+ removeSelectedItem: removeSelectedItem
293
+ }), /*#__PURE__*/React.createElement(Icons, {
294
+ isLoading: isLoading,
295
+ canHaveClearIcon: isClearable && !isDisabled && selectedItems.length > 0,
296
+ onClear: () => {
297
+ reset();
298
+ triggerRef.current?.focus({
299
+ focusVisible: false
300
+ });
301
+ },
302
+ triggerId: triggerProps.id
303
+ })));
304
+ }
305
+ })));
306
+ }
307
+
308
+ export { Multiselect };
@@ -0,0 +1,4 @@
1
+ import React from 'react';
2
+ import type { NativeSelectProps } from './types';
3
+ export declare const NativeSelect: React.FC<NativeSelectProps>;
4
+ export default NativeSelect;
@@ -0,0 +1,208 @@
1
+ "use client";
2
+ import React from 'react';
3
+ import PropTypes from 'prop-types';
4
+ import cn from 'classnames';
5
+ import { useThemeWithUndefined } from '@rescui/ui-contexts';
6
+ import { ErrorMessage } from '@rescui/form-field';
7
+ import { nativeOptionType, nativeOptionsGroupType, noOptionsMessageType } from './common-prop-types.js';
8
+ import { useA11y } from './hooks/use-a11y.js';
9
+ import { useHover } from './hooks/use-hover.js';
10
+ import { useFocus } from './hooks/use-focus.js';
11
+ import { FormTriggerWrapper } from './parts/form-trigger-wrapper.js';
12
+ import { NativeSelectOptionsWithGroups } from './parts/native-select-options-with-groups.js';
13
+ import { Icons } from './parts/icons.js';
14
+ import { isOptionAGroup } from './utils/is-option-a-group.js';
15
+ import { getEmptyMessage } from './utils/get-empty-message.js';
16
+ import { mergeProps } from './utils/merge-props.js';
17
+ import styles from './styles/common.p.module.css.js';
18
+
19
+ function findSelectedOption(options, selectedValue) {
20
+ let result = null;
21
+
22
+ const checkOption = option => {
23
+ if (result === null || option.value === selectedValue) {
24
+ result = option;
25
+ }
26
+ };
27
+
28
+ options.forEach(optionOrGroup => {
29
+ if (isOptionAGroup(optionOrGroup)) {
30
+ const group = optionOrGroup;
31
+ group.options?.forEach(checkOption);
32
+ } else {
33
+ checkOption(optionOrGroup);
34
+ }
35
+ });
36
+ return result;
37
+ }
38
+
39
+ const SIZE_STYLES = {
40
+ s: styles.sizeS,
41
+ m: styles.sizeM,
42
+ l: styles.sizeL
43
+ };
44
+ const THEME_STYLES = {
45
+ light: styles.themeLight,
46
+ dark: styles.themeDark
47
+ }; // eslint-disable-next-line complexity
48
+
49
+ const NativeSelect = _ref => {
50
+ let {
51
+ options = [],
52
+ size = 'm',
53
+ theme: themeFromProps,
54
+ className = null,
55
+ id,
56
+ style,
57
+ value,
58
+ onChange,
59
+ placeholder,
60
+ isLoading = false,
61
+ isDisabled = false,
62
+ isClearable = false,
63
+ trigger,
64
+ label,
65
+ note,
66
+ error,
67
+ reserveErrorLine = false,
68
+ noOptionsMessage,
69
+ name,
70
+ boldLabel = true,
71
+ ...rest
72
+ } = _ref;
73
+ const triggerRef = React.useRef(null);
74
+ const {
75
+ labelProps,
76
+ fieldProps,
77
+ errorMessageProps,
78
+ descriptionProps
79
+ } = useA11y({
80
+ prefix: 'native-select',
81
+ error,
82
+ description: note,
83
+ label,
84
+ fieldRef: triggerRef,
85
+ isDisabled
86
+ });
87
+
88
+ const reset = () => onChange(null);
89
+
90
+ const theme = useThemeWithUndefined(themeFromProps);
91
+
92
+ const handleChange = event => {
93
+ const newValue = event.target.value;
94
+ const selectedOption = findSelectedOption(options, newValue);
95
+
96
+ if (onChange) {
97
+ onChange(selectedOption);
98
+ }
99
+ }; // delete it when triggerFunc is migrated to the css-states instead of js-props for hover/focus
100
+ // replace it with ":focus + &" selector in that case
101
+
102
+
103
+ const {
104
+ isFocused,
105
+ focusProps
106
+ } = useFocus({
107
+ isDisabled
108
+ }); // same as above, could be replaced with ":hover + &" selector
109
+
110
+ const {
111
+ isHovered,
112
+ hoverProps
113
+ } = useHover({
114
+ isDisabled
115
+ });
116
+ const emptyListMessage = getEmptyMessage({
117
+ isLoading,
118
+ isNothingFound: false,
119
+ noOptionsMessage
120
+ });
121
+ return /*#__PURE__*/React.createElement("div", {
122
+ className: cn(className, styles.root, SIZE_STYLES[size], THEME_STYLES[theme], styles.classic, isDisabled ? styles.disabled : styles.enabled, Boolean(error) && styles.error),
123
+ id: id,
124
+ style: style,
125
+ "data-test": "native-select"
126
+ }, /*#__PURE__*/React.createElement(FormTriggerWrapper, {
127
+ theme: theme,
128
+ size: size,
129
+ disabled: isDisabled,
130
+ label: label,
131
+ labelProps: mergeProps(labelProps),
132
+ boldLabel: boldLabel,
133
+ error: error,
134
+ errorMessageProps: errorMessageProps,
135
+ reserveErrorLine: reserveErrorLine,
136
+ note: note,
137
+ descriptionProps: descriptionProps
138
+ }, /*#__PURE__*/React.createElement("div", {
139
+ className: styles.triggerContainer
140
+ }, /*#__PURE__*/React.createElement("select", { ...rest,
141
+ ...mergeProps(fieldProps, focusProps, hoverProps, {
142
+ onKeyDown: event => {
143
+ // backspace and backspace removing the last selected item (when popup is closed)
144
+ if (isClearable && (event.key === 'Backspace' || event.key === 'Delete')) {
145
+ reset();
146
+ }
147
+ }
148
+ }),
149
+ ref: triggerRef,
150
+ "data-test": "native-select_select",
151
+ "data-rs-internal": 'select-native__select',
152
+ className: styles.select,
153
+ disabled: isDisabled ? true : undefined,
154
+ onChange: handleChange,
155
+ name: name,
156
+ value: value?.value ?? ''
157
+ }, /*#__PURE__*/React.createElement(NativeSelectOptionsWithGroups, {
158
+ optionsWithGroups: options,
159
+ placeholder: placeholder,
160
+ emptyListMessage: emptyListMessage
161
+ })), trigger ? trigger({
162
+ focused: isFocused,
163
+ hovered: isHovered,
164
+ selectedLabel: value?.label,
165
+ selectedValue: value?.value,
166
+ placeholder
167
+ }) : /*#__PURE__*/React.createElement("div", {
168
+ className: cn(styles.trigger),
169
+ "data-test": 'native-select_trigger',
170
+ "data-rs-internal": 'select-native-trigger'
171
+ }, /*#__PURE__*/React.createElement("span", {
172
+ className: cn(styles.triggerText, !value?.value && styles.labelNotSelected),
173
+ "data-test": 'native-select_trigger_text',
174
+ "aria-hidden": "true"
175
+ }, value?.label ?? placeholder), /*#__PURE__*/React.createElement(Icons, {
176
+ isLoading: isLoading,
177
+ triggerId: fieldProps.id,
178
+ onClear: () => {
179
+ reset();
180
+ triggerRef.current?.focus({
181
+ focusVisible: false
182
+ });
183
+ },
184
+ canHaveClearIcon: isClearable && !isDisabled && Boolean(value?.value)
185
+ })))));
186
+ };
187
+
188
+ NativeSelect.propTypes = {
189
+ className: PropTypes.string,
190
+ style: PropTypes.object,
191
+ id: PropTypes.string,
192
+ options: PropTypes.arrayOf(PropTypes.oneOfType([nativeOptionType, nativeOptionsGroupType])),
193
+ value: nativeOptionType,
194
+ onChange: PropTypes.func,
195
+ size: PropTypes.oneOf(['m', 's', 'l']),
196
+ theme: PropTypes.oneOf(['light', 'dark']),
197
+ placeholder: PropTypes.string,
198
+ isDisabled: PropTypes.bool,
199
+ isLoading: PropTypes.bool,
200
+ trigger: PropTypes.func,
201
+ error: ErrorMessage.propTypes.children,
202
+ label: PropTypes.node,
203
+ note: PropTypes.node,
204
+ noOptionsMessage: noOptionsMessageType,
205
+ name: PropTypes.string,
206
+ boldLabel: PropTypes.bool
207
+ };
208
+ export { NativeSelect, NativeSelect as default };
@@ -1,6 +1,5 @@
1
- "use client";
2
1
  import React, { Component } from 'react';
3
- import { throttle } from './throttle.js';
2
+ import { throttle } from '../utils/throttle.js';
4
3
 
5
4
  function lastVisibleIndex(lens, maxLen, gap) {
6
5
  let extra = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 0;
@@ -195,12 +194,11 @@ class Foldable extends Component {
195
194
  const children = React.Children.toArray(_this.props.children);
196
195
  const showLastChildIfFit = index === children.length - 2 && extra - gap - 1 > _this.childrenWidths[_this.childrenWidths.length - 1];
197
196
  const newLastVisible = index + (showLastChildIfFit ? 1 : 0);
198
- const newState = {
199
- lastVisible: newLastVisible,
200
- renderingStage: nextStage ? nextStage : _this.state.renderingStage
201
- };
202
197
 
203
- _this.setState(newState);
198
+ _this.setState(prevState => ({ ...prevState,
199
+ lastVisible: newLastVisible,
200
+ renderingStage: nextStage ?? prevState.renderingStage
201
+ }));
204
202
  };
205
203
  })();
206
204
 
@@ -5,29 +5,29 @@ export declare type FormTriggerWrapperProps = {
5
5
  size?: SelectSize;
6
6
  theme?: Theme;
7
7
  className?: string;
8
- id?: string;
9
8
  disabled?: boolean;
10
- errorId?: string;
11
9
  error?: boolean | React.ReactNode;
12
10
  reserveErrorLine?: boolean;
11
+ errorMessageProps?: object;
13
12
  label?: React.ReactNode;
13
+ labelProps?: object;
14
14
  note?: React.ReactNode;
15
- onKeyDown?: React.KeyboardEventHandler<HTMLDivElement>;
15
+ descriptionProps?: object;
16
16
  boldLabel?: boolean;
17
17
  children?: React.ReactNode;
18
18
  } & React.HTMLAttributes<HTMLDivElement>;
19
- declare const FormTriggerWrapper: React.ForwardRefExoticComponent<{
19
+ export declare const FormTriggerWrapper: React.ForwardRefExoticComponent<{
20
20
  size?: SelectSize;
21
21
  theme?: Theme;
22
22
  className?: string;
23
- id?: string;
24
23
  disabled?: boolean;
25
- errorId?: string;
26
24
  error?: boolean | React.ReactNode;
27
25
  reserveErrorLine?: boolean;
26
+ errorMessageProps?: object;
28
27
  label?: React.ReactNode;
28
+ labelProps?: object;
29
29
  note?: React.ReactNode;
30
- onKeyDown?: React.KeyboardEventHandler<HTMLDivElement>;
30
+ descriptionProps?: object;
31
31
  boldLabel?: boolean;
32
32
  children?: React.ReactNode;
33
33
  } & React.HTMLAttributes<HTMLDivElement> & React.RefAttributes<HTMLDivElement>>;