Skip to content

Commit 045d73d

Browse files
committed
Merge branch 'main' into feat-change-i18n-configuration
# Conflicts: # package.json # pnpm-lock.yaml
2 parents 844ac96 + 803a38f commit 045d73d

46 files changed

Lines changed: 2565 additions & 211 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/lunaria.yml

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
name: lunaria
2+
3+
on:
4+
# Trigger the workflow every time a pull request is opened or synchronized at the target `main` branch
5+
pull_request_target:
6+
types: [opened, synchronize]
7+
8+
# Automatically cancel in-progress actions on the same branch
9+
concurrency:
10+
group: ${{ github.workflow }}-${{ github.event_name == 'pull_request_target' && github.head_ref || github.ref }}
11+
cancel-in-progress: true
12+
13+
# Allow this job to clone the repository and comment on the pull request
14+
permissions:
15+
contents: read
16+
pull-requests: write
17+
18+
jobs:
19+
lunaria-overview:
20+
name: Generate Lunaria Overview
21+
runs-on: ubuntu-latest
22+
23+
steps:
24+
- name: Checkout
25+
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
26+
with:
27+
# Necessary for Lunaria to work properly
28+
# Makes the action clone the entire git history
29+
fetch-depth: 0
30+
31+
- run: corepack enable
32+
- uses: actions/setup-node@v6
33+
with:
34+
node-version: lts/*
35+
cache: pnpm
36+
37+
- name: 📦 Install dependencies
38+
run: pnpm install
39+
40+
- name: Generate Lunaria Overview
41+
uses: lunariajs/action@v1-prerelease
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
name: chore
2+
3+
on:
4+
pull_request_target:
5+
types:
6+
- opened
7+
- edited
8+
- synchronize
9+
10+
permissions: {}
11+
12+
jobs:
13+
semantic-pr:
14+
permissions:
15+
contents: read
16+
pull-requests: read # for amannn/action-semantic-pull-request to analyze PRs
17+
statuses: write # for amannn/action-semantic-pull-request to mark status of analyzed PR
18+
if: github.repository == 'npmx-dev/npmx.dev'
19+
runs-on: ubuntu-latest
20+
name: semantic-pr
21+
steps:
22+
- name: Validate PR title
23+
uses: amannn/action-semantic-pull-request@48f256284bd46cdaab1048c3721360e808335d50 # v6.1.1
24+
with:
25+
scopes: |
26+
docs
27+
i18n
28+
deps
29+
subjectPattern: ^(?![A-Z]).+$
30+
subjectPatternError: |
31+
The subject "{subject}" found in the pull request title "{title}"
32+
didn't match the configured pattern. Please ensure that the subject
33+
doesn't start with an uppercase character.
34+
env:
35+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

CONTRIBUTING.md

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -365,13 +365,27 @@ Make sure to read about [Playwright best practices](https://playwright.dev/docs/
365365
4. ensure CI checks pass (lint, type check, tests)
366366
5. request review from maintainers
367367

368-
### Commit messages
368+
### Commit messages and PR titles
369369

370-
Write clear, concise commit messages that explain the "why" behind changes:
370+
Write clear, concise PR titles that explain the "why" behind changes.
371+
372+
We use [Conventional Commits](https://www.conventionalcommits.org/). Since we squash on merge, the PR title becomes the commit message in `main`, so it's important to get it right.
373+
374+
Format: `type(scope): description`
375+
376+
**Types:** `feat`, `fix`, `docs`, `style`, `refactor`, `perf`, `test`, `build`, `ci`, `chore`, `revert`
377+
378+
**Scopes (optional):** `docs`, `i18n`, `deps`
379+
380+
**Examples:**
371381

372382
- `fix: resolve search pagination issue`
373383
- `feat: add package version comparison`
374-
- `docs: update installation instructions`
384+
- `fix(i18n): update French translations`
385+
- `chore(deps): update vite to v6`
386+
387+
> [!NOTE]
388+
> 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.
375389
376390
## Pre-commit hooks
377391

app/components/ClaimPackageModal.vue

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ const connectorModalOpen = shallowRef(false)
160160
<button
161161
type="button"
162162
class="text-fg-subtle hover:text-fg transition-colors duration-200 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-fg/50 rounded"
163-
:aria-label="$t('claim.modal.close')"
163+
:aria-label="$t('common.close')"
164164
@click="open = false"
165165
>
166166
<span class="i-carbon-close block w-5 h-5" aria-hidden="true" />
@@ -203,7 +203,7 @@ const connectorModalOpen = shallowRef(false)
203203
class="flex-1 px-4 py-2 font-mono text-sm text-fg-muted bg-bg-subtle border border-border rounded-md transition-colors duration-200 hover:text-fg hover:border-border-hover focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-fg/50"
204204
@click="open = false"
205205
>
206-
{{ $t('claim.modal.close') }}
206+
{{ $t('common.close') }}
207207
</button>
208208
</div>
209209
</div>
@@ -395,7 +395,7 @@ const connectorModalOpen = shallowRef(false)
395395
class="w-full px-4 py-2 font-mono text-sm text-fg-muted bg-bg-subtle border border-border rounded-md transition-colors duration-200 hover:text-fg hover:border-border-hover focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-fg/50"
396396
@click="open = false"
397397
>
398-
{{ $t('claim.modal.close') }}
398+
{{ $t('common.close') }}
399399
</button>
400400
</div>
401401

@@ -412,7 +412,7 @@ const connectorModalOpen = shallowRef(false)
412412
class="w-full px-4 py-2 font-mono text-sm text-fg-muted bg-bg-subtle border border-border rounded-md transition-colors duration-200 hover:text-fg hover:border-border-hover focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-fg/50"
413413
@click="checkAvailability"
414414
>
415-
{{ $t('claim.modal.retry') }}
415+
{{ $t('common.retry') }}
416416
</button>
417417
</div>
418418
</div>

app/components/ConnectorModal.vue

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ const { isConnected, isConnecting, npmUser, error, hasOperations, connect, disco
66
77
const tokenInput = shallowRef('')
88
const portInput = shallowRef('31415')
9-
const copied = shallowRef(false)
9+
const { copied, copy } = useClipboard({ copiedDuring: 2000 })
1010
1111
async function handleConnect() {
1212
const port = Number.parseInt(portInput.value, 10) || 31415
@@ -26,11 +26,7 @@ function copyCommand() {
2626
if (portInput.value !== '31415') {
2727
command += ` --port ${portInput.value}`
2828
}
29-
navigator.clipboard.writeText(command)
30-
copied.value = true
31-
setTimeout(() => {
32-
copied.value = false
33-
}, 2000)
29+
copy(command)
3430
}
3531
3632
const selectedPM = useSelectedPackageManager()
@@ -83,7 +79,7 @@ watch(open, isOpen => {
8379
<button
8480
type="button"
8581
class="text-fg-subtle hover:text-fg transition-colors duration-200 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-fg/50 rounded"
86-
:aria-label="$t('connector.modal.close')"
82+
:aria-label="$t('common.close')"
8783
@click="open = false"
8884
>
8985
<span class="i-carbon-close block w-5 h-5" aria-hidden="true" />
@@ -162,8 +158,7 @@ watch(open, isOpen => {
162158
type="password"
163159
name="connector-token"
164160
:placeholder="$t('connector.modal.token_placeholder')"
165-
autocomplete="off"
166-
spellcheck="false"
161+
v-bind="noCorrect"
167162
class="w-full px-3 py-2 font-mono text-sm bg-bg-subtle border border-border rounded-md text-fg placeholder:text-fg-subtle transition-colors duration-200 focus:border-border-hover focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-fg/50"
168163
/>
169164
</div>

app/components/OrgMembersPanel.vue

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -327,7 +327,7 @@ watch(lastExecutionTime, () => {
327327
type="search"
328328
name="members-search"
329329
:placeholder="$t('org.members.filter_placeholder')"
330-
autocomplete="off"
330+
v-bind="noCorrect"
331331
class="w-full pl-7 pr-2 py-1.5 font-mono text-sm bg-bg-subtle border border-border rounded text-fg placeholder:text-fg-subtle transition-colors duration-200 focus:border-border-hover focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-fg/50"
332332
/>
333333
</div>
@@ -512,8 +512,7 @@ watch(lastExecutionTime, () => {
512512
type="text"
513513
name="new-member-username"
514514
:placeholder="$t('org.members.username_placeholder')"
515-
autocomplete="off"
516-
spellcheck="false"
515+
v-bind="noCorrect"
517516
class="w-full px-2 py-1.5 font-mono text-sm bg-bg border border-border rounded text-fg placeholder:text-fg-subtle transition-colors duration-200 focus:border-border-hover focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-fg/50"
518517
/>
519518
<div class="flex items-center gap-2">

app/components/OrgTeamsPanel.vue

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -296,7 +296,7 @@ watch(lastExecutionTime, () => {
296296
type="search"
297297
name="teams-search"
298298
:placeholder="$t('org.teams.filter_placeholder')"
299-
autocomplete="off"
299+
v-bind="noCorrect"
300300
class="w-full pl-7 pr-2 py-1.5 font-mono text-sm bg-bg-subtle border border-border rounded text-fg placeholder:text-fg-subtle transition-colors duration-200 focus:border-border-hover focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-fg/50"
301301
/>
302302
</div>
@@ -453,8 +453,7 @@ watch(lastExecutionTime, () => {
453453
type="text"
454454
:name="`add-user-${teamName}`"
455455
:placeholder="$t('org.teams.username_placeholder')"
456-
autocomplete="off"
457-
spellcheck="false"
456+
v-bind="noCorrect"
458457
class="flex-1 px-2 py-1 font-mono text-sm bg-bg-subtle border border-border rounded text-fg placeholder:text-fg-subtle transition-colors duration-200 focus:border-border-hover focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-fg/50"
459458
/>
460459
<button
@@ -510,8 +509,7 @@ watch(lastExecutionTime, () => {
510509
type="text"
511510
name="new-team-name"
512511
:placeholder="$t('org.teams.team_name_placeholder')"
513-
autocomplete="off"
514-
spellcheck="false"
512+
v-bind="noCorrect"
515513
class="flex-1 px-2 py-1.5 font-mono text-sm bg-bg border border-border rounded-r text-fg placeholder:text-fg-subtle transition-colors duration-200 focus:border-border-hover focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-fg/50"
516514
/>
517515
</div>

app/components/PackageDependencies.vue

Lines changed: 52 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,26 @@ const sortedOptionalDependencies = computed(() => {
4848
<template>
4949
<div class="space-y-8">
5050
<!-- Dependencies -->
51-
<section v-if="sortedDependencies.length > 0" aria-labelledby="dependencies-heading">
52-
<h2 id="dependencies-heading" class="text-xs text-fg-subtle uppercase tracking-wider mb-3">
53-
{{ $t('package.dependencies.title', { count: sortedDependencies.length }) }}
51+
<section
52+
id="dependencies"
53+
v-if="sortedDependencies.length > 0"
54+
aria-labelledby="dependencies-heading"
55+
class="scroll-mt-20"
56+
>
57+
<h2
58+
id="dependencies-heading"
59+
class="group text-xs text-fg-subtle uppercase tracking-wider mb-3"
60+
>
61+
<a
62+
href="#dependencies"
63+
class="inline-flex items-center gap-1.5 text-fg-subtle hover:text-fg-muted transition-colors duration-200 no-underline"
64+
>
65+
{{ $t('package.dependencies.title', { count: sortedDependencies.length }) }}
66+
<span
67+
class="i-carbon-link w-3 h-3 block opacity-0 group-hover:opacity-100 transition-opacity duration-200"
68+
aria-hidden="true"
69+
/>
70+
</a>
5471
</h2>
5572
<ul class="space-y-1 list-none m-0 p-0" :aria-label="$t('package.dependencies.list_label')">
5673
<li
@@ -99,12 +116,26 @@ const sortedOptionalDependencies = computed(() => {
99116
</section>
100117

101118
<!-- Peer Dependencies -->
102-
<section v-if="sortedPeerDependencies.length > 0" aria-labelledby="peer-dependencies-heading">
119+
<section
120+
id="peer-dependencies"
121+
v-if="sortedPeerDependencies.length > 0"
122+
aria-labelledby="peer-dependencies-heading"
123+
class="scroll-mt-20"
124+
>
103125
<h2
104126
id="peer-dependencies-heading"
105-
class="text-xs text-fg-subtle uppercase tracking-wider mb-3"
127+
class="group text-xs text-fg-subtle uppercase tracking-wider mb-3"
106128
>
107-
{{ $t('package.peer_dependencies.title', { count: sortedPeerDependencies.length }) }}
129+
<a
130+
href="#peer-dependencies"
131+
class="inline-flex items-center gap-1.5 text-fg-subtle hover:text-fg-muted transition-colors duration-200 no-underline"
132+
>
133+
{{ $t('package.peer_dependencies.title', { count: sortedPeerDependencies.length }) }}
134+
<span
135+
class="i-carbon-link w-3 h-3 block opacity-0 group-hover:opacity-100 transition-opacity duration-200"
136+
aria-hidden="true"
137+
/>
138+
</a>
108139
</h2>
109140
<ul
110141
class="space-y-1 list-none m-0 p-0"
@@ -154,16 +185,27 @@ const sortedOptionalDependencies = computed(() => {
154185

155186
<!-- Optional Dependencies -->
156187
<section
188+
id="optional-dependencies"
157189
v-if="sortedOptionalDependencies.length > 0"
158190
aria-labelledby="optional-dependencies-heading"
191+
class="scroll-mt-20"
159192
>
160193
<h2
161194
id="optional-dependencies-heading"
162-
class="text-xs text-fg-subtle uppercase tracking-wider mb-3"
195+
class="group text-xs text-fg-subtle uppercase tracking-wider mb-3"
163196
>
164-
{{
165-
$t('package.optional_dependencies.title', { count: sortedOptionalDependencies.length })
166-
}}
197+
<a
198+
href="#optional-dependencies"
199+
class="inline-flex items-center gap-1.5 text-fg-subtle hover:text-fg-muted transition-colors duration-200 no-underline"
200+
>
201+
{{
202+
$t('package.optional_dependencies.title', { count: sortedOptionalDependencies.length })
203+
}}
204+
<span
205+
class="i-carbon-link w-3 h-3 block opacity-0 group-hover:opacity-100 transition-opacity duration-200"
206+
aria-hidden="true"
207+
/>
208+
</a>
167209
</h2>
168210
<ul
169211
class="space-y-1 list-none m-0 p-0"

app/components/PackageDownloadAnalytics.vue

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -487,7 +487,9 @@ const config = computed(() => ({
487487
stroke: isDarkMode.value ? '#4A4A4A' : '#a3a3a3',
488488
labels: {
489489
axis: {
490-
yLabel: $t('package.downloads.y_axis_label', { granularity: selectedGranularity.value }),
490+
yLabel: $t('package.downloads.y_axis_label', {
491+
granularity: $t(`package.downloads.granularity_${selectedGranularity.value}`),
492+
}),
491493
xLabel: packageName,
492494
yLabelOffsetX: 12,
493495
fontSize: 24,

app/components/PackageListControls.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ const showFilteredCount = computed(() => {
6666
v-model="filterValue"
6767
type="search"
6868
:placeholder="placeholder ?? $t('package.list.filter_placeholder')"
69-
autocomplete="off"
69+
v-bind="noCorrect"
7070
class="w-full bg-bg-subtle border border-border rounded-lg pl-10 pr-4 py-2 font-mono text-sm text-fg placeholder:text-fg-subtle transition-colors duration-200 focus:(border-border-hover outline-none)"
7171
/>
7272
</div>

0 commit comments

Comments
 (0)