@atlaskit/react-select 0.0.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 (197) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/LICENSE.md +11 -0
  3. package/README.md +10 -0
  4. package/async/package.json +15 -0
  5. package/base/package.json +15 -0
  6. package/creatable/package.json +15 -0
  7. package/dist/cjs/accessibility/helpers.js +34 -0
  8. package/dist/cjs/accessibility/index.js +74 -0
  9. package/dist/cjs/async-creatable.js +27 -0
  10. package/dist/cjs/async.js +30 -0
  11. package/dist/cjs/builtins.js +18 -0
  12. package/dist/cjs/components/containers.js +100 -0
  13. package/dist/cjs/components/control.js +67 -0
  14. package/dist/cjs/components/group.js +79 -0
  15. package/dist/cjs/components/index.js +53 -0
  16. package/dist/cjs/components/indicators.js +214 -0
  17. package/dist/cjs/components/input.js +93 -0
  18. package/dist/cjs/components/internal/a11y-text.js +34 -0
  19. package/dist/cjs/components/internal/dummy-input.js +43 -0
  20. package/dist/cjs/components/internal/index.js +34 -0
  21. package/dist/cjs/components/internal/required-input.js +43 -0
  22. package/dist/cjs/components/internal/scroll-manager.js +57 -0
  23. package/dist/cjs/components/internal/use-scroll-capture.js +132 -0
  24. package/dist/cjs/components/internal/use-scroll-lock.js +149 -0
  25. package/dist/cjs/components/live-region.js +153 -0
  26. package/dist/cjs/components/menu.js +464 -0
  27. package/dist/cjs/components/multi-value.js +129 -0
  28. package/dist/cjs/components/option.js +62 -0
  29. package/dist/cjs/components/placeholder.js +39 -0
  30. package/dist/cjs/components/single-value.js +46 -0
  31. package/dist/cjs/creatable.js +30 -0
  32. package/dist/cjs/diacritics.js +274 -0
  33. package/dist/cjs/filters.js +50 -0
  34. package/dist/cjs/index.js +55 -0
  35. package/dist/cjs/nonce-provider.js +30 -0
  36. package/dist/cjs/select.js +1803 -0
  37. package/dist/cjs/state-manager.js +31 -0
  38. package/dist/cjs/styles.js +66 -0
  39. package/dist/cjs/theme.js +42 -0
  40. package/dist/cjs/types.js +5 -0
  41. package/dist/cjs/use-async.js +156 -0
  42. package/dist/cjs/use-creatable.js +114 -0
  43. package/dist/cjs/use-state-manager.js +83 -0
  44. package/dist/cjs/utils.js +357 -0
  45. package/dist/es2019/accessibility/helpers.js +24 -0
  46. package/dist/es2019/accessibility/index.js +72 -0
  47. package/dist/es2019/async-creatable.js +17 -0
  48. package/dist/es2019/async.js +16 -0
  49. package/dist/es2019/builtins.js +4 -0
  50. package/dist/es2019/components/containers.js +100 -0
  51. package/dist/es2019/components/control.js +62 -0
  52. package/dist/es2019/components/group.js +74 -0
  53. package/dist/es2019/components/index.js +41 -0
  54. package/dist/es2019/components/indicators.js +211 -0
  55. package/dist/es2019/components/input.js +88 -0
  56. package/dist/es2019/components/internal/a11y-text.js +25 -0
  57. package/dist/es2019/components/internal/dummy-input.js +36 -0
  58. package/dist/es2019/components/internal/index.js +4 -0
  59. package/dist/es2019/components/internal/required-input.js +35 -0
  60. package/dist/es2019/components/internal/scroll-manager.js +49 -0
  61. package/dist/es2019/components/internal/use-scroll-capture.js +128 -0
  62. package/dist/es2019/components/internal/use-scroll-lock.js +143 -0
  63. package/dist/es2019/components/live-region.js +151 -0
  64. package/dist/es2019/components/menu.js +466 -0
  65. package/dist/es2019/components/multi-value.js +134 -0
  66. package/dist/es2019/components/option.js +57 -0
  67. package/dist/es2019/components/placeholder.js +34 -0
  68. package/dist/es2019/components/single-value.js +41 -0
  69. package/dist/es2019/creatable.js +15 -0
  70. package/dist/es2019/diacritics.js +264 -0
  71. package/dist/es2019/filters.js +36 -0
  72. package/dist/es2019/index.js +8 -0
  73. package/dist/es2019/nonce-provider.js +19 -0
  74. package/dist/es2019/select.js +1766 -0
  75. package/dist/es2019/state-manager.js +22 -0
  76. package/dist/es2019/styles.js +56 -0
  77. package/dist/es2019/theme.js +36 -0
  78. package/dist/es2019/types.js +1 -0
  79. package/dist/es2019/use-async.js +117 -0
  80. package/dist/es2019/use-creatable.js +81 -0
  81. package/dist/es2019/use-state-manager.js +60 -0
  82. package/dist/es2019/utils.js +309 -0
  83. package/dist/esm/accessibility/helpers.js +24 -0
  84. package/dist/esm/accessibility/index.js +68 -0
  85. package/dist/esm/async-creatable.js +17 -0
  86. package/dist/esm/async.js +16 -0
  87. package/dist/esm/builtins.js +12 -0
  88. package/dist/esm/components/containers.js +96 -0
  89. package/dist/esm/components/control.js +62 -0
  90. package/dist/esm/components/group.js +74 -0
  91. package/dist/esm/components/index.js +43 -0
  92. package/dist/esm/components/indicators.js +209 -0
  93. package/dist/esm/components/input.js +88 -0
  94. package/dist/esm/components/internal/a11y-text.js +27 -0
  95. package/dist/esm/components/internal/dummy-input.js +37 -0
  96. package/dist/esm/components/internal/index.js +4 -0
  97. package/dist/esm/components/internal/required-input.js +36 -0
  98. package/dist/esm/components/internal/scroll-manager.js +49 -0
  99. package/dist/esm/components/internal/use-scroll-capture.js +126 -0
  100. package/dist/esm/components/internal/use-scroll-lock.js +143 -0
  101. package/dist/esm/components/live-region.js +148 -0
  102. package/dist/esm/components/menu.js +460 -0
  103. package/dist/esm/components/multi-value.js +122 -0
  104. package/dist/esm/components/option.js +57 -0
  105. package/dist/esm/components/placeholder.js +34 -0
  106. package/dist/esm/components/single-value.js +41 -0
  107. package/dist/esm/creatable.js +15 -0
  108. package/dist/esm/diacritics.js +268 -0
  109. package/dist/esm/filters.js +43 -0
  110. package/dist/esm/index.js +8 -0
  111. package/dist/esm/nonce-provider.js +20 -0
  112. package/dist/esm/select.js +1794 -0
  113. package/dist/esm/state-manager.js +22 -0
  114. package/dist/esm/styles.js +58 -0
  115. package/dist/esm/theme.js +36 -0
  116. package/dist/esm/types.js +1 -0
  117. package/dist/esm/use-async.js +149 -0
  118. package/dist/esm/use-creatable.js +107 -0
  119. package/dist/esm/use-state-manager.js +76 -0
  120. package/dist/esm/utils.js +328 -0
  121. package/dist/types/accessibility/helpers.d.ts +5 -0
  122. package/dist/types/accessibility/index.d.ts +125 -0
  123. package/dist/types/async-creatable.d.ts +10 -0
  124. package/dist/types/async.d.ts +9 -0
  125. package/dist/types/builtins.d.ts +5 -0
  126. package/dist/types/components/containers.d.ts +50 -0
  127. package/dist/types/components/control.d.ts +33 -0
  128. package/dist/types/components/group.d.ts +53 -0
  129. package/dist/types/components/index.d.ts +73 -0
  130. package/dist/types/components/indicators.d.ts +72 -0
  131. package/dist/types/components/input.d.ts +33 -0
  132. package/dist/types/components/internal/a11y-text.d.ts +8 -0
  133. package/dist/types/components/internal/dummy-input.d.ts +9 -0
  134. package/dist/types/components/internal/index.d.ts +4 -0
  135. package/dist/types/components/internal/required-input.d.ts +10 -0
  136. package/dist/types/components/internal/scroll-manager.d.ts +17 -0
  137. package/dist/types/components/internal/use-scroll-capture.d.ts +12 -0
  138. package/dist/types/components/internal/use-scroll-lock.d.ts +9 -0
  139. package/dist/types/components/live-region.d.ts +24 -0
  140. package/dist/types/components/menu.d.ts +130 -0
  141. package/dist/types/components/multi-value.d.ts +47 -0
  142. package/dist/types/components/option.d.ts +49 -0
  143. package/dist/types/components/placeholder.d.ts +22 -0
  144. package/dist/types/components/single-value.d.ts +28 -0
  145. package/dist/types/creatable.d.ts +10 -0
  146. package/dist/types/diacritics.d.ts +1 -0
  147. package/dist/types/filters.d.ts +15 -0
  148. package/dist/types/index.d.ts +28 -0
  149. package/dist/types/nonce-provider.d.ts +8 -0
  150. package/dist/types/select.d.ts +616 -0
  151. package/dist/types/state-manager.d.ts +17 -0
  152. package/dist/types/styles.d.ts +68 -0
  153. package/dist/types/theme.d.ts +27 -0
  154. package/dist/types/types.d.ts +134 -0
  155. package/dist/types/use-async.d.ts +31 -0
  156. package/dist/types/use-creatable.d.ts +46 -0
  157. package/dist/types/use-state-manager.d.ts +15 -0
  158. package/dist/types/utils.d.ts +44 -0
  159. package/dist/types-ts4.5/accessibility/helpers.d.ts +5 -0
  160. package/dist/types-ts4.5/accessibility/index.d.ts +125 -0
  161. package/dist/types-ts4.5/async-creatable.d.ts +10 -0
  162. package/dist/types-ts4.5/async.d.ts +9 -0
  163. package/dist/types-ts4.5/builtins.d.ts +5 -0
  164. package/dist/types-ts4.5/components/containers.d.ts +50 -0
  165. package/dist/types-ts4.5/components/control.d.ts +33 -0
  166. package/dist/types-ts4.5/components/group.d.ts +53 -0
  167. package/dist/types-ts4.5/components/index.d.ts +73 -0
  168. package/dist/types-ts4.5/components/indicators.d.ts +72 -0
  169. package/dist/types-ts4.5/components/input.d.ts +33 -0
  170. package/dist/types-ts4.5/components/internal/a11y-text.d.ts +8 -0
  171. package/dist/types-ts4.5/components/internal/dummy-input.d.ts +9 -0
  172. package/dist/types-ts4.5/components/internal/index.d.ts +4 -0
  173. package/dist/types-ts4.5/components/internal/required-input.d.ts +10 -0
  174. package/dist/types-ts4.5/components/internal/scroll-manager.d.ts +17 -0
  175. package/dist/types-ts4.5/components/internal/use-scroll-capture.d.ts +12 -0
  176. package/dist/types-ts4.5/components/internal/use-scroll-lock.d.ts +9 -0
  177. package/dist/types-ts4.5/components/live-region.d.ts +24 -0
  178. package/dist/types-ts4.5/components/menu.d.ts +130 -0
  179. package/dist/types-ts4.5/components/multi-value.d.ts +47 -0
  180. package/dist/types-ts4.5/components/option.d.ts +49 -0
  181. package/dist/types-ts4.5/components/placeholder.d.ts +22 -0
  182. package/dist/types-ts4.5/components/single-value.d.ts +28 -0
  183. package/dist/types-ts4.5/creatable.d.ts +10 -0
  184. package/dist/types-ts4.5/diacritics.d.ts +1 -0
  185. package/dist/types-ts4.5/filters.d.ts +15 -0
  186. package/dist/types-ts4.5/index.d.ts +28 -0
  187. package/dist/types-ts4.5/nonce-provider.d.ts +8 -0
  188. package/dist/types-ts4.5/select.d.ts +616 -0
  189. package/dist/types-ts4.5/state-manager.d.ts +17 -0
  190. package/dist/types-ts4.5/styles.d.ts +68 -0
  191. package/dist/types-ts4.5/theme.d.ts +27 -0
  192. package/dist/types-ts4.5/types.d.ts +134 -0
  193. package/dist/types-ts4.5/use-async.d.ts +31 -0
  194. package/dist/types-ts4.5/use-creatable.d.ts +46 -0
  195. package/dist/types-ts4.5/use-state-manager.d.ts +15 -0
  196. package/dist/types-ts4.5/utils.d.ts +44 -0
  197. package/package.json +83 -0
