Button
A button, or a link that looks like one when href is set. Inside a form, type="submit" and type="reset" act on that form.
import '@usezeno/tokens/css';
import '@usezeno/core/web-components';
Examples
Variants
<zeno-button variant="primary">Primary</zeno-button>
<zeno-button variant="secondary">Secondary</zeno-button>
<zeno-button variant="accent">Accent</zeno-button>
<zeno-button variant="outline">Outline</zeno-button>
<zeno-button variant="ghost">Ghost</zeno-button>
<zeno-button variant="destructive">Destructive</zeno-button>
Sizes
<zeno-button size="xs">Extra small</zeno-button>
<zeno-button size="sm">Small</zeno-button>
<zeno-button size="md">Medium</zeno-button>
<zeno-button size="lg">Large</zeno-button>
<zeno-button size="xl">Extra large</zeno-button>
Disabled and loading
A loading button keeps its width, shows a spinner and cannot be pressed.
<zeno-button disabled>Disabled</zeno-button>
<zeno-button loading>Saving</zeno-button>
As a link
With href the element renders a link that looks the same.
<zeno-button href="#as-a-link" variant="outline">Go to this heading</zeno-button>
In a form
A submit button runs the form’s validation and adds its own name and value to the data. A reset button puts every control back.
<form>
<zeno-input name="email" type="email" label="Email" required></zeno-input>
<zeno-button type="submit" name="action" value="join">Join</zeno-button>
<zeno-button type="reset" variant="ghost">Clear</zeno-button>
<p data-result>Nothing submitted yet.</p>
</form>
const form = document.querySelector('form');
form.addEventListener('submit', event => {
event.preventDefault();
const sent = [...new FormData(form)].map(([name, value]) => name + '=' + value);
document.querySelector('[data-result]').textContent = 'Submitted: ' + sent.join('&');
});
Attributes and properties
| Property | Attribute | Type | Default | Description |
|---|---|---|---|---|
variant | variantreflects | ButtonVariant | 'primary' | |
size | sizereflects | 'sm' | 'md' | 'lg' | 'xl' | 'md' | |
type | typereflects | 'button' | 'submit' | 'reset' | 'button' | |
disabled | disabledreflects | boolean | false | |
name | namereflects | string | With value, the entry a submit button adds to the form it submits. | |
value | value | string | ||
loading | loadingreflects | boolean | false | |
fullWidth | full-widthreflects | boolean | false | |
iconOnly | icon-onlyreflects | boolean | false | |
href | href | string | ||
target | target | string | ||
rel | rel | string | ||
download | download | string | ||
formread only | HTMLFormElement | null | The form the button belongs to, if any. | ||
isDisabledread only | boolean | True when the element or an ancestor fieldset disables it. | ||
testId | string | Test ID for automated testing From ZenoElement. |
Methods
| Method | Description |
|---|---|
focus(): void | Focus the component or its first focusable element From ZenoElement. |
blur(): void | Blur the component or its focused element From ZenoElement. |
Events
This element sends no events.
Slots
| Slot | Description |
|---|---|
| Default | The label. |
prefix | An icon before the label. |
suffix | An icon after the label. |
CSS parts
| Part |
|---|
base |
prefix |
suffix |
CSS custom properties
This element documents no custom properties of its own. Style it through its parts and through the tokens it reads.
The element's own source reads no tokens.
Types
type ButtonVariant =
| 'primary' // High-emphasis primary actions
| 'secondary' // Medium-emphasis secondary actions
| 'tertiary' // Low-emphasis actions
| 'outline' // Outlined variant (alias for secondary)
| 'accent' // Accent actions
| 'destructive' // Destructive actions (delete, remove)
| 'ghost' // Minimal emphasis
| 'link' // Text-like actions
| 'glass';
Accessibility
Keyboard
| Key | What it does |
|---|---|
| Tab | Moves focus to the button. |
| EnterSpace | Activates the button. On a submit or reset button this acts on the form. |
| Enter | Follows the link when href is set. |
Forms
This element is form-associated. See its properties above for what it does in a form.
Notes
- Renders a native
<button>in its shadow root, or a native<a>whenhrefis set, so the role and keyboard behaviour are the browser’s own. - Focus is delegated to the inner control.
aria-labeland the other ARIA attributes set on the element are copied to it. loadingdisables the inner button and setsaria-busy="true". The spinner is hidden from assistive technology.- A disabled link gets
aria-disabled="true"and leaves the tab order. - An
icon-onlybutton has no text, so give it anaria-label.
Tests and known gaps
- Tested in a real browser by
button.test.ts. - Checked with axe-core in the light and the dark theme.
- Has a Storybook story.
15 of the 24 properties, methods, events, slots and parts above have no description in the source
- the property
variant - the property
size - the property
type - the property
disabled - the property
value - the property
loading - the property
fullWidth - the property
iconOnly - the property
href - the property
target - the property
rel - the property
download - the part
base - the part
prefix - the part
suffix
Known gaps:
- The
varianttype also liststertiary,linkandglass. The element has no styles for them, so they render as an unstyled button. - The
xssize is styled, but thesizetype does not list it, so TypeScript and the framework wrappers reject it. - Nothing announces the change when
loadingstarts or ends, beyondaria-busy. - An
icon-onlybutton without anaria-labelhas no accessible name, and the element does not warn about it.