跳到主要内容
menumenu tanreiexpand_morecontrasttranslate
tanreiexpand_more
开始使用WebReactSwiftUIJetpack ComposeFlutterReact Native预设你自己的设计系统与 AI 代理一起使用 Tanrei品牌设计令牌设计系统与定制Theme Studio颜色字体排印图标形状层级动效交互状态行为布局无障碍文字颜色令牌字阶令牌形状令牌层级令牌动效令牌状态令牌间距与度量令牌组件按钮主操作按钮分段按钮按钮组带菜单的按钮工具栏复制按钮复选框单选按钮开关纸片(Chip)菜单滑块滑块字段日历DateTimePicker字段组单选组复选框组下拉选择框下拉选择字段菜单栏文件上传文件选择器 进阶放置区文本输入框 进阶文本字段纸片字段字段组合框 进阶组合框字段数字输入框 进阶数字字段颜色输入框 进阶颜色字段一次性验证码输入框 进阶一次性验证码字段嵌入式文本输入框 进阶聊天输入栏卡片分隔线模态层 进阶对话框列表列表行底部面板侧边面板轮播代码块表格弹出框步骤折叠面板描述列表图示应用外壳页头树视图时间线图片预览调整手柄可调整大小的框滚动区域徽标进度指示器计量条数字滚动器加载指示器消息条(Snackbar)工具提示键盘快捷键标签(Tag)行内代码提示块(Callout)头像空状态标签组(Tag group)骨架屏文件项色块跑马灯文本标签页标签页视图应用栏导航栏导航抽屉搜索链接分页上一页/下一页链接步骤条面包屑目录链接卡片FAB 菜单状态Tanrei 是如何构建的参与贡献许可与致谢
首页组件分页

分页

在同一个列表的各个编号页面之间移动。带有当前页标记的页码、上一页和下一页、按需提供的第一页和最后一页,以及只说明“第几页、共几页”的简短形式。

content_copy以 Markdown 格式查看
类别
导航
令牌
comp.pagination
层级
基础

概览

Web
tanrei-pagination
clock_loader_40
SwiftUI
TanreiPagination
radio_button_unchecked
Jetpack Compose
TanreiPagination
radio_button_unchecked
Flutter
TanreiPagination
radio_button_unchecked
React Native
Pagination
radio_button_unchecked

生成自 docs/status/status.json, specs/pagination.spec.json

带页码的形式,以及带第一页和最后一页的形式

分页按页码为同一个列表翻页:搜索结果、一个博客的帖子、一个表格的行。在一系列有标题的页面(例如一份指南的各章)之间前后移动的是上一页/下一页链接:标题说明它通向哪里,页码说明不了。

用法

给出当前页和总页数。要显示哪些页码,由分页自己算出。有 href 时,每一页都是指向它自己地址的链接。没有时,各页是按钮,页面变化时由你更换显示的内容。

<!-- 链接:每一页都有可以收藏、分享或在新标签页中打开的地址。{page} 会填入页码。 -->
<tanrei-pagination label="搜索结果的页面" page="3" count="12" href="/results/?page={page}"
  previous-label="上一页" next-label="下一页" page-label="第 {page} 页"></tanrei-pagination>

<!-- 按钮:页面在原地变化。元素先设置自己的 page,再触发 change;取消它,页面就保持不变。 -->
<tanrei-pagination id="pages" label="页面" page="1" count="10"
  previous-label="上一页" next-label="下一页" page-label="第 {page} 页"></tanrei-pagination>

<script type="module">
  import '@tanrei/web/components/pagination';
  document.querySelector('#pages').addEventListener('change', (e) => showPage(e.detail.page));
</script>
import { Pagination } from '@tanrei/react';

<Pagination label="页面" page={page} count={10}
  previousLabel="上一页" nextLabel="下一页" pageLabel="第 {page} 页"
  onChange={(e) => setPage(e.detail.page)} />

SwiftUI、Compose、Flutter 和 React Native 尚在计划中:本页开头各平台旁边的名称是规格为它们定下的,这些平台目前还没有提供任何实现。

文字由你提供:Tanrei 自己不提供任何文字。可以在每个元素上分别给出,也可以用 setWords() 为整个产品一次性给出(previousPageLabel、nextPageLabel、firstPageLabel、lastPageLabel、pageLabel、pageCountText)。

规格

简短形式,以及小尺寸

