メインコンテンツへスキップ
menumenu tanreiexpand_morecontrasttranslate
tanreiexpand_more
はじめにWebReactSwiftUIJetpack ComposeFlutterReact Nativeプリセット自分のデザインシステムを作るAI エージェントと Tanrei を使うブランドデザイントークンデザインシステムとカスタマイズTheme Studioカラータイポグラフィアイコン形状エレベーションモーションインタラクション状態振る舞いレイアウトアクセシビリティ言葉カラートークンタイプスケールトークン形状トークンエレベーショントークンモーショントークン状態トークンスペースと寸法のトークンコンポーネントボタンメインアクションボタンセグメントボタンボタングループメニュー付きボタンツールバーコピーボタンチェックボックスラジオボタンスイッチチップメニュースライダースライダーフィールドカレンダーDateTimePickerフィールドグループラジオグループチェックボックスグループセレクトセレクトフィールドメニューバーファイルアップロードファイルピッカー 上級者向けドロップゾーンテキスト入力欄 上級者向けテキストフィールドチップフィールドフィールドコンボボックス 上級者向けコンボボックスフィールド数値入力欄 上級者向け数値フィールドカラー入力欄 上級者向けカラーフィールドワンタイムコード入力欄 上級者向けワンタイムコードフィールド埋め込みテキスト入力欄 上級者向けチャットコンポーザーカード区切り線モーダルレイヤー 上級者向けダイアログリストリスト行ボトムシートサイドシートカルーセルコードブロックテーブルポップオーバーステップアコーディオン説明リスト図アプリシェルページヘッダーツリービュータイムライン画像プレビューハンドルサイズ変更できる枠スクロールエリアバッジプログレスインジケーターメーターナンバーティッカーローディングインジケータースナックバーツールチップキーボードショートカットタグインラインコードコールアウトアバター空の状態タググループスケルトンファイル項目色見本マーキーテキストタブタブビューアプリバーナビゲーションバーナビゲーションドロワー検索リンクページネーション前後のリンクステッパーパンくずリスト目次リンクカードFAB メニューステータスTanrei の作り方コントリビューションライセンスと帰属
ホームコンポーネント前後のリンク

前後のリンク

ひと続きのページの中で、いまいるページの前のページと次のページを示します。2 つのリンクから成り、それぞれの名前は方向と行き先のタイトルです。

content_copyMarkdown で表示
カテゴリ
ナビゲーション
トークン
comp.previous-next-links
レベル
基礎

概要

Web
tanrei-previous-next-links
schedule
SwiftUI
TanreiPreviousNextLinks
radio_button_unchecked
Jetpack Compose
TanreiPreviousNextLinks
radio_button_unchecked
Flutter
TanreiPreviousNextLinks
radio_button_unchecked
React Native
PreviousNextLinks
radio_button_unchecked

生成元 docs/status/status.json, specs/previous-next-links.spec.json

前と次

このページの末尾にある前後のリンクも同じコンポーネントです。

ガイドの章、連載の記事、ブログの投稿のように、それぞれのページにタイトルがある並びをたどるためのものです。1 つのリストを番号でめくる場合(検索結果のページ、テーブルの行など)は、独立したコンポーネントであるページネーションを使います。ページ番号は行き先について何も語りませんが、タイトルは語ります。

使い方

Web では、前後のリンクは要素ではなく、プロダクト側の nav とアンカーに付けるクラスです。アンカーは文書の中にあるので、スクリプトが動く前からリンクとして働き、クローラーからも、ページ内のアンカーを扱うルーターからも見つけられます。コンポーネント全体を、スタイルシートだけで描きます。

SwiftUI、Compose、Flutter、React Native は計画中です。このページの冒頭で各プラットフォームに添えた名前は仕様が定めたもので、まだ提供していません。React にもまだ PreviousNextLinks コンポーネントはないので、クラスを付けたマークアップを使ってください。

