Skip to content

Commit 669063c

Browse files
committed
merge: resolve conflicts with main
- Combined keyboard shortcuts (settings, compare, blog navigation) - Merged package.json dependencies (kept main versions, added blog dependencies) - Added presetTypography and presetRtl to uno config
2 parents 3ad742b + 0f945f8 commit 669063c

File tree

248 files changed

+16084
-3406
lines changed

Some content is hidden

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

248 files changed

+16084
-3406
lines changed

.github/workflows/ci.yml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,11 @@ on:
1111
branches:
1212
- main
1313

14+
# cancel in-progress runs on new commits to same PR (gitub.event.number)
15+
concurrency:
16+
group: ${{ github.workflow }}-${{ github.event.number || github.sha }}
17+
cancel-in-progress: true
18+
1419
permissions:
1520
contents: read
1621

@@ -134,4 +139,4 @@ jobs:
134139
run: pnpm install
135140

136141
- name: 🔍 Check for unused code
137-
run: pnpm knip:production
142+
run: pnpm knip

.oxfmtrc.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"$schema": "./node_modules/oxfmt/configuration_schema.json",
2+
"$schema": "https://unpkg.com/oxfmt/configuration_schema.json",
33
"semi": false,
44
"singleQuote": true,
55
"arrowParens": "avoid",

