--- ## ButtonGroup Groups related buttons with shared styling, layout, and optional selection behaviour. Supports single-select (radio), multi-select (checkbox), or no selection. Note the default `variant` is `outlined`, not `filled` as on a lone Button: a connected group with a selected state reads as a segmented control, which needs an outline to sit in and a filled active segment to stand out — three filled buttons side by side carry no hierarchy. Pass `variant="filled"` explicitly for a row of equally weighted actions. **Import:** `import { ButtonGroup } from '@urbicon-ui/blocks';` ### Examples ```svelte ``` ```svelte ``` ### Variants - connected: false, true (default: true) - disabled: true (default: false) - orientation: horizontal, vertical (default: horizontal) - tier: commit, modify (default: commit) ### Api | Prop | Type | Required | Default | Description | | --- | --- | :---: | --- | --- | | ...HTMLAttributes | `HTMLAttributes` | no | | HTML attributes (excluding: 'children') | | ariaLabel | `string` | no | | Accessible label for the group (prefer this over `aria-label` for correct HTML attribute). | | ariaLabelledBy | `string` | no | | ID of the element that labels the group. | | children | `Snippet` | no | | Button children to group. | | class | `string` | no | | Extra classes merged onto the root element. In the same Tailwind bucket `class` wins over the `slotClasses` entry for the element it lands on. Presets and provider defaults sit below both. | | connected | `boolean` | no | | Visually connect buttons (overlapping borders, shared rounding). When `false`, buttons are spaced with a small gap. | | disabled | `boolean` | no | | Disable the entire group and all child Buttons. | | intent | `ComponentIntent` | no | | Semantic colour propagated to child Buttons. | | mint | `MintProp` | no | 'none' | Micro-interaction preset applied to each child Button (per-item via context); overrides each button's own `mint` prop. The `'none'` default also flattens each button's press sink, so a connected group's shared seam stays still on click instead of one segment shrinking away from its neighbours. Buttons keep reporting the press in depth and colour. Name any real mint here to give the whole group its movement back. | | onSelectionChange | `(value: ButtonGroupValue, selectedValues: string[]) => void` | no | | Fired when selection changes. Receives the new value and an array of all selected values. | | orientation | `ButtonGroupOrientation` | no | | Stack direction. | | preset | `string` | no | | Apply a named preset registered via ``. Prefer this over `class` overrides when the requested look falls outside the semantic intent palette — presets keep hover/active/dark-mode logic coherent and make the custom look reusable across the project. | | selection | `ButtonGroupSelection` | no | | Selection mode. `"single"` = radio-group, `"multiple"` = checkbox-group, `"none"` = no selection. | | size | `ComponentSize` | no | | Size propagated to child Buttons (the group value wins over a Button's own `size`). | | slotClasses | `Partial>` | no | | Per-slot class overrides. Slots: base. In the same Tailwind bucket `class` wins over the `slotClasses` entry for the element it lands on. Presets and provider defaults sit below both. | | tier | `InteractiveTier` | no | | Semantic radius tier propagated to child Buttons. `commit` → pill caps for the group; `modify` → soft caps. Inherits from a wrapping Toolbar via TierContext when not set explicitly. The unset default is `commit`, except on a connected vertical group, where the pill cap domes the stack into a lozenge — that one defaults to `modify`. Set `tier="commit"` explicitly to get the capsule back (right for a narrow, icon-only stack). | | unstyled | `boolean` | no | | Remove all default tv classes. | | value | `ButtonGroupValue` | no | | Current selection value. Bind with `bind:value` for two-way sync. String for single, string[] for multiple. | | variant | `ButtonVariants['variant']` | no | | Visual weight propagated to child Buttons. | Inherited from: - Omit, 'children'> (omit-pattern) ### Types ```ts type ButtonGroupSelection = 'none' | 'single' | 'multiple' ``` ```ts type ButtonGroupOrientation = 'horizontal' | 'vertical' ``` ```ts type ButtonGroupValue = string | string[] | undefined ``` ```ts interface ButtonGroupContext { readonly orientation: ButtonGroupOrientation; readonly connected: boolean; readonly size: ComponentSize; readonly intent: ComponentIntent; readonly variant: ComponentVariant; readonly selection: ButtonGroupSelection; readonly disabled: boolean; readonly mint: MintProp; readonly selectedValues: Set; registerButton: (value: string | undefined) => { readonly isSelected: boolean; onClick: () => void; getButtonProps: () => { role?: 'radio' | 'checkbox'; 'aria-checked'?: boolean; /** * The Button's selection value, exposed on the element so the group can * resolve the selected radio by matching value instead of by position * (robust against duplicate values and runtime add/remove). */ 'data-value'?: string; }; }; } ``` ```ts type MintProp = | MintName | { name: MintName; config?: MintConfig & Record } | Array | Array }> ``` ```ts type ComponentIntent = (typeof INTENTS)[number] ``` ```ts type ComponentSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl' ``` ```ts type InteractiveTier = 'commit' | 'modify' ``` ```ts type MintName = BuiltinMintName | 'none' | (string & {}) ``` ```ts interface MintConfig { /** * `hover` and `focus` hold the effect while the pointer/visible focus stays * on the element; `click` and `load` run it once. */ trigger?: 'hover' | 'click' | 'focus' | 'load'; /** * Effect duration in ms. Written as an inline per-effect custom property * (`--blocks-mint--duration`), so the CSS transition/animation * actually runs at this speed; unset, the theme duration tokens apply. */ duration?: number; /** Delay in ms before the effect applies. */ delay?: number; /** * CSS easing for the effect (`--blocks-mint--easing` inline); * unset, the per-effect theme default applies. */ easing?: string; disabled?: boolean; } ``` ```ts type VariantProps = Omit< Exclude[0], undefined>, 'class' > ``` ```ts type BuiltinMintName = (typeof BUILTIN_MINT_NAMES)[number] ``` ### Slots (slotClasses keys) `base`