<link rel="stylesheet" href="@tanrei/web/tokens.css" />
<link rel="stylesheet" href="@tanrei/web/icons.css" />
<link rel="stylesheet" href="@tanrei/web/previous-next-links.css" />

<nav class="tanrei-previous-next-links" aria-label="ページ">
  <a class="tanrei-previous-next-links-item" data-direction="previous" rel="prev" href="https://example.com/guide/installation/">
    <span class="tanrei-previous-next-links-label">前へ</span>
    <span class="tanrei-previous-next-links-title">インストール</span>
  </a>
  <a class="tanrei-previous-next-links-item" data-direction="next" rel="next" href="https://example.com/guide/design-tokens/">
    <span class="tanrei-previous-next-links-label">次へ</span>
    <span class="tanrei-previous-next-links-title">デザイントークン</span>
  </a>
</nav>

<!-- 最初のページ:前の項目は href なしで書くか、省きます。次の項目の場所は変わりません。 -->
<nav class="tanrei-previous-next-links" aria-label="ページ">
  <a class="tanrei-previous-next-links-item" data-direction="previous"></a>
  <a class="tanrei-previous-next-links-item" data-direction="next" rel="next" href="https://example.com/guide/installation/">
    <span class="tanrei-previous-next-links-label">次へ</span>
    <span class="tanrei-previous-next-links-title">インストール</span>
  </a>
</nav>

<script type="module">
  // 任意:リップルと dim の押下への応え方、次の項目を先に書いたときの並べ替え、デバッグ時の報告。`@tanrei/web` を読み込んでも入ります。
  import '@tanrei/web/previous-next-links';
</script>
import '@tanrei/web/previous-next-links.css';
import '@tanrei/web/previous-next-links';
import { Link as RouterLink } from 'react-router-dom';

<nav className="tanrei-previous-next-links" aria-label="ページ">
  {/* ルーターのリンクは自分でアンカーを描くので、そのリンクにクラスを付けます。 */}
  <RouterLink className="tanrei-previous-next-links-item" data-direction="next" rel="next" to="/guide/design-tokens/">
    <span className="tanrei-previous-next-links-label">次へ</span>
    <span className="tanrei-previous-next-links-title">デザイントークン</span>
  </RouterLink>
</nav>
プロパティ Web での書き方
label nav の aria-label
項目 <a class="tanrei-previous-next-links-item">
direction data-direction="previous" または "next" と、rel="prev" または rel="next"
項目の label <span class="tanrei-previous-next-links-label">
title ラベルの後の <span class="tanrei-previous-next-links-title">
href href
click アンカー自身の click

仕様

次の項目だけでも場所は変わらない。ラベルだけの項目

狭いカラムでは項目が縦に並ぶ

  • 項目は 1 つのリンクで、全体が押せます。輪郭線のあるコンテナとして描きます。輪郭線は細い線で、塗りはなく、タイトルはテキストの色です。下線は引きません。輪郭線と矢印と置かれた場所で、周りのテキストと見分けられるからです。
  • 矢印はコンポーネントが描きます。前の項目の先頭側の端に arrow_back、次の項目の末尾側の端に arrow_forward です。icons.css が必要です。
  • 同じ幅の 2 列。 最初のページでは先頭側の列が空になり、次の項目はほかのページとまったく同じ場所に置かれます。
  • 縦に並ぶ形。 前後のリンクの幅が、項目の最小幅 2 つ分と隙間の合計(既定のシステムでは 496)に満たないとき、項目は前を上、次を下にして縦に並びます。これを決めるのはウィンドウの幅ではなく、コンポーネント自身の幅です。
  • タイトルは折り返し、途中で切れません。 横に並んだ 2 つの項目は、高いほうの高さにそろいます。タイトルのない項目は、方向だけをタイトルのスタイルで示します。
  • 右から左のレイアウトでは、前の項目が右に置かれて矢印は右を指し、次の項目が左に置かれて矢印は左を指します。読む順序とフォーカスの順序は、前、次のままです。

構成要素

プロパティ

