-
Notifications
You must be signed in to change notification settings - Fork 54
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
96d6884
commit ac3f39c
Showing
3 changed files
with
150 additions
and
63 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1 @@ | ||
export * from './Primitive/TabsProvider'; | ||
export * from './Primitive/Tabs'; | ||
export * from './Primitive/TabPanel'; | ||
export * from './variants/Tabs'; |
67 changes: 67 additions & 0 deletions
67
packages/design-system/src/components/Tabs/variants/Tabs.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
import { TabsProvider } from './Primitive/TabsProvider'; | ||
import { Tabs as TabList, Tab } from './Primitive/Tabs'; | ||
import { TabPanel } from './Primitive/TabPanel'; | ||
|
||
type TabTitlePropTypes = { | ||
id?: string; | ||
title: string; | ||
icon?: string; | ||
tag?: string | number; | ||
tooltip?: string; | ||
disabled?: boolean; | ||
}; | ||
type TabItemPropTypes = { | ||
tabTitle: string | TabTitlePropTypes; | ||
tabContent: React.ReactNode; | ||
}; | ||
|
||
export type TabsProps = { | ||
tabs: TabItemPropTypes[]; | ||
defaultActiveKey?: string; | ||
size?: 'S' | 'M' | 'L'; | ||
}; | ||
|
||
export function Tabs(props: TabsProps) { | ||
if (props.tabs) { | ||
return ( | ||
<TabsProvider | ||
size={props.size} | ||
defaultActiveKey={ | ||
props.defaultActiveKey || props.tabs[0].tabTitle?.id || props.tabs[0].tabTitle | ||
} | ||
> | ||
<TabList> | ||
{props.tabs.map((tab: TabItemPropTypes, index: number) => ( | ||
<Tab | ||
key={index} | ||
aria-controls={tab.tabTitle?.id || tab.tabTitle} | ||
title={tab.tabTitle?.title || tab.tabTitle} | ||
icon={tab.tabTitle?.icon} | ||
tag={tab.tabTitle?.tag} | ||
tooltip={tab.tabTitle?.tooltip} | ||
disabled={tab.tabTitle?.disabled} | ||
/> | ||
))} | ||
</TabList> | ||
{props.tabs.map((tab: TabItemPropTypes, index: number) => ( | ||
<TabPanel key={index} id={tab.tabTitle?.id || tab.tabTitle}> | ||
{tab.tabContent} | ||
</TabPanel> | ||
))} | ||
</TabsProvider> | ||
); | ||
} | ||
return null; | ||
} | ||
|
||
Tabs as typeof Tabs & { | ||
Container: typeof TabsProvider; | ||
List: typeof TabList; | ||
Panel: typeof TabPanel; | ||
Tab: typeof Tab; | ||
}; | ||
|
||
Tabs.Container = TabsProvider; | ||
Tabs.List = TabList; | ||
Tabs.Panel = TabPanel; | ||
Tabs.Tab = Tab; |
142 changes: 82 additions & 60 deletions
142
packages/design-system/src/stories/navigation/Tabs.stories.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,102 +1,124 @@ | ||
import { useState } from 'react'; | ||
import { StackHorizontal, StackVertical, Tabs, TabsProvider, Tab, TabPanel } from '../../'; | ||
import { StackHorizontal, StackVertical, Tabs } from '../../'; | ||
|
||
export default { component: Tabs, title: 'Navigation/Tabs' }; | ||
|
||
export const Styles = () => ( | ||
<StackHorizontal gap="M" justify="spaceBetween"> | ||
<StackVertical gap="S" align="center"> | ||
<h2>Default</h2> | ||
<TabsProvider defaultActiveKey="profile"> | ||
<Tabs> | ||
<Tab aria-controls="home" title="Home" /> | ||
<Tab aria-controls="profile" title="Profile" /> | ||
<Tab aria-controls="contact" title="Contact" disabled /> | ||
</Tabs> | ||
<TabPanel id="home">Tab content for Home</TabPanel> | ||
<TabPanel id="profile">Tab content for Profile</TabPanel> | ||
<TabPanel id="contact">Tab content for Contact</TabPanel> | ||
</TabsProvider> | ||
<Tabs.Container defaultActiveKey="profile"> | ||
<Tabs.List> | ||
<Tabs.Tab aria-controls="home" title="Home" /> | ||
<Tabs.Tab aria-controls="profile" title="Profile" /> | ||
<Tabs.Tab aria-controls="contact" title="Contact" disabled /> | ||
</Tabs.List> | ||
<Tabs.Panel id="home">Tab content for Home</Tabs.Panel> | ||
<Tabs.Panel id="profile">Tab content for Profile</Tabs.Panel> | ||
<Tabs.Panel id="contact">Tab content for Contact</Tabs.Panel> | ||
</Tabs.Container> | ||
</StackVertical> | ||
<StackVertical gap="S" align="center"> | ||
<h2>Large</h2> | ||
<TabsProvider size="L" defaultActiveKey="profile"> | ||
<Tabs> | ||
<Tab aria-controls="home" title="Home" /> | ||
<Tab aria-controls="profile" title="Profile" /> | ||
<Tab aria-controls="contact" title="Contact" disabled /> | ||
</Tabs> | ||
<TabPanel id="home">Tab content for Home</TabPanel> | ||
<TabPanel id="profile">Tab content for Profile</TabPanel> | ||
<TabPanel id="contact">Tab content for Contact</TabPanel> | ||
</TabsProvider> | ||
<Tabs.Container size="L" defaultActiveKey="profile"> | ||
<Tabs.List> | ||
<Tabs.Tab aria-controls="home" title="Home" /> | ||
<Tabs.Tab aria-controls="profile" title="Profile" /> | ||
<Tabs.Tab aria-controls="contact" title="Contact" disabled /> | ||
</Tabs.List> | ||
<Tabs.Panel id="home">Tab content for Home</Tabs.Panel> | ||
<Tabs.Panel id="profile">Tab content for Profile</Tabs.Panel> | ||
<Tabs.Panel id="contact">Tab content for Contact</Tabs.Panel> | ||
</Tabs.Container> | ||
</StackVertical> | ||
</StackHorizontal> | ||
); | ||
|
||
export const TabsWithIcon = () => ( | ||
<TabsProvider defaultActiveKey="profile"> | ||
<Tabs> | ||
<Tab aria-controls="user" title="User" icon="user" /> | ||
<Tab aria-controls="calendar" title="Calendar" icon="calendar" /> | ||
<Tab aria-controls="favorite" title="Favorite" icon="star" disabled /> | ||
</Tabs> | ||
<TabPanel id="user">Users tab content</TabPanel> | ||
<TabPanel id="calendar">Calendar tab content</TabPanel> | ||
<TabPanel id="favorite">Favorite tab content</TabPanel> | ||
</TabsProvider> | ||
<Tabs.Container defaultActiveKey="profile"> | ||
<Tabs.List> | ||
<Tabs.Tab aria-controls="user" title="User" icon="user" /> | ||
<Tabs.Tab aria-controls="calendar" title="Calendar" icon="calendar" /> | ||
<Tabs.Tab aria-controls="favorite" title="Favorite" icon="star" disabled /> | ||
</Tabs.List> | ||
<Tabs.Panel id="user">Users tab content</Tabs.Panel> | ||
<Tabs.Panel id="calendar">Calendar tab content</Tabs.Panel> | ||
<Tabs.Panel id="favorite">Favorite tab content</Tabs.Panel> | ||
</Tabs.Container> | ||
); | ||
|
||
export const TabsWithTag = () => ( | ||
<TabsProvider defaultActiveKey="profile"> | ||
<Tabs> | ||
<Tab aria-controls="user" title="User" icon="user" tag={13} /> | ||
<Tab aria-controls="calendar" title="Calendar" icon="calendar" tag={54} /> | ||
<Tab | ||
<Tabs.Container defaultActiveKey="profile"> | ||
<Tabs.List> | ||
<Tabs.Tab aria-controls="user" title="User" icon="user" tag={13} /> | ||
<Tabs.Tab aria-controls="calendar" title="Calendar" icon="calendar" tag={54} /> | ||
<Tabs.Tab | ||
aria-controls="favorite" | ||
title="Favorite" | ||
icon="star" | ||
tag="999+" | ||
tooltip="1534 Favorite items" | ||
/> | ||
</Tabs> | ||
<TabPanel id="user">Users tab content</TabPanel> | ||
<TabPanel id="calendar">Calendar tab content</TabPanel> | ||
<TabPanel id="favorite">Favorite tab content</TabPanel> | ||
</TabsProvider> | ||
</Tabs.List> | ||
<Tabs.Panel id="user">Users tab content</Tabs.Panel> | ||
<Tabs.Panel id="calendar">Calendar tab content</Tabs.Panel> | ||
<Tabs.Panel id="favorite">Favorite tab content</Tabs.Panel> | ||
</Tabs.Container> | ||
); | ||
|
||
export const TabsWithLongTitles = () => ( | ||
<TabsProvider defaultActiveKey="user"> | ||
<Tabs> | ||
<Tab aria-controls="user" title="User" icon="user" tag={13} /> | ||
<Tab | ||
<Tabs.Container defaultActiveKey="user"> | ||
<Tabs.List> | ||
<Tabs.Tab aria-controls="user" title="User" icon="user" tag={13} /> | ||
<Tabs.Tab | ||
aria-controls="notification" | ||
title="A much too long title that will trigger the overflow limit" | ||
icon="information-stroke" | ||
tag="999+" | ||
tooltip="1239 notifications - A much too long title that will trigger the overflow limit" | ||
/> | ||
</Tabs> | ||
<TabPanel id="user">Users tab content</TabPanel> | ||
<TabPanel id="notification"> | ||
</Tabs.List> | ||
<Tabs.Panel id="user">Users tab content</Tabs.Panel> | ||
<Tabs.Panel id="notification"> | ||
<h2>About tab content</h2> | ||
</TabPanel> | ||
</TabsProvider> | ||
</Tabs.Panel> | ||
</Tabs.Container> | ||
); | ||
|
||
export const TabStandaloneControlled = () => { | ||
const [key, setKey] = useState<string>('home'); | ||
return ( | ||
<TabsProvider activeKey={key} onSelect={(e, k) => setKey(k)}> | ||
<Tabs> | ||
<Tab aria-controls="home" title="Home" /> | ||
<Tab aria-controls="profile" title="Profile" /> | ||
<Tab aria-controls="contact" title="Contact" disabled /> | ||
</Tabs> | ||
<TabPanel id="home">Tab content for Home</TabPanel> | ||
<TabPanel id="profile">Tab content for Profile</TabPanel> | ||
<TabPanel id="contact">Tab content for Contact</TabPanel> | ||
</TabsProvider> | ||
<Tabs.Container activeKey={key} onSelect={(e, k) => setKey(k)}> | ||
<Tabs.List> | ||
<Tabs.Tab aria-controls="home" title="Home" /> | ||
<Tabs.Tab aria-controls="profile" title="Profile" /> | ||
<Tabs.Tab aria-controls="contact" title="Contact" disabled /> | ||
</Tabs.List> | ||
<Tabs.Panel id="home">Tab content for Home</Tabs.Panel> | ||
<Tabs.Panel id="profile">Tab content for Profile</Tabs.Panel> | ||
<Tabs.Panel id="contact">Tab content for Contact</Tabs.Panel> | ||
</Tabs.Container> | ||
); | ||
}; | ||
|
||
export const TabAPI = () => ( | ||
<Tabs | ||
tabs={[ | ||
{ | ||
tabTitle: 'Tabs 1', | ||
tabContent: <>Tab 1</>, | ||
}, | ||
{ | ||
tabTitle: 'Tabs 2', | ||
tabContent: <>Tab 2</>, | ||
}, | ||
{ | ||
tabTitle: { | ||
title: 'Tabs 3', | ||
icon: 'user', | ||
}, | ||
tabContent: <>Tab 3</>, | ||
}, | ||
]} | ||
/> | ||
); |