BaseButton

The kit's button, and — when asked — its link.

Import it from rei-kit: import { BaseButton } from 'rei-kit'

Open BaseButton in the live documentation, where every prop below is a control you can change, in four materials and ten palettes.

Usage

<script setup lang="ts">
import { ref } from 'vue'
import { BaseButton } from 'rei-kit'

const deleting = ref(false)

function save() {
  // …
}
</script>

<template>
  <div class="flex flex-wrap gap-2">
    <BaseButton @click="save">Save</BaseButton>
    <BaseButton variant="secondary">Cancel</BaseButton>
    <BaseButton variant="danger" :loading="deleting">Delete</BaseButton>
    <BaseButton as="a" href="/docs" variant="ghost">Read the docs</BaseButton>
  </div>
</template>

Props

Props
PropTypeRequired or defaultWhat it is for
as'button' | 'a' | 'router-link''button'What to render. `button` unless this navigates.
variant'primary' | 'secondary' | 'ghost' | 'quiet' | 'destructive' | 'row' | 'danger' | 'positive' | 'warning' | 'accent' | 'link' | 'unstyled''primary'`link` is a real action that should read as text — "clear this note", "remove", "change category". It has no surface at all, so it also has no height and no padding: giving it either would make it a ghost button, which is a different thing and was already here.
size'xs' | 'sm' | 'md' | 'lg''md'`xs` is the action inside a prompt or a nudge, not on a page.
loadingbooleanfalse
disabledbooleanfalse
type'button' | 'submit''button'Ignored unless `as` is `button`.
iconbooleanfalseSquare, sized to its icon, with no label beside it. **Pass `aria-label`.** An icon on its own has no accessible name, and a control a screen reader announces as "button" is not usable. Attributes fall through, so `aria-label` lands where it should — nothing here can check that you passed one, which is why it is said this loudly.
blockbooleanfalseFills its container. The ordinary case under a form.
tostring | Record<string, unknown>undefinedFor `as="router-link"`.
hrefstringundefinedFor `as="a"`.
pillbooleanfalseFully rounded rather than card-cornered. Every install prompt, update prompt and nudge across the apps used the same pair — a filled pill to act and a quiet one to dismiss — and none of them could use this component, because it only knew one corner radius.
pressedbooleanundefinedThat this button is a switch, and whether it is on. Omit it and the button is an action. Pass it and the button becomes a toggle: `aria-pressed` is written, and the variants that have an "off" look — ghost, quiet, secondary — take a filled one when on. There were 18 of these hand-written across the three apps, every one a picker cell or a filter chip, and almost none of them said `aria-pressed` at all. A screen reader met a row of identical buttons with no way to know which was chosen.

About rei-kit

rei-kit is an accessible Vue 3 and Tailwind CSS 4 component library: 106 components, themed by role rather than by colour on three independent axes — ten WCAG-checked palettes, four materials and light or dark, each switched with one attribute. Typed, tested, SSR-safe, no runtime dependencies, MIT.

pnpm add rei-kit · npm · GitHub