11<script setup lang="ts">
22const props = defineProps <{
33 username: string
4+ size: ' sm' | ' md' | ' lg'
45}>()
56
7+ const sizePixels = computed (() => {
8+ switch (props .size ) {
9+ case ' sm' :
10+ return 24
11+ case ' md' :
12+ return 40
13+ case ' lg' :
14+ return 64
15+ }
16+ })
17+
18+ const sizeClass = computed (() => {
19+ switch (props .size ) {
20+ case ' sm' :
21+ return ' size-6'
22+ case ' md' :
23+ return ' size-10'
24+ case ' lg' :
25+ return ' size-16'
26+ }
27+ })
28+
29+ const textClass = computed (() => {
30+ switch (props .size ) {
31+ case ' sm' :
32+ return ' text-xs'
33+ case ' md' :
34+ return ' text-base'
35+ case ' lg' :
36+ return ' text-2xl'
37+ }
38+ })
39+
640const { data : gravatarUrl } = useLazyFetch (() => ` /api/gravatar/${props .username } ` , {
7- transform : res => (res .hash ? ` /_avatar/${res .hash }?s=128 &d=404 ` : null ),
41+ transform : res => (res .hash ? ` /_avatar/${res .hash }?s=64 &d=404 ` : null ),
842 getCachedData(key , nuxtApp ) {
943 return nuxtApp .static .data [key ] ?? nuxtApp .payload .data [key ]
1044 },
@@ -14,7 +48,8 @@ const { data: gravatarUrl } = useLazyFetch(() => `/api/gravatar/${props.username
1448<template >
1549 <!-- Avatar -->
1650 <div
17- class =" size-16 shrink-0 rounded-full bg-bg-muted border border-border flex items-center justify-center overflow-hidden"
51+ class =" shrink-0 rounded-full bg-bg-muted border border-border flex items-center justify-center overflow-hidden"
52+ :class =" sizeClass"
1853 role =" img"
1954 :aria-label =" `Avatar for ${username}`"
2055 >
@@ -23,13 +58,22 @@ const { data: gravatarUrl } = useLazyFetch(() => `/api/gravatar/${props.username
2358 v-if =" gravatarUrl"
2459 :src =" gravatarUrl"
2560 alt =" "
26- width =" 64 "
27- height =" 64 "
61+ : width =" sizePixels "
62+ : height =" sizePixels "
2863 class =" w-full h-full object-cover"
2964 />
30- <!-- Else fallback to initials -->
31- <span v-else class =" text-2xl text-fg-subtle font-mono" aria-hidden =" true" >
32- {{ username.charAt(0).toUpperCase() }}
33- </span >
65+ <!-- Else fallback to initials (use svg to avoid underline styling) -->
66+ <svg
67+ v-else
68+ xmlns =" http://www.w3.org/2000/svg"
69+ :width =" sizePixels"
70+ :height =" sizePixels"
71+ class =" text-fg-subtle"
72+ :class =" textClass"
73+ >
74+ <text x =" 50%" y =" 50%" dominant-baseline =" central" text-anchor =" middle" fill =" currentColor" >
75+ {{ username.charAt(0).toUpperCase() }}
76+ </text >
77+ </svg >
3478 </div >
3579</template >
0 commit comments