3.9 KiB
title, description
| title | description |
|---|---|
| 双向布局(RTL) | 让组件跟随从右到左的书写方向,以及哪些地方刻意不镜像 |
双向布局(RTL)
组件库同时支持 LTR / RTL。镜像的原则只有一条:跟随行内方向(inline direction), 而不是「左边换成右边」的粗暴翻转。
怎么开启
整站(推荐):宿主在 <html> 上声明方向,组件零配置跟随:
<html lang="ar" dir="rtl">
视觉镜像完全由 CSS 的 [dir='rtl'] 选择器驱动;需要方向语义的 JS 逻辑
(浮层对齐轴、键盘左右键)由 useDirection() 读取 —— 它会观察
documentElement 的 dir / class / style,运行时切换也能跟上。
局部子树:同一页里既有 LTR 又有 RTL 时,用 G3ConfigProvider:
<G3ConfigProvider direction="rtl">
<G3Form>…</G3Form>
</G3ConfigProvider>
它会把 dir 挂到子树根,同时通过 provide 下发。这条路径在 SSR 首帧就生效,
不受「挂载后才能探测 DOM」影响,是服务端渲染场景的首选。
组件树外:G3Message / G3Notification 这类拿不到 inject 的实例走全局兜底:
G3UI.config({ direction: 'rtl' })
优先级:ConfigProvider → 全局配置 → 文档方向(<html dir>)→ ltr。
写组件样式的规矩
镜像靠逻辑属性实现,组件 <style> 里不要用 left / right:
| 场景 | 用什么 |
|---|---|
| 缩进、内边距、边框 | padding-inline-start / border-inline-start |
| 定位到某一侧 | inset-inline-start / inset-inline-end |
| 圆角 | border-start-start-radius 等逻辑角 |
| 外边距偏移(栅格 offset) | margin-inline-start |
| 带符号的位移 | token --g3-dir-sign(LTR 1 / RTL -1) |
/* 滑块位移:RTL 下自动反向 */
transform: translateX(calc(#{v('dir-sign', 1)} * 12px));
⚠️ 不要用 scaleX(-1) 做整块镜像,文字会变成反字。只有方向性图标(Chevron 系列)
该翻面,统一在 packages/ui/src/_styles/rtl.scss 里按 lucide 自带的 lucide-* 类名处理。
刻意不镜像的地方
这些是物理语义,dir="rtl" 下不会翻,属设计约定:
| 位置 | 原因 |
|---|---|
G3Drawer / G3Modal / G3Tabs 的 placement="left | right" |
字面 API,指定的是物理边 |
浮层(Popover / Tooltip / Dropdown / Select / DatePicker)的主方向 left / right |
与 floating-ui 一致:只镜像 *-start / *-end 的对齐轴 |
浮层箭头、left: 50% 居中、G3Notification 的停靠边 |
物理锚定,没有行内语义 |
另外 G3Grid 的 push / pull 已改为沿行内方向位移(跟随方向),
与 Bootstrap 的物理语义不同,迁移时留意。
键盘
水平方向键按行内方向解释:LTR 里 ArrowRight 是「下一个」,RTL 里反过来是 ArrowLeft。
已覆盖:
G3Tabs标签切换G3Tree展开 / 收起 / 进子节点 / 回父节点G3DatePicker日期面板的左右移动G3Splitter分隔条左右调整
G3Radio / G3Segmented 内部是原生 <input type="radio">,键盘行为交给浏览器。
自测
- playground 右上角
dir: ltr / rtl开关;也可用?dir=rtl直接以 RTL 进入 pnpm --filter @g3soft/ui test:e2e里的e2e/rtl.spec.ts锁住几何镜像 (滑块、滚动条轨道、树缩进、按钮组圆角、浮层对齐、键盘语义)
已知边界
- 横向
G3Scrollbar的拖拽在 RTL 下依赖浏览器scrollLeft的符号约定。 新版 Chrome / Edge / Safari 已一致;Firefox 未实测。 - 运行时用脚本直接翻
<html dir>时,CSS 立即生效,JS 侧靠MutationObserver跟随 (同一帧内可能读到旧值,定位类行为会在下一次展开 / 重算时纠正)。G3ConfigProvider路径没有这个问题。 - 语言包目前只有
zhCN/enUS,没有ar;文案需自行接入。