Skip to content

Commit da51ef1

Browse files
authored
Merge branch 'main' into feat/badge-support-colorLeft
2 parents 3f5f6c3 + cbec1ab commit da51ef1

67 files changed

Lines changed: 3030 additions & 1078 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/autofix.yml

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,6 @@ jobs:
3131
- name: 📦 Install dependencies
3232
run: pnpm install
3333

34-
- name: 📦 Install browsers
35-
run: pnpm playwright install
36-
3734
- name: 🌐 Compare translations
3835
run: pnpm i18n:check
3936

@@ -43,14 +40,4 @@ jobs:
4340
- name: 🔠 Fix lint errors
4441
run: pnpm lint:fix
4542

46-
- name: 🧪 Update unit test snapshots
47-
run: pnpm test:unit -u
48-
49-
- name: 🏃 Update component test snapshots
50-
run: pnpm test:nuxt -u
51-
52-
# TODO: re-enable when we have snapshots in browser tests
53-
# - name: 🖥️ Update browser test snapshots
54-
# run: pnpm test:browser --update-snapshots
55-
5643
- uses: autofix-ci/action@635ffb0c9798bd160680f18fd73371e355b85f27

.github/workflows/ci.yml

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -32,14 +32,10 @@ jobs:
3232

3333
- uses: pnpm/action-setup@1e1c8eafbd745f64b1ef30a7d7ed7965034c486c
3434
name: Install pnpm
35-
with:
36-
cache: true
37-
38-
- name: 📦 Install dependencies
39-
run: pnpm install
35+
# pnpm cache skipped deliberately as the project is not actually installed here
4036

4137
- name: 🔠 Lint project
42-
run: pnpm lint
38+
run: node scripts/lint.ts
4339

4440
test:
4541
runs-on: ubuntu-latest
@@ -60,16 +56,16 @@ jobs:
6056
run: pnpm install
6157

6258
- name: 🌐 Install browser
63-
run: pnpm playwright install
59+
run: pnpm playwright install chromium-headless-shell
6460

6561
- name: 💪 Type check
6662
run: pnpm test:types
6763

68-
- name: 🧪 Unit test
69-
run: pnpm test:unit
64+
- name: 🧪 Unit and component tests
65+
run: pnpm vite test run --coverage
7066

71-
- name: 🏃 Component tests
72-
run: pnpm test:nuxt
67+
- name: Upload coverage reports to Codecov
68+
uses: codecov/codecov-action@671740ac38dd9b0130fbe1cec585b89eea48d3de # v5
7369

7470
browser:
7571
runs-on: ubuntu-latest
@@ -91,11 +87,17 @@ jobs:
9187
- name: 📦 Install dependencies
9288
run: pnpm install
9389

90+
- name: 🏗️ Build project
91+
run: pnpm build:playwright
92+
9493
- name: 🖥️ Test project (browser)
95-
run: pnpm test:browser
94+
run: pnpm test:browser:prebuilt
9695

9796
a11y:
9897
runs-on: ubuntu-latest
98+
strategy:
99+
matrix:
100+
mode: [dark, light]
99101

100102
steps:
101103
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
@@ -115,10 +117,11 @@ jobs:
115117
- name: 🏗️ Build project
116118
run: pnpm build
117119

118-
- name: ♿ Accessibility audit (Lighthouse - dark & light mode)
120+
- name: ♿ Accessibility audit (Lighthouse - ${{ matrix.mode }} mode)
119121
run: ./scripts/lighthouse-a11y.sh
120122
env:
121123
LHCI_GITHUB_APP_TOKEN: ${{ secrets.LHCI_GITHUB_APP_TOKEN }}
124+
LIGHTHOUSE_COLOR_MODE: ${{ matrix.mode }}
122125

123126
knip:
124127
runs-on: ubuntu-latest

.github/workflows/provenance.yml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,21 +4,28 @@ on:
44
push:
55
branches:
66
- main
7+
paths:
8+
- pnpm-lock.yaml
79
pull_request:
810
branches:
911
- main
12+
paths:
13+
- pnpm-lock.yaml
1014
merge_group:
1115
branches:
1216
- main
17+
1318
permissions:
1419
contents: read
20+
1521
jobs:
1622
check-provenance:
1723
runs-on: ubuntu-slim
1824
steps:
1925
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
2026
with:
2127
fetch-depth: 0
28+
2229
- name: Check provenance downgrades
2330
uses: danielroe/provenance-action@41bcc969e579d9e29af08ba44fcbfdf95cee6e6c # v0.1.1
2431
with:

