-
Notifications
You must be signed in to change notification settings - Fork 12
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #37 from ebs-integrator/tabs
tabs componets
- Loading branch information
Showing
9 changed files
with
212 additions
and
1 deletion.
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
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,17 @@ | ||
import * as React from 'react'; | ||
import cn from 'classnames'; | ||
import { useTabs } from './Tabs'; | ||
|
||
export interface PanelProps { | ||
tabKey: string; | ||
className?: string; | ||
} | ||
|
||
/** | ||
* Individual panel component. | ||
*/ | ||
export const Panel: React.FC<PanelProps> = ({ tabKey, className, children }) => { | ||
const { activeTab } = useTabs(); | ||
|
||
return activeTab === tabKey ? <div className={cn(className)}>{children}</div> : null; | ||
}; |
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,37 @@ | ||
import * as React from 'react'; | ||
import cn from 'classnames'; | ||
import { useTabs } from './Tabs'; | ||
|
||
export interface TabProps { | ||
tabKey: string; | ||
label: React.ReactNode; | ||
disabled?: boolean; | ||
className?: string; | ||
onClick?: (tabKey: string) => void; | ||
} | ||
|
||
/** | ||
* This component allows changing of the active Tab. | ||
*/ | ||
export const Tab: React.FC<TabProps> = ({ tabKey, disabled, label, className, onClick }) => { | ||
const { activeTab, setActiveTab } = useTabs(); | ||
|
||
const handleClick = (): void => { | ||
if (setActiveTab && !disabled) { | ||
setActiveTab(tabKey); | ||
} | ||
|
||
if (onClick) { | ||
onClick(tabKey); | ||
} | ||
}; | ||
|
||
return ( | ||
<div | ||
onClick={handleClick} | ||
className={cn(`ebs-tabs__item`, className, { active: activeTab === tabKey, disabled: disabled })} | ||
> | ||
{label} | ||
</div> | ||
); | ||
}; |
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,25 @@ | ||
.ebs-tabs { | ||
display: flex; | ||
border: $tab-border; | ||
border-bottom: $tab-border-bottom; | ||
|
||
} | ||
|
||
.ebs-tabs__item { | ||
cursor: pointer; | ||
margin: $tab-item-margin; | ||
padding: $tab-item-padding; | ||
|
||
&.active { | ||
border-bottom: $tab-item-border-bottom-active; | ||
} | ||
|
||
&.disabled { | ||
color: $tab-item-disabled-color; | ||
cursor: initial; | ||
} | ||
} | ||
|
||
.ebs-tabs__content { | ||
padding: $tab-content-padding; | ||
} |
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,55 @@ | ||
import * as React from 'react'; | ||
import { Tabs } from './Tabs'; | ||
import { exportStory } from 'libs'; | ||
|
||
export default { | ||
title: exportStory('Tabs', 'atoms'), | ||
component: Tabs, | ||
}; | ||
|
||
export const regular = (): React.ReactElement => { | ||
// eslint-disable-next-line react-hooks/rules-of-hooks | ||
const [active, setActive] = React.useState('first'); | ||
|
||
const data = [ | ||
{ | ||
label: <span>First tab</span>, | ||
key: 'first', | ||
content: <span>Content First tab</span>, | ||
}, | ||
{ | ||
label: <span>Second tab</span>, | ||
disabled: true, | ||
key: 'second', | ||
content: <span>Content Second tab</span>, | ||
}, | ||
{ | ||
label: <span>Third tab</span>, | ||
disabled: false, | ||
key: 'third', | ||
content: <span>Content Third tab</span>, | ||
}, | ||
{ | ||
label: <span>Fourth tab</span>, | ||
disabled: true, | ||
key: 'fourth', | ||
content: <span>Content Fourth tab</span>, | ||
}, | ||
]; | ||
|
||
return ( | ||
<div> | ||
<Tabs activeTab={active} setActiveTab={setActive}> | ||
{data.map((item) => ( | ||
<Tabs.Tab {...item} tabKey={item.key} /> | ||
))} | ||
<h2>Custom elements for all tabs</h2> | ||
{data.map((item) => ( | ||
<Tabs.Panel key={item.key} tabKey={item.key}> | ||
{item.content} | ||
</Tabs.Panel> | ||
))} | ||
</Tabs> | ||
</div> | ||
); | ||
}; |
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,66 @@ | ||
import * as React from 'react'; | ||
import cn from 'classnames'; | ||
import { Panel, PanelProps } from './Panel'; | ||
import { Tab, TabProps } from './Tab'; | ||
|
||
export interface TabsProps { | ||
Tab: React.FC<TabProps>; | ||
Panel: React.FC<PanelProps>; | ||
} | ||
|
||
export interface TabsMainProps { | ||
activeTab?: string; | ||
setActiveTab?: (key: string) => void; | ||
className?: string; | ||
} | ||
|
||
export interface TabsContext { | ||
activeTab?: string; | ||
setActiveTab?: (key: string) => void; | ||
} | ||
|
||
const TabsContext = React.createContext<TabsContext | undefined>(undefined); | ||
|
||
const Tabs: React.FC<TabsMainProps> & TabsProps = ({ activeTab, setActiveTab, className, children }) => { | ||
const memoizedContextValue = React.useMemo( | ||
() => ({ | ||
activeTab, | ||
setActiveTab, | ||
}), | ||
[activeTab], | ||
); | ||
|
||
return ( | ||
<TabsContext.Provider value={memoizedContextValue}> | ||
<div className={cn(`ebs-tabs`, className)}> | ||
{children && | ||
React.Children.map(children, (child) => { | ||
if (child && child.type === Tab) { | ||
return child; | ||
} | ||
})} | ||
</div> | ||
<div className={`ebs-tabs__content`}> | ||
{children && | ||
React.Children.map(children, (child) => { | ||
if (child && child.type !== Tab) { | ||
return child; | ||
} | ||
})} | ||
</div> | ||
</TabsContext.Provider> | ||
); | ||
}; | ||
|
||
export const useTabs = (): TabsContext => { | ||
const context = React.useContext(TabsContext); | ||
if (!context) { | ||
throw new Error('This component must be used within a <Tabs> component.'); | ||
} | ||
return context; | ||
}; | ||
|
||
Tabs.Tab = Tab; | ||
Tabs.Panel = Panel; | ||
|
||
export { Tabs }; |
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
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 |
---|---|---|
|
@@ -16,3 +16,4 @@ | |
@import './Avatar/Avatar'; | ||
@import './Alert/Alert'; | ||
@import './Badge/Badge'; | ||
@import './Tabs/Tabs'; |
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