Skip to content

Commit 6228528

Browse files
fix: add label prop to icon button (#514)
* fix: add label prop to icon button * fix: snackbar using IconButton label * fix: add missing label to IconButton container * fix: snackbar test
1 parent 458f6b5 commit 6228528

File tree

5 files changed

+132
-21
lines changed

5 files changed

+132
-21
lines changed

package-lock.json

Lines changed: 101 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/components/experimental/IconButton/IconButton.spec.tsx

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,35 +6,35 @@ import { TrashIcon } from '../../../icons';
66
describe('Experimental: IconButton', () => {
77
it('renders an icon button with the provided icon', () => {
88
const onPress = jest.fn();
9-
render(<IconButton onPress={onPress} Icon={TrashIcon} />);
10-
expect(screen.getByTestId('standard-icon-container')).toBeInTheDocument();
9+
render(<IconButton onPress={onPress} Icon={TrashIcon} label="Icon label" />);
10+
expect(screen.getByRole("button", { name: "Icon label"})).toBeInTheDocument();
1111
});
1212

1313
it('calls onPress when clicked', () => {
1414
const onPress = jest.fn();
15-
render(<IconButton Icon={TrashIcon} onPress={onPress} />);
16-
screen.getByTestId('standard-icon-container').click();
15+
render(<IconButton Icon={TrashIcon} onPress={onPress} label="Icon label"/>);
16+
screen.getByRole("button", { name: "Icon label"}).click();
1717
expect(onPress).toHaveBeenCalledTimes(1);
1818
});
1919

2020
it('does not call onPress when disabled', () => {
2121
const onPress = jest.fn();
22-
render(<IconButton Icon={TrashIcon} onPress={onPress} isDisabled />);
23-
screen.getByTestId('standard-icon-container').click();
22+
render(<IconButton Icon={TrashIcon} onPress={onPress} isDisabled label="Icon label"/>);
23+
screen.getByRole("button", { name: "Icon label"}).click();
2424
expect(onPress).toHaveBeenCalledTimes(0);
2525
});
2626

2727
it('does not call onPress when is loading', () => {
2828
const onPress = jest.fn();
29-
render(<IconButton Icon={TrashIcon} onPress={onPress} isLoading />);
30-
screen.getByTestId('standard-icon-container').click();
29+
render(<IconButton Icon={TrashIcon} onPress={onPress} isLoading label="Icon label"/>);
30+
screen.getByRole("button", { name: "Icon label"}).click();
3131
expect(onPress).toHaveBeenCalledTimes(0);
3232
});
3333

3434
it('sets the right sizes for standard variant', () => {
3535
const onPress = jest.fn();
36-
render(<IconButton Icon={TrashIcon} onPress={onPress} />);
37-
const iconContainerInstance = screen.getByTestId('standard-icon-container');
36+
render(<IconButton Icon={TrashIcon} onPress={onPress} label="Icon label"/>);
37+
const iconContainerInstance = screen.getByRole("button", { name: "Icon label"});
3838
const containerStyle = window.getComputedStyle(iconContainerInstance);
3939
expect(containerStyle.width).toBe('2.5rem');
4040
expect(containerStyle.height).toBe('2.5rem');
@@ -43,8 +43,8 @@ describe('Experimental: IconButton', () => {
4343

4444
it('sets the right sizes for tonal variant', () => {
4545
const onPress = jest.fn();
46-
render(<IconButton Icon={TrashIcon} onPress={onPress} variant="tonal" />);
47-
const iconContainerInstance = screen.getByTestId('tonal-icon-container');
46+
render(<IconButton Icon={TrashIcon} onPress={onPress} variant="tonal" label="Icon label"/>);
47+
const iconContainerInstance = screen.getByRole("button", { name: "Icon label"});
4848
const containerStyle = window.getComputedStyle(iconContainerInstance);
4949
expect(containerStyle.width).toBe('3.5rem');
5050
expect(containerStyle.height).toBe('3.5rem');
@@ -53,7 +53,7 @@ describe('Experimental: IconButton', () => {
5353

5454
it('spinner is rendered when loading', () => {
5555
const onPress = jest.fn();
56-
render(<IconButton Icon={TrashIcon} onPress={onPress} isLoading />);
56+
render(<IconButton Icon={TrashIcon} onPress={onPress} isLoading label="Icon label"/>);
5757
expect(screen.getByTestId('iconbutton-spinner')).toBeInTheDocument();
5858
});
5959
});

src/components/experimental/IconButton/IconButton.tsx

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import React, { ReactElement } from 'react';
22
import styled from 'styled-components';
33
import { ButtonProps, Button } from 'react-aria-components';
4+
import { VisuallyHidden } from 'react-aria';
45
import { IconProps } from '../../../icons';
56
import { getSemanticValue } from '../../../essentials/experimental';
67
import { InlineSpinner } from '../InlineSpinner/InlineSpinner';
@@ -10,6 +11,7 @@ export interface IconButtonProps extends ButtonProps {
1011
isLoading?: boolean;
1112
variant?: 'standard' | 'tonal';
1213
Icon: React.FC<IconProps>;
14+
label: string;
1315
}
1416

1517
const StandardIconContainer = styled(Button)<Omit<IconButtonProps, 'Icon'>>`
@@ -109,6 +111,7 @@ export const IconButton = ({
109111
Icon,
110112
variant = 'standard',
111113
onPress,
114+
label,
112115
...restProps
113116
}: IconButtonProps): ReactElement => {
114117
const Container = variant === 'standard' ? StandardIconContainer : TonalIconContainer;
@@ -120,13 +123,21 @@ export const IconButton = ({
120123
isDisabled={isDisabled}
121124
isActive={isActive}
122125
isPending={isLoading}
126+
label={label}
123127
{...restProps}
124128
>
125-
{isLoading ? (
126-
<InlineSpinner data-testid="iconbutton-spinner" color={getSemanticValue('on-surface')} size="medium" />
127-
) : (
128-
<Icon data-testid="iconbutton-icon" />
129-
)}
129+
<>
130+
{isLoading ? (
131+
<InlineSpinner
132+
data-testid="iconbutton-spinner"
133+
color={getSemanticValue('on-surface')}
134+
size="medium"
135+
/>
136+
) : (
137+
<Icon data-testid="iconbutton-icon" />
138+
)}
139+
<VisuallyHidden>{label}</VisuallyHidden>
140+
</>
130141
</Container>
131142
);
132143
};

src/components/experimental/Snackbar/Snackbar.spec.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ test('renders the dismiss button when hasDismissButton is true and calls onDismi
1818
<span>Test Snackbar</span>
1919
</Snackbar>
2020
);
21-
const dismissButton = screen.getByTestId('snackbar-close-icon');
21+
const dismissButton = screen.getByRole("button", { name: 'Close snackbar'});
2222
fireEvent.click(dismissButton);
2323
expect(onDismiss).toHaveBeenCalledTimes(1);
2424
});

src/components/experimental/Snackbar/Snackbar.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,10 +50,9 @@ const Snackbar = forwardRef<HTMLDivElement, SnackbarProps>(
5050
{children}
5151
{hasDismissButton && (
5252
<DismissButton
53-
data-testid="snackbar-close-icon"
53+
label="Close snackbar"
5454
Icon={() => <XCrossIcon size={24} color={getSemanticValue('inverse-on-surface')} />}
5555
onPress={onDismiss}
56-
aria-label="close"
5756
/>
5857
)}
5958
</Container>

0 commit comments

Comments
 (0)