@@ -20,6 +20,7 @@ const logos = [
2020 {
2121 name : () => $t (' brand.logos.wordmark' ),
2222 src: ' /logo.svg' ,
23+ srcLight: ' /logo-light.svg' ,
2324 altDark : () => $t (' brand.logos.wordmark_alt' ),
2425 altLight : () => $t (' brand.logos.wordmark_light_alt' ),
2526 width: 602 ,
@@ -40,8 +41,20 @@ const logos = [
4041
4142const typographySizes = [' text-2xl' , ' text-xl' , ' text-lg' , ' text-base' , ' text-sm' ]
4243
44+ const svgLoading = ref (new Set <string >())
4345const pngLoading = ref (new Set <string >())
4446
47+ function handleSvgDownload(src : string ) {
48+ if (svgLoading .value .has (src )) return
49+ svgLoading .value .add (src )
50+ try {
51+ downloadFileLink (src , src .replace (' /' , ' ' ))
52+ }
53+ finally {
54+ svgLoading .value .delete (src )
55+ }
56+ }
57+
4558async function handlePngDownload(logo : (typeof logos )[number ]) {
4659 if (pngLoading .value .has (logo .src )) return
4760 pngLoading .value .add (logo .src )
@@ -111,19 +124,23 @@ async function handlePngDownload(logo: (typeof logos)[number]) {
111124 $t('brand.logos.on_dark')
112125 }}</span >
113126 <div class =" flex items-center gap-2" >
114- <a
115- :href =" logo.src"
116- :download =" logo.src.replace('/', '')"
117- class =" inline-flex items-center gap-1 text-xs font-mono text-fg-muted border border-border rounded-md px-2 py-0.5 hover:bg-bg-muted hover:text-fg transition-colors duration-200 no-underline focus-visible:ring-2 focus-visible:ring-accent focus-visible:ring-offset-2 focus-visible:ring-offset-bg"
127+ <ButtonBase
128+ size =" sm"
118129 :aria-label ="
119130 $t('brand.logos.download_svg_aria', {
120131 name: `${logo.name()} (${$t('brand.logos.on_dark')})`,
121132 })
122133 "
134+ :disabled =" svgLoading.has(logo.src)"
135+ @click =" handleSvgDownload(logo.src)"
123136 >
124- <span class =" i-lucide:download w-3.5 h-3.5" aria-hidden =" true" />
137+ <span
138+ class =" size-[1em]"
139+ aria-hidden =" true"
140+ :class =" svgLoading.has(logo.src) ? 'i-lucide:loader-circle animate-spin' : 'i-lucide:download'"
141+ />
125142 {{ $t('brand.logos.download_svg') }}
126- </a >
143+ </ButtonBase >
127144 <ButtonBase
128145 size =" sm"
129146 :aria-label ="
@@ -173,19 +190,23 @@ async function handlePngDownload(logo: (typeof logos)[number]) {
173190 $t('brand.logos.on_light')
174191 }}</span >
175192 <div class =" flex items-center gap-2" >
176- <a
177- :href =" logo.src"
178- :download =" logo.src.replace('/', '')"
179- class =" inline-flex items-center gap-1 text-xs font-mono text-fg-muted border border-border rounded-md px-2 py-0.5 hover:bg-bg-muted hover:text-fg transition-colors duration-200 no-underline focus-visible:ring-2 focus-visible:ring-accent focus-visible:ring-offset-2 focus-visible:ring-offset-bg"
193+ <ButtonBase
194+ size =" sm"
180195 :aria-label ="
181196 $t('brand.logos.download_svg_aria', {
182197 name: `${logo.name()} (${$t('brand.logos.on_light')})`,
183198 })
184199 "
200+ :disabled =" svgLoading.has(logo.srcLight ?? logo.src)"
201+ @click =" handleSvgDownload(logo.srcLight ?? logo.src)"
185202 >
186- <span class =" i-lucide:download w-3.5 h-3.5" aria-hidden =" true" />
203+ <span
204+ class =" size-[1em]"
205+ aria-hidden =" true"
206+ :class =" svgLoading.has(logo.srcLight ?? logo.src) ? 'i-lucide:loader-circle animate-spin' : 'i-lucide:download'"
207+ />
187208 {{ $t('brand.logos.download_svg') }}
188- </a >
209+ </ButtonBase >
189210 <ButtonBase
190211 size =" sm"
191212 :aria-label ="
0 commit comments