@rescui/select 0.15.1-RUI-280-Update-select-component-downshift-2f40ef205.67 → 0.15.2

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 (87) hide show
  1. package/lib/_virtual/index.css.js +12 -12
  2. package/lib/common-prop-types.d.ts +14 -9
  3. package/lib/common-prop-types.js +3 -4
  4. package/lib/index.css +432 -808
  5. package/lib/index.d.ts +6 -4
  6. package/lib/index.js +3 -3
  7. package/lib/key-codes.d.ts +7 -0
  8. package/lib/key-codes.js +8 -0
  9. package/lib/parts/common-select.p.module.css.js +15 -0
  10. package/lib/parts/foldable.js +2 -1
  11. package/lib/parts/form-trigger-wrapper.d.ts +7 -7
  12. package/lib/parts/form-trigger-wrapper.js +34 -16
  13. package/lib/parts/form-trigger.p.module.css.js +15 -0
  14. package/lib/parts/multiselect.d.ts +86 -0
  15. package/lib/parts/multiselect.js +455 -0
  16. package/lib/parts/native-select.d.ts +36 -0
  17. package/lib/parts/native-select.js +255 -0
  18. package/lib/parts/native-select.p.module.css.js +9 -0
  19. package/lib/parts/throttle.d.ts +1 -0
  20. package/lib/parts/trigger.d.ts +37 -0
  21. package/lib/parts/trigger.js +255 -0
  22. package/lib/parts/trigger.p.module.css.js +31 -0
  23. package/lib/parts/use-observable-force-rerender.d.ts +2 -0
  24. package/lib/parts/use-observable-force-rerender.js +16 -0
  25. package/lib/public-api.p.css +309 -545
  26. package/lib/public-api.pcss +309 -545
  27. package/lib/select.d.ts +91 -27
  28. package/lib/select.js +351 -51
  29. package/lib/types.d.ts +4 -167
  30. package/lib/utils.d.ts +22 -0
  31. package/lib/utils.js +199 -0
  32. package/package.json +12 -12
  33. package/lib/constants.d.ts +0 -6
  34. package/lib/constants.js +0 -7
  35. package/lib/hooks/use-a11y.d.ts +0 -29
  36. package/lib/hooks/use-a11y.js +0 -53
  37. package/lib/hooks/use-focus.d.ts +0 -10
  38. package/lib/hooks/use-focus.js +0 -17
  39. package/lib/hooks/use-hover.d.ts +0 -10
  40. package/lib/hooks/use-hover.js +0 -17
  41. package/lib/hooks/use-label-focus.d.ts +0 -9
  42. package/lib/hooks/use-label-focus.js +0 -22
  43. package/lib/hooks/use-multi-handlers.d.ts +0 -11
  44. package/lib/hooks/use-multi-handlers.js +0 -48
  45. package/lib/hooks/use-options.d.ts +0 -13
  46. package/lib/hooks/use-options.js +0 -89
  47. package/lib/multiselect.d.ts +0 -3
  48. package/lib/multiselect.js +0 -312
  49. package/lib/native-select.d.ts +0 -4
  50. package/lib/native-select.js +0 -211
  51. package/lib/parts/hidden-select.d.ts +0 -13
  52. package/lib/parts/hidden-select.js +0 -45
  53. package/lib/parts/icons.d.ts +0 -17
  54. package/lib/parts/icons.js +0 -69
  55. package/lib/parts/list-box.d.ts +0 -11
  56. package/lib/parts/list-box.js +0 -116
  57. package/lib/parts/multi-trigger.d.ts +0 -12
  58. package/lib/parts/multi-trigger.js +0 -74
  59. package/lib/parts/native-select-options-with-groups.d.ts +0 -8
  60. package/lib/parts/native-select-options-with-groups.js +0 -76
  61. package/lib/select-basic.d.ts +0 -3
  62. package/lib/select-basic.js +0 -203
  63. package/lib/select-searchable.d.ts +0 -3
  64. package/lib/select-searchable.js +0 -250
  65. package/lib/styles/common.p.module.css.js +0 -31
  66. package/lib/styles/form-trigger.p.module.css.js +0 -15
  67. package/lib/styles/list-box.p.module.css.js +0 -14
  68. package/lib/utils/calculate-max-height-by-items.d.ts +0 -13
  69. package/lib/utils/calculate-max-height-by-items.js +0 -22
  70. package/lib/utils/get-empty-message.d.ts +0 -6
  71. package/lib/utils/get-empty-message.js +0 -32
  72. package/lib/utils/get-option-value.d.ts +0 -2
  73. package/lib/utils/get-option-value.js +0 -11
  74. package/lib/utils/get-real-items-cnt.d.ts +0 -2
  75. package/lib/utils/get-real-items-cnt.js +0 -19
  76. package/lib/utils/get-text-from-nodes.d.ts +0 -2
  77. package/lib/utils/get-text-from-nodes.js +0 -28
  78. package/lib/utils/is-option-a-group.d.ts +0 -2
  79. package/lib/utils/is-option-a-group.js +0 -5
  80. package/lib/utils/item-to-string.d.ts +0 -2
  81. package/lib/utils/item-to-string.js +0 -7
  82. package/lib/utils/merge-props.d.ts +0 -29
  83. package/lib/utils/merge-props.js +0 -106
  84. package/lib/utils/throttle.d.ts +0 -1
  85. /package/lib/{utils → parts}/throttle.js +0 -0
  86. /package/lib/{hooks → parts}/use-backward-compatible-id.d.ts +0 -0
  87. /package/lib/{hooks → parts}/use-backward-compatible-id.js +0 -0
