Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,10 @@
"@rollup/plugin-node-resolve": "^15.0.1",
"@storybook/addon-actions": "^6.5.15",
"@storybook/addon-essentials": "^6.5.15",
"@storybook/addon-interactions": "^6.5.15",
"@storybook/addon-interactions": "^6.5.16",
"@storybook/addon-links": "^6.5.15",
"@storybook/builder-webpack4": "^6.5.15",
"@storybook/jest": "^0.0.10",
"@storybook/manager-webpack4": "^6.5.15",
"@storybook/react": "^6.5.15",
"@storybook/testing-library": "^0.0.13",
Expand Down
47 changes: 47 additions & 0 deletions src/Tabs/Tab/Tab.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import React from 'react'
import { Story } from '@storybook/react'
import Tab from '.'
import { TabProps } from './interface'

const ExampleIcon = () => (
<svg
width="25"
height="24"
viewBox="0 0 25 24"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M12.4233 2.19752C11.4063 2.18552 10.4109 2.52153 9.70429 3.22853L2.76679 10.3215C2.46839 10.6265 2.38849 11.0655 2.57929 11.4475L3.48549 13.2595L3.45429 18.9785C3.45419 20.1095 4.36049 21.0095 5.48549 21.0095H9.67299C10.6703 21.0095 11.4853 20.1945 11.4853 19.1975V14.8845C11.4853 14.4005 11.8763 14.0095 12.3603 14.0095H12.6103C13.0943 14.0095 13.4853 14.4005 13.4853 14.8845V19.1975C13.4853 20.1945 14.3003 21.0095 15.2983 21.0095H19.4853C20.6103 21.0095 21.5163 20.1035 21.5163 18.9785L21.4853 13.2595L22.3913 11.4475C22.5843 11.0625 22.5083 10.5955 22.2043 10.2905C21.9443 10.0305 15.8293 3.91554 15.2043 3.29054C14.4793 2.56554 13.4393 2.20852 12.4233 2.19752ZM12.4233 4.19752C12.9263 4.20752 13.4283 4.39053 13.7663 4.72853C14.3473 5.30853 19.3023 10.2635 20.2663 11.2285L19.5793 12.5715C19.5093 12.7125 19.4843 12.8525 19.4853 13.0095L19.5163 18.9785C19.5163 18.9925 19.5063 19.0095 19.4853 19.0095H15.4853V14.8845C15.4853 13.2955 14.1993 12.0095 12.6103 12.0095H12.3603C10.7713 12.0095 9.48549 13.2955 9.48549 14.8845V19.0095H5.48549C5.46509 19.0095 5.45429 18.9985 5.45429 18.9785L5.48549 13.0095C5.48649 12.8525 5.46209 12.7125 5.39179 12.5715L4.70429 11.1975L11.1103 4.63453C11.4193 4.32553 11.9193 4.18652 12.4233 4.19752Z"
fill="white"
/>
</svg>
)

export default {
id: 'tab',
title: 'Tab',
component: Tab,
argTypes: {
icon: {
if: {
arg: 'withIcon',
},
defaultValue: <ExampleIcon />,
table: {
disable: true,
},
},
withIcon: {
control: 'boolean',
defaultValue: false,
},
},
}

const Template: Story<TabProps> = (args) => <Tab {...args} />

export const _Tab = Template.bind({})
_Tab.args = {
title: 'Hello',
}
43 changes: 43 additions & 0 deletions src/Tabs/Tab/Tab.style.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import styled from 'styled-components'
import { StyledTabProps } from './interface'

export const StyledTab = styled.button<StyledTabProps>`
display: flex;
justify-content: center;
align-items: center;

padding: 12px 32px;
gap: 8px;
border: none;
border-radius: 12px;

font-weight: 600;
font-size: 16px;
line-height: 24px;

color: white;

cursor: pointer;

${(props) =>
!props.selected &&
`
background-color: transparent;

:hover {
background-color: rgba(255, 255, 255, 0.1);
}
`}

${(props) =>
props.selected &&
`
background-image: linear-gradient(
rgba(85, 97, 255, 1),
rgba(54, 67, 252, 1),
rgba(54, 67, 252, 1)
);

outline: 4px solid rgba(255, 255, 255, 0.1);
`}
`
16 changes: 16 additions & 0 deletions src/Tabs/Tab/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import React from 'react'
import { TabProps } from './interface'
import { StyledTab } from './Tab.style'

const Tab: React.FC<TabProps> = ({ title, icon, selected = false }) => {
return (
<>
<StyledTab selected={selected}>
{icon}
{title}
</StyledTab>
</>
)
}

export default Tab
10 changes: 10 additions & 0 deletions src/Tabs/Tab/interface.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { ReactNode } from 'react'

export interface StyledTabProps {
selected?: boolean
}

export interface TabProps extends StyledTabProps {
title?: string
icon?: ReactNode
}
70 changes: 70 additions & 0 deletions src/Tabs/TabGroup/TabGroup.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import React from 'react'
import { Story } from '@storybook/react'
import TabGroup from '.'
import { TabGroupProps } from './interface'
import Tab from '../Tab'
import { TabProps } from '../Tab/interface'
import { within, userEvent } from '@storybook/testing-library'
import { expect } from '@storybook/jest'

