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

可调整大小的框

一个由人改变宽度和高度的框:拖动它边上或角上的手柄,用键盘,或按一下。Outlined 时,它是在手机宽度和笔记本电脑宽度下检查预览的地方;Plain 时,它是导航抽屉或侧栏的边。

content_copy以 Markdown 格式查看
类别
容器
令牌
comp.resizable-frame
层级
组合
构成自
Handle

概览

Web
tanrei-resizable-frame
clock_loader_40
SwiftUI
TanreiResizableFrame
radio_button_unchecked
Jetpack Compose
TanreiResizableFrame
radio_button_unchecked
Flutter
TanreiResizableFrame
radio_button_unchecked
React Native
ResizableFrame
radio_button_unchecked

生成自 docs/status/status.json, specs/resizable-frame.spec.json

一个由人通过结束边、下边和角调整大小的预览

拖动手柄,或用 Tab 移到手柄上再按方向键。

可调整大小的框给它容纳的内容一个可以由人改变的宽度和高度。它的手柄就是调整手柄:拖动时改变大小;用键盘移动时一次改变一步;不拖动而按下时,在最大的大小和之前的大小之间切换。框保存大小,在人改变了大小时告诉你,并把大小作为值交给每个手柄,让辅助技术能够读出。

它有两种外观。Outlined 是一个圆角、带一条细线的框,手柄在框外,不遮住任何东西:这里用来检查页面或组件如何适应给它的空间。Plain 自己什么也不绘制:内容绘制自己的表面,每个手柄位于它的边上——比如为了长名称而被人拉宽的导航抽屉,或为了旁边的工作而被拉窄的侧栏。

在 Web 上它是 <tanrei-resizable-frame>。其他平台尚未实现。

用法

<!-- 在手机、平板和笔记本电脑的宽度下检查的预览:拖动时会吸附到每个宽度。 -->
<tanrei-resizable-frame width="390" height="640" snap-widths="360 600 1024" width-label="调整预览宽度">
  <iframe title="预览" src="/preview"></iframe>
</tanrei-resizable-frame>

<!-- 位于布局结束端的侧栏:Plain,从起始边调整大小。 -->
<tanrei-resizable-frame id="side" variant="plain" handles="start" min-width="240" max-width="560" size-indicator="none" width-label="调整侧栏大小">
  <aside>…</aside>
</tanrei-resizable-frame>

<script type="module">
  import '@tanrei/web/components/resizable-frame';
  const side = document.querySelector('#side');
  // 把这个人设定的宽度保留到下一次访问。
  side.width = Number(localStorage.getItem('side-bar')) || 320;
  side.addEventListener('change', (e) => localStorage.setItem('side-bar', String(e.detail.width)));
</script>
import { ResizableFrame } from '@tanrei/react';

<ResizableFrame
  variant="plain"
  handles={['start']}
  width={width}
  minWidth={240}
  maxWidth={560}
  sizeIndicator="none"
  widthLabel="调整侧栏大小"
  onChange={(e) => setWidth(e.detail.width)}
>
  <aside>…</aside>
</ResizableFrame>

规格

构成

部件 说明
1 container The box the content is laid out in, as wide and as tall as the frame's size. Outlined, its corners rounded and edged with one hairline, and the content clipped to it; plain, nothing drawn. It gives the content no fill of its own.
2 content Whatever the product puts in the frame: a component, an embedded document, a layout, a navigation drawer. The frame gives it its width and its height and does nothing else to it.
3 start-handle · 可选 A Handle (axis horizontal) centred along the start edge: it changes the width from that edge (a side bar at the end of a layout).
4 end-handle · 可选 A Handle (axis horizontal) centred along the end edge: it changes the width.
5 bottom-handle · 可选 A Handle (axis vertical) centred along the bottom edge: it changes the height.
6 corner-handle · 可选 A Handle (axis both, corner bottom-end) at the bottom-end corner: it changes both.
7 size-indicator · 可选 A small label inside the box at its top-end corner that shows the size as width × height in pixels while a handle is held or has keyboard focus, or always.

属性

