@gyyxds/zy-ui 0.0.1 → 0.0.2

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.
Files changed (39) hide show
  1. package/CHANGELOG.md +23 -19
  2. package/CONTRIBUTING.md +102 -99
  3. package/README.md +371 -162
  4. package/dist/zy-ui/badge/ZyBadge.vue.d.ts +4 -4
  5. package/dist/zy-ui/badge/index.d.ts +6 -6
  6. package/dist/zy-ui/button/ZyButton.vue.d.ts +3 -3
  7. package/dist/zy-ui/button/index.d.ts +9 -9
  8. package/dist/zy-ui/card/ZyCard.vue.d.ts +1 -1
  9. package/dist/zy-ui/card/index.d.ts +3 -3
  10. package/dist/zy-ui/checkbox/ZyCheckboxGroup.vue.d.ts +1 -1
  11. package/dist/zy-ui/checkbox/index.d.ts +3 -3
  12. package/dist/zy-ui/code-input/ZyCodeInput.vue.d.ts +2 -2
  13. package/dist/zy-ui/code-input/index.d.ts +2 -2
  14. package/dist/zy-ui/divider/ZyDivider.vue.d.ts +1 -1
  15. package/dist/zy-ui/divider/index.d.ts +3 -3
  16. package/dist/zy-ui/icon/ZyIcon.vue.d.ts +1 -1
  17. package/dist/zy-ui/icon/index.d.ts +1 -1
  18. package/dist/zy-ui/index.d.ts +46 -46
  19. package/dist/zy-ui/input/ZyInput.vue.d.ts +3 -3
  20. package/dist/zy-ui/input/index.d.ts +3 -3
  21. package/dist/zy-ui/loading/ZyLoading.vue.d.ts +1 -1
  22. package/dist/zy-ui/loading/index.d.ts +1 -1
  23. package/dist/zy-ui/mega-menu/ZyMegaMenu.vue.d.ts +4 -4
  24. package/dist/zy-ui/progress/ZyProgress.vue.d.ts +1 -1
  25. package/dist/zy-ui/progress/index.d.ts +3 -3
  26. package/dist/zy-ui/radio/ZyRadioGroup.vue.d.ts +3 -3
  27. package/dist/zy-ui/select/ZySelect.vue.d.ts +1 -1
  28. package/dist/zy-ui/select/index.d.ts +3 -3
  29. package/dist/zy-ui/space/ZySpace.vue.d.ts +1 -1
  30. package/dist/zy-ui/space/index.d.ts +3 -3
  31. package/dist/zy-ui/table/ZyTable.vue.d.ts +3 -3
  32. package/dist/zy-ui/tag/ZyTag.vue.d.ts +2 -2
  33. package/dist/zy-ui/tag/index.d.ts +6 -6
  34. package/dist/zy-ui/themes/basic.css +832 -832
  35. package/dist/zy-ui/themes/material.css +37 -37
  36. package/dist/zy-ui/tree/ZyTree.vue.d.ts +2 -2
  37. package/dist/zy-ui/zy-ui.css +1 -1
  38. package/dist/zy-ui/zy-ui.js +66 -41
  39. package/package.json +83 -82
