表单
Slider - 滑块
在一段范围里选一个值。
用法
import { Slider } from '@misoto22/folio'说明
在一段范围里选一个值。
键盘契约归 Radix——方向键走一步,Page 键跳一大步,Home 和 End 到两端——报告值的那套 ARIA 也归它。留在这里的是外观,以及命名,而后者正是滑块最常做错的那一半:一个只报「42」、别的什么都不说的滑块,留给读屏用户的是一个数字,和不知道它在量什么。
16px 的滑块外面有一圈看不见的 44px 命中区,因为一个按设计尺寸做的滑块,远在任何指针目标准则之下。
editable 是滑块做不到的那件事的答案。只要确切的数字才是重点——预算、超时、价格——就打开它;而当这个值本来就是个大概时,把它关掉,因为一个框会招来这项设置未必具备的精度。
放在 Field 里时,hint、error 和必填标记落在滑块上,也就是带着 role="slider" 的那个元素——落在根节点上的话,它们会待在一个没有 role 的 <span> 上,什么都播报不出来。名字仍然来自这里的 label:Field 上方那个标签指的是同一个没有 role 的根节点,所以它既命名不了这个控件,也点不进去。
结构
| 部件 | 说明 |
|---|---|
| 轨道必填 | 一条 --stone 的 1px 细线;只要指针落在这个控件上的任何位置——不必落在滑块上——它就加粗到 1.5。 |
| 已选区间 | 从最小值到滑块的那段 --accent 填充;范围滑块则是两个滑块之间的那一段。 |
| 滑块 | value 数组里每有一项就有一个——所以滑块的个数来自值,不来自某个属性;而一个既没给 value 也没给 defaultValue 的滑块,会退回原语自己的默认:一个停在最小值上的滑块。每一个都是 16px 的圆,外面有一圈由 before 伪元素撑出来的、看不见的 44px 命中区。 |
| 数值行 | 只有设了 showValue 才有:轨道上方一行等宽字,名字靠行首、格式化后的值靠行尾,各自用一个连接号连起来,顺序和滑块本身的顺序一致——所以一个两端的范围读出来是「Minimum – Maximum」压在「10 – 90」上面。 |
| 可编辑读数 | editable 会把那些数字变成这个:每个滑块一个框,静止时显示 format 的输出,拿到焦点时显示光秃秃的数字,所以读者看到的仍然是「$1,200」,而打字的人从不会被要求把货币符号也敲一遍。每个框都和它驱动的那个滑块分开命名——两个控件都播报成「Quality」,等于同一个控件被念了两遍。 |
实践建议
推荐
- 只要它不止一端,就要传 defaultValue 或 value。滑块的个数来自那个数组,所以一个放任默认的价格筛选,是一个停在最小值上的单滑块。
- 双滑块的范围要传两个名字的数组:第一个之后的每一个滑块都退回 names[0],否则价格筛选的两端都把自己播报成「最小值」。
- 确切的数字要紧时,把 editable 打开。滑块自己没法打字,而一个要的是 37、不是「大概 40」的人,只能拖着 16px 的滑块在一百个步长里挪过去——读数里那个框就是出路,它顶替了这里过去要求的第二个 Input。
避免
- format 会成为每个滑块的 aria-valuetext,而它是顶替那个数字,不是给它加装饰——所以一个把数字狠狠取整、或者把单位丢掉的格式化函数,就是读屏用户拿到的全部,值本身他拿不到。
- editable 打进去的数字,除了受 min 和 max 约束,也受相邻那个滑块约束,而且只能这样:往一个上端停在 70 的区间的下端里打 90,否则两个滑块就交叉过去了。所以一个数字可以被接受、然后落在别处,而那个框显示的是它落在了哪儿。
- 不要靠禁用一个滑块来让它只读:整个控件会变淡、不再接收指针,Radix 还会把滑块从 Tab 顺序里丢出去,于是那个值变成了够不着,而不是不可编辑。
- 不要给单滑块传两个名字:那一行是每个滑块打印一个名字,所以第二个名字哪儿都没画出来,也哪儿都没播报出来。
- Field 上方那个标签既命名不了它,也点不进去:role 长在滑块上,而根节点是一个 <span>,所以这里的 label 属性是读者唯一听得到的名字。hint 和 error 倒是抵达得了滑块。
示例
default
一个值,然后两个,都开着读数。永远要传 defaultValue 或 value:那些滑块是从这个组件自己的数组渲染出来的,不是从 Radix 的默认值,所以一个两个都没给的 Slider,画出来是一条轨道,上面没有任何可拖的东西。一个双滑块的区间需要两个 name——第一个之后的每个滑块都会退回用第一个名字,否则价格筛选的两端都会把自己播报成 Minimum。数字上方那个标题只印第一个名字,所以要把它当成这一对的开头来读,而不是两个的标签。
typing the exact value
滑块是一个管大致区间的控件,而这是它的出路。一个要的是 1,150 而不是「大概 1,200」的人,以前只能把 16px 的滑块横着拖过一百个刻度,或者在轨道旁边被塞第二个输入框、然后靠手工把两边同步住;editable 把那个框开在数字本来就在的地方。它静止时显示 format 的输出,拿到焦点时显示光秃秃的数字,所以读者看到的仍然是 $1,200,而打字的人从不会被要求把货币符号也敲一遍。区间上每一端各有自己的框,而且各自被对方兜住——往一个上端停在 70 的区间的下端里打 90,落点是 70,因为两个滑块过不去对方。
naming the unit
format 只管印,别的什么都不干:它渲染轨道上方那个读数,而这里没有任何东西设置 aria-valuetext,所以一个显示 12s 的滑块,播报出来是光秃秃的 12。单位属于名字,因为名字是会被播报的——「请求超时秒数」和 12 一起读出来是一个事实,而「超时」和 12 一起读出来是一个谜语。第二个滑块完全没有 format,一个普通计数就该长这样。
键盘操作
| 按键 | 作用 |
|---|---|
| ←→ | 移动一个步长。 |
| Page UpPage Down | 移动一个更大的步长。 |
| HomeEnd | 跳到最小值或最大值。 |
无障碍
- label 必填。一个只报“42”的滑块,给读屏用户留下一个数字和不知道它在量什么。
- 16px 的滑块外面有一个看不见的 44px 命中区。
- format 会作为 aria-valuetext 播报,所以一个显示着「$1,200」的滑块,念出来就是这个,而不是 1200。
- 方向键走一步,Page 键走一大步,Home 和 End 到两端。