button

Async action button with loading and success states

Async action button with loading and success states

Загрузка превью…

src/button/c-button-44.vue

<script setup lang="ts">
import { ref } from "vue"
import { Button } from "@/components/ui/button"
import { Spinner } from "@/components/ui/spinner"

type Status = "idle" | "loading" | "success"

const status = ref<Status>("idle")

function onClick() {
  if (status.value !== "idle") return

  status.value = "loading"
  setTimeout(() => {
    status.value = "success"
    setTimeout(() => {
      status.value = "idle"
    }, 2000)
  }, 900)
}
</script>

<template>
  <Button
    @click="onClick"
    :disabled="status === 'loading'"
    :aria-busy="status === 'loading'"
    aria-live="polite"
    class="min-w-32"
  >
    <template v-if="status === 'loading'">
      <Spinner aria-hidden="true" />
      Saving…
    </template>
    <template v-else-if="status === 'success'">
      <svg
        xmlns="http://www.w3.org/2000/svg"
        width="24"
        height="24"
        viewBox="0 0 24 24"
        fill="none"
        stroke="currentColor"
        stroke-width="2"
        stroke-linecap="round"
        stroke-linejoin="round"
        aria-hidden="true"
        class="lucide lucide-check"
      >
        <path d="M20 6 9 17l-5-5" />
      </svg>
      Saved
    </template>
    <template v-else>Save changes</template>
  </Button>
</template>

Установка

npx shadcn-vue@latest add https://revueui.rootapi.dev/r/c-button-44.json

Зависимости реестра

Источник: порт из ReUI (Keenthemes, MIT)