51 lines
1.4 KiB
TypeScript
51 lines
1.4 KiB
TypeScript
import { FunctionalComponent, h, ComponentChild } from "preact";
|
|
import style from "./style.module.css";
|
|
import { useState } from "preact/hooks";
|
|
|
|
export interface TabItem {
|
|
label: string
|
|
icon?: string
|
|
render: () => ComponentChild
|
|
}
|
|
|
|
export interface TabsProps {
|
|
class?: string
|
|
items: TabItem[]
|
|
}
|
|
|
|
const Tabs: FunctionalComponent<TabsProps> = ({ items, ...props }) => {
|
|
const [ selectedTabIndex, setSelectedTabIndex ] = useState(0);
|
|
|
|
const onTabClick = (tabIndex: number) => {
|
|
setSelectedTabIndex(tabIndex);
|
|
};
|
|
|
|
const selectedTab = items[selectedTabIndex];
|
|
|
|
return (
|
|
<div class={`${style.tabs} ${props.class}`}>
|
|
<div class="tabs">
|
|
<ul class={`noPrint`}>
|
|
{
|
|
items.map((tabItem, tabIndex) => (
|
|
<li key={`tab-${tabIndex}`}
|
|
onClick={onTabClick.bind(null, tabIndex)}
|
|
class={`${selectedTabIndex === tabIndex ? 'is-active' : ''}`}>
|
|
<a>
|
|
<span class="icon is-small">{tabItem.icon}</span>
|
|
{tabItem.label}
|
|
</a>
|
|
</li>
|
|
))
|
|
}
|
|
</ul>
|
|
</div>
|
|
<div class={style.tabContent}>
|
|
{ selectedTab.render() }
|
|
</div>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default Tabs;
|