diff --git a/src/list.tsx b/src/list.tsx index 3e338dd5c2..ef9cadc39c 100644 --- a/src/list.tsx +++ b/src/list.tsx @@ -27,6 +27,7 @@ import {vars} from './skins/skin-contract.css'; import {applyCssVars} from './utils/css'; import {IconButton, ToggleIconButton} from './icon-button'; import ScreenReaderOnly from './screen-reader-only'; +import Spinner from './spinner'; import type {IconButtonProps, ToggleIconButtonProps} from './icon-button'; import type {TouchableElement, TouchableProps} from './touchable'; @@ -52,7 +53,7 @@ interface CommonProps { touchableRole?: string; extra?: React.ReactNode; dataAttributes?: DataAttributes; - disabled?: boolean; + disabled?: boolean | 'busy'; withChevron?: boolean; 'aria-label'?: string; right?: Right; @@ -108,6 +109,19 @@ export const Content = ({ const numTextLines = [headline, title, subtitle, description, extra].filter(Boolean).length; const centerY = numTextLines === 1; + const rightContent = (right: Right): JSX.Element => ( +
+ {renderRight(right, centerY)} +
+ ); + console.log('content > ', disabled, control); return (
{asset && ( @@ -137,7 +151,6 @@ export const Content = ({
)} -
)}
- {badge && (
@@ -204,7 +216,6 @@ export const Content = ({
)} - {(detail || right || withChevron || control) && (
{detail && ( @@ -220,18 +231,7 @@ export const Content = ({
)} - {right && ( -
- {renderRight(right, centerY)} -
- )} + {right && disabled !== 'busy' && rightContent(right)} {withChevron && (
)} - {control && ( + {control && disabled !== 'busy' && (
{control}
)} + + {control && disabled === 'busy' && ( + <> + {rightContent()} +
+ {control} +
+ + )}
)} @@ -436,6 +445,7 @@ const RowContent = React.forwardRef((props, r 'aria-description': props['aria-description'], 'aria-describedby': props['aria-describedby'], 'aria-current': props['aria-current'], + 'aria-busy': props.disabled === 'busy', } as TouchableProps; const [isChecked, toggle] = useControlState(props.switch || props.checkbox || {}); @@ -479,26 +489,54 @@ const RowContent = React.forwardRef((props, r withChevron={hasChevron} /> ); + const BusyComponent = React.useMemo( + () => + disabled === 'busy' + ? () => ( +
+ this component is updating itself +
+ ) + : () => null, + [disabled] + ); if (isInteractive && !hasControl) { return ( - - - {renderContent({role})} - - + <> + + + + {renderContent({role})} + + + ); } @@ -508,8 +546,9 @@ const RowContent = React.forwardRef((props, r ref={ref as React.Ref} {...getPrefixedDataAttributes(dataAttributes)} > + ((props, r ref={ref as React.Ref} {...getPrefixedDataAttributes(dataAttributes)} > + {content} ); @@ -548,7 +588,7 @@ const RowContent = React.forwardRef((props, r return isInteractive ? renderRowWithDoubleInteraction( ((props, r ) : renderRowWithSingleControl( ((props, r {props.iconButton.Icon ? ( - + ) : ( - + )} @@ -634,13 +674,13 @@ const RowContent = React.forwardRef((props, r {props.iconButton.Icon ? ( ) : ( )} diff --git a/src/touchable.tsx b/src/touchable.tsx index f3508e0b48..05258fef36 100644 --- a/src/touchable.tsx +++ b/src/touchable.tsx @@ -34,6 +34,7 @@ interface CommonProps { 'aria-selected'?: 'true' | 'false' | boolean; 'aria-labelledby'?: string; 'aria-live'?: 'polite' | 'off' | 'assertive'; + 'aria-busy'?: boolean; 'aria-current'?: React.AriaAttributes['aria-current']; 'aria-description'?: string; 'aria-describedby'?: string; @@ -153,6 +154,7 @@ const RawTouchable = React.forwardRef((props, 'aria-labelledby': props['aria-labelledby'], 'aria-description': props['aria-description'], 'aria-describedby': props['aria-describedby'], + 'aria-busy': props['aria-busy'], }; const type = props.type ? props.type : 'button';