Appearance
QsButton
<qs-button>alphaA standard button component used to trigger actions and events. Definitely not a <div>.
Button
html
<qs-button>Here describe the action triggered</qs-button>
<qs-button variant="primary">Here describe the action triggered</qs-button>
<qs-button variant="danger">Here describe the action triggered</qs-button>
<qs-button variant="success">Here describe the action triggered</qs-button>
<qs-button variant="primary" icon="check">Here describe the action triggered</qs-button>Prop
| Prop | Type | Default | Description |
|---|---|---|---|
disabled | boolean | false | Whether or not the button is in a disabled state |
href | string | "" | Where the button should link to, will also force the component to render as a link. |
variant | "default" | "primary" | "danger" | "success" | "default" | The style variant of the component. |
icon | string | "" | Name of a `qs-icon` to render before the label. Must match a name from the icon set (e.g. `check`, `trash`). Omit for a text-only button. |
label | string | "" | Accessible name for the inner control. Required when the button has no visible text (icon-only); an `aria-label` on the host would not reach it. |
type | "submit" | "button" | "reset" | "submit" | Native button type. Inside a form, `submit` (the default) submits it; set `button` for any other action, so it doesn't submit by accident. Ignored with `href`. |
text | string | — | The text content of the element, captured from light DOM before the first render. |
Usage
Use a button to trigger an action or event, such as submitting a form, opening a dialog, or confirming a decision. Use a button with an href to act as a CTA link.
Variants
Use variant to communicate the intent of the action.
- Default — for secondary or low-priority actions
- Primary — for the single, primary action on a page or in a section; use sparingly
- Danger — for destructive or irreversible actions, such as deleting or removing
- Success — for confirming a positive outcome, such as saving or completing
Avoid using multiple primary or danger buttons in close proximity. If everything is high priority, nothing is.
Do:
Place primary buttons after default buttons if you need to stack two buttons together:
Don’t:
Stack primary, danger, or success buttons next to one another
Links
Pass an href to render the button as an anchor element. Use this when the action navigates the user to a new page or location rather than triggering an in-page action.
html
<qs-button href="/get-started">Get started</qs-button>Don't use a link-button for actions that don't result in navigation — use a standard button instead.
In a form
Like a native <button>, a qs-button inside a form submits it by default. Give every other button in the form type="button":
html
<form>
<qs-button type="button">Preview</qs-button>
<qs-button variant="primary">Save</qs-button>
</form>Icon
Pass icon with a name from the icon set to reinforce the action's meaning. The icon is placed before the label and inherits the button's text color.
html
<qs-button variant="success" icon="check">Save changes</qs-button>
<qs-button variant="primary" icon="plus">Add item</qs-button>
<qs-button variant="danger" icon="trash">Delete</qs-button>- Pair
iconwith a visible label by default — an icon alone is rarely unambiguous, and this component has no dedicated icon-only mode - Pick an icon whose meaning is well established (a checkmark for confirm, a trash can for delete) — don't use icon for pure decoration
- One icon per button; don't combine
iconwith other leading content - If you must ship an icon with no visible label (e.g. a tight toolbar), set
labelon the<qs-button>: it becomes the inner control'saria-label. Anaria-labelon the host does not reach the inner<button>. The icon itself isaria-hiddenand won't provide a name
Disabled state
Use disabled to prevent interaction when an action is temporarily unavailable. Where possible, pair a disabled button with an explanation of why it's unavailable.
html
<qs-button disabled>Unavailable</qs-button>Avoid using disabled as a default state — if an action is never available in a given context, don't show the button at all.
In a framework
Children are the static content of the first render, and their markup (links, <em>, lang spans) is kept. For text that changes, bind Elena's text property instead of rendering a child, as Elena recommends:
html
<!-- React --> <qs-button text={label} />
<!-- Vue --> <qs-button :text="label" />
<!-- Angular --><qs-button [text]="label" />Don't let a framework add or remove individual children inside qs-button: once rendered, they live inside the component's own element.
Accessibility
- Button text should clearly describe the action it triggers — avoid vague labels like "Click here" or "Submit"
- When using
icon, keep the slotted text present; if you must omit it, setlabelon the<qs-button>instead - If you need to construct more complex accessibilityName use
ariaLabelledbyto reference other elements on the page orariaDescribedbyto provide additional context - Disabled buttons are not focusable by default; consider whether users need to know why the action is unavailable before removing it from the tab order