# <aihio-button>

An action the user takes: submit a form, open a dialog, run a command. Renders a real <button>; variant="default" is the primary style and variant="destructive" marks an irreversible action. To go to another page, put an <a href> inside it instead: the link becomes the control, styled as the button.

Intents: `action`, `primary-action`, `secondary-action`, `destructive-action`, `navigation`.

## Attributes

- `variant` (`default` | `secondary` | `outline` | `ghost` | `link` | `destructive`): Visual style variant. Default: `default`.
- `size` (`sm` | `md` | `lg` | `icon`): Button size. Default: `md`.
- `disabled` (boolean): Disables the button. Default: `false`.
- `loading` (boolean): Shows loading state and disables interaction. Default: `false`.
- `type` (`button` | `submit` | `reset`): Form behaviour, forwarded to the native <button> this component renders. submit submits the owning form (running native constraint validation first); reset resets it. Defaults to button, which does neither. Default: `button`.
- `name` (string): Submitter name included with form data.
- `value` (string): Submitter value included with form data.
- `form` (string): Id of an external form that owns the button.
- `formaction` (string): Submit URL override for submit buttons.
- `formmethod` (`get` | `post` | `dialog`): HTTP method override for submit buttons.
- `formenctype` (`application/x-www-form-urlencoded` | `multipart/form-data` | `text/plain`): Encoding override for submit buttons.
- `formnovalidate` (boolean): Skips form validation when this submit button is used.
- `formtarget` (string): Browsing context target for the form response.
- `command` (string): Invoker command sent to the element named by commandfor when the button is activated, e.g. command="--open" to open an aihio-dialog. Aihio components take --prefixed custom commands; see each component's commands.
- `commandfor` (string): Id of the element that receives command. Use with command to open or close an overlay without script.

## Properties

- `control` (`HTMLButtonElement | HTMLAnchorElement | null`, read-only): The native button the component delegates to, or the authored <a> when it wraps a link.
- `form` (`HTMLFormElement | null`, read-only): The owning form, or null outside one or when the control is a link.
- `type` (`"button" | "submit" | "reset"`): Current native button type.

## Methods

- `click()`: Activates the native button.
- `focus()`: Moves focus to the native button.
- `blur()`: Removes focus from the native button.

## Events

- `click`: Fired when the button is clicked.

## Slots

- `default`: Button label content.

## Accessibility obligations

- (error, button-accessible-name) When size="icon" or the button has no visible text: Provide aria-label describing the action (e.g. aria-label="Close").
- (warn, button-form-owner) When the button submits a form: Set type="submit" and either place the button inside its <form> or reference that form with the form attribute.
- (error, button-link-navigation) When the button goes to another page from a click handler (onclick sets location, or calls window.open or router.push): Put an <a href> inside aihio-button instead: <aihio-button><a href="/pricing">See pricing</a></aihio-button>. A button that navigates is announced as a button, shows no URL, cannot be opened in a new tab, and does nothing without script.
- (error, button-link-href) When the button wraps an <a>: Give the <a> an href. Without one it is not a link: it has no role, takes no focus, and goes nowhere.
- (warn, button-link-attributes) When the button wraps an <a>: Leave type, name, value, form*, command, and commandfor off the host. They configure a <button>, so on a link they do nothing.

## Examples

### Primary action

The default variant, for the main thing to do in a view.

```html
<aihio-button>Click me</aihio-button>
```

### Small and outlined

A lower-emphasis action beside a primary one.

```html
<aihio-button variant="outline" size="sm">Cancel</aihio-button>
```

### Destructive

For an action that deletes something or cannot be undone.

```html
<aihio-button variant="destructive">Delete</aihio-button>
```

### Icon only

With no visible text, aria-label is its name.

```html
<aihio-button size="icon" aria-label="Close">&#x2715;</aihio-button>
```

### A link drawn as a button

A call to action that goes to another page wraps an <a href>.

```html
<aihio-button variant="outline"><a href="/pricing">See pricing</a></aihio-button>
```

### Submits its form

type="submit" makes it the form's submitter, so Enter in a field submits too.

```html
<form>
  <label>
    Email
    <aihio-input type="email" name="email" required></aihio-input>
  </label>
  <aihio-button type="submit">Sign in</aihio-button>
</form>
```

### Opens a dialog from markup

commandfor names the dialog and command="--open" opens it, with no script.

```html
<aihio-button commandfor="confirm-delete" command="--open" variant="destructive">Delete project</aihio-button>

<aihio-dialog id="confirm-delete">
  <aihio-dialog-header>
    <aihio-dialog-title>Delete project?</aihio-dialog-title>
  </aihio-dialog-header>
  <form method="post">
    <aihio-dialog-footer>
      <aihio-button commandfor="confirm-delete" command="--close" variant="outline">Cancel</aihio-button>
      <aihio-button type="submit" variant="destructive">Delete project</aihio-button>
    </aihio-dialog-footer>
  </form>
</aihio-dialog>
```

## Mistakes

### variant="primary" is not valid. The primary style is variant="default".

Don't (aihio lint: invalid-enum-attribute):

```html
<aihio-button variant="primary">Save</aihio-button>
```

Do:

```html
<aihio-button variant="default">Save</aihio-button>
```

### Buttons must not be nested. Use sibling buttons or aihio-dropdown for grouped actions.

Don't (aihio lint: forbidden-descendant):

```html
<aihio-button><aihio-button>Save</aihio-button></aihio-button>
```

Do:

```html
<aihio-cluster>
  <aihio-button variant="outline">Cancel</aihio-button>
  <aihio-button>Save</aihio-button>
</aihio-cluster>
```

### Icon-only button is missing an accessible name. Add aria-label="Close" (or similar).

Don't (aihio lint: button-accessible-name):

```html
<aihio-button size="icon">&#x2715;</aihio-button>
```

Do:

```html
<aihio-button size="icon" aria-label="Close">&#x2715;</aihio-button>
```

### A submit button outside the <form> never submits it. Move the button inside the form element.

Don't (aihio lint: button-form-owner):

```html
<form>
  <aihio-input name="email" aria-label="Email"></aihio-input>
</form>
<aihio-button type="submit">Sign in</aihio-button>
```

Do:

```html
<form>
  <aihio-input name="email" aria-label="Email"></aihio-input>
  <aihio-button type="submit">Sign in</aihio-button>
</form>
```

### A button that navigates is announced as a button, shows no URL, cannot be opened in a new tab, and does nothing without script. Put a link inside it: <aihio-button><a href="/pricing">See pricing</a></aihio-button>.

Don't (aihio lint: button-link-navigation):

```html
<aihio-button onclick="location.href='/pricing'">See pricing</aihio-button>
```

Do:

```html
<aihio-button><a href="/pricing">See pricing</a></aihio-button>
```

### aihio-button has no href; nothing reads it. Put the link inside: <aihio-button><a href="/pricing">See pricing</a></aihio-button>.

Don't (aihio lint: unknown-attribute):

```html
<aihio-button href="/pricing">See pricing</aihio-button>
```

Do:

```html
<aihio-button><a href="/pricing">See pricing</a></aihio-button>
```
