darshan-rajadhyaksha

Tabs Context

Component

About

A headless React context provider that manages the active-tab state (controlled or uncontrolled) for building custom tab/tabpanel components, ported from the RockSolid Solid.js library.

Built with React and Tailwind. Copy the prompt and paste it into Claude Code, Cursor or Lovable: your agent adds Tabs Context to your project and fits it to your theme.

Code

How Tabs Context is used: the demo's code. The component's own source comes with a free account.

Usage.tsx

"use client";

import * as React from "react";
import TabsContext, { useTabsContext } from "@/components/ui/tabs-context";

function DemoTab({
  value,
  children,
}: {
  value: string;
  children: React.ReactNode;
}) {
  const { activeTabValue, handleChange, tabId } = useTabsContext("Tab");
  const isSelected = activeTabValue() === value;
  const id = tabId() ? `${tabId()}-tab-${value}` : undefined;
  const ariaControls = tabId() ? `${tabId()}-tabpanel-${value}` : undefined;

  return (
    <button
      id={id}
      role="tab"
      aria-selected={isSelected}
      aria-controls={ariaControls}
      tabIndex={isSelected ? 0 : -1}
      onClick={(event) => handleChange(event as unknown as Event, value)}
      className={
        isSelected
          ? "px-4 py-2 text-sm font-medium border-b-2 border-foreground text-foreground"
          : "px-4 py-2 text-sm font-medium border-b-2 border-transparent text-muted-foreground hover:text-foreground"
      }
    >
      {children}
    </button>
  );
}

function DemoTabPanel({
  value,
  children,
}: {
  value: string;
  children: React.ReactNode;
}) {
  const { activeTabValue, tabId } = useTabsContext("TabPanel");
  const isActive = activeTabValue() === value;
  const id = tabId() ? `${tabId()}-tabpanel-${value}` : undefined;
  const ariaLabelledby = tabId() ? `${tabId()}-tab-${value}` : undefined;

  return (
    <div
      id={id}
      role="tabpanel"
      aria-labelledby={ariaLabelledby}
      hidden={!isActive}
      className="p-4 text-sm text-muted-foreground"
    >
      {children}
    </div>
  );
}

export default function TabsContextDemo() {
  return (
    <div className="w-full max-w-md rounded-lg border border-border">
      <TabsContext defaultValue="account" tabId="demo">
        <div role="tablist" className="flex border-b border-border">
          <DemoTab value="account">Account</DemoTab>
          <DemoTab value="password">Password</DemoTab>
          <DemoTab value="billing">Billing</DemoTab>
        </div>
        <DemoTabPanel value="account">
          Manage your account details here.
        </DemoTabPanel>
        <DemoTabPanel value="password">Update your password here.</DemoTabPanel>
        <DemoTabPanel value="billing">
          Review your billing information here.
        </DemoTabPanel>
      </TabsContext>
    </div>
  );
}

More by darshan-rajadhyaksha

View all
  • Backdrop

    Backdrop

    1
  • Card Content

    Card Content

  • Breadcrumbs

    Breadcrumbs

  • Checkbox

    Checkbox

  • Textarea

    Textarea

  • Card Title

    Card Title

  • Table

    Table

  • Accordion

    Accordion

Explore more