Skip to content

Commit c8420d2

Browse files
committed
refactor: change props for buttons and links
1 parent 042f468 commit c8420d2

9 files changed

Lines changed: 58 additions & 33 deletions

File tree

app/components/Button/Base.vue

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@ const props = withDefaults(
33
defineProps<{
44
'disabled'?: boolean
55
'type'?: 'button' | 'submit'
6-
'variant'?: 'primary' | 'secondary' | 'tag'
6+
'variant'?: 'primary' | 'secondary'
7+
'size'?: 'small' | 'medium'
78
'keyshortcut'?: string
89
910
/**
@@ -16,6 +17,7 @@ const props = withDefaults(
1617
{
1718
type: 'button',
1819
variant: 'secondary',
20+
size: 'medium',
1921
},
2022
)
2123
@@ -31,10 +33,10 @@ defineExpose({
3133
ref="el"
3234
class="group cursor-pointer inline-flex gap-x-1 items-center justify-center font-mono border border-border rounded-md transition-all duration-200 disabled:(opacity-40 cursor-not-allowed border-transparent) aria-pressed:(bg-fg text-bg border-fg hover:enabled:(text-bg/50)) bg-gradient-to-t dark:bg-gradient-to-b"
3335
:class="{
34-
'text-sm px-4 py-2': variant !== 'tag',
35-
'text-xs px-2 py-0.5': variant === 'tag',
36+
'text-sm px-4 py-2': size === 'medium',
37+
'text-xs px-2 py-0.5': size === 'small',
3638
'from-fg/10 via-transparent to-transparent text-fg hover:enabled:(bg-accent/20 border-accent) focus-visible:enabled:(bg-accent/20 border-accent)':
37-
variant === 'tag' || variant === 'secondary',
39+
variant === 'secondary',
3840
'text-black from-accent via-accent to-accent/30 hover:enabled:(bg-accent/50) focus-visible:enabled:(bg-accent/50)':
3941
variant === 'primary',
4042
}"
@@ -52,7 +54,7 @@ defineExpose({
5254
>
5355
<span
5456
v-if="classicon"
55-
:class="[variant === 'tag' ? 'size-3' : 'size-4', classicon]"
57+
:class="[size === 'small' ? 'size-3' : 'size-4', classicon]"
5658
aria-hidden="true"
5759
/>
5860
<slot />

app/components/Filter/Panel.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -310,7 +310,7 @@ const hasActiveFilters = computed(() => !!filterSummary.value)
310310
<ButtonBase
311311
v-for="keyword in displayedKeywords"
312312
:key="keyword"
313-
variant="tag"
313+
size="small"
314314
:aria-pressed="filters.keywords.includes(keyword)"
315315
@click="emit('toggleKeyword', keyword)"
316316
>

app/components/Link/Base.vue

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ const props = withDefaults(
1010
* `type` should never be used, because this will always be a link.
1111
* */
1212
'type'?: never
13-
'variant'?: 'button-primary' | 'button-secondary' | 'tag' | 'link'
13+
'variant'?: 'button-primary' | 'button-secondary' | 'link'
14+
'size'?: 'small' | 'medium'
1415
1516
'keyshortcut'?: string
1617
@@ -37,7 +38,7 @@ const props = withDefaults(
3738
'href'?: never
3839
} & NuxtLinkProps
3940
>(),
40-
{ variant: 'link' },
41+
{ variant: 'link', size: 'medium' },
4142
)
4243
4344
const isLinkExternal = computed(
@@ -49,17 +50,22 @@ const isLinkExternal = computed(
4950
const isLinkAnchor = computed(
5051
() => !!props.to && typeof props.to === 'string' && props.to.startsWith('#'),
5152
)
53+
54+
/** size is only applicable for button like links */
55+
const isLink = computed(() => props.variant === 'link')
56+
const isButton = computed(() => props.variant !== 'link')
57+
const isButtonSmall = computed(() => props.size === 'small' && props.variant !== 'link')
58+
const isButtonMedium = computed(() => props.size === 'medium' && props.variant !== 'link')
5259
</script>
5360

5461
<template>
5562
<span
5663
v-if="disabled"
5764
:class="{
5865
'opacity-50 inline-flex gap-x-1 items-center justify-center font-mono border border-transparent rounded-md':
59-
variant !== 'link',
60-
'text-sm px-4 py-2': variant !== 'tag' && variant !== 'link',
61-
'text-xs px-2 py-0.5': variant === 'tag',
62-
'bg-bg-muted text-fg-muted': variant === 'tag',
66+
isButton,
67+
'text-sm px-4 py-2': isButtonMedium,
68+
'text-xs px-2 py-0.5': isButtonSmall,
6369
'text-bg bg-fg': variant === 'button-primary',
6470
'bg-transparent text-fg': variant === 'button-secondary',
6571
}"
@@ -69,16 +75,15 @@ const isLinkAnchor = computed(
6975
v-else
7076
class="group inline-flex gap-x-1 items-center justify-center"
7177
:class="{
72-
'underline-offset-[0.2rem] underline decoration-1 decoration-fg/50':
73-
!isLinkAnchor && variant === 'link',
78+
'underline-offset-[0.2rem] underline decoration-1 decoration-fg/50': !isLinkAnchor && isLink,
7479
'text-fg hover:(no-underline text-accent) focus-visible:(no-underline text-accent) transition-colors duration-200':
75-
variant === 'link',
80+
isLink,
7681
'font-mono border border-border rounded-md transition-all duration-200 aria-current:(bg-fg text-bg border-fg hover:(text-bg/50)) bg-gradient-to-t dark:bg-gradient-to-b':
77-
variant !== 'link',
78-
'text-sm px-4 py-2': variant !== 'tag' && variant !== 'link',
79-
'text-xs px-2 py-0.5': variant === 'tag',
82+
isButton,
83+
'text-sm px-4 py-2': isButtonMedium,
84+
'text-xs px-2 py-0.5': isButtonSmall,
8085
'from-fg/10 via-transparent to-transparent text-fg hover:(bg-accent/20 border-accent) focus-visible:(bg-accent/20 border-accent)':
81-
variant === 'tag' || variant === 'button-secondary',
86+
variant === 'button-secondary',
8287
'text-black from-accent via-accent to-accent/30 hover:(bg-accent/50) focus-visible:(bg-accent/50)':
8388
variant === 'button-primary',
8489
}"
@@ -91,7 +96,7 @@ const isLinkAnchor = computed(
9196
>
9297
<span
9398
v-if="classicon"
94-
:class="[variant === 'tag' ? 'size-3' : 'size-4', classicon]"
99+
:class="[isButtonSmall ? 'size-3' : 'size-4', classicon]"
95100
aria-hidden="true"
96101
/>
97102
<slot />
@@ -102,7 +107,7 @@ const isLinkAnchor = computed(
102107
aria-hidden="true"
103108
/>
104109
<span
105-
v-else-if="isLinkAnchor && variant === 'link'"
110+
v-else-if="isLinkAnchor && isLink"
106111
class="i-carbon:link w-3 h-3 opacity-0 group-hover:opacity-100 transition-opacity duration-200"
107112
aria-hidden="true"
108113
/>

app/components/Package/Card.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ const pkgDescription = useMarkdown(() => ({
165165
<ButtonBase
166166
v-for="keyword in result.package.keywords.slice(0, 5)"
167167
class="pointer-events-auto"
168-
variant="tag"
168+
size="small"
169169
:key="keyword"
170170
:aria-pressed="props.filters?.keywords.includes(keyword)"
171171
:title="`Filter by ${keyword}`"

app/components/Package/Keywords.vue

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,11 @@ defineProps<{
77
<CollapsibleSection v-if="keywords?.length" :title="$t('package.keywords_title')" id="keywords">
88
<ul class="flex flex-wrap gap-1.5 list-none m-0 p-1">
99
<li v-for="keyword in keywords.slice(0, 15)" :key="keyword">
10-
<LinkBase variant="tag" :to="{ name: 'search', query: { q: `keywords:${keyword}` } }">
10+
<LinkBase
11+
variant="button-secondary"
12+
size="small"
13+
:to="{ name: 'search', query: { q: `keywords:${keyword}` } }"
14+
>
1115
{{ keyword }}
1216
</LinkBase>
1317
</li>

app/components/Package/MetricsBadges.vue

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,13 @@ const typesHref = computed(() => {
5858
<!-- TypeScript types badge -->
5959
<li v-if="!props.isBinary" class="contents">
6060
<TooltipApp :text="typesTooltip">
61-
<LinkBase v-if="typesHref" variant="tag" :to="typesHref" classicon="i-carbon-checkmark">
61+
<LinkBase
62+
v-if="typesHref"
63+
variant="button-secondary"
64+
size="small"
65+
:to="typesHref"
66+
classicon="i-carbon-checkmark"
67+
>
6268
{{ $t('package.metrics.types_label') }}
6369
</LinkBase>
6470
<TagStatic

app/components/Package/TableRow.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ const allMaintainersText = computed(() => {
132132
<ButtonBase
133133
v-for="keyword in pkg.keywords.slice(0, 3)"
134134
:key="keyword"
135-
variant="tag"
135+
size="small"
136136
:aria-pressed="props.filters?.keywords.includes(keyword)"
137137
:title="`Filter by ${keyword}`"
138138
@click.stop="emit('clickKeyword', keyword)"

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

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -573,7 +573,8 @@ onKeyStroke(
573573
position="bottom"
574574
>
575575
<LinkBase
576-
variant="tag"
576+
variant="button-secondary"
577+
size="small"
577578
to="#provenance"
578579
:aria-label="$t('package.provenance_section.view_more_details')"
579580
classicon="i-lucide-shield-check"
@@ -607,7 +608,7 @@ onKeyStroke(
607608
>
608609
<ButtonBase
609610
@click="likeAction"
610-
variant="tag"
611+
size="small"
611612
:title="
612613
likesData?.userHasLiked ? $t('package.likes.unlike') : $t('package.likes.like')
613614
"
@@ -839,7 +840,8 @@ onKeyStroke(
839840

840841
<span class="flex items-center gap-1">
841842
<LinkBase
842-
variant="tag"
843+
variant="button-secondary"
844+
size="small"
843845
v-if="getDependencyCount(displayVersion) > 0"
844846
:to="`https://npmgraph.js.org/?q=${pkg.name}`"
845847
:title="$t('package.stats.view_dependency_graph')"
@@ -849,7 +851,8 @@ onKeyStroke(
849851
</LinkBase>
850852

851853
<LinkBase
852-
variant="tag"
854+
variant="button-secondary"
855+
size="small"
853856
v-if="getDependencyCount(displayVersion) > 0"
854857
:to="`https://node-modules.dev/grid/depth#install=${pkg.name}${resolvedVersion ? `@${resolvedVersion}` : ''}`"
855858
:title="$t('package.stats.inspect_dependency_tree')"

test/nuxt/a11y.spec.ts

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -317,9 +317,9 @@ describe('component accessibility audits', () => {
317317
expect(results.violations).toEqual([])
318318
})
319319

320-
it('should have no accessibility violations as tag', async () => {
320+
it('should have no accessibility violations with size small', async () => {
321321
const component = await mountSuspended(ButtonBase, {
322-
props: { variant: 'tag' },
322+
props: { size: 'small' },
323323
slots: { default: 'Button content' },
324324
})
325325
const results = await runAxe(component)
@@ -373,9 +373,14 @@ describe('component accessibility audits', () => {
373373
expect(results.violations).toEqual([])
374374
})
375375

376-
it('should have no accessibility violations as tag', async () => {
376+
it('should have no accessibility violations as small button', async () => {
377377
const component = await mountSuspended(LinkBase, {
378-
props: { to: 'http://example.com', disabled: true, variant: 'tag' },
378+
props: {
379+
to: 'http://example.com',
380+
disabled: true,
381+
variant: 'button-secondary',
382+
size: 'small',
383+
},
379384
slots: { default: 'Button link content' },
380385
})
381386
const results = await runAxe(component)

0 commit comments

Comments
 (0)