.oxlintrc.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"$schema": "./node_modules/oxlint/configuration_schema.json",
2+
"$schema": "https://unpkg.com/oxlint/configuration_schema.json",
33
"plugins": ["unicorn", "typescript", "oxc", "vue", "vitest"],
44
"categories": {
55
"correctness": "error",

.vscode/extensions.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
{
2-
"recommendations": ["oxc.oxc-vscode", "Vue.volar", "lokalise.i18n-ally"]
2+
"recommendations": ["oxc.oxc-vscode", "Vue.volar", "lokalise.i18n-ally", "antfu.unocss"]
33
}

CONTRIBUTING.md

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,12 @@ The connector will check your npm authentication, generate a connection token, a
105105

106106
## Code style
107107

108+
When committing changes, try to keep an eye out for unintended formatting updates. These can make a pull request look noisier than it really is and slow down the review process. Sometimes IDEs automatically reformat files on save, which can unintentionally introduce extra changes.
109+
110+
To help with this, the project uses `oxfmt` to handle formatting via a pre-commit hook. The hook will automatically reformat files when needed. If something can’t be fixed automatically, it will let you know what needs to be updated before you can commit.
111+
112+
If you want to get ahead of any formatting issues, you can also run `pnpm lint:fix` before committing to fix formatting across the whole project.
113+
108114
### Typescript
109115

110116
- We care about good types – never cast things to `any` 💪
@@ -301,6 +307,14 @@ For example to check if all Japanese translation keys are up-to-date, run:
301307
pnpm i18n:check ja-JP
302308
```
303309

310+
To automatically add missing keys with English placeholders, use `--fix`:
311+
312+
```bash
313+
pnpm i18n:check:fix fr-FR
314+
```
315+
316+
This will add missing keys with `"EN TEXT TO REPLACE: {english text}"` as placeholder values, making it easier to see what needs translation.
317+
304318
#### Country variants (advanced)
305319

306320
Most languages only need a single locale file. Country variants are only needed when you want to support regional differences (e.g., `es-ES` for Spain vs `es-419` for Latin America).
@@ -361,13 +375,17 @@ We recommend the [i18n-ally](https://marketplace.visualstudio.com/items?itemName
361375

362376
The extension is included in our workspace recommendations, so VSCode should prompt you to install it.
363377

364-
### Formatting with locale
378+
### Formatting numbers and dates
365379

366-
When formatting numbers or dates that should respect the user's locale, pass the locale:
380+
Use vue-i18n's built-in formatters for locale-aware formatting:
367381

368-
```typescript
369-
const { locale } = useI18n()
370-
const formatted = formatNumber(12345, locale.value) // "12,345" in en-US
382+
```vue
383+
<template>
384+
<p>{{ $n(12345) }}</p>
385+
<!-- "12,345" in en-US, "12 345" in fr-FR -->
386+
<p>{{ $d(new Date()) }}</p>
387+
<!-- locale-aware date -->
388+
</template>
371389
```
372390

373391
## Testing
@@ -391,10 +409,10 @@ describe('featureName', () => {
391409
392410
### Component accessibility tests
393411

394-
All new components should have a basic accessibility test in `test/nuxt/components.spec.ts`. These tests use [axe-core](https://github.com/dequelabs/axe-core) to catch common accessibility violations.
412+
All Vue components should have accessibility tests in `test/nuxt/a11y.spec.ts`. These tests use [axe-core](https://github.com/dequelabs/axe-core) to catch common accessibility violations and run in a real browser environment via Playwright.
395413

396414
```typescript
397-
import MyComponent from '~/components/MyComponent.vue'
415+
import { MyComponent } from '#components'
398416

399417
describe('MyComponent', () => {
400418
it('should have no accessibility violations', async () => {
@@ -411,6 +429,8 @@ describe('MyComponent', () => {
411429

412430
The `runAxe` helper handles DOM isolation and disables page-level rules that don't apply to isolated component testing.
413431

432+
A coverage test in `test/unit/a11y-component-coverage.spec.ts` ensures all components are either tested or explicitly skipped with justification. When you add a new component, this test will fail until you add accessibility tests for it.
433+
414434
> [!IMPORTANT]
415435
> Just because axe-core doesn't find any obvious issues, it does not mean a component is accessible. Please do additional checks and use best practices.
416436

LICENSE

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
MIT License
22

3-
Copyright (c) 2026 Daniel Roe
3+
Copyright (c) 2026 npmx team and contributors
44

55
Permission is hereby granted, free of charge, to any person obtaining a copy
66
of this software and associated documentation files (the "Software"), to deal

app/app.vue

Lines changed: 38 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
<script setup lang="ts">
22
import type { Directions } from '@nuxtjs/i18n'
33
import { useEventListener } from '@vueuse/core'
4+
import { isEditableElement } from '~/utils/input'
45
56
const route = useRoute()
67
const router = useRouter()
@@ -39,14 +40,9 @@ if (import.meta.server) {
3940
// "/" focuses search or navigates to search page
4041
// "?" highlights all keyboard shortcut elements
4142
function handleGlobalKeydown(e: KeyboardEvent) {
42-
const target = e.target as HTMLElement
43-
44-
const isEditableTarget =
45-
target.tagName === 'INPUT' || target.tagName === 'TEXTAREA' || target.isContentEditable
43+
if (isEditableElement(e.target)) return
4644
47-
if (isEditableTarget) return
48-
49-
if (e.key === '/') {
45+
if (isKeyWithoutModifiers(e, '/')) {
5046
e.preventDefault()
5147
5248
// Try to find and focus search input on current page
@@ -62,7 +58,7 @@ function handleGlobalKeydown(e: KeyboardEvent) {
6258
router.push('/search')
6359
}
6460
65-
if (e.key === '?') {
61+
if (isKeyWithoutModifiers(e, '?')) {
6662
e.preventDefault()
6763
showKbdHints.value = true
6864
}
@@ -72,9 +68,20 @@ function handleGlobalKeyup() {
7268
showKbdHints.value = false
7369
}
7470
71+
/* A hack to get light dismiss to work in safari because it does not support closedby="any" yet */
72+
// https://codepen.io/paramagicdev/pen/gbYompq
73+
// see: https://github.com/npmx-dev/npmx.dev/pull/522#discussion_r2749978022
74+
function handleModalLightDismiss(e: MouseEvent) {
75+
const target = e.target as HTMLElement
76+
if (target.tagName === 'DIALOG' && target.hasAttribute('open')) {
77+
;(target as HTMLDialogElement).close()
78+
}
79+
}
80+
7581
if (import.meta.client) {
7682
useEventListener(document, 'keydown', handleGlobalKeydown)
7783
useEventListener(document, 'keyup', handleGlobalKeyup)
84+
useEventListener(document, 'click', handleModalLightDismiss)
7885
}
7986
</script>
8087

@@ -95,6 +102,29 @@ if (import.meta.client) {
95102
</div>
96103
</template>
97104

105+
<style scoped>
106+
/* Skip link */
107+
.skip-link {
108+
position: fixed;
109+
top: -100%;
110+
inset-inline-start: 0;
111+
padding: 0.5rem 1rem;
112+
background: var(--fg);
113+
color: var(--bg);
114+
font-size: 0.875rem;
115+
z-index: 100;
116+
transition: top 0.2s ease;
117+
}
118+
119+
.skip-link:hover {
120+
color: var(--bg);
121+
text-decoration: underline;
122+
}
123+
.skip-link:focus {
124+
top: 0;
125+
}
126+
</style>
127+
98128
<style>
99129
/* Keyboard shortcut highlight on "?" key press */
100130
kbd {

0 commit comments

Comments
 (0)