Add Loading to Avatar, add timer progress to Toast

This commit is contained in:
Peaceultime 2024-10-31 14:23:44 +01:00
parent bd32d176b1
commit 8a19448a38
5 changed files with 40 additions and 33 deletions

View File

@ -1,10 +1,11 @@
<template> <template>
<AvatarRoot class="inline-flex h-12 w-12 select-none items-center justify-center overflow-hidden align-middle"> <AvatarRoot class="inline-flex h-12 w-12 select-none items-center justify-center overflow-hidden align-middle">
<AvatarImage class="h-full w-full object-cover" :src="src" asChild> <AvatarImage class="h-full w-full object-cover" :src="src" asChild @loading-status-change="(status) => loading = status === 'loading'">
<img :src="src" /> <img :src="src" />
</AvatarImage> </AvatarImage>
<AvatarFallback :delay-ms="0" class="text-light-100 dark:text-dark-100 leading-1 flex h-full w-full items-center justify-center bg-light-25 dark:bg-dark-25 font-medium"> <AvatarFallback :delay-ms="0" class="text-light-100 dark:text-dark-100 leading-1 flex h-full w-full items-center justify-center bg-light-25 dark:bg-dark-25 font-medium">
<Icon v-if="!!icon" :icon="icon" class="w-8 h-8" /> <Loading v-if="loading" />
<Icon v-else-if="!!icon" :icon="icon" class="w-8 h-8" />
<span v-else-if="!!text">{{ text }}</span> <span v-else-if="!!text">{{ text }}</span>
</AvatarFallback> </AvatarFallback>
</AvatarRoot> </AvatarRoot>
@ -17,4 +18,5 @@ const { src, icon, text } = defineProps<{
icon?: string icon?: string
text?: string text?: string
}>(); }>();
const loading = ref(true);
</script> </script>

View File

@ -10,7 +10,7 @@
</CollapsibleTrigger> </CollapsibleTrigger>
</div> </div>
<slot name="alwaysVisible"></slot> <slot name="alwaysVisible"></slot>
<CollapsibleContent class="overflow-hidden data-[state=closed]:animate-[collapseClose_0.3s_ease-out] data-[state=open]:animate-[collapseOpen_0.3s_ease-out]"> <CollapsibleContent class="overflow-hidden data-[state=closed]:animate-[collapseClose_0.2s_ease-in-out] data-[state=open]:animate-[collapseOpen_0.2s_ease-in-out]">
<slot></slot> <slot></slot>
</CollapsibleContent> </CollapsibleContent>
</CollapsibleRoot> </CollapsibleRoot>

View File

@ -1,3 +1,9 @@
<template> <template>
<span class="w-6 h-6 border-4 rounded-full border-light-35 dark:border-dark-35 after:block after:relative after:-top-1 after:-left-1 after:w-6 after:h-6 after:rounded-full after:border-4 after:border-transparent after:border-t-accent-purple after:animate-spin"></span> <span :class="{'w-6 h-6 border-4 after:-top-[4px] after:-left-[4px] after:w-6 after:h-6 after:border-4': size === 'normal', 'w-4 h-4 border-2 after:-top-[2px] after:-left-[2px] after:w-4 after:h-4 after:border-2': size === 'small', 'w-12 h-12 border-[6px] after:-top-[6px] after:-left-[6px] after:w-12 after:h-12 after:border-[6px]': size === 'large'}" class="rounded-full border-light-35 dark:border-dark-35 after:block after:relative after:rounded-full after:border-transparent after:border-t-accent-purple after:animate-spin"></span>
</template> </template>
<script setup lang="ts">
const { size = 'normal' } = defineProps<{
size?: 'small' | 'normal' | 'large'
}>();
</script>

View File

