容器
DescriptionList - 描述列表
一条记录的各个字段,用真正的 <dl>,不是一堆 div 拼的网格。
用法
什么时候用它
import { DescriptionList } from '@misoto22/folio'说明
一条记录的各个字段:标签、值、标签、值。
这是任何详情页里重复得最多的那个形状,也是最常被人用一堆 <div> 拼成网格手搓出来的那个——而那样一拼,标记原本携带的唯一一件事就没了。<dl> 告诉读屏软件“Owner”命名的是它旁边那个东西;一堆 div 拼的网格告诉它的是这里有两列互不相干的文字,配对关系只能靠阅读顺序去猜。
有好几条记录时请改用 Table。这个是正面看一条记录,表格是从上往下看很多条。
每一对都包在一个 <div> 里——HTML 规范允许 <dl> 里出现它,正是为了让一对可以作为一个整体来排版——所以那条细线能贯穿整行,而不是断在列间距里。
items 为空时渲染 null,而不是一个空的带边框的盒子。一条一个字段都没有的记录,是上面那个页面该用 EmptyState 去处理的状态;而一圈围着空气的细线,看起来就像一个没加载出来的组件。
结构
| 部件 | 说明 |
|---|---|
| 列表必填 | 那个 <dl>。配对关系是靠这个元素承载的:一堆 div 拼的网格长得一模一样,告诉读屏软件的却是“两列互不相干的文字”。 |
| 一对必填 | 包住每组 dt/dd 的一个 <div>,HTML 规范允许它出现在 <dl> 里,正是为了让一对能作为一个整体来排版。细线画在它上面,所以那条线横穿整行,而不是在列间距处断掉。 |
| 名称必填 | item.term,渲染成 <dt>、--ink-3-aa。在行式布局里,它在 sm 及以上占一栏 12rem,往下就改成上下堆叠,因为手机上一栏 12rem 的标签,只给值留下大约八个字符的宽度。 |
| 描述必填 | item.description,渲染成 <dd>、--ink-2,浏览器默认的外边距被清掉。它收的是节点而不是字符串,所以一个值可以是 Badge、一个链接或者一个 Timestamp。 |
| 细线 | divided,默认开:除最后一对外,每一对下面一条 --rule。放进 Card 里就关掉它,Card 自己已经有边了。 |
实践建议
推荐
- items 为空时,就让它什么都不渲染。它返回的是 null,不是一个带边框的空盒子,所以上层页面可以自己去显示一个 EmptyState,而不是围着空无一物画一圈细线。
- 值是一个状态或一个链接时,就往 description 里放元素——它是 <dd>,所以 Badge、一个 <a> 或者一个 Timestamp 本来就该待在那儿,不用拿一串文字去假装。
- 行会增删或重排时,每个 item 都要传 id。不传就拿下标当 key,这对一个记录页渲染的固定字段列表是对的,对一个会变形的列表就是错的。
避免
- 不要拿它去展示好几条记录。每个 dt 都会沿着页面重复一遍,而对照两条记录的读者只能把两边都记在脑子里——Table 的列标题存在的意义,就是免掉这件事。
- 窄侧栏里不要用 layout="row"。它只在 sm 断点上折叠,而那是视口的断点、不是容器的——一个 20rem 的面板里塞一栏 12rem 的标签,值就没地方了。那种地方用 layout="stacked"。
示例
record fields
一条记录的正面。这段标记是真正的 dl/dt/dd,正是它告诉读屏软件「Owner」命名的是旁边那个值——一堆 div 拼出来的网格看起来一模一样,却什么都没说。值是一个节点,所以一个状态是一枚 Badge,一个日期是一个 Timestamp,而不是两个手工格式化出来的字符串。
- Owner
- Henry Chen
- Region
- ap-southeast-2
- Status
- Deployed
- Last deploy
row and stacked
同样三个字段,在两种布局下各来一遍。row 是记录页的形状——标签沿着一条边对齐,读者是在扫它们而不是读它们——而它在 sm 断点以下会塌成一列,因为手机上一根 12rem 的标签列,留给值的宽度大约八个字符。stacked 在任何宽度下都把值放在它的标签底下,而这是那种「因为设计如此、而不是因为视口而窄」的容器的答案:一张卡片、一根侧栏、一个 popover。按容器选,不是按字段个数选。
- Runtime
- Node 24 on Cloudflare Workers
- Region
- ap-southeast-2
- Build
- pnpm --filter @misoto22/folio build
- Runtime
- Node 24 on Cloudflare Workers
- Region
- ap-southeast-2
- Build
- pnpm --filter @misoto22/folio build
a metadata rail
它被造出来所针对的那个形状:一个详情页,左边是记录本身,旁边一根边栏放它的元信息。这根边栏是 stacked 且不带分隔线的——它本来就已经在一根带边框的列里面,而在一个盒子里再来一套细线,是一个装成表格的网格。边栏里的每样东西都是关于这个东西的事实,而不是这个东西的一部分,而这正是判断什么该放这儿时要划的那条线:标题和正文是这条记录,而负责人和最后一次部署,是这一页关于它所知道的事情。
ui.misoto22.com
The documentation site for the design package. Statically exported, so every page is HTML on a CDN and the only JavaScript is the parts a reader touches.
类型
export type DescriptionListLayout = 'row' | 'stacked'无障碍
- 真正的 <dl>、<dt> 和 <dd>,读屏软件靠它才知道一个标签命名的是它旁边那个值。
- 每一对包在一个 <div> 里,规范允许 <dl> 里出现它,辅助技术也会直接读穿过去。
- 空列表渲染成 null,而不是一个空的 <dl>,所以不会有谁去播报一个一项都没有的列表。