@@ -0,0 +1,1766 @@
1
+ import _extends from "@babel/runtime/helpers/extends";
2
+ import _defineProperty from "@babel/runtime/helpers/defineProperty";
3
+ import React, { Component } from 'react';
4
+ import { isAppleDevice } from './accessibility/helpers';
5
+ import { formatGroupLabel as formatGroupLabelBuiltin, getOptionLabel as getOptionLabelBuiltin, getOptionValue as getOptionValueBuiltin, isOptionDisabled as isOptionDisabledBuiltin } from './builtins';
6
+ import { defaultComponents } from './components';
7
+ import { DummyInput, RequiredInput, ScrollManager } from './components/internal';
8
+ import LiveRegion from './components/live-region';
9
+ import { MenuPlacer } from './components/menu';
10
+ import { createFilter } from './filters';
11
+ import { defaultStyles } from './styles';
12
+ import { defaultTheme } from './theme';
13
+ import { classNames, cleanValue, isDocumentElement, isMobileDevice, isTouchCapable, multiValueAsValue, noop, notNullish, scrollIntoView, singleValueAsValue, valueTernary } from './utils';
14
+ export const defaultProps = {
15
+ 'aria-live': 'polite',
16
+ backspaceRemovesValue: true,
17
+ blurInputOnSelect: isTouchCapable(),
18
+ captureMenuScroll: !isTouchCapable(),
19
+ classNames: {},
20
+ closeMenuOnSelect: true,
21
+ closeMenuOnScroll: false,
22
+ components: {},
23
+ controlShouldRenderValue: true,
24
+ escapeClearsValue: false,
25
+ filterOption: createFilter(),
26
+ formatGroupLabel: formatGroupLabelBuiltin,
27
+ getOptionLabel: getOptionLabelBuiltin,
28
+ getOptionValue: getOptionValueBuiltin,
29
+ isDisabled: false,
30
+ isLoading: false,
31
+ isMulti: false,
32
+ isRtl: false,
33
+ isSearchable: true,
34
+ isOptionDisabled: isOptionDisabledBuiltin,
35
+ loadingMessage: () => 'Loading...',
36
+ maxMenuHeight: 300,
37
+ minMenuHeight: 140,
38
+ menuIsOpen: false,
39
+ menuPlacement: 'bottom',
40
+ menuPosition: 'absolute',
41
+ menuShouldBlockScroll: false,
42
+ menuShouldScrollIntoView: !isMobileDevice(),
43
+ noOptionsMessage: () => 'No options',
44
+ openMenuOnFocus: false,
45
+ openMenuOnClick: true,
46
+ options: [],
47
+ pageSize: 5,
48
+ placeholder: 'Select...',
49
+ screenReaderStatus: ({
50
+ count
51
+ }) => `${count} result${count !== 1 ? 's' : ''} available`,
52
+ styles: {},
53
+ tabIndex: 0,
54
+ tabSelectsValue: true,
55
+ unstyled: false
56
+ };
57
+ function toCategorizedOption(props, option, selectValue, index) {
58
+ const isDisabled = isOptionDisabled(props, option, selectValue);
59
+ const isSelected = isOptionSelected(props, option, selectValue);
60
+ const label = getOptionLabel(props, option);
61
+ const value = getOptionValue(props, option);
62
+ return {
63
+ type: 'option',
64
+ data: option,
65
+ isDisabled,
66
+ isSelected,
67
+ label,
68
+ value,
69
+ index
70
+ };
71
+ }
72
+ function buildCategorizedOptions(props, selectValue) {
73
+ return props.options.map((groupOrOption, groupOrOptionIndex) => {
74
+ //@ts-ignore
75
+ if ('options' in groupOrOption) {
76
+ const categorizedOptions = groupOrOption.options.map((option, optionIndex) => toCategorizedOption(props, option, selectValue, optionIndex)).filter(categorizedOption => isFocusable(props, categorizedOption));
77
+ return categorizedOptions.length > 0 ? {
78
+ type: 'group',
79
+ data: groupOrOption,
80
+ options: categorizedOptions,
81
+ index: groupOrOptionIndex
82
+ } : undefined;
83
+ }
84
+ const categorizedOption = toCategorizedOption(props, groupOrOption, selectValue, groupOrOptionIndex);
85
+ return isFocusable(props, categorizedOption) ? categorizedOption : undefined;
86
+ }).filter(notNullish);
87
+ }
88
+ function buildFocusableOptionsFromCategorizedOptions(categorizedOptions) {
89
+ return categorizedOptions.reduce((optionsAccumulator, categorizedOption) => {
90
+ if (categorizedOption.type === 'group') {
91
+ optionsAccumulator.push(...categorizedOption.options.map(option => option.data));
92
+ } else {
93
+ optionsAccumulator.push(categorizedOption.data);
94
+ }
95
+ return optionsAccumulator;
96
+ }, []);
97
+ }
98
+ function buildFocusableOptionsWithIds(categorizedOptions, optionId) {
99
+ return categorizedOptions.reduce((optionsAccumulator, categorizedOption) => {
100
+ if (categorizedOption.type === 'group') {
101
+ optionsAccumulator.push(...categorizedOption.options.map(option => ({
102
+ data: option.data,
103
+ id: `${optionId}-${categorizedOption.index}-${option.index}`
104
+ })));
105
+ } else {
106
+ optionsAccumulator.push({
107
+ data: categorizedOption.data,
108
+ id: `${optionId}-${categorizedOption.index}`
109
+ });
110
+ }
111
+ return optionsAccumulator;
112
+ }, []);
113
+ }
114
+ function buildFocusableOptions(props, selectValue) {
115
+ return buildFocusableOptionsFromCategorizedOptions(buildCategorizedOptions(props, selectValue));
116
+ }
117
+ function isFocusable(props, categorizedOption) {
118
+ const {
119
+ inputValue = ''
120
+ } = props;
121
+ const {
122
+ data,
123
+ isSelected,
124
+ label,
125
+ value
126
+ } = categorizedOption;
127
+ return (!shouldHideSelectedOptions(props) || !isSelected) && filterOption(props, {
128
+ label,
129
+ value,
130
+ data
131
+ }, inputValue);
132
+ }
133
+ function getNextFocusedValue(state, nextSelectValue) {
134
+ const {
135
+ focusedValue,
136
+ selectValue: lastSelectValue
137
+ } = state;
138
+ const lastFocusedIndex = lastSelectValue.indexOf(focusedValue);
139
+ if (lastFocusedIndex > -1) {
140
+ const nextFocusedIndex = nextSelectValue.indexOf(focusedValue);
141
+ if (nextFocusedIndex > -1) {
142
+ // the focused value is still in the selectValue, return it
143
+ return focusedValue;
144
+ } else if (lastFocusedIndex < nextSelectValue.length) {
145
+ // the focusedValue is not present in the next selectValue array by
146
+ // reference, so return the new value at the same index
147
+ return nextSelectValue[lastFocusedIndex];
148
+ }
149
+ }
150
+ return null;
151
+ }
152
+ function getNextFocusedOption(state, options) {
153
+ const {
154
+ focusedOption: lastFocusedOption
155
+ } = state;
156
+ return lastFocusedOption && options.indexOf(lastFocusedOption) > -1 ? lastFocusedOption : options[0];
157
+ }
158
+ const getFocusedOptionId = (focusableOptionsWithIds, focusedOption) => {
159
+ var _focusableOptionsWith;
160
+ const focusedOptionId = (_focusableOptionsWith = focusableOptionsWithIds.find(option => option.data === focusedOption)) === null || _focusableOptionsWith === void 0 ? void 0 : _focusableOptionsWith.id;
161
+ return focusedOptionId || null;
162
+ };
163
+ const getOptionLabel = (props, data) => {
164
+ return props.getOptionLabel(data);
165
+ };
166
+ const getOptionValue = (props, data) => {
167
+ return props.getOptionValue(data);
168
+ };
169
+ function isOptionDisabled(props, option, selectValue) {
170
+ return typeof props.isOptionDisabled === 'function' ? props.isOptionDisabled(option, selectValue) : false;
171
+ }
172
+ function isOptionSelected(props, option, selectValue) {
173
+ if (selectValue.indexOf(option) > -1) {
174
+ return true;
175
+ }
176
+ if (typeof props.isOptionSelected === 'function') {
177
+ return props.isOptionSelected(option, selectValue);
178
+ }
179
+ const candidate = getOptionValue(props, option);
180
+ return selectValue.some(i => getOptionValue(props, i) === candidate);
181
+ }
182
+ function filterOption(props, option, inputValue) {
183
+ return props.filterOption ? props.filterOption(option, inputValue) : true;
184
+ }
185
+ const shouldHideSelectedOptions = props => {
186
+ const {
187
+ hideSelectedOptions,
188
+ isMulti
189
+ } = props;
190
+ if (hideSelectedOptions === undefined) {
191
+ return isMulti;
192
+ }
193
+ return hideSelectedOptions;
194
+ };
195
+ let instanceId = 1;
196
+
197
+ // eslint-disable-next-line @repo/internal/react/no-class-components
198
+ export default class Select extends Component {
199
+ // Lifecycle
200
+ // ------------------------------
201
+
202
+ constructor(_props) {
203
+ super(_props);
204
+ _defineProperty(this, "state", {
205
+ ariaSelection: null,
206
+ focusedOption: null,
207
+ focusedOptionId: null,
208
+ focusableOptionsWithIds: [],
209
+ focusedValue: null,
210
+ inputIsHidden: false,
211
+ isFocused: false,
212
+ selectValue: [],
213
+ clearFocusValueOnUpdate: false,
214
+ prevWasFocused: false,
215
+ inputIsHiddenAfterUpdate: undefined,
216
+ prevProps: undefined,
217
+ instancePrefix: ''
218
+ });
219
+ // Misc. Instance Properties
220
+ // ------------------------------
221
+ _defineProperty(this, "blockOptionHover", false);
222
+ _defineProperty(this, "isComposing", false);
223
+ // TODO
224
+ _defineProperty(this, "initialTouchX", 0);
225
+ _defineProperty(this, "initialTouchY", 0);
226
+ _defineProperty(this, "openAfterFocus", false);
227
+ _defineProperty(this, "scrollToFocusedOptionOnUpdate", false);
228
+ _defineProperty(this, "isAppleDevice", isAppleDevice());
229
+ // Refs
230
+ // ------------------------------
231
+ _defineProperty(this, "controlRef", null);
232
+ _defineProperty(this, "getControlRef", ref => {
233
+ this.controlRef = ref;
234
+ });
235
+ _defineProperty(this, "focusedOptionRef", null);
236
+ _defineProperty(this, "getFocusedOptionRef", ref => {
237
+ this.focusedOptionRef = ref;
238
+ });
239
+ _defineProperty(this, "menuListRef", null);
240
+ _defineProperty(this, "getMenuListRef", ref => {
241
+ this.menuListRef = ref;
242
+ });
243
+ _defineProperty(this, "inputRef", null);
244
+ _defineProperty(this, "getInputRef", ref => {
245
+ this.inputRef = ref;
246
+ });
247
+ // aliased for consumers
248
+ _defineProperty(this, "focus", this.focusInput);
249
+ _defineProperty(this, "blur", this.blurInput);
250
+ _defineProperty(this, "onChange", (newValue, actionMeta) => {
251
+ const {
252
+ onChange,
253
+ name
254
+ } = this.props;
255
+ actionMeta.name = name;
256
+ this.ariaOnChange(newValue, actionMeta);
257
+ onChange(newValue, actionMeta);
258
+ });
259
+ _defineProperty(this, "setValue", (newValue, action, option) => {
260
+ const {
261
+ closeMenuOnSelect,
262
+ isMulti,
263
+ inputValue
264
+ } = this.props;
265
+ this.onInputChange('', {
266
+ action: 'set-value',
267
+ prevInputValue: inputValue
268
+ });
269
+ if (closeMenuOnSelect) {
270
+ this.setState({
271
+ inputIsHiddenAfterUpdate: !isMulti
272
+ });
273
+ this.onMenuClose();
274
+ }
275
+ // when the select value should change, we should reset focusedValue
276
+ this.setState({
277
+ clearFocusValueOnUpdate: true
278
+ });
279
+ this.onChange(newValue, {
280
+ action,
281
+ option
282
+ });
283
+ });
284
+ _defineProperty(this, "selectOption", newValue => {
285
+ const {
286
+ blurInputOnSelect,
287
+ isMulti,
288
+ name
289
+ } = this.props;
290
+ const {
291
+ selectValue
292
+ } = this.state;
293
+ const deselected = isMulti && this.isOptionSelected(newValue, selectValue);
294
+ const isDisabled = this.isOptionDisabled(newValue, selectValue);
295
+ if (deselected) {
296
+ const candidate = this.getOptionValue(newValue);
297
+ this.setValue(multiValueAsValue(selectValue.filter(i => this.getOptionValue(i) !== candidate)), 'deselect-option', newValue);
298
+ } else if (!isDisabled) {
299
+ // Select option if option is not disabled
300
+ if (isMulti) {
301
+ this.setValue(multiValueAsValue([...selectValue, newValue]), 'select-option', newValue);
302
+ } else {
303
+ this.setValue(singleValueAsValue(newValue), 'select-option');
304
+ }
305
+ } else {
306
+ this.ariaOnChange(singleValueAsValue(newValue), {
307
+ action: 'select-option',
308
+ option: newValue,
309
+ name
310
+ });
311
+ return;
312
+ }
313
+ if (blurInputOnSelect) {
314
+ this.blurInput();
315
+ }
316
+ });
317
+ _defineProperty(this, "removeValue", removedValue => {
318
+ const {
319
+ isMulti
320
+ } = this.props;
321
+ const {
322
+ selectValue
323
+ } = this.state;
324
+ const candidate = this.getOptionValue(removedValue);
325
+ const newValueArray = selectValue.filter(i => this.getOptionValue(i) !== candidate);
326
+ const newValue = valueTernary(isMulti, newValueArray, newValueArray[0] || null);
327
+ this.onChange(newValue, {
328
+ action: 'remove-value',
329
+ removedValue
330
+ });
331
+ this.focusInput();
332
+ });
333
+ _defineProperty(this, "clearValue", () => {
334
+ const {
335
+ selectValue
336
+ } = this.state;
337
+ this.onChange(valueTernary(this.props.isMulti, [], null), {
338
+ action: 'clear',
339
+ removedValues: selectValue
340
+ });
341
+ });
342
+ _defineProperty(this, "popValue", () => {
343
+ const {
344
+ isMulti
345
+ } = this.props;
346
+ const {
347
+ selectValue
348
+ } = this.state;
349
+ const lastSelectedValue = selectValue[selectValue.length - 1];
350
+ const newValueArray = selectValue.slice(0, selectValue.length - 1);
351
+ const newValue = valueTernary(isMulti, newValueArray, newValueArray[0] || null);
352
+ this.onChange(newValue, {
353
+ action: 'pop-value',
354
+ removedValue: lastSelectedValue
355
+ });
356
+ });
357
+ _defineProperty(this, "getFocusedOptionId", focusedOption => {
358
+ return getFocusedOptionId(this.state.focusableOptionsWithIds, focusedOption);
359
+ });
360
+ _defineProperty(this, "getFocusableOptionsWithIds", () => {
361
+ return buildFocusableOptionsWithIds(buildCategorizedOptions(this.props, this.state.selectValue), this.getElementId('option'));
362
+ });
363
+ _defineProperty(this, "getValue", () => this.state.selectValue);
364
+ _defineProperty(this, "cx", (...args) => classNames(this.props.classNamePrefix, ...args));
365
+ _defineProperty(this, "getOptionLabel", data => {
366
+ return getOptionLabel(this.props, data);
367
+ });
368
+ _defineProperty(this, "getOptionValue", data => {
369
+ return getOptionValue(this.props, data);
370
+ });
371
+ _defineProperty(this, "getStyles", (key, props) => {
372
+ const {
373
+ unstyled
374
+ } = this.props;
375
+ const base = defaultStyles[key](props, unstyled);
376
+ base.boxSizing = 'border-box';
377
+ const custom = this.props.styles[key];
378
+ return custom ? custom(base, props) : base;
379
+ });
380
+ _defineProperty(this, "getClassNames", (key, props) => {
381
+ var _this$props$className, _this$props$className2;
382
+ return (_this$props$className = (_this$props$className2 = this.props.classNames)[key]) === null || _this$props$className === void 0 ? void 0 : _this$props$className.call(_this$props$className2, props);
383
+ });
384
+ _defineProperty(this, "getElementId", element => {
385
+ return `${this.state.instancePrefix}-${element}`;
386
+ });
387
+ _defineProperty(this, "getComponents", () => {
388
+ return defaultComponents(this.props);
389
+ });
390
+ _defineProperty(this, "buildCategorizedOptions", () => buildCategorizedOptions(this.props, this.state.selectValue));
391
+ _defineProperty(this, "getCategorizedOptions", () => this.props.menuIsOpen ? this.buildCategorizedOptions() : []);
392
+ _defineProperty(this, "buildFocusableOptions", () => buildFocusableOptionsFromCategorizedOptions(this.buildCategorizedOptions()));
393
+ _defineProperty(this, "getFocusableOptions", () => this.props.menuIsOpen ? this.buildFocusableOptions() : []);
394
+ // ==============================
395
+ // Helpers
396
+ // ==============================
397
+ _defineProperty(this, "ariaOnChange", (value, actionMeta) => {
398
+ this.setState({
399
+ ariaSelection: {
400
+ value,
401
+ ...actionMeta
402
+ }
403
+ });
404
+ });
405
+ // ==============================
406
+ // Mouse Handlers
407
+ // ==============================
408
+ _defineProperty(this, "onMenuMouseDown", event => {
409
+ if (event.button !== 0) {
410
+ return;
411
+ }
412
+ event.stopPropagation();
413
+ event.preventDefault();
414
+ this.focusInput();
415
+ });
416
+ _defineProperty(this, "onMenuMouseMove", event => {
417
+ this.blockOptionHover = false;
418
+ });
419
+ _defineProperty(this, "onControlMouseDown", event => {
420
+ // Event captured by dropdown indicator
421
+ if (event.defaultPrevented) {
422
+ return;
423
+ }
424
+ const {
425
+ openMenuOnClick
426
+ } = this.props;
427
+ if (!this.state.isFocused) {
428
+ if (openMenuOnClick) {
429
+ this.openAfterFocus = true;
430
+ }
431
+ this.focusInput();
432
+ } else if (!this.props.menuIsOpen) {
433
+ if (openMenuOnClick) {
434
+ this.openMenu('first');
435
+ }
436
+ } else {
437
+ if (event.target.tagName !== 'INPUT' && event.target.tagName !== 'TEXTAREA') {
438
+ this.onMenuClose();
439
+ }
440
+ }
441
+ if (event.target.tagName !== 'INPUT' && event.target.tagName !== 'TEXTAREA') {
442
+ event.preventDefault();
443
+ }
444
+ });
445
+ _defineProperty(this, "onDropdownIndicatorMouseDown", event => {
446
+ // ignore mouse events that weren't triggered by the primary button
447
+ if (event && event.type === 'mousedown' && event.button !== 0) {
448
+ return;
449
+ }
450
+ if (this.props.isDisabled) {
451
+ return;
452
+ }
453
+ const {
454
+ isMulti,
455
+ menuIsOpen
456
+ } = this.props;
457
+ this.focusInput();
458
+ if (menuIsOpen) {
459
+ this.setState({
460
+ inputIsHiddenAfterUpdate: !isMulti
461
+ });
462
+ this.onMenuClose();
463
+ } else {
464
+ this.openMenu('first');
465
+ }
466
+ event.preventDefault();
467
+ });
468
+ _defineProperty(this, "onClearIndicatorMouseDown", event => {
469
+ // ignore mouse events that weren't triggered by the primary button
470
+ if (event && event.type === 'mousedown' && event.button !== 0) {
471
+ return;
472
+ }
473
+ this.clearValue();
474
+ event.preventDefault();
475
+ this.openAfterFocus = false;
476
+ if (event.type === 'touchend') {
477
+ this.focusInput();
478
+ } else {
479
+ setTimeout(() => this.focusInput());
480
+ }
481
+ });
482
+ _defineProperty(this, "onScroll", event => {
483
+ if (typeof this.props.closeMenuOnScroll === 'boolean') {
484
+ if (event.target instanceof HTMLElement && isDocumentElement(event.target)) {
485
+ this.props.onMenuClose();
486
+ }
487
+ } else if (typeof this.props.closeMenuOnScroll === 'function') {
488
+ if (this.props.closeMenuOnScroll(event)) {
489
+ this.props.onMenuClose();
490
+ }
491
+ }
492
+ });
493
+ _defineProperty(this, "onCompositionStart", () => {
494
+ this.isComposing = true;
495
+ });
496
+ _defineProperty(this, "onCompositionEnd", () => {
497
+ this.isComposing = false;
498
+ });
499
+ _defineProperty(this, "onTouchStart", ({
500
+ touches
501
+ }) => {
502
+ const touch = touches && touches.item(0);
503
+ if (!touch) {
504
+ return;
505
+ }
506
+ this.initialTouchX = touch.clientX;
507
+ this.initialTouchY = touch.clientY;
508
+ this.userIsDragging = false;
509
+ });
510
+ _defineProperty(this, "onTouchMove", ({
511
+ touches
512
+ }) => {
513
+ const touch = touches && touches.item(0);
514
+ if (!touch) {
515
+ return;
516
+ }
517
+ const deltaX = Math.abs(touch.clientX - this.initialTouchX);
518
+ const deltaY = Math.abs(touch.clientY - this.initialTouchY);
519
+ const moveThreshold = 5;
520
+ this.userIsDragging = deltaX > moveThreshold || deltaY > moveThreshold;
521
+ });
522
+ _defineProperty(this, "onTouchEnd", event => {
523
+ if (this.userIsDragging) {
524
+ return;
525
+ }
526
+
527
+ // close the menu if the user taps outside
528
+ // we're checking on event.target here instead of event.currentTarget, because we want to assert information
529
+ // on events on child elements, not the document (which we've attached this handler to).
530
+ if (this.controlRef && !this.controlRef.contains(event.target) && this.menuListRef && !this.menuListRef.contains(event.target)) {
531
+ this.blurInput();
532
+ }
533
+
534
+ // reset move vars
535
+ this.initialTouchX = 0;
536
+ this.initialTouchY = 0;
537
+ });
538
+ _defineProperty(this, "onControlTouchEnd", event => {
539
+ if (this.userIsDragging) {
540
+ return;
541
+ }
542
+ this.onControlMouseDown(event);
543
+ });
544
+ _defineProperty(this, "onClearIndicatorTouchEnd", event => {
545
+ if (this.userIsDragging) {
546
+ return;
547
+ }
548
+ this.onClearIndicatorMouseDown(event);
549
+ });
550
+ _defineProperty(this, "onDropdownIndicatorTouchEnd", event => {
551
+ if (this.userIsDragging) {
552
+ return;
553
+ }
554
+ this.onDropdownIndicatorMouseDown(event);
555
+ });
556
+ // ==============================
557
+ // Focus Handlers
558
+ // ==============================
559
+ _defineProperty(this, "handleInputChange", event => {
560
+ const {
561
+ inputValue: prevInputValue
562
+ } = this.props;
563
+ const inputValue = event.currentTarget.value;
564
+ this.setState({
565
+ inputIsHiddenAfterUpdate: false
566
+ });
567
+ this.onInputChange(inputValue, {
568
+ action: 'input-change',
569
+ prevInputValue
570
+ });
571
+ if (!this.props.menuIsOpen) {
572
+ this.onMenuOpen();
573
+ }
574
+ });
575
+ _defineProperty(this, "onInputFocus", event => {
576
+ if (this.props.onFocus) {
577
+ this.props.onFocus(event);
578
+ }
579
+ this.setState({
580
+ inputIsHiddenAfterUpdate: false,
581
+ isFocused: true
582
+ });
583
+ if (this.openAfterFocus || this.props.openMenuOnFocus) {
584
+ this.openMenu('first');
585
+ }
586
+ this.openAfterFocus = false;
587
+ });
588
+ _defineProperty(this, "onInputBlur", event => {
589
+ const {
590
+ inputValue: prevInputValue
591
+ } = this.props;
592
+ if (this.menuListRef && this.menuListRef.contains(document.activeElement)) {
593
+ this.inputRef.focus();
594
+ return;
595
+ }
596
+ if (this.props.onBlur) {
597
+ this.props.onBlur(event);
598
+ }
599
+ this.onInputChange('', {
600
+ action: 'input-blur',
601
+ prevInputValue
602
+ });
603
+ this.onMenuClose();
604
+ this.setState({
605
+ focusedValue: null,
606
+ isFocused: false
607
+ });
608
+ });
609
+ _defineProperty(this, "onOptionHover", focusedOption => {
610
+ if (this.blockOptionHover || this.state.focusedOption === focusedOption) {
611
+ return;
612
+ }
613
+ const options = this.getFocusableOptions();
614
+ const focusedOptionIndex = options.indexOf(focusedOption);
615
+ this.setState({
616
+ focusedOption,
617
+ focusedOptionId: focusedOptionIndex > -1 ? this.getFocusedOptionId(focusedOption) : null
618
+ });
619
+ });
620
+ _defineProperty(this, "shouldHideSelectedOptions", () => {
621
+ return shouldHideSelectedOptions(this.props);
622
+ });
623
+ // If the hidden input gets focus through form submit,
624
+ // redirect focus to focusable input.
625
+ _defineProperty(this, "onValueInputFocus", e => {
626
+ e.preventDefault();
627
+ e.stopPropagation();
628
+ this.focus();
629
+ });
630
+ // ==============================
631
+ // Keyboard Handlers
632
+ // ==============================
633
+ _defineProperty(this, "onKeyDown", event => {
634
+ const {
635
+ isMulti,
636
+ backspaceRemovesValue,
637
+ escapeClearsValue,
638
+ inputValue,
639
+ isClearable,
640
+ isDisabled,
641
+ menuIsOpen,
642
+ onKeyDown,
643
+ tabSelectsValue,
644
+ openMenuOnFocus
645
+ } = this.props;
646
+ const {
647
+ focusedOption,
648
+ focusedValue,
649
+ selectValue
650
+ } = this.state;
651
+ if (isDisabled) {
652
+ return;
653
+ }
654
+ if (typeof onKeyDown === 'function') {
655
+ onKeyDown(event);
656
+ if (event.defaultPrevented) {
657
+ return;
658
+ }
659
+ }
660
+
661
+ // Block option hover events when the user has just pressed a key
662
+ this.blockOptionHover = true;
663
+ switch (event.key) {
664
+ case 'ArrowLeft':
665
+ if (!isMulti || inputValue) {
666
+ return;
667
+ }
668
+ this.focusValue('previous');
669
+ break;
670
+ case 'ArrowRight':
671
+ if (!isMulti || inputValue) {
672
+ return;
673
+ }
674
+ this.focusValue('next');
675
+ break;
676
+ case 'Delete':
677
+ case 'Backspace':
678
+ if (inputValue) {
679
+ return;
680
+ }
681
+ if (focusedValue) {
682
+ this.removeValue(focusedValue);
683
+ } else {
684
+ if (!backspaceRemovesValue) {
685
+ return;
686
+ }
687
+ if (isMulti) {
688
+ this.popValue();
689
+ } else if (isClearable) {
690
+ this.clearValue();
691
+ }
692
+ }
693
+ break;
694
+ case 'Tab':
695
+ if (this.isComposing) {
696
+ return;
697
+ }
698
+ if (event.shiftKey || !menuIsOpen || !tabSelectsValue || !focusedOption ||
699
+ // don't capture the event if the menu opens on focus and the focused
700
+ // option is already selected; it breaks the flow of navigation
701
+ openMenuOnFocus && this.isOptionSelected(focusedOption, selectValue)) {
702
+ return;
703
+ }
704
+ this.selectOption(focusedOption);
705
+ break;
706
+ case 'Enter':
707
+ if (event.keyCode === 229) {
708
+ // ignore the keydown event from an Input Method Editor(IME)
709
+ // ref. https://www.w3.org/TR/uievents/#determine-keydown-keyup-keyCode
710
+ break;
711
+ }
712
+ if (menuIsOpen) {
713
+ if (!focusedOption) {
714
+ return;
715
+ }
716
+ if (this.isComposing) {
717
+ return;
718
+ }
719
+ this.selectOption(focusedOption);
720
+ break;
721
+ }
722
+ return;
723
+ case 'Escape':
724
+ if (menuIsOpen) {
725
+ this.setState({
726
+ inputIsHiddenAfterUpdate: false
727
+ });
728
+ this.onInputChange('', {
729
+ action: 'menu-close',
730
+ prevInputValue: inputValue
731
+ });
732
+ this.onMenuClose();
733
+ } else if (isClearable && escapeClearsValue) {
734
+ this.clearValue();
735
+ }
736
+ break;
737
+ case ' ':
738
+ // space
739
+ if (inputValue) {
740
+ return;
741
+ }
742
+ if (!menuIsOpen) {
743
+ this.openMenu('first');
744
+ break;
745
+ }
746
+ if (!focusedOption) {
747
+ return;
748
+ }
749
+ this.selectOption(focusedOption);
750
+ break;
751
+ case 'ArrowUp':
752
+ if (menuIsOpen) {
753
+ this.focusOption('up');
754
+ } else {
755
+ this.openMenu('last');
756
+ }
757
+ break;
758
+ case 'ArrowDown':
759
+ if (menuIsOpen) {
760
+ this.focusOption('down');
761
+ } else {
762
+ this.openMenu('first');
763
+ }
764
+ break;
765
+ case 'PageUp':
766
+ if (!menuIsOpen) {
767
+ return;
768
+ }
769
+ this.focusOption('pageup');
770
+ break;
771
+ case 'PageDown':
772
+ if (!menuIsOpen) {
773
+ return;
774
+ }
775
+ this.focusOption('pagedown');
776
+ break;
777
+ case 'Home':
778
+ if (!menuIsOpen) {
779
+ return;
780
+ }
781
+ this.focusOption('first');
782
+ break;
783
+ case 'End':
784
+ if (!menuIsOpen) {
785
+ return;
786
+ }
787
+ this.focusOption('last');
788
+ break;
789
+ default:
790
+ return;
791
+ }
792
+ event.preventDefault();
793
+ });
794
+ this.state.instancePrefix = 'react-select-' + (this.props.instanceId || ++instanceId);
795
+ //@ts-ignore
796
+ this.state.selectValue = cleanValue(_props.value);
797
+ // Set focusedOption if menuIsOpen is set on init (e.g. defaultMenuIsOpen)
798
+ if (_props.menuIsOpen && this.state.selectValue.length) {
799
+ const focusableOptionsWithIds = this.getFocusableOptionsWithIds();
800
+ const focusableOptions = this.buildFocusableOptions();
801
+ const optionIndex = focusableOptions.indexOf(this.state.selectValue[0]);
802
+ this.state.focusableOptionsWithIds = focusableOptionsWithIds;
803
+ this.state.focusedOption = focusableOptions[optionIndex];
804
+ this.state.focusedOptionId = getFocusedOptionId(focusableOptionsWithIds, focusableOptions[optionIndex]);
805
+ }
806
+ }
807
+ static getDerivedStateFromProps(props, state) {
808
+ const {
809
+ prevProps,
810
+ clearFocusValueOnUpdate,
811
+ inputIsHiddenAfterUpdate,
812
+ ariaSelection,
813
+ isFocused,
814
+ prevWasFocused,
815
+ instancePrefix
816
+ } = state;
817
+ const {
818
+ options,
819
+ value,
820
+ menuIsOpen,
821
+ inputValue,
822
+ isMulti
823
+ } = props;
824
+ //@ts-ignore
825
+ const selectValue = cleanValue(value);
826
+ let newMenuOptionsState = {};
827
+ if (prevProps && (value !== prevProps.value || options !== prevProps.options || menuIsOpen !== prevProps.menuIsOpen || inputValue !== prevProps.inputValue)) {
828
+ const focusableOptions = menuIsOpen ? buildFocusableOptions(props, selectValue) : [];
829
+ const focusableOptionsWithIds = menuIsOpen ? buildFocusableOptionsWithIds(buildCategorizedOptions(props, selectValue), `${instancePrefix}-option`) : [];
830
+ const focusedValue = clearFocusValueOnUpdate ? getNextFocusedValue(state, selectValue) : null;
831
+ const focusedOption = getNextFocusedOption(state, focusableOptions);
832
+ const focusedOptionId = getFocusedOptionId(focusableOptionsWithIds, focusedOption);
833
+ newMenuOptionsState = {
834
+ selectValue,
835
+ focusedOption,
836
+ focusedOptionId,
837
+ focusableOptionsWithIds,
838
+ focusedValue,
839
+ clearFocusValueOnUpdate: false
840
+ };
841
+ }
842
+ // some updates should toggle the state of the input visibility
843
+ const newInputIsHiddenState = inputIsHiddenAfterUpdate != null && props !== prevProps ? {
844
+ inputIsHidden: inputIsHiddenAfterUpdate,
845
+ inputIsHiddenAfterUpdate: undefined
846
+ } : {};
847
+ let newAriaSelection = ariaSelection;
848
+ let hasKeptFocus = isFocused && prevWasFocused;
849
+ if (isFocused && !hasKeptFocus) {
850
+ // If `value` or `defaultValue` props are not empty then announce them
851
+ // when the Select is initially focused
852
+ newAriaSelection = {
853
+ value: valueTernary(isMulti, selectValue, selectValue[0] || null),
854
+ options: selectValue,
855
+ action: 'initial-input-focus'
856
+ };
857
+ hasKeptFocus = !prevWasFocused;
858
+ }
859
+
860
+ // If the 'initial-input-focus' action has been set already
861
+ // then reset the ariaSelection to null
862
+ if ((ariaSelection === null || ariaSelection === void 0 ? void 0 : ariaSelection.action) === 'initial-input-focus') {
863
+ newAriaSelection = null;
864
+ }
865
+ return {
866
+ ...newMenuOptionsState,
867
+ ...newInputIsHiddenState,
868
+ prevProps: props,
869
+ ariaSelection: newAriaSelection,
870
+ prevWasFocused: hasKeptFocus
871
+ };
872
+ }
873
+ componentDidMount() {
874
+ this.startListeningComposition();
875
+ this.startListeningToTouch();
876
+ if (this.props.closeMenuOnScroll && document && document.addEventListener) {
877
+ // Listen to all scroll events, and filter them out inside of 'onScroll'
878
+ // eslint-disable-next-line @repo/internal/dom-events/no-unsafe-event-listeners
879
+ document.addEventListener('scroll', this.onScroll, true);
880
+ }
881
+ if (this.props.autoFocus) {
882
+ this.focusInput();
883
+ }
884
+
885
+ // Scroll focusedOption into view if menuIsOpen is set on mount (e.g. defaultMenuIsOpen)
886
+ if (this.props.menuIsOpen && this.state.focusedOption && this.menuListRef && this.focusedOptionRef) {
887
+ scrollIntoView(this.menuListRef, this.focusedOptionRef);
888
+ }
889
+ }
890
+ componentDidUpdate(prevProps) {
891
+ const {
892
+ isDisabled,
893
+ menuIsOpen
894
+ } = this.props;
895
+ const {
896
+ isFocused
897
+ } = this.state;
898
+ if (
899
+ // ensure focus is restored correctly when the control becomes enabled
900
+ isFocused && !isDisabled && prevProps.isDisabled ||
901
+ // ensure focus is on the Input when the menu opens
902
+ isFocused && menuIsOpen && !prevProps.menuIsOpen) {
903
+ this.focusInput();
904
+ }
905
+ if (isFocused && isDisabled && !prevProps.isDisabled) {
906
+ // ensure select state gets blurred in case Select is programmatically disabled while focused
907
+ // eslint-disable-next-line react/no-did-update-set-state
908
+ this.setState({
909
+ isFocused: false
910
+ }, this.onMenuClose);
911
+ } else if (!isFocused && !isDisabled && prevProps.isDisabled && this.inputRef === document.activeElement) {
912
+ // ensure select state gets focused in case Select is programatically re-enabled while focused (Firefox)
913
+ // eslint-disable-next-line react/no-did-update-set-state
914
+ this.setState({
915
+ isFocused: true
916
+ });
917
+ }
918
+
919
+ // scroll the focused option into view if necessary
920
+ if (this.menuListRef && this.focusedOptionRef && this.scrollToFocusedOptionOnUpdate) {
921
+ scrollIntoView(this.menuListRef, this.focusedOptionRef);
922
+ this.scrollToFocusedOptionOnUpdate = false;
923
+ }
924
+ }
925
+ componentWillUnmount() {
926
+ this.stopListeningComposition();
927
+ this.stopListeningToTouch();
928
+ // eslint-disable-next-line @repo/internal/dom-events/no-unsafe-event-listeners
929
+ document.removeEventListener('scroll', this.onScroll, true);
930
+ }
931
+
932
+ // ==============================
933
+ // Consumer Handlers
934
+ // ==============================
935
+
936
+ onMenuOpen() {
937
+ this.props.onMenuOpen();
938
+ }
939
+ onMenuClose() {
940
+ this.onInputChange('', {
941
+ action: 'menu-close',
942
+ prevInputValue: this.props.inputValue
943
+ });
944
+ this.props.onMenuClose();
945
+ }
946
+ onInputChange(newValue, actionMeta) {
947
+ this.props.onInputChange(newValue, actionMeta);
948
+ }
949
+
950
+ // ==============================
951
+ // Methods
952
+ // ==============================
953
+
954
+ focusInput() {
955
+ if (!this.inputRef) {
956
+ return;
957
+ }
958
+ this.inputRef.focus();
959
+ }
960
+ blurInput() {
961
+ if (!this.inputRef) {
962
+ return;
963
+ }
964
+ this.inputRef.blur();
965
+ }
966
+ openMenu(focusOption) {
967
+ const {
968
+ selectValue,
969
+ isFocused
970
+ } = this.state;
971
+ const focusableOptions = this.buildFocusableOptions();
972
+ let openAtIndex = focusOption === 'first' ? 0 : focusableOptions.length - 1;
973
+ if (!this.props.isMulti) {
974
+ const selectedIndex = focusableOptions.indexOf(selectValue[0]);
975
+ if (selectedIndex > -1) {
976
+ openAtIndex = selectedIndex;
977
+ }
978
+ }
979
+
980
+ // only scroll if the menu isn't already open
981
+ this.scrollToFocusedOptionOnUpdate = !(isFocused && this.menuListRef);
982
+ this.setState({
983
+ inputIsHiddenAfterUpdate: false,
984
+ focusedValue: null,
985
+ focusedOption: focusableOptions[openAtIndex],
986
+ focusedOptionId: this.getFocusedOptionId(focusableOptions[openAtIndex])
987
+ }, () => this.onMenuOpen());
988
+ }
989
+ focusValue(direction) {
990
+ const {
991
+ selectValue,
992
+ focusedValue
993
+ } = this.state;
994
+
995
+ // Only multiselects support value focusing
996
+ if (!this.props.isMulti) {
997
+ return;
998
+ }
999
+ this.setState({
1000
+ focusedOption: null
1001
+ });
1002
+ let focusedIndex = selectValue.indexOf(focusedValue);
1003
+ if (!focusedValue) {
1004
+ focusedIndex = -1;
1005
+ }
1006
+ const lastIndex = selectValue.length - 1;
1007
+ let nextFocus = -1;
1008
+ if (!selectValue.length) {
1009
+ return;
1010
+ }
1011
+ switch (direction) {
1012
+ case 'previous':
1013
+ if (focusedIndex === 0) {
1014
+ // don't cycle from the start to the end
1015
+ nextFocus = 0;
1016
+ } else if (focusedIndex === -1) {
1017
+ // if nothing is focused, focus the last value first
1018
+ nextFocus = lastIndex;
1019
+ } else {
1020
+ nextFocus = focusedIndex - 1;
1021
+ }
1022
+ break;
1023
+ case 'next':
1024
+ if (focusedIndex > -1 && focusedIndex < lastIndex) {
1025
+ nextFocus = focusedIndex + 1;
1026
+ }
1027
+ break;
1028
+ }
1029
+ this.setState({
1030
+ inputIsHidden: nextFocus !== -1,
1031
+ focusedValue: selectValue[nextFocus]
1032
+ });
1033
+ }
1034
+ focusOption(direction = 'first') {
1035
+ const {
1036
+ pageSize
1037
+ } = this.props;
1038
+ const {
1039
+ focusedOption
1040
+ } = this.state;
1041
+ const options = this.getFocusableOptions();
1042
+ if (!options.length) {
1043
+ return;
1044
+ }
1045
+ let nextFocus = 0; // handles 'first'
1046
+ let focusedIndex = options.indexOf(focusedOption);
1047
+ if (!focusedOption) {
1048
+ focusedIndex = -1;
1049
+ }
1050
+ if (direction === 'up') {
1051
+ nextFocus = focusedIndex > 0 ? focusedIndex - 1 : options.length - 1;
1052
+ } else if (direction === 'down') {
1053
+ nextFocus = (focusedIndex + 1) % options.length;
1054
+ } else if (direction === 'pageup') {
1055
+ nextFocus = focusedIndex - pageSize;
1056
+ if (nextFocus < 0) {
1057
+ nextFocus = 0;
1058
+ }
1059
+ } else if (direction === 'pagedown') {
1060
+ nextFocus = focusedIndex + pageSize;
1061
+ if (nextFocus > options.length - 1) {
1062
+ nextFocus = options.length - 1;
1063
+ }
1064
+ } else if (direction === 'last') {
1065
+ nextFocus = options.length - 1;
1066
+ }
1067
+ this.scrollToFocusedOptionOnUpdate = true;
1068
+ this.setState({
1069
+ focusedOption: options[nextFocus],
1070
+ focusedValue: null,
1071
+ focusedOptionId: this.getFocusedOptionId(options[nextFocus])
1072
+ });
1073
+ }
1074
+ // ==============================
1075
+ // Getters
1076
+ // ==============================
1077
+
1078
+ getTheme() {
1079
+ // Use the default theme if there are no customisations.
1080
+ if (!this.props.theme) {
1081
+ return defaultTheme;
1082
+ }
1083
+ // If the theme prop is a function, assume the function
1084
+ // knows how to merge the passed-in default theme with
1085
+ // its own modifications.
1086
+ if (typeof this.props.theme === 'function') {
1087
+ return this.props.theme(defaultTheme);
1088
+ }
1089
+ // Otherwise, if a plain theme object was passed in,
1090
+ // overlay it with the default theme.
1091
+ return {
1092
+ ...defaultTheme,
1093
+ ...this.props.theme
1094
+ };
1095
+ }
1096
+ getCommonProps() {
1097
+ const {
1098
+ clearValue,
1099
+ cx,
1100
+ getStyles,
1101
+ getClassNames,
1102
+ getValue,
1103
+ selectOption,
1104
+ setValue,
1105
+ props
1106
+ } = this;
1107
+ const {
1108
+ isMulti,
1109
+ isRtl,
1110
+ options
1111
+ } = props;
1112
+ const hasValue = this.hasValue();
1113
+ return {
1114
+ clearValue,
1115
+ cx,
1116
+ getStyles,
1117
+ getClassNames,
1118
+ getValue,
1119
+ hasValue,
1120
+ isMulti,
1121
+ isRtl,
1122
+ options,
1123
+ selectOption,
1124
+ selectProps: props,
1125
+ setValue,
1126
+ theme: this.getTheme()
1127
+ };
1128
+ }
1129
+ hasValue() {
1130
+ const {
1131
+ selectValue
1132
+ } = this.state;
1133
+ return selectValue.length > 0;
1134
+ }
1135
+ hasOptions() {
1136
+ return !!this.getFocusableOptions().length;
1137
+ }
1138
+ isClearable() {
1139
+ const {
1140
+ isClearable,
1141
+ isMulti
1142
+ } = this.props;
1143
+
1144
+ // single select, by default, IS NOT clearable
1145
+ // multi select, by default, IS clearable
1146
+ if (isClearable === undefined) {
1147
+ return isMulti;
1148
+ }
1149
+ return isClearable;
1150
+ }
1151
+ isOptionDisabled(option, selectValue) {
1152
+ return isOptionDisabled(this.props, option, selectValue);
1153
+ }
1154
+ isOptionSelected(option, selectValue) {
1155
+ return isOptionSelected(this.props, option, selectValue);
1156
+ }
1157
+ filterOption(option, inputValue) {
1158
+ return filterOption(this.props, option, inputValue);
1159
+ }
1160
+ formatOptionLabel(data, context) {
1161
+ if (typeof this.props.formatOptionLabel === 'function') {
1162
+ const {
1163
+ inputValue
1164
+ } = this.props;
1165
+ const {
1166
+ selectValue
1167
+ } = this.state;
1168
+ return this.props.formatOptionLabel(data, {
1169
+ context,
1170
+ inputValue,
1171
+ selectValue
1172
+ });
1173
+ } else {
1174
+ return this.getOptionLabel(data);
1175
+ }
1176
+ }
1177
+ formatGroupLabel(data) {
1178
+ return this.props.formatGroupLabel(data);
1179
+ }
1180
+ // ==============================
1181
+ // Composition Handlers
1182
+ // ==============================
1183
+
1184
+ startListeningComposition() {
1185
+ if (document && document.addEventListener) {
1186
+ // eslint-disable-next-line @repo/internal/dom-events/no-unsafe-event-listeners
1187
+ document.addEventListener('compositionstart', this.onCompositionStart, false);
1188
+ // eslint-disable-next-line @repo/internal/dom-events/no-unsafe-event-listeners
1189
+ document.addEventListener('compositionend', this.onCompositionEnd, false);
1190
+ }
1191
+ }
1192
+ stopListeningComposition() {
1193
+ if (document && document.removeEventListener) {
1194
+ // eslint-disable-next-line @repo/internal/dom-events/no-unsafe-event-listeners
1195
+ document.removeEventListener('compositionstart', this.onCompositionStart);
1196
+ // eslint-disable-next-line @repo/internal/dom-events/no-unsafe-event-listeners
1197
+ document.removeEventListener('compositionend', this.onCompositionEnd);
1198
+ }
1199
+ }
1200
+ // ==============================
1201
+ // Touch Handlers
1202
+ // ==============================
1203
+
1204
+ startListeningToTouch() {
1205
+ if (document && document.addEventListener) {
1206
+ // eslint-disable-next-line @repo/internal/dom-events/no-unsafe-event-listeners
1207
+ document.addEventListener('touchstart', this.onTouchStart, false);
1208
+ // eslint-disable-next-line @repo/internal/dom-events/no-unsafe-event-listeners
1209
+ document.addEventListener('touchmove', this.onTouchMove, false);
1210
+ // eslint-disable-next-line @repo/internal/dom-events/no-unsafe-event-listeners
1211
+ document.addEventListener('touchend', this.onTouchEnd, false);
1212
+ }
1213
+ }
1214
+ stopListeningToTouch() {
1215
+ if (document && document.removeEventListener) {
1216
+ // eslint-disable-next-line @repo/internal/dom-events/no-unsafe-event-listeners
1217
+ document.removeEventListener('touchstart', this.onTouchStart);
1218
+ // eslint-disable-next-line @repo/internal/dom-events/no-unsafe-event-listeners
1219
+ document.removeEventListener('touchmove', this.onTouchMove);
1220
+ // eslint-disable-next-line @repo/internal/dom-events/no-unsafe-event-listeners
1221
+ document.removeEventListener('touchend', this.onTouchEnd);
1222
+ }
1223
+ }
1224
+ // ==============================
1225
+ // Renderers
1226
+ // ==============================
1227
+ renderInput() {
1228
+ const {
1229
+ isDisabled,
1230
+ isSearchable,
1231
+ inputId,
1232
+ inputValue,
1233
+ tabIndex,
1234
+ form,
1235
+ menuIsOpen,
1236
+ required
1237
+ } = this.props;
1238
+ const {
1239
+ Input
1240
+ } = this.getComponents();
1241
+ const {
1242
+ inputIsHidden,
1243
+ ariaSelection
1244
+ } = this.state;
1245
+ const {
1246
+ commonProps
1247
+ } = this;
1248
+ const id = inputId || this.getElementId('input');
1249
+
1250
+ // aria attributes makes the JSX "noisy", separated for clarity
1251
+ const ariaAttributes = {
1252
+ 'aria-autocomplete': 'list',
1253
+ 'aria-expanded': menuIsOpen,
1254
+ 'aria-haspopup': 'listbox',
1255
+ 'aria-errormessage': this.props['aria-errormessage'],
1256
+ 'aria-describedby': this.props['aria-describedby'],
1257
+ 'aria-invalid': this.props['aria-invalid'],
1258
+ 'aria-label': this.props['aria-label'],
1259
+ 'aria-labelledby': this.props['aria-labelledby'],
1260
+ 'aria-required': required,
1261
+ role: 'combobox',
1262
+ 'aria-activedescendant': this.isAppleDevice ? undefined : this.state.focusedOptionId,
1263
+ ...(menuIsOpen && {
1264
+ 'aria-controls': this.getElementId('listbox')
1265
+ }),
1266
+ ...(!isSearchable && {
1267
+ 'aria-readonly': true
1268
+ }),
1269
+ ...(this.hasValue() ? (ariaSelection === null || ariaSelection === void 0 ? void 0 : ariaSelection.action) === 'initial-input-focus' && {
1270
+ 'aria-describedby': this.getElementId('live-region')
1271
+ } : {
1272
+ 'aria-describedby': this.getElementId('placeholder')
1273
+ })
1274
+ };
1275
+ if (!isSearchable) {
1276
+ // use a dummy input to maintain focus/blur functionality
1277
+ return (
1278
+ /*#__PURE__*/
1279
+ //@ts-ignore
1280
+ React.createElement(DummyInput, _extends({
1281
+ id: id,
1282
+ innerRef: this.getInputRef,
1283
+ onBlur: this.onInputBlur,
1284
+ onChange: noop,
1285
+ onFocus: this.onInputFocus,
1286
+ disabled: isDisabled,
1287
+ tabIndex: tabIndex,
1288
+ inputMode: "none",
1289
+ form: form,
1290
+ value: ""
1291
+ }, ariaAttributes))
1292
+ );
1293
+ }
1294
+ return /*#__PURE__*/React.createElement(Input, _extends({}, commonProps, {
1295
+ autoCapitalize: "none",
1296
+ autoComplete: "off",
1297
+ autoCorrect: "off",
1298
+ id: id,
1299
+ innerRef: this.getInputRef,
1300
+ isDisabled: isDisabled,
1301
+ isHidden: inputIsHidden,
1302
+ onBlur: this.onInputBlur,
1303
+ onChange: this.handleInputChange,
1304
+ onFocus: this.onInputFocus,
1305
+ spellCheck: "false",
1306
+ tabIndex: tabIndex,
1307
+ form: form,
1308
+ type: "text",
1309
+ value: inputValue
1310
+ }, ariaAttributes));
1311
+ }
1312
+ renderPlaceholderOrValue() {
1313
+ const {
1314
+ MultiValue,
1315
+ MultiValueContainer,
1316
+ MultiValueLabel,
1317
+ MultiValueRemove,
1318
+ SingleValue,
1319
+ Placeholder
1320
+ } = this.getComponents();
1321
+ const {
1322
+ commonProps
1323
+ } = this;
1324
+ const {
1325
+ controlShouldRenderValue,
1326
+ isDisabled,
1327
+ isMulti,
1328
+ inputValue,
1329
+ placeholder
1330
+ } = this.props;
1331
+ const {
1332
+ selectValue,
1333
+ focusedValue,
1334
+ isFocused
1335
+ } = this.state;
1336
+ if (!this.hasValue() || !controlShouldRenderValue) {
1337
+ return inputValue ? null : /*#__PURE__*/React.createElement(Placeholder, _extends({}, commonProps, {
1338
+ key: "placeholder",
1339
+ isDisabled: isDisabled,
1340
+ isFocused: isFocused,
1341
+ innerProps: {
1342
+ id: this.getElementId('placeholder')
1343
+ }
1344
+ }), placeholder);
1345
+ }
1346
+ if (isMulti) {
1347
+ return selectValue.map((opt, index) => {
1348
+ const isOptionFocused = opt === focusedValue;
1349
+ const key = `${this.getOptionLabel(opt)}-${this.getOptionValue(opt)}`;
1350
+ return /*#__PURE__*/React.createElement(MultiValue, _extends({}, commonProps, {
1351
+ components: {
1352
+ Container: MultiValueContainer,
1353
+ Label: MultiValueLabel,
1354
+ Remove: MultiValueRemove
1355
+ },
1356
+ isFocused: isOptionFocused,
1357
+ isDisabled: isDisabled,
1358
+ key: key,
1359
+ index: index,
1360
+ removeProps: {
1361
+ onClick: () => this.removeValue(opt),
1362
+ onTouchEnd: () => this.removeValue(opt),
1363
+ onMouseDown: e => {
1364
+ e.preventDefault();
1365
+ }
1366
+ },
1367
+ data: opt
1368
+ }), this.formatOptionLabel(opt, 'value'));
1369
+ });
1370
+ }
1371
+ if (inputValue) {
1372
+ return null;
1373
+ }
1374
+ const singleValue = selectValue[0];
1375
+ return /*#__PURE__*/React.createElement(SingleValue, _extends({}, commonProps, {
1376
+ data: singleValue,
1377
+ isDisabled: isDisabled
1378
+ }), this.formatOptionLabel(singleValue, 'value'));
1379
+ }
1380
+ renderClearIndicator() {
1381
+ const {
1382
+ ClearIndicator
1383
+ } = this.getComponents();
1384
+ const {
1385
+ commonProps
1386
+ } = this;
1387
+ const {
1388
+ isDisabled,
1389
+ isLoading
1390
+ } = this.props;
1391
+ const {
1392
+ isFocused
1393
+ } = this.state;
1394
+ if (!this.isClearable() || !ClearIndicator || isDisabled || !this.hasValue() || isLoading) {
1395
+ return null;
1396
+ }
1397
+ const innerProps = {
1398
+ onMouseDown: this.onClearIndicatorMouseDown,
1399
+ onTouchEnd: this.onClearIndicatorTouchEnd,
1400
+ 'aria-hidden': 'true'
1401
+ };
1402
+ return /*#__PURE__*/React.createElement(ClearIndicator, _extends({}, commonProps, {
1403
+ innerProps: innerProps,
1404
+ isFocused: isFocused
1405
+ }));
1406
+ }
1407
+ renderLoadingIndicator() {
1408
+ const {
1409
+ LoadingIndicator
1410
+ } = this.getComponents();
1411
+ const {
1412
+ commonProps
1413
+ } = this;
1414
+ const {
1415
+ isDisabled,
1416
+ isLoading
1417
+ } = this.props;
1418
+ const {
1419
+ isFocused
1420
+ } = this.state;
1421
+ if (!LoadingIndicator || !isLoading) {
1422
+ return null;
1423
+ }
1424
+ const innerProps = {
1425
+ 'aria-hidden': 'true'
1426
+ };
1427
+ return /*#__PURE__*/React.createElement(LoadingIndicator, _extends({}, commonProps, {
1428
+ innerProps: innerProps,
1429
+ isDisabled: isDisabled,
1430
+ isFocused: isFocused
1431
+ }));
1432
+ }
1433
+ renderIndicatorSeparator() {
1434
+ const {
1435
+ DropdownIndicator,
1436
+ IndicatorSeparator
1437
+ } = this.getComponents();
1438
+
1439
+ // separator doesn't make sense without the dropdown indicator
1440
+ if (!DropdownIndicator || !IndicatorSeparator) {
1441
+ return null;
1442
+ }
1443
+ const {
1444
+ commonProps
1445
+ } = this;
1446
+ const {
1447
+ isDisabled
1448
+ } = this.props;
1449
+ const {
1450
+ isFocused
1451
+ } = this.state;
1452
+ return /*#__PURE__*/React.createElement(IndicatorSeparator, _extends({}, commonProps, {
1453
+ isDisabled: isDisabled,
1454
+ isFocused: isFocused
1455
+ }));
1456
+ }
1457
+ renderDropdownIndicator() {
1458
+ const {
1459
+ DropdownIndicator
1460
+ } = this.getComponents();
1461
+ if (!DropdownIndicator) {
1462
+ return null;
1463
+ }
1464
+ const {
1465
+ commonProps
1466
+ } = this;
1467
+ const {
1468
+ isDisabled
1469
+ } = this.props;
1470
+ const {
1471
+ isFocused
1472
+ } = this.state;
1473
+ const innerProps = {
1474
+ onMouseDown: this.onDropdownIndicatorMouseDown,
1475
+ onTouchEnd: this.onDropdownIndicatorTouchEnd,
1476
+ 'aria-hidden': 'true'
1477
+ };
1478
+ return /*#__PURE__*/React.createElement(DropdownIndicator, _extends({}, commonProps, {
1479
+ innerProps: innerProps,
1480
+ isDisabled: isDisabled,
1481
+ isFocused: isFocused
1482
+ }));
1483
+ }
1484
+ renderMenu() {
1485
+ const {
1486
+ Group,
1487
+ GroupHeading,
1488
+ Menu,
1489
+ MenuList,
1490
+ MenuPortal,
1491
+ LoadingMessage,
1492
+ NoOptionsMessage,
1493
+ Option
1494
+ } = this.getComponents();
1495
+ const {
1496
+ commonProps
1497
+ } = this;
1498
+ const {
1499
+ focusedOption
1500
+ } = this.state;
1501
+ const {
1502
+ captureMenuScroll,
1503
+ inputValue,
1504
+ isLoading,
1505
+ loadingMessage,
1506
+ minMenuHeight,
1507
+ maxMenuHeight,
1508
+ menuIsOpen,
1509
+ menuPlacement,
1510
+ menuPosition,
1511
+ menuPortalTarget,
1512
+ menuShouldBlockScroll,
1513
+ menuShouldScrollIntoView,
1514
+ noOptionsMessage,
1515
+ onMenuScrollToTop,
1516
+ onMenuScrollToBottom
1517
+ } = this.props;
1518
+ if (!menuIsOpen) {
1519
+ return null;
1520
+ }
1521
+
1522
+ // TODO: Internal Option Type here
1523
+ const render = (props, id) => {
1524
+ const {
1525
+ type,
1526
+ data,
1527
+ isDisabled,
1528
+ isSelected,
1529
+ label,
1530
+ value
1531
+ } = props;
1532
+ const isFocused = focusedOption === data;
1533
+ const onHover = isDisabled ? undefined : () => this.onOptionHover(data);
1534
+ const onSelect = isDisabled ? undefined : () => this.selectOption(data);
1535
+ const optionId = `${this.getElementId('option')}-${id}`;
1536
+ const innerProps = {
1537
+ id: optionId,
1538
+ onClick: onSelect,
1539
+ onMouseMove: onHover,
1540
+ onMouseOver: onHover,
1541
+ role: 'option',
1542
+ 'aria-selected': this.isAppleDevice ? undefined : isSelected // is not supported on Apple devices
1543
+ };
1544
+ return /*#__PURE__*/React.createElement(Option, _extends({}, commonProps, {
1545
+ innerProps: innerProps,
1546
+ data: data,
1547
+ isDisabled: isDisabled,
1548
+ isSelected: isSelected,
1549
+ key: optionId,
1550
+ label: label,
1551
+ type: type,
1552
+ value: value,
1553
+ isFocused: isFocused,
1554
+ innerRef: isFocused ? this.getFocusedOptionRef : undefined
1555
+ }), this.formatOptionLabel(props.data, 'menu'));
1556
+ };
1557
+ let menuUI;
1558
+ if (this.hasOptions()) {
1559
+ menuUI = this.getCategorizedOptions().map(item => {
1560
+ if (item.type === 'group') {
1561
+ const {
1562
+ data,
1563
+ options,
1564
+ index: groupIndex
1565
+ } = item;
1566
+ const groupId = `${this.getElementId('group')}-${groupIndex}`;
1567
+ const headingId = `${groupId}-heading`;
1568
+ return /*#__PURE__*/React.createElement(Group, _extends({}, commonProps, {
1569
+ key: groupId,
1570
+ data: data,
1571
+ options: options,
1572
+ Heading: GroupHeading,
1573
+ headingProps: {
1574
+ id: headingId,
1575
+ data: item.data
1576
+ },
1577
+ label: this.formatGroupLabel(item.data)
1578
+ }), item.options.map(option => render(option, `${groupIndex}-${option.index}`)));
1579
+ } else if (item.type === 'option') {
1580
+ return render(item, `${item.index}`);
1581
+ }
1582
+ });
1583
+ } else if (isLoading) {
1584
+ const message = loadingMessage({
1585
+ inputValue
1586
+ });
1587
+ if (message === null) {
1588
+ return null;
1589
+ }
1590
+ menuUI = /*#__PURE__*/React.createElement(LoadingMessage, commonProps, message);
1591
+ } else {
1592
+ const message = noOptionsMessage({
1593
+ inputValue
1594
+ });
1595
+ if (message === null) {
1596
+ return null;
1597
+ }
1598
+ menuUI = /*#__PURE__*/React.createElement(NoOptionsMessage, commonProps, message);
1599
+ }
1600
+ const menuPlacementProps = {
1601
+ minMenuHeight,
1602
+ maxMenuHeight,
1603
+ menuPlacement,
1604
+ menuPosition,
1605
+ menuShouldScrollIntoView
1606
+ };
1607
+ const menuElement = /*#__PURE__*/React.createElement(MenuPlacer, _extends({}, commonProps, menuPlacementProps), ({
1608
+ ref,
1609
+ placerProps: {
1610
+ placement,
1611
+ maxHeight
1612
+ }
1613
+ }) => /*#__PURE__*/React.createElement(Menu, _extends({}, commonProps, menuPlacementProps, {
1614
+ innerRef: ref,
1615
+ innerProps: {
1616
+ onMouseDown: this.onMenuMouseDown,
1617
+ onMouseMove: this.onMenuMouseMove
1618
+ },
1619
+ isLoading: isLoading,
1620
+ placement: placement
1621
+ }), /*#__PURE__*/React.createElement(ScrollManager, {
1622
+ captureEnabled: captureMenuScroll,
1623
+ onTopArrive: onMenuScrollToTop,
1624
+ onBottomArrive: onMenuScrollToBottom,
1625
+ lockEnabled: menuShouldBlockScroll
1626
+ }, scrollTargetRef => /*#__PURE__*/React.createElement(MenuList, _extends({}, commonProps, {
1627
+ innerRef: instance => {
1628
+ this.getMenuListRef(instance);
1629
+ scrollTargetRef(instance);
1630
+ },
1631
+ innerProps: {
1632
+ role: 'listbox',
1633
+ 'aria-multiselectable': commonProps.isMulti,
1634
+ id: this.getElementId('listbox')
1635
+ },
1636
+ isLoading: isLoading,
1637
+ maxHeight: maxHeight,
1638
+ focusedOption: focusedOption
1639
+ }), menuUI))));
1640
+
1641
+ // positioning behaviour is almost identical for portalled and fixed,
1642
+ // so we use the same component. the actual portalling logic is forked
1643
+ // within the component based on `menuPosition`
1644
+ return menuPortalTarget || menuPosition === 'fixed' ? /*#__PURE__*/React.createElement(MenuPortal, _extends({}, commonProps, {
1645
+ appendTo: menuPortalTarget,
1646
+ controlElement: this.controlRef,
1647
+ menuPlacement: menuPlacement,
1648
+ menuPosition: menuPosition
1649
+ }), menuElement) : menuElement;
1650
+ }
1651
+ renderFormField() {
1652
+ const {
1653
+ delimiter,
1654
+ isDisabled,
1655
+ isMulti,
1656
+ name,
1657
+ required
1658
+ } = this.props;
1659
+ const {
1660
+ selectValue
1661
+ } = this.state;
1662
+ if (required && !this.hasValue() && !isDisabled) {
1663
+ return /*#__PURE__*/React.createElement(RequiredInput, {
1664
+ name: name,
1665
+ onFocus: this.onValueInputFocus
1666
+ });
1667
+ }
1668
+ if (!name || isDisabled) {
1669
+ return;
1670
+ }
1671
+ if (isMulti) {
1672
+ if (delimiter) {
1673
+ const value = selectValue.map(opt => this.getOptionValue(opt)).join(delimiter);
1674
+ return /*#__PURE__*/React.createElement("input", {
1675
+ name: name,
1676
+ type: "hidden",
1677
+ value: value
1678
+ });
1679
+ } else {
1680
+ const input = selectValue.length > 0 ? selectValue.map((opt, i) => /*#__PURE__*/React.createElement("input", {
1681
+ key: `i-${i}`,
1682
+ name: name,
1683
+ type: "hidden",
1684
+ value: this.getOptionValue(opt)
1685
+ })) : /*#__PURE__*/React.createElement("input", {
1686
+ name: name,
1687
+ type: "hidden",
1688
+ value: ""
1689
+ });
1690
+ return /*#__PURE__*/React.createElement("div", null, input);
1691
+ }
1692
+ } else {
1693
+ const value = selectValue[0] ? this.getOptionValue(selectValue[0]) : '';
1694
+ return /*#__PURE__*/React.createElement("input", {
1695
+ name: name,
1696
+ type: "hidden",
1697
+ value: value
1698
+ });
1699
+ }
1700
+ }
1701
+ renderLiveRegion() {
1702
+ const {
1703
+ commonProps
1704
+ } = this;
1705
+ const {
1706
+ ariaSelection,
1707
+ focusedOption,
1708
+ focusedValue,
1709
+ isFocused,
1710
+ selectValue
1711
+ } = this.state;
1712
+ const focusableOptions = this.getFocusableOptions();
1713
+ return /*#__PURE__*/React.createElement(LiveRegion, _extends({}, commonProps, {
1714
+ id: this.getElementId('live-region'),
1715
+ ariaSelection: ariaSelection,
1716
+ focusedOption: focusedOption,
1717
+ focusedValue: focusedValue,
1718
+ isFocused: isFocused,
1719
+ selectValue: selectValue,
1720
+ focusableOptions: focusableOptions,
1721
+ isAppleDevice: this.isAppleDevice
1722
+ }));
1723
+ }
1724
+ render() {
1725
+ const {
1726
+ Control,
1727
+ IndicatorsContainer,
1728
+ SelectContainer,
1729
+ ValueContainer
1730
+ } = this.getComponents();
1731
+ const {
1732
+ className,
1733
+ id,
1734
+ isDisabled,
1735
+ menuIsOpen
1736
+ } = this.props;
1737
+ const {
1738
+ isFocused
1739
+ } = this.state;
1740
+ const commonProps = this.commonProps = this.getCommonProps();
1741
+ return /*#__PURE__*/React.createElement(SelectContainer, _extends({}, commonProps, {
1742
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop
1743
+ className: className,
1744
+ innerProps: {
1745
+ id: id,
1746
+ onKeyDown: this.onKeyDown
1747
+ },
1748
+ isDisabled: isDisabled,
1749
+ isFocused: isFocused
1750
+ }), this.renderLiveRegion(), /*#__PURE__*/React.createElement(Control, _extends({}, commonProps, {
1751
+ innerRef: this.getControlRef,
1752
+ innerProps: {
1753
+ onMouseDown: this.onControlMouseDown,
1754
+ onTouchEnd: this.onControlTouchEnd
1755
+ },
1756
+ isDisabled: isDisabled,
1757
+ isFocused: isFocused,
1758
+ menuIsOpen: menuIsOpen
1759
+ }), /*#__PURE__*/React.createElement(ValueContainer, _extends({}, commonProps, {
1760
+ isDisabled: isDisabled
1761
+ }), this.renderPlaceholderOrValue(), this.renderInput()), /*#__PURE__*/React.createElement(IndicatorsContainer, _extends({}, commonProps, {
1762
+ isDisabled: isDisabled
1763
+ }), this.renderClearIndicator(), this.renderLoadingIndicator(), this.renderIndicatorSeparator(), this.renderDropdownIndicator())), this.renderMenu(), this.renderFormField());
1764
+ }
1765
+ }
1766
+ _defineProperty(Select, "defaultProps", defaultProps);