`Link`: mark the link to the current page (`aria-current`, `data-active`)
Mantenedores costumam responder em até 1 dia
Ninguém assumiu esta issue ainda.
Avaliação
- Dificuldade
- 4/5
- Tempo estimado
- 3-5 dias
- Facilidade para iniciantes
- 25/100
- Tipo de issue
- Funcionalidade
- Clareza
- Razoavelmente clara
- Status de atividade
- Ativa
- Stack de tecnologia
- react, typescript
- Domínio
- frontend
Direção de pesquisa
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.
Escrita pelo modelo de indexação a partir do texto da issue.
Descrição
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
- Linguagem predominante
- TypeScript
- Estrelas
- 627
- Forks
- 66
- Merge médio
- 14h 56min
- PRs com merge (30d)
- 170
Preparar o ambiente
Este projeto não oferece contêiner de desenvolvimento, Dockerfile nem guia de contribuição, então a configuração fica por sua conta: comece pelo README e veja nosso guia da primeira contribuição para os passos gerais.
Primeiros passos
- Leia a issue inteira e depois o guia de contribuição do projeto.
- Comente na issue dizendo que vai assumir — evita que duas pessoas façam o mesmo trabalho.
- Faça um fork do repositório e trabalhe em uma branch.
- Abra um pull request que referencie o número da issue.
Mais de voidzero-dev/void
-
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 62/100
voidzero-dev/void#677 ·
Mantenedores costumam responder em até 1 dia
-
Dificuldade 3/5 1-2 dias Facilidade para iniciantes 52/100
voidzero-dev/void#680 ·
Mantenedores costumam responder em até 1 dia
-
`withValidator({ body })` rejects the multipart bodies that `useForm` and `action()` send for filesAberta
Dificuldade 4/5 3-5 dias Facilidade para iniciantes 35/100
voidzero-dev/void#679 ·
Mantenedores costumam responder em até 1 dia
-
Dificuldade 5/5 Mais de uma semana Facilidade para iniciantes 18/100
voidzero-dev/void#667 ·
Mantenedores costumam responder em até 1 dia
-
platform: interrupted install ignores a replacement runtime token and never updates deployed WorkersAberta
Dificuldade 4/5 3-5 dias Facilidade para iniciantes 35/100
voidzero-dev/void#666 ·
Mantenedores costumam responder em até 1 dia
Todas as issues de voidzero-dev/void
Issues semelhantes
-
ci-cd desktop size:low telemetry-improvement telemetry-round-1
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 66/100
vfarcic/dot-agent-deck#2079 ·
Mantenedores costumam responder em até 1 dia
-
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 75/100
Mantenedores costumam responder em até 1 dia
-
Broken links in the docsAberta
Dificuldade 1/5 Menos de uma hora Facilidade para iniciantes 83/100
Mantenedores costumam responder em até 1 dia
-
status:in-linear
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 68/100
n8n-io/n8n#43006 · 3 comentários ·
Mantenedores costumam responder em até 1 dia
-
🔊 a11y
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 82/100
betagouv/mon-entreprise#4726 ·
Mantenedores costumam responder em até 9 dias