@react-spectrum/combobox 3.16.7 → 3.17.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (240) hide show
  1. package/dist/import.mjs +5 -3
  2. package/dist/main.js +7 -5
  3. package/dist/main.js.map +1 -1
  4. package/dist/module.js +5 -3
  5. package/dist/module.js.map +1 -1
  6. package/dist/types/src/index.d.ts +4 -0
  7. package/package.json +14 -49
  8. package/src/index.ts +5 -3
  9. package/dist/ComboBox.main.js +0 -305
  10. package/dist/ComboBox.main.js.map +0 -1
  11. package/dist/ComboBox.mjs +0 -300
  12. package/dist/ComboBox.module.js +0 -300
  13. package/dist/ComboBox.module.js.map +0 -1
  14. package/dist/MobileComboBox.main.js +0 -432
  15. package/dist/MobileComboBox.main.js.map +0 -1
  16. package/dist/MobileComboBox.mjs +0 -427
  17. package/dist/MobileComboBox.module.js +0 -427
  18. package/dist/MobileComboBox.module.js.map +0 -1
  19. package/dist/ar-AE.main.js +0 -10
  20. package/dist/ar-AE.main.js.map +0 -1
  21. package/dist/ar-AE.mjs +0 -12
  22. package/dist/ar-AE.module.js +0 -12
  23. package/dist/ar-AE.module.js.map +0 -1
  24. package/dist/bg-BG.main.js +0 -10
  25. package/dist/bg-BG.main.js.map +0 -1
  26. package/dist/bg-BG.mjs +0 -12
  27. package/dist/bg-BG.module.js +0 -12
  28. package/dist/bg-BG.module.js.map +0 -1
  29. package/dist/button_vars_css.main.js +0 -125
  30. package/dist/button_vars_css.main.js.map +0 -1
  31. package/dist/button_vars_css.mjs +0 -127
  32. package/dist/button_vars_css.module.js +0 -127
  33. package/dist/button_vars_css.module.js.map +0 -1
  34. package/dist/combobox.1c1869da.css +0 -50
  35. package/dist/combobox.1c1869da.css.map +0 -1
  36. package/dist/combobox.32e7c48f.css +0 -550
  37. package/dist/combobox.32e7c48f.css.map +0 -1
  38. package/dist/combobox.8958325b.css +0 -1669
  39. package/dist/combobox.8958325b.css.map +0 -1
  40. package/dist/combobox.a38acc5c.css +0 -649
  41. package/dist/combobox.a38acc5c.css.map +0 -1
  42. package/dist/combobox.cab3a9ff.css +0 -271
  43. package/dist/combobox.cab3a9ff.css.map +0 -1
  44. package/dist/combobox.cce0a74c.css +0 -223
  45. package/dist/combobox.cce0a74c.css.map +0 -1
  46. package/dist/combobox_css.main.js +0 -35
  47. package/dist/combobox_css.main.js.map +0 -1
  48. package/dist/combobox_css.mjs +0 -37
  49. package/dist/combobox_css.module.js +0 -37
  50. package/dist/combobox_css.module.js.map +0 -1
  51. package/dist/cs-CZ.main.js +0 -10
  52. package/dist/cs-CZ.main.js.map +0 -1
  53. package/dist/cs-CZ.mjs +0 -12
  54. package/dist/cs-CZ.module.js +0 -12
  55. package/dist/cs-CZ.module.js.map +0 -1
  56. package/dist/da-DK.main.js +0 -10
  57. package/dist/da-DK.main.js.map +0 -1
  58. package/dist/da-DK.mjs +0 -12
  59. package/dist/da-DK.module.js +0 -12
  60. package/dist/da-DK.module.js.map +0 -1
  61. package/dist/de-DE.main.js +0 -10
  62. package/dist/de-DE.main.js.map +0 -1
  63. package/dist/de-DE.mjs +0 -12
  64. package/dist/de-DE.module.js +0 -12
  65. package/dist/de-DE.module.js.map +0 -1
  66. package/dist/el-GR.main.js +0 -10
  67. package/dist/el-GR.main.js.map +0 -1
  68. package/dist/el-GR.mjs +0 -12
  69. package/dist/el-GR.module.js +0 -12
  70. package/dist/el-GR.module.js.map +0 -1
  71. package/dist/en-US.main.js +0 -10
  72. package/dist/en-US.main.js.map +0 -1
  73. package/dist/en-US.mjs +0 -12
  74. package/dist/en-US.module.js +0 -12
  75. package/dist/en-US.module.js.map +0 -1
  76. package/dist/es-ES.main.js +0 -10
  77. package/dist/es-ES.main.js.map +0 -1
  78. package/dist/es-ES.mjs +0 -12
  79. package/dist/es-ES.module.js +0 -12
  80. package/dist/es-ES.module.js.map +0 -1
  81. package/dist/et-EE.main.js +0 -10
  82. package/dist/et-EE.main.js.map +0 -1
  83. package/dist/et-EE.mjs +0 -12
  84. package/dist/et-EE.module.js +0 -12
  85. package/dist/et-EE.module.js.map +0 -1
  86. package/dist/fi-FI.main.js +0 -10
  87. package/dist/fi-FI.main.js.map +0 -1
  88. package/dist/fi-FI.mjs +0 -12
  89. package/dist/fi-FI.module.js +0 -12
  90. package/dist/fi-FI.module.js.map +0 -1
  91. package/dist/fieldlabel_vars_css.main.js +0 -95
  92. package/dist/fieldlabel_vars_css.main.js.map +0 -1
  93. package/dist/fieldlabel_vars_css.mjs +0 -97
  94. package/dist/fieldlabel_vars_css.module.js +0 -97
  95. package/dist/fieldlabel_vars_css.module.js.map +0 -1
  96. package/dist/fr-FR.main.js +0 -10
  97. package/dist/fr-FR.main.js.map +0 -1
  98. package/dist/fr-FR.mjs +0 -12
  99. package/dist/fr-FR.module.js +0 -12
  100. package/dist/fr-FR.module.js.map +0 -1
  101. package/dist/he-IL.main.js +0 -10
  102. package/dist/he-IL.main.js.map +0 -1
  103. package/dist/he-IL.mjs +0 -12
  104. package/dist/he-IL.module.js +0 -12
  105. package/dist/he-IL.module.js.map +0 -1
  106. package/dist/hr-HR.main.js +0 -10
  107. package/dist/hr-HR.main.js.map +0 -1
  108. package/dist/hr-HR.mjs +0 -12
  109. package/dist/hr-HR.module.js +0 -12
  110. package/dist/hr-HR.module.js.map +0 -1
  111. package/dist/hu-HU.main.js +0 -10
  112. package/dist/hu-HU.main.js.map +0 -1
  113. package/dist/hu-HU.mjs +0 -12
  114. package/dist/hu-HU.module.js +0 -12
  115. package/dist/hu-HU.module.js.map +0 -1
  116. package/dist/inputgroup_vars_css.main.js +0 -86
  117. package/dist/inputgroup_vars_css.main.js.map +0 -1
  118. package/dist/inputgroup_vars_css.mjs +0 -88
  119. package/dist/inputgroup_vars_css.module.js +0 -88
  120. package/dist/inputgroup_vars_css.module.js.map +0 -1
  121. package/dist/intlStrings.main.js +0 -108
  122. package/dist/intlStrings.main.js.map +0 -1
  123. package/dist/intlStrings.mjs +0 -110
  124. package/dist/intlStrings.module.js +0 -110
  125. package/dist/intlStrings.module.js.map +0 -1
  126. package/dist/it-IT.main.js +0 -10
  127. package/dist/it-IT.main.js.map +0 -1
  128. package/dist/it-IT.mjs +0 -12
  129. package/dist/it-IT.module.js +0 -12
  130. package/dist/it-IT.module.js.map +0 -1
  131. package/dist/ja-JP.main.js +0 -10
  132. package/dist/ja-JP.main.js.map +0 -1
  133. package/dist/ja-JP.mjs +0 -12
  134. package/dist/ja-JP.module.js +0 -12
  135. package/dist/ja-JP.module.js.map +0 -1
  136. package/dist/ko-KR.main.js +0 -10
  137. package/dist/ko-KR.main.js.map +0 -1
  138. package/dist/ko-KR.mjs +0 -12
  139. package/dist/ko-KR.module.js +0 -12
  140. package/dist/ko-KR.module.js.map +0 -1
  141. package/dist/lt-LT.main.js +0 -10
  142. package/dist/lt-LT.main.js.map +0 -1
  143. package/dist/lt-LT.mjs +0 -12
  144. package/dist/lt-LT.module.js +0 -12
  145. package/dist/lt-LT.module.js.map +0 -1
  146. package/dist/lv-LV.main.js +0 -10
  147. package/dist/lv-LV.main.js.map +0 -1
  148. package/dist/lv-LV.mjs +0 -12
  149. package/dist/lv-LV.module.js +0 -12
  150. package/dist/lv-LV.module.js.map +0 -1
  151. package/dist/nb-NO.main.js +0 -10
  152. package/dist/nb-NO.main.js.map +0 -1
  153. package/dist/nb-NO.mjs +0 -12
  154. package/dist/nb-NO.module.js +0 -12
  155. package/dist/nb-NO.module.js.map +0 -1
  156. package/dist/nl-NL.main.js +0 -10
  157. package/dist/nl-NL.main.js.map +0 -1
  158. package/dist/nl-NL.mjs +0 -12
  159. package/dist/nl-NL.module.js +0 -12
  160. package/dist/nl-NL.module.js.map +0 -1
  161. package/dist/pl-PL.main.js +0 -10
  162. package/dist/pl-PL.main.js.map +0 -1
  163. package/dist/pl-PL.mjs +0 -12
  164. package/dist/pl-PL.module.js +0 -12
  165. package/dist/pl-PL.module.js.map +0 -1
  166. package/dist/pt-BR.main.js +0 -10
  167. package/dist/pt-BR.main.js.map +0 -1
  168. package/dist/pt-BR.mjs +0 -12
  169. package/dist/pt-BR.module.js +0 -12
  170. package/dist/pt-BR.module.js.map +0 -1
  171. package/dist/pt-PT.main.js +0 -10
  172. package/dist/pt-PT.main.js.map +0 -1
  173. package/dist/pt-PT.mjs +0 -12
  174. package/dist/pt-PT.module.js +0 -12
  175. package/dist/pt-PT.module.js.map +0 -1
  176. package/dist/ro-RO.main.js +0 -10
  177. package/dist/ro-RO.main.js.map +0 -1
  178. package/dist/ro-RO.mjs +0 -12
  179. package/dist/ro-RO.module.js +0 -12
  180. package/dist/ro-RO.module.js.map +0 -1
  181. package/dist/ru-RU.main.js +0 -10
  182. package/dist/ru-RU.main.js.map +0 -1
  183. package/dist/ru-RU.mjs +0 -12
  184. package/dist/ru-RU.module.js +0 -12
  185. package/dist/ru-RU.module.js.map +0 -1
  186. package/dist/search_vars_css.main.js +0 -53
  187. package/dist/search_vars_css.main.js.map +0 -1
  188. package/dist/search_vars_css.mjs +0 -55
  189. package/dist/search_vars_css.module.js +0 -55
  190. package/dist/search_vars_css.module.js.map +0 -1
  191. package/dist/sk-SK.main.js +0 -10
  192. package/dist/sk-SK.main.js.map +0 -1
  193. package/dist/sk-SK.mjs +0 -12
  194. package/dist/sk-SK.module.js +0 -12
  195. package/dist/sk-SK.module.js.map +0 -1
  196. package/dist/sl-SI.main.js +0 -10
  197. package/dist/sl-SI.main.js.map +0 -1
  198. package/dist/sl-SI.mjs +0 -12
  199. package/dist/sl-SI.module.js +0 -12
  200. package/dist/sl-SI.module.js.map +0 -1
  201. package/dist/sr-SP.main.js +0 -10
  202. package/dist/sr-SP.main.js.map +0 -1
  203. package/dist/sr-SP.mjs +0 -12
  204. package/dist/sr-SP.module.js +0 -12
  205. package/dist/sr-SP.module.js.map +0 -1
  206. package/dist/sv-SE.main.js +0 -10
  207. package/dist/sv-SE.main.js.map +0 -1
  208. package/dist/sv-SE.mjs +0 -12
  209. package/dist/sv-SE.module.js +0 -12
  210. package/dist/sv-SE.module.js.map +0 -1
  211. package/dist/textfield_vars_css.main.js +0 -74
  212. package/dist/textfield_vars_css.main.js.map +0 -1
  213. package/dist/textfield_vars_css.mjs +0 -76
  214. package/dist/textfield_vars_css.module.js +0 -76
  215. package/dist/textfield_vars_css.module.js.map +0 -1
  216. package/dist/tr-TR.main.js +0 -10
  217. package/dist/tr-TR.main.js.map +0 -1
  218. package/dist/tr-TR.mjs +0 -12
  219. package/dist/tr-TR.module.js +0 -12
  220. package/dist/tr-TR.module.js.map +0 -1
  221. package/dist/types.d.ts +0 -13
  222. package/dist/types.d.ts.map +0 -1
  223. package/dist/uk-UA.main.js +0 -10
  224. package/dist/uk-UA.main.js.map +0 -1
  225. package/dist/uk-UA.mjs +0 -12
  226. package/dist/uk-UA.module.js +0 -12
  227. package/dist/uk-UA.module.js.map +0 -1
  228. package/dist/zh-CN.main.js +0 -10
  229. package/dist/zh-CN.main.js.map +0 -1
  230. package/dist/zh-CN.mjs +0 -12
  231. package/dist/zh-CN.module.js +0 -12
  232. package/dist/zh-CN.module.js.map +0 -1
  233. package/dist/zh-TW.main.js +0 -10
  234. package/dist/zh-TW.main.js.map +0 -1
  235. package/dist/zh-TW.mjs +0 -12
  236. package/dist/zh-TW.module.js +0 -12
  237. package/dist/zh-TW.module.js.map +0 -1
  238. package/src/ComboBox.tsx +0 -376
  239. package/src/MobileComboBox.tsx +0 -571
  240. package/src/combobox.css +0 -65
