@react-spectrum/autocomplete 3.0.0-alpha.11 → 3.0.0-alpha.13

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.
@@ -27,7 +27,15 @@ import {ListBoxBase, useListBoxLayout} from '@react-spectrum/listbox';
27
27
  import Magnifier from '@spectrum-icons/ui/Magnifier';
28
28
  import {mergeProps, useId} from '@react-aria/utils';
29
29
  import {ProgressCircle} from '@react-spectrum/progress';
30
- import React, {HTMLAttributes, ReactElement, ReactNode, RefObject, useCallback, useEffect, useRef, useState} from 'react';
30
+ import React, {
31
+ HTMLAttributes,
32
+ ReactElement,
33
+ ReactNode,
34
+ useCallback,
35
+ useEffect,
36
+ useRef,
37
+ useState
38
+ } from 'react';
31
39
  import searchAutocompleteStyles from './searchautocomplete.css';
32
40
  import searchStyles from '@adobe/spectrum-css-temp/components/search/vars.css';
33
41
  import {setInteractionModality, useHover} from '@react-aria/interactions';
@@ -45,7 +53,7 @@ import {useOverlayTrigger} from '@react-aria/overlays';
45
53
  import {useProviderProps} from '@react-spectrum/provider';
46
54
  import {useSearchAutocomplete} from '@react-aria/autocomplete';
47
55
 