package/README.md CHANGED
@@ -1,162 +1,371 @@
1
- # MotionVault / @zy/zy-ui
2
-
3
- 组件库 + 动效片段库:同一个仓库,两套产物、两套规矩。
4
-
5
- > 当前状态:**28 个可发布组件**、**57 个动效片段**。
6
-
7
- ## 两个东西,别混
8
-
9
- | | 组件(`src/zy/`) | 动效(`src/effects/<key>/`) |
10
- |--|--|--|
11
- | 是什么 | 有 props / 事件 / 插槽的 Vue 组件 | 一段可直接复制的 HTML + CSS(+ 可选原生 JS) |
12
- | 怎么用 | `npm i @zy/zy-ui` 后 `import` | 动效页复制三栏 |
13
- | 运行时依赖 | vue、element-plus | 零依赖 |
14
- | 发布 | 进 lib 构建 | 不进任何构建产物 |
15
-
16
- 判断标准一句话:**要 API 就是「组件」,要粘贴就是「动效」。**
17
-
18
- ## 文档站
19
-
20
- ```bash
21
- npm install
22
- npm run dev # 顶栏「组件 / 动效」
23
- ```
24
-
25
- - `/components/:id` — 组件页:左树右文 + API 属性表
26
- - `/animations/:id` — 动效页:左舞台(底色两档可切)+ 右仿 VS Code 只读代码面板(HTML / CSS / JS 分栏),复制即用
27
-
28
- ## 组件:装到业务项目里
29
-
30
- 组件是 Element Plus 的二次封装(内部直接用 `El*`),所以 `element-plus` 与 `vue` 都是 peerDependency:
31
-
32
- ```bash
33
- npm i @zy/zy-ui element-plus
34
- ```
35
-
36
- ```ts
37
- // main.ts:Element 的样式 + 本包的组件样式 + 主题材质
38
- import 'element-plus/dist/index.css'
39
- import '@zy/zy-ui/style.css'
40
- import '@zy/zy-ui/theme/solid.css' // 浅色默认;需要图纸语言时改用 theme/basic.css
41
- ```
42
-
43
- 主题与明暗是两根独立的轴。在 `<html>` 上设置:
44
-
45
- ```html
46
- <html data-zy-theme="solid" data-zy-color-scheme="light">
47
- ```
48
-
49
- - `data-zy-theme`:`basic`(基础用法 / 图纸)或 `solid`(实色键帽)。
50
- - `data-zy-color-scheme`:`light` 或 `dark`。
51
- - 浅色默认 `solid`;深色当前统一使用 `basic` 形态,不叠加键帽材质。
52
- - 两个主题 CSS 可以同时引入,由根属性决定生效范围。
53
-
54
- 主题 CSS 的路径:
55
-
56
- ```ts
57
- import '@zy/zy-ui/theme/basic.css'
58
- import '@zy/zy-ui/theme/solid.css'
59
- ```
60
-
61
- **全局引入**(和 Element 一样 `app.use`):
62
-
63
- ```ts
64
- import ZyUi from '@zy/zy-ui'
65
-
66
- app.use(ZyUi) // 之后模板里可直接写 <ZyButton /> <ZyInput /> …
67
- ```
68
-
69
- **按需引入**(只有被引用的组件进包;组件内部自己 import 对应的 Element 组件,不需要先全局注册 Element):
70
-
71
- ```vue
72
- <script setup lang="ts">
73
- import { ZyButton, ZyInput } from '@zy/zy-ui'
74
- </script>
75
-
76
- <template>
77
- <ZyButton type="primary">提交</ZyButton>
78
- <ZyInput v-model="keyword" placeholder="Type something..." />
79
- </template>
80
- ```
81
-
82
- 用法与 Element 保持一致:`type` / `size` / `round` / `disabled` / `loading`、`v-model`、事件都照 Element 的写法;
83
- 每个组件另外带一组 `effect` 用来选微动效(`ZyButton` 的 `press` / `outline`,`ZyInput` 的 `underline` / `gradient` …)。
84
- 没有显式声明的 Element props 与事件会沿 Vue 的 attribute 透传,落到内部的 `El*` 上。
85
- 具名插槽同样原样转发(`<ZyButton><template #icon>…</template></ZyButton>` 会落到 `ElButton` 的 `#icon`),
86
- 默认插槽由各组件自己安排位置。
87
-
88
- 换肤:本包自带一份 `:root` 设计令牌(`--zy-brand`、`--zy-radius-pill`、`--zy-ease-out` …),
89
- 在自己的样式里覆盖同名变量即可;深色模式同理。Token 分为原始值、语义值、Element 映射和深色覆盖四层,
90
- 业务侧应优先覆盖语义令牌,不要依赖组件内部 `.el-*` 子结构。
91
-
92
- `src/zy/index.ts` 导出的 28 个组件:`ZyBadge`、`ZyButton`、`ZyCodeInput`、`ZyDatePicker`、`ZyInput`、
93
- `ZySelect`、`ZyCheckbox`、`ZyCheckboxGroup`、`ZySwitch`、`ZyRadio`、`ZyRadioGroup`、
94
- `ZyRadioButton`、`ZyCard`、`ZyTag`、`ZyProgress`、`ZyAlert`、`ZyDialog`、`ZyDivider`、
95
- `ZySpace`、`ZyIcon`、`ZyTable`、`ZyTree`、`ZyLoading`、`ZyMegaMenu`、`ZyPagination`、`ZyPanel`、`ZySlideVerify`、`ZyTimePicker`。
96
-
97
- ## 动效:复制片段
98
-
99
- 每个动效一个目录,三件套 + 一份配置:
100
-
101
- ```
102
- src/effects/switch-burst/
103
- snippet.html 纯标记(无 Vue 语法)
104
- snippet.css 自包含样式(每个 var() 都带字面量兜底)
105
- snippet.scoped.css 站内渲染用:选择器都带 .zy-stage-<key> 前缀(由 css 派生,别手改)
106
- snippet.js 可选;确实需要脚本时才有(当前 57 个都是零 JS),站点预览会执行它
107
- meta.ts 舞台与文档配置:scale / checker / doc
108
- ```
109
-
110
- 复制出去为什么能直接用:`var(--fx-x, 兜底)` 保留兜底值、片段自带 `box-sizing` 兜底、
111
- `<span />` 这类只对 Vue 模板块成立的写法已经补成标准 HTML。
112
-
113
- ## 收录新内容
114
-
115
- **新动效**
116
-
117
- 1. 在 `src/mocks/types.ts` 的 `EFFECT_KEYS` 追加 key
118
- 2. 建 `src/effects/<key>/{snippet.html,snippet.css,meta.ts}`(目录名必须与 key 一致)
119
- 3. `npm run sync:scoped` 生成站内用的 scoped 样式
120
- 4. 在 `src/mocks/families.ts` 的 `effectFamilies` 追加一条
121
-
122
- **新组件**
123
-
124
- 1. 实现放 `src/zy/<Name>/`(含 `index.ts`),并在 `src/zy/index.ts` 追加导出
125
- 2. 组件文档条目在 `src/mocks/element-components.ts`
126
- 3. 首页那句组件计数跟着改 `src/mocks/components.ts` 的 `COMPONENT_TOTAL`
127
-
128
- ## 脚本
129
-
130
- | 命令 | 作用 |
131
- |--|--|
132
- | `npm run dev` | 文档站(前置跑两项校验) |
133
- | `npm run build` | 构建站点 → `dist/site/` |
134
- | `npm run build:lib` | 构建可发布库 → `dist/zy-ui/`(只含 28 个组件) |
135
- | `npm run check:registry` | 动效 key ↔ 目录 ↔ `meta.ts` 三方一致、片段文件齐备、组件数对得上、无老写法引用 |
136
- | `npm run check:snippets` | 片段硬规则体检 + scoped 样式同步检查 |
137
- | `npm run check:package` | 校验包导出目标与 `npm pack` 文件清单 |
138
- | `npm run check:consumer` | 用 `npm pack` 产物在空项目安装、类型检查并构建 |
139
- | `npm run lint` | 检查组件、主题状态、脚本与单测代码 |
140
- | `npm run test` | 运行 Vitest 单元测试 |
141
- | `npm run check:theme-runtime` | 校验 basic / solid / 深色回退的运行时表现(需先启动站点) |
142
- | `npm run check:visual` | 核心组件的默认 / hover / active / focus / disabled 视觉回归(需先启动站点) |
143
- | `npm run check:visual:update` | 审核通过后更新视觉基线 |
144
- | `npm run changeset` | 记录一次待发布变更 |
145
- | `npm run release` | 构建并发布到已配置的 registry |
146
- | `npm run sync:scoped` | 由 `snippet.css` 生成 `snippet.scoped.css` |
147
-
148
- `dev` / `build` / `build:lib` 都已前置跑 `check:registry` 与 `check:snippets`。
149
- 站点与 lib 的产物分开放(`dist/site` 与 `dist/zy-ui`),互不覆盖。
150
-
151
- ## 技术栈
152
-
153
- Vite + Vue 3 + TypeScript · Vue Router · Pinia · Element Plus
154
-
155
- ## 团队协作
156
-
157
- - [贡献规范](CONTRIBUTING.md)
158
- - [浏览器支持](docs/browser-support.md)
159
- - [从 Element Plus 迁移](docs/migration-from-element.md)
160
- - [改造规范与进度](docs/ui-library-refactor-spec.md)
161
- - [发布检查清单](docs/release-checklist.md)
162
- - [组件 Owner 约定](docs/component-ownership.md)
1
+ # Zy UI 组件库 · MotionVault
2
+
3
+ 基于 **Vue 3 + TypeScript + Vite** 的 Element Plus 二次封装组件库,配套一套**可直接复制粘贴**的动效片段与文档站。组件带 props / 事件 / 插槽并随包发布;动效片段只在文档站复制使用,不进包。
4
+
5
+ | 属性 | 说明 |
6
+ | --- | --- |
7
+ | 包名 | `@gyyxds/zy-ui` |
8
+ | 技术栈 | Vue 3、TypeScript、Element Plus |
9
+ | 构建工具 | Vite 8(库模式)+ vue-tsc |
10
+ | 模块格式 | 仅 ESM(`"type": "module"`),无 CJS 产物 |
11
+ | 组件数 | 28 |
12
+ | 动效片段 | 57(零依赖、零 JS) |
13
+
14
+ ## 先说清楚:两套产物,别混
15
+
16
+ > **动效页(`/animations/:id`)里的 HTML / CSS 是「即时复制粘贴」用的片段,不属于发布的组件库。**
17
+ > 它们没有 npm 导出路径、不进 `dist/zy-ui`、也不能 `import`;正确用法是在文档站复制三栏代码,粘到自己页面里跑。
18
+
19
+ | | 组件库(`src/zy/`) | 动效片段(`src/effects/<key>/`) |
20
+ | --- | --- | --- |
21
+ | 是什么 | 有 props / 事件 / 插槽的 Vue 组件 | 可直接复制的 HTML + CSS(可选原生 JS) |
22
+ | 怎么用 | `npm i @gyyxds/zy-ui` 后 `import` | 文档站动效页复制三栏代码,粘贴即用 |
23
+ | 运行时依赖 | vue、element-plus(均为 peerDependency) | 零依赖 |
24
+ | 是否发布 | 进 lib 构建(`dist/zy-ui/`) | 不进任何构建产物 |
25
+
26
+ 判断标准一句话:**要 API 就是「组件」,要粘贴就是「动效」。**
27
+
28
+ ## 功能特性
29
+
30
+ - 28 个组件,全部是 Element Plus 的二次封装或同构重绘,`type` / `size` / `v-model` / 事件写法与 Element 保持一致
31
+ - 多个组件带一组 `effect` 微动效:按钮 `press` / `sweep` / `fill`,输入框 `underline` / `gradient` / `brutalist`,选择器 `underline` / `gradient` …
32
+ - 两套材质主题 × 深浅两档,四组配色互不回退:图纸(`basic`)与实色键帽(`solid`)
33
+ - 设计令牌随包发布(`--zy-*`),覆盖语义令牌即可换肤,无需改组件代码
34
+ - TypeScript 类型声明随包发布;ESLint 0 警告门槛、Vitest 单测、消费方冒烟检查
35
+ - 57 个零依赖动效片段,复制即用(见上文说明,不属于包内容)
36
+
37
+ ## 组件列表(28 个)
38
+
39
+ ### 基础(3)
40
+
41
+ | 组件 | 说明 |
42
+ | --- | --- |
43
+ | `ZyButton` | `type` / `plain` / `round` / `dashed` / `circle` 对齐 Element。`effect`:`press`(按压缩放,默认)/ `sweep`(左侧图标块 + 色块扫入)/ `fill`(实色键帽 + 悬停扩散,仅键帽主题,图纸主题下自动按 `press` 渲染) |
44
+ | `ZyIcon` | 内置 SVG 图标,`name` 取 `src/assets/icons/` 的文件名(如 `btn-search`);`size` / `label` / `spin` |
45
+ | `ZyLoading` | 纯 div + CSS,不基于 Element。`type`:`dots` 点环 / `line` 心电描线 / `text` 故障字 / `bar` 跳球柱形;`color` / `speed` / `width` / `height` / `label` |
46
+
47
+ ### 表单(12)
48
+
49
+ | 组件 | 说明 |
50
+ | --- | --- |
51
+ | `ZyInput` | `effect`:`focus`(默认)/ `underline` / `gradient` / `brutalist`;另有 `label` 浮动标签与 `raised` 键帽凸起形态 |
52
+ | `ZyCodeInput` | 验证码输入。`length` / `status`(idle / error / success)/ `size` / `mask` / `caret` / `disabled`,`v-model` + `complete` 事件 |
53
+ | `ZySelect` | `effect`:`focus` / `underline` / `gradient`;其余 API 照 Element |
54
+ | `ZyCheckbox` / `ZyCheckboxGroup` | `effect`:`''` / `checkmark` / `tick`;Group 用 `v-model` 收集选中值 |
55
+ | `ZySwitch` | 自研全息开关(不基于 Element):扫描线 / 粒子 / 三环自转;`v-model` + `activeText` / `inactiveText` / `label` / `disabled` |
56
+ | `ZyRadio` / `ZyRadioGroup` / `ZyRadioButton` | 选中态辉光圆点 + 过冲弹跳;`effect`:`''` / `underline` |
57
+ | `ZySlideVerify` | 滑块拼图验证(内置插画底图)。`gap` / `tolerance` / `image` / `darkImage` / `showRefresh` 与各档文案;事件:成功 / 失败 / 刷新 |
58
+ | `ZyDatePicker` / `ZyTimePicker` | 触发框与弹层形态重绘,API 照 Element |
59
+
60
+ ### 数据(7)
61
+
62
+ | 组件 | 说明 |
63
+ | --- | --- |
64
+ | `ZyCard` | `shadow`(always / hover / never)、`hoverFill`(悬停铺色,可传颜色) |
65
+ | `ZyTag` | `effect`:`dark` / `light`(默认)/ `plain` / `fill`(实色键帽,仅键帽主题;图纸下退回浅底,可关闭时关闭图标跟字色) |
66
+ | `ZyBadge` | 等宽数字不跳宽;`effect`:`''` / `ping`(扩散圈) |
67
+ | `ZyProgress` | 轨道 + 蓝绿渐变填充 |
68
+ | `ZyTable` | 台账式表格,`lines`(all / row)控制网格线;数据与列走插槽 / Element 透传 |
69
+ | `ZyTree` | 引导线 + 折角接线 + 写实节点图标;`folderIcon` / `folderOpenIcon` / `fileIcon` |
70
+ | `ZyPagination` | 纸面按钮 / 中性键帽页码 + 跳页输入框 |
71
+
72
+ ### 反馈(2)
73
+
74
+ | 组件 | 说明 |
75
+ | --- | --- |
76
+ | `ZyAlert` | 左侧 3px 语义强调条 / 语义键块,标题留语义色 |
77
+ | `ZyDialog` | `v-model` 开合;`title` / `width` / `icon` / `appendToBody` / `closeOnClickModal`(默认 false)/ `destroyOnClose` |
78
+
79
+ ### 布局(4)
80
+
81
+ | 组件 | 说明 |
82
+ | --- | --- |
83
+ | `ZyDivider` | `contentPosition`:left / center / right |
84
+ | `ZySpace` | 纯布局件,`direction` 等间距控制 |
85
+ | `ZyPanel` | 通用容器:有 `title` 分标题栏 + 正文,无 `title` 通体白面 |
86
+ | `ZyMegaMenu` | 数据驱动导航:`items`(有 `panel` = 下拉,无 `panel` + `href` = 普通链接)、`brand`;受控开合 `v-model:open`;`#panel-<key>` 接管面板内容 |
87
+
88
+ ## 动效片段(57 个,复制即用,不发布)
89
+
90
+ - 分类(`src/mocks/families.ts`):基础 / 按钮 / 表单 / 数据 / 反馈 / 导航 / 布局 / 动效。
91
+ - 每个片段一个目录,三件套 + 一份配置:
92
+
93
+ ```
94
+ src/effects/switch-burst/
95
+ snippet.html 纯标记,无 Vue 语法
96
+ snippet.css 自包含样式,每个 var() 都带字面量兜底
97
+ snippet.scoped.css 站内渲染用(由 snippet.css 派生,别手改)
98
+ snippet.js 可选;确实需要脚本时才有(当前 57 个全部零 JS)
99
+ meta.ts 舞台与文档配置:scale / doc(棋盘底等可选字段)
100
+ ```
101
+
102
+ - 复制出去能直接用:`var(--fx-x, 兜底)` 保留兜底值、片段自带 `box-sizing` 兜底、`<span />` 这类只对 Vue 模板块成立的写法已补成标准 HTML。
103
+ - 片段与主题解耦(令牌走 `--fx-*`),所以在文档站切换主题不会改变动效页的观感。
104
+
105
+ ## 安装使用
106
+
107
+ ```bash
108
+ npm i @gyyxds/zy-ui element-plus
109
+ ```
110
+
111
+ `vue` 与 `element-plus` 是 peerDependency,需由业务项目自己安装;组件内部直接使用 `El*`,**不需要**先全局注册 Element Plus。
112
+
113
+ ```ts
114
+ // main.ts —— 顺序:Element 样式 → 本包组件样式 → 主题材质
115
+ import { createApp } from 'vue'
116
+ import ElementPlus from 'element-plus'
117
+ import 'element-plus/dist/index.css'
118
+ import '@gyyxds/zy-ui/style.css'
119
+ import '@gyyxds/zy-ui/theme/solid.css' // 浅色默认;要图纸语言改用 theme/basic.css
120
+
121
+ import App from './App.vue'
122
+
123
+ createApp(App).use(ElementPlus).mount('#app')
124
+ ```
125
+
126
+ 导出路径(对应 `package.json` 的 `exports`):
127
+
128
+ | 路径 | 内容 |
129
+ | --- | --- |
130
+ | `@gyyxds/zy-ui` | 组件库入口(全局 install + 全部具名导出) |
131
+ | `@gyyxds/zy-ui/style.css` | 组件样式 + 设计令牌(`dist/zy-ui/zy-ui.css`) |
132
+ | `@gyyxds/zy-ui/theme/basic.css` | 主题 A「基础用法 / 图纸」材质层 |
133
+ | `@gyyxds/zy-ui/theme/solid.css` | 主题 B「实色键帽」材质层 |
134
+
135
+ 三种引入方式:
136
+
137
+ ```ts
138
+ // ① 全局注册
139
+ import ZyUi from '@gyyxds/zy-ui'
140
+ app.use(ZyUi) // 之后模板里直接写 <ZyButton /> <ZyInput /> …
141
+
142
+ // ② 按需引入(推荐,tree-shaking 生效,只打进用到的组件)
143
+ import { ZyButton, ZyInput } from '@gyyxds/zy-ui'
144
+
145
+ // ③ 单组件注册(组件自带 install,对齐 Element 的做法)
146
+ import { ZyButton } from '@gyyxds/zy-ui'
147
+ app.use(ZyButton)
148
+ ```
149
+
150
+ ```vue
151
+ <script setup lang="ts">
152
+ import { ref } from 'vue'
153
+ import { ZyButton, ZyInput } from '@gyyxds/zy-ui'
154
+
155
+ const keyword = ref('')
156
+ </script>
157
+
158
+ <template>
159
+ <ZyInput v-model="keyword" placeholder="搜索组件…" clearable />
160
+ <ZyButton type="primary" effect="press">提交</ZyButton>
161
+ </template>
162
+ ```
163
+
164
+ 使用约定:
165
+
166
+ - 未显式声明的 Element props / 事件按 Vue 的 attribute 透传,落到内部 `El*` 上。
167
+ - 具名插槽原样转发给内部 Element 组件(如 `<ZyButton><template #icon>…</template></ZyButton>`),默认插槽由各组件自己安排位置。
168
+ - 自定义组件(`ZySwitch` / `ZyCodeInput` / `ZyDialog` / `ZyCheckboxGroup` / `ZyRadioGroup`)用 `defineModel`,`v-model` 直接可用;`ZySlideVerify` 走事件。
169
+ - 图标属性传字符串时按本库内置图标名解析(`ZyIcon` / `ZyTree` 等);`ZyButton` 的 `icon` 目前只在 `sweep` 下解析字符串,`press` / `fill` 请按 Element 规则传组件或走 `#icon` 插槽。
170
+ - 不要依赖组件内部 `.el-*` 子结构与内部类名:只有 props / 事件 / 插槽 / `--zy-*` 令牌是稳定契约。
171
+
172
+ ## 主题
173
+
174
+ 主题与明暗是两根独立的轴,都设在 `<html>` 上:
175
+
176
+ ```html
177
+ <html data-zy-theme="solid" data-zy-color-scheme="light"></html>
178
+ ```
179
+
180
+ | 轴 | 属性 | 取值 | 默认 |
181
+ | --- | --- | --- | --- |
182
+ | 材质主题 | `data-zy-theme` | `basic`(图纸)/ `solid`(实色键帽) | `solid` |
183
+ | 明暗 | `data-zy-color-scheme` + `html.dark` class | `light` / `dark` | `light` |
184
+
185
+ - 两套材质各有深浅两档,切换深浅不会把当前材质换成另一套。
186
+ - 业务侧开深色:给 `<html>` 加 `dark` class 即可(`data-zy-color-scheme` 是语义标记)。
187
+ - 两个主题 CSS 可以同时引入,由根属性决定谁生效。
188
+
189
+ 两套材质说的是什么:
190
+
191
+ - **`basic` 基础用法(图纸)**:信息优先。纸白面 + 1px 发丝描边 + 极轻双层影,6px 方角;层级靠描边与留白,不靠厚度。
192
+ - **`solid` 实色键帽(实物)**:能按的件是凸的(实色面 + 深一档挤出边 + 两侧白弧 + 落地影),装东西的件是凹的(内阴影);按下必然下沉。只改材质,不改形状与尺寸。
193
+
194
+ 换肤:覆盖语义令牌即可,不要动组件内部结构。
195
+
196
+ ```css
197
+ :root {
198
+ --zy-brand: #0066a9;
199
+ --zy-radius: 6px;
200
+ --zy-ease-out: cubic-bezier(0.23, 1, 0.32, 1);
201
+ }
202
+ html.dark {
203
+ --zy-brand: #3d8fd4;
204
+ }
205
+ ```
206
+
207
+ 常用令牌:`--zy-brand` / `--zy-green` / `--zy-danger` / `--zy-warning` / `--zy-info`、`--zy-ink` / `--zy-muted`、`--zy-paper`(页面底)/ `--zy-surface`(面)/ `--zy-hairline`(发丝线)、`--zy-radius`(6px)/ `--zy-radius-sm`(4px)/ `--zy-radius-pill`(999px)、`--zy-shadow-card` / `--zy-shadow-float` / `--zy-focus-ring`、`--zy-duration-fast` / `--zy-duration-press`、`--zy-ease-out` / `--zy-ease-soft`、`--zy-font-sans`。键帽主题额外有 `--zy-key-*` / `--zy-slot-*` / `--zy-desk`(只在该主题下定义)。
208
+
209
+ ## 本地调试
210
+
211
+ ### 1. 安装依赖
212
+
213
+ ```bash
214
+ npm install
215
+ # 或 yarn install --ignore-engines(@changesets/cli 要求 yarn ≥ 4.5,本机 yarn 1.x 需跳过引擎检查)
216
+ ```
217
+
218
+ Node.js 需 ≥ 20.19(Vite 8 要求)。
219
+
220
+ ### 2. 启动开发服务
221
+
222
+ ```bash
223
+ npm run dev
224
+ ```
225
+
226
+ 该命令会先跑 `check:registry` 与 `check:snippets` 两项校验,再启动 Vite(默认端口 **5173**,`host: true` 便于局域网访问)。
227
+
228
+ ### 3. 访问文档站
229
+
230
+ 浏览器打开 [http://localhost:5173](http://localhost:5173)。
231
+
232
+ | 路由 | 内容 |
233
+ | --- | --- |
234
+ | `/components/:id` | 组件页:左树右文 + 舞台 + API 属性表 |
235
+ | `/animations/:id` | 动效页:左舞台(底色两档可切)+ 右只读代码面板(HTML / CSS / JS 分栏),复制即用 |
236
+
237
+ 顶栏可切材质(图纸 / 键帽)与深浅;`?theme=dark&zyTheme=basic` 之类的查询参数可固定主题,方便截图与分享。
238
+
239
+ ### 4. 常用命令
240
+
241
+ | 命令 | 作用 |
242
+ | --- | --- |
243
+ | `npm run dev` | 文档站(前置跑 registry + snippets 校验) |
244
+ | `npm run build` | 构建站点 → `dist/site/` |
245
+ | `npm run build:lib` | 构建可发布库 → `dist/zy-ui/`(只含 28 个组件) |
246
+ | `npm run lint` | ESLint 检查(0 警告门槛) |
247
+ | `npm run test` | Vitest 单元测试 |
248
+ | `npm run check:registry` | 动效 key ↔ 目录 ↔ `meta.ts` 三方一致、片段文件齐备、组件数核对 |
249
+ | `npm run check:snippets` | 片段硬规则体检 + scoped 样式同步检查 |
250
+ | `npm run check:package` | 校验包导出目标与 `npm pack` 文件清单 |
251
+ | `npm run check:consumer` | 用 `npm pack` 产物在空项目安装、类型检查并构建 |
252
+ | `npm run check:theme-runtime` | 主题运行时校验(需先启动站点) |
253
+ | `npm run check:visual` / `:update` | 视觉回归 / 审核通过后更新基线(需先启动站点) |
254
+ | `npm run sync:scoped` | 由 `snippet.css` 生成 `snippet.scoped.css` |
255
+ | `npm run check:release-env` | 发布前置体检:registry / 登录 / 版本 / 待发 changeset |
256
+ | `npm run changeset` | 记录一次待发布变更 |
257
+ | `npm run release` | 体检 → 构建 → `changeset publish` |
258
+
259
+ `dev` / `build` / `build:lib` 都已前置跑 `check:registry` 与 `check:snippets`;站点与库产物分开放(`dist/site` 与 `dist/zy-ui`),互不覆盖。
260
+
261
+ ### 5. 业务项目直接引用本仓库(`file:` 依赖)
262
+
263
+ 业务项目里写 `"@gyyxds/zy-ui": "file:../motion-vault-components"` 时,**不会**跑本仓库的 `prepare` / `prepublishOnly`,装的就是仓库里现成的 `dist/zy-ui`。所以改了组件后要手动重建一次:
264
+
265
+ ```bash
266
+ # 本仓库:改了 src/zy 之后都要跑一遍(约 30 秒,跑完 lint / 测试再打更稳)
267
+ npm run build:lib
268
+
269
+ # 业务项目:file: 依赖是软链,重建后产物已经生效,下面这步一般不需要;
270
+ # 只有 package.json 的 exports / 版本号变了才重装,换包名或首次接入时也要装一次
271
+ npm install
272
+ ```
273
+
274
+ 验证是不是跑上了最新的:
275
+
276
+ ```bash
277
+ # 1. 产物时间应该是刚才 build:lib 的时间(dist 被 .gitignore 忽略,但 file: 依赖照样读得到)
278
+ dir node_modules\@gyyxds\zy-ui\dist\zy-ui\zy-ui.js
279
+
280
+ # 2. 版本号与仓库 package.json 一致(现在是 0.0.1)
281
+ npm ls @gyyxds/zy-ui
282
+
283
+ # 3. 打开页面确认:控制台无报错,改动的样式 / 行为已生效
284
+ ```
285
+
286
+ 几条注意:
287
+
288
+ - `file:` 依赖是软链,`node_modules/@gyyxds/zy-ui` 指向本仓库根目录;本仓库 `rm -rf dist` 后业务项目会立刻报「找不到入口」,重建就好。
289
+ - 业务项目的 dev server 会缓存 `node_modules/.vite`:重建后没变化就删掉它、重启 dev(`rm -rf node_modules/.vite`)。
290
+ - 单页调试用 `npm run dev`(文档站)最快;`file:` 链路是给「在自己的业务页面里验证」用的。
291
+ - 样式三件套别漏:Element 样式 → `@gyyxds/zy-ui/style.css` → 一份主题 CSS(`theme/basic.css` 或 `theme/solid.css`)。
292
+
293
+
294
+ ### 6. 收录新内容
295
+
296
+ **新组件**
297
+
298
+ 1. 实现放 `src/zy/<Name>/`(含 `index.ts`),并在 `src/zy/index.ts` 追加导出
299
+ 2. 组件文档条目写进 `src/mocks/element-components.ts`
300
+ 3. 首页计数同步 `src/mocks/components.ts` 的 `COMPONENT_TOTAL`
301
+
302
+ **新动效**
303
+
304
+ 1. 在 `src/mocks/types.ts` 的 `EFFECT_KEYS` 追加 key
305
+ 2. 建 `src/effects/<key>/{snippet.html,snippet.css,meta.ts}`(目录名必须与 key 一致)
306
+ 3. `npm run sync:scoped` 生成站内用的 scoped 样式
307
+ 4. 在 `src/mocks/families.ts` 的 `effectFamilies` 追加一条
308
+
309
+ ## 发布到 npm
310
+
311
+ 包名 `@gyyxds/zy-ui`,发布地址固定 `https://registry.npmjs.org/`(`publishConfig` 已配 `access: public` + `registry`)。发布账号 **gyy-xds**(@gyyxds 组织),已开启 2FA。
312
+
313
+ ```bash
314
+ # 1. 打包(前置自动跑 registry / snippets 校验 → vue-tsc → vite lib 构建 → check:package)
315
+ npm run build:lib
316
+
317
+ # 2. 登录 npm(须为 gyy-xds 或 @gyyxds 组织成员;浏览器完成认证)
318
+ npm login --registry=https://registry.npmjs.org/
319
+
320
+ # 3. 确认当前登录账号
321
+ npm whoami --registry=https://registry.npmjs.org/
322
+
323
+ # 4. 发布(scoped 包须加 --access public;按提示完成 2FA 验证)
324
+ npm publish --access public --registry=https://registry.npmjs.org/
325
+ ```
326
+
327
+ 要点:
328
+
329
+ - `prepublishOnly` 会在 publish 前自动重跑一遍 `build:lib`;产物已确认最新时可用 `--ignore-scripts` 跳过重复构建。
330
+ - 账号开启 2FA 后,publish 会要求浏览器授权或验证器一次性验证码(EOTP)。
331
+ - 发布后用 `npm view @gyyxds/zy-ui version` 确认上架;新包首次发布后 registry 生效可能有短暂延迟,404 不代表失败。
332
+ - 正式变更走 Changesets:`npm run changeset` → `changeset version` → `npm run release`(`release` 会先跑 `check:release-env` 体检)。
333
+ - 要让业务项目验证发布产物,可先跑 `npm run check:consumer`(`npm pack` → 空项目安装 → 类型检查 → 构建)。
334
+
335
+ ## 目录结构
336
+
337
+ ```
338
+ src/zy/ # 组件库源码(只有这部分会进发布产物)
339
+ ├── button/ # 每个组件一个目录:index.ts 导出 + Zy*.vue 实现
340
+ ├── input/ select/ …
341
+ ├── styles/
342
+ │ ├── tokens/ # primitives → semantic → element → dark 四层令牌
343
+ │ └── themes/ # basic.css(图纸)/ solid.css(键帽)/ material.css
344
+ └── index.ts # 库入口:导出 + install
345
+
346
+ src/effects/<key>/ # 动效片段(复制即用,不发布)
347
+ src/views/ # 文档站页面(组件页 / 动效页 / 主题页 / 首页)
348
+ src/components/ # 文档站自身组件(布局、舞台、代码面板)
349
+ src/mocks/ # 文档数据:组件元信息、动效注册表、演示代码
350
+ src/stores/ # Pinia:主题、收藏
351
+ scripts/ # 校验与构建脚本(registry / snippets / package / consumer …)
352
+ tests/ # Vitest 单测 + 视觉回归基线
353
+ docs/ # 设计规范、迁移与发布文档
354
+
355
+ dist/site/ # 站点产物(npm run build)
356
+ dist/zy-ui/ # 库产物(npm run build:lib,进包)
357
+ ```
358
+
359
+ ## 浏览器支持
360
+
361
+ 现代浏览器。样式用到 `color-mix()`、`:has()`、嵌套与 CSS 自定义属性,旧 WebView / IE 需先评估降级方案,详见 [浏览器支持](docs/browser-support.md)。
362
+
363
+ ## 团队协作
364
+
365
+ - [贡献规范](CONTRIBUTING.md)
366
+ - [主题规范](docs/theme/README.md)
367
+ - [从 Element Plus 迁移](docs/migration-from-element.md)
368
+ - [改造规范与进度](docs/ui-library-refactor-spec.md)
369
+ - [发布检查清单](docs/release-checklist.md)
370
+ - [组件 Owner 约定](docs/component-ownership.md)
371
+ - [变更日志](CHANGELOG.md)
@@ -14,14 +14,14 @@ type __VLS_Props = {
14
14
  /** 微动效:'' 基础(等宽数字,9 → 10 宽度不跳)/ ping 角标后补一圈同色扩散圈,放大淡出 */
15
15
  effect?: '' | 'ping';
16
16
  };
17
- declare var __VLS_7: {};
17
+ declare var __VLS_8: {};
18
18
  type __VLS_Slots = {} & {
19
- default?: (props: typeof __VLS_7) => any;
19
+ default?: (props: typeof __VLS_8) => any;
20
20
  };
21
21
  declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
22
- type: "success" | "warning" | "info" | "primary" | "danger";
22
+ type: "primary" | "success" | "warning" | "info" | "danger";
23
23
  effect: "" | "ping";
24
- value: string | number;
24
+ value: number | string;
25
25
  max: number;
26
26
  isDot: boolean;
27
27
  hidden: boolean;
@@ -8,9 +8,9 @@ export declare const ZyBadge: import("../utils/withInstall").SFCWithInstall<{
8
8
  showZero?: boolean;
9
9
  effect?: "" | "ping";
10
10
  }> & Readonly<{}>, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, import("vue").PublicProps, {
11
- type: "success" | "warning" | "info" | "primary" | "danger";
11
+ type: "primary" | "success" | "warning" | "info" | "danger";
12
12
  effect: "" | "ping";
13
- value: string | number;
13
+ value: number | string;
14
14
  max: number;
15
15
  isDot: boolean;
16
16
  hidden: boolean;
@@ -31,9 +31,9 @@ export declare const ZyBadge: import("../utils/withInstall").SFCWithInstall<{
31
31
  showZero?: boolean;
32
32
  effect?: "" | "ping";
33
33
  }> & Readonly<{}>, {}, {}, {}, {}, {
34
- type: "success" | "warning" | "info" | "primary" | "danger";
34
+ type: "primary" | "success" | "warning" | "info" | "danger";
35
35
  effect: "" | "ping";
36
- value: string | number;
36
+ value: number | string;
37
37
  max: number;
38
38
  isDot: boolean;
39
39
  hidden: boolean;
@@ -51,9 +51,9 @@ export declare const ZyBadge: import("../utils/withInstall").SFCWithInstall<{
51
51
  showZero?: boolean;
52
52
  effect?: "" | "ping";
53
53
  }> & Readonly<{}>, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, {
54
- type: "success" | "warning" | "info" | "primary" | "danger";
54
+ type: "primary" | "success" | "warning" | "info" | "danger";
55
55
  effect: "" | "ping";
56
- value: string | number;
56
+ value: number | string;
57
57
  max: number;
58
58
  isDot: boolean;
59
59
  hidden: boolean;
@@ -27,9 +27,9 @@ type __VLS_Slots = {} & {
27
27
  default?: (props: typeof __VLS_29) => any;
28
28
  };
29
29
  declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
30
- size: "default" | "small" | "large";
31
- type: "" | "success" | "warning" | "info" | "primary" | "danger";
32
- effect: "fill" | "press" | "sweep";
30
+ size: "large" | "default" | "small";
31
+ type: "primary" | "success" | "warning" | "danger" | "info" | "";
32
+ effect: "press" | "sweep" | "fill";
33
33
  icon: string | Component;
34
34
  round: boolean;
35
35
  disabled: boolean;