プロパティ 型 既定値 説明
label string "" The accessible name of the landmark ("Pages", "Chapter navigation"), in the product's language. Tanrei ships no words of its own. It tells this landmark from the page's other navigation, so it is required.

アイテム

このコンポーネントが繰り返すアイテムの種類です。フィクスチャはアイテムを順に並べ、各プラットフォームはそれぞれの流儀で種類ごとに名前を付けます。

item

One neighbouring page of the sequence: a link to it, named by a direction and its title.

プロパティ 型 既定値 説明
direction previous | next "next" Which neighbour the item leads to. previous: the page before, placed at the start with the arrow arrow_back. next: the page after, placed at the end with the arrow arrow_forward. A pair of previous and next links holds at most one item of each.
label string "" The direction in the product's words ("Previous", "Next"; "Newer", "Older"). It is drawn above the title and begins the item's accessible name.
title string "" The title of the page the item leads to ("Installation"). Empty, the item shows its direction alone (PNL-7).
href string "" The destination: an address as the platform's links take one. Empty, there is no page on that side and the item is not drawn (PNL-3), so a product can always give both items and leave one without a destination on the first and the last page.
イベント 説明
click The item was activated by pointer, touch, Enter or assistive technology. It is emitted before the destination opens; a product that takes the navigation itself (a client-side router) cancels it (PNL-14).
仕様 Web SwiftUI Jetpack Compose Flutter React Native
アイテム tanrei-previous-next-links-item TanreiPreviousNextLinksItem TanreiPreviousNextLinksItem TanreiPreviousNextLinksItem PreviousNextLinksItem
direction · プロパティ data-direction direction direction direction direction
label · プロパティ tanrei-previous-next-links-label label label label label
title · プロパティ tanrei-previous-next-links-title title title title title
href · プロパティ href destination href href href
click · イベント click action onClick onPressed onPress
備考 A class on the product's own anchor. data-direction is previous or next; the anchor also carries rel="prev" or rel="next". The label and the title are two spans with their classes, in that order. TanreiPreviousNextLinksItem(.next, label: "Next", title: "Design tokens", destination: url, action:); destination is an optional URL, and nil is the empty href. A data class; href is nullable. onClick returns false to keep the address closed; otherwise LocalUriHandler.current opens it. A value class; href is nullable. onPressed returns false to keep the address closed; otherwise the opener the app provides opens it. An object of the previous or the next prop. onPress receives an event whose preventDefault() keeps the address closed; otherwise Linking.openURL(href).

状態

振る舞い

EARS 記法による要件です。各プラットフォームの実装は、この ID に対応するテストで検証されます。要件の原文は仕様ファイルのものをそのまま掲載しています。