属性 类型 默认值 说明
variant outlined | plain "outlined" outlined: a box with rounded corners and one hairline, its handles outside it so that they cover nothing — where a person checks how content responds to its room (a preview). plain: no edge and no corners of its own, the content drawing its own surface, and each handle centred on its edge — the edge of a pane (a navigation drawer, a side bar).
handles strings end Which handles the frame draws: any of start, end, bottom and bottom-end, in any combination. start is for content at the end of a layout, which grows toward the start (a side bar); end for content at its start (a preview, a navigation drawer). An empty list draws none, and the frame is a box of the size the product sets.
width number null The width of the box in pixels. Null takes the width the layout gives. A drag, a key or an activation changes it, and the frame keeps the width the person gave until the product sets another; a product that keeps a person's width (a drawer's, from one visit to the next) stores it from change and sets it again.
height number null The height of the box in pixels. Null takes the height the layout gives where it gives one (a row that stretches its items, a grid's cell, a pane beside the page), and the content's height where it does not, within minHeight and maxHeight. Changed as width is.
minWidth number null The least width a person can give. Null takes comp.resizable-frame.container.min-width (320 in the default system: the width at which content must reflow without scrolling sideways, WCAG 1.4.10). A pane sets its own (a navigation drawer's least).
maxWidth number null The greatest width. Null is the width the layout gives the frame.
minHeight number null The least height. Null takes comp.resizable-frame.container.min-height.
maxHeight number null The greatest height. Null is unlimited where the layout lets the frame grow.
snapWidths numbers Widths in whole pixels a drag of a handle that changes the width snaps to (360, 600, 1024: a common phone, a tablet, a small laptop). A width within comp.resizable-frame.snap-distance of one is taken as that one.
step number 10 How many pixels one arrow key changes a size by.
largeStep number 100 How many pixels Shift with an arrow key, Page Up or Page Down changes a size by.
sizeIndicator none | active | always "active" When the size indicator is drawn: never; while a handle is held or has keyboard focus; or all the time. A pane that is not checked for its size (a navigation drawer) sets none.
widthLabel string "" The accessible name of the start and the end handle ("Resize preview width", "Resize navigation"). Required while one of them is drawn.
heightLabel string "" The accessible name of the bottom handle ("Resize preview height"). Required while it is drawn.
cornerLabel string "" The accessible name of the corner handle ("Resize preview"). Required while it is drawn.

插槽

插槽 说明
default The content: a component, an embedded document, a layout, a navigation drawer. A fixture's string is drawn as plain text in it.

事件

事件 说明
resize The size changed during a drag; emitted in every frame it changes. Carries width and height in pixels.
change A person finished changing the size: a drag ended, a key changed it, or a handle was activated. Carries width and height. Not emitted when the product sets a size.

状态

行为

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

ID 需求
RSF-1 THE resizable frame SHALL lay out its container as a box of its width and its height — width while it is not null and otherwise the width the layout gives it, height while it is not null and otherwise the height the layout gives it or, where the layout gives none, its content's height — each kept within its least and greatest (minWidth or comp.resizable-frame.container.min-width, and the lesser of maxWidth and the layout's width; minHeight or comp.resizable-frame.container.min-height, and maxHeight), with no fill and no elevation of its own, placed at the start edge of the room the layout gives it, or at its end edge WHILE handles names start and not end, so that the edge a person drags is the one that moves.
RSF-2 WHILE variant is outlined THE resizable frame SHALL draw its container with comp.resizable-frame.container.shape corners eased by sys.shape.corner-smoothing, edged inside with a line comp.resizable-frame.outline.width wide in comp.resizable-frame.outline.color, SHALL lay its content out at the box's width and clip it to the box's shape, and WHILE the content is taller than the box SHALL scroll it inside the box and make the box one focus stop, so that a keyboard scrolls it; WHILE variant is plain THE resizable frame SHALL draw no edge and no corners, SHALL give the content the box's width and height to fill, and SHALL clip nothing: the content draws its own surface and scrolls itself. In both THE resizable frame SHALL style nothing inside the content.
RSF-3 THE resizable frame SHALL draw the handles that handles names and no other: for start and end a Handle with axis horizontal centred along that edge, for bottom a Handle with axis vertical centred along the bottom edge, for bottom-end a Handle with axis both and corner bottom-end at that corner, each at size medium, and each with a hit area that meets the minimum target by its own rule (HDL-5). WHILE variant is outlined each handle SHALL stand outside the box, its box comp.resizable-frame.handle.gap beyond the edge (beyond both edges for the corner), and THE resizable frame SHALL keep room for them outside the box, so that they never cover the content; WHILE variant is plain each handle SHALL be centred on its edge (its corner on the box's corner) and take no room.
RSF-4 WHILE a drag of a handle lasts THE resizable frame SHALL change its width by the inline distance of the end and the corner handle, and by that distance taken the other way for the start handle, and its height by the block distance of the bottom and the corner handle, from the size it had when the drag began, kept within its least and greatest, following the drag without a motion, and SHALL emit resize with the new width and height in every frame the size changes; WHEN the drag ends THE resizable frame SHALL keep the size and emit change once, and none WHERE the size did not change.
RSF-5 WHILE a drag of a handle that changes the width lasts and snapWidths names widths THE resizable frame SHALL take a width within comp.resizable-frame.snap-distance of one of them as that width, and SHALL let the width go on with the drag once it is farther than that.
RSF-6 WHILE a drag of a handle lasts THE resizable frame SHALL keep every embedded document in its content from taking pointer input, so that the drag is not lost when the pointer passes over it, and SHALL give it input again WHEN the drag ends.
RSF-7 WHEN a handle emits step THE resizable frame SHALL change the size the step's axis stands for — the width for the inline axis, the height for the block axis — by step pixels for amount one and by largeStep pixels for amount large, wider toward the edge the handle stands on (toward the end for the end and the corner handle, toward the start for the start handle) and taller downward, and to its least for amount limit with direction −1 (Home) and to its greatest with direction 1 (End), kept within its least and greatest, and SHALL emit change once WHERE the size changed; it SHALL move to the new size over comp.resizable-frame.motion.resize-duration with comp.resizable-frame.motion.resize-easing, and at once where motion is reduced.
RSF-8 WHEN the start or the end handle is activated THE resizable frame SHALL make its width its greatest WHILE it is narrower, and SHALL give it back the width it had before the person last made it the greatest WHILE it already is the greatest (the least width where it had none); the bottom handle SHALL do the same with the height, the content's height standing for the greatest WHILE maxHeight is null; the corner handle SHALL do both. Each SHALL move as RSF-7 says and emit change once, so that no size the frame offers depends on a drag (WCAG 2.5.7).
RSF-9 THE resizable frame SHALL give each handle the value its size stands for — the width in pixels for the start and the end handle, the height for the bottom and the corner handle — with its least and greatest as min and max, and SHALL name the start and the end handle by widthLabel, the bottom handle by heightLabel and the corner handle by cornerLabel; WHILE a drawn handle's label is empty THE resizable frame SHALL still render it, and in debug builds report that it has no accessible name.
RSF-10 WHILE sizeIndicator is always, or sizeIndicator is active and a handle is held by a press or a drag or has keyboard focus, THE resizable frame SHALL draw its size indicator inside the box, comp.resizable-frame.size-indicator.offset from its top and end edges, over the content: the width, the character ×, and the height, in whole pixels written with the platform's digits for the layout's language and without grouping, in comp.resizable-frame.size-indicator.label.typescale and comp.resizable-frame.size-indicator.label.color, on a container comp.resizable-frame.size-indicator.container.height high, padded by comp.resizable-frame.size-indicator.container.padding-inline at its sides, with comp.resizable-frame.size-indicator.container.shape corners, filled with comp.resizable-frame.size-indicator.container.color; it SHALL take no input, and SHALL be hidden from assistive technology, which reads each size as its handle's value.
RSF-11 WHEN the size indicator appears or goes THE resizable frame SHALL fade it in over comp.resizable-frame.motion.indicator-enter-duration with comp.resizable-frame.motion.indicator-enter-easing and out over comp.resizable-frame.motion.indicator-exit-duration with comp.resizable-frame.motion.indicator-exit-easing, and at once where motion is reduced; WHILE a drag lasts it SHALL update the numbers in every frame, without a motion.
RSF-12 WHEN the product sets width or height THE resizable frame SHALL draw the new size at once and SHALL NOT emit resize or change; WHEN the layout's width becomes narrower than the frame's width THE resizable frame SHALL be as wide as the layout allows and keep the width the person gave for when there is room again.
RSF-13 WHERE the layout direction is right-to-left THE resizable frame SHALL mirror its layout: the box at the right of its room (at its left WHILE it stands at the end edge, RSF-1), the end handle on the box's left edge and the start handle on its right, the corner handle at the bottom-left corner, so that a drag away from the box widens it, and the size indicator at the top-left, its numbers still written left to right, the width at the left of the height, as a size is written in every language.
RSF-14 THE resizable frame 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 frame is shown THE resizable frame SHALL draw itself for the new direction at once, without a motion of its own, keeping its size.
RSF-15 WHERE the platform draws with a person's own forced colors THE resizable frame SHALL draw the outlined box's edge in the platform's text color, and its size indicator's text in the platform's text color on the platform's canvas color, with an edge of comp.resizable-frame.outline.width in the text color around it.
RSF-16 IF handles names a value other than start, end, bottom and bottom-end, or variant or sizeIndicator a value the component does not define, THE resizable frame SHALL ignore that handle, draw the variant as outlined or treat the indicator as active, and in debug builds report the unknown value; IF a value of snapWidths is not a whole number of pixels above zero THE resizable frame SHALL ignore it and in debug builds report it.
RSF-17 THE resizable frame SHALL have no words of its own and SHALL read none of the product's words: widthLabel, heightLabel and cornerLabel are about this one frame, and the size indicator is made of digits and a mark.
RSF-18 THE resizable frame SHALL add to the focus order its handles after its content, in the order start, end, bottom, bottom-end, and no other stop of its own but the box while it scrolls (RSF-2).
RSF-19 WHILE variant is outlined and a fine pointer is over the frame — its box or a handle's target — THE resizable frame SHALL draw its handles at rest (the handle's revealed), so that a person who points at a preview sees where to take it; WHILE variant is plain THE resizable frame SHALL leave each handle out of sight until it is used, as the Handle does (HDL-23), so that a pane's edge stays quiet under a pointer that only passes over the pane.

各平台名称对照

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

规格 Web SwiftUI Jetpack Compose Flutter React Native
组件 tanrei-resizable-frame TanreiResizableFrame TanreiResizableFrame TanreiResizableFrame ResizableFrame
variant · 属性 variant variant variant variant variant
handles · 属性 handles handles handles handles handles
width · 属性 width width width width width
height · 属性 height height height height height
minWidth · 属性 minWidth minWidth minWidth minWidth minWidth
maxWidth · 属性 maxWidth maxWidth maxWidth maxWidth maxWidth
minHeight · 属性 minHeight minHeight minHeight minHeight minHeight
maxHeight · 属性 maxHeight maxHeight maxHeight maxHeight maxHeight
snapWidths · 属性 snapWidths snapWidths snapWidths snapWidths snapWidths
step · 属性 step step step step step
largeStep · 属性 largeStep largeStep largeStep largeStep largeStep
sizeIndicator · 属性 sizeIndicator sizeIndicator sizeIndicator sizeIndicator sizeIndicator
widthLabel · 属性 widthLabel widthLabel widthLabel widthLabel widthLabel
heightLabel · 属性 heightLabel heightLabel heightLabel heightLabel heightLabel
cornerLabel · 属性 cornerLabel cornerLabel cornerLabel cornerLabel cornerLabel
resize · 事件 resize onResize onResize onResize onResize
change · 事件 change onChange onChange onChanged onChange
备注 <tanrei-resizable-frame variant handles="end bottom-end" width height min-width max-width min-height max-height snap-widths="360 600 1024" step large-step size-indicator width-label height-label corner-label> with the content in the default slot. handles and snapWidths are array properties; their attributes are space-separated or a JSON array. The handles are <tanrei-handle> in the shadow root. RSF-6 sets pointer-events: none on every slotted <iframe>, <object> and <embed> (and every one inside the slotted content) between the handles' resizestart and resizeend. resize and change are composed, bubbling CustomEvents with { width, height }; the Handle's own events stay in the shadow root. width and height are Binding<CGFloat?>; snapWidths is [CGFloat]. Content is the view builder. snapWidths: List<Dp>; sizes in Dp. Content is the trailing composable. snapWidths: List<double>. Content is child. snapWidths: number[]. Content is children.

令牌

令牌 引用 解析值(浅色)
--tanrei-comp-resizable-frame-container-min-height — 200px
--tanrei-comp-resizable-frame-container-min-width — 320px
--tanrei-comp-resizable-frame-container-shape sys.shape.corner.large 12px
--tanrei-comp-resizable-frame-handle-gap sys.space.space100 8px
--tanrei-comp-resizable-frame-motion-indicator-enter-duration sys.motion.role.appear.hint.enter 250ms
--tanrei-comp-resizable-frame-motion-indicator-enter-easing sys.motion.easing.enter cubic-bezier(0.2, 0, 0, 1)
--tanrei-comp-resizable-frame-motion-indicator-exit-duration sys.motion.role.appear.hint.exit 200ms
--tanrei-comp-resizable-frame-motion-indicator-exit-easing sys.motion.easing.exit cubic-bezier(0.3, 0, 1, 1)
--tanrei-comp-resizable-frame-motion-resize-duration sys.motion.role.resize.default 300ms
--tanrei-comp-resizable-frame-motion-resize-easing sys.motion.easing.spatial cubic-bezier(0.2, 0, 0, 1)
--tanrei-comp-resizable-frame-outline-color sys.color.outline-variant #000000 · 8%
--tanrei-comp-resizable-frame-outline-width sys.border.hairline 1px
--tanrei-comp-resizable-frame-size-indicator-container-color sys.color.inverse-surface #1f1f1f
--tanrei-comp-resizable-frame-size-indicator-container-height — 24px
--tanrei-comp-resizable-frame-size-indicator-container-padding-inline sys.space.space100 8px
--tanrei-comp-resizable-frame-size-indicator-container-shape sys.shape.corner.small 6px
--tanrei-comp-resizable-frame-size-indicator-label-color sys.color.inverse-on-surface #f1f1f1
--tanrei-comp-resizable-frame-size-indicator-offset sys.space.space100 8px
--tanrei-comp-resizable-frame-snap-distance sys.space.space100 8px
--tanrei-comp-resizable-frame-size-indicator-label-typescale sys.typescale.code-small 400 12px/1.3333

测试样例

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

生成自 specs/resizable-frame.spec.json, tokens/comp/resizable-frame.tokens.json, design/tokens/

指南

何时使用

在应当让人给某样东西想要的空间、并看到它在这个空间里如何表现的地方使用:以另一宽度查看的页面或组件预览、主内容旁边的窗格、工具面板。

你需要 使用
只让字段自身的高度随文字增长 文本字段自带的角上手柄。
从下边升起的面板 底部面板,它绘制自己的拖动手柄。
在几个固定大小之间选择,中间没有其他大小 切换这些大小的分段按钮。
像缩放图片那样把显示的内容缩小,而不是给它更少的空间 不是这个:可调整大小的框改变的是空间,从不改变所容纳内容的比例。

外观

variant 绘制 用于
outlined(默认) 圆角和一条细线;手柄在框外自己的空间里。鼠标移到框上时显示手柄。 预览:内容完整可见,框的任何部分都不会遮住它。
plain 自己什么也不绘制:内容用自己的表面填满框。每个手柄位于它的边上,只在被指向、获得焦点或被按住时出现。 窗格的边:导航抽屉、侧栏。

手柄

handles 位于 改变
end(默认) 结束边 宽度。用于布局起始端的内容:预览、导航抽屉。
start 起始边 宽度,朝起始端增长。用于布局结束端的内容:侧栏。此时框位于它所得空间的结束端。
bottom 下边 高度。
bottom-end 结束端的下角 同时改变两者。

可以任意指定其中几个、任意组合;空列表不绘制任何手柄,框就是你设定大小的一个框。start 和 end 跟随页面的方向:在从右到左的布局中,结束边是左边。

大小

width 和 height 是框的大小,单位为像素。它们为 null 时,框取布局给它的宽度和布局给它的高度;布局不给高度时,取内容的高度。一旦有人移动了手柄,大小就归这个人所有,并一直保持,直到你设定另一个大小。你设定的大小会立即绘制,不发送任何事件;布局变窄时框也随之变窄,空间恢复后宽度也会恢复。

最小宽度是 minWidth,在你没有设定时为 320 像素:内容必须在不横向滚动的情况下重新排布的宽度。为窗格设定你自己的值——导航抽屉有它自己的最小宽度。最大宽度是 maxWidth,或布局给它的空间。snapWidths 是拖动经过时会吸附的宽度,例如常见手机、平板和小型笔记本电脑的宽度。

它告诉你什么

事件 何时
resize 拖动改变大小的每一帧:带有 width 和 height。
change 人改变了大小之后,一次:拖动结束、按键移动了它,或不拖动而按下了手柄。如果你要保留一个人设定的大小,就在这里保存。

尺寸指示

手柄被按住或拥有键盘焦点时,框结束端的上角会出现一个小标签,显示大小,如“390 × 640”。把 sizeIndicator 设为 always 时一直显示——用于需要检查大小的预览;设为 none 时从不显示——用于没人读它大小的窗格。它用页面语言的数字书写,在任何布局中都从左到右排列,辅助技术不读它,而是读每个手柄的值。

推荐

  • 给每个绘制的手柄一个说明它调整什么的名称:widthLabel、heightLabel、cornerLabel(“调整预览宽度”“调整侧栏大小”)。
  • 设定一个内容仍可用的最小宽度,以及一个让页面其余部分仍可用的最大宽度。
  • 把一个人设定的大小保存在他会回来的地方:抽屉或侧栏的宽度,从 change 中取得。

避免

  • 不要在内容周围自己绘制调整大小的手柄:使用这个框,窗格的边用 plain。
  • 不要用它把内容像图片那样缩小:它改变的是空间,而不是比例。
  • 在本应由人改变大小的窗格上,不要去掉它的手柄:无法拖动的人用的正是按键和按下。

无障碍

角色
none (a group of the product's content and its handles); each handle is a focusable separator
标注
Each handle is named by its label (widthLabel for the start and the end handle, heightLabel, cornerLabel) and tells its size as its value in pixels, with its least and greatest. The size indicator is hidden: it draws what the handles already tell.
最小目标
即使外观尺寸更小,点击区域也满足最小目标尺寸。 minimum 32px · pointer 44px · spacing 8px · touch 48px

键盘操作

按键 动作
Tab Moves through the content, then the handles: start, end, bottom, corner.
Arrow keys on a handle Change the size by step pixels; with Shift, by largeStep (HDL-9, RSF-7). On the start handle the arrow toward the start widens.
Page Up / Page Down Change the size by largeStep.
Home / End Give the size its least or its greatest.
Enter / Space Switch between the greatest size and the size before it (RSF-8).

备注

  • The default least width, 320, is the width at which content must reflow without a sideways scroll (WCAG 1.4.10), so that a person checking a design can reach that width and no narrower by accident; a product sets minWidth lower for a narrower check, and a pane sets its own.
  • Dragging movements (WCAG 2.5.7): every size is also reachable by activating a handle (the greatest and the one before) and by its keys.
  • The keys follow the window splitter pattern of the ARIA Authoring Practices: each handle is a separator with a value, Home and End give the least and the greatest.

生成自 specs/resizable-frame.spec.json, tokens/sys/measure.tokens.json

组件负责的部分

  • 每个手柄都是一个可聚焦的分隔符——ARIA Authoring Practices 中的窗口分隔条——由它的标签命名,以像素为单位的大小是它的值,最小和最大是它的范围。
  • 在焦点顺序中,手柄排在内容之后:起始、结束、下边、角。Outlined 的框只在内容比它高、需要滚动时才是焦点停靠点。
  • 方向键按 step 像素改变大小,Shift 加方向键以及 Page Up 和 Page Down 按 largeStep 改变;Home 和 End 给出最小和最大。在起始边的手柄上,指向起始端的方向键使它变宽。
  • Enter、Space 或不拖动的按下,会在最大的大小和之前的大小之间切换,所以每个大小都无需拖动即可到达。
  • 拖动期间,内容中嵌入的文档不会获取指针,所以指针经过它们时拖动不会中断。
  • 尺寸指示对辅助技术隐藏;它绘制的正是手柄的值已经说明的内容。在要求减弱动态效果时,由按键或按下引起的变化会立即完成。
  • 在强制颜色模式下,Outlined 的边和尺寸指示的文字使用文字颜色,尺寸指示的底色使用画布颜色。

需要你做的事

  • 给你绘制的每个手柄提供标签。没有它,手柄仍会绘制并工作,调试构建会报告这一点。
  • 确认从最小宽度起,在你允许的每个大小下内容都能正常使用。