48
- export const MobileSearchAutocomplete = React.forwardRef(function MobileSearchAutocomplete<T extends object>(props: SpectrumSearchAutocompleteProps<T>, ref: FocusableRef<HTMLElement>) {
56
+ function _MobileSearchAutocomplete<T extends object>(props: SpectrumSearchAutocompleteProps<T>, ref: FocusableRef<HTMLElement>) {
49
57
  props = useProviderProps(props);
50
58
 
51
59
  let {
@@ -71,7 +79,7 @@ export const MobileSearchAutocomplete = React.forwardRef(function MobileSearchAu
71
79
  defaultSelectedKey: undefined
72
80
  });
73
81
 
74
- let buttonRef = useRef<HTMLElement>();
82
+ let buttonRef = useRef<HTMLDivElement>(null);
75
83
  let domRef = useFocusableRef(ref, buttonRef);
76
84
  let {triggerProps, overlayProps} = useOverlayTrigger({type: 'listbox'}, state, buttonRef);
77
85
 
@@ -82,14 +90,12 @@ export const MobileSearchAutocomplete = React.forwardRef(function MobileSearchAu
82
90
 
83
91
  // Focus the button and show focus ring when clicking on the label
84
92
  labelProps.onClick = () => {
85
- if (!props.isDisabled) {
93
+ if (!props.isDisabled && buttonRef.current) {
86
94
  buttonRef.current.focus();
87
95
  setInteractionModality('keyboard');
88
96
  }
89
97
  };
90
98
 
91
- let onClose = () => state.commit();
92
-
93
99
  return (
94
100
  <>
95
101
  <Field
@@ -112,19 +118,22 @@ export const MobileSearchAutocomplete = React.forwardRef(function MobileSearchAu
112
118
  {state.inputValue || props.placeholder || ''}
113
119
  </SearchAutocompleteButton>
114
120
  </Field>
115
- <Tray isOpen={state.isOpen} onClose={onClose} isFixedHeight isNonModal {...overlayProps}>
121
+ <Tray state={state} isFixedHeight {...overlayProps}>
116
122
  <SearchAutocompleteTray
117
123
  {...props}
118
- onClose={onClose}
124
+ onClose={state.close}
119
125
  overlayProps={overlayProps}
120
126
  state={state} />
121
127
  </Tray>
122
128
  </>
123
129
  );
124
- });
130
+ }
131
+
132
+ export let MobileSearchAutocomplete = React.forwardRef(_MobileSearchAutocomplete) as <T>(props: SpectrumSearchAutocompleteProps<T> & {ref?: FocusableRef<HTMLElement>}) => ReactElement;
133
+
125
134
 
126
135
  interface SearchAutocompleteButtonProps extends AriaButtonProps {
127
- icon?: ReactElement,
136
+ icon?: ReactElement | null,
128
137
  isQuiet?: boolean,
129
138
  isDisabled?: boolean,
130
139
  isReadOnly?: boolean,
@@ -137,7 +146,9 @@ interface SearchAutocompleteButtonProps extends AriaButtonProps {
137
146
  className?: string
138
147
  }
139
148
 
140
- const SearchAutocompleteButton = React.forwardRef(function SearchAutocompleteButton(props: SearchAutocompleteButtonProps, ref: RefObject<HTMLElement>) {
149
+ // any type is because we don't want to call useObjectRef because this is an internal component and we know
150
+ // we are always passing an object ref
151
+ const SearchAutocompleteButton = React.forwardRef(function SearchAutocompleteButton(props: SearchAutocompleteButtonProps, ref: any) {
141
152
  let searchIcon = (
142
153
  <Magnifier data-testid="searchicon" />
143
154
  );
@@ -175,8 +186,8 @@ const SearchAutocompleteButton = React.forwardRef(function SearchAutocompleteBut
175
186
  let clearButton = (
176
187
  <ClearButton
177
188
  onPress={(e) => {
178
- clearInput();
179
- props.onPress(e);
189
+ clearInput?.();
190
+ props?.onPress?.(e);
180
191
  }}
181
192
  preventFocus
182
193
  aria-label={stringFormatter.format('clear')}
@@ -190,7 +201,6 @@ const SearchAutocompleteButton = React.forwardRef(function SearchAutocompleteBut
190
201
  isDisabled={isDisabled} />
191
202
  );
192
203
 
193
-
194
204
  let validation = React.cloneElement(validationIcon, {
195
205
  UNSAFE_className: classNames(
196
206
  textfieldStyles,
@@ -219,7 +229,7 @@ const SearchAutocompleteButton = React.forwardRef(function SearchAutocompleteBut
219
229
  <div
220
230
  {...mergeProps(hoverProps, focusProps, buttonProps)}
221
231
  aria-haspopup="dialog"
222
- ref={ref as RefObject<HTMLDivElement>}
232
+ ref={ref}
223
233
  style={{...style, outline: 'none'}}
224
234
  className={
225
235
  classNames(
@@ -228,13 +238,14 @@ const SearchAutocompleteButton = React.forwardRef(function SearchAutocompleteBut
228
238
  {
229
239
  'spectrum-InputGroup--quiet': isQuiet,
230
240
  'is-disabled': isDisabled,
231
- 'spectrum-InputGroup--invalid': validationState === 'invalid',
241
+ 'spectrum-InputGroup--invalid': validationState === 'invalid' && !isDisabled,
232
242
  'is-hovered': isHovered,
233
243
  'is-focused': isFocused,
234
244
  'focus-ring': isFocusVisible
235
245
  },
236
246
  classNames(
237
247
  searchAutocompleteStyles,
248
+ 'searchautocomplete',
238
249
  'mobile-searchautocomplete'
239
250
  ),
240
251
  className
@@ -246,8 +257,8 @@ const SearchAutocompleteButton = React.forwardRef(function SearchAutocompleteBut
246
257
  textfieldStyles,
247
258
  'spectrum-Textfield',
248
259
  {
249
- 'spectrum-Textfield--invalid': validationState === 'invalid',
250
- 'spectrum-Textfield--valid': validationState === 'valid',
260
+ 'spectrum-Textfield--invalid': validationState === 'invalid' && !isDisabled,
261
+ 'spectrum-Textfield--valid': validationState === 'valid' && !isDisabled,
251
262
  'spectrum-Textfield--quiet': isQuiet
252
263
  },
253
264
  classNames(
@@ -256,8 +267,8 @@ const SearchAutocompleteButton = React.forwardRef(function SearchAutocompleteBut
256
267
  {
257
268
  'is-disabled': isDisabled,
258
269
  'is-quiet': isQuiet,
259
- 'spectrum-Search--invalid': validationState === 'invalid',
260
- 'spectrum-Search--valid': validationState === 'valid'
270
+ 'spectrum-Search--invalid': validationState === 'invalid' && !isDisabled,
271
+ 'spectrum-Search--valid': validationState === 'valid' && !isDisabled
261
272
  }
262
273
  )
263
274
  )
@@ -273,8 +284,7 @@ const SearchAutocompleteButton = React.forwardRef(function SearchAutocompleteBut
273
284
  'is-placeholder': isPlaceholder,
274
285
  'is-disabled': isDisabled,
275
286
  'is-quiet': isQuiet,
276
- 'is-focused': isFocused,
277
- 'focus-ring': isFocusVisible
287
+ 'is-focused': isFocused
278
288
  },
279
289
  classNames(
280
290
  searchStyles,
@@ -298,21 +308,21 @@ const SearchAutocompleteButton = React.forwardRef(function SearchAutocompleteBut
298
308
  {children}
299
309
  </span>
300
310
  </div>
301
- {validationState ? validation : null}
311
+ {validationState && !isDisabled ? validation : null}
302
312
  {(inputValue !== '' || validationState != null) && !isReadOnly && clearButton}
303
313
  </div>
304
314
  </div>
305
315
  );
306
316
  });
307
317
 
308
- interface SearchAutocompleteTrayProps extends SpectrumSearchAutocompleteProps<unknown> {
309
- state: ComboBoxState<unknown>,
318
+ interface SearchAutocompleteTrayProps<T> extends SpectrumSearchAutocompleteProps<T> {
319
+ state: ComboBoxState<T>,
310
320
  overlayProps: HTMLAttributes<HTMLElement>,
311
321
  loadingIndicator?: ReactElement,
312
322
  onClose: () => void
313
323
  }
314
324
 
315
- function SearchAutocompleteTray(props: SearchAutocompleteTrayProps) {
325
+ function SearchAutocompleteTray<T>(props: SearchAutocompleteTrayProps<T>) {
316
326
  let searchIcon = (
317
327
  <Magnifier data-testid="searchicon" />
318
328
  );
@@ -331,15 +341,15 @@ function SearchAutocompleteTray(props: SearchAutocompleteTrayProps) {
331
341
  onSubmit
332
342
  } = props;
333
343
 
334
- let timeout = useRef(null);
344
+ let timeout = useRef<ReturnType<typeof setTimeout> | null>(null);
335
345
  let [showLoading, setShowLoading] = useState(false);
336
- let inputRef = useRef<HTMLInputElement>();
337
- let popoverRef = useRef<HTMLDivElement>();
338
- let listBoxRef = useRef<HTMLDivElement>();
346
+ let inputRef = useRef<HTMLInputElement>(null);
347
+ let popoverRef = useRef<HTMLDivElement>(null);
348
+ let listBoxRef = useRef<HTMLDivElement>(null);
339
349
  let layout = useListBoxLayout(state);
340
350
  let stringFormatter = useLocalizedStringFormatter(intlMessages);
341
351
 
342
- let {inputProps, listBoxProps, labelProps, clearButtonProps} = useSearchAutocomplete(
352
+ let {inputProps, listBoxProps, labelProps, clearButtonProps} = useSearchAutocomplete<T>(
343
353
  {
344
354
  ...props,
345
355
  keyboardDelegate: layout,
@@ -351,7 +361,9 @@ function SearchAutocompleteTray(props: SearchAutocompleteTrayProps) {
351
361
  );
352
362
 
353
363
  React.useEffect(() => {
354
- focusSafely(inputRef.current);
364
+ if (inputRef.current) {
365
+ focusSafely(inputRef.current);
366
+ }
355
367
 
356
368
  // When the tray unmounts, set state.isFocused (i.e. the tray input's focus tracker) to false.
357
369
  // This is to prevent state.isFocused from being set to true when the tray closes via tapping on the underlay
@@ -423,7 +435,9 @@ function SearchAutocompleteTray(props: SearchAutocompleteTrayProps) {
423
435
  return;
424
436
  }
425
437
 
426
- popoverRef.current.focus();
438
+ if (popoverRef.current) {
439
+ popoverRef.current.focus();
440
+ }
427
441
  }, [inputRef, popoverRef, isTouchDown]);
428
442
 
429
443
  let inputValue = inputProps.value;
@@ -446,8 +460,10 @@ function SearchAutocompleteTray(props: SearchAutocompleteTrayProps) {
446
460
  } else if (loadingState !== 'filtering') {
447
461
  // If loading is no longer happening, clear any timers and hide the loading circle
448
462
  setShowLoading(false);
449
- clearTimeout(timeout.current);
450
- timeout.current = null;
463
+ if (timeout.current !== null) {
464
+ clearTimeout(timeout.current);
465
+ timeout.current = null;
466
+ }
451
467
  }
452
468
 
453
469
  lastInputValue.current = inputValue;
@@ -456,11 +472,17 @@ function SearchAutocompleteTray(props: SearchAutocompleteTrayProps) {
456
472
  let onKeyDown = (e) => {
457
473
  // Close virtual keyboard, close tray, and fire onSubmit if user hits Enter w/o any focused options
458
474
  if (e.key === 'Enter' && state.selectionManager.focusedKey == null) {
459
- popoverRef.current.focus();
460
- onClose();
461
- onSubmit(inputValue.toString(), null);
475
+ popoverRef.current?.focus();
476
+ if (onClose) {
477
+ onClose();
478
+ }
479
+ if (onSubmit) {
480
+ onSubmit(inputValue == null ? null : inputValue.toString(), null);
481
+ }
462
482
  } else {
463
- inputProps.onKeyDown(e);
483
+ if (inputProps.onKeyDown) {
484
+ inputProps.onKeyDown(e);
485
+ }
464
486
  }
465
487
  };
466
488
 
@@ -493,9 +515,9 @@ function SearchAutocompleteTray(props: SearchAutocompleteTrayProps) {
493
515
  inputRef={inputRef}
494
516
  isDisabled={isDisabled}
495
517
  isLoading={showLoading && loadingState === 'filtering'}
496
- loadingIndicator={loadingState != null && loadingCircle}
518
+ loadingIndicator={loadingState != null ? loadingCircle : undefined}
497
519
  validationState={validationState}
498
- wrapperChildren={(state.inputValue !== '' || loadingState === 'filtering' || validationState != null) && !props.isReadOnly && clearButton}
520
+ wrapperChildren={((state.inputValue !== '' || loadingState === 'filtering' || validationState != null) && !props.isReadOnly) ? clearButton : undefined}
499
521
  icon={icon}
500
522
  UNSAFE_className={
501
523
  classNames(
@@ -504,8 +526,8 @@ function SearchAutocompleteTray(props: SearchAutocompleteTrayProps) {
504
526
  'spectrum-Textfield',
505
527
  'spectrum-Search--loadable',
506
528
  {
507
- 'spectrum-Search--invalid': validationState === 'invalid',
508
- 'spectrum-Search--valid': validationState === 'valid'
529
+ 'spectrum-Search--invalid': validationState === 'invalid' && !isDisabled,
530
+ 'spectrum-Search--valid': validationState === 'valid' && !isDisabled
509
531
  },
510
532
  classNames(
511
533
  searchAutocompleteStyles,
@@ -12,7 +12,6 @@
12
12
  import {AriaButtonProps} from '@react-types/button';
13
13
  import {classNames, useFocusableRef, useIsMobileDevice, useResizeObserver, useUnwrapDOMRef} from '@react-spectrum/utils';
14
14
  import {ClearButton} from '@react-spectrum/button';
15
- import {DismissButton, useOverlayPosition} from '@react-aria/overlays';
16
15
  import {DOMRefValue, FocusableRef} from '@react-types/shared';
17
16
  import {Field} from '@react-spectrum/label';
18
17
  import {FocusRing} from '@react-aria/focus';
@@ -21,10 +20,19 @@ import intlMessages from '../intl/*.json';
21
20
  import {ListBoxBase, useListBoxLayout} from '@react-spectrum/listbox';
22
21
  import Magnifier from '@spectrum-icons/ui/Magnifier';
23
22
  import {MobileSearchAutocomplete} from './MobileSearchAutocomplete';
24
- import {Placement} from '@react-types/overlays';
25
23
  import {Popover} from '@react-spectrum/overlays';
26
24
  import {ProgressCircle} from '@react-spectrum/progress';
27
- import React, {forwardRef, InputHTMLAttributes, RefObject, useCallback, useEffect, useRef, useState} from 'react';
25
+ import React, {
26
+ forwardRef,
27
+ InputHTMLAttributes,
28
+ ReactElement,
29
+ RefObject,
30
+ useCallback,
31
+ useEffect,
32
+ useRef,
33
+ useState
34
+ } from 'react';
35
+ import searchAutocompleteStyles from './searchautocomplete.css';
28
36
  import searchStyles from '@adobe/spectrum-css-temp/components/search/vars.css';
29
37
  import {SpectrumSearchAutocompleteProps} from '@react-types/autocomplete';
30
38
  import styles from '@adobe/spectrum-css-temp/components/inputgroup/vars.css';
@@ -53,7 +61,7 @@ function SearchAutocomplete<T extends object>(props: SpectrumSearchAutocompleteP
53
61
  }
54
62
  }
55
63
 
56
- const SearchAutocompleteBase = React.forwardRef(function SearchAutocompleteBase<T extends object>(props: SpectrumSearchAutocompleteProps<T>, ref: FocusableRef<HTMLElement>) {
64
+ function _SearchAutocompleteBase<T extends object>(props: SpectrumSearchAutocompleteProps<T>, ref: FocusableRef<HTMLElement>) {
57
65
  props = useProviderProps(props);
58
66
 
59
67
  let {
@@ -68,10 +76,10 @@ const SearchAutocompleteBase = React.forwardRef(function SearchAutocompleteBase<
68
76
 
69
77
  let stringFormatter = useLocalizedStringFormatter(intlMessages);
70
78
  let isAsync = loadingState != null;
71
- let popoverRef = useRef<DOMRefValue<HTMLDivElement>>();
79
+ let popoverRef = useRef<DOMRefValue<HTMLDivElement>>(null);
72
80
  let unwrappedPopoverRef = useUnwrapDOMRef(popoverRef);
73
- let listBoxRef = useRef();
74
- let inputRef = useRef<HTMLInputElement>();
81
+ let listBoxRef = useRef(null);
82
+ let inputRef = useRef<HTMLInputElement>(null);
75
83
  let domRef = useFocusableRef(ref, inputRef);
76
84
 
77
85
  let {contains} = useFilter({sensitivity: 'base'});
@@ -100,18 +108,8 @@ const SearchAutocompleteBase = React.forwardRef(function SearchAutocompleteBase<
100
108
  state
101
109
  );
102
110
 
103
- let {overlayProps, placement, updatePosition} = useOverlayPosition({
104
- targetRef: inputRef,
105
- overlayRef: unwrappedPopoverRef,
106
- scrollRef: listBoxRef,
107
- placement: `${direction} end` as Placement,
108
- shouldFlip: shouldFlip,
109
- isOpen: state.isOpen,
110
- onClose: state.close
111
- });
112
-
113
111
  // Measure the width of the inputfield to inform the width of the menu (below).
114
- let [menuWidth, setMenuWidth] = useState(null);
112
+ let [menuWidth, setMenuWidth] = useState<number>(0);
115
113
  let {scale} = useProvider();
116
114
 
117
115
  let onResize = useCallback(() => {
@@ -128,20 +126,8 @@ const SearchAutocompleteBase = React.forwardRef(function SearchAutocompleteBase<
128
126
 
129
127
  useLayoutEffect(onResize, [scale, onResize]);
130
128
 
131
- // Update position once the ListBox has rendered. This ensures that
132
- // it flips properly when it doesn't fit in the available space.
133
- // TODO: add ResizeObserver to useOverlayPosition so we don't need this.
134
- useLayoutEffect(() => {
135
- if (state.isOpen) {
136
- requestAnimationFrame(() => {
137
- updatePosition();
138
- });
139
- }
140
- }, [state.isOpen, updatePosition]);
141
-
142
129
  let style = {
143
- ...overlayProps.style,
144
- width: isQuiet ? null : menuWidth,
130
+ width: isQuiet ? undefined : menuWidth,
145
131
  minWidth: isQuiet ? `calc(${menuWidth}px + calc(2 * var(--spectrum-dropdown-quiet-offset)))` : menuWidth
146
132
  };
147
133
 
@@ -157,14 +143,15 @@ const SearchAutocompleteBase = React.forwardRef(function SearchAutocompleteBase<
157
143
  clearButtonProps={clearButtonProps} />
158
144
  </Field>
159
145
  <Popover
160
- isOpen={state.isOpen}
146
+ state={state}
161
147
  UNSAFE_style={style}
162
148
  UNSAFE_className={classNames(styles, 'spectrum-InputGroup-popover', {'spectrum-InputGroup-popover--quiet': isQuiet})}
163
149
  ref={popoverRef}
164
- placement={placement}
150
+ triggerRef={inputRef}
151
+ placement={`${direction} end`}
165
152
  hideArrow
166
153
  isNonModal
167
- isDismissable={false}>
154
+ shouldFlip={shouldFlip}>
168
155
  <ListBoxBase
169
156
  {...listBoxProps}
170
157
  ref={listBoxRef}
@@ -182,13 +169,15 @@ const SearchAutocompleteBase = React.forwardRef(function SearchAutocompleteBase<
182
169
  {stringFormatter.format('noResults')}
183
170
  </span>
184
171
  )} />
185
- <DismissButton onDismiss={() => state.close()} />
186
172
  </Popover>
187
173
  </>
188
174
  );
189
- });
175
+ }
176
+
177
+ let SearchAutocompleteBase = React.forwardRef(_SearchAutocompleteBase) as <T>(props: SpectrumSearchAutocompleteProps<T> & {ref?: FocusableRef<HTMLElement>}) => ReactElement;
190
178
 
191
- interface SearchAutocompleteInputProps extends SpectrumSearchAutocompleteProps<unknown> {
179
+
180
+ interface SearchAutocompleteInputProps<T> extends SpectrumSearchAutocompleteProps<T> {
192
181
  inputProps: InputHTMLAttributes<HTMLInputElement>,
193
182
  inputRef: RefObject<HTMLInputElement | HTMLTextAreaElement>,
194
183
  style?: React.CSSProperties,
@@ -197,7 +186,9 @@ interface SearchAutocompleteInputProps extends SpectrumSearchAutocompleteProps<u
197
186
  clearButtonProps: AriaButtonProps
198
187
  }
199
188
 
200
- const SearchAutocompleteInput = React.forwardRef(function SearchAutocompleteInput(props: SearchAutocompleteInputProps, ref: RefObject<HTMLElement>) {
189
+ // any type is because we don't want to call useObjectRef because this is an internal component and we know
190
+ // we are always passing an object ref
191
+ function _SearchAutocompleteInput<T>(props: SearchAutocompleteInputProps<T>, ref: any) {
201
192
  let searchIcon = (
202
193
  <Magnifier data-testid="searchicon" />
203
194
  );
@@ -220,7 +211,7 @@ const SearchAutocompleteInput = React.forwardRef(function SearchAutocompleteInpu
220
211
  } = props;
221
212
  let {hoverProps, isHovered} = useHover({});
222
213
  let stringFormatter = useLocalizedStringFormatter(intlMessages);
223
- let timeout = useRef(null);
214
+ let timeout = useRef<ReturnType<typeof setTimeout> | null>(null);
224
215
  let [showLoading, setShowLoading] = useState(false);
225
216
 
226
217
  let loadingCircle = (
@@ -272,8 +263,10 @@ const SearchAutocompleteInput = React.forwardRef(function SearchAutocompleteInpu
272
263
  } else if (!isLoading) {
273
264
  // If loading is no longer happening, clear any timers and hide the loading circle
274
265
  setShowLoading(false);
275
- clearTimeout(timeout.current);
276
- timeout.current = null;
266
+ if (timeout.current != null) {
267
+ clearTimeout(timeout.current);
268
+ timeout.current = null;
269
+ }
277
270
  }
278
271
 
279
272
  lastInputValue.current = inputValue;
@@ -297,9 +290,13 @@ const SearchAutocompleteInput = React.forwardRef(function SearchAutocompleteInpu
297
290
  {
298
291
  'spectrum-InputGroup--quiet': isQuiet,
299
292
  'is-disabled': isDisabled,
300
- 'spectrum-InputGroup--invalid': validationState === 'invalid',
293
+ 'spectrum-InputGroup--invalid': validationState === 'invalid' && !isDisabled,
301
294
  'is-hovered': isHovered
302
295
  },
296
+ classNames(
297
+ searchAutocompleteStyles,
298
+ 'searchautocomplete'
299
+ ),
303
300
  className
304
301
  )
305
302
  }>
@@ -314,9 +311,13 @@ const SearchAutocompleteInput = React.forwardRef(function SearchAutocompleteInpu
314
311
  {
315
312
  'is-disabled': isDisabled,
316
313
  'is-quiet': isQuiet,
317
- 'spectrum-Search--invalid': validationState === 'invalid',
318
- 'spectrum-Search--valid': validationState === 'valid'
319
- }
314
+ 'spectrum-Search--invalid': validationState === 'invalid' && !isDisabled,
315
+ 'spectrum-Search--valid': validationState === 'valid' && !isDisabled
316
+ },
317
+ classNames(
318
+ styles,
319
+ 'spectrum-InputGroup-field'
320
+ )
320
321
  )
321
322
  }
322
323
  inputClassName={classNames(searchStyles, 'spectrum-Search-input')}
@@ -324,13 +325,16 @@ const SearchAutocompleteInput = React.forwardRef(function SearchAutocompleteInpu
324
325
  isQuiet={isQuiet}
325
326
  validationState={validationState}
326
327
  isLoading={showLoading && (isOpen || menuTrigger === 'manual' || loadingState === 'loading')}
327
- loadingIndicator={loadingState != null && loadingCircle}
328
+ loadingIndicator={loadingState != null ? loadingCircle : undefined}
328
329
  icon={icon}
329
- wrapperChildren={(inputValue !== '' && !isReadOnly) && clearButton} />
330
+ wrapperChildren={(inputValue !== '' && !isReadOnly) ? clearButton : undefined}
331
+ disableFocusRing />
330
332
  </div>
331
333
  </FocusRing>
332
334
  );
333
- });
335
+ }
336
+
337
+ let SearchAutocompleteInput = React.forwardRef(_SearchAutocompleteInput) as <T>(props: SearchAutocompleteInputProps<T> & {ref?: any}) => ReactElement;
334
338
 
335
339
 
336
340
  /**
@@ -23,6 +23,12 @@
23
23
  font-style: italic;
24
24
  }
25
25
 
26
+ /* override .spectrum-InputGroup */
27
+ .searchautocomplete.searchautocomplete {
28
+ border-radius: var(--spectrum-search-border-radius);
29
+ --spectrum-focus-ring-border-radius: var(--spectrum-search-border-radius);
30
+ }
31
+
26
32
  .mobile-searchautocomplete {
27
33
  outline: none;
28
34
  }