{"name":"button-group","dependencies":["@base-ui/react","class-variance-authority"],"registryDependencies":["separator"],"files":[{"path":"button-group.tsx","content":"import { mergeProps } from \"@base-ui/react/merge-props\"\nimport { useRender } from \"@base-ui/react/use-render\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\n\nimport { cn } from \"@/lib/utils\"\nimport { Separator } from \"@/components/ui/separator\"\n\nconst buttonGroupVariants = cva(\n  cn(\n    // The GROUP itself is the cohesive NeoBrutalist unit: a single bold border +\n    // one hard offset shadow wrapping every segment, so it reads as ONE unit.\n    // The frame animates so the whole group can press like a single Button.\n    \"relative inline-flex w-fit items-stretch border-2 border-foreground bg-background shadow-md transition-all duration-200\",\n    // Segments become flush fills — the frame owns the border, shadow and corners.\n    \"[&>*]:rounded-none\",\n    \"[&>:is(button,a)]:border-0 [&>:is(button,a)]:shadow-none!\",\n    // Segments never translate on their own — only the whole frame moves.\n    \"[&>:is(button,a)]:hover:translate-y-0! [&>:is(button,a)]:active:translate-x-0! [&>:is(button,a)]:active:translate-y-0!\",\n    // The WHOLE group presses into its shadow like a single Button: hover sinks it\n    // toward the shadow, press sits it flush (shadow gone).\n    \"has-[:is(button,a):hover]:translate-y-1 has-[:is(button,a):hover]:shadow\",\n    \"has-[:is(button,a):active]:translate-y-2 has-[:is(button,a):active]:translate-x-1 has-[:is(button,a):active]:shadow-none\",\n    // When a group CONTAINS nested groups it becomes a plain gapped container\n    // (no frame / shadow / press) so each nested sub-group is its own pressable\n    // unit instead of pressing the whole outer frame.\n    \"has-[>[data-slot=button-group]]:gap-2 has-[>[data-slot=button-group]]:border-0 has-[>[data-slot=button-group]]:bg-transparent has-[>[data-slot=button-group]]:shadow-none! has-[>[data-slot=button-group]]:translate-x-0! has-[>[data-slot=button-group]]:translate-y-0!\",\n    // The hovered/pressed segment darkens in place via a full-bleed inset tint, so\n    // you can still tell which segment you're acting on while the frame presses.\n    \"[&>:is(button,a):hover]:shadow-[inset_0_0_0_999px_#00000012]! [&>:is(button,a):active]:shadow-[inset_0_0_0_999px_#0000001f]!\",\n\n    \"dark:[&>:is(button,a):hover]:shadow-[inset_0_0_0_999px_#ffffff1f]! dark:[&>:is(button,a):active]:shadow-[inset_0_0_0_999px_#ffffff33]!\",\n    // Solid dark segments (secondary) always lighten on hover — a dark tint would\n    // be invisible on a black button in light mode.\n    \"[&>:is(button,a)[data-variant=secondary]:hover]:shadow-[inset_0_0_0_999px_#ffffff2b]! [&>:is(button,a)[data-variant=secondary]:active]:shadow-[inset_0_0_0_999px_#ffffff45]!\",\n    \"[&>:is(button,a):focus-visible]:relative [&>:is(button,a):focus-visible]:z-10\"\n  ),\n  {\n    variants: {\n      orientation: {\n        // A single crisp seam between segments (logical side, so RTL-correct).\n        horizontal:\n          \"flex-row [&>*:not(:first-child)]:border-s-2! [&>*:not(:first-child)]:border-foreground\",\n        vertical:\n          \"flex-col [&>*:not(:first-child)]:border-t-2! [&>*:not(:first-child)]:border-foreground\",\n      },\n    },\n    defaultVariants: {\n      orientation: \"horizontal\",\n    },\n  }\n)\n\nfunction ButtonGroup({\n  className,\n  orientation,\n  ...props\n}: React.ComponentProps<\"div\"> & VariantProps<typeof buttonGroupVariants>) {\n  return (\n    <div\n      role=\"group\"\n      data-slot=\"button-group\"\n      data-orientation={orientation ?? \"horizontal\"}\n      className={cn(buttonGroupVariants({ orientation }), className)}\n      {...props}\n    />\n  )\n}\n\nfunction ButtonGroupText({\n  className,\n  render,\n  ...props\n}: useRender.ComponentProps<\"div\">) {\n  return useRender({\n    defaultTagName: \"div\",\n    props: mergeProps<\"div\">(\n      {\n        className: cn(\n          \"inline-flex items-center gap-2 bg-muted px-3 font-head text-sm font-medium text-foreground [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4\",\n          className\n        ),\n      },\n      props\n    ),\n    render,\n    state: {\n      slot: \"button-group-text\",\n    },\n  })\n}\n\nfunction ButtonGroupSeparator({\n  className,\n  orientation = \"vertical\",\n  ...props\n}: React.ComponentProps<typeof Separator>) {\n  return (\n    <Separator\n      data-slot=\"button-group-separator\"\n      orientation={orientation}\n      className={cn(\n        \"relative z-10 self-stretch bg-border data-horizontal:h-0.5 data-horizontal:w-auto data-vertical:h-auto data-vertical:w-0.5\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nexport {\n  ButtonGroup,\n  ButtonGroupSeparator,\n  ButtonGroupText,\n  buttonGroupVariants,\n}\n","type":"registry:ui","target":"components/ui/button-group.tsx"}],"type":"registry:ui"}