Tabs

PreviousNext

A component to display content in multiple tabs

Panel - 1
import { Tab, TabList, TabPanel, Tabs, TabsBody } from '../ui/tabs/Tabs';

export function TabsDemo() {
  const tabs = new Array(3).fill(undefined).map((_, n) => ({ label: `${n + 1}`, value: n + 1 }));

  const bgs = (count: number) => {
    switch (count % 3) {
      case 0:
        return 'bg-lightSand';
      case 1:
        return 'bg-saffron';
      case 2:
        return 'bg-lavender';
      default:
        return 'bg-sienna';
    }
  };
  return (
    <Tabs selected={1}>
      <TabList>
        {tabs.map((tab) => {
          return <Tab key={tab.label} label={`Tab - ${tab.label}`} value={tab.value} />;
        })}
      </TabList>
      <TabsBody>
        {tabs.map((tab) => {
          return (
            <TabPanel key={tab.label} value={tab.value}>
              <div className={`p-16 ${bgs(tab.value)}`}>Panel - {tab.label}</div>
            </TabPanel>
          );
        })}
      </TabsBody>
    </Tabs>
  );
}

Installation

npx shadcn@latest add https://develop.trident-ui.pro.clubmed/r/arrows.json

Usage

import { Tab, TabList, TabPanel, Tabs, TabsBody } from '../ui/tabs/Tabs';
 
export default function TabsDemo() {
  const tabs = new Array(3).fill(undefined).map((_, n) => ({ label: `${n + 1}`, value: n + 1 }));
 
  const bgs = (count: number) => {
    switch (count % 3) {
      case 0:
        return 'bg-lightSand';
      case 1:
        return 'bg-saffron';
      case 2:
        return 'bg-lavender';
      default:
        return 'bg-sienna';
    }
  };
  return (
    <Tabs selected={1}>
      <TabList>
        {tabs.map((tab) => {
          return <Tab key={tab.label} label={`Tab - ${tab.label}`} value={tab.value} />;
        })}
      </TabList>
      <TabsBody>
        {tabs.map((tab) => {
          return (
            <TabPanel key={tab.label} value={tab.value}>
              <div className={`p-16 ${bgs(tab.value)}`}>Panel - {tab.label}</div>
            </TabPanel>
          );
        })}
      </TabsBody>
    </Tabs>
  );
}

API Reference

Main Tabs component

Main container of the component, orchestrates

PropTypeDefaultDescription
selectednumberundefinedDefault selected tab
childrenchildrenundefined
compactedbooleanfalseTightens the vertical spacing between the TabList and the TabsBody
classNamestringundefinedAdditional className for the tabs container

Tab List component

Displays the Tab components side by side

PropTypeDefaultDescription
compactedbooleanfalseWhether or not to remove the spacers on the side of the tabs list
classNamestringundefinedAdditional className for the root element in this component

Tab component

The actual tab, clicking it will switch the current active tab and display its content in the TabPanel

PropTypeDefaultDescription
labelstringfalseTab Heading text
valuenumberMANDATORYTab Heading index (can be 0 or 1 indexed)
onSelect(context: {value:number, label:string}) => voidundefinedCallback on tab selection
as"div" | "h1" | "h2" | "h3" | "h4" | "h5";h2HTML tag to render the tab with
classNamestringundefinedAdditional className for the root element in this component

Tabs Body component

Container for the TabPanel components

PropTypeDefaultDescription
classNamestringundefinedAdditional className for the root element in this component

Tab Panel component

Container for the content displayed when a tab is selected

PropTypeDefaultDescription
valuenumberMANDATORYIndex of the tab this panel is associated with
classNamestringundefinedAdditional className for the root element in this component
onSelect(context: {value:number}) => voidundefinedCallback on tab panel selection

Examples

Au ski

A la patinoire
'use client';

import { Tab, TabList, TabPanel, Tabs, TabsBody } from '../ui/tabs/Tabs';

export function TabsWithinTabsDemo() {
  const handleSelect = (context: { value: number }) => {
    console.log('Selected tab:', context.value);
  };

  return (
    <Tabs compacted selected={1}>
      <TabList>
        <Tab label="Au ski" value={1} onSelect={handleSelect} />
        <Tab label="Au soleil" value={2} onSelect={handleSelect} />
        <Tab label="En croisière" value={3} onSelect={handleSelect} />
      </TabList>
      <TabsBody>
        <TabPanel value={1}>
          <div className="bg-lightSand p-16">
            <h4>Au ski</h4>
            <Tabs selected={2} compacted>
              <TabList constrained>
                <Tab label="Sur les pistes" value={1} onSelect={handleSelect} />
                <Tab label="A la patinoire" value={2} onSelect={handleSelect} />
              </TabList>
              <TabsBody>
                <TabPanel value={1}>
                  <div>Sur les pistes</div>
                </TabPanel>
                <TabPanel value={2}>
                  <div>A la patinoire</div>
                </TabPanel>
              </TabsBody>
            </Tabs>
          </div>
        </TabPanel>
        <TabPanel value={2}>
          <div className="bg-saffron p-16">
            <h4>Au soleil</h4>
            <Tabs selected={2} compacted>
              <TabList constrained>
                <Tab label="A la plage" value={1} onSelect={handleSelect} />
                <Tab label="A la piscine" value={2} onSelect={handleSelect} />
              </TabList>
              <TabsBody>
                <TabPanel value={1}>
                  <div>A la plage</div>
                </TabPanel>
                <TabPanel value={2}>
                  <div>A la piscine</div>
                </TabPanel>
              </TabsBody>
            </Tabs>
          </div>
        </TabPanel>
        <TabPanel value={3}>
          <div className="bg-lavender p-16">
            <h4>En croisière</h4>
            <Tabs selected={2} compacted>
              <TabList constrained>
                <Tab label="Au Karting" value={1} onSelect={handleSelect} />
                <Tab label="Au minigolf" value={2} onSelect={handleSelect} />
              </TabList>
              <TabsBody>
                <TabPanel value={1}>
                  <div>Au Karting</div>
                </TabPanel>
                <TabPanel value={2}>
                  <div>Au minigolf</div>
                </TabPanel>
              </TabsBody>
            </Tabs>
          </div>
        </TabPanel>
      </TabsBody>
    </Tabs>
  );
}
Panel - 1
import { Tab, TabList, TabPanel, Tabs, TabsBody, TabSelect } from '../ui/tabs/Tabs';

export function TabsWithSelectDemo() {
  const tabs = new Array(3).fill(undefined).map((_, n) => ({ label: `${n + 1}`, value: n + 1 }));

  const bgs = (count: number) => {
    switch (count % 3) {
      case 0:
        return 'bg-lightSand';
      case 1:
        return 'bg-saffron';
      case 2:
        return 'bg-lavender';
      default:
        return 'bg-sienna';
    }
  };
  return (
    <Tabs className="w-full" selected={1}>
      <TabSelect className="md:hidden w-full" items={tabs} />
      <TabList className="hidden md:flex">
        {tabs.map((tab) => {
          return <Tab key={tab.label} label={`Tab - ${tab.label}`} value={tab.value} />;
        })}
      </TabList>
      <TabsBody>
        {tabs.map((tab) => {
          return (
            <TabPanel key={tab.label} value={tab.value}>
              <div className={`p-16 ${bgs(tab.value)}`}>Panel - {tab.label}</div>
            </TabPanel>
          );
        })}
      </TabsBody>
    </Tabs>
  );
}

Notes