chore: use React.useId for a11y (#33402)
This commit is contained in:
parent
c76f004ec3
commit
80bd246543
|
@ -30,10 +30,12 @@ export const Chip: React.FC<{
|
|||
dataTestId?: string,
|
||||
targetRef?: React.RefObject<HTMLDivElement>,
|
||||
}> = ({ header, expanded, setExpanded, children, noInsets, dataTestId, targetRef }) => {
|
||||
const id = React.useId();
|
||||
return <div className='chip' data-testid={dataTestId} ref={targetRef}>
|
||||
<div
|
||||
role='button'
|
||||
aria-expanded={!!expanded}
|
||||
aria-controls={id}
|
||||
className={clsx('chip-header', setExpanded && ' expanded-' + expanded)}
|
||||
onClick={() => setExpanded?.(!expanded)}
|
||||
title={typeof header === 'string' ? header : undefined}>
|
||||
|
@ -41,7 +43,7 @@ export const Chip: React.FC<{
|
|||
{setExpanded && !expanded && icons.rightArrow()}
|
||||
{header}
|
||||
</div>
|
||||
{(!setExpanded || expanded) && <div role='region' className={clsx('chip-body', noInsets && 'chip-body-no-insets')}>{children}</div>}
|
||||
{(!setExpanded || expanded) && <div id={id} role='region' className={clsx('chip-body', noInsets && 'chip-body-no-insets')}>{children}</div>}
|
||||
</div>;
|
||||
};
|
||||
|
||||
|
|
|
@ -24,14 +24,20 @@ export const Expandable: React.FunctionComponent<React.PropsWithChildren<{
|
|||
expanded: boolean,
|
||||
expandOnTitleClick?: boolean,
|
||||
}>> = ({ title, children, setExpanded, expanded, expandOnTitleClick }) => {
|
||||
const id = React.useId();
|
||||
return <div className={clsx('expandable', expanded && 'expanded')}>
|
||||
<div className='expandable-title' onClick={() => expandOnTitleClick && setExpanded(!expanded)}>
|
||||
<div
|
||||
role='button'
|
||||
aria-expanded={expanded}
|
||||
aria-controls={id}
|
||||
className='expandable-title'
|
||||
onClick={() => expandOnTitleClick && setExpanded(!expanded)}>
|
||||
<div
|
||||
className={clsx('codicon', expanded ? 'codicon-chevron-down' : 'codicon-chevron-right')}
|
||||
style={{ cursor: 'pointer', color: 'var(--vscode-foreground)', marginLeft: '5px' }}
|
||||
onClick={() => !expandOnTitleClick && setExpanded(!expanded)} />
|
||||
{title}
|
||||
</div>
|
||||
{ expanded && <div style={{ marginLeft: 25 }}>{children}</div> }
|
||||
{ expanded && <div id={id} role='region' style={{ marginLeft: 25 }}>{children}</div> }
|
||||
</div>;
|
||||
};
|
||||
|
|
|
@ -231,6 +231,7 @@ export function TreeItemHeader<T extends TreeItem>({
|
|||
icon,
|
||||
isKeyboardNavigation,
|
||||
setIsKeyboardNavigation }: TreeItemHeaderProps<T>) {
|
||||
const groupId = React.useId();
|
||||
const itemRef = React.useRef(null);
|
||||
|
||||
React.useEffect(() => {
|
||||
|
@ -251,7 +252,7 @@ export function TreeItemHeader<T extends TreeItem>({
|
|||
const titled = title?.(item);
|
||||
const iconed = icon?.(item) || 'codicon-blank';
|
||||
|
||||
return <div ref={itemRef} role='treeitem' aria-selected={item === selectedItem} aria-expanded={expanded} title={titled} className='vbox' style={{ flex: 'none' }}>
|
||||
return <div ref={itemRef} role='treeitem' aria-selected={item === selectedItem} aria-expanded={expanded} aria-controls={groupId} title={titled} className='vbox' style={{ flex: 'none' }}>
|
||||
<div
|
||||
onDoubleClick={() => onAccepted?.(item)}
|
||||
className={clsx(
|
||||
|
@ -281,7 +282,7 @@ export function TreeItemHeader<T extends TreeItem>({
|
|||
{icon && <div className={'codicon ' + iconed} style={{ minWidth: 16, marginRight: 4 }} aria-label={'[' + iconed.replace('codicon', 'icon') + ']'}></div>}
|
||||
{typeof rendered === 'string' ? <div style={{ textOverflow: 'ellipsis', overflow: 'hidden' }}>{rendered}</div> : rendered}
|
||||
</div>
|
||||
{!!children.length && <div role='group'>
|
||||
{!!children.length && <div id={groupId} role='group'>
|
||||
{children.map(child => {
|
||||
const itemData = treeItems.get(child);
|
||||
return itemData && <TreeItemHeader
|
||||
|
|
Loading…
Reference in New Issue