button-group
neobrutalism/button-groupFreeComponent
neobrutalism publishes no description for this item.
Live preview
live · rendered by the registry
Rendered by neobrutalism on their own page — this is the component running, not a screenshot of it.Install it
npx shadcn@latest add https://neobrutalism.com/r/button-group.jsonSource
1import { mergeProps } from "@base-ui/react/merge-props"2import { useRender } from "@base-ui/react/use-render"3import { cva, type VariantProps } from "class-variance-authority"45import { cn } from "@/lib/utils"6import { Separator } from "@/components/ui/separator"78const buttonGroupVariants = cva(9 cn(10 // The GROUP itself is the cohesive NeoBrutalist unit: a single bold border +11 // one hard offset shadow wrapping every segment, so it reads as ONE unit.12 // The frame animates so the whole group can press like a single Button.13 "relative inline-flex w-fit items-stretch border-2 border-foreground bg-background shadow-md transition-all duration-200",14 // Segments become flush fills — the frame owns the border, shadow and corners.15 "[&>*]:rounded-none",16 "[&>:is(button,a)]:border-0 [&>:is(button,a)]:shadow-none!",17 // Segments never translate on their own — only the whole frame moves.18 "[&>:is(button,a)]:hover:translate-y-0! [&>:is(button,a)]:active:translate-x-0! [&>:is(button,a)]:active:translate-y-0!",19 // The WHOLE group presses into its shadow like a single Button: hover sinks it20 // toward the shadow, press sits it flush (shadow gone).21 "has-[:is(button,a):hover]:translate-y-1 has-[:is(button,a):hover]:shadow",22 "has-[:is(button,a):active]:translate-y-2 has-[:is(button,a):active]:translate-x-1 has-[:is(button,a):active]:shadow-none",23 // When a group CONTAINS nested groups it becomes a plain gapped container24 // (no frame / shadow / press) so each nested sub-group is its own pressable25 // unit instead of pressing the whole outer frame.26 "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!",27 // The hovered/pressed segment darkens in place via a full-bleed inset tint, so28 // you can still tell which segment you're acting on while the frame presses.29 "[&>:is(button,a):hover]:shadow-[inset_0_0_0_999px_#00000012]! [&>:is(button,a):active]:shadow-[inset_0_0_0_999px_#0000001f]!",3031 "dark:[&>:is(button,a):hover]:shadow-[inset_0_0_0_999px_#ffffff1f]! dark:[&>:is(button,a):active]:shadow-[inset_0_0_0_999px_#ffffff33]!",32 // Solid dark segments (secondary) always lighten on hover — a dark tint would33 // be invisible on a black button in light mode.34// … truncated
What it pulls in
npm packages
Other registry items
Files it writes
More from neobrutalism
All 54 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| accordionaccordion | neobrutalism | Components | Free | 2 deps | |
| alertalert | neobrutalism | Components | Free | 2 deps | |
| alert-dialogalert-dialog | neobrutalism | Components | Free | 1 dep | |
| aspect-ratioaspect-ratio | neobrutalism | Components | Free | 1 dep | |
| avataravatar | neobrutalism | Components | Free | 1 dep | |
| badgebadge | neobrutalism | Components | Free | 2 deps | |
| breadcrumbbreadcrumb | neobrutalism | Components | Free | 2 deps | |
| buttonbutton | neobrutalism | Components | Free | 2 deps |
