Skip to content

Commit 197fd67

Browse files
committed
IconButton: migrate to typescript & add unit test
1 parent 5dd03d1 commit 197fd67

File tree

2 files changed

+43
-23
lines changed

2 files changed

+43
-23
lines changed

client/common/IconButton.test.tsx

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import React from 'react';
2+
import { render, screen } from '../test-utils';
3+
import IconButton from './IconButton';
4+
5+
const MockIcon = (props: React.SVGProps<SVGSVGElement>) => (
6+
<svg data-testid="mock-icon" {...props} />
7+
);
8+
9+
describe('IconButton', () => {
10+
test('renders with an icon', () => {
11+
render(<IconButton icon={MockIcon} aria-label="test button" />);
12+
expect(screen.getByTestId('mock-icon')).toBeInTheDocument();
13+
expect(
14+
screen.getByRole('button', { name: 'test button' })
15+
).toBeInTheDocument();
16+
});
17+
18+
test('renders without an icon', () => {
19+
render(<IconButton />);
20+
expect(screen.queryByTestId('mock-icon')).not.toBeInTheDocument();
21+
});
22+
23+
test('passes other props to the button', () => {
24+
render(<IconButton icon={MockIcon} id="my-button" />);
25+
expect(screen.getByRole('button')).toHaveAttribute('id', 'my-button');
26+
});
27+
});

client/common/IconButton.tsx

Lines changed: 16 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
1-
import React from 'react';
2-
import PropTypes from 'prop-types';
1+
import React, { ComponentType } from 'react';
32
import styled from 'styled-components';
4-
import Button from './Button';
3+
import Button, { ButtonProps } from './Button';
54
import { remSize } from '../theme';
65

76
const ButtonWrapper = styled(Button)`
@@ -12,27 +11,21 @@ const ButtonWrapper = styled(Button)`
1211
}
1312
`;
1413

15-
const IconButton = (props) => {
16-
const { icon, ...otherProps } = props;
17-
const Icon = icon;
18-
19-
return (
20-
<ButtonWrapper
21-
iconBefore={icon && <Icon />}
22-
iconOnly
23-
display={Button.displays.inline}
24-
focusable="false"
25-
{...otherProps}
26-
/>
27-
);
28-
};
29-
30-
IconButton.propTypes = {
31-
icon: PropTypes.func
14+
export type IconButtonProps = Omit<
15+
ButtonProps,
16+
'iconBefore' | 'display' | 'focusable'
17+
> & {
18+
icon?: ComponentType<{ 'aria-label'?: string }> | null;
3219
};
3320

34-
IconButton.defaultProps = {
35-
icon: null
36-
};
21+
const IconButton = ({ icon: Icon, ...otherProps }: IconButtonProps) => (
22+
<ButtonWrapper
23+
iconBefore={Icon ? <Icon /> : undefined}
24+
iconOnly
25+
display={Button.displays.inline}
26+
focusable="false"
27+
{...otherProps}
28+
/>
29+
);
3730

3831
export default IconButton;

0 commit comments

Comments
 (0)