ID 要件
PNL-1 THE previous and next links SHALL be one navigation landmark named by label that holds its items in reading order — the previous item, then the next item, whatever order the product gave them in — and nothing else; WHILE label is empty THE previous and next links SHALL still render, and in debug builds report that the landmark has no accessible name.
PNL-2 WHILE an item's href is a destination THE previous and next links SHALL draw that item as the platform's own link to it (the web's anchor element in the document itself, not in a shadow root; SwiftUI's Link; on Compose, Flutter and React Native an element with the platform's link semantics whose address is opened by the platform's opener), so that whatever the platform gives a link — on the web its context menu, opening in a new tab or window, copying and dragging its address, the address shown before it is followed, a crawler that reads it, and a link that works before any script has run — is the platform's, and not the previous and next links's to draw or to take over; it SHALL expose the link role, named by the item's label followed by its title, with the arrow hidden from assistive technology, and WHERE the platform's links can say how a destination relates to the page (the web's rel) SHALL say previous for the previous item and next for the next.
PNL-3 IF an item's href is empty or only white space THE previous and next links SHALL draw nothing for that item and expose nothing for it, because the sequence has no page on that side; IF it names a script to run rather than a place to go (the web's javascript: scheme) or cannot be read as an address by the platform, or direction names a value the previous and next links do not have, or a second item has the direction of an earlier one, THE previous and next links SHALL likewise draw nothing for that item and in debug builds report it. WHILE no item has a destination THE previous and next links SHALL draw nothing, take no room and expose no landmark.
PNL-4 THE previous and next links SHALL lay its row out in two columns of equal width, comp.previous-next-links.gap apart, with the previous item in the column at the start and the next item in the column at the end, each as wide as its column and both as high as the taller of the two; an item that is not drawn SHALL leave its column empty, so that the next item stands at the same place and has the same width on every page of the sequence.
PNL-5 WHERE the layout gives the previous and next links less width than two times comp.previous-next-links.container.min-width plus comp.previous-next-links.gap THE previous and next links SHALL stack its items instead: each drawn item as wide as the previous and next links, the previous item above the next, comp.previous-next-links.gap between them, and no room kept for an item that is not drawn. It SHALL decide this by the width it is given, not by the window's.
PNL-6 THE previous and next links SHALL draw each item as a container with corners comp.previous-next-links.container.shape and an edge comp.previous-next-links.outline.width wide inside it, its content comp.previous-next-links.container.padding from the edge on every side: the arrow in a box comp.previous-next-links.icon.size large — arrow_back at the start edge of the previous item, arrow_forward at the end edge of the next — centred on the item's height, comp.previous-next-links.container.gap from the text, and the text filling the rest of the width, its lines aligned to the start in the previous item and to the end in the next, so that each item's text stands beside its arrow.
PNL-7 THE previous and next links SHALL set an item's label in comp.previous-next-links.label.typescale and, comp.previous-next-links.label.gap under it, its title in comp.previous-next-links.title.typescale; it SHALL wrap both where their language allows a break and, for a run with no such place that is longer than the line, inside the run, and SHALL NOT cut them, draw an ellipsis or scroll. WHILE an item's title is empty THE previous and next links SHALL draw its label alone, in the title's text style and color. WHILE an item's label is empty THE previous and next links SHALL draw its title alone and in debug builds report that the item does not say its direction in words.
PNL-8 WHILE an item is hovered, keyboard-focused or pressed THE previous and next links SHALL render its container, outline, label, title, arrow and opacity from the component tokens of the highest-precedence active state, with precedence pressed over focused over hovered (comp.previous-next-links.item.container.color, comp.previous-next-links.item.outline.color, comp.previous-next-links.item.label.color, comp.previous-next-links.item.title.color and comp.previous-next-links.item.icon.color at rest); focus gained by pointer or touch SHALL NOT select the focused state.
PNL-9 WHEN an item receives keyboard focus THE previous and next links SHALL show the focus ring around that item's container without animation — the system's focus indicator, sys.focus.offset from the container, sys.focus.outer-width wide in the focus-ring color, with the inner stroke of sys.focus.inner-width where the system has one; focus gained by pointer or touch SHALL NOT show it.
PNL-10 WHEN an item is pressed by pointer, touch or Enter THE previous and next links SHALL show the pressed state without delay and SHALL keep it visible for at least sys.motion.duration.press-hold, even when the press ends sooner.
PNL-11 WHILE pressed THE previous and next links SHALL answer as sys.behavior.pressed-feedback names: overlay applies the pressed tokens to the whole container at once; ripple grows the pressed state layer from the point of contact (from the center for keyboard activation); dim applies the pressed opacity to the whole control and draws no state layer; none draws no answer to the press. Under ripple and dim only the container color stays with the state under the press; label, title, icon, outline, opacity and shape still come from the pressed tokens. Under none every part stays with the state under the press. The ripple grows over comp.previous-next-links.motion.feedback-duration with motion.state-easing, fades over motion.state-duration with motion.state-easing once the press has ended and press-hold has passed, and appears whole where motion is reduced.
PNL-12 THE previous and next links SHALL ease its container corners by sys.shape.corner-smoothing (0 is a quarter circle, 0.6 the iOS continuous corner; a platform with only the OS curve draws it for any amount above 0) and show its keyboard focus as sys.behavior.focus-style names (ring or glow); a platform that cannot draw a choice SHALL fall back to the first value and state that in its README.
PNL-13 THE previous and next links SHALL change an item between its states over comp.previous-next-links.motion.state-duration with comp.previous-next-links.motion.state-easing, and at once where motion is reduced.
PNL-14 WHEN the user activates an item by pointer, touch or Enter THE previous and next links SHALL emit that item's click exactly once and then open its href where the person is, unless the product cancelled that click, in which case it SHALL open nothing: the product's own router has taken the navigation. It SHALL NOT hold the navigation back for sys.motion.duration.press-hold. THE previous and next links SHALL NOT activate an item on Space, which on the web scrolls the page as it does on any link, and SHALL NOT show the pressed state for it; WHERE the platform gives its links other keys or gestures (on the web a modified or a middle click that opens a new tab, on Apple platforms a long press that previews) THE previous and next links SHALL leave them to the platform.
PNL-15 WHERE the visual size of an item is below the minimum target THE previous and next links SHALL extend its hit area on both axes to sys.target.touch for touch input and sys.target.pointer for fine pointers, without changing its visual size; a platform that cannot tell the input type SHALL use sys.target.touch.
PNL-16 THE previous and next links SHALL open a destination in the context the person is in and in no other, SHALL draw no mark for a new context and SHALL draw no state for a destination already visited: the pages of one sequence replace one another, and an item's colors say what it is and what state it is in.
PNL-17 THE previous and next links SHALL draw each arrow through the platform's icon helper, as a glyph of the system's icon set, in the icon color of its state, with sys.icon.family.unselected and sys.icon.fill.unselected, sys.icon.weight and an optical size clamped between sys.icon.optical-size.min and sys.icon.optical-size.max; it SHALL take no glyph from the product and SHALL draw no path of its own.
PNL-18 WHERE the platform draws with a person's own forced colors (the web's forced-colors mode, and a platform's equivalent where it has one) THE previous and next links SHALL draw each item's edge, label, title and arrow in the platform's link color, keeping the edge comp.previous-next-links.outline.width wide so that what is pressed stays bounded, and SHALL draw the focus ring in the platform's highlight color.
PNL-19 WHILE the text size is enlarged THE previous and next links SHALL grow each item with its text — both items of a row to the height of the taller — keeping comp.previous-next-links.container.padding, comp.previous-next-links.container.gap, comp.previous-next-links.label.gap, comp.previous-next-links.gap and the arrow at comp.previous-next-links.icon.size, and SHALL still stack by the width it is given (PNL-5).
PNL-20 THE previous and next links SHALL take its layout direction from where it is used — the direction of the nearest ancestor that sets one, and the platform's own where none does — and SHALL have no direction setting of its own; WHEN that direction changes while the previous and next links are shown THE previous and next links SHALL draw itself for the new direction at once, without a motion of its own, keeping its focus.
PNL-21 WHERE the layout direction is right-to-left THE previous and next links SHALL mirror its row and each item's content by logical start and end, so that the previous item stands at the right with its arrow at its right edge and the next item at the left with its arrow at its left edge, and SHALL draw both arrows mirrored left to right, so that the previous item's points to the right and the next item's to the left: the icon helper mirrors them inside their own boxes because the system's icon set marks arrow_back and arrow_forward as mirrored. THE previous and next links SHALL NOT mirror a glyph itself, and the reading and focus order SHALL stay previous, then next.
PNL-22 THE previous and next links SHALL lay out each label and each title as text of its own direction, isolated from the text around it: it takes the base direction of its first strong character, or the layout direction where it has none, so that a left-to-right name, a number with its sign or unit and a version keep their own order in a right-to-left layout and reorder nothing beside them; THE previous and next links SHALL still place the text and align its lines by the layout direction and the item's side (PNL-6), not by the text's own.

