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>