Appearance
Button
SButton is a button with style variants, sizes, a loading state, and icon slots. It is polymorphic: as renders it as another element, such as a link.
Variants
vue
<template>
<SButton variant="primary">Primary</SButton>
<SButton variant="secondary">Secondary</SButton>
<SButton variant="outline">Outline</SButton>
<SButton variant="ghost">Ghost</SButton>
<SButton variant="negative">Negative</SButton>
</template>Sizes
vue
<template>
<SButton size="sm">Small</SButton>
<SButton size="md">Medium</SButton>
<SButton size="lg">Large</SButton>
</template>Shape
The round prop fully rounds the edges (pill shape), while square does the opposite and removes the rounding (square corners). Every component with a frame (buttons, inputs, cards, overlays, etc.) has the square prop, and it works the same way everywhere.
vue
<template>
<SButton
round
variant="primary"
>
Get started
</SButton>
<SButton
round
variant="outline"
>
Learn more
</SButton>
<SButton
square
variant="primary"
>
Square
</SButton>
<SButton
round
icon="plus"
variant="primary"
aria-label="Add"
/>
</template>Color
The color prop sets a color from the palette: a brand role, a family, or one of its shades (primary, teal, teal-10). It overrides the variant color while keeping the style (fill/outline). The hover/active states are derived automatically. On a light fill, set text-color to keep the text readable.
vue
<template>
<SButton color="teal">teal</SButton>
<SButton color="deep-purple">deep-purple</SButton>
<SButton color="teal-10">teal-10</SButton>
<SButton
variant="outline"
color="pink"
>
outline pink
</SButton>
<SButton
color="light-blue-3"
text-color="dark"
>
Light fill, dark text
</SButton>
</template>States
vue
<template>
<SButton disabled>Disabled</SButton>
<SButton loading>Loading</SButton>
</template>As a link
vue
<template>
<SButton
as="a"
href="/docs"
variant="outline"
>
Link button
</SButton>
</template>Icons
The leading (icon) and trailing (icon-right) icons take a registry name. For a button without text, set aria-label so the icon gets an accessible name.
vue
<template>
<SButton
icon="plus"
variant="primary"
>
Add
</SButton>
<SButton
icon-right="chevron-down"
variant="outline"
>
Menu
</SButton>
<SButton
icon="x"
variant="ghost"
aria-label="Close"
/>
</template>Icon button
An icon without a text label makes the button square automatically: the horizontal padding is removed and the width equals the height of the size. If the content comes through a slot, enable the mode with the icon-only prop. Such a button requires aria-label, since there is nothing else to announce.
vue
<template>
<SButton
icon="x"
variant="outline"
aria-label="Close"
/>
<SButton
icon="pencil"
variant="ghost"
aria-label="Edit"
/>
<SButton
icon="trash-2"
variant="negative"
aria-label="Delete"
/>
<SButton
icon="settings"
variant="outline"
size="sm"
aria-label="Settings"
/>
<SButton
icon="settings"
variant="outline"
size="lg"
aria-label="Settings"
/>
<SButton
icon-only
variant="ghost"
aria-label="Favorite"
>
<template #leading>
<SIcon icon="heart" />
</template>
</SButton>
</template>Without shadow
The filled variants (primary, secondary, negative) come with a shadow. The flat prop removes it without touching the shadows of other components. If you want flat buttons across the whole app, make the prop a default: installDefaults(app, { SButton: { flat: true } }). The reverse also works: elevation sets the level explicitly and overrides flat, including a flat that comes from the global defaults. The scale and the rules are on the Elevation page.
vue
<template>
<SButton variant="primary">With shadow</SButton>
<SButton
variant="primary"
flat
>
No shadow
</SButton>
<SButton
variant="secondary"
flat
>
No shadow
</SButton>
<SButton
variant="primary"
:elevation="4"
>
elevation 4
</SButton>
</template>Button type
Inside a form, type="submit" submits it and type="reset" resets the fields. The default is type="button", a neutral button that does not submit.
vue
<template>
<form @submit.prevent="onSubmit">
<SButton
type="submit"
variant="primary"
>
Submit
</SButton>
<SButton
type="reset"
variant="outline"
>
Reset
</SButton>
</form>
</template>Icon slots
The #leading and #trailing slots override the icon/icon-right props and accept any markup, for example an SIcon with a custom size.
vue
<template>
<SButton variant="primary">
<template #leading>
<SIcon
icon="check"
:size="18"
/>
</template>
Save
</SButton>
<SButton variant="outline">
Next
<template #trailing>
<SIcon
icon="chevron-right"
:size="18"
/>
</template>
</SButton>
</template>API
Props
| Name | Type | Default | Description |
|---|---|---|---|
as | string | "button" | Tag/component to render (polymorphism). button by default. |
variant | | "primary"
| "secondary"
| "negative"
| "outline"
| "ghost" | "primary" | Visual variant: filled primary/secondary/negative, outlined outline or transparent
ghost. |
color | string | undefined | Accent color: a name from the palette (primary/teal/teal-10).
Overrides the variant color. |
text-color | string | undefined | Text/icon color on the fill: a name from the palette. White by default
(set it for light color values). |
size | "md" | "sm" | "lg" | "md" | Button size: sm (32px), md (40px) or lg (48px). |
round | boolean | undefined | Fully rounded edges (pill shape). |
square | boolean | undefined | Square corners: removes the border radius (rounded by default). |
type | | "button"
| "submit"
| "reset" | "button" | type of the native button (ignored when as is not button). |
disabled | boolean | false | Disables the button. |
loading | boolean | false | Loading state: shows a spinner and blocks interaction. |
icon-only | boolean | undefined | Icon button: a square sized by the control height, without horizontal padding. Turns on
automatically when an icon is set without a text label; the prop is needed when the content
comes from a slot. Such a button requires ariaLabel — a screen reader has nothing else to
announce. |
flat | boolean | undefined | Button without a shadow. Filled variants (primary/secondary/negative) have a built-in
shadow; flat removes it without affecting other components' shadows. Can also be set
globally: installDefaults(app, { SButton: { flat: true } }). |
elevation | 0 | 1 | 2 | 3 | 4 | 5 | undefined | Shadow level 0–5 (scale); 0 means no shadow. Overrides flat. |
icon | string | undefined | Leading icon: a registry name or a raw SVG path. Ignored when the leading slot is set. |
icon-right | string | undefined | Trailing icon: a registry name or a raw SVG path. Ignored when the trailing slot is set. |
aria-label | string | undefined | Accessible name of the button. Required for icon-only buttons (no text label). |
Slots
| Name | Description |
|---|---|
leading | Content before the label, usually a leading icon. Overrides the icon prop. |
default | Button label (text). |
trailing | Content after the label, usually a trailing icon. Overrides the iconRight prop. |