プラットフォーム別の名前対応

パリティは API が同一であることを意味しません。同じ契約を、各プラットフォームの流儀で表現します。

仕様 Web SwiftUI Jetpack Compose Flutter React Native
コンポーネント tanrei-previous-next-links TanreiPreviousNextLinks TanreiPreviousNextLinks TanreiPreviousNextLinks PreviousNextLinks
label · プロパティ aria-label label contentDescription semanticLabel accessibilityLabel
備考 Classes on the product's own elements, as Link is: <nav class="tanrei-previous-next-links" aria-label="Pages"><a class="tanrei-previous-next-links-item" data-direction="previous" rel="prev" href="…"><span class="tanrei-previous-next-links-label">Previous</span><span class="tanrei-previous-next-links-title">Installation</span></a><a class="tanrei-previous-next-links-item" data-direction="next" rel="next" href="…">…</a></nav>, styled by a stylesheet of the package. The anchors are in the document, so they are links before any script runs and for whatever reads the page as built (PNL-2). The stylesheet alone gives the whole component: the two columns are a grid in which each item takes the column of its data-direction, whatever its place in the markup, and an anchor without href is not displayed (PNL-3); stacking is a container query on the nav (PNL-5); the arrows are the items' ::before and ::after in the icon font, mirrored under :dir(rtl); the states and the press-hold are the stylesheet's as they are Link's. The package's script, where it is loaded, adds through its one listener on the document what a stylesheet cannot: the shared press primitive (ripple and dim, PNL-11), the reordering of items given next-first so that the focus order is right, and every debug report. The web is not a custom element here, so packages/tools/src/conventions.js needs an entry for where the implementation lives, as prose has. React: PreviousNextLinks renders the same markup and takes a render prop for a router's link. TanreiPreviousNextLinks(label:previous:next:), each item optional. Each item is built on SwiftUI's Link; action runs before the address opens and returns whether the link should still open it (the environment's OpenURLAction does the opening). The container has the navigation landmark through an accessibility container with label. The row stacks with ViewThatFits measured against the proposed width. TanreiPreviousNextLinks(previous, next, contentDescription, modifier). Compose has no navigation landmark and no link role for a clickable element: the row is a semantics group named by contentDescription, and its README says what is not exposed. Stacking reads the incoming constraints (BoxWithConstraints). TanreiPreviousNextLinks(previous: …, next: …, semanticLabel: …). Semantics(container: true, label:) around the row; each item Semantics(link: true), with linkUrl where the engine has it. Stacking reads the incoming constraints (LayoutBuilder). <PreviousNextLinks accessibilityLabel="Pages" previous={{ label, title, href }} next={…} />. Each item is a Pressable with accessibilityRole="link"; the row has accessibilityRole="navigation" where the platform maps it (the web target) and is a labelled group elsewhere. Stacking reads onLayout. Follows the app's direction where an ancestor's is not known.

