Initial commit
This commit is contained in:
commit
fa30c04815
117 changed files with 33513 additions and 0 deletions
8
src/components/Tabs/TabPanel.tsx
Normal file
8
src/components/Tabs/TabPanel.tsx
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
import React from 'react';
|
||||
import { TabPanelProps } from './types';
|
||||
|
||||
export const TabPanel = ({ children, isActive }: TabPanelProps) => {
|
||||
if (!isActive) return null;
|
||||
|
||||
return <div className="pt-8 pb-4">{children}</div>;
|
||||
};
|
||||
64
src/components/Tabs/Tabs.tsx
Normal file
64
src/components/Tabs/Tabs.tsx
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
import React, { useState } from 'react';
|
||||
import { TabPanel } from './TabPanel';
|
||||
import { TabsProps } from './types';
|
||||
|
||||
export const Tabs = ({ tabs }: TabsProps) => {
|
||||
const [activeTabIndex, setActiveTabIndex] = useState<number>(0);
|
||||
|
||||
const handleTabPress = (index: number) => () => {
|
||||
setActiveTabIndex(index);
|
||||
};
|
||||
|
||||
function classNames(...classes: any) {
|
||||
return classes.filter(Boolean).join(' ');
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="sm:hidden">
|
||||
<label htmlFor="tabs" className="sr-only">
|
||||
Select a tab
|
||||
</label>
|
||||
<select
|
||||
id="tabs"
|
||||
name="tabs"
|
||||
className="block w-full focus:ring-primary-500 focus:border-primary-500 border-gray-300 rounded-md"
|
||||
// defaultValue={tabs ? tabs.find((tab) => tab.current).name : undefined}
|
||||
>
|
||||
{tabs.map((tab) => (
|
||||
<option key={tab.name}>{tab.name}</option>
|
||||
))}
|
||||
</select>
|
||||
</div>
|
||||
<div className="hidden sm:block">
|
||||
<nav className="flex space-x-4" aria-label="Tabs">
|
||||
{tabs.map((tab, tabIndex) => (
|
||||
<a
|
||||
onClick={handleTabPress(tabIndex)}
|
||||
key={tab.name}
|
||||
className={classNames(
|
||||
activeTabIndex === tabIndex
|
||||
? 'bg-gray-100 text-gray-700'
|
||||
: 'text-gray-500 hover:text-gray-700 hover:bg-gray-50',
|
||||
'px-3 py-2 font-medium text-sm rounded-md cursor-pointer',
|
||||
)}
|
||||
aria-current={activeTabIndex === tabIndex ? 'page' : undefined}
|
||||
>
|
||||
{tab.name}
|
||||
</a>
|
||||
))}
|
||||
</nav>
|
||||
</div>
|
||||
|
||||
{tabs.map(({ component, name, disabled }, index) =>
|
||||
disabled ? (
|
||||
<React.Fragment key={name} />
|
||||
) : (
|
||||
<TabPanel key={name} isActive={activeTabIndex === index}>
|
||||
{component}
|
||||
</TabPanel>
|
||||
),
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
1
src/components/Tabs/index.ts
Normal file
1
src/components/Tabs/index.ts
Normal file
|
|
@ -0,0 +1 @@
|
|||
export { Tabs } from './Tabs';
|
||||
21
src/components/Tabs/types.ts
Normal file
21
src/components/Tabs/types.ts
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
type Tab = {
|
||||
disabled?: boolean;
|
||||
name: string;
|
||||
component: JSX.Element;
|
||||
};
|
||||
|
||||
export interface TabsProps {
|
||||
tabs: Tab[];
|
||||
}
|
||||
|
||||
export interface TabPanelProps {
|
||||
isActive: boolean;
|
||||
children: JSX.Element | JSX.Element[];
|
||||
}
|
||||
|
||||
export interface TabProps {
|
||||
title: string;
|
||||
isActive: boolean;
|
||||
onPress(): void;
|
||||
disabled: boolean;
|
||||
}
|
||||
Reference in a new issue