Skip to content

Commit e1383d3

Browse files
Sameerali0mistercrunchgeido
authored
refactor(IconButton): Refactor IconButton to use Ant Design 5 Card (apache#32890)
Co-authored-by: Maxime Beauchemin <[email protected]> Co-authored-by: Geido <[email protected]>
1 parent c131205 commit e1383d3

File tree

5 files changed

+191
-182
lines changed

5 files changed

+191
-182
lines changed

superset-frontend/src/components/IconButton/IconButton.stories.tsx

Lines changed: 25 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -16,42 +16,37 @@
1616
* specific language governing permissions and limitations
1717
* under the License.
1818
*/
19-
import IconButton, { IconButtonProps } from '.';
19+
import { Meta, StoryObj } from '@storybook/react';
20+
import { IconButton } from 'src/components/IconButton';
2021

21-
export default {
22-
title: 'IconButton',
22+
const meta: Meta<typeof IconButton> = {
23+
title: 'Components/IconButton',
2324
component: IconButton,
25+
argTypes: {
26+
onClick: { action: 'clicked' },
27+
},
28+
parameters: {
29+
a11y: {
30+
enabled: true,
31+
},
32+
},
2433
};
2534

26-
export const InteractiveIconButton = (args: IconButtonProps) => (
27-
<IconButton
28-
buttonText={args.buttonText}
29-
altText={args.altText}
30-
icon={args.icon}
31-
href={args.href}
32-
target={args.target}
33-
htmlType={args.htmlType}
34-
/>
35-
);
35+
export default meta;
3636

37-
InteractiveIconButton.args = {
38-
buttonText: 'This is the IconButton text',
39-
altText: 'This is an example of non-default alt text',
40-
href: 'https://preset.io/',
41-
target: '_blank',
37+
type Story = StoryObj<typeof IconButton>;
38+
39+
export const Default: Story = {
40+
args: {
41+
buttonText: 'Default IconButton',
42+
altText: 'Default icon button alt text',
43+
},
4244
};
4345

44-
InteractiveIconButton.argTypes = {
45-
icon: {
46-
defaultValue: '/images/icons/sql.svg',
47-
control: {
48-
type: 'select',
49-
},
50-
options: [
51-
'/images/icons/sql.svg',
52-
'/images/icons/server.svg',
53-
'/images/icons/image.svg',
54-
'Click to see example alt text',
55-
],
46+
export const CustomIcon: Story = {
47+
args: {
48+
buttonText: 'Custom icon IconButton',
49+
altText: 'Custom icon button alt text',
50+
icon: '/images/sqlite.png',
5651
},
5752
};

superset-frontend/src/components/IconButton/IconButton.test.jsx

Lines changed: 0 additions & 37 deletions
This file was deleted.
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
/**
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
import { render, screen, fireEvent } from 'spec/helpers/testing-library';
20+
import { IconButton } from 'src/components/IconButton';
21+
22+
const defaultProps = {
23+
buttonText: 'This is the IconButton text',
24+
icon: '/images/icons/sql.svg',
25+
};
26+
27+
describe('IconButton', () => {
28+
it('renders an IconButton with icon and text', () => {
29+
render(<IconButton {...defaultProps} />);
30+
31+
const icon = screen.getByRole('img');
32+
const buttonText = screen.getByText(/this is the iconbutton text/i);
33+
34+
expect(icon).toBeVisible();
35+
expect(buttonText).toBeVisible();
36+
});
37+
38+
it('is keyboard accessible and has correct aria attributes', () => {
39+
render(<IconButton {...defaultProps} />);
40+
41+
const button = screen.getByRole('button');
42+
43+
expect(button).toHaveAttribute('tabIndex', '0');
44+
expect(button).toHaveAttribute('aria-label', defaultProps.buttonText);
45+
});
46+
47+
it('handles Enter and Space key presses', () => {
48+
const mockOnClick = jest.fn();
49+
render(<IconButton {...defaultProps} onClick={mockOnClick} />);
50+
51+
const button = screen.getByRole('button');
52+
53+
fireEvent.keyDown(button, { key: 'Enter', code: 'Enter' });
54+
expect(mockOnClick).toHaveBeenCalledTimes(1);
55+
56+
fireEvent.keyDown(button, { key: ' ', code: 'Space' });
57+
expect(mockOnClick).toHaveBeenCalledTimes(2);
58+
});
59+
60+
it('uses custom alt text when provided', () => {
61+
const customAltText = 'Custom Alt Text';
62+
render(
63+
<IconButton
64+
buttonText="Custom Alt Text Button"
65+
icon="/images/icons/sql.svg"
66+
altText={customAltText}
67+
/>,
68+
);
69+
70+
const icon = screen.getByAltText(customAltText);
71+
expect(icon).toBeVisible();
72+
});
73+
74+
it('displays tooltip with button text', () => {
75+
render(<IconButton {...defaultProps} />);
76+
77+
const tooltipTrigger = screen.getByText(/this is the iconbutton text/i);
78+
expect(tooltipTrigger).toBeVisible();
79+
});
80+
81+
it('calls onClick handler when clicked', () => {
82+
const mockOnClick = jest.fn();
83+
render(<IconButton {...defaultProps} onClick={mockOnClick} />);
84+
85+
const button = screen.getByRole('button');
86+
fireEvent.click(button);
87+
88+
expect(mockOnClick).toHaveBeenCalledTimes(1);
89+
});
90+
});

0 commit comments

Comments
 (0)