openxiangda 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +58 -0
- package/bin/openxiangda.js +11 -0
- package/lib/cli.js +2423 -0
- package/lib/config.js +121 -0
- package/lib/http.js +47 -0
- package/lib/skills.js +371 -0
- package/lib/utils.js +87 -0
- package/lib/workspace-init.js +139 -0
- package/openxiangda-skills/SKILL.md +128 -0
- package/openxiangda-skills/references/architecture-patterns.md +242 -0
- package/openxiangda-skills/references/automation-v3.md +129 -0
- package/openxiangda-skills/references/component-guide.md +198 -0
- package/openxiangda-skills/references/forms/component-registry.md +53 -0
- package/openxiangda-skills/references/forms/form-schema.md +109 -0
- package/openxiangda-skills/references/forms/layout-and-rules.md +24 -0
- package/openxiangda-skills/references/openxiangda-api.md +466 -0
- package/openxiangda-skills/references/pages/page-sdk.md +13 -0
- package/openxiangda-skills/references/pages/publish-flow.md +36 -0
- package/openxiangda-skills/references/pages/workspace-structure.md +38 -0
- package/openxiangda-skills/references/permissions-settings.md +147 -0
- package/openxiangda-skills/references/platform-data-model.md +305 -0
- package/openxiangda-skills/references/style-system.md +492 -0
- package/openxiangda-skills/references/troubleshooting.md +246 -0
- package/openxiangda-skills/references/workflow-v3.md +105 -0
- package/openxiangda-skills/references/workspace-state.md +45 -0
- package/openxiangda-skills/skills/openxiangda-app/SKILL.md +64 -0
- package/openxiangda-skills/skills/openxiangda-core/SKILL.md +143 -0
- package/openxiangda-skills/skills/openxiangda-form/SKILL.md +76 -0
- package/openxiangda-skills/skills/openxiangda-inspect/SKILL.md +40 -0
- package/openxiangda-skills/skills/openxiangda-page/SKILL.md +62 -0
- package/openxiangda-skills/skills/openxiangda-permission-settings/SKILL.md +95 -0
- package/openxiangda-skills/skills/openxiangda-workflow-automation/SKILL.md +97 -0
- package/package.json +126 -0
- package/packages/sdk/bin/lowcode-workspace.mjs +4 -0
- package/packages/sdk/dist/build/index.cjs +33 -0
- package/packages/sdk/dist/build/index.cjs.map +1 -0
- package/packages/sdk/dist/build/index.d.mts +40 -0
- package/packages/sdk/dist/build/index.d.ts +40 -0
- package/packages/sdk/dist/build/index.mjs +8 -0
- package/packages/sdk/dist/build/index.mjs.map +1 -0
- package/packages/sdk/dist/components/index.cjs +18700 -0
- package/packages/sdk/dist/components/index.cjs.map +1 -0
- package/packages/sdk/dist/components/index.d.mts +2094 -0
- package/packages/sdk/dist/components/index.d.ts +2094 -0
- package/packages/sdk/dist/components/index.mjs +18649 -0
- package/packages/sdk/dist/components/index.mjs.map +1 -0
- package/packages/sdk/dist/runtime/index.cjs +1469 -0
- package/packages/sdk/dist/runtime/index.cjs.map +1 -0
- package/packages/sdk/dist/runtime/index.d.mts +831 -0
- package/packages/sdk/dist/runtime/index.d.ts +831 -0
- package/packages/sdk/dist/runtime/index.mjs +1420 -0
- package/packages/sdk/dist/runtime/index.mjs.map +1 -0
- package/packages/sdk/dist/styles/antd-theme.cjs +60 -0
- package/packages/sdk/dist/styles/antd-theme.cjs.map +1 -0
- package/packages/sdk/dist/styles/antd-theme.d.mts +5 -0
- package/packages/sdk/dist/styles/antd-theme.d.ts +5 -0
- package/packages/sdk/dist/styles/antd-theme.mjs +35 -0
- package/packages/sdk/dist/styles/antd-theme.mjs.map +1 -0
- package/packages/sdk/dist/styles/tailwind-preset.cjs +2641 -0
- package/packages/sdk/dist/styles/tailwind-preset.cjs.map +1 -0
- package/packages/sdk/dist/styles/tailwind-preset.d.mts +75 -0
- package/packages/sdk/dist/styles/tailwind-preset.d.ts +75 -0
- package/packages/sdk/dist/styles/tailwind-preset.mjs +2618 -0
- package/packages/sdk/dist/styles/tailwind-preset.mjs.map +1 -0
- package/packages/sdk/dist/styles/tokens.css +73 -0
- package/packages/sdk/src/build-source/README.md +9 -0
- package/packages/sdk/src/build-source/bin/lowcode-workspace.mjs +7 -0
- package/packages/sdk/src/build-source/package.json +34 -0
- package/packages/sdk/src/build-source/scripts/build-forms.mjs +824 -0
- package/packages/sdk/src/build-source/scripts/build-forms.runtime-entry.test.ts +18 -0
- package/packages/sdk/src/build-source/scripts/build-pages.mjs +793 -0
- package/packages/sdk/src/build-source/scripts/build-workspace.mjs +64 -0
- package/packages/sdk/src/build-source/scripts/publish-all.mjs +127 -0
- package/packages/sdk/src/build-source/scripts/publish-oss.mjs +149 -0
- package/packages/sdk/src/build-source/scripts/register-bundle.mjs +1 -0
- package/packages/sdk/src/build-source/scripts/register.mjs +329 -0
- package/packages/sdk/src/build-source/scripts/sync-schema.mjs +301 -0
- package/packages/sdk/src/build-source/scripts/utils/form-api.mjs +639 -0
- package/packages/sdk/src/build-source/scripts/utils/form-api.test.ts +244 -0
- package/packages/sdk/src/build-source/scripts/utils/form-runtime-assets.mjs +57 -0
- package/packages/sdk/src/build-source/scripts/utils/form-runtime-assets.test.ts +135 -0
- package/packages/sdk/src/build-source/scripts/utils/incremental.mjs +210 -0
- package/packages/sdk/src/build-source/scripts/utils/load-config.mjs +257 -0
- package/packages/sdk/src/build-source/scripts/utils/load-config.test.ts +44 -0
- package/packages/sdk/src/build-source/scripts/utils/mime-types.mjs +70 -0
- package/packages/sdk/src/build-source/scripts/utils/namespace-css.mjs +61 -0
- package/packages/sdk/src/build-source/scripts/utils/oss-client.mjs +128 -0
- package/packages/sdk/src/build-source/scripts/utils/pages.mjs +80 -0
- package/packages/sdk/src/build-source/scripts/utils/progress.mjs +57 -0
- package/packages/sdk/src/build-source/scripts/utils/register-payload.mjs +89 -0
- package/packages/sdk/src/build-source/scripts/utils/register-payload.test.ts +76 -0
- package/packages/sdk/src/build-source/scripts/utils/runtime-css-check.mjs +44 -0
- package/packages/sdk/src/build-source/scripts/utils/runtime-css-check.test.ts +54 -0
- package/packages/sdk/src/build-source/scripts/utils/schema-transform.mjs +130 -0
- package/packages/sdk/src/build-source/scripts/utils/schema-transform.test.ts +141 -0
- package/packages/sdk/src/build-source/scripts/utils/tailwind-config.mjs +227 -0
- package/packages/sdk/src/build-source/scripts/utils/tailwind-config.test.ts +187 -0
- package/packages/sdk/src/build-source/src/cli.mjs +679 -0
- package/templates/sy-lowcode-app-workspace/app-workspace.config.ts +34 -0
- package/templates/sy-lowcode-app-workspace/examples/forms/customer/page.tsx +1 -0
- package/templates/sy-lowcode-app-workspace/examples/forms/customer/schema.ts +35 -0
- package/templates/sy-lowcode-app-workspace/index.html +12 -0
- package/templates/sy-lowcode-app-workspace/package.json +49 -0
- package/templates/sy-lowcode-app-workspace/postcss.config.cjs +6 -0
- package/templates/sy-lowcode-app-workspace/scripts/build-js-code.mjs +100 -0
- package/templates/sy-lowcode-app-workspace/src/dev/App.tsx +26 -0
- package/templates/sy-lowcode-app-workspace/src/forms/.gitkeep +1 -0
- package/templates/sy-lowcode-app-workspace/src/forms/README.md +48 -0
- package/templates/sy-lowcode-app-workspace/src/index.css +28 -0
- package/templates/sy-lowcode-app-workspace/src/js-code-nodes/.gitkeep +1 -0
- package/templates/sy-lowcode-app-workspace/src/js-code-nodes/types.d.ts +3 -0
- package/templates/sy-lowcode-app-workspace/src/main.tsx +36 -0
- package/templates/sy-lowcode-app-workspace/src/pages/.gitkeep +1 -0
- package/templates/sy-lowcode-app-workspace/src/shared/form-schema.ts +128 -0
- package/templates/sy-lowcode-app-workspace/src/types/app-workspace.types.ts +31 -0
- package/templates/sy-lowcode-app-workspace/tailwind.config.cjs +30 -0
- package/templates/sy-lowcode-app-workspace/tsconfig.app.json +24 -0
- package/templates/sy-lowcode-app-workspace/tsconfig.js-code-nodes.json +15 -0
- package/templates/sy-lowcode-app-workspace/tsconfig.json +7 -0
- package/templates/sy-lowcode-app-workspace/tsconfig.node.json +10 -0
- package/templates/sy-lowcode-app-workspace/vite.config.ts +32 -0
|
@@ -0,0 +1,492 @@
|
|
|
1
|
+
# OpenXiangda 样式体系参考
|
|
2
|
+
|
|
3
|
+
> 本文档面向 AI Agent,约束代码页面/表单/工作流自定义节点的样式编写规范。**严禁硬编码颜色、间距、圆角、字号、阴影**,统一通过三层变量体系消费设计 Token。
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 1. 样式体系总览
|
|
8
|
+
|
|
9
|
+
### 1.1 三层结构
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
┌──────────────────────────────────────────────────────────────┐
|
|
13
|
+
│ Layer 3: Tailwind Utilities (原子类层) │
|
|
14
|
+
│ 语义化类名 → 引用 CSS Variables │
|
|
15
|
+
│ 例: text-primary, bg-container, gap-form, rounded-form │
|
|
16
|
+
└──────────────────────────────────────────────────────────────┘
|
|
17
|
+
▲
|
|
18
|
+
│ 引用
|
|
19
|
+
│
|
|
20
|
+
┌──────────────────────────────────────────────────────────────┐
|
|
21
|
+
│ Layer 2: AntD Theme Token (组件库层) │
|
|
22
|
+
│ ConfigProvider.theme.token → 映射到 CSS Variables │
|
|
23
|
+
│ 例: colorPrimary: var(--sy-color-primary) │
|
|
24
|
+
└──────────────────────────────────────────────────────────────┘
|
|
25
|
+
▲
|
|
26
|
+
│ 映射
|
|
27
|
+
│
|
|
28
|
+
┌──────────────────────────────────────────────────────────────┐
|
|
29
|
+
│ Layer 1: CSS Variables (基础层 / Single Source of Truth) │
|
|
30
|
+
│ --sy-color-*, --sy-spacing-*, --sy-radius-*, --sy-shadow-* │
|
|
31
|
+
│ 定义在 :root 与 .sy-app-workspace │
|
|
32
|
+
└──────────────────────────────────────────────────────────────┘
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
**核心原则**:所有视觉 Token 来源于 Layer 1 的 CSS Variables;AntD 与 Tailwind 都只是 Layer 1 的消费者。
|
|
36
|
+
|
|
37
|
+
### 1.2 为什么不使用 Shadow DOM
|
|
38
|
+
|
|
39
|
+
| 维度 | Shadow DOM | CSS Namespace(当前方案)|
|
|
40
|
+
|---|---|---|
|
|
41
|
+
| antd 弹层(Modal/Drawer/Select 下拉/DatePicker)| **失效** —— 默认挂载到 `document.body`,逃出 Shadow 边界后丢失样式 | **正常** —— 通过 `getPopupContainer` 挂载到 `.sy-app-workspace` 内 |
|
|
42
|
+
| 全局样式继承 | 完全隔离,需重写所有基础样式 | 受控隔离,通过命名空间避免冲突 |
|
|
43
|
+
| 调试体验 | DevTools 跨边界困难 | 与普通 DOM 一致 |
|
|
44
|
+
| 主题切换 | 必须穿透 Shadow Root | 直接覆盖 `.sy-app-workspace` 上的 CSS 变量 |
|
|
45
|
+
|
|
46
|
+
**结论**:Shadow DOM 与 antd 的 Portal 弹层机制不兼容;改用 `.sy-app-workspace` 命名空间方案。
|
|
47
|
+
|
|
48
|
+
### 1.3 CSS Namespace 隔离原理
|
|
49
|
+
|
|
50
|
+
- 应用根节点统一加 `class="sy-app-workspace"`。
|
|
51
|
+
- 所有自定义样式(Tailwind、业务 CSS)通过 `.sy-app-workspace` 前缀限定作用域。
|
|
52
|
+
- AntD CSS-in-JS 通过 `ConfigProvider.theme.cssVar.prefix = 'sy-ant'` 输出独立变量名,避免与宿主页面碰撞。
|
|
53
|
+
- 弹层容器通过 `getPopupContainer={() => document.querySelector('.sy-app-workspace')}` 锚定到命名空间内部。
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
## 2. Layer 1:CSS Variables 设计 Token
|
|
58
|
+
|
|
59
|
+
> 唯一真源(Single Source of Truth)。**所有变量同时挂载在 `:root` 与 `.sy-app-workspace`**,前者用于全局可用,后者保证命名空间生效时不依赖根选择器。
|
|
60
|
+
|
|
61
|
+
```css
|
|
62
|
+
:root, .sy-app-workspace {
|
|
63
|
+
/* ───── 品牌色 ───── */
|
|
64
|
+
--sy-color-primary: #1677ff;
|
|
65
|
+
--sy-color-primary-hover: #4096ff;
|
|
66
|
+
--sy-color-primary-active: #0958d9;
|
|
67
|
+
--sy-color-success: #52c41a;
|
|
68
|
+
--sy-color-warning: #faad14;
|
|
69
|
+
--sy-color-error: #ff4d4f;
|
|
70
|
+
|
|
71
|
+
/* ───── 文本 ───── */
|
|
72
|
+
--sy-color-text: rgba(0, 0, 0, 0.88);
|
|
73
|
+
--sy-color-text-secondary: rgba(0, 0, 0, 0.65);
|
|
74
|
+
--sy-color-text-tertiary: rgba(0, 0, 0, 0.45);
|
|
75
|
+
--sy-color-text-disabled: rgba(0, 0, 0, 0.25);
|
|
76
|
+
|
|
77
|
+
/* ───── 背景 ───── */
|
|
78
|
+
--sy-color-bg-container: #ffffff;
|
|
79
|
+
--sy-color-bg-layout: #f5f5f5;
|
|
80
|
+
--sy-color-bg-elevated: #ffffff;
|
|
81
|
+
|
|
82
|
+
/* ───── 边框 ───── */
|
|
83
|
+
--sy-color-border: #d9d9d9;
|
|
84
|
+
--sy-color-border-secondary: #f0f0f0;
|
|
85
|
+
|
|
86
|
+
/* ───── 间距 ───── */
|
|
87
|
+
--sy-spacing-xs: 4px;
|
|
88
|
+
--sy-spacing-sm: 8px;
|
|
89
|
+
--sy-spacing-md: 16px;
|
|
90
|
+
--sy-spacing-lg: 24px;
|
|
91
|
+
--sy-spacing-xl: 32px;
|
|
92
|
+
|
|
93
|
+
/* ───── 圆角 ───── */
|
|
94
|
+
--sy-radius-sm: 4px;
|
|
95
|
+
--sy-radius-md: 6px;
|
|
96
|
+
--sy-radius-lg: 8px;
|
|
97
|
+
|
|
98
|
+
/* ───── 字体 ───── */
|
|
99
|
+
--sy-font-size-sm: 12px;
|
|
100
|
+
--sy-font-size-base: 14px;
|
|
101
|
+
--sy-font-size-lg: 16px;
|
|
102
|
+
--sy-font-size-xl: 20px;
|
|
103
|
+
--sy-font-size-2xl: 24px;
|
|
104
|
+
|
|
105
|
+
/* ───── 阴影 ───── */
|
|
106
|
+
--sy-shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.03), 0 1px 6px -1px rgba(0, 0, 0, 0.02);
|
|
107
|
+
--sy-shadow-md: 0 6px 16px rgba(0, 0, 0, 0.08), 0 3px 6px -4px rgba(0, 0, 0, 0.12);
|
|
108
|
+
--sy-shadow-lg: 0 12px 40px rgba(0, 0, 0, 0.12);
|
|
109
|
+
|
|
110
|
+
/* ───── 表单特定 ───── */
|
|
111
|
+
--sy-form-gap: 16px;
|
|
112
|
+
--sy-form-padding: 24px;
|
|
113
|
+
--sy-form-field-height: 32px;
|
|
114
|
+
}
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
### 2.1 Token 速查表
|
|
118
|
+
|
|
119
|
+
| 类别 | 变量 | 默认值 | 用途 |
|
|
120
|
+
|---|---|---|---|
|
|
121
|
+
| 品牌 | `--sy-color-primary` | `#1677ff` | 主按钮、主色链接、激活态 |
|
|
122
|
+
| 品牌 | `--sy-color-primary-hover` | `#4096ff` | 主色 hover |
|
|
123
|
+
| 品牌 | `--sy-color-primary-active` | `#0958d9` | 主色 active/pressed |
|
|
124
|
+
| 状态 | `--sy-color-success` | `#52c41a` | 成功/通过 |
|
|
125
|
+
| 状态 | `--sy-color-warning` | `#faad14` | 警示 |
|
|
126
|
+
| 状态 | `--sy-color-error` | `#ff4d4f` | 错误/危险操作 |
|
|
127
|
+
| 文本 | `--sy-color-text` | `rgba(0,0,0,.88)` | 主文本 |
|
|
128
|
+
| 文本 | `--sy-color-text-secondary` | `rgba(0,0,0,.65)` | 次文本 |
|
|
129
|
+
| 文本 | `--sy-color-text-tertiary` | `rgba(0,0,0,.45)` | 提示/占位 |
|
|
130
|
+
| 文本 | `--sy-color-text-disabled` | `rgba(0,0,0,.25)` | 禁用 |
|
|
131
|
+
| 背景 | `--sy-color-bg-container` | `#ffffff` | 卡片/输入框 |
|
|
132
|
+
| 背景 | `--sy-color-bg-layout` | `#f5f5f5` | 页面底色 |
|
|
133
|
+
| 背景 | `--sy-color-bg-elevated` | `#ffffff` | 浮层/抽屉 |
|
|
134
|
+
| 边框 | `--sy-color-border` | `#d9d9d9` | 实体边框 |
|
|
135
|
+
| 边框 | `--sy-color-border-secondary` | `#f0f0f0` | 分隔线 |
|
|
136
|
+
| 间距 | `--sy-spacing-{xs\|sm\|md\|lg\|xl}` | 4/8/16/24/32 | 通用间距 |
|
|
137
|
+
| 圆角 | `--sy-radius-{sm\|md\|lg}` | 4/6/8 | 通用圆角 |
|
|
138
|
+
| 字号 | `--sy-font-size-{sm\|base\|lg\|xl\|2xl}` | 12/14/16/20/24 | 字号阶梯 |
|
|
139
|
+
| 阴影 | `--sy-shadow-{sm\|md\|lg}` | 见上 | 卡片/浮层阴影 |
|
|
140
|
+
| 表单 | `--sy-form-gap` | `16px` | 表单字段间距 |
|
|
141
|
+
| 表单 | `--sy-form-padding` | `24px` | 表单容器内边距 |
|
|
142
|
+
| 表单 | `--sy-form-field-height` | `32px` | 输入框高度 |
|
|
143
|
+
|
|
144
|
+
---
|
|
145
|
+
|
|
146
|
+
## 3. Layer 2:AntD Theme Token 映射
|
|
147
|
+
|
|
148
|
+
通过 `ConfigProvider` 让 antd 组件读取 CSS 变量,实现"改变量即改主题"。
|
|
149
|
+
|
|
150
|
+
```tsx
|
|
151
|
+
import { ConfigProvider } from 'antd';
|
|
152
|
+
|
|
153
|
+
export function AppThemeProvider({ children }: { children: React.ReactNode }) {
|
|
154
|
+
return (
|
|
155
|
+
<ConfigProvider
|
|
156
|
+
// 让弹层挂载到命名空间容器内(关键:保证 CSS 变量可达)
|
|
157
|
+
getPopupContainer={() =>
|
|
158
|
+
(document.querySelector('.sy-app-workspace') as HTMLElement) ?? document.body
|
|
159
|
+
}
|
|
160
|
+
theme={{
|
|
161
|
+
cssVar: { prefix: 'sy-ant' }, // 输出 --sy-ant-* 变量,避免冲突
|
|
162
|
+
hashed: false, // 与 cssVar 配合,禁用 hash
|
|
163
|
+
token: {
|
|
164
|
+
// 颜色
|
|
165
|
+
colorPrimary: 'var(--sy-color-primary)',
|
|
166
|
+
colorSuccess: 'var(--sy-color-success)',
|
|
167
|
+
colorWarning: 'var(--sy-color-warning)',
|
|
168
|
+
colorError: 'var(--sy-color-error)',
|
|
169
|
+
colorText: 'var(--sy-color-text)',
|
|
170
|
+
colorTextSecondary: 'var(--sy-color-text-secondary)',
|
|
171
|
+
colorTextTertiary: 'var(--sy-color-text-tertiary)',
|
|
172
|
+
colorTextDisabled: 'var(--sy-color-text-disabled)',
|
|
173
|
+
colorBgContainer: 'var(--sy-color-bg-container)',
|
|
174
|
+
colorBgLayout: 'var(--sy-color-bg-layout)',
|
|
175
|
+
colorBgElevated: 'var(--sy-color-bg-elevated)',
|
|
176
|
+
colorBorder: 'var(--sy-color-border)',
|
|
177
|
+
colorBorderSecondary: 'var(--sy-color-border-secondary)',
|
|
178
|
+
|
|
179
|
+
// 度量(antd token 不支持 var(),需用数值;通过 components 精细控制时再用 var)
|
|
180
|
+
borderRadius: 6,
|
|
181
|
+
borderRadiusLG: 8,
|
|
182
|
+
borderRadiusSM: 4,
|
|
183
|
+
fontSize: 14,
|
|
184
|
+
controlHeight: 32,
|
|
185
|
+
},
|
|
186
|
+
components: {
|
|
187
|
+
Form: { itemMarginBottom: 16 },
|
|
188
|
+
Card: { paddingLG: 24 },
|
|
189
|
+
},
|
|
190
|
+
}}
|
|
191
|
+
>
|
|
192
|
+
{children}
|
|
193
|
+
</ConfigProvider>
|
|
194
|
+
);
|
|
195
|
+
}
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
> **注意**:antd token 中数值类(borderRadius/fontSize/controlHeight)需直接写数值,与 Layer 1 的 `--sy-radius-md`/`--sy-font-size-base`/`--sy-form-field-height` 保持同步即可。
|
|
199
|
+
|
|
200
|
+
---
|
|
201
|
+
|
|
202
|
+
## 4. Layer 3:Tailwind 语义化工具类
|
|
203
|
+
|
|
204
|
+
`tailwind-preset.ts` 基于 CSS Variables 扩展语义化类,**优先使用语义类**而非数值类。
|
|
205
|
+
|
|
206
|
+
### 4.1 颜色类
|
|
207
|
+
|
|
208
|
+
| Tailwind 类 | 等价 CSS | 场景 |
|
|
209
|
+
|---|---|---|
|
|
210
|
+
| `text-primary` | `color: var(--sy-color-primary)` | 主色文本/链接 |
|
|
211
|
+
| `text-success` | `color: var(--sy-color-success)` | 成功文本 |
|
|
212
|
+
| `text-warning` | `color: var(--sy-color-warning)` | 警示文本 |
|
|
213
|
+
| `text-error` | `color: var(--sy-color-error)` | 错误文本 |
|
|
214
|
+
| `text-default` | `color: var(--sy-color-text)` | 主文本 |
|
|
215
|
+
| `text-secondary` | `color: var(--sy-color-text-secondary)` | 次文本 |
|
|
216
|
+
| `text-tertiary` | `color: var(--sy-color-text-tertiary)` | 提示文本 |
|
|
217
|
+
| `text-disabled` | `color: var(--sy-color-text-disabled)` | 禁用文本 |
|
|
218
|
+
| `bg-container` | `background: var(--sy-color-bg-container)` | 卡片底 |
|
|
219
|
+
| `bg-layout` | `background: var(--sy-color-bg-layout)` | 页面底 |
|
|
220
|
+
| `bg-elevated` | `background: var(--sy-color-bg-elevated)` | 浮层底 |
|
|
221
|
+
| `border-default` | `border-color: var(--sy-color-border)` | 边框 |
|
|
222
|
+
| `border-secondary` | `border-color: var(--sy-color-border-secondary)` | 分隔 |
|
|
223
|
+
|
|
224
|
+
### 4.2 间距 / 布局类
|
|
225
|
+
|
|
226
|
+
| Tailwind 类 | 等价 CSS |
|
|
227
|
+
|---|---|
|
|
228
|
+
| `gap-form` | `gap: var(--sy-form-gap)` |
|
|
229
|
+
| `p-form` | `padding: var(--sy-form-padding)` |
|
|
230
|
+
| `px-form` / `py-form` | `padding-inline / padding-block: var(--sy-form-padding)` |
|
|
231
|
+
| `space-y-form > * + *` | `margin-top: var(--sy-form-gap)` |
|
|
232
|
+
| `h-field` | `height: var(--sy-form-field-height)` |
|
|
233
|
+
|
|
234
|
+
### 4.3 圆角 / 阴影 / 字号
|
|
235
|
+
|
|
236
|
+
| Tailwind 类 | 等价 CSS |
|
|
237
|
+
|---|---|
|
|
238
|
+
| `rounded-form` | `border-radius: var(--sy-radius-md)` |
|
|
239
|
+
| `rounded-card` | `border-radius: var(--sy-radius-lg)` |
|
|
240
|
+
| `rounded-pill` | `border-radius: var(--sy-radius-sm)` |
|
|
241
|
+
| `shadow-card` | `box-shadow: var(--sy-shadow-md)` |
|
|
242
|
+
| `shadow-popover` | `box-shadow: var(--sy-shadow-lg)` |
|
|
243
|
+
| `shadow-subtle` | `box-shadow: var(--sy-shadow-sm)` |
|
|
244
|
+
| `text-sm-sy` | `font-size: var(--sy-font-size-sm)` |
|
|
245
|
+
| `text-base-sy` | `font-size: var(--sy-font-size-base)` |
|
|
246
|
+
| `text-lg-sy` | `font-size: var(--sy-font-size-lg)` |
|
|
247
|
+
| `text-xl-sy` | `font-size: var(--sy-font-size-xl)` |
|
|
248
|
+
| `text-2xl-sy` | `font-size: var(--sy-font-size-2xl)` |
|
|
249
|
+
|
|
250
|
+
> 通用 Tailwind 数值类(如 `p-4`、`text-sm`)仍可使用,但**当存在语义类时优先用语义类**。
|
|
251
|
+
|
|
252
|
+
---
|
|
253
|
+
|
|
254
|
+
## 5. 禁止规则(AI Agent 必须遵守)
|
|
255
|
+
|
|
256
|
+
| # | 规则 | 反例 | 正例 |
|
|
257
|
+
|---|---|---|---|
|
|
258
|
+
| 1 | **禁止硬编码颜色** | `color: #333`、`className="bg-[#1677ff]"` | `text-default`、`bg-container` 或 `var(--sy-color-primary)` |
|
|
259
|
+
| 2 | **禁止硬编码间距** | `padding: 16px`、`className="p-[24px]"` | `p-form`、`var(--sy-spacing-md)` |
|
|
260
|
+
| 3 | **禁止用数值类替代语义类** | `className="rounded-md gap-4"`(用于表单时)| `className="rounded-form gap-form"` |
|
|
261
|
+
| 4 | **禁止内联颜色/间距** | `<div style={{ color: '#1677ff', padding: 16 }}>` | `<div className="text-primary p-form">` |
|
|
262
|
+
| 5 | **禁止绕过 ConfigProvider 直接覆盖 antd 类名** | `.ant-btn { background: red }` | 通过 `theme.token.colorPrimary` 或自定义类组合 |
|
|
263
|
+
| 6 | **禁止 antd 弹层挂到 body** | 默认行为 | 通过 `getPopupContainer` 锚定到 `.sy-app-workspace` |
|
|
264
|
+
| 7 | **禁止在样式中假设白色/黑色背景** | `color: #fff`(在深色主题失效)| `text-default`,让 Token 决定 |
|
|
265
|
+
|
|
266
|
+
---
|
|
267
|
+
|
|
268
|
+
## 6. 正确示例 vs 错误示例
|
|
269
|
+
|
|
270
|
+
### 示例 1:主操作按钮的容器
|
|
271
|
+
|
|
272
|
+
```tsx
|
|
273
|
+
// ❌ 错误:硬编码颜色 + 硬编码间距
|
|
274
|
+
<div style={{ background: '#fff', padding: 24, borderRadius: 6 }}>
|
|
275
|
+
<button style={{ background: '#1677ff', color: '#fff' }}>提交</button>
|
|
276
|
+
</div>
|
|
277
|
+
|
|
278
|
+
// ✅ 正确:语义类 + antd 组件
|
|
279
|
+
<div className="bg-container p-form rounded-form">
|
|
280
|
+
<Button type="primary">提交</Button>
|
|
281
|
+
</div>
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
### 示例 2:表单字段布局
|
|
285
|
+
|
|
286
|
+
```tsx
|
|
287
|
+
// ❌ 错误:随意数值类
|
|
288
|
+
<div className="flex flex-col gap-[16px] p-[24px]">
|
|
289
|
+
<Input className="h-[32px]" />
|
|
290
|
+
<Input className="h-[32px]" />
|
|
291
|
+
</div>
|
|
292
|
+
|
|
293
|
+
// ✅ 正确:表单语义类
|
|
294
|
+
<div className="flex flex-col gap-form p-form">
|
|
295
|
+
<Input />
|
|
296
|
+
<Input />
|
|
297
|
+
</div>
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
### 示例 3:状态文案
|
|
301
|
+
|
|
302
|
+
```tsx
|
|
303
|
+
// ❌ 错误:直接写颜色值
|
|
304
|
+
<span style={{ color: '#52c41a' }}>已通过</span>
|
|
305
|
+
<span style={{ color: '#ff4d4f' }}>已驳回</span>
|
|
306
|
+
|
|
307
|
+
// ✅ 正确:状态语义类
|
|
308
|
+
<span className="text-success">已通过</span>
|
|
309
|
+
<span className="text-error">已驳回</span>
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
### 示例 4:卡片容器
|
|
313
|
+
|
|
314
|
+
```tsx
|
|
315
|
+
// ❌ 错误:阴影硬编码
|
|
316
|
+
<div style={{
|
|
317
|
+
background: '#fff',
|
|
318
|
+
boxShadow: '0 6px 16px rgba(0,0,0,0.08)',
|
|
319
|
+
borderRadius: 8
|
|
320
|
+
}}>...</div>
|
|
321
|
+
|
|
322
|
+
// ✅ 正确:语义类
|
|
323
|
+
<div className="bg-container shadow-card rounded-card">...</div>
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
### 示例 5:次要文本 + 提示
|
|
327
|
+
|
|
328
|
+
```tsx
|
|
329
|
+
// ❌ 错误:rgba 硬编码
|
|
330
|
+
<p style={{ color: 'rgba(0,0,0,0.65)', fontSize: 12 }}>提示信息</p>
|
|
331
|
+
|
|
332
|
+
// ✅ 正确:层级语义
|
|
333
|
+
<p className="text-secondary text-sm-sy">提示信息</p>
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
### 示例 6:自定义代码节点的 CSS(局部样式表)
|
|
337
|
+
|
|
338
|
+
```css
|
|
339
|
+
/* ❌ 错误 */
|
|
340
|
+
.my-node-card {
|
|
341
|
+
background: #ffffff;
|
|
342
|
+
border: 1px solid #d9d9d9;
|
|
343
|
+
padding: 16px;
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
/* ✅ 正确 */
|
|
347
|
+
.sy-app-workspace .my-node-card {
|
|
348
|
+
background: var(--sy-color-bg-container);
|
|
349
|
+
border: 1px solid var(--sy-color-border);
|
|
350
|
+
padding: var(--sy-spacing-md);
|
|
351
|
+
border-radius: var(--sy-radius-md);
|
|
352
|
+
}
|
|
353
|
+
```
|
|
354
|
+
|
|
355
|
+
---
|
|
356
|
+
|
|
357
|
+
## 7. 自定义主题
|
|
358
|
+
|
|
359
|
+
### 7.1 全局主题切换
|
|
360
|
+
|
|
361
|
+
直接覆盖 `.sy-app-workspace` 上的 CSS 变量即可,**无需重新构建**:
|
|
362
|
+
|
|
363
|
+
```css
|
|
364
|
+
/* 应用 A —— 默认蓝 */
|
|
365
|
+
.sy-app-workspace.theme-default {
|
|
366
|
+
--sy-color-primary: #1677ff;
|
|
367
|
+
--sy-color-primary-hover: #4096ff;
|
|
368
|
+
--sy-color-primary-active: #0958d9;
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
/* 应用 B —— 品牌绿 */
|
|
372
|
+
.sy-app-workspace.theme-brand-green {
|
|
373
|
+
--sy-color-primary: #00b96b;
|
|
374
|
+
--sy-color-primary-hover: #2fd58a;
|
|
375
|
+
--sy-color-primary-active: #008a4f;
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
/* 应用 C —— 暗色 */
|
|
379
|
+
.sy-app-workspace.theme-dark {
|
|
380
|
+
--sy-color-text: rgba(255, 255, 255, 0.88);
|
|
381
|
+
--sy-color-text-secondary: rgba(255, 255, 255, 0.65);
|
|
382
|
+
--sy-color-bg-container: #1f1f1f;
|
|
383
|
+
--sy-color-bg-layout: #141414;
|
|
384
|
+
--sy-color-border: #424242;
|
|
385
|
+
}
|
|
386
|
+
```
|
|
387
|
+
|
|
388
|
+
```tsx
|
|
389
|
+
// 运行时切换
|
|
390
|
+
document.querySelector('.sy-app-workspace')?.classList.toggle('theme-dark');
|
|
391
|
+
```
|
|
392
|
+
|
|
393
|
+
由于 antd token 与 Tailwind 语义类都引用相同 CSS 变量,**变量一改,三层全变**。
|
|
394
|
+
|
|
395
|
+
### 7.2 单应用差异化
|
|
396
|
+
|
|
397
|
+
不同应用可在自身 workspace 入口注入差异化变量:
|
|
398
|
+
|
|
399
|
+
```tsx
|
|
400
|
+
// app-workspace.config.ts(应用级)
|
|
401
|
+
export default {
|
|
402
|
+
theme: {
|
|
403
|
+
'--sy-color-primary': '#722ed1',
|
|
404
|
+
'--sy-radius-md': '10px',
|
|
405
|
+
}
|
|
406
|
+
};
|
|
407
|
+
```
|
|
408
|
+
|
|
409
|
+
入口处将 `theme` 对象 inline 到根容器 `style` 上即可。
|
|
410
|
+
|
|
411
|
+
---
|
|
412
|
+
|
|
413
|
+
## 8. CSS Namespace 下的特殊注意事项
|
|
414
|
+
|
|
415
|
+
### 8.1 根容器要求
|
|
416
|
+
|
|
417
|
+
```tsx
|
|
418
|
+
// 应用入口必须包裹 .sy-app-workspace
|
|
419
|
+
<div className="sy-app-workspace">
|
|
420
|
+
<AppThemeProvider>
|
|
421
|
+
<YourApp />
|
|
422
|
+
</AppThemeProvider>
|
|
423
|
+
</div>
|
|
424
|
+
```
|
|
425
|
+
|
|
426
|
+
### 8.2 Tailwind 配置(关键)
|
|
427
|
+
|
|
428
|
+
`tailwind.config.cjs` 中:
|
|
429
|
+
|
|
430
|
+
```js
|
|
431
|
+
module.exports = {
|
|
432
|
+
important: '.sy-app-workspace', // 所有 Tailwind 工具类都受命名空间限定
|
|
433
|
+
corePlugins: {
|
|
434
|
+
preflight: false, // 避免污染宿主页面
|
|
435
|
+
},
|
|
436
|
+
content: ['./src/**/*.{ts,tsx}'],
|
|
437
|
+
presets: [require('./tailwind-preset')],
|
|
438
|
+
};
|
|
439
|
+
```
|
|
440
|
+
|
|
441
|
+
`important: '.sy-app-workspace'` 让所有原子类输出形如 `.sy-app-workspace .text-primary { ... }`,自动隔离。
|
|
442
|
+
|
|
443
|
+
### 8.3 antd 弹层挂载
|
|
444
|
+
|
|
445
|
+
任何 `Modal` / `Drawer` / `Select` / `DatePicker` / `Tooltip` 等组件,**必须**通过 `ConfigProvider.getPopupContainer` 或局部 `getPopupContainer` 锚定到命名空间容器:
|
|
446
|
+
|
|
447
|
+
```tsx
|
|
448
|
+
<ConfigProvider
|
|
449
|
+
getPopupContainer={() =>
|
|
450
|
+
(document.querySelector('.sy-app-workspace') as HTMLElement) ?? document.body
|
|
451
|
+
}
|
|
452
|
+
>
|
|
453
|
+
...
|
|
454
|
+
</ConfigProvider>
|
|
455
|
+
```
|
|
456
|
+
|
|
457
|
+
否则弹层会挂到 `document.body`,导致 CSS 变量无法继承、Tailwind 工具类失效。
|
|
458
|
+
|
|
459
|
+
### 8.4 第三方组件库
|
|
460
|
+
|
|
461
|
+
引入第三方组件时,若其样式依赖全局 reset,需在 `.sy-app-workspace` 内手动补齐;不要依赖 Tailwind preflight。
|
|
462
|
+
|
|
463
|
+
### 8.5 字体与基础样式
|
|
464
|
+
|
|
465
|
+
基础 `font-family` / `line-height` 应在 `.sy-app-workspace` 上设置一次,避免逐组件重复:
|
|
466
|
+
|
|
467
|
+
```css
|
|
468
|
+
.sy-app-workspace {
|
|
469
|
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'PingFang SC',
|
|
470
|
+
'Hiragino Sans GB', 'Microsoft YaHei', sans-serif;
|
|
471
|
+
font-size: var(--sy-font-size-base);
|
|
472
|
+
color: var(--sy-color-text);
|
|
473
|
+
line-height: 1.5715;
|
|
474
|
+
}
|
|
475
|
+
```
|
|
476
|
+
|
|
477
|
+
---
|
|
478
|
+
|
|
479
|
+
## 速查 Cheatsheet
|
|
480
|
+
|
|
481
|
+
| 想做什么 | 用什么 |
|
|
482
|
+
|---|---|
|
|
483
|
+
| 主色按钮 | `<Button type="primary">` |
|
|
484
|
+
| 主色文本 | `className="text-primary"` |
|
|
485
|
+
| 卡片容器 | `className="bg-container shadow-card rounded-card p-form"` |
|
|
486
|
+
| 表单纵向布局 | `className="flex flex-col gap-form"` |
|
|
487
|
+
| 错误状态文本 | `className="text-error"` |
|
|
488
|
+
| 次要说明文本 | `className="text-secondary text-sm-sy"` |
|
|
489
|
+
| 浮层背景 | `className="bg-elevated shadow-popover"` |
|
|
490
|
+
| 分隔线 | `className="border-t border-secondary"` |
|
|
491
|
+
| 切换主题 | 改 `.sy-app-workspace` 的 CSS 变量 |
|
|
492
|
+
| 弹层挂载 | `getPopupContainer` 指向 `.sy-app-workspace` |
|