トークン

トークン 参照先 解決値(ライト)
--tanrei-comp-previous-next-links-container-gap sys.space.space150 12px
--tanrei-comp-previous-next-links-container-min-width — 240px
--tanrei-comp-previous-next-links-container-padding sys.space.space200 16px
--tanrei-comp-previous-next-links-container-shape sys.shape.corner.medium 8px
--tanrei-comp-previous-next-links-focused-container-shape — 8px
--tanrei-comp-previous-next-links-focused-opacity — 1
--tanrei-comp-previous-next-links-gap sys.space.space200 16px
--tanrei-comp-previous-next-links-hovered-container-shape — 8px
--tanrei-comp-previous-next-links-hovered-opacity — 1
--tanrei-comp-previous-next-links-icon-size sys.icon.small 20px
--tanrei-comp-previous-next-links-item-container-color — #000000 · 0%
--tanrei-comp-previous-next-links-item-focused-container-color — #1b1b1b · 10%
--tanrei-comp-previous-next-links-item-focused-icon-color — #4b4b4b
--tanrei-comp-previous-next-links-item-focused-label-color — #4b4b4b
--tanrei-comp-previous-next-links-item-focused-outline-color — #000000 · 8%
--tanrei-comp-previous-next-links-item-focused-state-layer-color — #1b1b1b
--tanrei-comp-previous-next-links-item-focused-title-color — #1b1b1b
--tanrei-comp-previous-next-links-item-hovered-container-color — #1b1b1b · 8%
--tanrei-comp-previous-next-links-item-hovered-icon-color — #4b4b4b
--tanrei-comp-previous-next-links-item-hovered-label-color — #4b4b4b
--tanrei-comp-previous-next-links-item-hovered-outline-color — #000000 · 8%
--tanrei-comp-previous-next-links-item-hovered-state-layer-color — #1b1b1b
--tanrei-comp-previous-next-links-item-hovered-title-color — #1b1b1b
--tanrei-comp-previous-next-links-item-icon-color sys.color.on-surface-variant #4b4b4b
--tanrei-comp-previous-next-links-item-label-color sys.color.on-surface-variant #4b4b4b
--tanrei-comp-previous-next-links-item-outline-color sys.color.outline-variant #000000 · 8%
--tanrei-comp-previous-next-links-item-pressed-container-color — #1b1b1b · 10%
--tanrei-comp-previous-next-links-item-pressed-icon-color — #4b4b4b
--tanrei-comp-previous-next-links-item-pressed-label-color — #4b4b4b
--tanrei-comp-previous-next-links-item-pressed-outline-color — #000000 · 8%
--tanrei-comp-previous-next-links-item-pressed-state-layer-color — #1b1b1b
--tanrei-comp-previous-next-links-item-pressed-title-color — #1b1b1b
--tanrei-comp-previous-next-links-item-state-layer-color comp.previous-next-links.item.title.color #1b1b1b
--tanrei-comp-previous-next-links-item-title-color sys.color.on-surface #1b1b1b
--tanrei-comp-previous-next-links-label-gap sys.space.space25 2px
--tanrei-comp-previous-next-links-motion-feedback-duration sys.motion.role.feedback 450ms
--tanrei-comp-previous-next-links-motion-state-duration sys.motion.role.state.large 250ms
--tanrei-comp-previous-next-links-motion-state-easing sys.motion.easing.state cubic-bezier(0.2, 0, 0, 1)
--tanrei-comp-previous-next-links-outline-width sys.border.hairline 1px
--tanrei-comp-previous-next-links-pressed-container-shape — 8px
--tanrei-comp-previous-next-links-pressed-opacity — 1
--tanrei-comp-previous-next-links-label-typescale sys.typescale.label-small 500 12px/1.3333
--tanrei-comp-previous-next-links-title-typescale sys.typescale.body-large 400 16px/1.625

