`Link`: mark the link to the current page (`aria-current`, `data-active`)
Les mainteneurs répondent en général sous 1 jour
Personne n'a encore pris cette issue.
Évaluation
- Difficulté
- 4/5
- Temps estimé
- 3-5 jours
- Accessibilité débutants
- 25/100
- Type d'issue
- Fonctionnalité
- Clarté
- Plutôt claire
- Activité
- Active
- Stack technique
- react, typescript
- Domaine
- frontend
Piste de recherche
Start with the shared Link logic that #672 moves into void/pages-client, and read how useRouter() exposes the current path in the React adapter. The open questions are the prop name for prefix matching and whether to match by segment; settle those with maintainers before coding. Done when an exact match sets aria-current="page" and data-active, and activeMatch="prefix" matches whole segments while ignoring query and hash.
Rédigé par le modèle d'indexation à partir du texte de l'issue.
Description
Summary
Link renders a plain <a> with no sign that it points to the current page. Every navigation menu (a header, a sidebar, tabs) has to compare useRouter().path with each link's href by hand. Those hand-written checks usually style the active link but forget aria-current="page", so screen readers aren't told which link is the current page.
Example
What an app writes today:
import { Link, useRouter } from '@void/react';
// The section's home link only matches itself; the others also match their nested pages.
function isActive(path: string, href: string, home: string) {
return path === href || (href !== home && path.startsWith(`${href}/`));
}
function Sidebar({ links, home }: { links: { href: string; label: string }[]; home: string }) {
const { path } = useRouter();
return links.map((link) => {
const active = isActive(path, link.href, home);
return (
<Link
key={link.href}
href={link.href}
data-active={active || undefined}
aria-current={active ? 'page' : undefined}
>
{link.label}
</Link>
);
});
}
What it could be:
<Link href="/admin">Overview</Link>
<Link href="/admin/users" activeMatch="prefix">Users</Link>
Proposal
aria-current="page"when the link's path is the current path. It's semantically "this is the current page", so exact match only.data-activeon the same link, for styling with[data-active]or Tailwind'sdata-active:. Unlike a class, it doesn't collide with the app's ownclassName.- An opt-in for nested pages, for example
activeMatch="prefix", so/admin/usersstays highlighted on/admin/users/42. It matches whole path segments, so/admin/usersdoesn't match/admin/users-archive. - Ignore the query and hash when matching, so
/inbox?page=2still marks/inbox.
The names are only suggestions. The router already holds the current path in every adapter, so this should look the same in React, Vue, Svelte and Solid. #672, which moves the shared Link logic into void/pages-client, looks like the natural place for the matching.
Prior art
- React Router:
NavLinksetsaria-current="page"and anactiveclass, and takesendto choose between exact and nested matching. - TanStack Router:
Linksetsaria-current="page"anddata-status="active", and takesactiveOptions: { exact, includeSearch }andactiveProps. - Vue Router:
RouterLinkaddsrouter-link-activefor nested matches, androuter-link-exact-activeplusaria-current="page"for exact ones. - Nuxt:
NuxtLinktakesactiveClassandexactActiveClass.
Environment
void1.5.0@void/react1.5.0
- Langage dominant
- TypeScript
- Étoiles
- 627
- Forks
- 66
- Merge moyen
- 14 h 56 min
- PR mergées (30 j)
- 170
Préparer son environnement
Ce projet ne fournit ni conteneur de développement, ni Dockerfile, ni guide de contribution : l'installation est à votre charge. Commencez par son README, et consultez notre guide de la première contribution pour les étapes générales.
Par où commencer
- Lisez l'issue en entier, puis le guide de contribution du projet.
- Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
- Forkez le dépôt et travaillez sur une branche.
- Ouvrez une pull request qui référence le numéro de l'issue.
Autres issues de voidzero-dev/void
-
Difficulté 2/5 1-3 heures Accessibilité débutants 62/100
voidzero-dev/void#677 ·
Les mainteneurs répondent en général sous 1 jour
-
Difficulté 3/5 1-2 jours Accessibilité débutants 52/100
voidzero-dev/void#680 ·
Les mainteneurs répondent en général sous 1 jour
-
`withValidator({ body })` rejects the multipart bodies that `useForm` and `action()` send for filesOuverte
Difficulté 4/5 3-5 jours Accessibilité débutants 35/100
voidzero-dev/void#679 ·
Les mainteneurs répondent en général sous 1 jour
-
Difficulté 5/5 Plus d'une semaine Accessibilité débutants 18/100
voidzero-dev/void#667 ·
Les mainteneurs répondent en général sous 1 jour
-
platform: interrupted install ignores a replacement runtime token and never updates deployed WorkersOuverte
Difficulté 4/5 3-5 jours Accessibilité débutants 35/100
voidzero-dev/void#666 ·
Les mainteneurs répondent en général sous 1 jour
Toutes les issues de voidzero-dev/void
Issues similaires
-
Difficulté 2/5 1-3 heures Accessibilité débutants 72/100
Les mainteneurs répondent en général sous 1 jour
-
ready-for-agent
Difficulté 2/5 1-3 heures Accessibilité débutants 72/100
LucasSantana-Dev/Lucky#2951 ·
Les mainteneurs répondent en général sous 1 jour
-
Difficulté 2/5 1-3 heures Accessibilité débutants 75/100
danielmiessler/LifeOS#2567 ·
Les mainteneurs répondent en général sous 9 jours
-
refactor(react-pi): classify base64 images with core's parseBase64Peut-être pris @jimmyallinai l’a pris aujourd’hui. Ouvertemaintenance
Difficulté 2/5 1-3 heures Accessibilité débutants 62/100
assistant-ui/assistant-ui#10293 · 2 commentaires · 1 réaction ·
Les mainteneurs répondent en général sous 1 jour
-
Difficulté 2/5 1-3 heures Accessibilité débutants 70/100
brijeshb42/monaco-vim#175 ·