Components / Actions

Button

A native button with five variants, three sizes, and a loading state.

Preview

Use cases

Submit a form

Use type="submit" for the form’s primary action and show loading while the request is pending.

Secondary action

Use an outline or ghost button for an action that should not compete with the primary task.

Usage example

Vue
<script setup lang="ts">
import Button from './components/ui/button/Button.vue'
</script>

<template>
  <Button variant="default">Save changes</Button>
  <Button variant="outline" size="sm">Cancel</Button>
</template>

More examples

Saving a form

The native submit type participates in form validation.

Saving a form
<script setup lang="ts">
import { ref } from 'vue'
import Button from './components/ui/button/Button.vue'
const saving = ref(false)
async function save() {
  saving.value = true
  try { await fetch('/api/profile', { method: 'POST' }) } finally { saving.value = false }
}
</script>
<template>
  <form @submit.prevent="save">
    <Button type="submit" :loading="saving">Save profile</Button>
  </form>
</template>

Destructive action

Name the consequence in the button text.

Destructive action
<script setup lang="ts">
import Button from './components/ui/button/Button.vue'
function removeDraft() { /* Confirm or remove the draft here. */ }
</script>
<template><Button variant="destructive" @click="removeDraft">Delete draft</Button></template>

Key API

The most useful props, models, slots, events, and methods for this component.

Key API for Button
NameTypeDefault or requirement
variantdefault | secondary | outline | ghost | destructivedefault
sizesm | md | lgmd
loadingbooleanfalse
disabledbooleanfalse
typebutton | submit | resetbutton

Native button attributes and click events pass through. Loading blocks repeat activation.

Implementation notes

  • The default type is button; set type="submit" or type="reset" explicitly when form behavior is intended.
  • Loading blocks another click and keeps the button’s accessible name and layout stable.

Accessibility and localization

  • Keep the default slot descriptive; supply an accessible name for an icon-only button.
  • Decorative icons in the prefix or suffix slot should use aria-hidden="true".
Weini UIDesign system · Vue component library · Free and public