Skip to content

Commit 2fb44eb

Browse files
committed
refactor: extract tags components
1 parent 9e276c3 commit 2fb44eb

7 files changed

Lines changed: 43 additions & 21 deletions

File tree

app/components/Filter/Chips.vue

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ const emit = defineEmits<{
1414
<template>
1515
<div v-if="chips.length > 0" class="flex flex-wrap items-center gap-2">
1616
<TransitionGroup name="chip">
17-
<span v-for="chip in chips" :key="chip.id" class="tag gap-1">
17+
<TagStatic v-for="chip in chips" :key="chip.id" class="gap-1">
1818
<span class="text-fg-subtle text-xs">{{ chip.label }}:</span>
1919
<span class="max-w-32 truncate">{{
2020
Array.isArray(chip.value) ? chip.value.join(', ') : chip.value
@@ -27,7 +27,7 @@ const emit = defineEmits<{
2727
>
2828
<span class="i-carbon-close w-3 h-3" aria-hidden="true" />
2929
</button>
30-
</span>
30+
</TagStatic>
3131
</TransitionGroup>
3232

3333
<button

app/components/Filter/Panel.vue

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -243,13 +243,13 @@ const hasActiveFilters = computed(() => !!filterSummary.value)
243243
role="radiogroup"
244244
:aria-label="$t('filters.weekly_downloads')"
245245
>
246-
<button
246+
<TagClickable
247247
v-for="range in DOWNLOAD_RANGES"
248248
:key="range.value"
249249
type="button"
250250
role="radio"
251251
:aria-checked="filters.downloadRange === range.value"
252-
class="tag transition-colors duration-200 focus-visible:ring-2 focus-visible:ring-fg focus-visible:ring-offset-1"
252+
class="transition-colors duration-200 focus-visible:ring-2 focus-visible:ring-fg focus-visible:ring-offset-1"
253253
:class="
254254
filters.downloadRange === range.value
255255
? 'bg-fg text-bg border-fg hover:text-bg/50'
@@ -258,7 +258,7 @@ const hasActiveFilters = computed(() => !!filterSummary.value)
258258
@click="emit('update:downloadRange', range.value)"
259259
>
260260
{{ $t(getDownloadRangeLabelKey(range.value)) }}
261-
</button>
261+
</TagClickable>
262262
</div>
263263
</fieldset>
264264

@@ -272,13 +272,13 @@ const hasActiveFilters = computed(() => !!filterSummary.value)
272272
role="radiogroup"
273273
:aria-label="$t('filters.updated_within')"
274274
>
275-
<button
275+
<TagClickable
276276
v-for="option in UPDATED_WITHIN_OPTIONS"
277277
:key="option.value"
278278
type="button"
279279
role="radio"
280280
:aria-checked="filters.updatedWithin === option.value"
281-
class="tag transition-colors duration-200 focus-visible:ring-2 focus-visible:ring-fg focus-visible:ring-offset-1"
281+
class="transition-colors duration-200 focus-visible:ring-2 focus-visible:ring-fg focus-visible:ring-offset-1"
282282
:class="
283283
filters.updatedWithin === option.value
284284
? 'bg-fg text-bg border-fg hover:text-bg/70'
@@ -287,7 +287,7 @@ const hasActiveFilters = computed(() => !!filterSummary.value)
287287
@click="emit('update:updatedWithin', option.value)"
288288
>
289289
{{ $t(getUpdatedWithinLabelKey(option.value)) }}
290-
</button>
290+
</TagClickable>
291291
</div>
292292
</fieldset>
293293

@@ -300,20 +300,20 @@ const hasActiveFilters = computed(() => !!filterSummary.value)
300300
</span>
301301
</legend>
302302
<div class="flex flex-wrap gap-2" role="radiogroup" :aria-label="$t('filters.security')">
303-
<button
303+
<TagClickable
304304
v-for="option in SECURITY_FILTER_OPTIONS"
305305
:key="option.value"
306306
type="button"
307307
role="radio"
308308
disabled
309309
:aria-checked="filters.security === option.value"
310-
class="tag transition-colors duration-200 opacity-50 cursor-not-allowed focus-visible:ring-2 focus-visible:ring-fg focus-visible:ring-offset-1"
310+
class="transition-colors duration-200 opacity-50 cursor-not-allowed focus-visible:ring-2 focus-visible:ring-fg focus-visible:ring-offset-1"
311311
:class="
312312
filters.security === option.value ? 'bg-fg text-bg border-fg hover:text-bg/70' : ''
313313
"
314314
>
315315
{{ $t(getSecurityLabelKey(option.value)) }}
316-
</button>
316+
</TagClickable>
317317
</div>
318318
</fieldset>
319319

@@ -323,19 +323,19 @@ const hasActiveFilters = computed(() => !!filterSummary.value)
323323
{{ $t('filters.keywords') }}
324324
</legend>
325325
<div class="flex flex-wrap gap-1.5" role="group" :aria-label="$t('filters.keywords')">
326-
<button
326+
<TagClickable
327327
v-for="keyword in displayedKeywords"
328328
:key="keyword"
329329
type="button"
330330
:aria-pressed="filters.keywords.includes(keyword)"
331-
class="tag text-xs transition-colors duration-200 focus-visible:ring-2 focus-visible:ring-fg focus-visible:ring-offset-1"
331+
class="text-xs transition-colors duration-200 focus-visible:ring-2 focus-visible:ring-fg focus-visible:ring-offset-1"
332332
:class="
333333
filters.keywords.includes(keyword) ? 'bg-fg text-bg border-fg hover:text-bg/70' : ''
334334
"
335335
@click="emit('toggleKeyword', keyword)"
336336
>
337337
{{ keyword }}
338-
</button>
338+
</TagClickable>
339339
<button
340340
v-if="hasMoreKeywords"
341341
type="button"

app/components/Package/Card.vue

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -154,9 +154,9 @@ const pkgDescription = useMarkdown(() => ({
154154
:aria-label="$t('package.card.keywords')"
155155
class="relative z-10 flex flex-wrap gap-1.5 mt-3 pt-3 border-t border-border list-none m-0 p-0"
156156
>
157-
<li v-for="keyword in result.package.keywords.slice(0, 5)" :key="keyword" class="tag">
157+
<TagStatic as="li" v-for="keyword in result.package.keywords.slice(0, 5)" :key="keyword">
158158
{{ keyword }}
159-
</li>
159+
</TagStatic>
160160
</ul>
161161
</BaseCard>
162162
</template>

app/components/Package/TableRow.vue

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -118,16 +118,16 @@ const allMaintainersText = computed(() => {
118118
<!-- Keywords -->
119119
<td v-if="isColumnVisible('keywords')" class="py-2 px-3">
120120
<div v-if="pkg.keywords?.length" class="flex flex-wrap gap-1">
121-
<button
121+
<TagClickable
122122
v-for="keyword in pkg.keywords.slice(0, 3)"
123123
:key="keyword"
124124
type="button"
125-
class="tag text-xs hover:bg-fg hover:text-bg hover:border-fg transition-colors duration-200 focus-visible:ring-2 focus-visible:ring-fg focus-visible:ring-offset-1"
125+
class="text-xs hover:bg-fg hover:text-bg hover:border-fg transition-colors duration-200 focus-visible:ring-2 focus-visible:ring-fg focus-visible:ring-offset-1"
126126
:title="`Filter by ${keyword}`"
127127
@click.stop="emit('clickKeyword', keyword)"
128128
>
129129
{{ keyword }}
130-
</button>
130+
</TagClickable>
131131
<span v-if="pkg.keywords.length > 3" class="text-fg-subtle text-xs">
132132
+{{ pkg.keywords.length - 3 }}
133133
</span>

app/components/Tag/Clickable.vue

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<script setup lang="ts">
2+
const props = withDefaults(defineProps<{ as?: string | Component }>(),{ as: 'button' })
3+
</script>
4+
5+
<template>
6+
<component :is="props.as" class="tag">
7+
<slot />
8+
</component>
9+
</template>

app/components/Tag/Static.vue

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<script setup lang="ts">
2+
const props = withDefaults(defineProps<{ as?: string | Component }>(),{ as: 'span' })
3+
</script>
4+
5+
<template>
6+
<component :is="props.as" class="tag">
7+
<slot />
8+
</component>
9+
</template>

app/pages/package/[...package].vue

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import { joinURL } from 'ufo'
1111
import { areUrlsEquivalent } from '#shared/utils/url'
1212
import { isEditableElement } from '~/utils/input'
1313
import { formatBytes } from '~/utils/formatters'
14+
import { NuxtLink } from '#components'
1415
1516
definePageMeta({
1617
name: 'package',
@@ -1005,9 +1006,12 @@ defineOgImageComponent('Package', {
10051006
</h2>
10061007
<ul class="flex flex-wrap gap-1.5 list-none m-0 p-0">
10071008
<li v-for="keyword in displayVersion.keywords.slice(0, 15)" :key="keyword">
1008-
<NuxtLink :to="{ name: 'search', query: { q: `keywords:${keyword}` } }" class="tag">
1009+
<TagClickable
1010+
:as="NuxtLink"
1011+
:to="{ name: 'search', query: { q: `keywords:${keyword}` } }"
1012+
>
10091013
{{ keyword }}
1010-
</NuxtLink>
1014+
</TagClickable>
10111015
</li>
10121016
</ul>
10131017
</section>

0 commit comments

Comments
 (0)