CONTRIBUTING.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -522,6 +522,31 @@ Format: `type(scope): description`
522522
> [!NOTE]
523523
> The subject must start with a lowercase letter. Individual commit messages within your PR don't need to follow this format since they'll be squashed.
524524
525+
### PR descriptions
526+
527+
If your pull request directly addresses an open issue, use the following inside your PR description.
528+
529+
```text
530+
Resolves | Fixes | Closes: #xxx
531+
```
532+
533+
Replace `#xxx` with either a URL to the issue, or the number of the issue. For example:
534+
535+
```text
536+
Fixes #123
537+
```
538+
539+
or
540+
541+
```text
542+
Closes https://github.com/npmx-dev/npmx.dev/issues/123
543+
```
544+
545+
This provides the following benefits:
546+
547+
- it links the pull request to the issue (the merge icon will appear in the issue), so everybody can see there is an open PR
548+
- when the pull request is merged, the linked issue is automatically closed
549+
525550
## Pre-commit hooks
526551

527552
The project uses `lint-staged` with `simple-git-hooks` to automatically lint files on commit.

app/app.vue

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,8 @@ function handleGlobalKeydown(e: KeyboardEvent) {
6969
router.push('/search')
7070
}
7171
72-
if (isKeyWithoutModifiers(e, '?')) {
72+
// For "?" we check the key property directly since it's usually combined with shift
73+
if (e.key === '?') {
7374
e.preventDefault()
7475
showKbdHints.value = true
7576
}

app/assets/main.css

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -154,17 +154,9 @@ html {
154154
-webkit-font-smoothing: antialiased;
155155
-moz-osx-font-smoothing: grayscale;
156156
text-rendering: optimizeLegibility;
157-
scroll-behavior: smooth;
158157
scroll-padding-top: 5rem; /* Offset for fixed header - otherwise anchor headers are cutted */
159158
}
160159

161-
/* Disable smooth scrolling if user prefers reduced motion */
162-
@media (prefers-reduced-motion: reduce) {
163-
html {
164-
scroll-behavior: auto;
165-
}
166-
}
167-
168160
/*
169161
* Enable CSS scroll-state container queries for the document
170162
* This allows the footer to query the scroll state using pure CSS

app/components/CallToAction.vue

Lines changed: 45 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,30 @@
11
<script setup lang="ts">
2-
const socialLinks = {
3-
github: 'https://repo.npmx.dev',
4-
discord: 'https://chat.npmx.dev',
5-
bluesky: 'https://social.npmx.dev',
6-
}
2+
const socialLinks = computed(() => [
3+
{
4+
id: 'github',
5+
href: 'https://repo.npmx.dev',
6+
icon: 'i-carbon:logo-github',
7+
titleKey: $t('about.get_involved.contribute.title'),
8+
descriptionKey: $t('about.get_involved.contribute.description'),
9+
ctaKey: $t('about.get_involved.contribute.cta'),
10+
},
11+
{
12+
id: 'discord',
13+
href: 'https://chat.npmx.dev',
14+
icon: 'i-carbon:chat',
15+
titleKey: $t('about.get_involved.community.title'),
16+
descriptionKey: $t('about.get_involved.community.description'),
17+
ctaKey: $t('about.get_involved.community.cta'),
18+
},
19+
{
20+
id: 'bluesky',
21+
href: 'https://social.npmx.dev',
22+
icon: 'i-simple-icons:bluesky',
23+
titleKey: $t('about.get_involved.follow.title'),
24+
descriptionKey: $t('about.get_involved.follow.description'),
25+
ctaKey: $t('about.get_involved.follow.cta'),
26+
},
27+
])
728
</script>
829

930
<template>
@@ -13,74 +34,31 @@ const socialLinks = {
1334
</h2>
1435

1536
<div class="grid gap-4 sm:grid-cols-3 sm:items-stretch sm:grid-rows-[auto,1fr,auto]">
16-
<a
17-
:href="socialLinks.github"
18-
target="_blank"
19-
rel="noopener noreferrer"
20-
class="group grid gap-3 p-4 rounded-lg bg-bg-subtle hover:bg-bg-elevated border border-border hover:border-border-hover transition-all duration-200 sm:grid-rows-subgrid sm:row-span-3"
37+
<div
38+
v-for="link in socialLinks"
39+
:key="link.id"
40+
class="group relative grid gap-3 p-4 rounded-lg bg-bg-subtle hover:bg-bg-elevated border border-border hover:border-border-hover transition-all duration-200 sm:grid-rows-subgrid sm:row-span-3 focus-within:ring-2 focus-within:ring-accent/50"
2141
>
22-
<div class="flex gap-2">
23-
<span class="i-carbon:logo-github shrink-0 mt-1 w-5 h-5 text-fg" aria-hidden="true" />
42+
<h3 class="z-1 flex gap-2">
43+
<span :class="link.icon" class="shrink-0 mt-1 w-5 h-5 text-fg" aria-hidden="true" />
2444
<span class="font-medium text-fg">
25-
{{ $t('about.get_involved.contribute.title') }}
45+
{{ link.titleKey }}
2646
</span>
27-
</div>
28-
<p class="text-sm text-fg-muted leading-relaxed">
29-
{{ $t('about.get_involved.contribute.description') }}
47+
</h3>
48+
<p class="z-1 text-sm text-fg-muted leading-relaxed">
49+
{{ link.descriptionKey }}
3050
</p>
31-
<span
32-
class="text-sm text-fg-muted group-hover:text-fg inline-flex items-center gap-1 mt-auto"
51+
<a
52+
:href="link.href"
53+
target="_blank"
54+
rel="noopener noreferrer"
55+
class="text-sm text-fg-muted group-hover:text-fg inline-flex items-center gap-1 mt-auto focus-visible:outline-none"
3356
>
34-
{{ $t('about.get_involved.contribute.cta') }}
57+
{{ link.ctaKey }}
3558
<span class="i-carbon:arrow-right rtl-flip w-3 h-3" aria-hidden="true" />
36-
</span>
37-
</a>
38-
39-
<a
40-
:href="socialLinks.discord"
41-
target="_blank"
42-
rel="noopener noreferrer"
43-
class="group grid gap-3 p-4 rounded-lg bg-bg-subtle hover:bg-bg-elevated border border-border hover:border-border-hover transition-all duration-200 sm:grid-rows-subgrid sm:row-span-3"
44-
>
45-
<div class="flex gap-2">
46-
<span class="i-carbon:chat shrink-0 mt-1 w-5 h-5 text-fg" aria-hidden="true" />
47-
<span class="font-medium text-fg">
48-
{{ $t('about.get_involved.community.title') }}
49-
</span>
50-
</div>
51-
<p class="text-sm text-fg-muted leading-relaxed">
52-
{{ $t('about.get_involved.community.description') }}
53-
</p>
54-
<span
55-
class="text-sm text-fg-muted group-hover:text-fg inline-flex items-center gap-1 mt-auto"
56-
>
57-
{{ $t('about.get_involved.community.cta') }}
58-
<span class="i-carbon:arrow-right rtl-flip w-3 h-3" aria-hidden="true" />
59-
</span>
60-
</a>
61-
62-
<a
63-
:href="socialLinks.bluesky"
64-
target="_blank"
65-
rel="noopener noreferrer"
66-
class="group grid gap-3 p-4 rounded-lg bg-bg-subtle hover:bg-bg-elevated border border-border hover:border-border-hover transition-all duration-200 sm:grid-rows-subgrid sm:row-span-3"
67-
>
68-
<div class="flex gap-2">
69-
<span class="i-simple-icons:bluesky shrink-0 mt-1 w-5 h-5 text-fg" aria-hidden="true" />
70-
<span class="font-medium text-fg">
71-
{{ $t('about.get_involved.follow.title') }}
72-
</span>
73-
</div>
74-
<p class="text-sm text-fg-muted leading-relaxed">
75-
{{ $t('about.get_involved.follow.description') }}
76-
</p>
77-
<span
78-
class="text-sm text-fg-muted group-hover:text-fg inline-flex items-center gap-1 mt-auto"
79-
>
80-
{{ $t('about.get_involved.follow.cta') }}
81-
<span class="i-carbon:arrow-right rtl-flip w-3 h-3" aria-hidden="true" />
82-
</span>
83-
</a>
59+
<span class="absolute z-0 inset-0" aria-hidden="true" />
60+
</a>
61+
</div>
8462
</div>
8563
</div>
8664
</template>
Lines changed: 37 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -38,23 +38,49 @@ function getBarWidth(value: FacetValue | null | undefined): number {
3838
return (value.raw / maxValue.value) * 100
3939
}
4040
41-
function getStatusClass(status?: FacetValue['status']): string {
41+
function getStatusClass(status?: FacetValue['status'], hasBar = false): string {
42+
// When there's a bar, only apply text color, not background
43+
if (hasBar) {
44+
switch (status) {
45+
case 'muted':
46+
return 'text-fg-subtle'
47+
default:
48+
return 'text-fg'
49+
}
50+
}
51+
52+
// Original behavior when no bar
4253
switch (status) {
4354
case 'good':
44-
return 'text-emerald-400'
55+
return 'bg-emerald-400/20 px-3 py-0.5 rounded-xl'
4556
case 'info':
46-
return 'text-blue-400'
57+
return 'bg-blue-400/20 px-3 py-0.5 rounded-xl'
4758
case 'warning':
48-
return 'text-amber-400'
59+
return 'bg-amber-400/20 px-3 py-0.5 rounded-xl'
4960
case 'bad':
50-
return 'text-red-400'
61+
return 'bg-red-400/20 px-3 py-0.5 rounded-xl'
5162
case 'muted':
5263
return 'text-fg-subtle'
5364
default:
5465
return 'text-fg'
5566
}
5667
}
5768
69+
function getStatusBarClass(status?: FacetValue['status']): string {
70+
switch (status) {
71+
case 'good':
72+
return 'bg-emerald-500/20'
73+
case 'info':
74+
return 'bg-blue-500/20'
75+
case 'warning':
76+
return 'bg-amber-500/20'
77+
case 'bad':
78+
return 'bg-red-500/20'
79+
default:
80+
return 'bg-fg/5'
81+
}
82+
}
83+
5884
// Check if a specific cell is loading
5985
function isCellLoading(index: number): boolean {
6086
return props.facetLoading || (props.columnLoading?.[index] ?? false)
@@ -80,7 +106,8 @@ function isCellLoading(index: number): boolean {
80106
<!-- Background bar for numeric values -->
81107
<div
82108
v-if="showBar && value && getBarWidth(value) > 0"
83-
class="absolute inset-y-1 inset-is-1 bg-fg/5 rounded-sm transition-all duration-300"
109+
class="absolute inset-y-1 inset-is-1 rounded-sm transition-all duration-300"
110+
:class="getStatusBarClass(value.status)"
84111
:style="{ width: `calc(${getBarWidth(value)}% - 8px)` }"
85112
aria-hidden="true"
86113
/>
@@ -103,7 +130,8 @@ function isCellLoading(index: number): boolean {
103130
<TooltipApp v-if="value.tooltip" :text="value.tooltip" position="top">
104131
<span
105132
class="relative font-mono text-sm text-center tabular-nums cursor-help"
106-
:class="getStatusClass(value.status)"
133+
:class="getStatusClass(value.status, showBar && getBarWidth(value) > 0)"
134+
:data-status="value.status"
107135
>
108136
<!-- Date values use DateTime component for i18n and user settings -->
109137
<DateTime v-if="value.type === 'date'" :datetime="value.display" date-style="medium" />
@@ -113,7 +141,8 @@ function isCellLoading(index: number): boolean {
113141
<span
114142
v-else
115143
class="relative font-mono text-sm text-center tabular-nums"
116-
:class="getStatusClass(value.status)"
144+
:class="getStatusClass(value.status, showBar && getBarWidth(value) > 0)"
145+
:data-status="value.status"
117146
>
118147
<!-- Date values use DateTime component for i18n and user settings -->
119148
<DateTime v-if="value.type === 'date'" :datetime="value.display" date-style="medium" />

0 commit comments

Comments
 (0)