`Link` marks links to the same page with a different query as `aria-current="page"`

オープン
#713 コメント 1 件 リアクション 0 件 担当者 0 名 GitHub で見る

メンテナーはふだん 1 日以内に返信

まだ誰も着手していません。

評価

難易度
3/5
見積もり時間
1〜2日
初心者へのやさしさ
72/100
issue の種類
バグ
明瞭さ
明確に書かれている
活発さ
活発
技術スタック
typescript

調査の方向性

Start by locating linkActiveAttributes() and the tests for Link active state. Read how it compares the target and current URLs, then check cases with query parameters, reordered parameters, extra current parameters, and links without a query. Done when query-bearing links are marked current only when their parameters match, while query-free menu links retain the described behavior.

索引モデルが issue の本文から書いたものです。

説明

Since #676, Link adds aria-current="page" and data-void-active when its destination is the current page. linkActiveAttributes() compares only the pathname ("The query and hash are ignored"). So a link that changes only the query is marked as the current page, even though it leads somewhere else.

Repro (Void 1.6.1)

On /posts?page=2:

<Link href="/posts?page=1">Previous</Link>
<Link href="/posts?page=3">Next</Link>

Both render with aria-current="page" and data-void-active. Screen readers announce "Previous, current page" and "Next, current page". The same happens with any links that change only the query: pagination, previous/next date ranges, sort and filter tabs. A GET link's data merged into its query has the same issue.

Expected

A link whose href has a query is current only when that query matches the current URL. The page itself (/posts?page=2) is the current page; the other two links aren't.

Ignoring the query is still right for links without one. A menu link to /posts should stay current on /posts?page=2 or /posts?sort=new, so that part of the behaviour should stay.

Suggested fix

In linkActiveAttributes(), when the target has a query, also require each of its params to have the same value in the current URL:

const queryMatches = [...target.searchParams].every(
  ([key, value]) => current.searchParams.getAll(key).includes(value),
);
if (linkPath === currentPath && queryMatches) return { 'aria-current': 'page', 'data-void-active': '' };

Comparing params one by one, instead of the raw search string, means param order doesn't matter. It also keeps a tab link like ?status=open current on ?status=open&page=2. A stricter rule, the whole query must match, would work too.

Another option is a way to opt out, such as activeMatch={false}, though fixing the default is better: most apps won't know their pagination links are announced wrong.

Workaround

Pass aria-current={undefined} on those links, since user attributes win. data-void-active still stays on them.

主要言語
TypeScript
スター
627
フォーク
66
平均マージ
13時間 57分
マージ済み PR(30日)
194

環境構築

このプロジェクトには開発コンテナ、Dockerfile、コントリビューションガイドがありません。まず README を読み、一般的な手順ははじめてのコントリビューションガイドを参照してください。

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

voidzero-dev/void のほかの issue

voidzero-dev/void の issue をすべて見る

似ている issue

TypeScript の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。