Skip to content

Commit 15db64a

Browse files
feat: useLinkProps hook
1 parent ef44366 commit 15db64a

47 files changed

Lines changed: 1219 additions & 87 deletions

Some content is hidden

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

.eslintignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package.json
33
playwright.config.ts
44
rollup.config.*
55
.eslintrc.cjs
6+
scripts
67
*.test.ts
78
*.test.tsx
89
*.spec.ts

.eslintrc.cjs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,5 +64,11 @@ module.exports = {
6464
'@typescript-eslint/no-unused-vars': 'warn',
6565
},
6666
},
67+
{
68+
// `tsconfig.json` excludes `tests`, so type-aware parsing cannot reach
69+
// these — without this they are a parsing error, not a lint result.
70+
files: ['tests/**/*.ts'],
71+
parserOptions: { project: null },
72+
},
6773
],
6874
};

.github/workflows/tests.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,9 @@ jobs:
5050
# run: npm run test:exports
5151

5252
- name: Unit tests
53-
run: pnpm exec tsc --noEmit && pnpm exec vitest --run --coverage
53+
# Through wireit: the examples import `state-in-url`, so the typecheck
54+
# needs a built `dist/`, and `tsc` depends on `build`.
55+
run: pnpm run tsc && pnpm exec vitest --run --coverage
5456
- name: Run codacy-coverage-reporter
5557
uses: codacy/codacy-coverage-reporter-action@89d6c85cfafaec52c72b6c5e8b2878d33104c699 # v1.3.0
5658
continue-on-error: true

README.es.md

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<!-- i18n:start -->
22
[English](./README.md) · [简体中文](./README.zh-CN.md) · [日本語](./README.ja.md) · [한국어](./README.ko.md) · [Русский](./README.ru.md) · Español · [Português (BR)](./README.pt-BR.md) · [Français](./README.fr.md) · [Tiếng Việt](./README.vi.md)
3-
<!-- i18n:meta locale=es source=README.md source-blob=01b5b4f72aa3c8871c185cfce21c6d696edb847b status=translated -->
3+
<!-- i18n:meta locale=es source=README.md source-blob=bbf45a10aae9e88f68b27d84f51ee3e7e8a1e436 status=translated -->
44
<!-- i18n:end -->
55

