Shared Spinner component for button loading states

Adds a reusable shadcn-style Spinner (lucide loader-circle icon,
localized aria-label) and wires it into every button that has a
pending state: comment submit, delete, tag save, profile save,
admin saves, upload, login and register.

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
2026-10-04 03:05:48 +02:00
co-authored by Devin
parent fab086d17e
commit d95ccf9dc7
9 changed files with 40 additions and 0 deletions
+2
View File
@@ -11,6 +11,7 @@ import {
PopoverTitle,
PopoverTrigger,
} from '@/components/ui/popover'
import { Spinner } from '@/components/ui/spinner'
const { user } = useAuth()
const { t } = useI18n()
@@ -82,6 +83,7 @@ async function onSubmit() {
{{ errorMessage }}
</p>
<Button type="submit" class="w-full" :disabled="loading || (!file && !url.trim())">
<Spinner v-if="loading" />
{{ loading ? $t('upload.uploading') : $t('upload.upload') }}
</Button>
</form>
+17
View File
@@ -0,0 +1,17 @@
<script setup lang="ts">
import type { HTMLAttributes } from 'vue'
import { cn } from '@/lib/utils'
const props = defineProps<{
class?: HTMLAttributes['class']
}>()
</script>
<template>
<Icon
name="lucide:loader-circle"
role="status"
:aria-label="$t('common.loading')"
:class="cn('size-4 animate-spin', props.class)"
/>
</template>
+1
View File
@@ -0,0 +1 @@
export { default as Spinner } from './Spinner.vue'