package/lib/select.d.ts CHANGED
@@ -1,28 +1,92 @@
1
1
  import React from 'react';
2
- import PropTypes from 'prop-types';
3
- import type { SelectProps, SelectOption, SelectOptionOrGroup } from './types';
4
- export declare const Select: {
5
- ({ options, size, mode, theme: themeFromProps, className, style, value, onChange, placeholder, isClearable, isLoading, isDisabled, isSearchable, noOptionsMessage, error, placement, boldLabel, reserveErrorLine, note, maxVisibleItems, id, ...restProps }: SelectProps): JSX.Element;
6
- propTypes: {
7
- className: PropTypes.Requireable<string>;
8
- style: PropTypes.Requireable<object>;
9
- options: PropTypes.Validator<SelectOptionOrGroup[]>;
10
- value: PropTypes.Validator<SelectOption>;
11
- onChange: PropTypes.Requireable<(...args: any[]) => any>;
12
- size: PropTypes.Requireable<string>;
13
- mode: PropTypes.Requireable<string>;
14
- theme: PropTypes.Requireable<string>;
15
- placeholder: PropTypes.Requireable<string>;
16
- isClearable: PropTypes.Requireable<boolean>;
17
- isSearchable: PropTypes.Requireable<boolean>;
18
- isDisabled: PropTypes.Requireable<boolean>;
19
- isLoading: PropTypes.Requireable<boolean>;
20
- error: React.Validator<React.ReactNode>;
21
- label: PropTypes.Requireable<PropTypes.ReactNodeLike>;
22
- id: PropTypes.Requireable<string>;
23
- note: PropTypes.Requireable<PropTypes.ReactNodeLike>;
24
- noOptionsMessage: React.Validator<import("./types").NoOptionsMessage>;
25
- placement: PropTypes.Requireable<string>;
26
- name: PropTypes.Requireable<string>;
27
- };
28
- };
2
+ import { Theme } from '@rescui/ui-contexts';
3
+ import type { SelectOption, NoOptionsMessage, SelectOptionOrGroup, SelectSize, SelectMode } from './types';
4
+ export interface CustomTriggerOptions {
5
+ selectedLabel?: string;
6
+ selectedValue: string;
7
+ placeholder?: string;
8
+ hovered: boolean;
9
+ }
10
+ export interface SelectProps {
11
+ /**
12
+ * Additional class name
13
+ */
14
+ className?: string;
15
+ id?: string;
16
+ /**
17
+ * Array of options or option groups
18
+ */
19
+ options: SelectOptionOrGroup[];
20
+ /**
21
+ * Is select supports clear the value
22
+ */
23
+ isClearable?: boolean;
24
+ /**
25
+ * Is select supports inplace filtering
26
+ */
27
+ isSearchable?: boolean;
28
+ /**
29
+ * Is select has been disabled
30
+ */
31
+ isDisabled?: boolean;
32
+ /**
33
+ * Is loader displayed inside select
34
+ */
35
+ isLoading?: boolean;
36
+ /**
37
+ * A hint to the user of what can be entered in the control
38
+ */
39
+ placeholder?: string;
40
+ /**
41
+ * Size
42
+ */
43
+ size?: SelectSize;
44
+ /**
45
+ * Appearance mode
46
+ */
47
+ mode?: SelectMode;
48
+ /**
49
+ * Appearance theme
50
+ */
51
+ theme?: Theme;
52
+ /**
53
+ * Value of the select
54
+ */
55
+ value: SelectOption;
56
+ /**
57
+ * Change value callback. `value => ...`
58
+ */
59
+ onChange?: (newValue: SelectOption) => void;
60
+ /**
61
+ * Error state flag or React.ReactNode (use with forms)
62
+ */
63
+ error?: boolean | React.ReactNode;
64
+ /**
65
+ * If `true`, there will be reserved a space for a 1-line error message. Subsequent lines will be placed below normally.
66
+ * If `false`, there will be no reservation.
67
+ */
68
+ reserveErrorLine?: boolean;
69
+ /**
70
+ * Label element upper then Select element (use with forms)
71
+ */
72
+ label?: React.ReactNode;
73
+ /**
74
+ * Placement of dropdown element
75
+ */
76
+ placement?: 'auto-start' | 'auto' | 'auto-end' | 'top-start' | 'top' | 'top-end' | 'right-start' | 'right' | 'right-end' | 'bottom-end' | 'bottom' | 'bottom-start' | 'left-end' | 'left' | 'left-start';
77
+ /**
78
+ * Note element below then Select element (use with forms)
79
+ */
80
+ note?: React.ReactNode;
81
+ /**
82
+ * Text to display when there are no options
83
+ */
84
+ noOptionsMessage?: NoOptionsMessage;
85
+ /**
86
+ * Input name attribute
87
+ */
88
+ name?: string;
89
+ boldLabel?: boolean;
90
+ }
91
+ declare const Select: React.FC<SelectProps>;
92
+ export default Select;
package/lib/select.js CHANGED
@@ -1,36 +1,103 @@
1
1
  "use client";