66
<div align="center">
@@ -134,6 +134,7 @@ Esta biblioteca es una buena alternativa a NUQS.
134134
- [Otros hooks y helpers](#otros-hooks-y-helpers)
135135
- [Hook `useUrlStateBase` para otros routers](#hook-useurlstatebase-para-otros-routers)
136136
- [Hook `useSharedState` para React.js](#hook-usesharedstate-para-reactjs)
137+
- [Hook `useLinkProps` para React.js](#hook-uselinkprops-para-reactjs)
137138
- [Hook `useUrlEncode` para React.js](#hook-useurlencode-para-reactjs)
138139
- [Helpers `encodeState` y `decodeState`](#helpers-encodestate-y-decodestate)
139140
- [Helpers `encode` y `decode`](#helpers-encode-y-decode)
@@ -698,6 +699,29 @@ function SettingsComponent() {
698699

699700
[Documentación de la API](packages/urlstate/useSharedState/README.es.md)
700701

702+
### Hook `useLinkProps` para React.js
703+
704+
Hook para llevar el estado a un enlace que apunta a otra ruta, por ejemplo un selector de idioma. `setUrl` siempre escribe en la ruta actual; este no.
705+
706+
```tsx
707+
'use client'
708+
import Link from 'next/link';
709+
import { useRouter } from 'next/navigation';
710+
import { useLinkProps } from 'state-in-url/useLinkProps';
711+
712+
export const form = { name: '' };
713+
714+
function LanguagePicker() {
715+
const linkProps = useLinkProps(form, useRouter().push);
716+
717+
return <Link {...linkProps('/de/pricing')}>Deutsch</Link>;
718+
}
719+
```
720+
721+
El marcado conserva el `href` tal cual, así que los rastreadores y `hreflang` ven la URL canónica; el estado se lee al hacer clic.
722+
723+
[Documentación de la API](packages/urlstate/useLinkProps/README.es.md)
724+
701725
### Hook `useUrlEncode` para React.js
702726

703727
[Documentación de la API](packages/urlstate/useUrlEncode/README.es.md)

README.fr.md

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<!-- i18n:start -->
22
[English](./README.md) · [简体中文](./README.zh-CN.md) · [日本語](./README.ja.md) · [한국어](./README.ko.md) · [Русский](./README.ru.md) · [Español](./README.es.md) · [Português (BR)](./README.pt-BR.md) · Français · [Tiếng Việt](./README.vi.md)
3-
<!-- i18n:meta locale=fr source=README.md source-blob=01b5b4f72aa3c8871c185cfce21c6d696edb847b status=translated -->
3+
<!-- i18n:meta locale=fr source=README.md source-blob=bbf45a10aae9e88f68b27d84f51ee3e7e8a1e436 status=translated -->
44
<!-- i18n:end -->
55

66
<div align="center">
@@ -134,6 +134,7 @@ Cette bibliothèque est une bonne alternative à NUQS.
134134
- [Autres hooks et helpers](#autres-hooks-et-helpers)
135135
- [Hook `useUrlStateBase` pour d'autres routeurs](#hook-useurlstatebase-pour-dautres-routeurs)
136136
- [Hook `useSharedState` pour React.js](#hook-usesharedstate-pour-reactjs)
137+
- [Hook `useLinkProps` pour React.js](#hook-uselinkprops-pour-reactjs)
137138
- [Hook `useUrlEncode` pour React.js](#hook-useurlencode-pour-reactjs)
138139
- [Helpers `encodeState` et `decodeState`](#helpers-encodestate-et-decodestate)
139140
- [Helpers `encode` et `decode`](#helpers-encode-et-decode)
@@ -698,6 +699,29 @@ function SettingsComponent() {
698699

699700
[Documentation de l'API](packages/urlstate/useSharedState/README.fr.md)
700701

702+
### Hook `useLinkProps` pour React.js
703+
704+
Hook qui emporte l'état vers un lien pointant sur une autre route, par exemple un sélecteur de langue. `setUrl` écrit toujours sur le chemin courant ; celui-ci non.
705+
706+
```tsx
707+
'use client'
708+
import Link from 'next/link';
709+
import { useRouter } from 'next/navigation';
710+
import { useLinkProps } from 'state-in-url/useLinkProps';
711+
712+
export const form = { name: '' };
713+
714+
function LanguagePicker() {
715+
const linkProps = useLinkProps(form, useRouter().push);
716+
717+
return <Link {...linkProps('/de/pricing')}>Deutsch</Link>;
718+
}
719+
```
720+
721+
Le balisage conserve le `href` tel quel : les robots d'indexation et `hreflang` voient donc l'URL canonique ; l'état est lu au clic.
722+
723+
[Documentation de l'API](packages/urlstate/useLinkProps/README.fr.md)
724+
701725
### Hook `useUrlEncode` pour React.js
702726

703727
[Documentation de l'API](packages/urlstate/useUrlEncode/README.fr.md)

README.ja.md

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<!-- i18n:start -->
22
[English](./README.md) · [简体中文](./README.zh-CN.md) · 日本語 · [한국어](./README.ko.md) · [Русский](./README.ru.md) · [Español](./README.es.md) · [Português (BR)](./README.pt-BR.md) · [Français](./README.fr.md) · [Tiếng Việt](./README.vi.md)
3-
<!-- i18n:meta locale=ja source=README.md source-blob=01b5b4f72aa3c8871c185cfce21c6d696edb847b status=translated -->
3+
<!-- i18n:meta locale=ja source=README.md source-blob=bbf45a10aae9e88f68b27d84f51ee3e7e8a1e436 status=translated -->
44
<!-- i18n:end -->
55

66
<div align="center">
@@ -134,6 +134,7 @@ Next.js と react-router 用の `useUrlState` フックと、その他あらゆ
134134
- [その他のフックとヘルパー](#その他のフックとヘルパー)
135135
- [他のルーター向け `useUrlStateBase` フック](#他のルーター向け-useurlstatebase-フック)
136136
- [React.js 向け `useSharedState` フック](#reactjs-向け-usesharedstate-フック)
137+
- [React.js 向け `useLinkProps` フック](#reactjs-向け-uselinkprops-フック)
137138
- [React.js 向け `useUrlEncode` フック](#reactjs-向け-useurlencode-フック)
138139
- [`encodeState``decodeState` ヘルパー](#encodestate-と-decodestate-ヘルパー)
139140
- [`encode``decode` ヘルパー](#encode-と-decode-ヘルパー)
@@ -698,6 +699,29 @@ function SettingsComponent() {
698699

699700
[API ドキュメント](packages/urlstate/useSharedState/README.ja.md)
700701

702+
### React.js 向け `useLinkProps` フック
703+
704+
別のルートを指すリンクに状態を引き継ぐためのフックです。言語切り替えなどに使います。`setUrl` は常に現在のパスに書き込みますが、こちらは違います。
705+
706+
```tsx
707+
'use client'
708+
import Link from 'next/link';
709+
import { useRouter } from 'next/navigation';
710+
import { useLinkProps } from 'state-in-url/useLinkProps';
711+
712+
export const form = { name: '' };
713+
714+
function LanguagePicker() {
715+
const linkProps = useLinkProps(form, useRouter().push);
716+
717+
return <Link {...linkProps('/de/pricing')}>Deutsch</Link>;
718+
}
719+
```
720+
721+
マークアップには素の `href` が残るため、クローラーと `hreflang` は正規の URL を参照します。状態はクリック時に読み取られます。
722+
723+
[API ドキュメント](packages/urlstate/useLinkProps/README.ja.md)
724+
701725
### React.js 向け `useUrlEncode` フック
702726

703727
[API ドキュメント](packages/urlstate/useUrlEncode/README.ja.md)

README.ko.md

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<!-- i18n:start -->
22
[English](./README.md) · [简体中文](./README.zh-CN.md) · [日本語](./README.ja.md) · 한국어 · [Русский](./README.ru.md) · [Español](./README.es.md) · [Português (BR)](./README.pt-BR.md) · [Français](./README.fr.md) · [Tiếng Việt](./README.vi.md)
3-
<!-- i18n:meta locale=ko source=README.md source-blob=01b5b4f72aa3c8871c185cfce21c6d696edb847b status=translated -->
3+
<!-- i18n:meta locale=ko source=README.md source-blob=bbf45a10aae9e88f68b27d84f51ee3e7e8a1e436 status=translated -->
44
<!-- i18n:end -->
55

66
<div align="center">
@@ -134,6 +134,7 @@ Next.js와 react-router용 `useUrlState` 훅과 그 외 JS 환경을 위한 헬
134134
- [기타 훅과 헬퍼](#기타-훅과-헬퍼)
135135
- [다른 라우터용 `useUrlStateBase`](#다른-라우터용-useurlstatebase-훅)
136136
- [React.js용 `useSharedState`](#reactjs용-usesharedstate-훅)
137+
- [React.js용 `useLinkProps`](#reactjs용-uselinkprops-훅)
137138
- [React.js용 `useUrlEncode`](#reactjs용-useurlencode-훅)
138139
- [`encodeState``decodeState` 헬퍼](#encodestate-및-decodestate-헬퍼)
139140
- [`encode``decode` 헬퍼](#encode-및-decode-헬퍼)
@@ -694,6 +695,29 @@ function SettingsComponent() {
694695

695696
[API 문서](packages/urlstate/useSharedState/README.md)
696697

698+
### React.js용 `useLinkProps`
699+
700+
다른 라우트를 가리키는 링크로 상태를 넘기는 훅입니다. 예를 들어 언어 전환기에 씁니다. `setUrl` 은 언제나 현재 경로에 쓰지만, 이 훅은 그렇지 않습니다.
701+
702+
```tsx
703+
'use client'
704+
import Link from 'next/link';
705+
import { useRouter } from 'next/navigation';
706+
import { useLinkProps } from 'state-in-url/useLinkProps';
707+
708+
export const form = { name: '' };
709+
710+
function LanguagePicker() {
711+
const linkProps = useLinkProps(form, useRouter().push);
712+
713+
return <Link {...linkProps('/de/pricing')}>Deutsch</Link>;
714+
}
715+
```
716+
717+
마크업에는 원래의 `href` 가 남으므로 크롤러와 `hreflang` 은 정규 URL 을 봅니다. 상태는 클릭할 때 읽습니다.
718+
719+
[API 문서](packages/urlstate/useLinkProps/README.ko.md)
720+
697721
### React.js용 `useUrlEncode`
698722

699723
[API 문서](packages/urlstate/useUrlEncode/README.md)

README.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@ This library is a good alternative for NUQS.
134134
- [Other hooks and helpers](#other-hooks-and-helpers)
135135
- [`useUrlStateBase` hook for others routers](#useurlstatebase-hook-for-others-routers)
136136
- [`useSharedState` hook for React.js](#usesharedstate-hook-for-reactjs)
137+
- [`useLinkProps` hook for React.js](#uselinkprops-hook-for-reactjs)
137138
- [`useUrlEncode` hook for React.js](#useurlencode-hook-for-reactjs)
138139
- [`encodeState` and `decodeState` helpers](#encodestate-and-decodestate-helpers)
139140
- [`encode` and `decode` helpers](#encode-and-decode-helpers)
@@ -698,6 +699,29 @@ function SettingsComponent() {
698699

699700
[API Docs](packages/urlstate/useSharedState/README.md)
700701

702+
### `useLinkProps` hook for React.js
703+
704+
Hook to carry the state to a link pointing at a different route, e.g. a language switcher. `setUrl` always writes to the current path; this doesn't.
705+
706+
```tsx
707+
'use client'
708+
import Link from 'next/link';
709+
import { useRouter } from 'next/navigation';
710+
import { useLinkProps } from 'state-in-url/useLinkProps';
711+
712+
export const form = { name: '' };
713+
714+
function LanguagePicker() {
715+
const linkProps = useLinkProps(form, useRouter().push);
716+
717+
return <Link {...linkProps('/de/pricing')}>Deutsch</Link>;
718+
}
719+
```
720+
721+
The markup keeps the plain `href`, so crawlers and `hreflang` see the canonical URL; the state is read on click.
722+
723+
[API Docs](packages/urlstate/useLinkProps/README.md)
724+
701725
### `useUrlEncode` hook for React.js
702726

703727
[API Docs](packages/urlstate/useUrlEncode/README.md)

README.pt-BR.md

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<!-- i18n:start -->
22
[English](./README.md) · [简体中文](./README.zh-CN.md) · [日本語](./README.ja.md) · [한국어](./README.ko.md) · [Русский](./README.ru.md) · [Español](./README.es.md) · Português (BR) · [Français](./README.fr.md) · [Tiếng Việt](./README.vi.md)
3-
<!-- i18n:meta locale=pt-BR source=README.md source-blob=01b5b4f72aa3c8871c185cfce21c6d696edb847b status=translated -->
3+
<!-- i18n:meta locale=pt-BR source=README.md source-blob=bbf45a10aae9e88f68b27d84f51ee3e7e8a1e436 status=translated -->
44
<!-- i18n:end -->
55

66
<div align="center">
@@ -134,6 +134,7 @@ Esta biblioteca é uma boa alternativa ao NUQS.
134134
- [Outros hooks e helpers](#outros-hooks-e-helpers)
135135
- [Hook `useUrlStateBase` para outros routers](#hook-useurlstatebase-para-outros-routers)
136136
- [Hook `useSharedState` para React.js](#hook-usesharedstate-para-reactjs)
137+
- [Hook `useLinkProps` para React.js](#hook-uselinkprops-para-reactjs)
137138
- [Hook `useUrlEncode` para React.js](#hook-useurlencode-para-reactjs)
138139
- [Helpers `encodeState` e `decodeState`](#helpers-encodestate-e-decodestate)
139140
- [Helpers `encode` e `decode`](#helpers-encode-e-decode)
@@ -698,6 +699,29 @@ function SettingsComponent() {
698699

699700
[Documentação da API](packages/urlstate/useSharedState/README.pt-BR.md)
700701

702+
### Hook `useLinkProps` para React.js
703+
704+
Hook para levar o estado até um link que aponta para outra rota, por exemplo um seletor de idioma. `setUrl` sempre escreve no caminho atual; este não.
705+
706+
```tsx
707+
'use client'
708+
import Link from 'next/link';
709+
import { useRouter } from 'next/navigation';
710+
import { useLinkProps } from 'state-in-url/useLinkProps';
711+
712+
export const form = { name: '' };
713+
714+
function LanguagePicker() {
715+
const linkProps = useLinkProps(form, useRouter().push);
716+
717+
return <Link {...linkProps('/de/pricing')}>Deutsch</Link>;
718+
}
719+
```
720+
721+
A marcação mantém o `href` simples, então rastreadores e `hreflang` enxergam a URL canônica; o estado é lido no clique.
722+
723+
[Documentação da API](packages/urlstate/useLinkProps/README.pt-BR.md)
724+
701725
### Hook `useUrlEncode` para React.js
702726

703727
[Documentação da API](packages/urlstate/useUrlEncode/README.pt-BR.md)

README.ru.md

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<!-- i18n:start -->
22
[English](./README.md) · [简体中文](./README.zh-CN.md) · [日本語](./README.ja.md) · [한국어](./README.ko.md) · Русский · [Español](./README.es.md) · [Português (BR)](./README.pt-BR.md) · [Français](./README.fr.md) · [Tiếng Việt](./README.vi.md)
3-
<!-- i18n:meta locale=ru source=README.md source-blob=01b5b4f72aa3c8871c185cfce21c6d696edb847b status=translated -->
3+
<!-- i18n:meta locale=ru source=README.md source-blob=bbf45a10aae9e88f68b27d84f51ee3e7e8a1e436 status=translated -->
44
<!-- i18n:end -->
55

66
<div align="center">
@@ -134,6 +134,7 @@
134134
- [Другие hook'и и вспомогательные функции](#другие-hookи-и-вспомогательные-функции)
135135
- [Hook `useUrlStateBase` для других роутеров](#hook-useurlstatebase-для-других-роутеров)
136136
- [Hook `useSharedState` для React.js](#hook-usesharedstate-для-reactjs)
137+
- [Hook `useLinkProps` для React.js](#hook-uselinkprops-для-reactjs)
137138
- [Hook `useUrlEncode` для React.js](#hook-useurlencode-для-reactjs)
138139
- [Вспомогательные функции `encodeState` и `decodeState`](#вспомогательные-функции-encodestate-и-decodestate)
139140
- [Вспомогательные функции `encode` и `decode`](#вспомогательные-функции-encode-и-decode)
@@ -698,6 +699,29 @@ function SettingsComponent() {
698699

699700
[Документация по API](packages/urlstate/useSharedState/README.ru.md)
700701

702+
### Hook `useLinkProps` для React.js
703+
704+
Хук, переносящий состояние на ссылку, которая ведёт на другой маршрут, — например, в переключателе языка. `setUrl` всегда пишет в текущий путь, этот хук — нет.
705+
706+
```tsx
707+
'use client'
708+
import Link from 'next/link';
709+
import { useRouter } from 'next/navigation';
710+
import { useLinkProps } from 'state-in-url/useLinkProps';
711+
712+
export const form = { name: '' };
713+
714+
function LanguagePicker() {
715+
const linkProps = useLinkProps(form, useRouter().push);
716+
717+
return <Link {...linkProps('/de/pricing')}>Deutsch</Link>;
718+
}
719+
```
720+
721+
В разметке остаётся обычный `href`, поэтому краулеры и `hreflang` видят канонический URL; состояние читается в момент клика.
722+
723+
[Документация по API](packages/urlstate/useLinkProps/README.ru.md)
724+
701725
### Hook `useUrlEncode` для React.js
702726

703727
[Документация по API](packages/urlstate/useUrlEncode/README.ru.md)

0 commit comments

Comments
 (0)