Skip to content

Commit 7674b61

Browse files
authored
Merge branch 'main' into lino/add-module-replacements
2 parents 34280db + 6a5d286 commit 7674b61

113 files changed

Lines changed: 11195 additions & 641 deletions

File tree

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: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,9 @@ jobs:
1717
runs-on: ubuntu-latest
1818

1919
steps:
20-
- uses: actions/checkout@v6
20+
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
2121
- run: corepack enable
22-
- uses: actions/setup-node@v6
22+
- uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
2323
with:
2424
node-version: lts/*
2525
cache: 'pnpm'
@@ -30,6 +30,9 @@ jobs:
3030
- name: 📦 Install browsers
3131
run: pnpm playwright install
3232

33+
- name: 🌍 Update lunaria data
34+
run: pnpm build:lunaria
35+
3336
- name: 🔠 Fix lint errors
3437
run: pnpm lint:fix
3538

.github/workflows/ci.yml

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,9 @@ jobs:
1919
runs-on: ubuntu-latest
2020

2121
steps:
22-
- uses: actions/checkout@v6
22+
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
2323
- run: corepack enable
24-
- uses: actions/setup-node@v6
24+
- uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
2525
with:
2626
node-version: lts/*
2727
cache: pnpm
@@ -36,9 +36,9 @@ jobs:
3636
runs-on: ubuntu-latest
3737

3838
steps:
39-
- uses: actions/checkout@v6
39+
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
4040
- run: corepack enable
41-
- uses: actions/setup-node@v6
41+
- uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
4242
with:
4343
node-version: lts/*
4444
cache: pnpm
@@ -64,9 +64,9 @@ jobs:
6464
image: mcr.microsoft.com/playwright:v1.57.0-noble
6565

6666
steps:
67-
- uses: actions/checkout@v6
67+
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
6868
- run: corepack enable
69-
- uses: actions/setup-node@v6
69+
- uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
7070
with:
7171
node-version: lts/*
7272
cache: pnpm
@@ -81,9 +81,9 @@ jobs:
8181
runs-on: ubuntu-latest
8282

8383
steps:
84-
- uses: actions/checkout@v6
84+
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
8585
- run: corepack enable
86-
- uses: actions/setup-node@v6
86+
- uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
8787
with:
8888
node-version: lts/*
8989
cache: pnpm
@@ -98,3 +98,20 @@ jobs:
9898
run: ./scripts/lighthouse-a11y.sh
9999
env:
100100
LHCI_GITHUB_APP_TOKEN: ${{ secrets.LHCI_GITHUB_APP_TOKEN }}
101+
102+
knip:
103+
runs-on: ubuntu-latest
104+
105+
steps:
106+
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
107+
- run: corepack enable
108+
- uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
109+
with:
110+
node-version: lts/*
111+
cache: pnpm
112+
113+
- name: 📦 Install dependencies
114+
run: pnpm install
115+
116+
- name: 🔍 Check for unused code
117+
run: pnpm knip:production

.github/workflows/lunaria.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,14 @@ jobs:
2222

2323
steps:
2424
- name: Checkout
25-
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
25+
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
2626
with:
2727
# Necessary for Lunaria to work properly
2828
# Makes the action clone the entire git history
2929
fetch-depth: 0
3030

3131
- run: corepack enable
32-
- uses: actions/setup-node@v6
32+
- uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
3333
with:
3434
node-version: lts/*
3535
cache: pnpm

.github/workflows/provenance.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ jobs:
1616
check-provenance:
1717
runs-on: ubuntu-latest
1818
steps:
19-
- uses: actions/checkout@v6
19+
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
2020
with:
2121
fetch-depth: 0
2222
- name: Check provenance downgrades

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,3 +36,6 @@ test-results/
3636

3737
# Lighthouse
3838
.lighthouseci
39+
40+
# generated files
41+
shared/types/lexicons

CONTRIBUTING.md

Lines changed: 53 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -208,20 +208,70 @@ const props = defineProps<{
208208

209209
Ideally, extract utilities into separate files so they can be unit tested. 🙏
210210

211+
## RTL Support
212+
213+
We support `right-to-left` languages, we need to make sure that the UI is working correctly in both directions.
214+
215+
Simple approach used by most websites of relying on direction set in HTML element does not work because direction for various items, such as timeline, does not always match direction set in HTML.
216+
217+
We've added some `UnoCSS` utilities styles to help you with that:
218+
219+
- Do not use `left/right` padding and margin: for example `pl-1`. Use `padding-inline-start/end` instead. So `pl-1` should be `ps-1`, `pr-1` should be `pe-1`. The same rules apply to margin.
220+
- Do not use `rtl-` classes, such as `rtl-left-0`.
221+
- For icons that should be rotated for RTL, add `class="rtl-flip"`. This can only be used for icons outside of elements with `dir="auto"`.
222+
- For absolute positioned elements, don't use `left/right`: for example `left-0`. Use `inset-inline-start/end` instead. `UnoCSS` shortcuts are `inset-is` for `inset-inline-start` and `inset-ie` for `inset-inline-end`. Example: `left-0` should be replaced with `inset-is-0`.
223+
- If you need to change the border radius for an entire left or right side, use `border-inline-start/end`. `UnoCSS` shortcuts are `rounded-is` for left side, `rounded-ie` for right side. Example: `rounded-l-5` should be replaced with `rounded-ie-5`.
224+
- If you need to change the border radius for one corner, use `border-start-end-radius` and similar rules. `UnoCSS` shortcuts are `rounded` + top/bottom as either `-bs` (top) or `-be` (bottom) + left/right as either `-is` (left) or `-ie` (right). Example: `rounded-tl-0` should be replaced with `rounded-bs-is-0`.
225+
211226
## Localization (i18n)
212227

213228
npmx.dev uses [@nuxtjs/i18n](https://i18n.nuxtjs.org/) for internationalization. We aim to make the UI accessible to users in their preferred language.
214229

215230
### Approach
216231

217232
- All user-facing strings should use translation keys via `$t()` in templates and script
218-
- Translation files live in `i18n/locales/` (e.g., `en.json`)
219-
- We use the `no_prefix` strategy (no `/en/` or `/fr/` in URLs)
233+
- Translation files live in `i18n/locales/` (e.g., `en-US.json`)
234+
- We use the `no_prefix` strategy (no `/en-US/` or `/fr-FR/` in URLs)
220235
- Locale preference is stored in cookies and respected on subsequent visits
221236

237+
### Adding a new locale
238+
239+
We are using localization using country variants (ISO-6391) via [multiple translation files](https://i18n.nuxtjs.org/docs/guide/lazy-load-translations#multiple-files-lazy-loading) to avoid repeating every key per country.
240+
241+
The [config/i18n.ts](./config/i18n.ts) configuration file will be used to register the new locale:
242+
243+
- `countryLocaleVariants` object will be used to register the country variants
244+
- `locales` object will be used to link the supported locales (country and single one)
245+
- `buildLocales` function will build the target locales
246+
247+
To register a new locale:
248+
249+
- for a single country, your JSON file should include the language and the country in the name (for example, `pl-PL.json`) and register the info at `locales` object
250+
- for multiple country variants, you need to add the default language JSON file (for example for Spanish, `es.json`) and one of the country variants (for example for Spanish for Spain, `es-ES.json`); register the language at `countryLocaleVariants` object adding the country variants with the JSON country file and register the language at `locales` object using the language JSON file (check how we register `es`, `es-ES` and `es-419` in [config/i18n.ts](./config/i18n.ts))
251+
252+
The country file should contain will contain only the translations that differ from the language JSON file, Vue I18n will merge the messages for us.
253+
254+
To add a new locale:
255+
256+
1. Add a new file at [locales](./i18n/locales) folder with the language code as the filename.
257+
2. Copy [en](./i18n/locales/en.json) and translate the strings
258+
3. Add the language to the `locales` array in [config/i18n.ts](./config/i18n.ts), below `en` and `ar`:
259+
- If your language has multiple country variants, add the generic one for language only (only if there are a lot of common entries, you can always add it as a new one)
260+
- Add all country variants in [country variants object](./config/i18n.ts)
261+
- Add all country variants files with empty `messages` object: `{}`
262+
- Translate the strings in the generic language file
263+
- Later, when anyone wants to add the corresponding translations for the country variant, just override any entry in the corresponding file: you can see an example with `es` variants.
264+
- If the generic language already exists:
265+
- If the translation doesn't differ from the generic language, then add the corresponding translations in the corresponding file
266+
- If the translation differs from the generic language, then add the corresponding translations in the corresponding file and remove it from the country variants entry
267+
4. If the language is `right-to-left`, add `dir` option with `rtl` value, for example, for [ar](./config/i18n.ts)
268+
5. If the language requires special pluralization rules, add `pluralRule` callback option, for example, for [ar](./config/i18n.ts)
269+
270+
Check [Pluralization rule callback](https://vue-i18n.intlify.dev/guide/essentials/pluralization.html#custom-pluralization) for more info.
271+
222272
### Adding translations
223273

224-
1. Add your translation key to `i18n/locales/en.json` first (English is the source of truth)
274+
1. Add your translation key to `i18n/locales/en.json` first (American English is the source of truth)
225275
2. Use the key in your component:
226276

227277
```vue
@@ -267,22 +317,6 @@ We recommend the [i18n-ally](https://marketplace.visualstudio.com/items?itemName
267317

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

270-
### Adding a new locale
271-
272-
1. Create a new JSON file in `i18n/locales/` (e.g., `fr.json`)
273-
2. Add the locale to `nuxt.config.ts`:
274-
275-
```typescript
276-
i18n: {
277-
locales: [
278-
{ code: 'en', language: 'en-US', name: 'English', file: 'en.json' },
279-
{ code: 'fr', language: 'fr-FR', name: 'Francais', file: 'fr.json' },
280-
],
281-
}
282-
```
283-
284-
3. Translate all keys from `en.json`
285-
286320
### Formatting with locale
287321

288322
When formatting numbers or dates that should respect the user's locale, pass the locale:

README.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,3 +159,13 @@ If you're building something cool, let us know! 🙏
159159
Made with ❤️
160160

161161
Published under [MIT License](./LICENSE).
162+
163+
## Star History
164+
165+
<a href="https://www.star-history.com/#npmx-dev/npmx.dev&type=date&legend=top-left">
166+
<picture>
167+
<source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/svg?repos=npmx-dev/npmx.dev&type=date&theme=dark&legend=top-left" />
168+
<source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/svg?repos=npmx-dev/npmx.dev&type=date&legend=top-left" />
169+
<img alt="Star History Chart" src="https://api.star-history.com/svg?repos=npmx-dev/npmx.dev&type=date&legend=top-left" />
170+
</picture>
171+
</a>

app/app.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ if (import.meta.client) {
5050

5151
<template>
5252
<div class="min-h-screen flex flex-col bg-bg text-fg">
53-
<a href="#main-content" class="skip-link font-mono">Skip to main content</a>
53+
<a href="#main-content" class="skip-link font-mono">{{ $t('common.skip_link') }}</a>
5454

5555
<AppHeader :show-logo="!isHomepage" />
5656

app/assets/main.css

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,10 @@ html {
8080
}
8181
}
8282

83+
html[dir='rtl'] .rtl-flip {
84+
transform: scale(-1, 1);
85+
}
86+
8387
body {
8488
margin: 0;
8589
background-color: var(--bg);

app/components/AccentColorPicker.vue

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ const { accentColors, selectedAccentColor, setAccentColor } = useAccentColor()
55
</script>
66

77
<template>
8-
<div role="listbox" aria-label="Accent colors" class="flex items-center gap-4">
8+
<div role="listbox" :aria-label="$t('settings.accent_colors')" class="flex items-center gap-4">
99
<button
1010
v-for="color in accentColors"
1111
:key="color.id"
@@ -19,7 +19,7 @@ const { accentColors, selectedAccentColor, setAccentColor } = useAccentColor()
1919
/>
2020
<button
2121
type="button"
22-
aria-label="Clear accent color"
22+
:aria-label="$t('settings.clear_accent')"
2323
class="size-6 rounded-full transition-transform duration-150 motion-safe:hover:scale-110 focus-ring flex items-center justify-center bg-accent-fallback"
2424
@click="setAccentColor(null)"
2525
>

0 commit comments

Comments
 (0)