注意
当你通过 CLI (npx shadcn@latest add …) 添加组件后,使用编辑器的“全局搜索替换”功能,或者在具体组件文件中手动修改这些类名。
设置阿拉伯文的字体
设置 HTML dir 属性
DirectionProvider
是为整个应用提供全局的文本方向上下文(Text Direction Context),特别是指明应用处于 RTL(Right-to-Left,从右向左) 模式。
|
|
- 为什么 CSS 的 dir=“rtl” 甚至 html dir=“rtl” 都不够? 通常,我们在 HTML 标签上写 就可以让浏览器自动处理大部分排版(比如文字对齐、Flex/Grid 布局翻转)。 但是,Radix UI (Shadcn 的底层) 是通过 JavaScript 来计算位置、管理焦点和处理键盘事件的,而不是单纯依赖 CSS。Radix 组件需要通过 React Context 明确知道当前的方向,才能正确地执行逻辑。 如果不加 DirectionProvider,Radix 组件会默认假设方向是 ltr (Left-to-Right),即使你的 CSS 已经把页面翻转了,交互逻辑可能还是反的。
- 它具体影响了哪些交互逻辑? 当你把 dir 设置为 rtl 后,Radix 会自动调整以下行为: A. 键盘导航 (Keyboard Navigation) 这是最关键的一点。Radix 致力于无障碍访问(A11y),键盘操作必须符合直觉。 Slider (滑块): LTR: 按 右箭头 键,滑块向右移动,数值增加。 RTL: 按 右箭头 键,滑块(物理上)向右移动,但逻辑上代表“后退/减小”;或者按 左箭头 才是“前进/增加”。Radix 会自动处理这种按键映射。 Tabs / Menus (标签页/菜单): LTR: 右箭头 聚焦下一个标签,左箭头 聚焦上一个。 RTL: 左箭头 聚焦下一个标签,右箭头 聚焦上一个。逻辑完全反转。 B. 弹出方向与定位 (Positioning & Collision) Radix 的 Popover, Tooltip, DropdownMenu 使用 JavaScript 计算弹出位置。 Tooltip / Popover: 如果你设置 side=“right”(在右侧显示)。 在 LTR 中,它显示在目标的右边。 在 RTL 中,如果不使用 Provider,它可能还是显示在物理右边,但这符合 RTL 用户的直觉吗?有时候我们需要逻辑上的“开始端(Start)”和“结束端(End)”。 更重要的是 Collisions (碰撞检测):当菜单靠近屏幕边缘时,Radix 需要知道哪一边是“阅读方向的起始边”,以便正确地翻转菜单位置。 C. 组件动画与布局 (Sheet / Dialog) Sheet (侧边抽屉): Shadcn 的 Sheet 组件通常有一个 side 属性。 默认 side=“left”。在 LTR 中,它从左侧滑出。 在 RTL 上下文中,通常希望主菜单从右侧滑出(因为右侧是视觉起点)。虽然这通常结合 CSS 变换,但 Radix 的底层逻辑(如焦点陷阱 Focus Trap)需要知道布局方向,以确保 Tab 键循序正确。
物理属性转逻辑属性
这是一个基于 Tailwind CSS 逻辑属性(Logical Properties)的 Shadcn 组件 RTL 适配对照表:
把所有 ml/mr/pl/pr 批量替换为 ms/me/ps/pe
Tailwind CSS 逻辑属性替换对照表
| 类别 | 原始物理类 (LTR) | 新逻辑类 (RTL 适配) | 说明与常见场景 |
|---|---|---|---|
| 外边距 (Margin) | ml-* |
ms-* |
Margin Start 原左边距。例如:列表项之间的间距。 |
mr-* |
me-* |
Margin End 原右边距。例如:图标在左、文字在右时,图标的右间距。 |
|
| 内边距 (Padding) | pl-* |
ps-* |
Padding Start 原左内边距。 |
pr-* |
pe-* |
Padding End 原右内边距。例如:输入框右侧有图标时,预留的 padding。 |
|
| 定位 (Position) | left-* |
start-* |
Start Position 原靠左定位。例如:头像左上角的在线状态点。 |
right-* |
end-* |
End Position 原靠右定位。例如:关闭按钮、角标、输入框内部右侧的图标。 |
|
| 文本对齐 (Text) | text-left |
text-start |
Text Start 文本起始对齐(LTR 下居左,RTL 下居右)。 |
text-right |
text-end |
Text End 文本结束对齐。例如:表格中的数值列通常需要 text-end。 |
|
| 边框 (Border) | border-l |
border-s |
Border Start 起始边框。 |
border-r |
border-e |
Border End 结束边框。例如:竖向分割线。 |
|
| 圆角 (Rounded) | rounded-l-* |
rounded-s-* |
Rounded Start 起始侧圆角。例如:按钮组最左侧的按钮。 |
rounded-r-* |
rounded-e-* |
Rounded End 结束侧圆角。例如:按钮组最右侧的按钮。 |
替换速查口诀
- Left (左) $\rightarrow$ Start (始) (
ml$\rightarrow$ms,pl$\rightarrow$ps) - Right (右) $\rightarrow$ End (终) (
mr$\rightarrow$me,pr$\rightarrow$pe)
处理图标翻转 (Icons)
添加 classNamertl:rotate-180
- ChevronLeft / ChevronRight (左右箭头): 需要翻转
-
ArrowLeft / ArrowRight (左右箭头): 需要翻转