Skip to content

Commit e487292

Browse files
authored
Merge branch 'npmx-dev:main' into feat/changelog-1
2 parents a424459 + b5eb232 commit e487292

File tree

170 files changed

+6718
-3002
lines changed

Some content is hidden

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

170 files changed

+6718
-3002
lines changed

.github/workflows/autofix.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,8 @@ jobs:
3232
- name: 📦 Install dependencies
3333
run: pnpm install
3434

35-
- name: 🎨 Check for non-RTL CSS classes
36-
run: pnpm rtl:check
35+
- name: 🎨 Check for non-RTL/non-a11y CSS classes
36+
run: pnpm lint:css
3737

3838
- name: 🌐 Compare translations
3939
run: pnpm i18n:check

.github/workflows/ci.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ jobs:
8484
run: pnpm install
8585

8686
- name: 🧪 Unit tests
87-
run: pnpm test:unit run --coverage --reporter=junit --outputFile=test-report.junit.xml
87+
run: pnpm test:unit run --coverage --reporter=default --reporter=junit --outputFile=test-report.junit.xml
8888

8989
- name: ⬆︎ Upload test results to Codecov
9090
if: ${{ !cancelled() }}
@@ -115,7 +115,7 @@ jobs:
115115
run: pnpm playwright install chromium-headless-shell
116116

117117
- name: 🧪 Component tests
118-
run: pnpm test:nuxt run --coverage --reporter=junit --outputFile=test-report.junit.xml
118+
run: pnpm test:nuxt run --coverage --reporter=default --reporter=junit --outputFile=test-report.junit.xml
119119

120120
- name: ⬆︎ Upload coverage reports to Codecov
121121
uses: codecov/codecov-action@671740ac38dd9b0130fbe1cec585b89eea48d3de # v5

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,5 +40,7 @@ test-results/
4040
# generated files
4141
shared/types/lexicons
4242

43+
**/__screenshots__/**
44+
4345
# output
4446
.vercel

.nuxtrc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
setups.@nuxt/test-utils="3.23.0"
1+
setups.@nuxt/test-utils="4.0.0"

app/assets/main.css

Lines changed: 37 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,14 @@
2727
--accent: var(--accent-color, oklch(1 0 0));
2828
--accent-muted: var(--accent-color, oklch(0.922 0 0));
2929

30+
/* accent colors */
31+
--swatch-coral: oklch(0.704 0.177 14.75);
32+
--swatch-amber: oklch(0.828 0.165 84.429);
33+
--swatch-emerald: oklch(0.792 0.153 166.95);
34+
--swatch-sky: oklch(0.787 0.128 230.318);
35+
--swatch-violet: oklch(0.78 0.148 286.067);
36+
--swatch-magenta: oklch(0.78 0.15 330);
37+
3038
/* syntax highlighting colors */
3139
--syntax-fn: oklch(0.727 0.137 299.149);
3240
--syntax-str: oklch(0.829 0.088 252.458);
@@ -89,6 +97,14 @@
8997
--accent: var(--accent-color, oklch(0.145 0 0));
9098
--accent-muted: var(--accent-color, oklch(0.205 0 0));
9199

100+
/* accent colors */
101+
--swatch-coral: oklch(0.7 0.19 14.75);
102+
--swatch-amber: oklch(0.8 0.25 84.429);
103+
--swatch-emerald: oklch(0.7 0.17 166.95);
104+
--swatch-sky: oklch(0.7 0.15 230.318);
105+
--swatch-violet: oklch(0.7 0.17 286.067);
106+
--swatch-magenta: oklch(0.75 0.18 330);
107+
92108
--syntax-fn: oklch(0.502 0.188 294.988);
93109
--syntax-str: oklch(0.425 0.152 252);
94110
--syntax-kw: oklch(0.588 0.193 20.469);
@@ -155,12 +171,32 @@
155171
}
156172
}
157173

174+
/*
175+
* Forced Colors Mode (WHCM) Override for Icons
176+
*
177+
* By default, `forced-color-adjust: preserve-parent-color` (from UnoConfig) works fine
178+
* for most icons as they inherit the correct text color.
179+
*
180+
* However, if icons disappear in specific contexts (e.g., inside buttons with
181+
* complex backgrounds or transparent states), uncomment the following block
182+
* to enforce visibility using `CanvasText`.
183+
*/
184+
/*
185+
@media (forced-colors: active) {
186+
[class^='i-'],
187+
[class*=' i-'] {
188+
forced-color-adjust: none !important;
189+
color: CanvasText !important;
190+
}
191+
}
192+
*/
193+
158194
html {
195+
@apply scroll-pt-20;
159196
-webkit-font-smoothing: antialiased;
160197
-moz-osx-font-smoothing: grayscale;
161198
text-rendering: optimizeLegibility;
162199
/* Offset for fixed header - otherwise anchor headers are cutted */
163-
scroll-padding-top: 5rem;
164200
scrollbar-gutter: stable;
165201
}
166202

