OButton
OButton renders an accessible native button with a default type of button.
Usage
@lucide/vue is Ooko's recommended and default icon library. Consuming applications can use Lucide directly or pass a compatible Vue icon component from any other icon library to OButton.
Step by step
- Import
OButtonfrom theooko-ui/buttonpublic subpath. - Put the action name in the default slot. Buttons are pill-shaped and use the
neutralink color by default; choose another semanticcoloronly when it adds meaning. - Add an icon or visual treatment, then handle native events such as
clickon the component.
Example
The rendered example and its source come from the same Vue single-file component.
Interactive playground
Change the content, color, size, visual treatment, disabled, and loading states. The preview updates immediately.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
color | "primary" | "secondary" | "info" | "success" | "warning" | "danger" | "neutral" | "neutral" | Visual color applied to the button. |
size | OButtonSize | "md" | Controls the button's form-control scale. |
disabled | boolean | false | Prevents interaction with the button. |
loading | boolean | false | Disables the button and shows a spinner over its content without changing its size. |
outline | boolean | false | Uses the outlined button treatment. |
nude | boolean | false | Uses the minimal button treatment. |
soft | boolean | false | Uses the soft treatment: a background tinted with the button color and no border. |
icon | Component | undefined | Vue component rendered as the button icon. |
iconPosition | OButtonIconPosition | "leading" | Places the icon before or after the button content. |
Events
| Event | Payload | Description |
|---|---|---|
| none | none | No custom Vue events are emitted. |
Slots
| Slot | Props | Description |
|---|---|---|
default | none | Provides the visible button content. |
icon | none | Provides configured or custom icon markup and overrides the icon prop. |
Related types
| Type | Definition |
|---|---|
OButtonIconPosition | type OButtonIconPosition = "leading" | "trailing"; |
OButtonSize | type OButtonSize = "xs" | OokoFormControlSize; |
OokoFormControlSize | type OokoFormControlSize = "sm" | "md"; |
OokoColor | type OokoColor = (typeof OOKO_COLORS)[number]; |
CSS custom properties
| Custom property | Default | Description |
|---|---|---|
--o-button-padding | var(--o-space-1-5) var(--o-space-4) | Sets the inner spacing around the button content. |
--o-button-border | 1px solid | Sets the button border width and style. |
--o-button-border-color | transparent | Sets the button border color. Outline and hovered nude buttons assign their color's border shade on the button itself. |
--o-button-border-radius | var(--o-radius-round) | Sets the button corner radius. |
--o-button-gap | var(--o-space-2) | Sets the space between the icon and visible content. |
--o-button-icon-size | 1.25rem | Sets the rendered icon size. |
--o-button-focus-width | 0.1875rem | Sets the focus outline width. |
--o-button-focus-style | solid | Sets the focus outline style. |
--o-button-focus-offset | 0.125rem | Sets the distance between the button and outline. |
--o-button-disabled-opacity | 0.5 | Sets the disabled button opacity. |
--o-button-font-size | var(--o-font-size-md) | Sets the label size of xs, sm, and md buttons. |
Override example
:root {
--o-button-border-radius: var(--o-radius-round);
}Define the same custom properties on a container instead of :root to limit an override to one part of an application.
Outline buttons and hovered nude buttons set --o-button-border-color on the button itself, so override it on .ooko-button or a more specific selector to replace their border color:
.toolbar .ooko-button {
--o-button-border-color: var(--o-border-neutral-lighter);
}Accessibility
- The component renders a native
buttonand preserves its keyboard and focus behavior. - The default slot must provide a meaningful accessible name, usually through visible text.
- Button icons are decorative and hidden from assistive technologies.
- An icon-only button must receive an accessible name through
aria-labeloraria-labelledby. - The
disabledprop uses the native disabled state and prevents interaction. - The
loadingprop also disables the button and setsaria-busy="true". The content stays in the accessible name; the spinner is decorative. - Native attributes and event listeners are forwarded to the underlying button.
- A visible
:focus-visibleoutline identifies keyboard focus.
Behavior and edge cases
- The button defaults to
type="button"to avoid accidental form submission. - The
iconprop accepts any Vue icon component; Ooko does not require a specific icon library. - The
iconslot overrides theiconprop for libraries that require configured markup. - Providing an icon without a default slot creates a square button with an aspect ratio of
1. iconPositionhas no visual effect when neither theiconprop nor theiconslot is provided.- The
mdbutton uses--o-control-form-height-md,smuses--o-control-form-height-sm, and the button-onlyxssize uses a spacing token for a1.5remminimum, for actions inside table rows. All sizes grow when the label wraps or text is enlarged. loadingdraws the spinner over the content and makes the content transparent instead of removing it, so the button keeps its exact size and the layout does not shift.- With reduced motion, the loading spinner turns more slowly instead of stopping.
- Filled buttons use white text (
--o-color-white), at rest and on hover, exceptneutralin the dark theme, whose fill is the light end of the scale and gets a dark label. Light fills such aswarningandsuccessthen fall below a 4.5:1 contrast ratio. Filled hover states darken the background. Outline and nude buttons keep their color's text shades. outline,nude, andsoftare alternative visual treatments and should not be combined.softtints the background with the button color, without a border, for secondary actions shown in a series.- A secondary outline button has a translucent fill for decorated surfaces, and its discreet border takes the primary color on hover.
- Native button attributes, such as
aria-label, are forwarded to the underlying element. - App defaults may configure
color,size,outline,nude, andiconPosition; direct props take precedence.