V1.0

Base Components

Tab Menu Vertical

Provides a stacked layout for making it easy to switch between sections or categories.

Installation

Install the following dependencies:

terminal
npm install @radix-ui/react-tabs

Create a tab-menu-vertical.tsx file and paste the following code into it.

/components/ui/tab-menu-vertical.tsx
'use client';
 
import * as React from 'react';
import * as TabsPrimitive from '@radix-ui/react-tabs';
 
import { cnExt } from '@/utils/cn';
import { PolymorphicComponentProps } from '@/utils/polymorphic';
 
const TabMenuVerticalContent = TabsPrimitive.Content;
TabMenuVerticalContent.displayName = 'TabMenuVerticalContent';
 
type TabMenuVerticalRootProps = Omit<
  React.ComponentPropsWithoutRef<typeof TabsPrimitive.Root>,
  'orientation'
>;
 
const TabMenuVerticalRoot = React.forwardRef<
  React.ComponentRef<typeof TabsPrimitive.Root>,
  TabMenuVerticalRootProps
>(({ ...rest }, forwardedRef) => {
  return (
    <TabsPrimitive.Root ref={forwardedRef} orientation='vertical' {...rest} />
  );
});
TabMenuVerticalRoot.displayName = 'TabMenuVerticalRoot';
 
const TabMenuVerticalList = React.forwardRef<
  React.ComponentRef<typeof TabsPrimitive.List>,
  React.ComponentPropsWithoutRef<typeof TabsPrimitive.List>
>(({ className, ...rest }, forwardedRef) => {
  return (
    <TabsPrimitive.List
      ref={forwardedRef}
      className={cnExt('w-full space-y-2', className)}
      {...rest}
    />
  );
});
TabMenuVerticalList.displayName = 'TabMenuVerticalList';
 
const TabMenuVerticalTrigger = React.forwardRef<
  React.ComponentRef<typeof TabsPrimitive.Trigger>,
  React.ComponentPropsWithoutRef<typeof TabsPrimitive.Trigger>
>(({ className, ...rest }, forwardedRef) => {
  return (
    <TabsPrimitive.Trigger
      ref={forwardedRef}
      className={cnExt(
        // base
        'group/tab-item w-full rounded-lg p-2 text-left text-label-sm text-text-sub-600 outline-none',
        'grid auto-cols-auto grid-flow-col grid-cols-[auto,minmax(0,1fr)] items-center gap-1.5',
        'transition duration-200 ease-out',
        // hover
        'hover:bg-bg-weak-50',
        // focus
        'focus:outline-none',
        // active
        'data-[state=active]:bg-bg-weak-50 data-[state=active]:text-text-strong-950',
        className,
      )}
      {...rest}
    />
  );
});
TabMenuVerticalTrigger.displayName = 'TabMenuVerticalTrigger';
 
function TabMenuVerticalIcon<T extends React.ElementType>({
  className,
  as,
  ...rest
}: PolymorphicComponentProps<T>) {
  const Component = as || 'div';
 
  return (
    <Component
      className={cnExt(
        // base
        'size-5 text-text-sub-600',
        'transition duration-200 ease-out',
        // active
        'group-data-[state=active]/tab-item:text-primary-base',
        className,
      )}
      {...rest}
    />
  );
}
TabMenuVerticalIcon.displayName = 'TabsVerticalIcon';
 
function TabMenuVerticalArrowIcon<T extends React.ElementType>({
  className,
  as,
  ...rest
}: PolymorphicComponentProps<T>) {
  const Component = as || 'div';
 
  return (
    <Component
      className={cnExt(
        // base
        'size-5 p-px text-text-sub-600',
        'rounded-full bg-bg-white-0 opacity-0 shadow-regular-xs',
        'scale-75 transition ease-out',
        // active
        'group-data-[state=active]/tab-item:scale-100 group-data-[state=active]/tab-item:opacity-100',
        className,
      )}
      {...rest}
    />
  );
}
TabMenuVerticalArrowIcon.displayName = 'TabMenuVerticalArrowIcon';
 
export {
  TabMenuVerticalRoot as Root,
  TabMenuVerticalList as List,
  TabMenuVerticalTrigger as Trigger,
  TabMenuVerticalIcon as Icon,
  TabMenuVerticalArrowIcon as ArrowIcon,
  TabMenuVerticalContent as Content,
};

Update the import paths to match your project setup.

Examples

With Heading

Settings

Styled Container

Settings

API Reference

This component is based on the Radix UI Tabs primitives. Refer to their documentation for the API reference.

© 2024 AlignUI Design System. All rights reserved.