package/src/ComboBox.tsx DELETED
@@ -1,376 +0,0 @@
1
- /*
2
- * Copyright 2020 Adobe. All rights reserved.
3
- * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
- * you may not use this file except in compliance with the License. You may obtain a copy
5
- * of the License at http://www.apache.org/licenses/LICENSE-2.0
6
- *
7
- * Unless required by applicable law or agreed to in writing, software distributed under
8
- * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9
- * OF ANY KIND, either express or implied. See the License for the specific language
10
- * governing permissions and limitations under the License.
11
- */
12
-
13
- import {AriaButtonProps} from '@react-types/button';
14
- import ChevronDownMedium from '@spectrum-icons/ui/ChevronDownMedium';
15
- import {
16
- classNames,
17
- dimensionValue,
18
- useFocusableRef,
19
- useIsMobileDevice,
20
- useResizeObserver,
21
- useUnwrapDOMRef
22
- } from '@react-spectrum/utils';
23
- import comboboxStyles from './combobox.css';
24
- import {DOMRefValue, FocusableRef, FocusableRefValue} from '@react-types/shared';
25
- import {Field} from '@react-spectrum/label';
26
- import {FieldButton} from '@react-spectrum/button';
27
- import {FocusRing} from '@react-aria/focus';
28
- // @ts-ignore
29
- import intlMessages from '../intl/*.json';
30
- import {ListBoxBase, useListBoxLayout} from '@react-spectrum/listbox';
31
- import {MobileComboBox} from './MobileComboBox';
32
- import {Popover} from '@react-spectrum/overlays';
33
- import {PressResponder, useHover} from '@react-aria/interactions';
34
- import {ProgressCircle} from '@react-spectrum/progress';
35
- import React, {
36
- ForwardedRef,
37
- InputHTMLAttributes,
38
- ReactElement,
39
- RefObject,
40
- useCallback,
41
- useEffect,
42
- useRef,
43
- useState
44
- } from 'react';
45
- import {SpectrumComboBoxProps} from '@react-types/combobox';
46
- import styles from '@adobe/spectrum-css-temp/components/inputgroup/vars.css';
47
- import {TextFieldBase} from '@react-spectrum/textfield';
48
- import textfieldStyles from '@adobe/spectrum-css-temp/components/textfield/vars.css';
49
- import {useComboBox} from '@react-aria/combobox';
50
- import {useComboBoxState} from '@react-stately/combobox';
51
- import {useFilter, useLocalizedStringFormatter} from '@react-aria/i18n';
52
- import {useFormProps} from '@react-spectrum/form';
53
- import {useLayoutEffect} from '@react-aria/utils';
54
- import {useProvider, useProviderProps} from '@react-spectrum/provider';
55
-
56
- /**
57
- * ComboBoxes combine a text entry with a picker menu, allowing users to filter longer lists to only the selections matching a query.
58
- */
59
- export const ComboBox = React.forwardRef(function ComboBox<T extends object>(props: SpectrumComboBoxProps<T>, ref: FocusableRef<HTMLElement>) {
60
- props = useProviderProps(props);
61
- props = useFormProps(props);
62
-
63
- let hasWarned = useRef(false);
64
- useEffect(() => {
65
- if (props.placeholder && !hasWarned.current && process.env.NODE_ENV !== 'production') {
66
- console.warn('Placeholders are deprecated due to accessibility issues. Please use help text instead. See the docs for details: https://react-spectrum.adobe.com/react-spectrum/ComboBox.html#help-text');
67
- hasWarned.current = true;
68
- }
69
- }, [props.placeholder]);
70
-
71
- let isMobile = useIsMobileDevice();
72
- if (isMobile) {
73
- // menuTrigger=focus/manual don't apply to mobile combobox
74
- return <MobileComboBox {...props} menuTrigger="input" ref={ref} />;
75
- } else {
76
- return <ComboBoxBase {...props} ref={ref} />;
77
- }
78
- }) as <T>(props: SpectrumComboBoxProps<T> & {ref?: FocusableRef<HTMLElement>}) => ReactElement;
79
-
80
- const ComboBoxBase = React.forwardRef(function ComboBoxBase(props: SpectrumComboBoxProps<any>, ref: FocusableRef<HTMLElement>) {
81
- let {
82
- menuTrigger = 'input',
83
- shouldFlip = true,
84
- direction = 'bottom',
85
- align = 'start',
86
- isQuiet,
87
- loadingState,
88
- onLoadMore,
89
- allowsCustomValue,
90
- menuWidth: customMenuWidth,
91
- name,
92
- formValue = 'text'
93
- } = props;
94
- if (allowsCustomValue) {
95
- formValue = 'text';
96
- }
97
-
98
- let stringFormatter = useLocalizedStringFormatter(intlMessages, '@react-spectrum/combobox');
99
- let isAsync = loadingState != null;
100
- let popoverRef = useRef<DOMRefValue<HTMLDivElement>>(null);
101
- let unwrappedPopoverRef = useUnwrapDOMRef(popoverRef);
102
- let buttonRef = useRef<FocusableRefValue<HTMLElement>>(null);
103
- let unwrappedButtonRef = useUnwrapDOMRef(buttonRef);
104
- let listBoxRef = useRef(null);
105
- let inputRef = useRef<HTMLInputElement>(null);
106
- // serve as the new popover `triggerRef` instead of `unwrappedButtonRef` before for better positioning.
107
- let inputGroupRef = useRef<HTMLDivElement>(null);
108
- let domRef = useFocusableRef(ref, inputRef);
109
-
110
- let {contains} = useFilter({sensitivity: 'base'});
111
- let state = useComboBoxState(
112
- {
113
- ...props,
114
- defaultFilter: contains,
115
- allowsEmptyCollection: isAsync
116
- }
117
- );
118
- let layout = useListBoxLayout();
119
-
120
- let {buttonProps, inputProps, listBoxProps, labelProps, descriptionProps, errorMessageProps, isInvalid, validationErrors, validationDetails} = useComboBox(
121
- {
122
- ...props,
123
- layoutDelegate: layout,
124
- buttonRef: unwrappedButtonRef,
125
- popoverRef: unwrappedPopoverRef,
126
- listBoxRef,
127
- inputRef: inputRef,
128
- menuTrigger,
129
- name: formValue === 'text' ? name : undefined
130
- },
131
- state
132
- );
133
-
134
- // Measure the width of the inputfield and the button to inform the width of the menu (below).
135
- let [menuWidth, setMenuWidth] = useState<number | undefined>(undefined);
136
- let {scale} = useProvider();
137
-
138
- let onResize = useCallback(() => {
139
- if (unwrappedButtonRef.current && inputRef.current) {
140
- let buttonWidth = unwrappedButtonRef.current.offsetWidth;
141
- let inputWidth = inputRef.current.offsetWidth;
142
- setMenuWidth(buttonWidth + inputWidth);
143
- }
144
- }, [unwrappedButtonRef, inputRef, setMenuWidth]);
145
-
146
- useResizeObserver({
147
- ref: domRef,
148
- onResize: onResize
149
- });
150
-
151
- useLayoutEffect(onResize, [scale, onResize]);
152
-
153
- let width = isQuiet ? undefined : menuWidth;
154
- let style = {
155
- width: customMenuWidth ? dimensionValue(customMenuWidth) : width,
156
- minWidth: isQuiet ? `calc(${menuWidth}px + calc(2 * var(--spectrum-dropdown-quiet-offset)))` : menuWidth
157
- };
158
- let cbInputProps = {...props, children: null};
159
-
160
- return (
161
- <>
162
- <Field
163
- {...props}
164
- descriptionProps={descriptionProps}
165
- errorMessageProps={errorMessageProps}
166
- isInvalid={isInvalid}
167
- validationErrors={validationErrors}
168
- validationDetails={validationDetails}
169
- labelProps={labelProps}
170
- ref={domRef}>
171
- <ComboBoxInput
172
- {...cbInputProps}
173
- isOpen={state.isOpen}
174
- loadingState={loadingState}
175
- inputProps={inputProps}
176
- inputRef={inputRef}
177
- triggerProps={buttonProps}
178
- triggerRef={buttonRef}
179
- validationState={props.validationState || (isInvalid ? 'invalid' : undefined)}
180
- ref={inputGroupRef} />
181
- </Field>
182
- {name && formValue === 'key' && <input type="hidden" name={name} form={props.form} value={state.selectedKey ?? ''} />}
183
- <Popover
184
- state={state}
185
- UNSAFE_style={style}
186
- UNSAFE_className={classNames(styles, 'spectrum-InputGroup-popover', {'spectrum-InputGroup-popover--quiet': isQuiet})}
187
- ref={popoverRef}
188
- triggerRef={inputGroupRef}
189
- scrollRef={listBoxRef}
190
- placement={`${direction} ${align}`}
191
- hideArrow
192
- isNonModal
193
- shouldFlip={shouldFlip}>
194
- <ListBoxBase
195
- {...listBoxProps}
196
- ref={listBoxRef}
197
- disallowEmptySelection
198
- shouldSelectOnPressUp
199
- focusOnPointerEnter
200
- layout={layout}
201
- state={state}
202
- shouldUseVirtualFocus
203
- isLoading={loadingState === 'loading' || loadingState === 'loadingMore'}
204
- showLoadingSpinner={loadingState === 'loadingMore'}
205
- onLoadMore={onLoadMore}
206
- renderEmptyState={() => isAsync && (
207
- <span className={classNames(comboboxStyles, 'no-results')}>
208
- {loadingState === 'loading' ? stringFormatter.format('loading') : stringFormatter.format('noResults')}
209
- </span>
210
- )} />
211
- </Popover>
212
- </>
213
- );
214
- });
215
-
216
- interface ComboBoxInputProps extends SpectrumComboBoxProps<unknown> {
217
- inputProps: InputHTMLAttributes<HTMLInputElement>,
218
- inputRef: RefObject<HTMLInputElement | HTMLTextAreaElement | null>,
219
- triggerProps: AriaButtonProps,
220
- triggerRef: RefObject<FocusableRefValue<HTMLElement> | null>,
221
- style?: React.CSSProperties,
222
- className?: string,
223
- isOpen?: boolean
224
- }
225
-
226
- const ComboBoxInput = React.forwardRef(function ComboBoxInput(props: ComboBoxInputProps, ref: ForwardedRef<HTMLElement | null>) {
227
- let {
228
- isQuiet,
229
- isDisabled,
230
- validationState,
231
- inputProps,
232
- inputRef,
233
- triggerProps,
234
- triggerRef,
235
- autoFocus,
236
- style,
237
- className,
238
- loadingState,
239
- isOpen,
240
- menuTrigger
241
- } = props;
242
- let {hoverProps, isHovered} = useHover({});
243
- let stringFormatter = useLocalizedStringFormatter(intlMessages, '@react-spectrum/combobox');
244
- let timeout = useRef<ReturnType<typeof setTimeout> | null>(null);
245
- let [showLoading, setShowLoading] = useState(false);
246
-
247
- let loadingCircle = (
248
- <ProgressCircle
249
- aria-label={stringFormatter.format('loading')}
250
- size="S"
251
- isIndeterminate
252
- UNSAFE_className={classNames(
253
- textfieldStyles,
254
- 'spectrum-Textfield-circleLoader',
255
- classNames(
256
- styles,
257
- 'spectrum-InputGroup-input-circleLoader'
258
- )
259
- )} />
260
- );
261
-
262
- let isLoading = loadingState === 'loading' || loadingState === 'filtering';
263
- let inputValue = inputProps.value;
264
- let lastInputValue = useRef(inputValue);
265
- useEffect(() => {
266
- if (isLoading && !showLoading) {
267
- if (timeout.current === null) {
268
- timeout.current = setTimeout(() => {
269
- setShowLoading(true);
270
- }, 500);
271
- }
272
-
273
- // If user is typing, clear the timer and restart since it is a new request
274
- if (inputValue !== lastInputValue.current) {
275
- clearTimeout(timeout.current);
276
- timeout.current = setTimeout(() => {
277
- setShowLoading(true);
278
- }, 500);
279
- }
280
- } else if (!isLoading) {
281
- if (timeout.current) {
282
- clearTimeout(timeout.current);
283
- }
284
- timeout.current = null;
285
- }
286
-
287
- lastInputValue.current = inputValue;
288
- }, [isLoading, showLoading, inputValue]);
289
-
290
- let [prevIsLoading, setPrevIsLoading] = useState(isLoading);
291
- if (prevIsLoading !== isLoading && !isLoading) {
292
- setShowLoading(false);
293
- setPrevIsLoading(isLoading);
294
- }
295
-
296
- useEffect(() => {
297
- return () => {
298
- if (timeout.current) {
299
- clearTimeout(timeout.current);
300
- }
301
- timeout.current = null;
302
- };
303
- }, []);
304
-
305
- return (
306
- (<FocusRing
307
- within
308
- isTextInput
309
- focusClass={classNames(styles, 'is-focused')}
310
- focusRingClass={classNames(styles, 'focus-ring')}
311
- autoFocus={autoFocus}>
312
- <div
313
- {...hoverProps}
314
- ref={ref as RefObject<HTMLDivElement | null>}
315
- style={style}
316
- className={
317
- classNames(
318
- styles,
319
- 'spectrum-InputGroup',
320
- {
321
- 'spectrum-InputGroup--quiet': isQuiet,
322
- 'is-disabled': isDisabled,
323
- 'spectrum-InputGroup--invalid': validationState === 'invalid' && !isDisabled,
324
- 'is-hovered': isHovered
325
- },
326
- className
327
- )
328
- }>
329
- <TextFieldBase
330
- inputProps={inputProps}
331
- inputRef={inputRef}
332
- UNSAFE_className={
333
- classNames(
334
- styles,
335
- 'spectrum-InputGroup-field'
336
- )
337
- }
338
- inputClassName={
339
- classNames(
340
- styles,
341
- 'spectrum-InputGroup-input'
342
- )
343
- }
344
- validationIconClassName={
345
- classNames(
346
- styles,
347
- 'spectrum-InputGroup-input-validationIcon'
348
- )
349
- }
350
- isDisabled={isDisabled}
351
- isQuiet={isQuiet}
352
- validationState={validationState}
353
- // loading circle should only be displayed if menu is open, if menuTrigger is "manual", or first time load (to stop circle from showing up when user selects an option)
354
- // TODO: add special case for completionMode: complete as well
355
- isLoading={showLoading && (isOpen || menuTrigger === 'manual' || loadingState === 'loading')}
356
- loadingIndicator={loadingState != null ? loadingCircle : undefined}
357
- disableFocusRing />
358
- <PressResponder preventFocusOnPress isPressed={isOpen}>
359
- <FieldButton
360
- {...triggerProps}
361
- ref={triggerRef}
362
- UNSAFE_className={
363
- classNames(
364
- styles,
365
- 'spectrum-FieldButton'
366
- )
367
- }
368
- isQuiet={isQuiet}
369
- validationState={validationState}>
370
- <ChevronDownMedium UNSAFE_className={classNames(styles, 'spectrum-Dropdown-chevron')} />
371
- </FieldButton>
372
- </PressResponder>
373
- </div>
374
- </FocusRing>)
375
- );
376
- });