--- ## Button Versatile button component with multiple variants, sizes, intents, and micro-interaction patterns. Built with Svelte 5 and optimized for performance and accessibility. Takes no `href`. A link that should look like a Button is an `` with `buttonVariants({ … }).base()` on it — the recipe in `urbicon primer` under "A link that looks like a button". **Import:** `import { Button } from '@urbicon-ui/blocks';` ### Examples ```svelte ``` ```svelte ``` ```svelte ``` ### Variants - intent: danger, neutral, primary, secondary, success, warning (default: neutral) - variant: filled, ghost, outlined, text (default: filled) - size: 2xs, lg, md, sm, xl, xs (default: md) - active: false, true (default: false) - buttonGroupConnected: true - loading: false, true (default: false) - loadingPlacement: end, overlay, start (default: start) - pressed: true (default: false) - tier: commit, modify (default: commit) ### Api | Prop | Type | Required | Default | Description | | --- | --- | :---: | --- | --- | | ...ButtonVariants | `VariantProps` | no | | Styling variants from ButtonVariants | | ...HTMLButtonAttributes | `HTMLAttributes` | no | | HTML attributes (excluding: 'children') | | active | `boolean` | no | false | Whether the button is visually active/selected (e.g. in a ButtonGroup with selection). Unlike `pressed` (momentary feedback), `active` represents a persistent selected state. | | children | `Snippet` | no | | The content of the button | | class | `string` | no | | Custom CSS class name. In the same Tailwind bucket `class` wins over the `slotClasses` entry for the element it lands on. Presets and provider defaults sit below both. | | disabled | `boolean` | no | false | Whether the button is disabled | | loading | `boolean` | no | false | Whether the button is in a loading state | | loadingPlacement | `'overlay' | 'start' | 'end'` | no | 'overlay' | Where the loading indicator should appear when loading is true - 'overlay': spinner overlays content and hides it (default) - 'start': spinner appears before the content - 'end': spinner appears after the content | | mint | `MintProp` | no | 'scale' | Micro-interaction preset applied to the button. Only applies while the button is neither disabled nor loading. Inside a ButtonGroup, the group's `mint` always wins over this prop. `mint="none"` also flattens the press sink — the dip under a held pointer — leaving a button that reacts in colour and depth but never moves. Every ButtonGroup renders its children that way by default (its own `mint` defaults to `'none'` and wins over this prop), which is what keeps a connected group's shared seam still on click; it is also what a large or full-width trigger row wants, where the dip reads as a wobble. | | onclick | `(event: MouseEvent) => void` | no | | Click handler | | preset | `string` | no | | Apply a named preset registered via ``. Prefer this over `class="bg-…!"` overrides when the requested look is outside the semantic intent palette — presets keep hover/active/dark-mode logic coherent and make the custom look reusable across the project. | | pressed | `boolean` | no | false | Whether the button is pressed (for toggle buttons) | | slotClasses | `Partial>` | no | | Per-slot class overrides merged with tv styles. Slots: base | content | spinner. A button never shrinks below its label and never clips it; to truncate a long label instead, let the button shrink (`class="min-w-0"`) and wrap the label in a block that clips it: `…`. Not `slotClasses={{ content: 'truncate' }}` — the content slot is a flex row, and `text-overflow` paints its ellipsis only on a block container. In the same Tailwind bucket `class` wins over the `slotClasses` entry for the element it lands on. Presets and provider defaults sit below both. | | unstyled | `boolean` | no | false | Remove the default variant classes and apply yours instead. Not an empty element: the `blocks-*` hooks stay on the root (`blocks-button`, `blocks-intent-*`) so a stylesheet can still reach the button — see ARCHITECTURE.md § The override cascade. | | value | `string` | no | | The value associated with the button (useful in ButtonGroups) | | intent | `'danger' | 'neutral' | 'primary' | 'secondary' | 'success' | 'warning'` | no | neutral | Controls the color theme and semantic meaning of the Button. Affects the overall appearance and user perception. Available options: danger, neutral, primary, and 3 more. | | variant | `'filled' | 'ghost' | 'outlined' | 'text'` | no | filled | Controls the visual style and presentation of the Button. Determines the component's visual treatment. Available options: filled, ghost, outlined, text. | | size | `'2xs' | 'lg' | 'md' | 'sm' | 'xl' | 'xs'` | no | md | Controls the dimensions, padding, and text size of the Button. Affects the component's physical footprint. Available options: 2xs, lg, md, and 3 more. | | buttonGroupConnected | `'true'` | no | | Controls the buttonGroupConnected behavior and appearance of the Button component. Available options: true. | | tier | `'commit' | 'modify'` | no | commit | Selects the semantic radius tier of the Button — the shape family it belongs to (`--radius-commit`/`-modify`/`-contain`/`-bridge`). Shape is retuned per family in your theme, so this picks the family rather than a pixel value. Available options: commit, modify. | Inherited from: - ButtonVariants (external) - Omit (omit-pattern) ### Types ```ts type MintProp = | MintName | { name: MintName; config?: MintConfig & Record } | Array | Array }> ``` ```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 BuiltinMintName = (typeof BUILTIN_MINT_NAMES)[number] ``` ### Slots (slotClasses keys) `base`, `content`, `spinner`