{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "toggle-group",
  "title": "Toggle Group",
  "description": "Toggle Group from the Get IT Done design system.",
  "dependencies": [
    "@radix-ui/react-toggle-group@^1.2.1",
    "class-variance-authority@^0.7.0"
  ],
  "registryDependencies": [
    "https://zero-design.itdone.de/r/labels-context.json",
    "https://zero-design.itdone.de/r/utils.json",
    "https://zero-design.itdone.de/r/theme.json"
  ],
  "files": [
    {
      "path": "registry/ui/toggle-group.tsx",
      "content": "'use client';\n\nimport * as ToggleGroupPrimitive from '@radix-ui/react-toggle-group';\nimport React from 'react';\n\nimport { cva, type VariantProps } from 'class-variance-authority';\n\nimport { cn } from '@/lib/utils';\nimport { usePreset } from '@/components/ui/labels-context';\n\nconst toggleGroupVariants = cva(\n  'inline-flex items-center justify-center rounded-control transition-[color,background-color,border-color,box-shadow] duration-150 hover:bg-muted hover:text-foreground focus-visible:outline-none focus-visible:ring-focus focus-visible:ring-offset-focus focus-visible:ring-offset-background focus-visible:ring-ring-default disabled:pointer-events-none disabled:opacity-disabled data-[state=on]:bg-muted data-[state=on]:text-foreground',\n  {\n    variants: {\n      variant: {\n        default: 'bg-transparent',\n        outline:\n          'border border-solid border-input bg-background shadow-xs hover:border-border-bold hover:bg-background data-[state=on]:bg-muted',\n        // Segmented control: items sit in a `bg-muted` track (see the Root), the on item is a raised chip.\n        segmented:\n          'rounded-item bg-transparent text-muted-foreground hover:bg-transparent hover:text-foreground data-[state=on]:bg-background data-[state=on]:hover:bg-background data-[state=on]:shadow-xs',\n      },\n      size: {\n        default: 'h-9 px-3',\n        sm: 'h-8 px-2',\n        md: 'h-10 px-3',\n        lg: 'h-10 px-3',\n      },\n      // Product preset (DesignSystemProvider `preset`): `zero` binds the heights to the control tokens and the label to the button roles, and the segmented item to the Tabs segment size.\n      preset: { default: 'text-sm font-medium', zero: '' },\n    },\n    compoundVariants: [\n      { preset: 'zero', size: 'default', className: 'h-control-md typography-button-md' },\n      { preset: 'zero', size: 'sm', className: 'h-control-sm typography-button-sm' },\n      { preset: 'zero', size: 'md', className: 'h-control-md typography-button-md' },\n      { preset: 'zero', size: 'lg', className: 'h-control-lg typography-button-md' },\n      { preset: 'zero', variant: 'segmented', className: 'h-control-xs rounded-item px-control-px-sm typography-tab' },\n      // Outside zero the default-size segmented item is 32px, so the track (3px padding) is 38px like the segmented Tabs.\n      { preset: 'default', variant: 'segmented', size: 'default', className: 'h-8' },\n      // Sized segmented group outside zero: the track sets the height (Button sm 32, md 40), the items fill it.\n      { preset: 'default', variant: 'segmented', size: ['sm', 'md', 'lg'], className: 'h-full' },\n    ],\n    defaultVariants: {\n      variant: 'default',\n      size: 'default',\n      preset: 'default',\n    },\n  },\n);\n\ntype ToggleGroupContextValue = Omit<VariantProps<typeof toggleGroupVariants>, 'preset'>;\n\n// Group-level defaults for `variant`/`size` (shadcn pattern). Items read these and may override them.\nconst ToggleGroupContext = React.createContext<ToggleGroupContextValue>({});\n\nconst ToggleGroup = React.forwardRef<\n  React.ElementRef<typeof ToggleGroupPrimitive.Root>,\n  React.ComponentPropsWithoutRef<typeof ToggleGroupPrimitive.Root> & Omit<VariantProps<typeof toggleGroupVariants>, 'preset'>\n\n>(({ className, variant, size, children, ...props }, ref) => {\n  const zero = usePreset() === 'zero';\n  // Standard controlled/uncontrolled dual-mode: forward value/defaultValue/onValueChange\n  // straight through to Radix, which already implements this correctly via\n  // useControllableState. Do NOT shadow `value` with local state here - doing so\n  // permanently uncontrols the component and discards any consumer-supplied value.\n  return (\n    // The Root is a layout container, not a toggle button: `toggleGroupVariants` (height, padding,\n    // hover/on states) styles the ITEMS only. The Root forwards `className` and shares\n    // `variant`/`size` with its items via context. No base classes are added, so unstyled\n    // groups render exactly as before.\n    <ToggleGroupPrimitive.Root\n      {...props}\n      className={cn(variant === 'segmented' && 'inline-flex items-center gap-0 rounded-control bg-muted', variant === 'segmented' && (zero ? 'p-micro' : 'p-[3px]'),\n        // Sized track outside zero: total height equals the Button height (sm 32, md and lg 40). Without size the 38px legacy track stays.\n        variant === 'segmented' && !zero && size && size !== 'default' && (size === 'sm' ? 'h-control-sm' : 'h-control-md'),\n        className,\n      )}\n      ref={ref}\n    >\n      <ToggleGroupContext.Provider value={{ variant, size }}>{children}</ToggleGroupContext.Provider>\n    </ToggleGroupPrimitive.Root>\n  );\n});\n\nToggleGroup.displayName = ToggleGroupPrimitive.Root.displayName;\n\nconst ToggleGroupItem = React.forwardRef<\n  React.ElementRef<typeof ToggleGroupPrimitive.Item>,\n  React.ComponentPropsWithoutRef<typeof ToggleGroupPrimitive.Item> &\n    VariantProps<typeof toggleGroupVariants> & {\n      /**\n       * Marks the item as reachable-but-blocked: it stays in the roving-tabindex/\n       * arrow-key sequence and remains focusable, but activation (click or\n       * keyboard) is suppressed. Unlike native `disabled`, this does NOT remove\n       * the item from the tab order or the accessibility tree.\n       */\n      unreachable?: boolean;\n    }\n>(({ className, variant, size, children, unreachable, onClick, ...props }, ref) => {\n  const context = React.useContext(ToggleGroupContext);\n  const zero = usePreset() === 'zero';\n  return (\n    <ToggleGroupPrimitive.Item\n      {...props}\n      {...(unreachable ? { 'aria-disabled': true, 'data-unreachable': true } : {})}\n      onClick={(event) => {\n        if (unreachable) {\n          event.preventDefault();\n        }\n        onClick?.(event);\n      }}\n      className={cn(\n        toggleGroupVariants({ variant: variant ?? context.variant, size: size ?? context.size, preset: zero ? 'zero' : 'default', className }),\n        'data-[unreachable=true]:pointer-events-none data-[unreachable=true]:opacity-disabled',\n      )}\n      ref={ref}\n    >\n      <span>{children}</span>\n    </ToggleGroupPrimitive.Item>\n  );\n});\n\nToggleGroupItem.displayName = ToggleGroupPrimitive.Item.displayName;\n\nexport { ToggleGroup, ToggleGroupItem, toggleGroupVariants };\n",
      "type": "registry:ui"
    }
  ],
  "type": "registry:ui"
}