フィクスチャ

基準となる描画パターンです。全プラットフォームが同じ ID でスナップショットを撮り、結果を比較できるようにしています。

生成元 specs/previous-next-links.spec.json, tokens/comp/previous-next-links.tokens.json, design/tokens/

Web での描き方の違い

  • 縦に並ぶ形は、nav の幅から決まるグリッド自身の列数で描きます。コンテナクエリもメディアクエリも使いません。
  • パッケージのスクリプトがなくても、スタイルシートがすべての状態を描きます。このとき、押下への応え方はオーバーレイです。次の項目を先に書いた場合、描かれる順序は正しくなりますが、フォーカスの順序は次が先のままです。前の項目を先に書いてください。
  • スタイルシートは、右から左のレイアウトで両方の矢印を反転します。アイコンセットがどちらのグリフも反転の対象にしていないデザインシステムでは、スクリプトが反転を取り消します。スクリプトがなければ、項目に data-mirror="never" を書いてください。
  • 前後のリンクは .tanrei-prose の外か、tanrei-not-prose を付けた部分の中に置いてください。プローズは、その中のアンカーをテキストリンクとして描きます。

ガイドライン

推奨

  • コンテンツの後に、1 ページに 1 つだけ置きます。
  • どのページでも両方の項目を書き、行き先のないほうは href を付けずにおきます。href のない項目は描かれません。
  • 方向は、プロダクトの言葉で書きます。「前へ」と「次へ」、「新しい記事」と「古い記事」などです。

