UIPackage

Toggle

React action
Edit on GitHub

On/off button (different from Switch — this is shaped like a button and lives in toolbars). Three sizes, two variants. Use inside Toggle Group or standalone for "press to enable" buttons like bold / italic.

Also available for Vue ->

Installation

$ npx shadcn@latest add https://react.uipkge.dev/r/react/toggle.json

Or with the named registry: npx shadcn@latest add @uipkge-react/toggle

Examples

Props

Name Type / Values Default Required
variant
'default''outline'
default optional
size
'default''sm''lg'
default optional
asChild

emitting a <button> — the React equivalent of reka-ui's as-child.

boolean optional

Dependencies

Used by

Files (3)

  • components/ui/toggle/toggle.tsx 0.9 kB
    'use client'
    
    import * as React from 'react'
    import * as TogglePrimitive from '@radix-ui/react-toggle'
    import { cn } from '@/lib/utils'
    import { toggleVariants, type ToggleVariants } from './toggle.variants'
    
    export interface ToggleProps
      extends Omit<React.ComponentPropsWithoutRef<typeof TogglePrimitive.Root>, 'asChild'>,
        ToggleVariants {
      /** Render the child element as the toggle (merging props/styles) instead of
       *  emitting a <button> — the React equivalent of reka-ui's as-child. */
      asChild?: boolean
    }
    
    const Toggle = React.forwardRef<React.ElementRef<typeof TogglePrimitive.Root>, ToggleProps>(
      ({ className, variant, size, ...props }, ref) => (
        <TogglePrimitive.Root
          ref={ref}
          data-uipkge=""
          data-slot="toggle"
          className={cn(toggleVariants({ variant, size }), className)}
          {...props}
        />
      ),
    )
    Toggle.displayName = 'Toggle'
    
    export { Toggle }
  • components/ui/toggle/toggle.variants.ts 1.6 kB
    import type { VariantProps } from 'class-variance-authority'
    import { cva } from 'class-variance-authority'
    
    /**
     * Variant definitions live in their own file (rather than the package
     * `index.ts`) so consuming Vue SFCs can import without creating a circular
     * dependency through the index. See card.variants.ts for the canonical
     * example + the SSR symptom that motivated the split.
     */
    
    export const toggleVariants = cva(
      // Focus ring intentionally subtle: 1px ring on :focus-visible only, no
      // border swap. Keyboard users still get a clear focused state; mouse
      // users don't see a loud 3px halo after click (which lingers because
      // the button retains focus). Matches the segmented-control density.
      "inline-flex items-center justify-center gap-2 rounded-md text-sm font-medium hover:bg-muted hover:text-muted-foreground disabled:pointer-events-none disabled:opacity-50 data-[state=on]:bg-accent data-[state=on]:text-accent-foreground [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 [&_svg]:shrink-0 focus-visible:ring-ring/50 focus-visible:ring-1 outline-none transition-colors duration-200 whitespace-nowrap",
      {
        variants: {
          variant: {
            default: 'bg-transparent',
            outline: 'border border-input bg-transparent shadow-xs hover:bg-accent hover:text-accent-foreground',
          },
          size: {
            default: 'h-9 px-2 min-w-9',
            sm: 'h-8 px-1.5 min-w-8',
            lg: 'h-10 px-2.5 min-w-10',
          },
        },
        defaultVariants: {
          variant: 'default',
          size: 'default',
        },
      },
    )
    
    export type ToggleVariants = VariantProps<typeof toggleVariants>
  • components/ui/toggle/index.ts 0.1 kB
    export { Toggle, type ToggleProps } from './toggle'
    export { toggleVariants, type ToggleVariants } from './toggle.variants'

Raw manifest: https://react.uipkge.dev/r/react/toggle.json