diff --git a/src/components/tabs/Tabs.tsx b/src/components/tabs/Tabs.tsx
index e309a00b..ae997ace 100644
--- a/src/components/tabs/Tabs.tsx
+++ b/src/components/tabs/Tabs.tsx
@@ -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,
@@ -21,14 +25,19 @@ export const CustomTabs = ({
-
+
{tabs.map((tab) => (
- {tab.icon && {tab.icon}}
- {tab.label}
+ {tab.icon && {tab.icon}}
+
+ {tab.label}
+ { tab.subtext && orientation === 'vertical' && {tab.subtext} }
+
))}
diff --git a/src/components/tabs/index.scss b/src/components/tabs/index.scss
index 9c89759e..1e8573d7 100644
--- a/src/components/tabs/index.scss
+++ b/src/components/tabs/index.scss
@@ -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] {
@@ -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;
+ }
+ }
+
+ }
+
}
diff --git a/src/components/tabs/tabs.stories.tsx b/src/components/tabs/tabs.stories.tsx
index 142cd696..23d7c468 100644
--- a/src/components/tabs/tabs.stories.tsx
+++ b/src/components/tabs/tabs.stories.tsx
@@ -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
@@ -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",
@@ -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",
+ },
+ ],
+ },
+};
diff --git a/src/components/tabs/types.ts b/src/components/tabs/types.ts
index 60b96f7f..d5f6af6b 100644
--- a/src/components/tabs/types.ts
+++ b/src/components/tabs/types.ts
@@ -1,6 +1,7 @@
export type TabData = {
id: string;
label: string;
+ subtext?: string;
icon?: string;
content: React.ReactNode;
};