@ -1,8 +1,11 @@
<template> <template>
<ToastRoot :duration="duration" class="ToastRoot grid grid-cols-8 bg-light-10 dark:bg-dark-10 p-3 border border-light-30 dark:border-dark-30" v-model:open="model"> <ToastRoot :duration="duration" class="ToastRoot bg-light-10 dark:bg-dark-10 border border-light-30 dark:border-dark-30" v-model:open="model">
<ToastTitle class="font-semibold text-xl col-span-7 text-light-70 dark:text-dark-70" asChild><h4>{{ title }}</h4></ToastTitle> <div class="grid grid-cols-8 p-3">
<ToastTitle v-if="title" class="font-semibold text-xl col-span-7 text-light-70 dark:text-dark-70" asChild><h4>{{ title }}</h4></ToastTitle>
<ToastClose v-if="closeable" aria-label="Close" class="text-2xl -translate-y-1/2 translate-x-1/2 cursor-pointer"><span aria-hidden>×</span></ToastClose> <ToastClose v-if="closeable" aria-label="Close" class="text-2xl -translate-y-1/2 translate-x-1/2 cursor-pointer"><span aria-hidden>×</span></ToastClose>
<ToastDescription class="text-md col-span-8 text-light-70 dark:text-dark-70" asChild><span>{{ content }}</span></ToastDescription> <ToastDescription v-if="content" class="text-md col-span-8 text-light-70 dark:text-dark-70" asChild><span>{{ content }}</span></ToastDescription>
</div>
<TimerProgress v-if="timer" shape="thin" :delay="duration" class="mb-0 mt-0 w-full" />
</ToastRoot> </ToastRoot>
<ToastViewport class="fixed bottom-0 right-0 flex flex-col p-6 gap-2 max-w-[512px] z-50 outline-none min-w-72" /> <ToastViewport class="fixed bottom-0 right-0 flex flex-col p-6 gap-2 max-w-[512px] z-50 outline-none min-w-72" />
@ -11,11 +14,12 @@
<script setup lang="ts"> <script setup lang="ts">
const model = defineModel<boolean>(); const model = defineModel<boolean>();
const { closeable = true, duration, title, content } = defineProps<{ const { closeable = true, duration, title, content, timer = true } = defineProps<{
closeable?: boolean closeable?: boolean
duration?: number duration?: number
title: string title?: string
content: string content?: string
timer?: boolean
}>(); }>();
</script> </script>

View File

@ -1,5 +1,12 @@
<script setup lang="ts"> <script setup lang="ts">
const open = ref(false), username = ref(""), price = ref(750), disabled = ref(false); const open = ref(false), username = ref(""), price = ref(750), disabled = ref(false), loading = ref(false);
watch(loading, (value) => {
if(value)
{
setTimeout(() => { open.value = true; loading.value = false }, 1500);
}
})
</script> </script>
<template> <template>
@ -7,8 +14,7 @@ const open = ref(false), username = ref(""), price = ref(750), disabled = ref(fa
<Title>Accueil</Title> <Title>Accueil</Title>
</Head> </Head>
<div class="h-100 w-100 flex flex-1 flex-col justify-center items-center"> <div class="h-100 w-100 flex flex-1 flex-col justify-center items-center">
<div class="w-1/2 flex flex-1 flex-col justify-center items-center"> <div class="w-1/2 flex flex-1 flex-col justify-center items-center gap-2">
<Loading />
<Collapsible label="Options"> <Collapsible label="Options">
<div class="flex flex-col"> <div class="flex flex-col">
<Switch label="Test" v-model="disabled" /> <Switch label="Test" v-model="disabled" />
@ -18,23 +24,12 @@ const open = ref(false), username = ref(""), price = ref(750), disabled = ref(fa
<NumberPicker label="Age" :disabled="disabled" /> <NumberPicker label="Age" :disabled="disabled" />
</div> </div>
</Collapsible> </Collapsible>
<Separator decorative orientation="horizontal" class="h-px w-96 my-2 bg-light-30 dark:bg-dark-30" />
<HoverCard> <Button @click="() => loading = true">
<span>Texte</span> <span v-if="!loading">Load data</span>
<template v-slot:content> <Loading v-else size="small" />
<div> </Button>
<Avatar src="public/logo.svg" icon="radix-icons:question-mark"/> <Toast v-model="open" :duration="7500" content="Je suis un long texte pour tester comment ça se comporte aaaaaaaa aaaaaaaa aaaaaaaaa aaaaaaaa" :closeable="false" />
<span class="text-xl font-light px-4">Dice[any]</span>
</div>
</template>
</HoverCard>
<Dialog label="Open" title="Titre" description="Description courte de la popup">
<div class="flex flex-col items-start">
<Separator decorative orientation="horizontal" class="h-px w-96 my-2 bg-light-30 dark:bg-dark-30" />
<span>Contenu special</span>
<Switch label="Theme sombre ?" />
</div>
</Dialog>
</div> </div>
</div> </div>
</template> </template>