# Button

`Button` triggers an action or opens a destination, with shared variants, keyboard behavior and disabled states.

## Usage

Import `Button` from the shared package. Load `@dg/ui/styles.css` once in the application layout.

```svelte
<script>
  import { Button } from "@dg/ui";
  let count = $state(0);
</script>

<Button label="Explore artworks" href="/artworks" />
<Button label="Add an item" variant="accent" onclick={() => count++} />
<p class="feedback" aria-live="polite">Items added: {count}</p>
<Button disabled icon={false}>Unavailable action</Button>
```

Use `type="submit"` or `type="reset"` inside a form for native form behavior. Without `href`, the default type is `button`, so an ordinary action does not submit its surrounding form.

## Notes

- Native HTML attributes (`id`, `class`, `style`, `aria-*`, `target`, `rel`, `name`, `value`) and DOM callbacks such as `onclick`, `onfocus` and `onkeydown` are forwarded to the native button or anchor.
- Forwarding uses native attribute types; unknown props are not supported. Pass class as a string and use attributes appropriate to the rendered button or link.
- `subtle` is the default neutral variant: a prominent surface without a visible border, marked at its four corners by the shared [`.half-crossed`](../foundations/surfaces.md#classes) accent half-crosses, like focused fields. Hover replaces the marks with the shared inverted fill. `solid` uses the prominent text color as its resting background. `accent` uses the accent color for its background and border, with dark lettering in both themes and the shared inverted hover state.
- The `children` snippet replaces `label`. The default arrow can be removed with `icon={false}`, replaced with a string such as `icon="+"`, or supplied as a decorative snippet.
- Width follows the label, even inside a stack or `Section` that stretches its children; long labels wrap within the container. Set a width in the owning styles for a full-width button. Padding uses the shared control tokens, and both minimum dimensions follow `--control-min-size`.

## Parameters

| Name       | Type                              | Default     | Description                                                                            |
| ---------- | --------------------------------- | ----------- | -------------------------------------------------------------------------------------- |
| `label`    | `string`                          | `""`        | Button text when no children snippet is supplied.                                      |
| `variant`  | `'subtle' \| 'solid' \| 'accent'` | `"subtle"`  | Neutral surface with accent corners, solid inverted surface, or filled accent surface. |
| `href`     | `string`                          | `undefined` | Supplying a destination renders a native link instead of a button.                     |
| `type`     | `'button' \| 'submit' \| 'reset'` | `"button"`  | Native form behavior for the button variant.                                           |
| `disabled` | `boolean`                         | `false`     | Block activation and remove keyboard focus, including when href is supplied.           |
| `icon`     | `string \| false \| Snippet`      | `"→"`       | Trailing decorative icon. False removes it; a string or snippet replaces the arrow.    |
| `children` | `Snippet`                         | `undefined` | Custom button content; replaces label.                                                 |

## Methods

| Name      | Description                                                   |
| --------- | ------------------------------------------------------------- |
| `focus()` | Focus the element without scrolling. Access with `bind:this`. |

## Accessibility

Give textless actions an explicit accessible name with `aria-label`. Icons are decorative and do not supply the button's accessible name. Disabled actions, including links, cannot be activated and are excluded from keyboard navigation.

Use Tab to check visible focus, then Enter to activate a link or Enter and Space to activate a button. Hover over the variants and switch themes to inspect their states. Focus can also be restored explicitly through the component's `focus()` method.
