English
Button
Basic button component, an enhanced native <button>.
Types
Button types
Example
Sizes
Five sizes
Example
size supports five tiers: xs / small / medium (default) / large / xl; invalid values fall back to medium with a warning.
Five sizes · primary
Example
Five sizes · icon-only
Example
Disabled & Loading
disabled disables the button; loading enters the loading state — the original label keeps its space (width stays unchanged) and a spinner is centered; pair with loading-text to show a loading message.
Disabled and loading states
Example
Async auto loading
With loading="auto", the button automatically enters the loading state while the host oas-click handler returns a Promise, and exits after the Promise resolves or rejects.
Auto loading for async submit
Example
Disabled but focusable
disabled-focusable renders a disabled look (desaturated + aria-disabled) without a native disabled attribute — still focusable and hoverable, ideal for wrapping in a tooltip that explains why it is disabled; clicks are intercepted by the component and oas-click is not dispatched.
Disabled but focusable (with tooltip)
Example
Events
Click event
Example
Clicking dispatches the oas-click CustomEvent (bubbles + composed); detail.originalEvent is the native MouseEvent.
Icon buttons
icon renders an icon before the text (reusing the oas-icon icon set, IconName); the spacing between the icon and text follows --oas-space-2.
Icon + text
Example
Without text, the button becomes an equal-width square and needs an aria-label for an accessible name; when not set explicitly, the icon name is used as a fallback (e.g. icon="close" → aria-label="close"). It is recommended to provide an explicit label.
Icon-only buttons
Example
Block
block makes the button fill the full width of its parent container.
Block buttons
Example
Rounded
round applies a pill radius (--oas-radius-full, falling back to 999px when the token is unavailable).
Rounded buttons
Example
Ghost
ghost renders a transparent background with an outline; the outline and text are colored by type and darken on hover.
Ghost buttons
Example
Circle
circle turns the button into a circle; icon-only buttons combine equal-width and full rounding into a circle.
Circle buttons
Example
Icon position
icon-position controls the icon/text order: start (default, icon on the left) or end (icon on the right).
Icon on the right
Example
Dual icons
icon renders an icon before the text and icon-end renders a second icon after the text (both reuse the oas-icon set); they can coexist with icon-position.
Dual icons
Example
Secondary text (compound two-row variant)
When the slot="description" secondary line is present, the button switches to a vertical two-row layout: the main row (icon + text) on top, the secondary line below (smaller, muted). Good for card entries, settings entries, upload entries — "main action + one line of explanation". Fully compatible with loading / icon / disabled / href.
Two-row button
Example
Link button
Setting href renders a native link (<a>); target controls how it opens (_blank / _self etc.); download (file download) and rel (link relationship) are passed through.
Link buttons
Example
Download and rel
Example
Plain
plain uses a low-contrast, subtle style (a 12% tint of the semantic color as background with a transparent border and semantic-colored text), gentler on light backgrounds.
Plain buttons
Example
Variant
variant controls the button shape, orthogonal to the type semantic color: solid (default filled) / outlined / dashed / filled (soft) / text / link. Legacy ghost equals outlined, plain equals filled.
Outlined / Dashed / Filled
Example
Text / Link
Example
Custom color
color overrides the type semantic color with any color value.
Color priority: --oas-button-bg (host-injected CSS variable, gradients allowed) > color attribute > type semantic color > default gray. In outlined / filled / dashed / text variants, color tints the border/text/light background; for solid buttons the text color is picked black or white by background luminance (stays readable in dark mode).
Custom color values are rendered as-is (never rewritten) — make sure the text/background contrast meets WCAG AA (4.5:1).
Custom color
Example
Selected state (active / active-tint)
The active boolean attribute marks the selected state (controlled: the component does not toggle itself; the host writes back on oas-click). Selected visuals share the button-group selection anchor (aria-pressed). active-tint customizes the selected color — the 11 preset names resolve to theme tokens (light/dark adapted automatically), any CSS color is injected as-is, and the solid selected text color adapts to background luminance (contrast is the host's responsibility, WCAG AA 4.5:1).
Selected state
Example
active-tint custom selected color
Example
Toggle selection on click (controlled write-back)
Example
Press feedback
wave enables a subtle press feedback (slight sink + darken, on by default); wave="false" disables it.
Press feedback
Example
CJK auto spacing
auto-insert-space inserts a space between two consecutive CJK characters (typography optimization, off by default).
CJK auto spacing
Example
Autofocus
autofocus gives the button focus after page load (native autofocus does not pierce Shadow DOM; the component forwards focus to the inner button on mount).
autofocus
Example
Long content wrapping
Buttons are single-line by default (white-space: nowrap). With the explicit wrap attribute, long text wraps within a constrained width (parent container or width / max-width) and the box grows with the content (same height as default when it fits on one line).
wrap for long content
Example
Touch targets on mobile
On touch devices (pointer: coarse) the button minimum height grows to 44px (--oas-touch-target-min): small sizes such as the 32px default or the 20px xs become 44px tall on touch, while sizes already ≥44px (e.g. xl) are unchanged; icon-only / circle buttons become 44×44 hit areas via aspect-ratio. Only the height grows — padding, font size, and border radius stay untouched; desktop (fine pointer) is unaffected.
Native form submission
html-type sets the native form behavior: button (default, no form behavior) / submit / reset. Buttons inside Shadow DOM do not participate in native form submission — the component bridges automatically: clicking triggers native submit/reset on the target form (the enclosing <form>, or the form id referenced by form); formaction / formmethod / formnovalidate / formtarget take effect through the native submitter mechanism (overriding the form's own action / method / novalidate / target). Submission is not triggered in disabled / loading state; in href link mode this attribute group is silently ignored.
Bridging notes (two boundaries): ① the bridge works via a transient native proxy submitter injected at click time — the form's
submitevent sees this proxy assubmitter, not theoas-button(the proxy carriesdata-oas-form-proxyfor identification); hosts with click delegation on the form area will see both the host's synthetic click and the proxy's native click bubble. ②html-type="submit"does not work insideoas-form: its real<form>lives in shadow DOM, so a light-DOM proxy finds no ancestor form — useoas-form'ssubmit()method /oas-submitevent instead.
Native form submission (html-type / form attributes)
Example
Clicking "Submit" fires the native submit event (the demo calls preventDefault and shows the fields about to be submitted); "Reset" restores the initial input values and fires reset; "No-validate submit" demonstrates formnovalidate skipping required validation plus formaction/formmethod overriding the submission target.
Custom Loading Icon
slot="loading-icon" replaces the built-in spinner ring with custom content while loading (the spinner positioning is reused, so stable loading width etc. are unchanged); when absent, the built-in spinner shows. Commonly paired with oas-icon spin for a themed loading icon.
loading-icon slot
Example
API
oas-button
Attributes
| Attribute | Description | Type | Default |
|---|---|---|---|
active | Selected state (controlled): present = selected; the host writes back on oas-click (the component does not toggle itself); selected visuals share the button-group selection anchor (aria-pressed), pair with active-tint for a custom tint | boolean | — |
active-tint | Selected-state tint: the 11 preset names resolve to --oas-preset-*-text tokens (one set per theme); any CSS color is injected as-is; solid selected text color (primary etc.) adapts to background luminance, contrast is the host’s responsibility | string | — |
auto-insert-space | CJK auto spacing: inserts a space between two consecutive CJK characters (off by default) | string | — |
autofocus | Autofocus: focuses the inner button on mount (native autofocus does not pierce Shadow DOM; the component forwards it) | boolean | — |
block | Fill the full width of the parent container (block level) | boolean | — |
circle | Circle button (icon-only, square + full rounding) | boolean | — |
color | Custom color: overrides the type semantic color (any color value) | string | — |
disabled | Disabled | boolean | — |
disabled-focusable | Visually disabled but stays focusable/hoverable (aria-disabled + click intercepted), for tooltips explaining why | boolean | — |
download | Passthrough download attribute in link mode (href) for file-download buttons | string | — |
form | Associated form id for buttons outside the target form (native form-attribute association) | string | — |
formaction | Target URL for this submission (overrides the form action) | string | — |
formenctype | Form encoding for this submission (application/x-www-form-urlencoded / multipart/form-data / text/plain, overrides the form enctype) | string | — |
formmethod | HTTP method for this submission (get/post/dialog, overrides the form method) | string | — |
formnovalidate | Skip native validation for this submission only | boolean | — |
formtarget | Browsing target for the response (_blank/_self etc., overrides the form target) | string | — |
ghost | Ghost/outline style: transparent background + outline colored by type, darkens on hover | boolean | — |
href | Link address: renders a native <a> when set | string | — |
html-type | Native form behavior: button (default, none) / submit submits the containing or form-targeted form / reset resets it (bridged via a proxy submitter) | string | button |
icon | Icon name (reusing the oas-icon icon set); without text it becomes an equal-width square and uses the icon name as the fallback label | string | — |
icon-end | A second icon after the text (built-in icon name), works with icon/icon-position — e.g. left icon + right dropdown arrow | string | — |
icon-position | Icon position: start (default, left) / end (right) | string | start |
loading | Loading state | — | — |
loading-text | Text shown while loading (e.g. "Submitting…"); replaces the label content when set | string | — |
plain | Plain style: a 12% tinted background in the semantic color with text in its -text tone and a transparent border (no visible outline); equals variant="filled" | boolean | — |
rel | Passthrough rel attribute in link mode (pair noopener with target="_blank") | string | — |
round | Pill radius (--oas-radius-full / 999px) | boolean | — |
size | Size: xs / small / medium (default) / large / xl; invalid values fall back to medium with a warning | ButtonSize | medium |
target | How the link opens (_blank / _self etc.), with href | string | — |
type | Type | ButtonType | default |
variant | Shape (orthogonal to type): solid (default filled) / outlined / dashed / filled (soft) / text / link | ButtonVariant | '' | — |
wave | Press feedback: slight sink + darken (on by default); wave="false" disables | string | true |
wrap | Long-text wrapping: single-line nowrap by default; when enabled, content wraps within constrained widths and the box grows with it | boolean | — |
Events
| Event | Description |
|---|---|
oas-click | Click, detail: { originalEvent } |
Slots
| Name | Description |
|---|---|
| default | Button content (text / icon) |
description | Secondary text line (compound two-row variant): when present, the button switches to a vertical two-row layout (main row on top, secondary below, smaller muted text) |
loading-icon | Custom loading icon replacing the built-in spinner ring when slot content is present |
CSS Variables
| CSS Variable | Description | Default |
|---|---|---|
--oas-button-active-tint | Selected-state tint channel (injected by the active-tint attribute; preset names resolve to --oas-preset-*-text, raw colors as-is); consumed by selected text/border/soft and solid fills | var(--oas-color-primary) |
--oas-button-active-tint-on | Label color on solid selected fills (primary etc.): custom tints pick black/white by background luminance; falls back to --oas-color-text-on-primary when not injected | var(--oas-color-text-on-primary) |
--oas-button-active-tint-text | Text-safe variant of the selected tint: theme-aware deepen/lighten mix (toward near-black in light, near-white in dark; presets use the -text token directly) — labels on soft selected fills and text-variant selection | var(--oas-color-primary-text) |
--oas-button-bg | — | var(--oas-color-primary) |
--oas-button-color | — | var(--oas-color-text-primary) |
--oas-button-color-deep | Text-safe deepened variant of the custom color: the color-mix used for hover/active and outlined/dashed/filled text (injected by the component via --oas-deep-mix / --oas-deep-sink; inert without a custom color) | var(--btn-color, var(--oas-color-text-primary)) |
--oas-button-group-radius | — | var(--oas-radius-md) |
--oas-button-group-width | — | auto |
--oas-button-height | Button height override (falls back to the size-tier value by default); containers needing full-row-height buttons (e.g. swipe-cell actions) inject 100% via ::slotted (built into swipe-cell) | var(--oas-control-height-md) |
--oas-button-on-color | — | var(--oas-color-text-on-primary) |