在窄栏中,带页码的形式会变成简短形式

  • 显示哪些页码。 第一页和最后一页(boundaries,默认为 1),当前页以及它两侧各一页(siblings,默认为 1)。它们之间省去的页合为一个省略号。靠近两端时,另一侧会多显示几页,因此每一页上这一行的位置数都相同,宽度也保持不变。
  • 当前页以填充色绘制,并作为当前页公开。激活它不会发生任何事。
  • 上一页和下一页只有图标。在第一页和最后一页上它们被禁用,但保留各自的位置。加上 first-last 时,第一页和最后一页画在它们外侧。
  • 简短形式(variant="compact")在上一页和下一页之间画出你的句子“第 3 页,共 10 页”。没有句子时,它画出用斜线连接的两个数字“3 / 10”,开发构建会报告缺少文字。带页码的形式在给定宽度放不下时,会自己变成简短形式。
  • 两种尺寸:medium(40)和 small(32),后者用于紧凑的地方,例如表格的状态行。
  • 从右到左时,这一行从右侧排起,箭头会镜像。数字用页面语言的数字书写。

构成

部件 说明
1 root The navigation landmark: as wide as its layout gives it, holding one row of items at its start edge. It draws nothing of its own.
2 item One place of the row that can be pressed: a page, or one of the controls first, previous, next and last. As high as its size, at least as wide, and where hover, focus and press are drawn.
3 label A page's number, in the digits of the language of where the pagination is used.
4 icon The arrow of a control, from the system's icon set: first_page, chevron_left, chevron_right and last_page. Decorative; mirrored in a right-to-left layout by the icon helper.
5 ellipsis · 可选 The mark that stands for the pages left out, in a place as wide as an item. It is not a control and is hidden from assistive technology.
6 count · 可选 The short form's sentence, between previous and next: which page of how many ("Page 3 of 10").
7 focus-ring The indicator shown for keyboard focus, around an item.

属性

属性 类型 默认值 说明
label string "" The accessible name of the landmark ("Pages", "Search results pages"), 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.
page number 1 The current page, counted from 1. Activating another page sets it (PGN-7).
count number 1 How many pages there are. Below 1 the pagination draws nothing (PGN-3).
siblings number 1 How many pages are shown on each side of the current page in the numbered form (PGN-2).
boundaries number 1 How many pages are always shown at the start and at the end of the numbered form (PGN-2).
variant numbered | compact "numbered" numbered: the page numbers, with the controls on either side; it draws the compact form where its row does not fit (PGN-11). compact: the controls and the sentence that says which page of how many, never the numbers — for a narrow place, a table's status line, or a list whose pages are not reached by number.
size small | medium "medium" An item's height (32 / 40 under the default system). small is for a dense place, such as the status line of a compact table. The hit area always meets the minimum target. A design system may add sizes.
firstLast boolean false Draws first and last on either side of previous and next, for a list long enough that its ends are worth a control of their own.
href string "" The address of a page, with the place {page}, which the pagination fills with the page's number ("/results/?page={page}"). Not empty, every page and every control is a link to its page's address (PGN-6). Empty, they are buttons, and the product changes what is shown when the page changes (PGN-7).
previousLabel string "" The previous control's accessible name ("Previous page"). Empty reads the product's words. Required.
nextLabel string "" The next control's accessible name ("Next page"). Empty reads the product's words. Required.
firstLabel string "" The first control's accessible name ("First page"). Empty reads the product's words. Required while firstLast is true.
lastLabel string "" The last control's accessible name ("Last page"). Empty reads the product's words. Required while firstLast is true.
pageLabel string "" A page's accessible name, with the place {page}, which the pagination fills with the page's number as it draws it ("Page {page}", "{page}ページ"). Empty reads the product's words; where neither gives one, a page is named by its number alone.
countText string "" The short form's sentence, which the product writes whole in its own language with two places the pagination fills: {page} with the current page and {count} with the number of pages ("Page {page} of {count}", "{count}ページ中{page}ページ"). Empty reads the product's words; where neither gives one, the short form draws the two numbers with a slash between them ("3 / 10"), and a debug build reports it.

事件

事件 说明
change The user asked for another page, by a page or by first, previous, next or last; carries the page asked for. It is emitted before the page changes and before a link opens its address; a product that cancels it keeps the page as it was and opens nothing — its own router has taken the navigation (PGN-7).

状态

行为

以 EARS 形式写成的需求。每个平台的实现都按这些 ID 逐条测试。需求原文取自规格文件,原样以英文呈现。

