{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "toggle",
  "title": "Toggle",
  "description": "A button that stays pressed, with the Material selected state.",
  "dependencies": [
    "@base-ui/react@^1.7.0",
    "class-variance-authority@^0.7.1"
  ],
  "registryDependencies": [
    "https://guillermo-rebolledo.github.io/materialcn/r/materialcn-theme.json",
    "https://guillermo-rebolledo.github.io/materialcn/r/utils.json"
  ],
  "files": [
    {
      "path": "src/components/ui/toggle.tsx",
      "content": "import { Toggle as TogglePrimitive } from \"@base-ui/react/toggle\"\nimport { type VariantProps } from \"class-variance-authority\"\n\nimport { cn } from \"@/lib/utils\"\nimport { toggleVariants } from \"./toggle-variants\"\n\nfunction Toggle({\n  className,\n  variant = \"default\",\n  size = \"default\",\n  shape = \"round\",\n  ...props\n}: TogglePrimitive.Props & VariantProps<typeof toggleVariants>) {\n  return (\n    <TogglePrimitive\n      data-slot=\"toggle\"\n      data-shape={shape}\n      className={cn(toggleVariants({ variant, size, shape, className }))}\n      {...props}\n    />\n  )\n}\n\nexport { Toggle, toggleVariants }\n",
      "type": "registry:ui"
    },
    {
      "path": "src/components/ui/toggle-variants.ts",
      "content": "/**\n * Variant definitions live beside the component rather than inside it.\n *\n * React Fast Refresh only treats a module as a hot boundary when every export\n * either is a component or keeps a stable identity across re-evaluations.\n * `cva()` builds a fresh object each time its module runs, so exporting it from\n * the component file demoted that file to a full page reload on every edit.\n * Re-exported from here, the binding's identity survives edits to the component.\n */\n\nimport { cva } from \"class-variance-authority\"\n\n/**\n * Material 3 Expressive toggle button.\n *\n * Unselected it sits on `surface-container`; selected it takes the primary\n * pair. Selection also swaps the shape: a round toggle settles from a pill to\n * the medium/large corner, and a square toggle does the reverse, so the\n * selected state reads at a glance even without color. Pressing tightens the\n * corners further, exactly as the button does.\n *\n * Base UI's Toggle exposes selection as `data-pressed` (plus `aria-pressed`);\n * there is no `data-state`, so every selected style keys off `data-pressed:`.\n *\n * Hover and press are a state layer of the content color rather than a\n * background swap, so the selected and unselected states share one mechanism.\n */\nexport const toggleVariants = cva(\n  [\n    \"group/toggle relative isolate inline-flex cursor-pointer items-center justify-center gap-2\",\n    \"border border-transparent font-m3-medium text-m3-label-lg whitespace-nowrap outline-none\",\n    // Shape morph on a clamped property: effects spring, never spatial.\n    \"transition-[border-radius,background-color,color,border-color]\",\n    \"duration-(--m3-spring-effects-default-duration) ease-(--m3-spring-effects-default)\",\n    \"text-m3-on-surface-variant\",\n    \"disabled:pointer-events-none disabled:text-m3-on-surface/38 disabled:bg-m3-on-surface/10\",\n    // State layer.\n    // Covers the border box — see the note in button-variants.ts.\n    \"after:pointer-events-none after:absolute after:-inset-px after:-z-10\",\n    \"after:rounded-[inherit] after:bg-current after:opacity-0\",\n    \"after:transition-opacity after:duration-(--m3-spring-effects-fast-duration)\",\n    \"after:ease-(--m3-spring-effects-fast)\",\n    \"hover:not-disabled:after:opacity-8 focus-visible:after:opacity-10\",\n    \"active:not-disabled:after:opacity-10\",\n    \"focus-visible:outline-m3-secondary focus-visible:outline-3 focus-visible:outline-offset-2\",\n    // Selected.\n    \"data-pressed:bg-m3-primary data-pressed:text-m3-on-primary\",\n    \"data-pressed:disabled:bg-m3-on-surface/10 data-pressed:disabled:text-m3-on-surface/38\",\n    \"[&_svg]:pointer-events-none [&_svg]:shrink-0\",\n  ],\n  {\n    variants: {\n      variant: {\n        default: \"bg-m3-surface-container\",\n        // Outlined toggles invert on selection, and the stroke goes away with\n        // the fill taking its place.\n        outline: [\n          \"border-m3-outline-variant bg-transparent\",\n          \"data-pressed:border-transparent data-pressed:bg-m3-inverse-surface data-pressed:text-m3-inverse-on-surface\",\n        ],\n      },\n      // Heights, padding, gap and icon size per kit size (XSmall / Small /\n      // Medium). Radii are set by the shape compound variants below.\n      size: {\n        sm: \"h-8 min-w-8 gap-1 px-3 [&_svg:not([class*='size-'])]:size-5\",\n        default: \"h-10 min-w-10 px-4 [&_svg:not([class*='size-'])]:size-5\",\n        lg: \"h-14 min-w-14 px-6 text-m3-title-md [&_svg:not([class*='size-'])]:size-6\",\n      },\n      shape: {\n        round: \"\",\n        square: \"\",\n      },\n    },\n    compoundVariants: [\n      // Round: pill at rest, kit's selected corner (12 / 12 / 16) when\n      // selected, and the pressed corner (8 / 8 / 12) while pressed. The\n      // resting pill is half the height rather than `rounded-m3-full` so the\n      // morph spends its whole duration inside the perceptible range.\n      {\n        shape: \"round\",\n        size: \"sm\",\n        class: \"rounded-[16px] data-pressed:rounded-m3-md active:not-disabled:rounded-m3-sm\",\n      },\n      {\n        shape: \"round\",\n        size: \"default\",\n        class: \"rounded-[20px] data-pressed:rounded-m3-md active:not-disabled:rounded-m3-sm\",\n      },\n      {\n        shape: \"round\",\n        size: \"lg\",\n        class: \"rounded-[28px] data-pressed:rounded-m3-lg active:not-disabled:rounded-m3-md\",\n      },\n      // Square: the mirror image — rounded rect at rest, pill when selected.\n      {\n        shape: \"square\",\n        size: \"sm\",\n        class: \"rounded-m3-md data-pressed:rounded-[16px] active:not-disabled:rounded-m3-sm\",\n      },\n      {\n        shape: \"square\",\n        size: \"default\",\n        class: \"rounded-m3-md data-pressed:rounded-[20px] active:not-disabled:rounded-m3-sm\",\n      },\n      {\n        shape: \"square\",\n        size: \"lg\",\n        class: \"rounded-m3-lg data-pressed:rounded-[28px] active:not-disabled:rounded-m3-md\",\n      },\n    ],\n    defaultVariants: {\n      variant: \"default\",\n      size: \"default\",\n      shape: \"round\",\n    },\n  },\n)\n",
      "type": "registry:ui"
    }
  ],
  "categories": [
    "actions"
  ],
  "type": "registry:ui"
}