Skip to content

Commit 1c56a45

Browse files
authored
Merge branch 'main' into jg/test-i-see-colours
2 parents 885df49 + f8a66e0 commit 1c56a45

File tree

31 files changed

+647
-213
lines changed

31 files changed

+647
-213
lines changed

.github/workflows/autofix.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ permissions:
1414

1515
jobs:
1616
code:
17+
name: 🤖 Autofix code
1718
runs-on: ubuntu-latest
1819

1920
steps:
@@ -24,7 +25,7 @@ jobs:
2425
node-version: lts/*
2526

2627
- uses: pnpm/action-setup@1e1c8eafbd745f64b1ef30a7d7ed7965034c486c
27-
name: Install pnpm
28+
name: 🟧 Install pnpm
2829
with:
2930
cache: true
3031

.github/workflows/ci.yml

Lines changed: 57 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ permissions:
2121

2222
jobs:
2323
lint:
24+
name: 🔠 Lint project
2425
runs-on: ubuntu-latest
2526

2627
steps:
@@ -31,13 +32,58 @@ jobs:
3132
node-version: lts/*
3233

3334
- uses: pnpm/action-setup@1e1c8eafbd745f64b1ef30a7d7ed7965034c486c
34-
name: Install pnpm
35+
name: 🟧 Install pnpm
3536
# pnpm cache skipped deliberately as the project is not actually installed here
3637

3738
- name: 🔠 Lint project
3839
run: node scripts/lint.ts
3940

41+
types:
42+
name: 💪 Type check
43+
runs-on: ubuntu-latest
44+
45+
steps:
46+
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
47+
48+
- uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
49+
with:
50+
node-version: lts/*
51+
52+
- uses: pnpm/action-setup@1e1c8eafbd745f64b1ef30a7d7ed7965034c486c
53+
name: 🟧 Install pnpm
54+
with:
55+
cache: true
56+
57+
- name: 📦 Install dependencies
58+
run: pnpm install
59+
60+
- name: 💪 Type check
61+
run: pnpm test:types
62+
63+
unit:
64+
name: 🧪 Unit tests
65+
runs-on: ubuntu-latest
66+
67+
steps:
68+
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
69+
70+
- uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
71+
with:
72+
node-version: lts/*
73+
74+
- uses: pnpm/action-setup@1e1c8eafbd745f64b1ef30a7d7ed7965034c486c
75+
name: 🟧 Install pnpm
76+
with:
77+
cache: true
78+
79+
- name: 📦 Install dependencies
80+
run: pnpm install
81+
82+
- name: 🧪 Unit tests
83+
run: pnpm test:unit --project unit run --coverage
84+
4085
test:
86+
name: 🧪 Component tests
4187
runs-on: ubuntu-latest
4288

4389
steps:
@@ -48,7 +94,7 @@ jobs:
4894
node-version: lts/*
4995

5096
- uses: pnpm/action-setup@1e1c8eafbd745f64b1ef30a7d7ed7965034c486c
51-
name: Install pnpm
97+
name: 🟧 Install pnpm
5298
with:
5399
cache: true
54100

@@ -58,18 +104,16 @@ jobs:
58104
- name: 🌐 Install browser
59105
run: pnpm playwright install chromium-headless-shell
60106

61-
- name: 💪 Type check
62-
run: pnpm test:types
63-
64-
- name: 🧪 Unit and component tests
65-
run: pnpm vite test run --coverage
107+
- name: 🧪 Component tests
108+
run: pnpm vite test --project nuxt run --coverage
66109

67110
- name: Upload coverage reports to Codecov
68111
uses: codecov/codecov-action@671740ac38dd9b0130fbe1cec585b89eea48d3de # v5
69112
env:
70113
CODECOV_TOKEN: 17b4bed9-d407-4ce2-9c10-2ccd4328a1d9
71114

72115
browser:
116+
name: 🖥️ Browser tests
73117
runs-on: ubuntu-latest
74118
container:
75119
image: mcr.microsoft.com/playwright:v1.58.0-noble
@@ -82,7 +126,7 @@ jobs:
82126
node-version: lts/*
83127

84128
- uses: pnpm/action-setup@1e1c8eafbd745f64b1ef30a7d7ed7965034c486c
85-
name: Install pnpm
129+
name: 🟧 Install pnpm
86130
with:
87131
cache: true
88132

@@ -96,6 +140,7 @@ jobs:
96140
run: pnpm test:browser:prebuilt
97141

98142
a11y:
143+
name: ♿ Accessibility audit
99144
runs-on: ubuntu-latest
100145
strategy:
101146
matrix:
@@ -109,7 +154,7 @@ jobs:
109154
node-version: lts/*
110155

111156
- uses: pnpm/action-setup@1e1c8eafbd745f64b1ef30a7d7ed7965034c486c
112-
name: Install pnpm
157+
name: 🟧 Install pnpm
113158
with:
114159
cache: true
115160

@@ -126,6 +171,7 @@ jobs:
126171
LIGHTHOUSE_COLOR_MODE: ${{ matrix.mode }}
127172

128173
knip:
174+
name: 🧹 Unused code check
129175
runs-on: ubuntu-latest
130176

131177
steps:
@@ -136,12 +182,12 @@ jobs:
136182
node-version: lts/*
137183

138184
- uses: pnpm/action-setup@1e1c8eafbd745f64b1ef30a7d7ed7965034c486c
139-
name: Install pnpm
185+
name: 🟧 Install pnpm
140186
with:
141187
cache: true
142188

143189
- name: 📦 Install dependencies
144190
run: pnpm install
145191

146-
- name: 🔍 Check for unused code
192+
- name: 🧹 Check for unused code
147193
run: pnpm knip

.github/workflows/lunaria.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ permissions:
1717

1818
jobs:
1919
lunaria-overview:
20-
name: Generate Lunaria Overview
20+
name: 🌝 Generate Lunaria Overview
2121
runs-on: ubuntu-latest
2222

2323
steps:
@@ -33,7 +33,7 @@ jobs:
3333
node-version: lts/*
3434

3535
- uses: pnpm/action-setup@1e1c8eafbd745f64b1ef30a7d7ed7965034c486c
36-
name: Install pnpm
36+
name: 🟧 Install pnpm
3737
with:
3838
cache: true
3939

.github/workflows/provenance.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ permissions:
2020

2121
jobs:
2222
check-provenance:
23+
name: 🔒 Check provenance downgrades
2324
runs-on: ubuntu-slim
2425
steps:
2526
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1

.github/workflows/semantic-pull-requests.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ jobs:
1717
statuses: write # for amannn/action-semantic-pull-request to mark status of analyzed PR
1818
if: github.repository == 'npmx-dev/npmx.dev'
1919
runs-on: ubuntu-slim
20-
name: semantic-pr
20+
name: 🏷️ Validate PR title
2121
steps:
2222
- name: Validate PR title
2323
uses: amannn/action-semantic-pull-request@48f256284bd46cdaab1048c3721360e808335d50 # v6.1.1

app/components/Filter/Panel.vue

Lines changed: 20 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -243,17 +243,16 @@ const hasActiveFilters = computed(() => !!filterSummary.value)
243243
role="radiogroup"
244244
:aria-label="$t('filters.weekly_downloads')"
245245
>
246-
<TagClickable
246+
<TagRadioButton
247247
v-for="range in DOWNLOAD_RANGES"
248248
:key="range.value"
249-
type="button"
250-
role="radio"
251-
:aria-checked="filters.downloadRange === range.value"
252-
:status="filters.downloadRange === range.value ? 'active' : 'default'"
253-
@click="emit('update:downloadRange', range.value)"
249+
:model-value="filters.downloadRange"
250+
:value="range.value"
251+
@update:modelValue="emit('update:downloadRange', $event as DownloadRange)"
252+
name="range"
254253
>
255254
{{ $t(getDownloadRangeLabelKey(range.value)) }}
256-
</TagClickable>
255+
</TagRadioButton>
257256
</div>
258257
</fieldset>
259258

@@ -267,17 +266,16 @@ const hasActiveFilters = computed(() => !!filterSummary.value)
267266
role="radiogroup"
268267
:aria-label="$t('filters.updated_within')"
269268
>
270-
<TagClickable
269+
<TagRadioButton
271270
v-for="option in UPDATED_WITHIN_OPTIONS"
272271
:key="option.value"
273-
type="button"
274-
role="radio"
275-
:aria-checked="filters.updatedWithin === option.value"
276-
:status="filters.updatedWithin === option.value ? 'active' : 'default'"
277-
@click="emit('update:updatedWithin', option.value)"
272+
:model-value="filters.updatedWithin"
273+
:value="option.value"
274+
name="updatedWithin"
275+
@update:modelValue="emit('update:updatedWithin', $event as UpdatedWithin)"
278276
>
279277
{{ $t(getUpdatedWithinLabelKey(option.value)) }}
280-
</TagClickable>
278+
</TagRadioButton>
281279
</div>
282280
</fieldset>
283281

@@ -290,17 +288,16 @@ const hasActiveFilters = computed(() => !!filterSummary.value)
290288
</span>
291289
</legend>
292290
<div class="flex flex-wrap gap-2" role="radiogroup" :aria-label="$t('filters.security')">
293-
<TagClickable
291+
<TagRadioButton
294292
v-for="security in SECURITY_FILTER_VALUES"
295293
:key="security"
296-
type="button"
297-
role="radio"
298294
disabled
299-
:aria-checked="filters.security === security"
300-
:status="filters.security === security ? 'active' : 'default'"
295+
:model-value="filters.security"
296+
:value="security"
297+
name="security"
301298
>
302299
{{ $t(getSecurityLabelKey(security)) }}
303-
</TagClickable>
300+
</TagRadioButton>
304301
</div>
305302
</fieldset>
306303

@@ -310,16 +307,14 @@ const hasActiveFilters = computed(() => !!filterSummary.value)
310307
{{ $t('filters.keywords') }}
311308
</legend>
312309
<div class="flex flex-wrap gap-1.5" role="group" :aria-label="$t('filters.keywords')">
313-
<TagClickable
310+
<TagButton
314311
v-for="keyword in displayedKeywords"
315312
:key="keyword"
316-
type="button"
317-
:aria-pressed="filters.keywords.includes(keyword)"
318-
:status="filters.keywords.includes(keyword) ? 'active' : 'default'"
313+
:pressed="filters.keywords.includes(keyword)"
319314
@click="emit('toggleKeyword', keyword)"
320315
>
321316
{{ keyword }}
322-
</TagClickable>
317+
</TagButton>
323318
<button
324319
v-if="hasMoreKeywords"
325320
type="button"

app/components/Package/Card.vue

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -162,17 +162,16 @@ const pkgDescription = useMarkdown(() => ({
162162
:aria-label="$t('package.card.keywords')"
163163
class="relative z-10 flex flex-wrap gap-1.5 mt-3 pt-3 border-t border-border list-none m-0 p-0 pointer-events-none"
164164
>
165-
<TagClickable
165+
<TagButton
166166
v-for="keyword in result.package.keywords.slice(0, 5)"
167-
:key="keyword"
168-
type="button"
169167
class="pointer-events-auto"
170-
:status="props.filters?.keywords.includes(keyword) ? 'active' : 'default'"
168+
:key="keyword"
169+
:pressed="props.filters?.keywords.includes(keyword)"
171170
:title="`Filter by ${keyword}`"
172171
@click.stop="emit('clickKeyword', keyword)"
173172
>
174173
{{ keyword }}
175-
</TagClickable>
174+
</TagButton>
176175
<span
177176
v-if="result.package.keywords.length > 5"
178177
class="text-fg-subtle text-xs pointer-events-auto"

app/components/Package/Keywords.vue

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
11
<script setup lang="ts">
2-
import { NuxtLink } from '#components'
3-
42
defineProps<{
53
keywords?: string[]
64
}>()
@@ -9,9 +7,9 @@ defineProps<{
97
<CollapsibleSection v-if="keywords?.length" :title="$t('package.keywords_title')" id="keywords">
108
<ul class="flex flex-wrap gap-1.5 list-none m-0 p-0">
119
<li v-for="keyword in keywords.slice(0, 15)" :key="keyword">
12-
<TagClickable :as="NuxtLink" :to="{ name: 'search', query: { q: `keywords:${keyword}` } }">
10+
<TagLink :to="{ name: 'search', query: { q: `keywords:${keyword}` } }">
1311
{{ keyword }}
14-
</TagClickable>
12+
</TagLink>
1513
</li>
1614
</ul>
1715
</CollapsibleSection>

app/components/Package/TableRow.vue

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -126,17 +126,16 @@ const allMaintainersText = computed(() => {
126126
class="flex flex-wrap gap-1 justify-end"
127127
:aria-label="$t('package.card.keywords')"
128128
>
129-
<TagClickable
129+
<TagButton
130130
v-for="keyword in pkg.keywords.slice(0, 3)"
131131
:key="keyword"
132-
type="button"
133-
:status="props.filters?.keywords.includes(keyword) ? 'active' : 'default'"
132+
:pressed="props.filters?.keywords.includes(keyword)"
134133
:title="`Filter by ${keyword}`"
135134
@click.stop="emit('clickKeyword', keyword)"
136135
:class="{ 'group-hover:bg-bg-elevated': !props.filters?.keywords.includes(keyword) }"
137136
>
138137
{{ keyword }}
139-
</TagClickable>
138+
</TagButton>
140139
<span
141140
v-if="pkg.keywords.length > 3"
142141
class="text-fg-subtle text-xs"

app/components/Tag/Button.vue

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<script setup lang="ts">
2+
const props = defineProps<{
3+
disabled?: boolean
4+
/**
5+
* type should never be used, because this will always be a button.
6+
*
7+
* If you want a link use `TagLink` instead.
8+
* */
9+
type?: never
10+
pressed?: boolean
11+
}>()
12+
</script>
13+
14+
<template>
15+
<button
16+
class="inline-flex items-center px-2 py-0.5 text-xs font-mono border rounded transition-colors duration-200 focus-visible:ring-2 focus-visible:ring-fg focus-visible:ring-offset-1"
17+
:class="[
18+
pressed
19+
? 'bg-fg text-bg border-fg hover:(text-text-bg/50)'
20+
: 'bg-bg-muted text-fg-muted border-border hover:(text-fg border-border-hover)',
21+
{
22+
'opacity-50 cursor-not-allowed': disabled,
23+
},
24+
]"
25+
type="button"
26+
:disabled="disabled ? true : undefined"
27+
:aria-pressed="pressed"
28+
>
29+
<slot />
30+
</button>
31+
</template>

0 commit comments

Comments
 (0)