`Link`: mark the link to the current page (`aria-current`, `data-active`)
Los mantenedores suelen responder en 1 día
Evaluación
- Dificultad
- 4/5
- Tiempo estimado
- 3-5 días
- Aptitud para principiantes
- 25/100
- Tipo de issue
- Nueva funcionalidad
- Claridad
- Bastante claro
- Estado de actividad
- Activo
- Stack tecnológico
- react, typescript
- Área
- frontend
Línea de trabajo
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.
Escrito por el modelo de indexación a partir del texto del issue.
Descripción
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
- Lenguaje dominante
- TypeScript
- Estrellas
- 627
- Forks
- 66
- Merge medio
- 13 h 57 min
- PR fusionados (30 d)
- 194
Preparar el entorno
Este proyecto no incluye contenedor de desarrollo, Dockerfile ni guía de contribución, así que la configuración corre por tu cuenta: empieza por su README y consulta nuestra guía para la primera contribución para los pasos generales.
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de voidzero-dev/void
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 62/100
voidzero-dev/void#677 ·
Los mantenedores suelen responder en 1 día
-
Export a guard for `VoidActionError` at every statusPosiblemente ocupada @karthickeyan-dev la tomó hoy. Abierto
Dificultad 3/5 1-2 días Aptitud para principiantes 78/100
voidzero-dev/void#714 ·
Los mantenedores suelen responder en 1 día
-
Dificultad 3/5 1-2 días Aptitud para principiantes 72/100
voidzero-dev/void#713 · 1 comentario ·
Los mantenedores suelen responder en 1 día
-
`@void/solid`: `useParams()` keeps the first page's params after client-side navigationPosiblemente ocupada @yujiym la tomó hoy. Abierto
Dificultad 1/5 Menos de una hora Aptitud para principiantes 20/100
voidzero-dev/void#708 ·
Los mantenedores suelen responder en 1 día
-
Dificultad 5/5 Más de una semana Aptitud para principiantes 28/100
voidzero-dev/void#692 · 1 comentario ·
Los mantenedores suelen responder en 1 día
Todos los issues de voidzero-dev/void
Issues similares
-
Report: &TV InternationalAbiertocheck:passed streams:remove
Dificultad 1/5 Menos de una hora Aptitud para principiantes 67/100
Los mantenedores suelen responder en 1 día
-
bug priority-p1
Dificultad 2/5 1-3 horas Aptitud para principiantes 82/100
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 88/100
-
beginner blocked
Dificultad 2/5 1-3 horas Aptitud para principiantes 82/100
hiero-ledger/hiero-sdk-js#4670 ·
Los mantenedores suelen responder en 1 día
-
[Exploratory] Expense - 2 selected drop-down is shown twice when selecting hold from more option.AbiertoMonthly Not a priority
Dificultad 2/5 1-3 horas Aptitud para principiantes 65/100
Expensify/App#106080 · 1 comentario ·
Los mantenedores suelen responder en 1 día