@@ -200,11 +236,6 @@ dd {
200236
margin: 0;
201237
}
202238

203-
/* Reset button styles */
204-
button {
205-
cursor: pointer;
206-
}
207-
208239
/* Selection */
209240
::selection {
210241
background-color: var(--fg-muted);

app/components/AppFooter.vue

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
<script setup lang="ts">
22
const route = useRoute()
33
const isHome = computed(() => route.name === 'index')
4+
5+
const modalRef = useTemplateRef('modalRef')
6+
const showModal = () => modalRef.value?.showModal?.()
47
</script>
58

69
<template>
@@ -33,6 +36,73 @@ const isHome = computed(() => route.name === 'index')
3336
<LinkBase to="https://chat.npmx.dev">
3437
{{ $t('footer.chat') }}
3538
</LinkBase>
39+
40+
<button
41+
type="button"
42+
class="group inline-flex gap-x-1 items-center justify-center underline-offset-[0.2rem] underline decoration-1 decoration-fg/30 font-mono text-fg hover:(decoration-accent text-accent) focus-visible:(decoration-accent text-accent) transition-colors duration-200"
43+
@click.prevent="showModal"
44+
aria-haspopup="dialog"
45+
>
46+
{{ $t('footer.keyboard_shortcuts') }}
47+
</button>
48+
49+
<Modal
50+
ref="modalRef"
51+
:modalTitle="$t('footer.keyboard_shortcuts')"
52+
class="w-auto max-w-lg"
53+
>
54+
<p class="mb-2 font-mono text-fg-subtle">
55+
{{ $t('shortcuts.section.global') }}
56+
</p>
57+
<ul class="mb-6 flex flex-col gap-2">
58+
<li class="flex gap-2 items-center">
59+
<kbd class="kbd">/</kbd>
60+
<span>{{ $t('shortcuts.focus_search') }}</span>
61+
</li>
62+
<li class="flex gap-2 items-center">
63+
<kbd class="kbd">?</kbd>
64+
<span>{{ $t('shortcuts.show_kbd_hints') }}</span>
65+
</li>
66+
<li class="flex gap-2 items-center">
67+
<kbd class="kbd">,</kbd>
68+
<span>{{ $t('shortcuts.settings') }}</span>
69+
</li>
70+
<li class="flex gap-2 items-center">
71+
<kbd class="kbd">c</kbd>
72+
<span>{{ $t('shortcuts.compare') }}</span>
73+
</li>
74+
</ul>
75+
<p class="mb-2 font-mono text-fg-subtle">
76+
{{ $t('shortcuts.section.search') }}
77+
</p>
78+
<ul class="mb-6 flex flex-col gap-2">
79+
<li class="flex gap-2 items-center">
80+
<kbd class="kbd">↑</kbd>/<kbd class="kbd">↓</kbd>
81+
<span>{{ $t('shortcuts.navigate_results') }}</span>
82+
</li>
83+
<li class="flex gap-2 items-center">
84+
<kbd class="kbd">Enter</kbd>
85+
<span>{{ $t('shortcuts.go_to_result') }}</span>
86+
</li>
87+
</ul>
88+
<p class="mb-2 font-mono text-fg-subtle">
89+
{{ $t('shortcuts.section.package') }}
90+
</p>
91+
<ul class="mb-6 flex flex-col gap-2">
92+
<li class="flex gap-2 items-center">
93+
<kbd class="kbd">.</kbd>
94+
<span>{{ $t('shortcuts.open_code_view') }}</span>
95+
</li>
96+
<li class="flex gap-2 items-center">
97+
<kbd class="kbd">d</kbd>
98+
<span>{{ $t('shortcuts.open_docs') }}</span>
99+
</li>
100+
<li class="flex gap-2 items-center">
101+
<kbd class="kbd">c</kbd>
102+
<span>{{ $t('shortcuts.compare_from_package') }}</span>
103+
</li>
104+
</ul>
105+
</Modal>
36106
</div>
37107
</div>
38108
<p class="text-xs text-fg-muted text-center sm:text-start m-0">
@@ -42,3 +112,9 @@ const isHome = computed(() => route.name === 'index')
42112
</div>
43113
</footer>
44114
</template>
115+
116+
<style scoped>
117+
.kbd {
118+
@apply items-center justify-center text-sm text-fg bg-bg-muted border border-border rounded px-2;
119+
}
120+
</style>

app/components/AppHeader.vue

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -122,8 +122,12 @@ onKeyStroke(
122122

123123
<!-- Center: Search bar + nav items -->
124124
<div
125-
class="flex-1 flex items-center justify-center md:gap-6"
126-
:class="{ 'hidden sm:flex': !isSearchExpanded }"
125+
class="flex-1 flex items-center md:gap-6"
126+
:class="{
127+
'hidden sm:flex': !isSearchExpanded,
128+
'justify-end': isOnHomePage,
129+
'justify-center': !isOnHomePage,
130+
}"
127131
>
128132
<!-- Search bar (hidden on mobile unless expanded) -->
129133
<HeaderSearchBox

app/components/CollapsibleSection.vue

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
<script setup lang="ts">
22
import { shallowRef, computed } from 'vue'
3+
import { LinkBase } from '#components'
34
45
interface Props {
56
title: string
@@ -18,7 +19,6 @@ const appSettings = useSettings()
1819
1920
const buttonId = `${props.id}-collapsible-button`
2021
const contentId = `${props.id}-collapsible-content`
21-
const headingId = `${props.id}-heading`
2222
2323
const isOpen = shallowRef(true)
2424
@@ -75,11 +75,10 @@ useHead({
7575
</script>
7676

7777
<template>
78-
<section class="scroll-mt-20" :data-anchor-id="id">
78+
<section :id="id" :data-anchor-id="id" class="scroll-mt-20 xl:scroll-mt-0">
7979
<div class="flex items-center justify-between mb-3 px-1">
8080
<component
8181
:is="headingLevel"
82-
:id="headingId"
8382
class="group text-xs text-fg-subtle uppercase tracking-wider flex items-center gap-2"
8483
>
8584
<button
@@ -104,17 +103,9 @@ useHead({
104103
/>
105104
</button>
106105

107-
<a
108-
:href="`#${id}`"
109-
class="inline-flex items-center gap-1.5 text-fg-subtle hover:text-fg-muted transition-colors duration-200 no-underline"
110-
>
111-
<span v-if="icon" :class="icon" aria-hidden="true" />
106+
<LinkBase :to="`#${id}`" class="">
112107
{{ title }}
113-
<span
114-
class="i-carbon:link w-3 h-3 opacity-0 group-hover:opacity-100 transition-opacity duration-200"
115-
aria-hidden="true"
116-
/>
117-
</a>
108+
</LinkBase>
118109
</component>
119110

120111
<!-- Actions slot for buttons or other elements -->

app/components/ColumnPicker.vue

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -102,11 +102,7 @@ function handleReset() {
102102
v-for="column in toggleableColumns"
103103
:key="column.id"
104104
class="flex gap-2 items-center px-3 py-2 transition-colors duration-200"
105-
:class="
106-
column.disabled
107-
? 'opacity-50 cursor-not-allowed'
108-
: 'hover:bg-bg-muted cursor-pointer'
109-
"
105+
:class="column.disabled ? 'opacity-50 cursor-not-allowed' : 'hover:bg-bg-muted'"
110106
>
111107
<input
112108
type="checkbox"

app/components/Compare/FacetSelector.vue

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,12 @@ function isCategoryNoneSelected(category: string): boolean {
2929
<div v-for="category in categoryOrder" :key="category">
3030
<!-- Category header with all/none buttons -->
3131
<div class="flex items-center gap-2 mb-2">
32-
<span class="text-[10px] text-fg-subtle uppercase tracking-wider">
32+
<span class="text-3xs text-fg-subtle uppercase tracking-wider">
3333
{{ getCategoryLabel(category) }}
3434
</span>
3535
<button
3636
type="button"
37-
class="text-[10px] transition-colors focus-visible:outline-none focus-visible:underline focus-visible:underline-accent"
37+
class="text-3xs transition-colors focus-visible:outline-none focus-visible:underline focus-visible:underline-accent"
3838
:class="
3939
isCategoryAllSelected(category)
4040
? 'text-fg-muted'
@@ -48,10 +48,10 @@ function isCategoryNoneSelected(category: string): boolean {
4848
>
4949
{{ $t('compare.facets.all') }}
5050
</button>
51-
<span class="text-[10px] text-fg-muted/40">/</span>
51+
<span class="text-2xs text-fg-muted/40">/</span>
5252
<button
5353
type="button"
54-
class="text-[10px] transition-colors focus-visible:outline-none focus-visible:underline focus-visible:underline-accent"
54+
class="text-3xs transition-colors focus-visible:outline-none focus-visible:underline focus-visible:underline-accent"
5555
:class="
5656
isCategoryNoneSelected(category)
5757
? 'text-fg-muted'
@@ -94,7 +94,7 @@ function isCategoryNoneSelected(category: string): boolean {
9494
aria-hidden="true"
9595
/>
9696
{{ facet.label }}
97-
<span v-if="facet.comingSoon" class="text-[9px]"
97+
<span v-if="facet.comingSoon" class="text-4xs"
9898
>({{ $t('compare.facets.coming_soon') }})</span
9999
>
100100
</button>

0 commit comments

Comments
 (0)