Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 12 additions & 3 deletions src/components/tabs/Tabs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,16 @@ import { TabData } from "./types";
import clsx from "clsx";

export type TabsProps = {
theme?: "brand" | "neutral";
orientation?: "horizontal" | "vertical";
tabs: TabData[];
defaultSelectedTab?: string;
fullWidth?: boolean;
};

export const CustomTabs = ({
orientation = "horizontal",
theme = 'brand',
tabs,
defaultSelectedTab,
fullWidth = false,
Expand All @@ -21,14 +25,19 @@ export const CustomTabs = ({
<div
className={clsx("c__tabs", {
"c__tabs__full-width": fullWidth,
"c__tabs__neutral": theme === 'neutral',
"c__tabs__orientation-vertical": orientation === 'vertical',
})}
>
<Tabs defaultSelectedKey={defaultSelectedTab}>
<TabList aria-label="History of Ancient Rome">
<TabList aria-label="menu">
{tabs.map((tab) => (
<Tab key={tab.id} id={tab.id}>
{tab.icon && <span className="material-icons">{tab.icon}</span>}
{tab.label}
{tab.icon && <span aria-hidden="true" className="material-icons">{tab.icon}</span>}
<span>
<span className="react-aria-Tab__title">{tab.label}</span>
{ tab.subtext && orientation === 'vertical' && <span className="react-aria-Tab__subtext">{tab.subtext}</span> }
</span>
</Tab>
))}
</TabList>
Expand Down
69 changes: 60 additions & 9 deletions src/components/tabs/index.scss
Original file line number Diff line number Diff line change
Expand Up @@ -23,35 +23,32 @@

.react-aria-TabList {
display: flex;
width: 100%;
}

.react-aria-Tab {
padding: 10px;
cursor: pointer;
font-weight: 500;
color: var(--c--contextuals--content--semantic--brand--tertiary);
outline: none;
position: relative;
color: var(--c--contextuals--content--semantic--neutral--tertiary);
transition: color 200ms;
--border-color: transparent;
forced-color-adjust: none;
display: flex;
align-items: center;
gap: 8px;
gap: var(--c--globals--spacings--sm);
border-bottom: 1px solid var(--c--contextuals--border--surface--primary);

&[data-hovered] {
background-color: var(
--c--contextuals--background--semantic--neutral--tertiary-hover
--c--contextuals--background--semantic--overlay--primary
);
color: var(--text-color-hover);
}

&[data-selected] {
font-weight: 500;
color: var(--c--contextuals--content--semantic--brand--primary);
padding-bottom: 9px;
border-bottom: 2px solid
var(--c--contextuals--content--semantic--brand--primary);
var(--c--contextuals--content--semantic--brand--tertiary);
}

&[data-disabled] {
Expand Down Expand Up @@ -80,4 +77,58 @@
outline: 2px solid var(--focus-ring-color);
}
}

&__neutral {
.react-aria-Tab {
color: var(--c--contextuals--content--semantic--neutral--tertiary);
&[data-selected] {
border-color: var(--c--contextuals--content--semantic--neutral--tertiary);
}
}
}

&__orientation-vertical {
.react-aria-Tabs {
width: 100%;
}
.react-aria-TabList {
width: 100%;
flex-direction: column;
gap: 10px;
}
.react-aria-Tab {
color: var(--c--contextuals--content--semantic--neutral--primary);
border-radius: 4px;
border: none !important;
font-weight: 500;
letter-spacing: -0.01em;
font-size: var(--c--globals--font--sizes--sm);
line-height: var(--c--globals--font--sizes--md);

&[data-hovered] {
background-color: var(
--c--contextuals--background--semantic--overlay--primary
);
}

.react-aria-Tab__subtext {
display: block;
font-weight: 400;
line-height: var(--c--globals--font--sizes--md);
font-size: var(--c--globals--font--sizes--xs);
color: var(--c--contextuals--content--semantic--neutral--secondary);
}

&[data-selected] {
font-weight: 700;
padding-bottom: 10px;
background-color: var(
--c--contextuals--background--semantic--overlay--primary
);
border: none;
}
}

}

}
53 changes: 52 additions & 1 deletion src/components/tabs/tabs.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { CustomTabs } from "./Tabs";

// More on how to set up stories at: https://storybook.js.org/docs/writing-stories#default-export
const meta = {
title: "Components/Tabs [WIP]",
title: "Components/Tabs",
component: CustomTabs,
tags: ["autodocs"],
// This component will have an automatically generated Autodocs entry: https://storybook.js.org/docs/writing-docs/autodocs
Expand All @@ -29,6 +29,23 @@ export const Default: Story = {
},
};

export const ThemeNeutral: Story = {
args: {
theme: "neutral",
defaultSelectedTab: "Tpr",
tabs: [
{ id: "FoR", label: "Infos", content: "Infos", icon: "info" },
{ id: "Emp", label: "Activités", content: "Activités", icon: "list" },
{
id: "Tpr",
label: "Notifications",
content: "Notifications",
icon: "notifications",
},
],
},
};

export const FullWidth: Story = {
parameters: {
layout: "fullscreen",
Expand All @@ -48,3 +65,37 @@ export const FullWidth: Story = {
],
},
};

export const Vertical: Story = {
args: {
orientation: 'vertical',
defaultSelectedTab: "Emp",
tabs: [
{ id: "FoR", label: "Infos", content: "Infos", subtext: "Voir plus d'infos", icon: "info" },
{ id: "Emp", label: "Activités", content: "Activités", subtext: "Description courte", icon: "list" },
{
id: "Tpr",
label: "Notifications",
content: "Notifications",
subtext: "Voir plus de notifications",
icon: "notifications",
},
],
},
};

export const VerticalSmall: Story = {
args: {
orientation: 'vertical',
defaultSelectedTab: "Emp",
tabs: [
{ id: "FoR", label: "Infos", content: "Infos" },
{ id: "Emp", label: "Activités", content: "Activités" },
{
id: "Tpr",
label: "Notifications",
content: "Notifications",
},
],
},
};
1 change: 1 addition & 0 deletions src/components/tabs/types.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
export type TabData = {
id: string;
label: string;
subtext?: string;
icon?: string;
content: React.ReactNode;
};