Skip to content

Commit

Permalink
fix(composer): add aria labels to buttons in hierarchy panel
Browse files Browse the repository at this point in the history
fix: fix bug, update test
  • Loading branch information
jacksonvogt committed Oct 5, 2023
1 parent db16712 commit 24c8c30
Show file tree
Hide file tree
Showing 12 changed files with 190 additions and 86 deletions.
22 changes: 19 additions & 3 deletions packages/scene-composer/src/components/Tree/TreeItem.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Button } from '@awsui/components-react';
import React, { ComponentPropsWithRef, FC, ReactNode, useCallback } from 'react';
import { useIntl } from 'react-intl';

import RadioButton from '../RadioButton';
import { useStore } from '../../store';
Expand All @@ -17,7 +18,8 @@ interface TreeItemInnerProps {
}

export interface TreeItemProps extends TreeItemInnerProps, ComponentPropsWithRef<'li'> {
labelText: ReactNode;
labelNode: ReactNode;
labelText: string;
selectionMode?: SelectionMode;

// Expandable
Expand Down Expand Up @@ -77,6 +79,7 @@ const TreeItem = React.forwardRef<HTMLLIElement, TreeItemProps>(
(
{
className = '',
labelNode,
labelText,
children,
selected,
Expand All @@ -91,6 +94,7 @@ const TreeItem = React.forwardRef<HTMLLIElement, TreeItemProps>(
}: TreeItemProps,
ref,
) => {
const { formatMessage } = useIntl();
const expandHandler = useCallback(
async (e) => {
e.stopPropagation(); // Prevent bubbling that would result in triggering selected.
Expand All @@ -111,17 +115,29 @@ const TreeItem = React.forwardRef<HTMLLIElement, TreeItemProps>(
selectable={selectable}
onActivated={onActivated}
onSelected={onSelected}
label={(labelText as any)?.props?.labelText || ''}
label={labelText}
>
{expandable && (
<Button
className='tm-tree-item-expand-btn'
variant='inline-icon'
onClick={expandHandler}
iconName={`treeview-${expanded ? 'collapse' : 'expand'}`}
ariaExpanded={expanded}
ariaLabel={`${
expanded
? formatMessage({
defaultMessage: 'Collapse',
description: 'Label for button that triggers a collapsable section',
})
: formatMessage({
defaultMessage: 'Expand',
description: 'Label for button that triggers a expandable section',
})
} ${labelText}`}
/>
)}
{labelText}
{labelNode}
</TreeItemInner>
{!expandable || (expandable && expanded) ? children : null}
</li>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,28 @@ import { render, fireEvent } from '@testing-library/react';
import React, { useRef, useState } from 'react';

import TreeItem, { TreeItemProps } from '../TreeItem';
import SceneNodeLabel from '../../panels/SceneHierarchyPanel/components/SceneHierarchyTree/SceneNodeLabel';

jest.mock('react-dnd', () => ({
useDrag: jest.fn(() => [1, useRef(2)]),
useDrop: jest.fn(() => [1, useRef(2)]),
}));

jest.mock('../../panels/SceneHierarchyPanel/components/SceneHierarchyTree/SceneNodeLabel', () => (props) => (
<div data-mocked='SceneNodeLabel'>{JSON.stringify(props)}</div>
));

const mockSceneNodeLabel = ({ label }) => <SceneNodeLabel objectRef='' labelText={label} componentTypes={['']} />;

describe('<TreeItem />', () => {
(
[
{ labelText: '', selected: false, expandable: false },
{ labelText: null, selected: false, expandable: false },
{ labelText: 'Label 1', selected: false, expandable: false },
{ labelText: <span>Label</span>, selected: false, expandable: false },
{ labelText: 'Label', selected: true, expandable: false },
{ labelText: 'Label', selected: false, expandable: true },
{ labelText: 'Label', selected: true, expandable: true },
{ labelNode: mockSceneNodeLabel({ label: '' }), labelText: '', selected: false, expandable: false },
{ labelNode: mockSceneNodeLabel({ label: 'Label 1' }), labelText: 'Label 1', selected: false, expandable: false },
{ labelNode: mockSceneNodeLabel({ label: 'Label' }), labelText: 'Label', selected: false, expandable: false },
{ labelNode: mockSceneNodeLabel({ label: 'Label' }), labelText: 'Label', selected: true, expandable: false },
{ labelNode: mockSceneNodeLabel({ label: 'Label' }), labelText: 'Label', selected: false, expandable: true },
{ labelNode: mockSceneNodeLabel({ label: 'Label' }), labelText: 'Label', selected: true, expandable: true },
] as TreeItemProps[]
).forEach((props) => {
it(`should render appropriate configuration "${JSON.stringify(props)}"`, () => {
Expand All @@ -29,7 +35,9 @@ describe('<TreeItem />', () => {
it(`should activate on double click`, () => {
const onActivated = jest.fn();

const { container } = render(<TreeItem labelText='Click me' onActivated={onActivated} />);
const { container } = render(
<TreeItem labelNode={mockSceneNodeLabel({ label: 'Click me' })} labelText='Click me' onActivated={onActivated} />,
);
const target = container.querySelector('.tm-tree-item-inner') as Element;

fireEvent.doubleClick(target);
Expand All @@ -39,7 +47,9 @@ describe('<TreeItem />', () => {
it(`should select on click`, () => {
const onSelected = jest.fn();

const { container } = render(<TreeItem labelText='Click me' onSelected={onSelected} />);
const { container } = render(
<TreeItem labelNode={mockSceneNodeLabel({ label: 'Click me' })} labelText='Click me' onSelected={onSelected} />,
);
const target = container.querySelector('.tm-tree-item-inner') as Element;

fireEvent.click(target);
Expand All @@ -51,7 +61,13 @@ describe('<TreeItem />', () => {
const [expand, setExpand] = useState(false);

return (
<TreeItem expandable onExpand={setExpand} expanded={expand} labelText='I am expandable'>
<TreeItem
expandable
onExpand={setExpand}
expanded={expand}
labelNode={mockSceneNodeLabel({ label: 'I am expandable' })}
labelText='I am expandable'
>
<div data-testid='hidden-section'>I should only exist when expanded</div>
</TreeItem>
);
Expand All @@ -75,15 +91,20 @@ describe('<TreeItem />', () => {
>
<input
type="radio"
value=""
value="I am expandable"
/>
<div
arialabel="Collapse I am expandable"
class="tm-tree-item-expand-btn"
data-mocked="Button"
iconname="treeview-collapse"
variant="inline-icon"
/>
I am expandable
<div
data-mocked="SceneNodeLabel"
>
{"objectRef":"","labelText":"I am expandable","componentTypes":[""]}
</div>
</label>
<div
data-testid="hidden-section"
Expand All @@ -104,6 +125,7 @@ describe('<TreeItem />', () => {
expandable
onSelected={() => setSelected(!selected)}
selected={selected}
labelNode={mockSceneNodeLabel({ label: `${selected ? 'selected' : 'not selected'}` })}
labelText={`${selected ? 'selected' : 'not selected'}`}
/>
);
Expand All @@ -128,15 +150,20 @@ describe('<TreeItem />', () => {
>
<input
type="radio"
value=""
value="selected"
/>
<div
arialabel="Expand selected"
class="tm-tree-item-expand-btn"
data-mocked="Button"
iconname="treeview-expand"
variant="inline-icon"
/>
selected
<div
data-mocked="SceneNodeLabel"
>
{"objectRef":"","labelText":"selected","componentTypes":[""]}
</div>
</label>
</li>
</div>
Expand All @@ -152,6 +179,7 @@ describe('<TreeItem />', () => {
children={null}
onSelected={() => setSelected(!selected)}
selected={selected}
labelNode={mockSceneNodeLabel({ label: `${selected ? 'selected' : 'not selected'}` })}
labelText={`${selected ? 'selected' : 'not selected'}`}
/>
);
Expand All @@ -176,9 +204,13 @@ describe('<TreeItem />', () => {
>
<input
type="radio"
value=""
value="selected"
/>
selected
<div
data-mocked="SceneNodeLabel"
>
{"objectRef":"","labelText":"selected","componentTypes":[""]}
</div>
</label>
</li>
</div>
Expand Down

0 comments on commit 24c8c30

Please sign in to comment.