Skip to content

Commit 59b6350

Browse files
WesSouzaarturbien
authored andcommitted
feat(tab,tabbody,tabs): convert to TypeScript and export types
1 parent 375646b commit 59b6350

File tree

10 files changed

+173
-171
lines changed

10 files changed

+173
-171
lines changed

src/Tab/Tab.spec.js renamed to src/Tab/Tab.spec.tsx

+1-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
1-
import React from 'react';
2-
31
import { renderWithTheme } from '../../test/utils';
4-
import Tab from './Tab';
2+
import { Tab } from './Tab';
53

64
describe('<Tab />', () => {
75
describe('prop: children', () => {

src/Tab/Tab.js renamed to src/Tab/Tab.tsx

+22-24
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,21 @@
1-
import React from 'react';
2-
import propTypes from 'prop-types';
3-
1+
import React, { forwardRef } from 'react';
42
import styled from 'styled-components';
3+
54
import { createBorderStyles, createBoxStyles, focusOutline } from '../common';
65
import { blockSizes } from '../common/system';
6+
import { CommonStyledProps } from '../types';
7+
8+
type TabProps = {
9+
children?: React.ReactNode;
10+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
11+
onClick?: (event: React.MouseEvent<HTMLButtonElement>, value: any) => void;
12+
selected?: boolean;
13+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
14+
value?: any;
15+
} & Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, 'onClick' | 'value'> &
16+
CommonStyledProps;
717

8-
const StyledTab = styled.button`
18+
const StyledTab = styled.button<TabProps>`
919
${createBoxStyles()}
1020
${createBorderStyles()}
1121
position: relative;
@@ -59,34 +69,22 @@ const StyledTab = styled.button`
5969
}
6070
`;
6171

62-
const Tab = React.forwardRef(function Tab(props, ref) {
63-
const { value, onClick, selected, children, ...otherProps } = props;
64-
72+
const Tab = forwardRef<HTMLButtonElement, TabProps>(function Tab(
73+
{ value, onClick, selected = false, children, ...otherProps },
74+
ref
75+
) {
6576
return (
6677
<StyledTab
67-
selected={selected}
6878
aria-selected={selected}
69-
onClick={e => onClick(e, value)}
70-
role='tab'
79+
selected={selected}
80+
onClick={(e: React.MouseEvent<HTMLButtonElement>) => onClick?.(e, value)}
7181
ref={ref}
82+
role='tab'
7283
{...otherProps}
7384
>
7485
{children}
7586
</StyledTab>
7687
);
7788
});
7889

79-
Tab.defaultProps = {
80-
onClick: () => {},
81-
selected: false,
82-
children: null
83-
};
84-
85-
Tab.propTypes = {
86-
// eslint-disable-next-line react/require-default-props, react/forbid-prop-types
87-
value: propTypes.any,
88-
onClick: propTypes.func,
89-
selected: propTypes.bool,
90-
children: propTypes.node
91-
};
92-
export default Tab;
90+
export { Tab, TabProps };

src/TabBody/TabBody.spec.js renamed to src/TabBody/TabBody.spec.tsx

+1-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
1-
import React from 'react';
2-
31
import { renderWithTheme } from '../../test/utils';
4-
import TabBody from './TabBody';
2+
import { TabBody } from './TabBody';
53

64
describe('<TabBody />', () => {
75
describe('prop: children', () => {
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,13 @@
1-
import React from 'react';
2-
import propTypes from 'prop-types';
1+
import React, { forwardRef } from 'react';
32

43
import styled from 'styled-components';
54
import { createBorderStyles, createBoxStyles } from '../common';
5+
import { CommonStyledProps } from '../types';
6+
7+
type TabBodyProps = {
8+
children: React.ReactNode;
9+
} & React.HTMLAttributes<HTMLDivElement> &
10+
CommonStyledProps;
611

712
const StyledTabBody = styled.div`
813
${createBoxStyles()}
@@ -13,20 +18,15 @@ const StyledTabBody = styled.div`
1318
padding: 16px;
1419
font-size: 1rem;
1520
`;
16-
const TabBody = React.forwardRef(function TabBody(props, ref) {
17-
const { children, ...otherProps } = props;
21+
const TabBody = forwardRef<HTMLDivElement, TabBodyProps>(function TabBody(
22+
{ children, ...otherProps },
23+
ref
24+
) {
1825
return (
1926
<StyledTabBody ref={ref} {...otherProps}>
2027
{children}
2128
</StyledTabBody>
2229
);
2330
});
2431

25-
TabBody.defaultProps = {
26-
children: null
27-
};
28-
29-
TabBody.propTypes = {
30-
children: propTypes.node
31-
};
32-
export default TabBody;
32+
export { TabBody, TabBodyProps };

src/Tabs/Tabs.js

-97
This file was deleted.

src/Tabs/Tabs.mdx

+14-14
Original file line numberDiff line numberDiff line change
@@ -3,27 +3,27 @@ name: Tabs
33
menu: Components
44
---
55

6-
import Tabs from './Tabs'
7-
import Tab from '../Tab/Tab'
8-
import TabBody from '../TabBody/TabBody'
9-
import Fieldset from '../Fieldset/Fieldset'
10-
import Window from '../Window/Window'
11-
import WindowHeader from '../WindowHeader/WindowHeader'
12-
import NumberField from '../NumberField/NumberField'
13-
import Checkbox from '../Checkbox/Checkbox'
14-
import WindowContent from '../WindowContent/WindowContent'
6+
import { Tabs } from './Tabs';
7+
import { Tab } from '../Tab/Tab';
8+
import { TabBody } from '../TabBody/TabBody';
9+
import Fieldset from '../Fieldset/Fieldset';
10+
import Window from '../Window/Window';
11+
import WindowHeader from '../WindowHeader/WindowHeader';
12+
import NumberField from '../NumberField/NumberField';
13+
import Checkbox from '../Checkbox/Checkbox';
14+
import WindowContent from '../WindowContent/WindowContent';
1515

1616
# Tabs
1717

1818
## Usage
1919

2020
<Playground>
2121
{() => {
22-
const [activeTab, setActiveTab] = React.useState(0)
23-
const handleChange = value => {
24-
setActiveTab(value)
25-
}
26-
const a11yProps = (index) => ({
22+
const [activeTab, setActiveTab] = React.useState(0);
23+
const handleChange = (event, value) => {
24+
setActiveTab(value);
25+
};
26+
const a11yProps = index => ({
2727
id: `tab-${index}`,
2828
'aria-controls': `tabpanel-${index}`
2929
});

src/Tabs/Tabs.spec.js renamed to src/Tabs/Tabs.spec.tsx

+2-3
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
1-
import React from 'react';
21
import { fireEvent } from '@testing-library/react';
32

43
import { renderWithTheme } from '../../test/utils';
54
import { Tab } from '..';
6-
import Tabs from './Tabs';
5+
import { Tabs } from './Tabs';
76

87
describe('<Tabs />', () => {
98
describe('prop: children', () => {
@@ -112,7 +111,7 @@ describe('<Tabs />', () => {
112111
const rowElements = getAllByTestId('tab-row');
113112
const selectedTab = container.querySelector('[aria-selected=true]');
114113

115-
expect(rowElements.pop().contains(selectedTab)).toBe(true);
114+
expect(rowElements?.pop()?.contains(selectedTab)).toBe(true);
116115
});
117116
});
118117
});

src/Tabs/Tabs.stories.js renamed to src/Tabs/Tabs.stories.tsx

+18-12
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
1-
import React, { useState } from 'react';
2-
import styled from 'styled-components';
3-
1+
import { ComponentMeta } from '@storybook/react';
2+
import { useState } from 'react';
43
import {
5-
Tabs,
4+
Anchor,
5+
Checkbox,
6+
Fieldset,
7+
NumberField,
68
Tab,
79
TabBody,
10+
Tabs,
811
Window,
9-
WindowHeader,
1012
WindowContent,
11-
Fieldset,
12-
NumberField,
13-
Checkbox,
14-
Anchor
13+
WindowHeader
1514
} from 'react95';
15+
import styled from 'styled-components';
1616

1717
const Wrapper = styled.div`
1818
padding: 5rem;
@@ -24,14 +24,17 @@ export default {
2424
component: Tabs,
2525
subcomponents: { Tab, TabBody },
2626
decorators: [story => <Wrapper>{story()}</Wrapper>]
27-
};
27+
} as ComponentMeta<typeof Tabs>;
2828

2929
export function Default() {
3030
const [state, setState] = useState({
3131
activeTab: 0
3232
});
3333

34-
const handleChange = (e, value) => setState({ activeTab: value });
34+
const handleChange = (
35+
_: React.MouseEvent<HTMLButtonElement>,
36+
value: number
37+
) => setState({ activeTab: value });
3538

3639
const { activeTab } = state;
3740
return (
@@ -85,7 +88,10 @@ export function MultiRow() {
8588
activeTab: 'Shoes'
8689
});
8790

88-
const handleChange = (e, value) => setState({ activeTab: value });
91+
const handleChange = (
92+
_: React.MouseEvent<HTMLButtonElement>,
93+
value: number
94+
) => setState({ activeTab: value });
8995

9096
const { activeTab } = state;
9197
return (

0 commit comments

Comments
 (0)