mirror of
https://github.com/graphql-hive/console
synced 2026-05-23 00:58:36 +00:00
Drop V2: Tabs component (#5229)
This commit is contained in:
parent
5c3eaafa0c
commit
e1539b5f5f
6 changed files with 166 additions and 119 deletions
|
|
@ -24,7 +24,6 @@ import { Input } from '@/components/ui/input';
|
|||
import { RadioGroup, RadioGroupItem } from '@/components/ui/radio-group';
|
||||
import { useToast } from '@/components/ui/use-toast';
|
||||
import { UserMenu } from '@/components/ui/user-menu';
|
||||
import { Tabs } from '@/components/v2/tabs';
|
||||
import { env } from '@/env/frontend';
|
||||
import { graphql, useFragment } from '@/gql';
|
||||
import { ProjectType } from '@/gql/graphql';
|
||||
|
|
@ -44,6 +43,7 @@ import { RateLimitWarn } from '../organization/billing/RateLimitWarn';
|
|||
import { HiveLink } from '../ui/hive-link';
|
||||
import { PlusIcon } from '../ui/icon';
|
||||
import { QueryError } from '../ui/query-error';
|
||||
import { Tabs, TabsList, TabsTrigger } from '../ui/tabs';
|
||||
import { OrganizationSelector } from './organization-selectors';
|
||||
|
||||
export enum Page {
|
||||
|
|
@ -144,18 +144,18 @@ export function OrganizationLayout({
|
|||
<div className="relative h-[--tabs-navbar-height] border-b border-gray-800">
|
||||
<div className="container flex items-center justify-between">
|
||||
{currentOrganization && meInCurrentOrg ? (
|
||||
<Tabs value={page}>
|
||||
<Tabs.List>
|
||||
<Tabs.Trigger value={Page.Overview} asChild>
|
||||
<Tabs value={page} className="min-w-[600px]">
|
||||
<TabsList variant="menu">
|
||||
<TabsTrigger variant="menu" value={Page.Overview} asChild>
|
||||
<Link
|
||||
to="/$organizationId"
|
||||
params={{ organizationId: currentOrganization.cleanId }}
|
||||
>
|
||||
Overview
|
||||
</Link>
|
||||
</Tabs.Trigger>
|
||||
</TabsTrigger>
|
||||
{canAccessOrganization(OrganizationAccessScope.Members, meInCurrentOrg) && (
|
||||
<Tabs.Trigger value={Page.Members} asChild>
|
||||
<TabsTrigger variant="menu" value={Page.Members} asChild>
|
||||
<Link
|
||||
to="/$organizationId/view/members"
|
||||
params={{ organizationId: currentOrganization.cleanId }}
|
||||
|
|
@ -163,51 +163,51 @@ export function OrganizationLayout({
|
|||
>
|
||||
Members
|
||||
</Link>
|
||||
</Tabs.Trigger>
|
||||
</TabsTrigger>
|
||||
)}
|
||||
{canAccessOrganization(OrganizationAccessScope.Settings, meInCurrentOrg) && (
|
||||
<>
|
||||
<Tabs.Trigger value={Page.Policy} asChild>
|
||||
<TabsTrigger variant="menu" value={Page.Policy} asChild>
|
||||
<Link
|
||||
to="/$organizationId/view/policy"
|
||||
params={{ organizationId: currentOrganization.cleanId }}
|
||||
>
|
||||
Policy
|
||||
</Link>
|
||||
</Tabs.Trigger>
|
||||
<Tabs.Trigger value={Page.Settings} asChild>
|
||||
</TabsTrigger>
|
||||
<TabsTrigger variant="menu" value={Page.Settings} asChild>
|
||||
<Link
|
||||
to="/$organizationId/view/settings"
|
||||
params={{ organizationId: currentOrganization.cleanId }}
|
||||
>
|
||||
Settings
|
||||
</Link>
|
||||
</Tabs.Trigger>
|
||||
</TabsTrigger>
|
||||
</>
|
||||
)}
|
||||
{canAccessOrganization(OrganizationAccessScope.Read, meInCurrentOrg) &&
|
||||
env.zendeskSupport && (
|
||||
<Tabs.Trigger value={Page.Support} asChild>
|
||||
<TabsTrigger variant="menu" value={Page.Support} asChild>
|
||||
<Link
|
||||
to="/$organizationId/view/support"
|
||||
params={{ organizationId: currentOrganization.cleanId }}
|
||||
>
|
||||
Support
|
||||
</Link>
|
||||
</Tabs.Trigger>
|
||||
</TabsTrigger>
|
||||
)}
|
||||
{getIsStripeEnabled() &&
|
||||
canAccessOrganization(OrganizationAccessScope.Settings, meInCurrentOrg) && (
|
||||
<Tabs.Trigger value={Page.Subscription} asChild>
|
||||
<TabsTrigger variant="menu" value={Page.Subscription} asChild>
|
||||
<Link
|
||||
to="/$organizationId/view/subscription"
|
||||
params={{ organizationId: currentOrganization.cleanId }}
|
||||
>
|
||||
Subscription
|
||||
</Link>
|
||||
</Tabs.Trigger>
|
||||
</TabsTrigger>
|
||||
)}
|
||||
</Tabs.List>
|
||||
</TabsList>
|
||||
</Tabs>
|
||||
) : (
|
||||
<div className="flex flex-row gap-x-8 border-b-2 border-b-transparent px-4 py-3">
|
||||
|
|
|
|||
|
|
@ -15,7 +15,6 @@ import { Form, FormControl, FormField, FormItem, FormMessage } from '@/component
|
|||
import { Input } from '@/components/ui/input';
|
||||
import { useToast } from '@/components/ui/use-toast';
|
||||
import { UserMenu } from '@/components/ui/user-menu';
|
||||
import { Tabs } from '@/components/v2/tabs';
|
||||
import { graphql } from '@/gql';
|
||||
import { canAccessProject, ProjectAccessScope, useProjectAccess } from '@/lib/access/project';
|
||||
import { useToggle } from '@/lib/hooks';
|
||||
|
|
@ -25,6 +24,7 @@ import { Link, useRouter } from '@tanstack/react-router';
|
|||
import { ProjectMigrationToast } from '../project/migration-toast';
|
||||
import { HiveLink } from '../ui/hive-link';
|
||||
import { PlusIcon } from '../ui/icon';
|
||||
import { Tabs, TabsList, TabsTrigger } from '../ui/tabs';
|
||||
import { ProjectSelector } from './project-selector';
|
||||
|
||||
export enum Page {
|
||||
|
|
@ -130,8 +130,8 @@ export function ProjectLayout({
|
|||
<div className="container flex items-center justify-between">
|
||||
{currentOrganization && currentProject ? (
|
||||
<Tabs value={page}>
|
||||
<Tabs.List>
|
||||
<Tabs.Trigger value={Page.Targets} asChild>
|
||||
<TabsList variant="menu">
|
||||
<TabsTrigger variant="menu" value={Page.Targets} asChild>
|
||||
<Link
|
||||
to="/$organizationId/$projectId"
|
||||
params={{
|
||||
|
|
@ -141,9 +141,9 @@ export function ProjectLayout({
|
|||
>
|
||||
Targets
|
||||
</Link>
|
||||
</Tabs.Trigger>
|
||||
</TabsTrigger>
|
||||
{canAccessProject(ProjectAccessScope.Alerts, currentOrganization.me) && (
|
||||
<Tabs.Trigger value={Page.Alerts} asChild>
|
||||
<TabsTrigger variant="menu" value={Page.Alerts} asChild>
|
||||
<Link
|
||||
to="/$organizationId/$projectId/view/alerts"
|
||||
params={{
|
||||
|
|
@ -153,11 +153,11 @@ export function ProjectLayout({
|
|||
>
|
||||
Alerts
|
||||
</Link>
|
||||
</Tabs.Trigger>
|
||||
</TabsTrigger>
|
||||
)}
|
||||
{canAccessProject(ProjectAccessScope.Settings, currentOrganization.me) && (
|
||||
<>
|
||||
<Tabs.Trigger value={Page.Policy} asChild>
|
||||
<TabsTrigger variant="menu" value={Page.Policy} asChild>
|
||||
<Link
|
||||
to="/$organizationId/$projectId/view/policy"
|
||||
params={{
|
||||
|
|
@ -167,8 +167,8 @@ export function ProjectLayout({
|
|||
>
|
||||
Policy
|
||||
</Link>
|
||||
</Tabs.Trigger>
|
||||
<Tabs.Trigger value={Page.Settings} asChild>
|
||||
</TabsTrigger>
|
||||
<TabsTrigger variant="menu" value={Page.Settings} asChild>
|
||||
<Link
|
||||
to="/$organizationId/$projectId/view/settings"
|
||||
params={{
|
||||
|
|
@ -178,10 +178,10 @@ export function ProjectLayout({
|
|||
>
|
||||
Settings
|
||||
</Link>
|
||||
</Tabs.Trigger>
|
||||
</TabsTrigger>
|
||||
</>
|
||||
)}
|
||||
</Tabs.List>
|
||||
</TabsList>
|
||||
</Tabs>
|
||||
) : (
|
||||
<div className="flex flex-row gap-x-8 border-b-2 border-b-transparent px-4 py-3">
|
||||
|
|
|
|||
|
|
@ -22,7 +22,6 @@ import {
|
|||
} from '@/components/ui/select';
|
||||
import { UserMenu } from '@/components/ui/user-menu';
|
||||
import { CopyValue, Tag } from '@/components/v2';
|
||||
import { Tabs } from '@/components/v2/tabs';
|
||||
import { graphql } from '@/gql';
|
||||
import { ProjectType } from '@/gql/graphql';
|
||||
import { canAccessTarget, TargetAccessScope, useTargetAccess } from '@/lib/access/target';
|
||||
|
|
@ -32,6 +31,7 @@ import { useLastVisitedOrganizationWriter } from '@/lib/last-visited-org';
|
|||
import { cn } from '@/lib/utils';
|
||||
import { Link } from '@tanstack/react-router';
|
||||
import { ProjectMigrationToast } from '../project/migration-toast';
|
||||
import { Tabs, TabsList, TabsTrigger } from '../ui/tabs';
|
||||
import { TargetSelector } from './target-selector';
|
||||
|
||||
export enum Page {
|
||||
|
|
@ -168,10 +168,10 @@ export const TargetLayout = ({
|
|||
<div className="container flex items-center justify-between">
|
||||
{currentOrganization && currentProject && currentTarget ? (
|
||||
<Tabs className="flex h-full grow flex-col" value={page}>
|
||||
<Tabs.List>
|
||||
<TabsList variant="menu">
|
||||
{canAccessSchema && (
|
||||
<>
|
||||
<Tabs.Trigger value={Page.Schema} asChild>
|
||||
<TabsTrigger variant="menu" value={Page.Schema} asChild>
|
||||
<Link
|
||||
to="/$organizationId/$projectId/$targetId"
|
||||
params={{
|
||||
|
|
@ -182,8 +182,8 @@ export const TargetLayout = ({
|
|||
>
|
||||
Schema
|
||||
</Link>
|
||||
</Tabs.Trigger>
|
||||
<Tabs.Trigger value={Page.Checks} asChild>
|
||||
</TabsTrigger>
|
||||
<TabsTrigger variant="menu" value={Page.Checks} asChild>
|
||||
<Link
|
||||
to="/$organizationId/$projectId/$targetId/checks"
|
||||
params={{
|
||||
|
|
@ -194,8 +194,8 @@ export const TargetLayout = ({
|
|||
>
|
||||
Checks
|
||||
</Link>
|
||||
</Tabs.Trigger>
|
||||
<Tabs.Trigger value={Page.Explorer} asChild>
|
||||
</TabsTrigger>
|
||||
<TabsTrigger variant="menu" value={Page.Explorer} asChild>
|
||||
<Link
|
||||
to="/$organizationId/$projectId/$targetId/explorer"
|
||||
params={{
|
||||
|
|
@ -206,8 +206,8 @@ export const TargetLayout = ({
|
|||
>
|
||||
Explorer
|
||||
</Link>
|
||||
</Tabs.Trigger>
|
||||
<Tabs.Trigger value={Page.History} asChild>
|
||||
</TabsTrigger>
|
||||
<TabsTrigger variant="menu" value={Page.History} asChild>
|
||||
<Link
|
||||
to="/$organizationId/$projectId/$targetId/history"
|
||||
params={{
|
||||
|
|
@ -218,8 +218,8 @@ export const TargetLayout = ({
|
|||
>
|
||||
History
|
||||
</Link>
|
||||
</Tabs.Trigger>
|
||||
<Tabs.Trigger value={Page.Insights} asChild>
|
||||
</TabsTrigger>
|
||||
<TabsTrigger variant="menu" value={Page.Insights} asChild>
|
||||
<Link
|
||||
to="/$organizationId/$projectId/$targetId/insights"
|
||||
params={{
|
||||
|
|
@ -230,9 +230,9 @@ export const TargetLayout = ({
|
|||
>
|
||||
Insights
|
||||
</Link>
|
||||
</Tabs.Trigger>
|
||||
</TabsTrigger>
|
||||
{currentOrganization.isAppDeploymentsEnabled && (
|
||||
<Tabs.Trigger value={Page.Apps} asChild>
|
||||
<TabsTrigger variant="menu" value={Page.Apps} asChild>
|
||||
<Link
|
||||
to="/$organizationId/$projectId/$targetId/apps"
|
||||
params={{
|
||||
|
|
@ -243,9 +243,9 @@ export const TargetLayout = ({
|
|||
>
|
||||
Apps
|
||||
</Link>
|
||||
</Tabs.Trigger>
|
||||
</TabsTrigger>
|
||||
)}
|
||||
<Tabs.Trigger value={Page.Laboratory} asChild>
|
||||
<TabsTrigger variant="menu" value={Page.Laboratory} asChild>
|
||||
<Link
|
||||
to="/$organizationId/$projectId/$targetId/laboratory"
|
||||
params={{
|
||||
|
|
@ -256,11 +256,11 @@ export const TargetLayout = ({
|
|||
>
|
||||
Laboratory
|
||||
</Link>
|
||||
</Tabs.Trigger>
|
||||
</TabsTrigger>
|
||||
</>
|
||||
)}
|
||||
{canAccessSettings && (
|
||||
<Tabs.Trigger value={Page.Settings} asChild>
|
||||
<TabsTrigger variant="menu" value={Page.Settings} asChild>
|
||||
<Link
|
||||
to="/$organizationId/$projectId/$targetId/settings"
|
||||
params={{
|
||||
|
|
@ -272,9 +272,9 @@ export const TargetLayout = ({
|
|||
>
|
||||
Settings
|
||||
</Link>
|
||||
</Tabs.Trigger>
|
||||
</TabsTrigger>
|
||||
)}
|
||||
</Tabs.List>
|
||||
</TabsList>
|
||||
</Tabs>
|
||||
) : (
|
||||
<div className="flex flex-row gap-x-8 border-b-2 border-b-transparent px-4 py-3">
|
||||
|
|
|
|||
|
|
@ -1,21 +1,61 @@
|
|||
'use client';
|
||||
|
||||
import React from 'react';
|
||||
import { cva, type VariantProps } from 'class-variance-authority';
|
||||
import { cn } from '@/lib/utils';
|
||||
import * as TabsPrimitive from '@radix-ui/react-tabs';
|
||||
|
||||
// Define variants for TabsList
|
||||
const tabsListVariants = cva('relative flex items-center', {
|
||||
variants: {
|
||||
variant: {
|
||||
default:
|
||||
'bg-muted text-muted-foreground inline-flex h-10 items-center justify-center rounded-md p-1',
|
||||
menu: 'text-gray-700',
|
||||
},
|
||||
},
|
||||
defaultVariants: {
|
||||
variant: 'default',
|
||||
},
|
||||
});
|
||||
|
||||
// Define variants for TabsTrigger
|
||||
const tabsTriggerVariants = cva('cursor-pointer !appearance-none text-sm font-medium transition', {
|
||||
variants: {
|
||||
variant: {
|
||||
default:
|
||||
'ring-offset-background focus-visible:ring-ring data-[state=active]:bg-background data-[state=active]:text-foreground inline-flex items-center justify-center whitespace-nowrap rounded-sm px-3 py-1.5 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 disabled:opacity-50 data-[state=active]:shadow-sm disabled:cursor-not-allowed active:disabled:pointer-events-none',
|
||||
menu: 'text-white radix-state-active:border-b-orange-500 border-b-2 border-b-transparent px-4 py-3 hover:border-b-orange-900',
|
||||
},
|
||||
},
|
||||
defaultVariants: {
|
||||
variant: 'default',
|
||||
},
|
||||
});
|
||||
|
||||
// Define variants for TabsContent
|
||||
const tabsContentVariants = cva(
|
||||
'ring-offset-background focus-visible:ring-ring mt-2 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2',
|
||||
{
|
||||
variants: {
|
||||
variant: {
|
||||
default: 'py-7',
|
||||
menu: '',
|
||||
},
|
||||
},
|
||||
defaultVariants: {
|
||||
variant: 'default',
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
const Tabs = TabsPrimitive.Root;
|
||||
|
||||
const TabsList = React.forwardRef<
|
||||
React.ElementRef<typeof TabsPrimitive.List>,
|
||||
React.ComponentPropsWithoutRef<typeof TabsPrimitive.List>
|
||||
>(({ className, ...props }, ref) => (
|
||||
React.ComponentPropsWithoutRef<typeof TabsPrimitive.List> & VariantProps<typeof tabsListVariants>
|
||||
>(({ className, variant, ...props }, ref) => (
|
||||
<TabsPrimitive.List
|
||||
ref={ref}
|
||||
className={cn(
|
||||
'bg-muted text-muted-foreground inline-flex h-10 items-center justify-center rounded-md p-1',
|
||||
className,
|
||||
)}
|
||||
className={cn(tabsListVariants({ variant }), className)}
|
||||
{...props}
|
||||
/>
|
||||
));
|
||||
|
|
@ -23,15 +63,12 @@ TabsList.displayName = TabsPrimitive.List.displayName;
|
|||
|
||||
const TabsTrigger = React.forwardRef<
|
||||
React.ElementRef<typeof TabsPrimitive.Trigger>,
|
||||
React.ComponentPropsWithoutRef<typeof TabsPrimitive.Trigger>
|
||||
>(({ className, ...props }, ref) => (
|
||||
React.ComponentPropsWithoutRef<typeof TabsPrimitive.Trigger> &
|
||||
VariantProps<typeof tabsTriggerVariants> & { hasBorder?: boolean }
|
||||
>(({ className, variant, hasBorder = true, ...props }, ref) => (
|
||||
<TabsPrimitive.Trigger
|
||||
ref={ref}
|
||||
className={cn(
|
||||
'ring-offset-background focus-visible:ring-ring data-[state=active]:bg-background data-[state=active]:text-foreground inline-flex items-center justify-center whitespace-nowrap rounded-sm px-3 py-1.5 text-sm font-medium transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 disabled:opacity-50 data-[state=active]:shadow-sm',
|
||||
'disabled:cursor-not-allowed active:disabled:pointer-events-none', // `:active` allows `:hover` state for using with `TooltipTrigger` with `asChild` prop
|
||||
className,
|
||||
)}
|
||||
className={cn(tabsTriggerVariants({ variant }), hasBorder, className)}
|
||||
{...props}
|
||||
/>
|
||||
));
|
||||
|
|
@ -39,14 +76,12 @@ TabsTrigger.displayName = TabsPrimitive.Trigger.displayName;
|
|||
|
||||
const TabsContent = React.forwardRef<
|
||||
React.ElementRef<typeof TabsPrimitive.Content>,
|
||||
React.ComponentPropsWithoutRef<typeof TabsPrimitive.Content>
|
||||
>(({ className, ...props }, ref) => (
|
||||
React.ComponentPropsWithoutRef<typeof TabsPrimitive.Content> &
|
||||
VariantProps<typeof tabsContentVariants>
|
||||
>(({ className, variant, ...props }, ref) => (
|
||||
<TabsPrimitive.Content
|
||||
ref={ref}
|
||||
className={cn(
|
||||
'ring-offset-background focus-visible:ring-ring mt-2 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2',
|
||||
className,
|
||||
)}
|
||||
className={cn(tabsContentVariants({ variant }), className)}
|
||||
{...props}
|
||||
/>
|
||||
));
|
||||
|
|
|
|||
|
|
@ -1,52 +0,0 @@
|
|||
import { forwardRef, ReactElement } from 'react';
|
||||
import clsx from 'clsx';
|
||||
import {
|
||||
Root,
|
||||
Content as TabsContent,
|
||||
TabsContentProps,
|
||||
List as TabsList,
|
||||
TabsListProps,
|
||||
Trigger as TabsTrigger,
|
||||
TabsTriggerProps,
|
||||
} from '@radix-ui/react-tabs';
|
||||
|
||||
const List = ({ children, className, ...props }: TabsListProps): ReactElement => (
|
||||
<TabsList className={clsx('relative flex items-center text-gray-700', className)} {...props}>
|
||||
{children}
|
||||
</TabsList>
|
||||
);
|
||||
|
||||
const Trigger = forwardRef<any, Omit<TabsTriggerProps, 'className'> & { hasBorder?: boolean }>(
|
||||
({ children, hasBorder = true, ...props }, forwardedRef /* when has asChild prop */) => (
|
||||
<TabsTrigger
|
||||
ref={forwardedRef}
|
||||
className={clsx(
|
||||
'!appearance-none', // unset button styles in Safari
|
||||
'text-sm font-medium text-white transition',
|
||||
hasBorder
|
||||
? 'radix-state-active:border-b-orange-500 cursor-pointer border-b-2 border-b-transparent px-4 py-3 hover:border-b-orange-900'
|
||||
: null,
|
||||
)}
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
</TabsTrigger>
|
||||
),
|
||||
);
|
||||
|
||||
const Content = ({
|
||||
children,
|
||||
className,
|
||||
noPadding,
|
||||
...props
|
||||
}: TabsContentProps & { noPadding?: boolean }): ReactElement => (
|
||||
<TabsContent className={clsx(noPadding ? undefined : 'py-7', className)} {...props}>
|
||||
{children}
|
||||
</TabsContent>
|
||||
);
|
||||
|
||||
export const Tabs = Object.assign(Root, {
|
||||
Content,
|
||||
Trigger,
|
||||
List,
|
||||
});
|
||||
64
packages/web/app/src/stories/tabs.stories.tsx
Normal file
64
packages/web/app/src/stories/tabs.stories.tsx
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
import { MouseEvent, useCallback, useState } from 'react';
|
||||
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';
|
||||
import { Meta, StoryObj } from '@storybook/react';
|
||||
|
||||
const meta: Meta<typeof Template> = {
|
||||
title: 'Components/Tabs',
|
||||
component: Template,
|
||||
argTypes: {
|
||||
variant: {
|
||||
control: { type: 'inline-radio' },
|
||||
options: ['default', 'menu'],
|
||||
},
|
||||
tabs: {
|
||||
control: { type: 'object' },
|
||||
},
|
||||
},
|
||||
args: {
|
||||
tabs: ['Overview', 'Members', 'Policy', 'Settings', 'Support', 'Subscription'],
|
||||
variant: 'default',
|
||||
},
|
||||
};
|
||||
|
||||
export default meta;
|
||||
|
||||
type Story = StoryObj<typeof Template>;
|
||||
|
||||
function Template({ tabs, variant }: { tabs: string[]; variant: 'default' | 'menu' }) {
|
||||
const [page, setPage] = useState(tabs[0]);
|
||||
|
||||
const handleClick = useCallback((event: MouseEvent<HTMLElement>) => {
|
||||
setPage(event.currentTarget.dataset.value!);
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<Tabs value={page}>
|
||||
<TabsList variant={variant}>
|
||||
{tabs.map(value => (
|
||||
<TabsTrigger
|
||||
key={value}
|
||||
variant={variant}
|
||||
onClick={handleClick}
|
||||
value={value}
|
||||
data-value={value}
|
||||
>
|
||||
{value}
|
||||
</TabsTrigger>
|
||||
))}
|
||||
</TabsList>
|
||||
{tabs.map(value => (
|
||||
<TabsContent key={value} variant={variant} value={value}>
|
||||
{value} Tab Content
|
||||
</TabsContent>
|
||||
))}
|
||||
</Tabs>
|
||||
);
|
||||
}
|
||||
|
||||
export const Default: Story = {};
|
||||
|
||||
export const Menu: Story = {
|
||||
args: {
|
||||
variant: 'menu',
|
||||
},
|
||||
};
|
||||
Loading…
Reference in a new issue