Files
gh-vuer-ai-vuer-skill-marke…/docs/components/toggle-buttons.md
2025-11-30 09:05:04 +08:00

6.4 KiB

  1. Home
  2. Components
  3. Toggle Buttons

Toggle Buttons

A set of buttons where only one can be selected at a time, with smooth animated transitions between selections.

Props

ToggleButtons

Prop Type Default Description
value string - Controlled value
onValueChange (value: string) => void - Callback when value changes
size 'sm' 'base' 'lg'
variant 'primary' 'secondary' 'ghost'
padding boolean true Whether to add padding between container and buttons
className string - Custom CSS classes
children ReactNode - ToggleButton components

ToggleButton

Prop Type Default Description
value string - Value for this button
icon boolean false If true, renders as square icon button with proper sizing
asChild boolean false Render as child element (using Slot)
className string - Custom CSS classes
children ReactNode - Button content

Icon Only

Perfect for toolbar-style interfaces with square buttons:

Primary

Secondary

Ghost

Selected: select

import { MousePointer, Hand, Scissors } from "lucide-react";

const [selectedTool, setSelectedTool] = useState("select");

return (
  <div className="space-y-6">
    <div className="space-y-2">
      <p className="text-sm font-medium">Primary</p>
      <ToggleButtons value={selectedTool} onValueChange={setSelectedTool} padding={false} variant="primary">
        <ToggleButton value="select" icon>
          <MousePointer className="size-4" />
        </ToggleButton>
        <ToggleButton value="pick" icon>
          <Hand className="size-4" />
        </ToggleButton>
        <ToggleButton value="cut" icon>
          <Scissors className="size-4" />
        </ToggleButton>
      </ToggleButtons>
    </div>

    <div className="space-y-2">
      <p className="text-sm font-medium">Secondary</p>
      <ToggleButtons value={selectedTool} onValueChange={setSelectedTool} padding={false} variant="secondary">
        <ToggleButton value="select" icon>
          <MousePointer className="size-4" />
        </ToggleButton>
        <ToggleButton value="pick" icon>
          <Hand className="size-4" />
        </ToggleButton>
        <ToggleButton value="cut" icon>
          <Scissors className="size-4" />
        </ToggleButton>
      </ToggleButtons>
    </div>

    <div className="space-y-2">
      <p className="text-sm font-medium">Ghost</p>
      <ToggleButtons value={selectedTool} onValueChange={setSelectedTool} padding={false} variant="ghost">
        <ToggleButton value="select" icon>
          <MousePointer className="size-4" />
        </ToggleButton>
        <ToggleButton value="pick" icon>
          <Hand className="size-4" />
        </ToggleButton>
        <ToggleButton value="cut" icon>
          <Scissors className="size-4" />
        </ToggleButton>
      </ToggleButtons>
    </div>
  </div>
);

Usage

Select Pick Cut Selected: select

const [selectedTool, setSelectedTool] = useState("select");

return (
  <ToggleButtons value={selectedTool} onValueChange={setSelectedTool}>
    <ToggleButton value="select">Select</ToggleButton>
    <ToggleButton value="pick">Pick</ToggleButton>
    <ToggleButton value="cut">Cut</ToggleButton>
  </ToggleButtons>
);

Padding Options

Control the spacing between the container and buttons:

With Padding (default)

Select Pick Cut Without Padding

Select Pick Cut Selected: select

const [selectedTool, setSelectedTool] = useState("select");

return (
  <>
    {/* With padding (default) */}
    <ToggleButtons value={selectedTool} onValueChange={setSelectedTool} padding={true} variant="primary">
      <ToggleButton value="select">Select</ToggleButton>
      <ToggleButton value="pick">Pick</ToggleButton>
      <ToggleButton value="cut">Cut</ToggleButton>
    </ToggleButtons>

    {/* Without padding - buttons inherit full container size */}
    <ToggleButtons value={selectedTool} onValueChange={setSelectedTool} padding={false} variant="primary">
      <ToggleButton value="select">Select</ToggleButton>
      <ToggleButton value="pick">Pick</ToggleButton>
      <ToggleButton value="cut">Cut</ToggleButton>
    </ToggleButtons>
  </>
);

Sizes

Small

Select Pick Cut Base

Select Pick Cut Large

Select Pick Cut Selected: select

const [selectedTool, setSelectedTool] = useState("select");

return (
  <>
    <ToggleButtons size="sm" value={selectedTool} onValueChange={setSelectedTool}>
      <ToggleButton value="select">Select</ToggleButton>
      <ToggleButton value="pick">Pick</ToggleButton>
      <ToggleButton value="cut">Cut</ToggleButton>
    </ToggleButtons>

    <ToggleButtons size="base" value={selectedTool} onValueChange={setSelectedTool}>
      <ToggleButton value="select">Select</ToggleButton>
      <ToggleButton value="pick">Pick</ToggleButton>
      <ToggleButton value="cut">Cut</ToggleButton>
    </ToggleButtons>

    <ToggleButtons size="lg" value={selectedTool} onValueChange={setSelectedTool}>
      <ToggleButton value="select">Select</ToggleButton>
      <ToggleButton value="pick">Pick</ToggleButton>
      <ToggleButton value="cut">Cut</ToggleButton>
    </ToggleButtons>
  </>
);

Custom Styling

Select Pick Cut Selected: select

const [selectedTool, setSelectedTool] = useState("select");

return (
  <ToggleButtons 
    value={selectedTool} 
    onValueChange={setSelectedTool}
    className="bg-blue-100 border-2 border-blue-300" // Custom container styles
  >
    <ToggleButton 
      value="select" 
      className="font-bold text-blue-600" // Custom item styles
    >
      Select
    </ToggleButton>
    <ToggleButton value="pick">Pick</ToggleButton>
    <ToggleButton value="cut">Cut</ToggleButton>
  </ToggleButtons>
);

AsChild

Use asChild to render the toggle button as a different element while maintaining all functionality:

HomeAboutContactSelected: home

const [selectedPage, setSelectedPage] = useState("home");

return (
  <ToggleButtons value={selectedPage} onValueChange={setSelectedPage}>
    <ToggleButton value="home" asChild>
      <a href="#home">Home</a>
    </ToggleButton>
    <ToggleButton value="about" asChild>
      <a href="#about">About</a>
    </ToggleButton>
    <ToggleButton value="contact" asChild>
      <a href="#contact">Contact</a>
    </ToggleButton>
  </ToggleButtons>
);