Forms

Toggle Group.

A row of toggles joined together, allowing one or many to be pressed.

Installation#

With the CLI

$npx lanterncn add toggle-group

This also installs the Lantern theme and any Lantern UI components it depends on. The shadcn CLI works directly too: npx shadcn@latest add httptim/lantern-ui/toggle-group. See Installation if your project is not set up yet.

Manually

  1. Install the dependencies

    npm install radix-ui class-variance-authority
  2. Copy the source into your project

    components/ui/toggle-group.tsx
    "use client";
    
    import * as React from "react";
    import { type VariantProps } from "class-variance-authority";
    import { ToggleGroup as ToggleGroupPrimitive } from "radix-ui";
    
    import { cn } from "@/lib/utils";
    import { toggleVariants } from "@/components/ui/toggle";
    
    const ToggleGroupContext = React.createContext<VariantProps<typeof toggleVariants>>({
      size: "default",
      variant: "default",
    });
    
    function ToggleGroup({
      className,
      variant,
      size,
      children,
      ...props
    }: React.ComponentProps<typeof ToggleGroupPrimitive.Root> & VariantProps<typeof toggleVariants>) {
      return (
        <ToggleGroupPrimitive.Root
          data-slot="toggle-group"
          data-variant={variant ?? "default"}
          data-size={size ?? "default"}
          className={cn(
            "group/toggle-group flex w-fit items-center rounded-md data-[variant=default]:gap-1 data-[variant=outline]:shadow-[3px_3px_0_var(--block-shadow)]",
            className,
          )}
          {...props}
        >
          <ToggleGroupContext.Provider value={{ variant, size }}>{children}</ToggleGroupContext.Provider>
        </ToggleGroupPrimitive.Root>
      );
    }
    
    function ToggleGroupItem({
      className,
      children,
      variant,
      size,
      ...props
    }: React.ComponentProps<typeof ToggleGroupPrimitive.Item> & VariantProps<typeof toggleVariants>) {
      const context = React.useContext(ToggleGroupContext);
    
      return (
        <ToggleGroupPrimitive.Item
          data-slot="toggle-group-item"
          data-variant={context.variant || variant || "default"}
          data-size={context.size || size || "default"}
          className={cn(
            toggleVariants({ variant: context.variant || variant, size: context.size || size }),
            "min-w-0 flex-1 shrink-0 shadow-none focus:z-10 focus-visible:z-10",
            "data-[variant=outline]:rounded-none data-[variant=outline]:focus-visible:ring-offset-0 data-[variant=outline]:first:rounded-l-md data-[variant=outline]:last:rounded-r-md",
            "data-[variant=outline]:border-l-0 data-[variant=outline]:first:border-l data-[variant=outline]:data-[state=on]:border-input",
            className,
          )}
          {...props}
        >
          {children}
        </ToggleGroupPrimitive.Item>
      );
    }
    
    export { ToggleGroup, ToggleGroupItem };
  3. Update the import paths to match your project

    The source imports cn from @/lib/utils and uses toggle.

Usage#

import { ToggleGroup, ToggleGroupItem } from "@/components/ui/toggle-group";
<ToggleGroup type="single" variant="outline" defaultValue="left">
  <ToggleGroupItem value="left" aria-label="Align left">
    <AlignLeftIcon />
  </ToggleGroupItem>
  <ToggleGroupItem value="right" aria-label="Align right">
    <AlignRightIcon />
  </ToggleGroupItem>
</ToggleGroup>

Examples#

Multiple

Show devices