divider —— 分割线
本頁內容尚未翻譯。
分割线是最「薄」的组件,但它的无障碍语义恰恰最值得讲究:一条分隔区域的线,对读屏软件是有用的结构还是噪音?core/divider 用 getDividerRole 把这个决策显式化——带文案的分割线是真正的 separator,纯装饰线是 presentation(移出无障碍树)。
- 各端实现
LhDivider:类名、语义角色、方向声明全部由 core 计算。 - 表单分区、卡片内容分组、文章段落分隔。
- 不该用它:用它做布局间距。间距是
LhSpace或 padding 的职责,分割线是语义元素。
import { getDividerClassNames, getDividerRole, needsAriaOrientation,} from '@lh-ui/share/core/divider'import type { LhDividerState, LhDividerDirection, LhDividerLabelPosition, LhDividerRole,} from '@lh-ui/share/core/divider'分割线有两套「虚线」表达:老的 dashed 布尔 prop 与新的 borderStyle 字符串。getDividerClassNames 的优先级是 borderStyle 显式非空 > dashed,且只有 'dashed' / 'dotted' 有对应样式类——传 'solid' 或任意非法值不会产出脏类,按默认实线渲染。这是一个渐进迁移的设计:老代码传 dashed 仍然工作,新代码可以用 borderStyle 表达更丰富的边框风格。
needsAriaOrientation 的条件是 hasContent && direction === 'vertical',两个条件都必要:
- 水平是 APG 中 separator 的默认方向,声明
aria-orientation="horizontal"是冗余信息。 - 无文案时角色是
presentation,元素已移出无障碍树,声明方向没有接收方。
竖向与横向一样支持文案(竖向文案在线段上下排布),故「有文案且竖向」是可达状态;labelPosition 是
横向语义,竖向文案恒居中,getDividerClassNames 不会为竖向产出 --label-* 修饰类。
| 函数 | 签名 | 返回 | 作用 |
|---|---|---|---|
getDividerClassNames |
(state: LhDividerState) => string[] |
类名数组 | 方向、虚线、文案修饰类 |
getDividerRole |
(hasContent: boolean) => LhDividerRole |
'separator' / 'presentation' |
语义角色 |
needsAriaOrientation |
(direction: 'horizontal' | 'vertical', hasContent: boolean) => boolean |
布尔 | 是否需要声明 aria-orientation |
输出示例:
getDividerClassNames({ direction: 'horizontal', dashed: false, hasContent: true, labelPosition: 'center', borderStyle: null })// ['lh-divider', 'lh-divider--horizontal', 'lh-divider--with-text', 'lh-divider--label-center']
getDividerRole(true) // 'separator'getDividerRole(false) // 'presentation'needsAriaOrientation('vertical', true) // trueneedsAriaOrientation('vertical', false) // falseexport type LhDividerDirection = 'horizontal' | 'vertical'export type LhDividerLabelPosition = 'left' | 'center' | 'right'export type LhDividerRole = 'separator' | 'presentation'
export interface LhDividerState { direction: LhDividerDirection dashed: boolean hasContent: boolean labelPosition: LhDividerLabelPosition borderStyle?: string // 显式指定时优先于 dashed}分割线的无障碍由三部分拼装,UI 层应当原样使用:
const role = getDividerRole(hasContent) // 'separator' | 'presentation'const orientation = needsAriaOrientation(direction, hasContent)const aria = { role, ...(orientation ? { 'aria-orientation': 'vertical' } : {}) }- 带文案的分割线:
role="separator",读屏软件会播报「分隔符」并感知它把内容分成两段。 - 纯装饰线:
role="presentation",从无障碍树移除。 - 垂直 + 带文案:额外
aria-orientation="vertical",因为垂直不是默认方向。
import { getDividerClassNames, getDividerRole } from '@lh-ui/share/core/divider'
getDividerClassNames({ direction: 'vertical', dashed: true, hasContent: false, labelPosition: 'left', borderStyle: null })// ['lh-divider', 'lh-divider--vertical', 'lh-divider--dashed']<!-- Vue3 --><div :class="getDividerClassNames({ direction, dashed, hasContent: !!slots.default, labelPosition, borderStyle })" :role="getDividerRole(!!slots.default)" :aria-orientation="needsAriaOrientation(direction, !!slots.default) ? 'vertical' : undefined"> <span v-if="slots.default" class="lh-divider__label"><slot /></span></div>// Reactconst hasContent = !!childrenconst cls = getDividerClassNames({ direction, dashed, hasContent, labelPosition, borderStyle })return ( <div className={cls.join(' ')} role={getDividerRole(hasContent)} aria-orientation={needsAriaOrientation(direction, hasContent) ? 'vertical' : undefined} > {hasContent && <span className="lh-divider__label">{children}</span>} </div>)// uniapp:role/aria 在非 h5 端支持有限,可降级只渲染类名(视觉一致优先)| 类名 | 语义 |
|---|---|
.lh-divider |
基础类:定位、边框颜色 |
.lh-divider--horizontal / .lh-divider--vertical |
方向(决定边框在哪一侧) |
.lh-divider--dashed |
虚线(兼容老 dashed prop) |
.lh-divider--with-text |
带文案:边框让出中间位置 |
.lh-divider--label-{left|center|right} |
文案对齐位置 |
.lh-divider__label |
文字节点(带两侧间距与背景遮盖边框) |
边框颜色用 var(--lh-border-color),暗色自动翻转。
borderStyle优先于dashed,且只'dashed'/'dotted'有效——这是有意的克制,避免把任意 CSS border-style 都暴露成 prop。- 垂直分割线需要父容器有明确高度(通常是 flex 行),否则高度塌缩到 0。
role="presentation"与role="none"在 APG 中等价,本组件用presentation(历史兼容性更好)。- 判定
hasContent时注意「只渲染了空白插槽」的情形,Vue 用!!slots.default?.()更稳妥。
@lh-ui/share/core/divider → getDividerClassNames( )返回值
(填好参数后点运行)Copyright © 2024-2026 风默文学 | 宁ICP备2024006574号 |
苏公网安备32040002010537