const ExampleIcon = () => (
<svg
width="25"
height="24"
viewBox="0 0 25 24"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M12.4233 2.19752C11.4063 2.18552 10.4109 2.52153 9.70429 3.22853L2.76679 10.3215C2.46839 10.6265 2.38849 11.0655 2.57929 11.4475L3.48549 13.2595L3.45429 18.9785C3.45419 20.1095 4.36049 21.0095 5.48549 21.0095H9.67299C10.6703 21.0095 11.4853 20.1945 11.4853 19.1975V14.8845C11.4853 14.4005 11.8763 14.0095 12.3603 14.0095H12.6103C13.0943 14.0095 13.4853 14.4005 13.4853 14.8845V19.1975C13.4853 20.1945 14.3003 21.0095 15.2983 21.0095H19.4853C20.6103 21.0095 21.5163 20.1035 21.5163 18.9785L21.4853 13.2595L22.3913 11.4475C22.5843 11.0625 22.5083 10.5955 22.2043 10.2905C21.9443 10.0305 15.8293 3.91554 15.2043 3.29054C14.4793 2.56554 13.4393 2.20852 12.4233 2.19752ZM12.4233 4.19752C12.9263 4.20752 13.4283 4.39053 13.7663 4.72853C14.3473 5.30853 19.3023 10.2635 20.2663 11.2285L19.5793 12.5715C19.5093 12.7125 19.4843 12.8525 19.4853 13.0095L19.5163 18.9785C19.5163 18.9925 19.5063 19.0095 19.4853 19.0095H15.4853V14.8845C15.4853 13.2955 14.1993 12.0095 12.6103 12.0095H12.3603C10.7713 12.0095 9.48549 13.2955 9.48549 14.8845V19.0095H5.48549C5.46509 19.0095 5.45429 18.9985 5.45429 18.9785L5.48549 13.0095C5.48649 12.8525 5.46209 12.7125 5.39179 12.5715L4.70429 11.1975L11.1103 4.63453C11.4193 4.32553 11.9193 4.18652 12.4233 4.19752Z"
fill="white"
/>
</svg>
)

export default {
id: 'tab',
title: 'Tab',
component: TabGroup,
argTypes: {
withIcon: {
defaultValue: false,
control: 'boolean',
},
icon: {
if: {
arg: 'withIcon',
},
defaultValue: <ExampleIcon />,
table: {
disable: true,
},
},
},
}

const Template: Story<TabGroupProps & TabProps> = (args) => (
<TabGroup>
<Tab title="Tab 1" icon={args.icon} data-testid="tabgroup-id" />
<Tab title="Tab 2" icon={args.icon} data-testid="tabgroup-id" />
<Tab title="Tab 3" icon={args.icon} data-testid="tabgroup-id" />
</TabGroup>
)

export const _TabGroup = Template.bind({})

_TabGroup.play = async ({ canvasElement }) => {
const canvas = within(canvasElement)

await userEvent.click(canvas.getByText('Tab 1'))
expect(canvas.getByText('Tab 1')).toHaveProperty('selected', true)
await new Promise((r) => setTimeout(r, 1000))

await userEvent.click(canvas.getByText('Tab 2'))
expect(canvas.getByText('Tab 2')).toHaveProperty('selected', true)
await new Promise((r) => setTimeout(r, 1000))

await userEvent.click(canvas.getByText('Tab 3'))
expect(canvas.getByText('Tab 3')).toHaveProperty('selected', true)
await new Promise((r) => setTimeout(r, 1000))
}
11 changes: 11 additions & 0 deletions src/Tabs/TabGroup/TabGroup.style.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import styled from 'styled-components'

export const TabGroupDiv = styled.div`
display: flex;
gap: 4px;
padding: 4px;
background-color: rgba(0, 0, 0, 0.1);
border-radius: 12px;
`

export const TabDiv = styled.div``
27 changes: 27 additions & 0 deletions src/Tabs/TabGroup/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import React, { cloneElement, useState } from 'react'
import { TabGroupProps } from './interface'
import { TabDiv, TabGroupDiv } from './TabGroup.style'

const TabGroup: React.FC<TabGroupProps> = ({ children }) => {
const [selected, setSelected] = useState(0)

return (
<>
<TabGroupDiv>
{children?.map((value, idx) => {
return (
<TabDiv onClick={() => setSelected(idx)} key={idx}>
{cloneElement(value, {
title: value.props.title,
icon: value.props.icon,
selected: selected === idx,
})}
</TabDiv>
)
})}
</TabGroupDiv>
</>
)
}

export default TabGroup
6 changes: 6 additions & 0 deletions src/Tabs/TabGroup/interface.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { ReactElement } from 'react'
import { TabProps } from '../Tab/interface'

export interface TabGroupProps {
children?: ReactElement<TabProps>[]
}
Loading