u
This commit is contained in:
1 parent
0be0b0767a
commit
5f28a10d89
852 files changed
+8962
-111755
No files matched your search
@@ -0,0 +1,100 @@
|
||||
---
|
||||
title: 双向布局(RTL)
|
||||
description: 让组件跟随从右到左的书写方向,以及哪些地方刻意不镜像
|
||||
---
|
||||
|
||||
# 双向布局(RTL)
|
||||
|
||||
组件库同时支持 LTR / RTL。镜像的原则只有一条:**跟随行内方向**(inline direction),
|
||||
而不是「左边换成右边」的粗暴翻转。
|
||||
|
||||
## 怎么开启
|
||||
|
||||
**整站(推荐)**:宿主在 `<html>` 上声明方向,组件零配置跟随:
|
||||
|
||||
```html
|
||||
<html lang="ar" dir="rtl">
|
||||
```
|
||||
|
||||
视觉镜像完全由 CSS 的 `[dir='rtl']` 选择器驱动;需要方向语义的 JS 逻辑
|
||||
(浮层对齐轴、键盘左右键)由 `useDirection()` 读取 —— 它会观察
|
||||
`documentElement` 的 `dir` / `class` / `style`,运行时切换也能跟上。
|
||||
|
||||
**局部子树**:同一页里既有 LTR 又有 RTL 时,用 `G3ConfigProvider`:
|
||||
|
||||
```vue
|
||||
<G3ConfigProvider direction="rtl">
|
||||
<G3Form>…</G3Form>
|
||||
</G3ConfigProvider>
|
||||
```
|
||||
|
||||
它会把 `dir` 挂到子树根,同时通过 `provide` 下发。这条路径**在 SSR 首帧就生效**,
|
||||
不受「挂载后才能探测 DOM」影响,是服务端渲染场景的首选。
|
||||
|
||||
**组件树外**:`G3Message` / `G3Notification` 这类拿不到 `inject` 的实例走全局兜底:
|
||||
|
||||
```ts
|
||||
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`) |
|
||||
|
||||
```scss
|
||||
/* 滑块位移: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`;文案需自行接入。
|
||||
Reference in new issue
Block a user