This commit is contained in:
oneao committed 2026-10-09 22:05:02 +08:00
1 parent 0be0b0767a
commit 5f28a10d89
852 files changed
+8962 -111755

No files matched your search

@@ -1,20 +0,0 @@
---
title: Layout 布局框架
description: G3 框架的布局骨架,支持 7 种布局模式,菜单/页签数据由宿主注入
---
# Layout 布局框架
`G3Layout` 是 `@g3soft/framework` 的布局骨架。它只负责「怎么摆」,不关心菜单从哪来 —— 菜单、用户、页签都由宿主通过 props / 插槽注入。
点击下方按钮切换 7 种布局模式:
<demo vue="layout/basic.vue" />
## 说明
- **7 种模式**:`sidebar-nav`(垂直,默认)/ `header-nav`(顶部)/ `sidebar-mixed-nav`(双列)/ `mixed-nav` / `header-sidebar-nav` / `header-mixed-nav` / `full-content`。
- **一个组件 + 模式表驱动**:内部按 `layout` prop 条件渲染,不拆成 7 个组件。
- **菜单数据注入**:`:menus` 直接给数组,或 `:menu-source` 给函数(framework 接管加载态)。
- **插槽宁可多不要少**:`logo` / `header-left` / `header-right` / `sidebar-top` / `sidebar-footer` / `tabbar-extra` / `breadcrumb-extra` / `page` / `default`。
- **主题**:偏好里的主色 / 暗色最终经 `@g3soft/ui` 的 `ConfigProvider` 派生,不另起一套变量系统。
-3
View File
@@ -20,9 +20,6 @@ features:
- title: 参考
details: 每个组件的手写 API 与可运行示例,含 props / events / slots 与类型定义。
link: /ui/general/button
- title: 框架
details: 应用框架:布局骨架(7 种模式)、偏好设置与主题,供业务项目引用。
link: /framework/layout
- title: 使用规范
details: 安装与引入方式、换肤与暗色主题、全局默认值配置。
link: /ui/usage/getting-started
@@ -75,6 +75,7 @@ description: 日期 / 日期时间 / 范围选择与时间滚轮(DatePicker /
| `disabled` | `boolean` | `false` | 禁用态 |
| `disabledDate` | `(date: Date) => boolean` | — | 禁用某些日期 |
| `timeDefault` | `'' \| 'start' \| 'end'` | `''` | 无值时的默认时间 |
| `placeholder` | `string` | 语言包 | 无值时的占位文案(不传取 `date.placeholder`) |
### Props(RangePicker)
@@ -86,6 +87,8 @@ description: 日期 / 日期时间 / 范围选择与时间滚轮(DatePicker /
| `clearable` | `boolean` | `true` | 显示清除按钮 |
| `disabled` | `boolean` | `false` | 禁用态 |
| `disabledDate` | `(date: Date) => boolean` | — | 禁用某些日期 |
| `startPlaceholder` | `string` | 语言包 | 起始端占位文案(不传取 `date.startPlaceholder`) |
| `endPlaceholder` | `string` | 语言包 | 结束端占位文案(不传取 `date.endPlaceholder`) |
### Props(TimeSelect)
@@ -43,7 +43,7 @@ description: 单行 / 密码 / 数字 / 多行四种模式,支持清除、前
## 可清除
`allowClear` 时,有值且 hover / 聚焦会出现清除按钮;点击清空值并触发 `clear` 事件。
`clearable` 时,有值且 hover / 聚焦会出现清除按钮;点击清空值并触发 `clear` 事件。
<demo vue="input/clearable.vue" />
@@ -83,7 +83,8 @@ inputRef.value?.focus({ preventScroll: true }) // 聚焦但不滚动页面
| `disabled` | `boolean` | `false` | 禁用态 |
| `readonly` | `boolean` | `false` | 只读态:可聚焦、可复制,但不可修改 |
| `status` | `'' \| 'error' \| 'warning'` | `''` | 校验状态 |
| `allowClear` | `boolean` | `false` | 有值时显示清除按钮(hover / 聚焦时出现),多行模式不支持 |
| `clearable` | `boolean` | `false` | 有值时显示清除按钮(hover / 聚焦时出现),多行模式不支持 |
| `allowClear` | `boolean` | — | **已废弃**,改用 `clearable`(与 Select / DatePicker 统一);保留仅为兼容旧代码 |
| `showCount` | `boolean` | `false` | 显示字数统计(`maxlength` 存在时显示 `当前 / 上限`) |
| `maxlength` | `string \| number` | — | 最大长度,透传给原生 `maxlength` |
| `rows` | `string \| number` | `3` | 多行模式的初始行数(仅 `textarea` 生效) |
@@ -127,7 +128,8 @@ export interface InputProps {
disabled?: boolean
readonly?: boolean
status?: InputStatus
allowClear?: boolean
clearable?: boolean
allowClear?: boolean // 已废弃,改用 clearable
showCount?: boolean
maxlength?: string | number
rows?: string | number
@@ -82,6 +82,7 @@ description: 下拉选择,支持筛选、多选、远程搜索、触底加载
| `filterOption` | `(input: string, option: unknown) => boolean` | — | 自定义筛选函数,`option` 是**原始**选项对象 |
| `remote` | `boolean` | `false` | 远程搜索模式:不做本地筛选,输入时触发 `search` |
| `loading` | `boolean` | `false` | 加载中:右侧显示加载图标,并阻止触底重复触发 |
| `placeholder` | `string` | 语言包 | 无值时的占位文案(不传取 `common.selectPlaceholder`,即「请选择」) |
| `notFoundText` | `string` | 语言包 | 无匹配项时的文案 |
| `allowFreeInput` | `boolean` | `false` | 允许自由输入:不在列表里的文本也可以作为值提交 |
| `labelKey` | `string` | `'label'` | 选项对象中作为显示文本的字段名 |
@@ -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`;文案需自行接入。