Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/vert tabs #1384

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
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
6 changes: 6 additions & 0 deletions apps/web/content/docs/components/tabs.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,12 @@ Here's an example on how you can set the activate tab programatically using the

<Example name="tabs.stateOptions" />

## Vertical Tabs

Use this example to show a vertically aligned set of tabs on the left side of the page.

<Example name="tabs.vertical" />

## Theme

To learn more about how to customize the appearance of components, please see the [Theme docs](/docs/customize/theme).
Expand Down
1 change: 1 addition & 0 deletions apps/web/examples/tabs/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
export { fullWidth } from "./tabs.fullWidth";
export { root } from "./tabs.root";
export { stateOptions } from "./tabs.stateOptions";
export { vertical } from "./tabs.vertical";
export { withIcons } from "./tabs.withIcons";
export { withPills } from "./tabs.withPills";
export { withUnderline } from "./tabs.withUnderline";
63 changes: 63 additions & 0 deletions apps/web/examples/tabs/tabs.vertical.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
"use client";

import { Tabs } from "flowbite-react";
import { type CodeData } from "~/components/code-demo";

const code = `
import { Tabs } from "flowbite-react";

export function Component() {
return (
<Tabs aria-label="Vertical" style="vertical">
<Tabs.Item active title="Tab 1">
<p className="text-sm text-gray-500 dark:text-gray-400">Content 1</p>
</Tabs.Item>
<Tabs.Item title="Tab 2">
<p className="text-sm text-gray-500 dark:text-gray-400">Content 2</p>
</Tabs.Item>
<Tabs.Item title="Tab 3">
<p className="text-sm text-gray-500 dark:text-gray-400">Content 3</p>
</Tabs.Item>
<Tabs.Item title="Tab 4">
<p className="text-sm text-gray-500 dark:text-gray-400">Content 4</p>
</Tabs.Item>
<Tabs.Item disabled title="Tab 5">
<p className="text-sm text-gray-500 dark:text-gray-400">Content 5</p>
</Tabs.Item>
</Tabs>
);
}
`;

export function Component() {
return (
<Tabs aria-label="Vertical" style="vertical">
<Tabs.Item active title="Tab 1">
<p className="text-sm text-gray-500 dark:text-gray-400">Content 1</p>
</Tabs.Item>
<Tabs.Item title="Tab 2">
<p className="text-sm text-gray-500 dark:text-gray-400">Content 2</p>
</Tabs.Item>
<Tabs.Item title="Tab 3">
<p className="text-sm text-gray-500 dark:text-gray-400">Content 3</p>
</Tabs.Item>
<Tabs.Item title="Tab 4">
<p className="text-sm text-gray-500 dark:text-gray-400">Content 4</p>
</Tabs.Item>
<Tabs.Item disabled title="Tab 5">
<p className="text-sm text-gray-500 dark:text-gray-400">Content 5</p>
</Tabs.Item>
</Tabs>
);
}

export const vertical: CodeData = {
type: "single",
code: {
fileName: "client",
language: "tsx",
code,
},
githubSlug: "tabs/tabs.vertical.tsx",
component: <Component />,
};
18 changes: 17 additions & 1 deletion packages/ui/src/components/Tabs/Tabs.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export default {
},
style: {
control: "radio",
options: ["default", "underline", "pills", "fullWidth"],
options: ["default", "underline", "pills", "fullWidth", "vertical"],
},
},
} as Meta;
Expand Down Expand Up @@ -103,3 +103,19 @@ FullWidth.args = {
style: "fullWidth",
};
FullWidth.storyName = "Full width";

export const Vertical = (args: TabsProps): JSX.Element => (
<Tabs {...args}>
<Tabs.Item title="Profile">Profile content</Tabs.Item>
<Tabs.Item title="Dashboard">Dashboard content</Tabs.Item>
<Tabs.Item title="Settings">Settings content</Tabs.Item>
<Tabs.Item title="Contacts">Contacts content</Tabs.Item>
<Tabs.Item disabled title="Disabled">
Disabled content
</Tabs.Item>
</Tabs>
);
Vertical.args = {
style: "vertical",
};
Vertical.storyName = "Vertical Tabs";
3 changes: 2 additions & 1 deletion packages/ui/src/components/Tabs/Tabs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ export interface TabStyles {
fullWidth: string;
pills: string;
underline: string;
vertical: string;
}

export interface TabStyleItemProps {
Expand Down Expand Up @@ -126,7 +127,7 @@ const TabsComponent = forwardRef<TabsRef, TabsProps>(
}));

return (
<div className={twMerge(theme.base, className)}>
<div className={twMerge(theme.base, className)} data-tab-style={style}>
<div
aria-label="Tabs"
role="tablist"
Expand Down
12 changes: 11 additions & 1 deletion packages/ui/src/components/Tabs/theme.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { createTheme } from "../../helpers/create-theme";
import type { FlowbiteTabsTheme } from "./Tabs";

export const tabTheme: FlowbiteTabsTheme = createTheme({
base: "flex flex-col gap-2",
base: "flex flex-col gap-2 data-[tab-style=vertical]:flex-col md:data-[tab-style=vertical]:flex-row",
tablist: {
base: "flex text-center",
styles: {
Expand All @@ -11,6 +11,8 @@ export const tabTheme: FlowbiteTabsTheme = createTheme({
pills: "flex-wrap space-x-2 text-sm font-medium text-gray-500 dark:text-gray-400",
fullWidth:
"grid w-full grid-flow-col divide-x divide-gray-200 rounded-none text-sm font-medium shadow dark:divide-gray-700 dark:text-gray-400",
vertical:
"mb-4 flex w-full flex-col space-y-4 text-sm font-medium text-gray-500 dark:text-gray-400 md:mb-0 md:me-4 md:w-fit",
},
tabitem: {
base: "flex items-center justify-center rounded-t-lg p-4 text-sm font-medium first:ml-0 focus:outline-none focus:ring-4 focus:ring-cyan-300 disabled:cursor-not-allowed disabled:text-gray-400 disabled:dark:text-gray-500",
Expand Down Expand Up @@ -43,6 +45,13 @@ export const tabTheme: FlowbiteTabsTheme = createTheme({
off: "rounded-none bg-white hover:bg-gray-50 hover:text-gray-700 dark:bg-gray-800 dark:hover:bg-gray-700 dark:hover:text-white",
},
},
vertical: {
base: "",
active: {
on: "inline-flex w-full items-center rounded-lg bg-cyan-600 px-4 py-3 text-white",
off: "inline-flex w-full items-center rounded-lg px-4 py-3 hover:bg-gray-100 hover:text-gray-900 dark:bg-gray-800 dark:hover:bg-gray-700 dark:hover:text-white",
},
},
},
icon: "mr-2 h-5 w-5",
},
Expand All @@ -54,6 +63,7 @@ export const tabTheme: FlowbiteTabsTheme = createTheme({
underline: "",
pills: "",
fullWidth: "",
vertical: "",
},
},
tabpanel: "py-3",
Expand Down
Loading