Skip to content
Aihio v2.3.0
Search
GitHub
Search Describe what you are building, or name a component, intent, or token. Components and patterns are ranked the way the MCP server's find tool ranks them for an agent.

<aihio-button> v1.5.0 Markdown for agents

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

Variants

Every value of the attributes that change how it looks. The values come from the schema.

variant

Visual style variant

Default
variant="default"
Secondary
variant="secondary"
Outline
variant="outline"
Ghost
variant="ghost"
Link
variant="link"
Destructive
variant="destructive"

size

Button size

Size sm
size="sm"
Size md
size="md"
Size lg
size="lg"
+
size="icon"

Examples

Each one rendered live, over the markup that produces it.

Primary action

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

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

Small and outlined

A lower-emphasis action beside a primary one.

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

Destructive

For an action that deletes something or cannot be undone.

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

Icon only

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

✕
<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>.

<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.

Sign in
<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.

Delete project Delete project?
Cancel Delete project
<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

Each one beside its fix, with what aihio lint says about it. The prompt fragment gives agents the same pairs, and the build fails if the linter stops catching one or a fix stops passing.

variant="primary" is not valid.

The primary style is variant="default".

Don't

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

aihio lint reports

  • invalid-enum-attribute error invalid variant="primary". Use variant="default". Expected one of: default, secondary, outline, ghost, link, destructive. Suggests variant="default"

Do

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

Buttons must not be nested.

Use sibling buttons or aihio-dropdown for grouped actions.

Don't

<aihio-button><aihio-button>Save</aihio-button></aihio-button>

aihio lint reports

  • forbidden-descendant error descendant <aihio-button> is forbidden inside <aihio-button>.

Do

Cancel Save
<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-button size="icon">&#x2715;</aihio-button>

aihio lint reports

  • button-accessible-name error Provide aria-label describing the action (e.g. aria-label="Close").

Do

✕
<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

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

aihio lint reports

  • button-form-owner warn Set type="submit" and either place the button inside its <form> or reference that form with the form attribute.

Do

Sign in
<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-button onclick="location.href='/pricing'">See pricing</aihio-button>

aihio lint reports

  • button-link-navigation error 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.

Do

<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-button href="/pricing">See pricing</aihio-button>

aihio lint reports

  • unknown-attribute error <aihio-button> has no attribute "href": a button does not navigate. Put the link inside it, and it becomes the control, styled as the button: <aihio-button><a href="/pricing">See pricing</a></aihio-button> Suggests <aihio-button><a href="/pricing">See pricing</a></aihio-button>

Do

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

API

Every attribute, property, method, and event the schema declares for aihio-button.

Attributes

variant
one of defaultsecondaryoutlineghostlinkdestructive default default
Visual style variant
size
one of smmdlgicon default md
Button size
disabled
boolean default false
Disables the button
loading
boolean default false
Shows loading state and disables interaction
type
one of buttonsubmitreset default button
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.
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
one of getpostdialog
HTTP method override for submit buttons.
formenctype
one of application/x-www-form-urlencodedmultipart/form-datatext/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(): void
Activates the native button.
focus(options?: FocusOptions): void
Moves focus to the native button.
blur(): void
Removes focus from the native button.

Events

click
Fired when the button is clicked

Slots

default
Button label content

Composition

Accessibility

What you have to provide, and what the component already does. The obligations with a rule are checked by aihio lint and by the dev build's console warnings.

Your obligations

  • error When size="icon" or the button has no visible text

    Provide aria-label describing the action (e.g. aria-label="Close").

    Checked as button-accessible-name

  • warn 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.

    Checked as button-form-owner

  • error 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.

    Checked as button-link-navigation

  • error 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.

    Checked as button-link-href

  • warn 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.

    Checked as button-link-attributes

Handled for you

  • The component renders a real <button> and forwards its attributes to it, so the role, Enter and Space activation, focus behaviour, disabled semantics, and the forced-colours mapping are the platform's rather than an emulation of it
  • An authored <a> child becomes the control instead of a <button>, so a call to action that goes to another page is a real link: it is announced as one, shows its URL, opens in a new tab, and works before the module loads
  • aria-* set on the host is mirrored onto that control
  • A disabled or loading link gets aria-disabled="true", leaves the tab order, and its clicks are cancelled, since a link has no native disabled state
  • aria-busy reflects loading state, which also disables the control
  • Form participation is native: the button is a submitter of its owning form, so Enter in a field submits, SubmitEvent.submitter identifies it, and <fieldset disabled> disables it in both directions
  • type="submit" runs native constraint validation before the form submits

In patterns

Canonical compositions that use aihio-button.