2
- import React from 'react';
2
+ import _includesInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/includes";
3
+ import React, { useState, useRef, useEffect, useMemo, useCallback } from 'react';
3
4
  import PropTypes from 'prop-types';
4
- import { ErrorMessage } from '@rescui/form-field';
5
5
  import cn from 'classnames';
6
+ import scrollIntoView from 'scroll-into-view-if-needed';
7
+ import { Dropdown } from '@rescui/dropdown';
8
+ import { Menu, MenuItem, Divider, GroupHeader } from '@rescui/menu';
9
+ import { ErrorMessage } from '@rescui/form-field';
6
10
  import { useThemeWithUndefined } from '@rescui/ui-contexts';
7
- import { optionType, optionsGroupType, noOptionsMessageType } from './common-prop-types.js';
8
- import { SelectBasic } from './select-basic.js';
9
- import { SelectSearchable } from './select-searchable.js';
10
- import styles from './styles/common.p.module.css.js';
11
- const THEME_STYLES = {
12
- light: styles.themeLight,
13
- dark: styles.themeDark
11
+ import SelectTrigger from './parts/trigger.js';
12
+ import FormTriggerWrapper from './parts/form-trigger-wrapper.js';
13
+ import { useObservableForceRerender } from './parts/use-observable-force-rerender.js';
14
+ import { useBackwardCompatibleId } from './parts/use-backward-compatible-id.js';
15
+ import { optionType, optionsGroupType, noOptionsMessageConfigType } from './common-prop-types.js';
16
+ import { useStrongMemo, getDefaultCursorIndex, isGroupsEmpty, getMovedCursorIndex, shouldOpenSelect, isIndexMatchCursor, withoutGroupsLabel, getPlainOptionsFromGroups, getEmptyMessage, OptionGroupTypes, getOptionValue, convertToOptionGroupsIfNeeded, escapeRegex, getTextFromNodes, calculateMaxHeight } from './utils.js';
17
+ import { ARROW_DOWN, ARROW_UP, ENTER, SPACE, TAB, ESCAPE, BACKSPACE } from './key-codes.js';
18
+ import styles from './parts/common-select.p.module.css.js'; // eslint-disable-next-line complexity
19
+
20
+ const Option = _ref => {
21
+ let {
22
+ selected,
23
+ cursorIndex,
24
+ item,
25
+ isLastItem,
26
+ highlightedItemRef,
27
+ handleSelectIndex,
28
+ handleHighlightIndex
29
+ } = _ref;
30
+
31
+ if (item.type === OptionGroupTypes.OPTION) {
32
+ const {
33
+ index,
34
+ label
35
+ } = item;
36
+ const value = getOptionValue(item);
37
+ const isSelected = selected && value === getOptionValue(selected);
38
+ const isHighlighted = isIndexMatchCursor(cursorIndex, index);
39
+ return /*#__PURE__*/React.createElement(MenuItem, {
40
+ selected: isSelected,
41
+ highlighted: isHighlighted,
42
+ ref: isHighlighted ? highlightedItemRef : null,
43
+ onMouseMove: () => handleHighlightIndex(index),
44
+ onClick: () => handleSelectIndex(index),
45
+ className: cn(isLastItem && styles.lastOption),
46
+ "data-test": ['select-menu-item', isHighlighted && 'select-menu-item-highlighted', isSelected && 'select-menu-item-selected'].filter(Boolean).join(' ')
47
+ }, label);
48
+ }
49
+
50
+ if (item.type === OptionGroupTypes.DIVIDER) {
51
+ return /*#__PURE__*/React.createElement(Divider, {
52
+ className: styles.divider
53
+ });
54
+ }
55
+
56
+ if (item.type === OptionGroupTypes.HEADER) {
57
+ const {
58
+ label
59
+ } = item;
60
+ return /*#__PURE__*/React.createElement(GroupHeader, {
61
+ text: label
62
+ });
63
+ }
64
+
65
+ return null;
66
+ };
67
+
68
+ const getOptionKey = (item, i) => {
69
+ if (item.type === OptionGroupTypes.OPTION) {
70
+ const value = getOptionValue(item);
71
+ return `${value}_${item.index[0]}`;
72
+ } else if (item.type === OptionGroupTypes.DIVIDER) {
73
+ return `divider${i}`;
74
+ } else if (item.type === OptionGroupTypes.HEADER) {
75
+ return `header${i}`;
76
+ }
77
+
78
+ return null;
14
79
  };
80
+
15
81
  const SIZE_STYLES = {
16
82
  s: styles.sizeS,
17
83
  m: styles.sizeM,
18
84
  l: styles.sizeL
19
85
  };
20
- const MODE_STYLES = {
21
- classic: styles.classic,
22
- rock: styles.rock
23
- };
86
+ const MENU_SIZE_STYLES = {
87
+ s: styles.menuSizeS,
88
+ m: styles.menuSizeM,
89
+ l: styles.menuSizeL
90
+ }; // eslint-disable-next-line complexity
24
91
 
25
- const Select = _ref => {
92
+ const Select = _ref2 => {
26
93
  let {
27
- options = [],
94
+ options,
28
95
  size = 'm',
29
96
  mode = 'classic',
30
97
  theme: themeFromProps,
31
- className,
32
- style,
33
- value,
98
+ className = null,
99
+ id,
100
+ value = undefined,
34
101
  onChange,
35
102
  placeholder,
36
103
  isClearable = false,
@@ -42,45 +109,278 @@ const Select = _ref => {
42
109
  placement = 'bottom',
43
110
  boldLabel = true,
44
111
  reserveErrorLine = false,
45
- note,
46
- maxVisibleItems = 5,
47
- id,
48
112
  ...restProps
49
- } = _ref;
113
+ } = _ref2;
114
+ const [triggerFormWrapperRef, setTriggerFormWrapperRef] = useState(null);
50
115
  const theme = useThemeWithUndefined(themeFromProps);
51
- const InnerSingleComponent = isSearchable ? SelectSearchable : SelectBasic;
52
- return /*#__PURE__*/React.createElement("div", {
53
- className: cn(className, styles.root, THEME_STYLES[theme], SIZE_STYLES[size], MODE_STYLES[mode], isDisabled ? styles.disabled : styles.enabled, Boolean(error) && styles.error, isSearchable && styles.searchable),
54
- id: id,
55
- style: style,
56
- "data-test": "select"
57
- }, /*#__PURE__*/React.createElement(InnerSingleComponent, { ...restProps,
58
- options: options,
59
- size: size,
60
- mode: mode,
116
+ const dropdownRef = useRef(null);
117
+ const highlightedItemRef = /*#__PURE__*/React.createRef();
118
+ const [isKeyboardNavigating, setIsKeyboardNavigating] = useState(false);
119
+ const skipScrollingRef = useRef(false);
120
+ const [searchString, setSearchString] = useState('');
121
+ const groups = useStrongMemo(() => convertToOptionGroupsIfNeeded(options), [options]);
122
+ const filteredGroups = useStrongMemo(() => {
123
+ if (searchString === '') {
124
+ return groups;
125
+ }
126
+
127
+ const filter = new RegExp(`(?:^|\\s)${escapeRegex(searchString)}`, 'i');
128
+ return groups.map(g => ({ ...g,
129
+ options: g.options.filter(_ref3 => {
130
+ let {
131
+ label
132
+ } = _ref3;
133
+ return filter.test(getTextFromNodes(label));
134
+ })
135
+ }));
136
+ }, [searchString, groups]);
137
+ const [menuIsOpen, setMenuIsOpen] = useState(false);
138
+ const [cursorIndex, setCursorIndex] = useState(() => getDefaultCursorIndex(filteredGroups));
139
+ useEffect(() => {
140
+ setCursorIndex(getDefaultCursorIndex(filteredGroups));
141
+
142
+ if (searchString !== '') {
143
+ setMenuIsOpen(true);
144
+ }
145
+ }, [searchString, filteredGroups]);
146
+ const isEmptyMenu = useMemo(() => isGroupsEmpty(filteredGroups), [filteredGroups]);
147
+ const handleSelectIndex = useCallback(index => {
148
+ const [grpIndex, optIndex] = index;
149
+ const selectedOption = filteredGroups[grpIndex].options[optIndex];
150
+ setMenuIsOpen(false);
151
+ setSearchString('');
152
+ setIsKeyboardNavigating(false);
153
+
154
+ if (onChange) {
155
+ onChange(selectedOption);
156
+ }
157
+ }, [onChange, filteredGroups]);
158
+ useEffect(() => {
159
+ if (dropdownRef.current) {
160
+ dropdownRef.current.scheduleUpdate();
161
+ }
162
+ }, [searchString]);
163
+ const handleMouseMove = useCallback(() => setIsKeyboardNavigating(false), []);
164
+ useEffect(() => {
165
+ if (isKeyboardNavigating) {
166
+ document.addEventListener('mousemove', handleMouseMove);
167
+ }
168
+
169
+ return () => document.removeEventListener('mousemove', handleMouseMove);
170
+ }, [handleMouseMove, isKeyboardNavigating]);
171
+ useEffect(() => {
172
+ if (isKeyboardNavigating && highlightedItemRef.current) {
173
+ if (skipScrollingRef.current) {
174
+ skipScrollingRef.current = false;
175
+ } else {
176
+ let elementToScrollTo = highlightedItemRef.current;
177
+
178
+ if (cursorIndex[0] === 0 && cursorIndex[1] === 0) {
179
+ const groupHeader = highlightedItemRef.current.previousSibling;
180
+
181
+ if (groupHeader) {
182
+ elementToScrollTo = groupHeader;
183
+ }
184
+ }
185
+
186
+ scrollIntoView(elementToScrollTo, {
187
+ behavior: 'instant',
188
+ scrollMode: 'if-needed',
189
+ block: 'nearest',
190
+ inline: 'nearest'
191
+ });
192
+ }
193
+ }
194
+ }, [highlightedItemRef, cursorIndex, isKeyboardNavigating]);
195
+ const handleClose = useCallback(() => {
196
+ setSearchString('');
197
+ setMenuIsOpen(false);
198
+ setIsKeyboardNavigating(false);
199
+ }, []);
200
+ const handleKeyNavigation = useCallback( // eslint-disable-next-line complexity
201
+ e => {
202
+ if (e.key === ARROW_DOWN || e.key === ARROW_UP) {
203
+ const isDownDirection = e.key === ARROW_DOWN;
204
+ setCursorIndex(getMovedCursorIndex(filteredGroups, cursorIndex, isDownDirection));
205
+ setIsKeyboardNavigating(true);
206
+ e.preventDefault();
207
+ }
208
+
209
+ if (e.key === ENTER || !isSearchable && e.key === SPACE) {
210
+ if (cursorIndex !== null) {
211
+ handleSelectIndex(cursorIndex);
212
+ } else {
213
+ handleClose();
214
+ }
215
+
216
+ e.preventDefault();
217
+ }
218
+
219
+ if (e.key === TAB) {
220
+ handleClose();
221
+ }
222
+ }, [filteredGroups, cursorIndex, handleClose, handleSelectIndex, isSearchable]);
223
+ const handleClick = useCallback(() => {
224
+ if (isDisabled) {
225
+ return;
226
+ }
227
+
228
+ setMenuIsOpen(currentMenuIsOpen => !currentMenuIsOpen);
229
+ setSearchString('');
230
+ }, [isDisabled]);
231
+ const handleSearchInputChange = useCallback(searchValue => setSearchString(searchValue), []);
232
+ const handleClearClick = useCallback(() => {
233
+ setCursorIndex(getDefaultCursorIndex(filteredGroups));
234
+ setMenuIsOpen(false);
235
+
236
+ if (onChange) {
237
+ onChange(null);
238
+ }
239
+ }, [filteredGroups, onChange]);
240
+ const handleTriggerKeyDown = useCallback(e => {
241
+ if (e.key === ESCAPE) {
242
+ handleClose();
243
+ e.preventDefault();
244
+ }
245
+
246
+ if (isDisabled) {
247
+ return;
248
+ }
249
+
250
+ if (menuIsOpen) {
251
+ handleKeyNavigation(e);
252
+ } else {
253
+ const target = e.target;
254
+ const trigger = target.closest('[data-target="trigger"]');
255
+ const isTriggerTarget = trigger === target;
256
+
257
+ if (shouldOpenSelect(e.key, isTriggerTarget)) {
258
+ setMenuIsOpen(true);
259
+ setSearchString('');
260
+ setIsKeyboardNavigating(true);
261
+ skipScrollingRef.current = true;
262
+ trigger.focus();
263
+ e.preventDefault();
264
+ }
265
+
266
+ if (e.key === BACKSPACE && isClearable) {
267
+ handleClearClick();
268
+ trigger.focus();
269
+ e.preventDefault();
270
+ }
271
+ }
272
+ }, [menuIsOpen, isDisabled, isClearable, handleClose, handleClearClick, handleKeyNavigation]);
273
+ const handleHighlightIndex = useCallback(index => {
274
+ if (!isIndexMatchCursor(cursorIndex, index)) {
275
+ setCursorIndex(index);
276
+ }
277
+ }, [cursorIndex]); // We use invisible and "untouchable" dummy element to observe `size` changes from css to trigger force rerenders
278
+
279
+ const observableRef = useObservableForceRerender();
280
+ let sizeFromCss = null;
281
+
282
+ if (triggerFormWrapperRef && menuIsOpen) {
283
+ var _context;
284
+
285
+ // In theory this part of the code might cause issues with SSR.
286
+ // But in this specific context, because of checking ref "triggerFormWrapperRef",
287
+ // we are sure that the value will still be "null" on the first render.
288
+ // Therefore, the first render on the client will be the same as on the server.
289
+ // Also, there will be no layout shifts on the following renders because
290
+ // it's a dropdown-content and in most cases it opens only on-demand.
291
+ // In additional, we use "observable" el to watch size changes between rerenders (@media query case).
292
+ const triggerFormWrapperStyles = getComputedStyle(triggerFormWrapperRef);
293
+ const rawSizeFromCss = triggerFormWrapperStyles.getPropertyValue('--_rs-select-size');
294
+ sizeFromCss = _includesInstanceProperty(_context = ['s', 'm', 'l']).call(_context, rawSizeFromCss) ? rawSizeFromCss : null;
295
+ }
296
+
297
+ const actualSize = sizeFromCss || size;
298
+ const maxHeight = calculateMaxHeight(actualSize);
299
+ const withGroupsLabel = !withoutGroupsLabel(filteredGroups);
300
+ const uniqueId = `select-${useBackwardCompatibleId()}`;
301
+ const errorId = `${id ? id : uniqueId}-error`;
302
+ return /*#__PURE__*/React.createElement(Dropdown, {
61
303
  theme: theme,
62
- className: className,
63
- id: id,
64
- style: style,
65
- value: value,
66
- onChange: onChange,
67
- placeholder: placeholder,
68
- isClearable: isClearable,
69
- isLoading: isLoading,
70
- isDisabled: isDisabled,
71
- noOptionsMessage: noOptionsMessage,
72
- error: error,
304
+ onRequestClose: handleClose,
73
305
  placement: placement,
74
- boldLabel: boldLabel,
75
- reserveErrorLine: reserveErrorLine,
76
- note: note,
77
- maxVisibleItems: maxVisibleItems
78
- }));
306
+ mode: mode,
307
+ ref: dropdownRef,
308
+ cancelCloseAnimation: true,
309
+ minWidth: "trigger",
310
+ maxWidth: "trigger",
311
+ maxHeight: maxHeight,
312
+ leastMaxHeight: maxHeight,
313
+ disableFocusLock: true,
314
+ trigger: _ref4 => {
315
+ let {
316
+ ref
317
+ } = _ref4;
318
+ return /*#__PURE__*/React.createElement(FormTriggerWrapper, {
319
+ ref: setTriggerFormWrapperRef,
320
+ className: cn(className, SIZE_STYLES[size]),
321
+ id: id,
322
+ errorId: errorId,
323
+ theme: theme,
324
+ size: size,
325
+ disabled: isDisabled,
326
+ error: error,
327
+ reserveErrorLine: reserveErrorLine,
328
+ label: restProps.label,
329
+ note: restProps.note,
330
+ onKeyDown: handleTriggerKeyDown,
331
+ boldLabel: boldLabel,
332
+ role: "listbox",
333
+ "aria-errormessage": error ? errorId : undefined,
334
+ "aria-invalid": Boolean(error)
335
+ }, /*#__PURE__*/React.createElement("div", {
336
+ ref: observableRef,
337
+ className: styles.observable
338
+ }), restProps.name && /*#__PURE__*/React.createElement("input", {
339
+ type: "hidden",
340
+ name: restProps.name,
341
+ value: value && value.value || ''
342
+ }), /*#__PURE__*/React.createElement(SelectTrigger, {
343
+ theme: theme,
344
+ mode: mode,
345
+ size: size,
346
+ isOpen: menuIsOpen,
347
+ triggerRef: ref,
348
+ selected: value,
349
+ placeholder: placeholder,
350
+ isClearable: isClearable,
351
+ isLoading: isLoading,
352
+ isDisabled: isDisabled,
353
+ searchInput: searchString,
354
+ isSearchable: isSearchable,
355
+ onSearchChange: handleSearchInputChange,
356
+ onClick: handleClick,
357
+ onClearClick: handleClearClick,
358
+ error: Boolean(error),
359
+ "data-target": "trigger"
360
+ }));
361
+ },
362
+ isOpen: menuIsOpen
363
+ }, /*#__PURE__*/React.createElement(Menu, {
364
+ size: actualSize,
365
+ disableCursor: isKeyboardNavigating,
366
+ className: cn(styles.menu, withGroupsLabel && styles.withGroupsLabel, MENU_SIZE_STYLES[actualSize]),
367
+ enableKeyboardNavigation: false
368
+ }, !isEmptyMenu ? getPlainOptionsFromGroups(filteredGroups).map((item, i, collection) => /*#__PURE__*/React.createElement(Option, {
369
+ item: item,
370
+ isLastItem: i === collection.length - 1,
371
+ key: getOptionKey(item, i),
372
+ selected: value,
373
+ cursorIndex: cursorIndex,
374
+ highlightedItemRef: highlightedItemRef,
375
+ handleSelectIndex: handleSelectIndex,
376
+ handleHighlightIndex: handleHighlightIndex
377
+ })) : /*#__PURE__*/React.createElement(MenuItem, {
378
+ disabled: true
379
+ }, getEmptyMessage(isLoading, isSearchable && searchString.length > 0, noOptionsMessage))));
79
380
  };
80
381
 
81
382
  Select.propTypes = {
82
383
  className: PropTypes.string,
83
- style: PropTypes.object,
84
384
  options: PropTypes.oneOfType([PropTypes.arrayOf(optionType), PropTypes.arrayOf(optionsGroupType)]),
85
385
  value: optionType,
86
386
  onChange: PropTypes.func,
@@ -96,8 +396,8 @@ Select.propTypes = {
96
396
  label: PropTypes.node,
97
397
  id: PropTypes.string,
98
398
  note: PropTypes.node,
99
- noOptionsMessage: noOptionsMessageType,
399
+ noOptionsMessage: PropTypes.oneOfType([PropTypes.string, noOptionsMessageConfigType]),
100
400
  placement: PropTypes.oneOf(['auto-start', 'auto', 'auto-end', 'top-start', 'top', 'top-end', 'right-start', 'right', 'right-end', 'bottom-end', 'bottom', 'bottom-start', 'left-end', 'left', 'left-start']),
101
401
  name: PropTypes.string
102
402
  };
103
- export { Select };
403
+ export { Select as default };