非推奨

  • アドレスを変えずに表示だけを切り替えるボタンとして使わない。項目はリンクです。
  • リストやテーブルを番号でめくるために使わない。それはページネーションの役目です。
  • 隣のページを新しいタブで開かない。ひと続きのページは、その場で入れ替わっていくものです。
  • 項目に独自のグリフを付けない。

アクセシビリティ

ロール
navigation
ラベル付け
The landmark is named by label, which is required: a page has other navigation, and the name tells this one apart. Each item is a link named by its label and then its title ("Next Design tokens"), both of which are drawn, so the name a person hears holds the words a person sees; the arrow is decorative. Nothing is added to the name.
最小ターゲット
見た目のサイズが小さくても、ヒット領域は最小ターゲットサイズを満たします。 minimum 32px · pointer 44px · spacing 8px · touch 48px

キーボード操作

キー 動作
Tab Moves focus to the previous item, then to the next: each drawn item is a tab stop, as the links of a navigation region are.
Enter Follows the focused item. Space does what it does on any link (on the web it scrolls the page).

備考

  • An item is a link and never a button: it has a destination, and without one it is not drawn. Paging by number — the pages of a list or a result set, with or without an address for each — is Pagination, a component of its own: these links say where they lead by its title, a page number says nothing of the sort.
  • An item is pressed as a whole, so its title is not a second link and is not underlined. A text link is underlined because nothing else tells it from the text beside it; an item is told by its edge, its arrow and its place, none of which is a color. In forced colors the edge and the text take the platform's link color (PNL-18).
  • The reading and focus order is previous, then next, in both layout directions and when the items stack; the visual order follows it (WCAG 1.3.2, 2.4.3).
  • The direction is said in words by label. The arrow repeats it for sighted people and is hidden from assistive technology; an item with an empty label is reported in debug builds.
  • The next item keeps its place when there is no previous page (PNL-4): a person who pages through a sequence finds it where it was.
  • Text must remain readable at 200% text size: titles wrap and are never cut, the items grow, and the row stacks by the width it has (PNL-5, PNL-19).
  • Contrast in the default system: the title is on-surface and the label and the arrow on-surface-variant, both held to 4.5:1 (7:1 in the high-contrast schemes) on every surface by the token invariants. The edge is outline-variant, the one hairline: it is not held to 3:1, and it does not need to be, because the label, the title and the arrow identify the item without it (WCAG 1.4.11 asks 3:1 of what is required to identify a control). The focus ring is held to 3:1 against every surface.
  • How a state looks is a value decision of the active design system (a state-layer mix in Tanrei, a dim or no hover at all elsewhere). The previous and next links read the state's tokens and never computes the effect itself.
  • A pair of previous and next links belongs after the content it pages, once per page. A product that prints its pages hides it in print.

生成元 specs/previous-next-links.spec.json, tokens/sys/measure.tokens.json

コンポーネントが担うこと

  • それぞれの項目はブラウザー自身のリンクで、名前はラベル、タイトルの順です(「次へ デザイントークン」)。どちらも画面に描かれています。
  • 矢印は装飾で、支援技術からは隠されます。
  • 見た目の順序は、読む順序と同じです。左から右でも右から左でも、縦に並んだときも、前、次の順です。
  • キーボードフォーカスのリングは、項目の周りに描きます。タイトルは折り返し、項目は読み手の文字サイズに合わせて大きくなります。

利用者側で行うこと

  • ランドマークには、aria-label でプロダクトの言語の名前を付けます。ページにはほかのナビゲーションもあるので、名前で区別できるようにします。Tanrei は言葉を同梱しません。
  • アンカーに rel="prev" と rel="next" を書きます。
  • 前の項目を、次の項目より先に書きます。