{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "split-button",
  "type": "registry:ui",
  "title": "Split button",
  "description": "Split button with a primary action and a chevron that opens a dropdown of secondary actions, including destructive items. The menu matches the button width.",
  "dependencies": [
    "lucide-react"
  ],
  "registryDependencies": [
    "https://ui.minidev.pro/r/button.json",
    "https://ui.minidev.pro/r/dropdown-menu.json",
    "utils"
  ],
  "files": [
    {
      "path": "registry/ui/split-button.tsx",
      "type": "registry:ui",
      "target": "components/ui/split-button.tsx",
      "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { ChevronDownIcon } from \"lucide-react\"\nimport { Button } from \"@/components/ui/button\"\nimport {\n  DropdownMenu,\n  DropdownMenuContent,\n  DropdownMenuItem,\n  DropdownMenuTrigger,\n} from \"@/components/ui/dropdown-menu\"\nimport { cn } from \"@/lib/utils\"\n\n/** A primary action with an attached chevron that opens a menu of related actions. */\ntype SplitButtonItem = { label: string; onSelect?: () => void; destructive?: boolean }\n\ntype SplitButtonProps = {\n  /** The primary action's label. */\n  label?: React.ReactNode\n  onPrimaryClick?: () => void\n  disabled?: boolean\n  className?: string\n  /** Secondary actions in the menu; the menu matches the button's width. */\n  items?: SplitButtonItem[]\n}\n\nconst SAMPLE_ITEMS: SplitButtonItem[] = [\n  { label: \"Save draft\" },\n  { label: \"Save and close\" },\n  { label: \"Discard\", destructive: true },\n]\n\nfunction SplitButton({\n  label = \"Save invoice\",\n  onPrimaryClick,\n  disabled,\n  className,\n  items = SAMPLE_ITEMS,\n}: SplitButtonProps) {\n  const ref = React.useRef<HTMLDivElement>(null)\n  const [menuMinWidth, setMenuMinWidth] = React.useState<number>()\n\n  React.useLayoutEffect(() => {\n    const el = ref.current\n    if (!el) return\n    const sync = () => setMenuMinWidth(el.getBoundingClientRect().width)\n    sync()\n    const ro = new ResizeObserver(sync)\n    ro.observe(el)\n    return () => ro.disconnect()\n  }, [])\n\n  return (\n    <div\n      ref={ref}\n      data-slot=\"split-button\"\n      className={cn(\"inline-flex items-stretch\", className)}\n    >\n      <Button\n        variant=\"outline\"\n        disabled={disabled}\n        onClick={onPrimaryClick}\n        className=\"rounded-r-none border-r-transparent\"\n      >\n        {label}\n      </Button>\n      <DropdownMenu>\n        <DropdownMenuTrigger\n          disabled={disabled}\n          className={cn(\n            \"inline-flex h-9 w-9 items-center justify-center rounded-l-none rounded-r-lg border border-border bg-surface text-fg\",\n            \"border-l-border shadow-highlight outline-none\",\n            \"transition-[border-color,background-color,transform] duration-[70ms]\",\n            \"hover:border-fg-subtle focus-visible:ring-2 focus-visible:ring-accent focus-visible:ring-offset-2 focus-visible:ring-offset-bg\",\n            \"active:translate-y-[0.5px] disabled:opacity-50\"\n          )}\n          aria-label=\"More actions\"\n        >\n          <ChevronDownIcon className=\"size-4\" />\n        </DropdownMenuTrigger>\n        <DropdownMenuContent\n          align=\"end\"\n          sideOffset={6}\n          className=\"min-w-44\"\n          style={menuMinWidth ? { minWidth: menuMinWidth } : undefined}\n        >\n          {items.map((item) => (\n            <DropdownMenuItem\n              key={item.label}\n              variant={item.destructive ? \"destructive\" : \"default\"}\n              onClick={item.onSelect}\n            >\n              {item.label}\n            </DropdownMenuItem>\n          ))}\n        </DropdownMenuContent>\n      </DropdownMenu>\n    </div>\n  )\n}\n\nexport { SplitButton }\nexport type { SplitButtonProps, SplitButtonItem }\n"
    }
  ]
}
