Skip to content

Commit da166f2

Browse files
committed
update S2 Picker/Combobox so they are described by loading spinner
1 parent 0b06824 commit da166f2

File tree

2 files changed

+21
-12
lines changed

2 files changed

+21
-12
lines changed

packages/@react-spectrum/s2/src/ComboBox.tsx

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ import {
4444
} from './Menu';
4545
import CheckmarkIcon from '../ui-icons/Checkmark';
4646
import ChevronIcon from '../ui-icons/Chevron';
47-
import {createContext, CSSProperties, ForwardedRef, forwardRef, ReactNode, Ref, useCallback, useContext, useEffect, useImperativeHandle, useRef, useState} from 'react';
47+
import {createContext, CSSProperties, ForwardedRef, forwardRef, ReactNode, Ref, useCallback, useContext, useEffect, useImperativeHandle, useMemo, useRef, useState} from 'react';
4848
import {createFocusableRef} from '@react-spectrum/utils';
4949
import {field, fieldInput, getAllowedOverrides, StyleProps} from './style-utils' with {type: 'macro'};
5050
import {FieldErrorIcon, FieldGroup, FieldLabel, HelpText, Input} from './Field';
@@ -56,7 +56,7 @@ import {IconContext} from './Icon';
5656
// @ts-ignore
5757
import intlMessages from '../intl/*.json';
5858
import {menu} from './Picker';
59-
import {mergeRefs, useResizeObserver} from '@react-aria/utils';
59+
import {mergeRefs, useResizeObserver, useSlotId} from '@react-aria/utils';
6060
import {Placement} from 'react-aria';
6161
import {PopoverBase} from './Popover';
6262
import {pressScale} from './pressScale';
@@ -367,6 +367,9 @@ const ComboboxInner = forwardRef(function ComboboxInner(props: ComboBoxProps<any
367367
let timeout = useRef<ReturnType<typeof setTimeout> | null>(null);
368368
let [showLoading, setShowLoading] = useState(false);
369369
let isLoading = loadingState === 'loading' || loadingState === 'filtering';
370+
{/* Logic copied from S1 */}
371+
let showFieldSpinner = useMemo(() => showLoading && (isOpen || menuTrigger === 'manual' || loadingState === 'loading'), [showLoading, isOpen, menuTrigger, loadingState]);
372+
let spinnerId = useSlotId([showFieldSpinner]);
370373

371374
let inputValue = state?.inputValue;
372375
let lastInputValue = useRef(inputValue);
@@ -467,18 +470,18 @@ const ComboboxInner = forwardRef(function ComboboxInner(props: ComboBoxProps<any
467470
<InputContext.Consumer>
468471
{ctx => (
469472
<InputContext.Provider value={{...ctx, ref: mergeRefs((ctx as any)?.ref, inputRef)}}>
470-
<Input />
473+
<Input aria-describedby={spinnerId} />
471474
</InputContext.Provider>
472475
)}
473476
</InputContext.Consumer>
474477
{isInvalid && <FieldErrorIcon isDisabled={isDisabled} />}
475-
{/* Logic copied from S1 */}
476-
{showLoading && (isOpen || menuTrigger === 'manual' || loadingState === 'loading') && (
478+
{showFieldSpinner && (
477479
<ProgressCircle
480+
id={spinnerId}
478481
isIndeterminate
479482
size="S"
480483
styles={progressCircleStyles({size, isInput: true})}
481-
aria-label={stringFormatter.format('table.loadingMore')} />
484+
aria-label={stringFormatter.format('table.loading')} />
482485
)}
483486
<Button
484487
ref={buttonRef}

packages/@react-spectrum/s2/src/Picker.tsx

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ import {ProgressCircle} from './ProgressCircle';
6868
import {raw} from '../style/style-macro' with {type: 'macro'};
6969
import React, {createContext, forwardRef, ReactNode, useContext, useRef, useState} from 'react';
7070
import {useFocusableRef} from '@react-spectrum/utils';
71-
import {useGlobalListeners} from '@react-aria/utils';
71+
import {useGlobalListeners, useSlotId} from '@react-aria/utils';
7272
import {useLocalizedStringFormatter} from '@react-aria/i18n';
7373
import {useSpectrumContextProps} from './useSpectrumContextProps';
7474

@@ -224,9 +224,6 @@ const valueStyles = style({
224224
alignItems: 'center'
225225
});
226226

227-
// TODO: the designs show that it should be disabled when loading, but I think that should
228-
// only apply if there aren't any items in the picker. What do we think? I could also do the same
229-
// for the button and make it have disabled styles
230227
const iconStyles = style({
231228
flexShrink: 0,
232229
rotate: 90,
@@ -320,8 +317,8 @@ export const Picker = /*#__PURE__*/ (forwardRef as forwardRefType)(function Pick
320317
}, {once: true, capture: true});
321318
};
322319

323-
// TODO: no designs for the spinner in the listbox that I've seen so will need to double check
324320
let renderer;
321+
let spinnerId = useSlotId([isLoading]);
325322
let loadingCircle = (
326323
<ProgressCircle
327324
isIndeterminate
@@ -359,6 +356,7 @@ export const Picker = /*#__PURE__*/ (forwardRef as forwardRefType)(function Pick
359356
return (
360357
<AriaSelect
361358
{...pickerProps}
359+
aria-describedby={spinnerId}
362360
placeholder={placeholder}
363361
style={UNSAFE_style}
364362
className={UNSAFE_className + style(field(), getAllowedOverrides())({
@@ -402,7 +400,15 @@ export const Picker = /*#__PURE__*/ (forwardRef as forwardRefType)(function Pick
402400
isQuiet={isQuiet}
403401
isInvalid={isInvalid}
404402
isOpen={isOpen}
405-
loadingCircle={loadingCircle} />
403+
loadingCircle={
404+
<ProgressCircle
405+
id={spinnerId}
406+
isIndeterminate
407+
size="S"
408+
styles={progressCircleStyles({size})}
409+
// Same loading string as table
410+
aria-label={stringFormatter.format('table.loading')} />
411+
} />
406412
)}
407413
</Button>
408414
</PressResponder>

0 commit comments

Comments
 (0)