Skip to content

Commit

Permalink
fix: add label prop to icon button (#514)
Browse files Browse the repository at this point in the history
* fix: add label prop to icon button

* fix: snackbar using IconButton label

* fix: add missing label to IconButton container

* fix: snackbar test
  • Loading branch information
dornelasnelson authored Jan 31, 2025
1 parent 458f6b5 commit 6228528
Show file tree
Hide file tree
Showing 5 changed files with 132 additions and 21 deletions.
101 changes: 101 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

26 changes: 13 additions & 13 deletions src/components/experimental/IconButton/IconButton.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,35 +6,35 @@ import { TrashIcon } from '../../../icons';
describe('Experimental: IconButton', () => {
it('renders an icon button with the provided icon', () => {
const onPress = jest.fn();
render(<IconButton onPress={onPress} Icon={TrashIcon} />);
expect(screen.getByTestId('standard-icon-container')).toBeInTheDocument();
render(<IconButton onPress={onPress} Icon={TrashIcon} label="Icon label" />);
expect(screen.getByRole("button", { name: "Icon label"})).toBeInTheDocument();
});

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

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

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

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

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

it('spinner is rendered when loading', () => {
const onPress = jest.fn();
render(<IconButton Icon={TrashIcon} onPress={onPress} isLoading />);
render(<IconButton Icon={TrashIcon} onPress={onPress} isLoading label="Icon label"/>);
expect(screen.getByTestId('iconbutton-spinner')).toBeInTheDocument();
});
});
21 changes: 16 additions & 5 deletions src/components/experimental/IconButton/IconButton.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React, { ReactElement } from 'react';
import styled from 'styled-components';
import { ButtonProps, Button } from 'react-aria-components';
import { VisuallyHidden } from 'react-aria';
import { IconProps } from '../../../icons';
import { getSemanticValue } from '../../../essentials/experimental';
import { InlineSpinner } from '../InlineSpinner/InlineSpinner';
Expand All @@ -10,6 +11,7 @@ export interface IconButtonProps extends ButtonProps {
isLoading?: boolean;
variant?: 'standard' | 'tonal';
Icon: React.FC<IconProps>;
label: string;
}

const StandardIconContainer = styled(Button)<Omit<IconButtonProps, 'Icon'>>`
Expand Down Expand Up @@ -109,6 +111,7 @@ export const IconButton = ({
Icon,
variant = 'standard',
onPress,
label,
...restProps
}: IconButtonProps): ReactElement => {
const Container = variant === 'standard' ? StandardIconContainer : TonalIconContainer;
Expand All @@ -120,13 +123,21 @@ export const IconButton = ({
isDisabled={isDisabled}
isActive={isActive}
isPending={isLoading}
label={label}
{...restProps}
>
{isLoading ? (
<InlineSpinner data-testid="iconbutton-spinner" color={getSemanticValue('on-surface')} size="medium" />
) : (
<Icon data-testid="iconbutton-icon" />
)}
<>
{isLoading ? (
<InlineSpinner
data-testid="iconbutton-spinner"
color={getSemanticValue('on-surface')}
size="medium"
/>
) : (
<Icon data-testid="iconbutton-icon" />
)}
<VisuallyHidden>{label}</VisuallyHidden>
</>
</Container>
);
};
2 changes: 1 addition & 1 deletion src/components/experimental/Snackbar/Snackbar.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ test('renders the dismiss button when hasDismissButton is true and calls onDismi
<span>Test Snackbar</span>
</Snackbar>
);
const dismissButton = screen.getByTestId('snackbar-close-icon');
const dismissButton = screen.getByRole("button", { name: 'Close snackbar'});
fireEvent.click(dismissButton);
expect(onDismiss).toHaveBeenCalledTimes(1);
});
3 changes: 1 addition & 2 deletions src/components/experimental/Snackbar/Snackbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,9 @@ const Snackbar = forwardRef<HTMLDivElement, SnackbarProps>(
{children}
{hasDismissButton && (
<DismissButton
data-testid="snackbar-close-icon"
label="Close snackbar"
Icon={() => <XCrossIcon size={24} color={getSemanticValue('inverse-on-surface')} />}
onPress={onDismiss}
aria-label="close"
/>
)}
</Container>
Expand Down

0 comments on commit 6228528

Please sign in to comment.