# TallStackUI: Button > TallStackUI is a TALL Stack (Tailwind CSS, Alpine.js, Laravel, Livewire) > component library providing 80+ Blade components for building modern web interfaces. A versatile button component supporting solid, light, outline, and flat styles with optional icons, loading states, tooltips, and link behavior. ## Basic Usage ```blade ``` ```blade ``` ```blade ``` ```blade ``` Submitting a form. The button renders `type="button"` by default, so it does **not** submit the surrounding form until `submit` is set. Use the `submit` prop — never write `type="submit"` by hand: ```blade {{-- correct --}} {{-- wrong: use the submit prop --}} ``` To submit a form declared elsewhere in the DOM, keep `submit` and add the native `form` attribute pointing at the form's `id`: ```blade
...
``` Controlling the border radius. `round` on its own gives a pill; with a size it gives that exact radius. `square` drops the radius altogether and wins over `round`: ```blade {{-- rounded-md --}} {{-- rounded-full --}} {{-- rounded-lg --}} {{-- no radius --}} ``` | Value | Class | |----------------|----------------| | (none) | `rounded-md` | | `round` | `rounded-full` | | `round="xs"` | `rounded-xs` | | `round="sm"` | `rounded-sm` | | `round="md"` | `rounded-md` | | `round="lg"` | `rounded-lg` | | `round="xl"` | `rounded-xl` | | `round="full"` | `rounded-full` | Omitted, `round` falls back to `config('tallstackui.components.button.round')` (`false` by default), so an application that leads with pills sets it once. The inline prop always wins, including `:round="false"`, and `square` still wins over both: ```blade {{-- with 'round' => true in the config --}} {{-- rounded-full --}} {{-- rounded-md --}} ``` Choosing the loading indicator. `spinner` renders one of the nine visual [Spinner](../spinner.md) variants as the `wire:loading` indicator — `ring`, `throbber`, `gradient`, `ping`, `dots`, `pulse`, `typing`, `bars` or `wave`. Omitted, it falls back to `config('tallstackui.components.button.spinner')` (shared with ``, `null` by default) and finally to the default effect. The textual variants (`shimmer`, `caret`, `terminal`, `thinking`) animate their own text and throw inside a button: ```blade {{-- throws --}} ``` ## Attributes | Attribute | Type | Default | Description | |-----------|--------------------|-----------|----------------------------------------------------------------------------------------------------------------------------------------------------------------| | text | string\|null | null | Button label text | | icon | string\|null | null | Heroicon name displayed alongside the text | | position | string\|null | 'left' | Icon position relative to text: 'left' or 'right' | | xs | bool | null | Extra-small size | | sm | bool | null | Small size | | md | bool | null | Medium size (default) | | lg | bool | null | Large size | | color | string\|null | 'primary' | Color theme (e.g., primary, red, green, yellow) | | square | string\|null | null | Removes border radius for square corners. Wins over `round` | | round | bool\|string\|null | null | `true` gives a pill (`rounded-full`). A size (xs, sm, md, lg, xl, full) gives that exact radius. Falls back to the `button.round` config, then to `rounded-md` | | block | bool | false | Expands button to full width (`w-full`) | | href | string\|null | null | When set, renders as an anchor tag instead of a button | | loading | string\|null | null | Livewire action name to show a loading spinner during execution | | delay | string\|null | null | Delay duration for the loading indicator (e.g., 'longest') | | spinner | string\|null | null | Loading spinner variant: ring, throbber, gradient, ping, dots, pulse, typing, bars, wave. Falls back to the `button.spinner` config | | solid | bool | true | Uses the solid color style variant (default) | | outline | bool | false | Uses the outline color style variant | | light | bool | false | Uses the light color style variant | | flat | bool | false | Uses the flat color style variant (no border) | | submit | bool | false | Renders `type="submit"` so the button submits its form. Always prefer this over passing `type="submit"` yourself | | unfocus | bool | false | No focus on mouse click (no ring/color); keyboard focus kept | | tooltip | string\|null | null | Tooltip text shown on hover | The balloon accepts the same attributes as anywhere else — `data-position`, `data-tooltip-delay`, `data-tooltip-color` and `data-tooltip-disabled`. See [Tooltip](../tooltip.md#the-x-tooltip-directive). ```blade ``` ## Slots | Slot | Description | |-----------|-----------------------------------------------------------------------| | (default) | Custom content, used when `text` is not provided | | left | Custom HTML rendered before the text (overrides left-positioned icon) | | right | Custom HTML rendered after the text (overrides right-positioned icon) | ## Soft Customization Soft customization allows you to override default Tailwind CSS classes used by this component at runtime, either through a service provider or scoped per-instance. ### Customization ```php TallStackUi::customize() ->button() ->block('wrapper.class', 'your-tailwind-classes'); ``` ### Available Blocks | Block Name | Purpose | |---------------------|---------------------------------------------------------------------| | wrapper.class | Base button styles (inline-flex, border, transition, cursor states) | | wrapper.sizes.xs | Extra-small text and padding | | wrapper.sizes.sm | Small text and padding | | wrapper.sizes.md | Medium text and padding | | wrapper.sizes.lg | Large text and padding | | wrapper.block | Full-width class applied by `block` | | border.radius.xs | Radius applied by `round="xs"` | | border.radius.sm | Radius applied by `round="sm"` | | border.radius.md | Radius applied by `round="md"` and by default | | border.radius.lg | Radius applied by `round="lg"` | | border.radius.xl | Radius applied by `round="xl"` | | border.radius.full | Radius applied by `round` and by `round="full"` | | wire.loading-cursor | Cursor applied while a `loading` action runs | | icon.sizes.xs | Extra-small icon dimensions | | icon.sizes.sm | Small icon dimensions | | icon.sizes.md | Medium icon dimensions | | icon.sizes.lg | Large icon dimensions | The loading indicator mirrors the Spinner's blocks under a `spinner.` prefix, sized to the button's icon box and isolated from the Spinner component's own customization: | Block Name | Purpose | |--------------------------------------|--------------------------------------------------------------| | spinner.delays.{0..4} | Shared stagger applied by index to every multi-child variant | | spinner.ring.base | Spinning border | | spinner.ring.sizes.{xs,sm,md,lg} | Ring diameter and border width | | spinner.throbber.base | Rotating SVG | | spinner.throbber.segment | Each of the twelve segments | | spinner.throbber.sizes.{xs,sm,md,lg} | SVG size | | spinner.gradient.base | Rotating SVG | | spinner.gradient.track | Dimmed circle behind the arc | | spinner.gradient.head | Highlighted arc | | spinner.gradient.sizes.{xs,sm,md,lg} | SVG size | | spinner.ping.wrapper | Positioning context | | spinner.ping.echo | Expanding echo ring | | spinner.ping.core | Static inner ring | | spinner.ping.sizes.wrapper.* | Ring diameter | | spinner.ping.sizes.border.* | Ring border width | | spinner.dots.wrapper | Dot row | | spinner.dots.dot | Each dot | | spinner.dots.sizes.wrapper.* | Gap between dots | | spinner.dots.sizes.dot.* | Dot diameter | | spinner.pulse.dot | The single dot | | spinner.pulse.sizes.{xs,sm,md,lg} | Dot diameter | | spinner.typing.wrapper | Dot row | | spinner.typing.dot | Each dot | | spinner.typing.sizes.wrapper.* | Gap between dots | | spinner.typing.sizes.dot.* | Dot diameter | | spinner.bars.wrapper | Bar row | | spinner.bars.bar | Each bar | | spinner.bars.sizes.wrapper.* | Gap between bars | | spinner.bars.sizes.bar.* | Bar height and width | | spinner.wave.wrapper | Bar row | | spinner.wave.bar | Each bar | | spinner.wave.sizes.wrapper.* | Gap between bars | | spinner.wave.sizes.bar.* | Bar height and width |