ID 需求
PGN-1 THE pagination SHALL be one navigation landmark named by label that holds its items as one list in reading order — first, previous, the pages and ellipses, next, last; in the compact form first, previous, the count sentence, next, last — and nothing else; WHILE label is empty THE pagination SHALL still render, and in debug builds report that the landmark has no accessible name.
PGN-2 THE numbered form SHALL show the pages 1 to boundaries, the pages count − boundaries + 1 to count, and the current page with siblings pages on each side of it, and SHALL draw an ellipsis in place of the pages left out between two of these runs; WHERE the ellipsis would stand for one page only THE numbered form SHALL draw that page instead. WHILE the current page is near an end THE numbered form SHALL show more pages on the other side of it, so that the row holds the same number of places — 2 × boundaries + 2 × siblings + 3 — on every page whenever count is at least that many, and the row keeps its width from page to page.
PGN-3 THE pagination SHALL read count as a whole number, and WHILE it is below 1 or cannot be read SHALL draw nothing, take no room and expose no landmark; it SHALL read page as a whole number held between 1 and count, and siblings and boundaries as whole numbers of 0 or more (boundaries 0 shows no end pages, so that an ellipsis stands at an end), and in debug builds report each value it had to change.
PGN-4 THE pagination SHALL draw the current page from the current tokens (comp.pagination.current.container.color, comp.pagination.current.label.color and so on) and every other page and every control from the item tokens, and SHALL expose the current page as the current one (on the web aria-current="page") while keeping it the same kind of element as the other pages: a link to its own address while href is given, a button otherwise. WHEN the current page is activated THE pagination SHALL emit no change; a current page that is a link still opens its own address, as any link does.
PGN-5 WHILE the current page is 1 THE pagination SHALL draw first and previous disabled, and WHILE it is count, next and last disabled: drawn from the disabled state's tokens, exposed as disabled, out of the focus order and not activatable, and in their places, so that the row keeps its width; a disabled control of a pagination with href SHALL have no address.
PGN-6 WHILE href is not empty THE pagination SHALL draw every page and every enabled control as the platform's own link to href with {page} filled with the page it leads to, written as a whole number in Western digits whatever the language, so that whatever the platform gives a link — on the web its context menu, opening in a new tab, copying its address, the address shown before it is followed — is the platform's; it SHALL expose the link role and WHERE the platform's links can say how a destination relates to the page (the web's rel) SHALL say prev for previous and next for next. IF href does not hold the place {page}, or names a script to run (the web's javascript: scheme), THE pagination SHALL draw buttons as if href were empty and in debug builds report it.
PGN-7 WHEN the user activates a page other than the current one, or an enabled control, by pointer, touch, Enter, Space on a button or assistive technology THE pagination SHALL emit change exactly once with the page it leads to — first 1, previous page − 1, next page + 1, last count — and then, unless the product cancelled it, SHALL make that page the current one and, while href is given, open the link's address where the person is; WHEN the product cancels change THE pagination SHALL keep the page it had and open nothing. A link SHALL NOT be activated by Space, which scrolls the page as it does on any link.
PGN-8 THE pagination SHALL draw previous, next, first and last as icons only — chevron_left, chevron_right, first_page and last_page of the system's icon set, through the platform's icon helper, in a box of comp.pagination.icon.size, in the icon color of their 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 — and SHALL name them by previousLabel, nextLabel, firstLabel and lastLabel, taking each from the product's words WHILE it is empty; WHILE a control's name is empty in both THE pagination SHALL still draw it and in debug builds report that it has no accessible name. It SHALL take no glyph from the product and SHALL draw no path of its own.
PGN-9 THE pagination SHALL draw a page's number in comp.pagination.label.typescale, in the digits the platform's number formatting gives for the language where it is used, without grouping separators (1205, not 1,205), and in figures of one width, and SHALL name the page by pageLabel with {page} filled by the number as it is drawn, taking pageLabel from the product's words WHILE it is empty and naming the page by its number alone WHILE neither gives one; the number drawn SHALL stay part of the name, so that a person who says what they see can activate the page.
PGN-10 THE pagination SHALL draw an ellipsis as the character … in comp.pagination.label.typescale and comp.pagination.ellipsis.color, centred in a place as wide as an item is high (comp.pagination.container.height.medium for medium, and so on), hidden from assistive technology, out of the focus order and with no state: the pages left out are said by the numbers on either side of it.
PGN-11 WHILE variant is compact, or variant is numbered and the width the layout gives the pagination is less than its numbered row needs, THE pagination SHALL draw the compact form: first and previous, then countText with {page} and {count} filled, comp.pagination.count.padding-inline on each side, in comp.pagination.count.typescale and comp.pagination.count.color, then next and last; WHILE countText is empty in both the prop and the product's words THE compact form SHALL draw the two numbers with a slash between them ("3 / 10") and in debug builds report it. It SHALL decide this by the width it is given, not by the window's, and the width it asks of a layout that sizes it by its content SHALL be the width of its numbered row, so that it draws the numbered form again where the room comes back. The sentence is text, not a control and not a live region: the product says what changed where the content changes.
PGN-12 THE pagination SHALL lay its items out in one row at the start edge of its box, comp.pagination.gap apart, each item the container height of its size high (comp.pagination.container.height.medium for medium, and so on) and at least as wide, a page's number centred in it with comp.pagination.container.padding-inline on each side where the number is wider than the square, and each control's arrow centred in its square; it SHALL NOT wrap the row.
PGN-13 WHILE an item is hovered, keyboard-focused, pressed or disabled THE pagination SHALL render its container, label, arrow and opacity from the component tokens of the highest-precedence active state of its part (item or current), with precedence disabled over pressed over focused over hovered; focus gained by pointer or touch SHALL NOT select the focused state.
PGN-14 WHEN an item receives keyboard focus THE pagination SHALL show the focus ring around that item 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.
PGN-15 WHEN an enabled item is pressed by pointer, touch, Enter or, on a button, Space THE pagination 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; it SHALL NOT hold the change or the navigation back for press-hold.
PGN-16 WHILE pressed THE pagination 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 item 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, icon, 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.pagination.motion.feedback-duration with comp.pagination.motion.state-easing, fades over comp.pagination.motion.state-duration with comp.pagination.motion.state-easing once the press has ended and press-hold has passed, and appears whole where motion is reduced.
PGN-17 THE pagination SHALL ease its item 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.
PGN-18 THE pagination SHALL change an item between its states over comp.pagination.motion.state-duration with comp.pagination.motion.state-easing, and at once where motion is reduced; WHEN the current page changes THE pagination SHALL change the item that was current and the item that becomes current between their states as it changes any item's, and SHALL draw at once the items whose page numbers or places change.
PGN-19 THE pagination SHALL make each enabled item one stop of the focus order, in the order of PGN-1, as the links and buttons of a navigation region are, and SHALL take no arrow key: Tab and Shift+Tab move between items. WHEN the current page changes by an item the person activated THE pagination SHALL keep focus on an item: on the page now current where the person activated a page, and on the control they activated where it is still enabled, otherwise on the page now current — and in the compact form, which draws no pages, on the nearest enabled control (previous after next or last, next after previous or first).
PGN-20 WHERE the visual size of an item is below the minimum target THE pagination 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 and without overlapping the hit area of its neighbour beyond the gap between them; a platform that cannot tell the input type SHALL use sys.target.touch.
PGN-21 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 pagination SHALL draw the numbers, the arrows and the count sentence in the platform's text or link color, the current page in the platform's highlight colors, a disabled control in the platform's disabled text color, and the focus ring in the platform's highlight color.
PGN-22 WHILE the text size is enlarged THE pagination SHALL grow each item with its number, never below the container height of its size (comp.pagination.container.height.medium for medium, and so on), keeping comp.pagination.gap and the arrows at comp.pagination.icon.size, and SHALL draw the compact form where the grown row no longer fits (PGN-11).
PGN-23 THE pagination 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; WHERE that direction is right-to-left THE pagination SHALL lay its row from the right — first at the right edge, last at the left — keeping the reading and focus order of PGN-1, and SHALL draw the arrows mirrored where the system's icon set marks them as mirrored; THE pagination SHALL NOT mirror a glyph itself. WHEN the direction changes while the pagination is shown THE pagination SHALL draw itself for the new direction at once, keeping its focus.
PGN-24 THE pagination SHALL lay out the count sentence as text of its own direction, isolated from the text around it, and each number as a number that keeps its own order in a right-to-left layout, so that "3 / 10" reads 3 then 10 in either direction.
PGN-25 WHERE the platform has ARIA attributes (the web), WHEN the product sets an aria- attribute on the host, by the attribute or by the ARIA property that reflects it, THE pagination SHALL move it to the data-aria- attribute of the same name, so that the host is no second node with its name, description or state, and SHALL expose it on its navigation landmark (PGN-1) — an id reference by the elements it names in the host's tree or a tree around it, a description after its own. WHILE label is not empty it is the landmark's name, over a name given so; WHILE label is empty, a name given so is the landmark's name and SHALL NOT be reported as having none in debug builds. WHEN the product removes the aria- attribute or its data-aria- twin, or sets the ARIA property that reflects it (ariaLabel, ariaDescribedByElements…) to null, THE pagination SHALL take it off that element.

各平台名称对照

对等并不意味着 API 完全相同。同一份契约,由各平台以自己的惯用方式表达。

规格 Web SwiftUI Jetpack Compose Flutter React Native
组件 tanrei-pagination TanreiPagination TanreiPagination TanreiPagination Pagination
label · 属性 label label contentDescription semanticLabel accessibilityLabel
page · 属性 page page page page page
count · 属性 count count count count count
siblings · 属性 siblings siblings siblings siblings siblings
boundaries · 属性 boundaries boundaries boundaries boundaries boundaries
variant · 属性 variant variant variant variant variant
size · 属性 size size size size size
firstLast · 属性 firstLast showsFirstLast showFirstLast showFirstLast showFirstLast
href · 属性 href destination hrefFor hrefFor hrefFor
previousLabel · 属性 previousLabel previousLabel previousLabel previousLabel previousLabel
nextLabel · 属性 nextLabel nextLabel nextLabel nextLabel nextLabel
firstLabel · 属性 firstLabel firstLabel firstLabel firstLabel firstLabel
lastLabel · 属性 lastLabel lastLabel lastLabel lastLabel lastLabel
pageLabel · 属性 pageLabel pageLabel pageLabel pageLabel pageLabel
countText · 属性 countText countText countText countText countText
change · 事件 change onChange onPageChange onPageChanged onPageChange
备注 <tanrei-pagination label="Pages" page="3" count="10" previous-label="Previous page" next-label="Next page" page-label="Page {page}">; the attributes are the props in kebab case (first-last, count-text). The element draws a nav with aria-label around one ol in its shadow root; each page and control is an a (with href) or a button, the current page with aria-current="page", a disabled link an a without href and with aria-disabled="true" and role="link". change is a cancelable CustomEvent whose detail is { page }, fired before page changes and, for a link, before the browser follows it. The narrow form is decided by a ResizeObserver on the element against its numbered row, which is kept in the layout at no height so that the element asks for its width. React: the generated Pagination wrapper, with onChange. TanreiPagination(label:page: $page, count:, destination: { page in URL? }): page is a Binding<Int>; destination is a closure from a page to an optional URL, the idiom for the href with its place; with one, each item is a Link. onChange returns whether to take the page. The narrow form is a ViewThatFits of the numbered row and the compact one. TanreiPagination(page, count, onPageChange = { page -> true }, contentDescription = …); hrefFor: ((Int) -> String)? opens through LocalUriHandler. Compose has no navigation landmark and no link role for a clickable element: the row is a semantics group named by contentDescription, the current page selected, and its README says what is not exposed. The narrow form reads the incoming constraints (SubcomposeLayout). TanreiPagination(page: 3, count: 10, onPageChanged: (page) => true, semanticLabel: …); hrefFor: String Function(int)? makes each item Semantics(link: true) with linkUrl, opened by the opener the app provides. The narrow form reads the incoming constraints (LayoutBuilder). <Pagination accessibilityLabel="Pages" page={3} count={10} onPageChange={(event) => …} />; onPageChange receives an event with page whose preventDefault() keeps the page. Each item is a Pressable with accessibilityRole="link" (with hrefFor) or "button", the current page accessibilityState={{ selected: true }}. The narrow form reads onLayout.

令牌

令牌 引用 解析值(浅色)
--tanrei-comp-pagination-container-height-medium — 40px
--tanrei-comp-pagination-container-height-small — 32px
--tanrei-comp-pagination-container-padding-inline sys.space.space100 8px
--tanrei-comp-pagination-container-shape sys.shape.corner.full 9999px
--tanrei-comp-pagination-count-color sys.color.on-surface #1b1b1b
--tanrei-comp-pagination-count-padding-inline sys.space.space100 8px
--tanrei-comp-pagination-current-container-color sys.color.secondary-container #eeeeee
--tanrei-comp-pagination-current-disabled-container-color — #1b1b1b · 12%
--tanrei-comp-pagination-current-disabled-icon-color — #1b1b1b · 38%
--tanrei-comp-pagination-current-disabled-label-color — #1b1b1b · 38%
--tanrei-comp-pagination-current-disabled-state-layer-color — #1b1b1b · 38%
--tanrei-comp-pagination-current-focused-container-color — #dadada
--tanrei-comp-pagination-current-focused-icon-color — #262626
--tanrei-comp-pagination-current-focused-label-color — #262626
--tanrei-comp-pagination-current-focused-state-layer-color — #262626
--tanrei-comp-pagination-current-hovered-container-color — #dedede
--tanrei-comp-pagination-current-hovered-icon-color — #262626
--tanrei-comp-pagination-current-hovered-label-color — #262626
--tanrei-comp-pagination-current-hovered-state-layer-color — #262626
--tanrei-comp-pagination-current-icon-color sys.color.on-secondary-container #262626
--tanrei-comp-pagination-current-label-color sys.color.on-secondary-container #262626
--tanrei-comp-pagination-current-pressed-container-color — #dadada
--tanrei-comp-pagination-current-pressed-icon-color — #262626
--tanrei-comp-pagination-current-pressed-label-color — #262626
--tanrei-comp-pagination-current-pressed-state-layer-color — #262626
--tanrei-comp-pagination-current-state-layer-color comp.pagination.current.label.color #262626
--tanrei-comp-pagination-disabled-container-shape — 9999px
--tanrei-comp-pagination-disabled-opacity — 1
--tanrei-comp-pagination-ellipsis-color sys.color.on-surface-variant #4b4b4b
--tanrei-comp-pagination-focused-container-shape — 9999px
--tanrei-comp-pagination-focused-opacity — 1
--tanrei-comp-pagination-gap sys.space.space50 4px
--tanrei-comp-pagination-hovered-container-shape — 9999px
--tanrei-comp-pagination-hovered-opacity — 1
--tanrei-comp-pagination-icon-size sys.icon.small 20px
--tanrei-comp-pagination-item-container-color — #000000 · 0%
--tanrei-comp-pagination-item-disabled-container-color — #000000 · 0%
--tanrei-comp-pagination-item-disabled-icon-color — #1b1b1b · 38%
--tanrei-comp-pagination-item-disabled-label-color — #1b1b1b · 38%
--tanrei-comp-pagination-item-disabled-state-layer-color — #1b1b1b · 38%
--tanrei-comp-pagination-item-focused-container-color — #1b1b1b · 10%
--tanrei-comp-pagination-item-focused-icon-color — #1b1b1b
--tanrei-comp-pagination-item-focused-label-color — #1b1b1b
--tanrei-comp-pagination-item-focused-state-layer-color — #1b1b1b
--tanrei-comp-pagination-item-hovered-container-color — #1b1b1b · 8%
--tanrei-comp-pagination-item-hovered-icon-color — #1b1b1b
--tanrei-comp-pagination-item-hovered-label-color — #1b1b1b
--tanrei-comp-pagination-item-hovered-state-layer-color — #1b1b1b
--tanrei-comp-pagination-item-icon-color sys.color.on-surface #1b1b1b
--tanrei-comp-pagination-item-label-color sys.color.on-surface #1b1b1b
--tanrei-comp-pagination-item-pressed-container-color — #1b1b1b · 10%
--tanrei-comp-pagination-item-pressed-icon-color — #1b1b1b
--tanrei-comp-pagination-item-pressed-label-color — #1b1b1b
--tanrei-comp-pagination-item-pressed-state-layer-color — #1b1b1b
--tanrei-comp-pagination-item-state-layer-color comp.pagination.item.label.color #1b1b1b
--tanrei-comp-pagination-motion-feedback-duration sys.motion.role.feedback 450ms
--tanrei-comp-pagination-motion-state-duration sys.motion.role.state.compact 200ms
--tanrei-comp-pagination-motion-state-easing sys.motion.easing.state cubic-bezier(0.2, 0, 0, 1)
--tanrei-comp-pagination-pressed-container-shape — 9999px
--tanrei-comp-pagination-pressed-opacity — 1
--tanrei-comp-pagination-count-typescale sys.typescale.body 400 14px/1.5714
--tanrei-comp-pagination-label-typescale sys.typescale.label 500 14px/1.4286

测试样例

作为基准的渲染结果。所有平台都以相同的 ID 为每个样例截取快照,以便相互比较。

生成自 specs/pagination.spec.json, tokens/comp/pagination.tokens.json, design/tokens/

指南

推荐

  • 把它放在它所翻页的列表之后;列表很长时,列表之前也放一个。
  • 每一页都有自己的地址时用链接(href),页面在原地变化时用按钮。
  • 在表格下方,在状态行里使用 small 尺寸的简短形式;如果让用户选择每页行数,就在它旁边放一个用于此事的下拉选择框。当前显示的行的范围(“第 1–10 件,共 248 件”)是表格的状态文字。
  • 页面变化时,在内容变化的地方说明变化了什么:一个标题,或者表格的状态文字。分页自己不朗读任何内容。

避免

  • 不要用它在一系列有标题的页面之间前后移动。那是上一页/下一页链接。
  • 不要为只有一页的列表显示它。
  • 不要在第一页和最后一页上隐藏上一页和下一页。它们被禁用并保留位置。

无障碍

角色
navigation
标注
The landmark is named by label, which is required: a page has other navigation, and the name tells this one apart. Each page is named by pageLabel with its number ("Page 3"), which holds the number a person sees; the current page is exposed as the current one (aria-current="page"), so the name says nothing of it. The controls are icon-only and named by previousLabel, nextLabel, firstLabel and lastLabel. The arrows and the ellipsis are hidden from assistive technology.
最小目标
即使外观尺寸更小,点击区域也满足最小目标尺寸。 minimum 32px · pointer 44px · spacing 8px · touch 48px

键盘操作

按键 动作
Tab / Shift+Tab Moves focus through the enabled items in reading order: each page and each enabled control is a tab stop, as the links of a navigation region are. The current page is a stop too; a disabled control is not.
Enter Activates the focused item: goes to its page.
Space Activates the focused item where the items are buttons. Where they are links it scrolls the page, as on any link.

备注

  • A pagination pages one list by number. The page before and after in a sequence of titled pages — the chapters of a guide, the articles of a series — is Previous and next links, which say by title where they lead.
  • Links or buttons: a page with an address of its own (a result page a person can bookmark, share or open in a tab) is a link; a list whose page changes in place (the rows of a table, a dialog's list) is a button. href decides.
  • The current page is marked by its fill and by aria-current, never by color alone: its fill differs from the rest in lightness, and forced colors draw it in the highlight colors (PGN-21).
  • Disabled controls keep their places, so a person who pages through a list finds next where it was (PGN-5). They are out of the focus order: there is nothing to go to.
  • The ellipsis is not a control. A person reaches a page it stands for by moving towards it, or by the product's own way to jump to a page; a pagination does not draw a field to type a page into.
  • How many rows a page holds, and the range of rows shown ("1–10 of 248"), are the list's and not the pagination's: a table says them in its status line, where the pagination stands beside a Select for the rows per page.
  • The short form is text: when the page changes, the product says what changed where the content changes (a heading, a status). The pagination announces nothing.
  • Contrast in the default system: the numbers and arrows are on-surface, held to 4.5:1 (7:1 in the high-contrast schemes) by the token invariants, and the current page's number on-secondary-container on its fill. 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 pagination reads the state's tokens and never computes the effect itself.
  • A pagination belongs after the list it pages, and where the list is long, before it too; both name the same landmark by different labels.

生成自 specs/pagination.spec.json, tokens/sys/measure.tokens.json

组件负责的部分

  • 一个导航地标包住一个列表。每一页和每个启用的控件都是一个链接或按钮,也是焦点顺序中的一站。
  • 当前页以 aria-current="page" 公开,并以填充色绘制,而不只是换一种颜色。
  • 禁用的控件不在焦点顺序中。箭头和省略号对辅助技术隐藏。
  • 一页的名称包含人们看到的数字,所以说出所见内容来操作的人也能激活它。

需要你做的事

  • 用 label 为这个地标命名,使用你的产品的语言。页面上还有别的导航,这个名称把它与它们区分开。
  • 为各控件命名(previous-label、next-label,有 first-last 时再加上 first-label 和 last-label),并用 page-label 为各页命名。Tanrei 自己不提供任何文字。
  • 更换列表时,说明变化了什么。分页会把焦点留在它的某一项上:被激活的控件;如果该控件已被禁用,则是新的当前页。