Update tabs for mobile
This commit is contained in:
53
src/tabs/Tabs.jsx
Normal file
53
src/tabs/Tabs.jsx
Normal file
@@ -0,0 +1,53 @@
|
||||
import React, { useRef } from "react";
|
||||
import { useTabList, useTab, useTabPanel } from "@react-aria/tabs";
|
||||
import { Item } from "@react-stately/collections";
|
||||
import { useTabListState } from "@react-stately/tabs";
|
||||
import styles from "./Tabs.module.css";
|
||||
import classNames from "classnames";
|
||||
|
||||
export function TabContainer(props) {
|
||||
const state = useTabListState(props);
|
||||
const ref = useRef();
|
||||
const { tabListProps } = useTabList(props, state, ref);
|
||||
return (
|
||||
<div className={classNames(styles.tabContainer, props.className)}>
|
||||
<ul {...tabListProps} ref={ref} className={styles.tabList}>
|
||||
{[...state.collection].map((item) => (
|
||||
<Tab key={item.key} item={item} state={state} />
|
||||
))}
|
||||
</ul>
|
||||
<TabPanel key={state.selectedItem?.key} state={state} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function Tab({ item, state }) {
|
||||
const { key, rendered } = item;
|
||||
const ref = useRef();
|
||||
const { tabProps } = useTab({ key }, state, ref);
|
||||
|
||||
return (
|
||||
<li
|
||||
{...tabProps}
|
||||
ref={ref}
|
||||
className={classNames(styles.tab, {
|
||||
[styles.selected]: state.selectedKey === key,
|
||||
[styles.disabled]: state.disabledKeys.has(key),
|
||||
})}
|
||||
>
|
||||
{rendered}
|
||||
</li>
|
||||
);
|
||||
}
|
||||
|
||||
function TabPanel({ state, ...props }) {
|
||||
const ref = useRef();
|
||||
const { tabPanelProps } = useTabPanel(props, state, ref);
|
||||
return (
|
||||
<div {...tabPanelProps} ref={ref} className={styles.tabPanel}>
|
||||
{state.selectedItem?.props.children}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export const TabItem = Item;
|
||||
86
src/tabs/Tabs.module.css
Normal file
86
src/tabs/Tabs.module.css
Normal file
@@ -0,0 +1,86 @@
|
||||
.tabContainer {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.tabList {
|
||||
display: flex;
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
margin: 0 auto 24px auto;
|
||||
}
|
||||
|
||||
.tab {
|
||||
max-width: 190px;
|
||||
min-width: fit-content;
|
||||
height: 32px;
|
||||
border-radius: 8px;
|
||||
background-color: transparent;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0 8px;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.tab > * {
|
||||
color: var(--textColor4);
|
||||
margin: 0 8px 0 0;
|
||||
}
|
||||
|
||||
.tab svg * {
|
||||
fill: var(--textColor4);
|
||||
}
|
||||
|
||||
.tab > :last-child {
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
.tab.selected {
|
||||
background-color: #0dbd8b;
|
||||
}
|
||||
|
||||
.tab.selected * {
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.tab.selected svg * {
|
||||
fill: #ffffff;
|
||||
}
|
||||
|
||||
.tab.disabled {
|
||||
}
|
||||
|
||||
.tabPanel {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex: 1;
|
||||
padding: 0;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
@media (min-width: 800px) {
|
||||
.tab {
|
||||
padding: 0 16px;
|
||||
}
|
||||
|
||||
.tab > * {
|
||||
margin: 0 16px 0 0;
|
||||
}
|
||||
|
||||
.tabContainer {
|
||||
width: 100%;
|
||||
flex-direction: row;
|
||||
margin: 0 0 44px 0;
|
||||
}
|
||||
|
||||
.tabList {
|
||||
flex-direction: column;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.tabPanel {
|
||||
padding: 0 40px;
|
||||
}
|
||||
}
|
||||
49
src/tabs/Tabs.stories.jsx
Normal file
49
src/tabs/Tabs.stories.jsx
Normal file
@@ -0,0 +1,49 @@
|
||||
import React from "react";
|
||||
import { TabContainer, TabItem } from "./Tabs";
|
||||
import { ReactComponent as AudioIcon } from "../icons/Audio.svg";
|
||||
import { ReactComponent as VideoIcon } from "../icons/Video.svg";
|
||||
import { ReactComponent as DeveloperIcon } from "../icons/Developer.svg";
|
||||
import { Body } from "../typography/Typography";
|
||||
|
||||
export default {
|
||||
title: "Tabs",
|
||||
component: TabContainer,
|
||||
parameters: {
|
||||
layout: "fullscreen",
|
||||
},
|
||||
};
|
||||
|
||||
export const Tabs = () => (
|
||||
<TabContainer>
|
||||
<TabItem
|
||||
title={
|
||||
<>
|
||||
<AudioIcon width={16} height={16} />
|
||||
<Body>Audio</Body>
|
||||
</>
|
||||
}
|
||||
>
|
||||
Audio Tab Content
|
||||
</TabItem>
|
||||
<TabItem
|
||||
title={
|
||||
<>
|
||||
<VideoIcon width={16} height={16} />
|
||||
<Body>Video</Body>
|
||||
</>
|
||||
}
|
||||
>
|
||||
Video Tab Content
|
||||
</TabItem>
|
||||
<TabItem
|
||||
title={
|
||||
<>
|
||||
<DeveloperIcon width={16} height={16} />
|
||||
<Body>Developer</Body>
|
||||
</>
|
||||
}
|
||||
>
|
||||
Developer Tab Content
|
||||
</TabItem>
|
||||
</TabContainer>
|
||||
);
|
||||
Reference in New Issue
Block a user