x-next 1.5.0 → 1.7.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.
Files changed (171) hide show
  1. package/AI_USAGE.md +57 -4
  2. package/CHANGELOG.md +72 -0
  3. package/dist/_utils/color.d.ts +53 -0
  4. package/dist/components/color-picker/ColorPicker.d.ts +239 -0
  5. package/dist/components/color-picker/gradient-slider.d.ts +52 -0
  6. package/dist/components/color-picker/index.d.ts +238 -0
  7. package/dist/components/color-picker/panel.d.ts +721 -0
  8. package/dist/components/color-picker/sv-panel.d.ts +48 -0
  9. package/dist/components/date-picker/DatePicker.vue.d.ts +3 -3
  10. package/dist/components/date-picker/index.d.ts +6 -6
  11. package/dist/components/draggable/Draggable.d.ts +1 -1
  12. package/dist/components/draggable/index.d.ts +2 -2
  13. package/dist/components/drawer/index.d.ts +6 -6
  14. package/dist/components/drawer/src/Drawer.vue.d.ts +3 -3
  15. package/dist/components/dropdown/Dropdown.vue.d.ts +34 -4
  16. package/dist/components/dropdown/DropdownButton.vue.d.ts +35 -5
  17. package/dist/components/dropdown/DropdownSubmenu.vue.d.ts +34 -4
  18. package/dist/components/dropdown/dropdown-panel.vue.d.ts +30 -0
  19. package/dist/components/dropdown/index.d.ts +209 -29
  20. package/dist/components/form/FormItem.vue.d.ts +12 -12
  21. package/dist/components/form/form-item-label.vue.d.ts +3 -3
  22. package/dist/components/form/index.d.ts +24 -24
  23. package/dist/components/form-select/Select.d.ts +3 -3
  24. package/dist/components/form-select/SelectDropdown.vue.d.ts +30 -0
  25. package/dist/components/form-select/index.d.ts +66 -6
  26. package/dist/components/form-slider/Slider.vue.d.ts +3 -3
  27. package/dist/components/form-slider/index.d.ts +6 -6
  28. package/dist/components/form-slider/slider-button.vue.d.ts +3 -3
  29. package/dist/components/grid/Row.vue.d.ts +3 -3
  30. package/dist/components/grid/index.d.ts +9 -9
  31. package/dist/components/heatmap/Heatmap.d.ts +311 -0
  32. package/dist/components/heatmap/helpers/matrix.d.ts +58 -0
  33. package/dist/components/heatmap/index.d.ts +372 -0
  34. package/dist/components/heatmap/interface.d.ts +57 -0
  35. package/dist/components/image/Image.vue.d.ts +125 -17
  36. package/dist/components/image/ImagePreview.vue.d.ts +97 -7
  37. package/dist/components/image/ImagePreviewAction.d.ts +3 -3
  38. package/dist/components/image/ImagePreviewGroup.vue.d.ts +100 -7
  39. package/dist/components/image/hooks/use-image-drag.d.ts +2 -2
  40. package/dist/components/image/index.d.ts +712 -124
  41. package/dist/components/image/interface.d.ts +9 -1
  42. package/dist/components/image/preview-toolbar.vue.d.ts +3 -3
  43. package/dist/components/index.d.ts +3 -0
  44. package/dist/components/menu/sub-menu-pop.vue.d.ts +3 -3
  45. package/dist/components/network/Network.vue.d.ts +1 -1
  46. package/dist/components/network/index.d.ts +3 -3
  47. package/dist/components/network/utils.d.ts +2 -0
  48. package/dist/components/pagination/page-item-ellipsis.vue.d.ts +9 -0
  49. package/dist/components/pagination/page-jumper.vue.d.ts +6 -0
  50. package/dist/components/pagination/page-options.vue.d.ts +6 -6
  51. package/dist/components/popconfirm/src/popup.vue.d.ts +3 -3
  52. package/dist/components/popover/Popover.d.ts +1 -1
  53. package/dist/components/popover/index.d.ts +3 -3
  54. package/dist/components/popup/Popup.d.ts +1 -1
  55. package/dist/components/popup/index.d.ts +3 -3
  56. package/dist/components/skeleton/SkeletonShape.vue.d.ts +3 -3
  57. package/dist/components/skeleton/index.d.ts +6 -6
  58. package/dist/components/space/Space.d.ts +1 -1
  59. package/dist/components/space/index.d.ts +3 -3
  60. package/dist/components/spin/Spin.d.ts +38 -0
  61. package/dist/components/spin/index.d.ts +30 -0
  62. package/dist/components/table/Table.d.ts +1 -1
  63. package/dist/components/table/index.d.ts +3 -3
  64. package/dist/components/tabs/Tabs.d.ts +1 -1
  65. package/dist/components/tabs/index.d.ts +3 -3
  66. package/dist/components/time-picker/TimePicker.vue.d.ts +3 -3
  67. package/dist/components/time-picker/index.d.ts +6 -6
  68. package/dist/components/tooltip/Tooltip.vue.d.ts +1 -1
  69. package/dist/components/tooltip/index.d.ts +3 -3
  70. package/dist/components/trigger/Trigger.d.ts +1 -1
  71. package/dist/components/trigger/index.d.ts +3 -3
  72. package/dist/components/upload/Upload.d.ts +372 -0
  73. package/dist/components/upload/context.d.ts +28 -0
  74. package/dist/components/upload/index.d.ts +656 -0
  75. package/dist/components/upload/interface.d.ts +110 -0
  76. package/dist/components/upload/props.d.ts +321 -0
  77. package/dist/components/upload/upload-list-item.d.ts +15 -0
  78. package/dist/components/upload/upload-list.d.ts +11 -0
  79. package/dist/components/upload/upload-picture-item.d.ts +20 -0
  80. package/dist/components/upload/upload-trigger.d.ts +8 -0
  81. package/dist/components/upload/utils.d.ts +48 -0
  82. package/dist/components/watermark/Watermark.d.ts +1 -1
  83. package/dist/components/watermark/index.d.ts +3 -3
  84. package/dist/es/_styles/palette-aliases.js +10 -4
  85. package/dist/es/_utils/color.js +73 -0
  86. package/dist/es/components/button/Button.js +2 -2
  87. package/dist/es/components/color-picker/ColorPicker.js +239 -0
  88. package/dist/es/components/color-picker/gradient-slider.js +79 -0
  89. package/dist/es/components/color-picker/index.js +8 -0
  90. package/dist/es/components/color-picker/panel.js +307 -0
  91. package/dist/es/components/color-picker/sv-panel.js +99 -0
  92. package/dist/es/components/dropdown/dropdown-panel.vue.js +17 -17
  93. package/dist/es/components/form-input/Input.js +7 -7
  94. package/dist/es/components/form-input/InputPassword.vue2.js +2 -2
  95. package/dist/es/components/form-input/InputSearch.js +2 -2
  96. package/dist/es/components/form-input-number/InputNumber.js +12 -12
  97. package/dist/es/components/heatmap/Heatmap.js +334 -0
  98. package/dist/es/components/heatmap/helpers/matrix.js +106 -0
  99. package/dist/es/components/heatmap/index.js +8 -0
  100. package/dist/es/components/image/Image.vue.js +55 -45
  101. package/dist/es/components/image/Image.vue2.js +113 -92
  102. package/dist/es/components/image/ImagePreview.vue.js +66 -53
  103. package/dist/es/components/image/ImagePreview.vue2.js +219 -171
  104. package/dist/es/components/image/ImagePreviewAction.js +12 -15
  105. package/dist/es/components/image/ImagePreviewGroup.vue.js +21 -20
  106. package/dist/es/components/image/ImagePreviewGroup.vue2.js +45 -39
  107. package/dist/es/components/image/hooks/use-image-drag.js +16 -14
  108. package/dist/es/components/index.js +123 -117
  109. package/dist/es/components/menu/sub-menu-pop.vue2.js +12 -12
  110. package/dist/es/components/network/Network.vue2.js +72 -72
  111. package/dist/es/components/network/utils.js +44 -35
  112. package/dist/es/components/pagination/Pagination.js +113 -104
  113. package/dist/es/components/pagination/page-item-ellipsis.vue.js +13 -12
  114. package/dist/es/components/pagination/page-item-ellipsis.vue2.js +19 -15
  115. package/dist/es/components/pagination/page-jumper.vue.js +13 -12
  116. package/dist/es/components/pagination/page-jumper.vue2.js +7 -4
  117. package/dist/es/components/pagination/page-options.vue.js +4 -3
  118. package/dist/es/components/pagination/page-options.vue2.js +17 -15
  119. package/dist/es/components/skeleton/Skeleton.vue.js +11 -9
  120. package/dist/es/components/skeleton/SkeletonLine.vue.js +9 -8
  121. package/dist/es/components/skeleton/SkeletonShape.vue.js +8 -7
  122. package/dist/es/components/spin/Spin.js +124 -60
  123. package/dist/es/components/table/Table.js +3 -1
  124. package/dist/es/components/trigger/Trigger.js +19 -19
  125. package/dist/es/components/upload/Upload.js +420 -0
  126. package/dist/es/components/upload/context.js +4 -0
  127. package/dist/es/components/upload/index.js +8 -0
  128. package/dist/es/components/upload/props.js +321 -0
  129. package/dist/es/components/upload/upload-list-item.js +138 -0
  130. package/dist/es/components/upload/upload-list.js +48 -0
  131. package/dist/es/components/upload/upload-picture-item.js +109 -0
  132. package/dist/es/components/upload/upload-trigger.js +89 -0
  133. package/dist/es/components/upload/utils.js +195 -0
  134. package/dist/es/icons/_self/empty-better.js +25 -8
  135. package/dist/es/icons/_self/upload-icons.js +103 -0
  136. package/dist/es/index.js +168 -162
  137. package/dist/es/locale/en-US.js +39 -1
  138. package/dist/es/locale/zh-CN.js +39 -1
  139. package/dist/es/style.css +1 -1
  140. package/dist/icons/_self/upload-icons.d.ts +523 -0
  141. package/dist/index.cjs +4 -4
  142. package/dist/index.umd.js +4 -4
  143. package/dist/locale/interface.d.ts +60 -0
  144. package/dist/style/base.css +1 -1
  145. package/dist/style/button.css +1 -1
  146. package/dist/style/color-picker.css +1 -0
  147. package/dist/style/color-picker.js +2 -0
  148. package/dist/style/date-picker.css +1 -1
  149. package/dist/style/empty.css +1 -1
  150. package/dist/style/form-checkbox.css +1 -1
  151. package/dist/style/form-input-tag.css +1 -1
  152. package/dist/style/form-input.css +1 -1
  153. package/dist/style/form-radio.css +1 -1
  154. package/dist/style/form-textarea.css +1 -1
  155. package/dist/style/form.css +1 -1
  156. package/dist/style/heatmap.css +1 -0
  157. package/dist/style/heatmap.js +2 -0
  158. package/dist/style/image.css +1 -1
  159. package/dist/style/menu.css +1 -1
  160. package/dist/style/pagination.css +1 -1
  161. package/dist/style/skeleton.css +1 -1
  162. package/dist/style/spin.css +1 -1
  163. package/dist/style/steps.css +1 -1
  164. package/dist/style/table.css +1 -1
  165. package/dist/style/upload.css +1 -0
  166. package/dist/style/upload.js +2 -0
  167. package/dist/style.css +1 -1
  168. package/dist/types.d.ts +3 -0
  169. package/package.json +1 -1
  170. package/volar.d.ts +3 -0
  171. package/dist/es/_hooks/use-popup-overflow-hidden.js +0 -29
package/AI_USAGE.md CHANGED
@@ -1,11 +1,11 @@
1
1
  <!-- Generated by pnpm generate:ai-usage. Edit src/docs/guide/ai-usage-recipes.md and script/ai-usage/manifest.js. -->
2
2
  # x-next AI 使用手册
3
3
 
4
- 适用版本:**x-next@1.5.0**。Vue:`^3.5.0`;Node:`>=20.19.0`。
4
+ 适用版本:**x-next@1.7.0**。Vue:`^3.5.0`;Node:`>=20.19.0`。
5
5
 
6
- 来源指纹(精选示例、映射、版本与公开类型声明):`8ed10e46d0e5b1359b27d93837370dcf2fca95d511be5e798e112ff5977d856f`。
6
+ 来源指纹(精选示例、映射、版本与公开类型声明):`9a84aab8ad9388abbcade590e1a24c7d5049c9ef14d04313edfc96860c34ed86`。
7
7
 
8
- 先按业务需要选择组件,不要求全部迁移。本手册限定在用户确认的 22 个组件及必要的同族子组件,未覆盖的导出不表示已完成业务验收。
8
+ 先按业务需要选择组件,不要求全部迁移。本手册限定在用户确认的 23 个组件及必要的同族子组件,未覆盖的导出不表示已完成业务验收。
9
9
 
10
10
  读取入口:`node_modules/x-next/AI_USAGE.md`;可用 `require.resolve('x-next/AI_USAGE.md')` 定位。这个文件名不会自动让所有 AI 工具加载,消费项目应在自己的指令中明确引用。
11
11
 
@@ -35,7 +35,8 @@
35
35
  | Steps | `Steps` | `<x-steps>` | `v-model:current` | [组件文档](https://x-next.ztes.com/components/steps) |
36
36
  | Tabs | `Tabs` | `<x-tabs>` | `v-model:active-key` | [组件文档](https://x-next.ztes.com/components/tabs) |
37
37
  | Empty | `Empty` | `<x-empty>` | 无 | [组件文档](https://x-next.ztes.com/components/empty) |
38
- 这是一份给业务开发者和 AI Coding 使用的中文代码手册。以下 22 个入口是本手册选定的常用组件与服务;公开导出还有其他能力,不能据此推断所有导出都具有相同成熟度,也不要求每个项目全部使用。
38
+ | Upload | `Upload` | `<x-upload>` | `v-model:file-list` | [组件文档](https://x-next.ztes.com/components/upload) |
39
+ 这是一份给业务开发者和 AI Coding 使用的中文代码手册。以下 23 个入口是本手册选定的常用组件与服务;公开导出还有其他能力,不能据此推断所有导出都具有相同成熟度,也不要求每个项目全部使用。
39
40
 
40
41
  每节提供一个可复制到 `App.vue` 的独立 Vue SFC,显式从 `x-next` 根入口导入,并包含全量 CSS。实际项目可将重复的 CSS 导入统一移到应用入口。本文是代码配方,不新增 live demo;每节链接的既有组件文档提供可交互示例和完整 API。
41
42
 
@@ -645,3 +646,55 @@ function refresh() { refreshed.value = true; }
645
646
  </Empty>
646
647
  </template>
647
648
  ```
649
+
650
+ ## Upload
651
+
652
+ [组件文档与 live demo](https://x-next.ztes.com/components/upload)。`action` 是上传地址,也可用 `customRequest` 接管请求;两者都没提供时组件不会发起上传。`name` 是 FormData 字段名,默认 `'file'`;`method` 默认 `'post'`,`withCredentials` 默认 `false`。
653
+
654
+ **接入已有上传方法的推荐写法**:`customRequest` 返回 Promise 时组件自动接管状态,resolve 即成功(结果写入 `file.response`,可用 `responseUrlKey` 提取 url,字符串支持 `data.url` 嵌套路径)、reject 即失败并出现重试入口,无需手动调用 `onSuccess` / `onError`。axios、flyio、fetch 或任何返回 Promise 的方法都适用。返回值是 fetch `Response` 时组件读取响应体;非 2xx 按失败处理,`error.status` 为状态码。需要进度与取消时,把 option 的 `signal`(取消 / 移除 / 卸载时触发)与 `onProgress`(0 ~ 1)透传给底层请求。返回 `{ abort }` 并手动回调的旧写法仍然支持。
655
+
656
+ 列表默认非受控,用 `defaultFileList` 给初值;需要外部驱动时用 `v-model:file-list`,列表项以 `uid` 为稳定标识。`listType` 取 `'text' | 'picture' | 'picture-card'`。`limit` 为数量上限,超出会触发 `exceed`,超出部分不进入列表;`beforeUpload` 返回 `false` 拦截、返回新 `File` 替换,支持 Promise。
657
+
658
+ `change({ file, fileList })` 覆盖加入、进度、成功、失败和移除;`success` / `error` / `remove` / `progress` 是更细粒度的补充。`autoUpload=false` 时文件先以 `init` 入列,再用组件 `submit()` 上传、`abort()` 取消、`retry()` 重试。图片卡场景可加 `image-preview` 用内置 `ImagePreview` 看图。
659
+
660
+ ```vue
661
+ <script setup lang="ts">
662
+ import { ref } from 'vue';
663
+ import { Upload, type UploadFile } from 'x-next';
664
+ import 'x-next/dist/style.css';
665
+ const fileList = ref<UploadFile[]>([]);
666
+ const status = ref('尚未选择文件');
667
+ // 项目里已封装好的上传方法:返回 Promise 即可,组件自动显示成功与失败
668
+ function uploadAttachment(params: { file: File; orderId: string }) {
669
+ const form = new FormData();
670
+ form.append('file', params.file);
671
+ form.append('orderId', params.orderId);
672
+ return fetch('/api/upload', { method: 'POST', body: form }).then((response) => {
673
+ if (!response.ok) throw new Error(`上传失败:${response.status}`);
674
+ return response.json() as Promise<{ data: { url: string } }>;
675
+ });
676
+ }
677
+ function changed(info: { file: UploadFile; fileList: UploadFile[] }) {
678
+ status.value = `${info.file.name}:${info.file.status ?? 'unknown'}`;
679
+ }
680
+ function beforeUpload(file: File) {
681
+ // 超过 2MB 直接拦截,文件不会进入列表
682
+ return file.size <= 2 * 1024 * 1024;
683
+ }
684
+ </script>
685
+ <template>
686
+ <Upload
687
+ v-model:file-list="fileList"
688
+ :custom-request="({ file }) => uploadAttachment({ file, orderId: 'SO-20261003' })"
689
+ response-url-key="data.url"
690
+ name="file"
691
+ multiple
692
+ list-type="picture"
693
+ accept="image/*"
694
+ :limit="5"
695
+ :before-upload="beforeUpload"
696
+ @change="changed"
697
+ />
698
+ <p role="status">{{ status }}</p>
699
+ </template>
700
+ ```
package/CHANGELOG.md CHANGED
@@ -2,6 +2,78 @@
2
2
 
3
3
  本项目遵循 [语义化版本](https://semver.org/lang/zh-CN/)。
4
4
 
5
+ ## [1.7.0] - 2026-10-04
6
+
7
+ ### 新增
8
+
9
+ - **Upload 上传组件**:支持点击选择、拖拽(含文件夹递归读取并保留相对路径)、粘贴上传;文本 / 图片 / 图片卡三种列表形态;`limit` 数量限制与 `exceed`、`beforeUpload` 拦截或替换文件、`beforeRemove` 移除前钩子;`autoUpload=false` 手动上传配合 `submit()` / `abort()` / `retry()`;逐项取消回到待上传态(不同于 Arco 归属 error 的处理);`updateFile(uid, file)` 原地替换文件;`tip` 提示、操作按钮开关、内置 `ImagePreview` 图片预览;`aria-live` 上传状态播报与操作按钮无障碍名称。
10
+ - **接入已有上传方法(`customRequest` 返回 Promise)**:业务只需 `:custom-request="({ file }) => uploadApi({ file, orderId })"`,组件自动接管状态——resolve 即成功、reject 即失败并出现重试入口,结果写入 `file.response`;axios、flyio、fetch 或任何返回 Promise 的方法均可直接接入,无需手动调用 `onSuccess` / `onError`。返回 `{ abort }` 加手动回调的写法继续兼容。
11
+ - **`UploadRequestOption.signal`**:每次尝试独立的 `AbortSignal`,取消上传、移除文件或组件卸载时触发,可直接透传给 fetch / axios 真正中止网络请求。
12
+ - **fetch `Response` 自动归一化**:`customRequest` 直接返回 `fetch(...)` 时,JSON / text 响应体解析后写入 `file.response`,非 2xx 按失败处理并在 `error.status` 提供状态码;axios / flyio 已解析的响应对象原样透传。
13
+ - **`responseUrlKey` 嵌套路径**:字符串支持 `data.url` 形式的路径提取;函数形态增加第二个参数 `response`。
14
+ - 新增 Upload 中英文语言包(`trigger` / `drag` / `fileUploaded` 等 18 项);ImagePreview 语言包补 `openLabel` / `loadError` / `loading`。
15
+ - 新增 `_self/upload-icons` 图标(上传云、文件、图片、刷新、下载、删除)。
16
+
17
+ ### 修复
18
+
19
+ - **Image 加载失败态**:默认错误占位由大红底改为中性色底 + 次级文字,错误占位补齐圆角,不再刺眼。
20
+ - **ImagePreview 工具条**:亮色白底改为深色半透明 + 模糊背景,hover 反馈统一为透明底浅色图标,窄屏工具条可折行不再溢出。
21
+ - **Image 换图与 SSR**:`src` 由 `watchEffect` 直写 DOM 改为声明式绑定带 key 的 `img`,SSR 正确输出地址;源变更重置加载状态,旧图片节点的 load / error 事件不再覆盖新图;`description` 按文档回退给 `alt`。
22
+ - **Image / Preview 键盘可达性**:缩略图可聚焦并用 Enter 打开预览;预览弹层补齐 Tab 圈定与关闭后焦点恢复;快捷键只在顶层预览生效。
23
+ - **ImagePreview 加载失败**:失败时提供可访问的错误占位而非只撤下 spinner;`actionsLayout=[]` 时自定义 actions 独立渲染,不再被一并隐藏。
24
+ - **ImagePreview 动态配置与边界**:`keyboard` / `popupContainer` 动态变更时迁移监听并清理计时器;`defaultScale` / `zoomRate` 非法值与满屏零尺寸兜底,不再产生无效 transform。
25
+ - **ImagePreviewAction**:`attrs` 不再覆盖内部 class、`disabled` 与 aria 属性,自定义样式与禁用语义同时生效。
26
+ - **Image 拖拽 hook**:`use-image-drag` 在节点更换时解绑旧监听,移除 / 换图不再残留移动状态。
27
+ - **ImagePreviewGroup 无障碍**:弹层读屏标签传入真实序号与总数,不再恒为「第 1 张,共 1 张」。
28
+ - **多层预览滚动锁**:预览使用 `useOverflow` 引用计数与容器迁移,关闭上层预览不再提前解锁页面滚动。
29
+ - **Image 外置 footer 高度**:根节点高度由内容撑开,多行说明不再溢出或与下方内容重叠。
30
+ - **ImagePreview SSR**:仅客户端清理 wheel 的 RAF,`docs:build` 不再输出 `cancelAnimationFrame` 报错。
31
+ - **Image 原生事件声明**:`load` / `error` 显式声明并转发,消费者 `strictTemplates` 编译通过。
32
+
33
+ ### 文档与测试
34
+
35
+ - 新增 `upload.md`(15 个 live demo,覆盖接入已有方法、响应提取、进度与取消、多选限制、拖拽、图片卡、手动上传、校验重试、插槽、禁用粘贴、文件夹、替换文件、Form 联动)与 `volar` 注册;组件索引、侧栏同步。
36
+ - `image.md` 重写扩充:12 个场景全部含 live demo 与完整 SFC,补换图、错误恢复、仅自定义工具条、局部容器、键盘组切换等。
37
+ - Upload 单测 81 项(含 Promise resolve / reject、取消后晚到结果不覆盖、signal 中止、fetch Response 归一化、手动回调优先等 13 项新增回归);Image 新增 21 项行为断言;全量测试 2136 项。
38
+ - AI 使用手册新增 Upload(23 个公共组件),`ai-usage-recipes.md` 示例改为「接入已有上传方法」并重新生成 `AI_USAGE.md`。
39
+ - `check:bundle-size` 的 Input 预算由 38,000 调整为 39,500:Input 消费者结构性携带整个共享语言包(zh-CN + en-US 合计 11,635 bytes,约占 30%),按组件拆分的方案继续在 `项目审查/2026-10-03-main-共享语言包与Input体积门禁.md` 跟踪。
40
+
41
+ ## [1.6.0] - 2026-10-02
42
+
43
+ ### 新增
44
+
45
+ - **Heatmap 热力图**:以「周 × 星期」网格展示按天聚合的数值分布,支持自然年与自定义跨度、五档色阶、尺寸与首日配置、月/周标签与图例开关、格子点击事件与自定义提示。整块网格只挂一个 `mousemove` 做事件委托 + 单个浮层节点,避免 371 个格子各挂一个 Trigger 带来的开销。
46
+ - **ColorPicker 颜色选择器**:SV 取色面板 + 色相条 + 透明度条 + hex/rgb/hsl 三格式输入 + 预设色板 + 确认/清除。受控与非受控、禁用与尺寸、表单校验联动、自定义触发器均支持;Esc 关闭并把焦点归还触发器。
47
+ - 新增 `_utils/color.ts` 颜色工具(含 alpha 的 hex/rgb/hsl 解析、HSV 双向换算、格式化与混色),附 44 项单测。
48
+ - **Spin `tipShimmer`**:提示文字扫光效果。新增 `--x-spin-tip-shimmer-color-highlight` / `--x-spin-tip-shimmer-duration` 两个 token;用 `background-clip: text` 实现,并包在 `@supports` 中兜底(不支持裁切时文字保持原色,不会变成空白)。
49
+ - **Spin `delay`**:延迟显示加载态,避免快速请求闪一下遮罩。语义与 AntDV 有一处刻意差异——只延迟出现、结束时立即收起,不会让已加载完的内容再被多盖一段时间。
50
+ - 修复 `Empty` 的插画色阶后新增 `--x-empty-illustration-*` 四个 token,使默认插画能随亮/暗主题换色。
51
+
52
+ ### 修复
53
+
54
+ - **全库行高依赖宿主(系统性缺陷)**:组件文案未显式声明行高时会继承宿主(如 `body`)的行高,导致同一组件在不同项目中高度与文字位置不一致。实测宿主行高设为 3 时按钮内容盒涨到 42px、设为 1 时只有 14px。已为 Steps 描述、Pagination 跳转区、Image footer、Input/Select 前后缀、Input 字数统计、Radio/Checkbox、InputTag 输入框、Form 说明文字等补齐行高声明。
55
+ - **Input 字数统计类名漂移**:`.x-input-word-limit`(单横线)与运行时类名 `x-input--word-limit`(双横线)不匹配,整条规则从未生效——该元素字号一直是宿主默认值而非规定的 12px。
56
+ - **InputTag 输入框字号**:原生 `<input>` 不继承父级字体,此前一直渲染在 UA 默认的 `13.3333px`:既与标签字号(12/14px)不一致,也让内部测宽元素 `.x-input-tag--mirror` 的测量失准。现已显式 `font-size: inherit`。
57
+ - **Radio / Checkbox 的 `line-height: unset`**:该写法会主动丢弃行高、完全继承宿主,比不声明更糟;改为显式声明。
58
+ - **Table / Dropdown 空态来源标识**:两者渲染裸 `<Empty />`,导致 `ConfigProvider` 的 `#empty` 插槽回调 `component` 恒为 `'empty'`,文档承诺的「按来源区分空态」在这两个组件里失效。
59
+ - **Spin 容器模式的无障碍语义**:`loading=false` 时仍保留 `aria-label="加载中"`,屏幕阅读器会把已加载完成的区域播报为加载中。
60
+ - **Spin 默认图标旋转叠加**:默认图标同时叠加了 Icon 的 `spin` 层与图标自带的旋转动画,两层周期与缓动都不同,合成转速在 1~2 圈/秒之间波动,观感又快又乱。现只保留图标自带旋转;自定义 `icon` 插槽仍注入 `spin`。
61
+ - **Spin 点状动画与文案扫光的动效降级**:新增 `prefers-reduced-motion` 适配,扫光在降级时还原成纯色(而非停在某处留下一块亮斑)。
62
+ - **Network 字段缺失被误判为「较差」**:`navigator.connection` 存在但字段不全时(部分浏览器只给 `effectiveType`),旧逻辑把缺失值兜底成 `downlink=0 / rtt=Infinity` 再走阈值判断,结果一律判成 `poor`,比完全不支持该 API 还悲观,且与文档描述相反。现在字段不足回落为「检测中」,`4g` 直接判良好。
63
+ - **Network 其它缺陷**:`connection.onchange` 降级会顶掉使用方已注册的处理器(现改为转发并在卸载时归还);轮询无变化仍反复派发 `change`(现按语义字段去重,但仍保留首次状态派发);`refresh()` 可能返回 `undefined`(现始终返回 `Promise<NetworkStatus>`)。
64
+ - **Pagination `total` 非有限值导致死循环**:`total` 传 `Infinity`(「总数未知」)时会渲染出文案为 `Infinity` 的页码;若 `current` 同时非有限,页列表里的 `for (let i = Infinity; i <= Infinity; i++)` 条件恒为真(`Infinity++ === Infinity`),主线程死循环、页面卡死。现对 `total` / `current` 做归一化。
65
+ - **Pagination 无障碍与边界**:根节点补 `role="navigation"` 与可访问名称;跳转输入框补无障碍名称;省略号在禁用态下不再可聚焦、不再响应键盘;`pageSize` 不在 `pageSizeOptions` 中时不再显示空 placeholder;`pageSizeProps` 不再能覆盖 `disabled` / `modelValue`。
66
+ - **Skeleton 无障碍**:根节点补 `aria-busy`,装饰性的 `SkeletonLine` / `SkeletonShape` 补 `aria-hidden`(此前空 `<li>` 会被读屏念成一串无内容的列表项)。
67
+ - **Skeleton 动画时长**硬编码 `1.5s` 提到 token;`SkeletonShape.size` 类型收窄。
68
+ - **Empty 默认插画**:四个灰阶是硬编码浅色字面量,暗色主题下整块发白;现改为 `--x-empty-illustration-*` token,图形本身不变,亮色取值与原字面量逐位一致。
69
+ - **forced-colors 适配**:补齐分页当前页描边与骨架屏轮廓,避免背景被强制成 Canvas 后这些状态不可见。
70
+ - **Steps 描述行高**、**TimePicker / DatePicker 面板宽度自适应**等文档与样式细节。
71
+
72
+ ### 测试
73
+
74
+ - 新增 Heatmap / ColorPicker / 颜色工具共 100+ 项单测。
75
+ - 新增 Empty 插画单色契约、Table/Dropdown 空态来源、Spin `delay` 与 `tipShimmer`、Spin `inert` 键盘兜底(显式移除 `inert` 原型属性以覆盖真实降级路径)、Network 字段缺失与 `onchange` 转发、Pagination 非有限 `total` 等回归测试,测试总数 2034。
76
+
5
77
  ## [1.5.0] - 2026-10-02
6
78
 
7
79
  ### 修复
@@ -0,0 +1,53 @@
1
+ import { hslToRgb, rgbToHsl } from './palette';
2
+ export { hslToRgb, rgbToHsl };
3
+ /**
4
+ * 带透明度的颜色工具。
5
+ *
6
+ * 与 `palette.ts` 的分工:那里的 `parseColor` 服务于主题色阶生成,语义是
7
+ * 「丢弃 alpha、只取不透明 RGB」(该行为被色阶测试锁定)。颜色选择器需要
8
+ * 保留 alpha、需要 HSV(取色面板的饱和度/明度轴)以及多格式输出,
9
+ * 因此单独放在这里,不修改 palette.ts 的既有语义。
10
+ */
11
+ /** 通道 0-255,alpha 0-1 */
12
+ export interface RGBA {
13
+ r: number;
14
+ g: number;
15
+ b: number;
16
+ a: number;
17
+ }
18
+ /** h 0-360,s/v 0-100 */
19
+ export interface HSV {
20
+ h: number;
21
+ s: number;
22
+ v: number;
23
+ }
24
+ export type ColorFormat = 'hex' | 'rgb' | 'hsl';
25
+ /**
26
+ * 解析颜色字符串为 RGBA。
27
+ *
28
+ * 支持 `#rgb` / `#rgba` / `#rrggbb` / `#rrggbbaa`、`rgb()` / `rgba()`、
29
+ * `hsl()` / `hsla()`(通道可用百分比),逗号与空格两种语法均可。
30
+ * 无法解析时返回 null。
31
+ */
32
+ export declare const parseColorAlpha: (input: string) => RGBA | null;
33
+ /** 解析失败时回退到给定颜色,便于受控输入容错 */
34
+ export declare const parseColorAlphaOr: (input: string, fallback: RGBA) => RGBA;
35
+ export declare const rgbToHsv: ({ r, g, b }: Pick<RGBA, "r" | "g" | "b">) => HSV;
36
+ export declare const hsvToRgb: ({ h, s, v }: HSV) => [number, number, number];
37
+ export declare const rgbaToHex: ({ r, g, b, a }: RGBA, showAlpha?: boolean) => string;
38
+ /** alpha 输入框展示用:整数百分比 */
39
+ export declare const formatAlphaPercent: (a: number) => number;
40
+ /**
41
+ * 按目标格式输出颜色字符串。
42
+ * `showAlpha` 为 false 时忽略 alpha;为 true 但 alpha 为 1 时省略 alpha 通道。
43
+ */
44
+ export declare const formatColor: (rgba: RGBA, format: ColorFormat, showAlpha?: boolean) => string;
45
+ /**
46
+ * 输出 `rgba(r, g, b, a)`,用于渐变端点等需要精确 alpha 的场景。
47
+ * alpha 滑块的两端分别是「完全透明」与「当前色」,都靠它构造。
48
+ */
49
+ export declare const toRgbaString: ({ r, g, b, a }: RGBA) => string;
50
+ /** alpha 滑轨的渐变终点色:始终输出不透明的 `rgba()` */
51
+ export declare const toAlphaSliderColor: ({ r, g, b }: RGBA) => string;
52
+ /** 十六进制输入框的即时校验(供输入过程的分支判断,允许带 alpha) */
53
+ export declare const isHexColor: (input: string) => boolean;
@@ -0,0 +1,239 @@
1
+ import { PropType, SlotsType } from 'vue';
2
+ import { ColorFormat } from '../../_utils/color';
3
+ declare const _default: import('vue').DefineComponent<import('vue').ExtractPropTypes<{
4
+ /**
5
+ * @zh 颜色值,支持 hex / rgb / hsl(含 alpha)
6
+ * @en Color value, supports hex / rgb / hsl with alpha
7
+ * @vModel
8
+ */
9
+ modelValue: {
10
+ type: StringConstructor;
11
+ default: undefined;
12
+ };
13
+ /**
14
+ * @zh 非受控初值
15
+ * @en Default value for uncontrolled mode
16
+ */
17
+ defaultValue: {
18
+ type: StringConstructor;
19
+ default: undefined;
20
+ };
21
+ /**
22
+ * @zh 面板是否可见
23
+ * @en Whether the panel is visible
24
+ * @vModel
25
+ */
26
+ show: {
27
+ type: BooleanConstructor;
28
+ default: undefined;
29
+ };
30
+ /**
31
+ * @zh 面板默认是否可见
32
+ * @en Whether the panel is visible by default
33
+ */
34
+ defaultShow: {
35
+ type: BooleanConstructor;
36
+ default: boolean;
37
+ };
38
+ /**
39
+ * @zh 可选的颜色格式
40
+ * @en Available color formats
41
+ * @defaultValue ['hex', 'rgb', 'hsl']
42
+ */
43
+ modes: {
44
+ type: PropType<ColorFormat[]>;
45
+ default: () => ColorFormat[];
46
+ };
47
+ /**
48
+ * @zh 是否启用透明度
49
+ * @en Whether alpha is enabled
50
+ * @defaultValue true
51
+ */
52
+ showAlpha: {
53
+ type: BooleanConstructor;
54
+ default: boolean;
55
+ };
56
+ /**
57
+ * @zh 预设色块
58
+ * @en Preset swatches
59
+ */
60
+ swatches: {
61
+ type: PropType<string[]>;
62
+ default: () => never[];
63
+ };
64
+ /**
65
+ * @zh 是否展示确认按钮
66
+ * @en Whether to show the confirm button
67
+ * @defaultValue true
68
+ */
69
+ showConfirm: {
70
+ type: BooleanConstructor;
71
+ default: boolean;
72
+ };
73
+ /**
74
+ * @zh 是否展示清除按钮
75
+ * @en Whether to show the clear button
76
+ * @defaultValue true
77
+ */
78
+ showClear: {
79
+ type: BooleanConstructor;
80
+ default: boolean;
81
+ };
82
+ /**
83
+ * @zh 是否禁用
84
+ * @en Whether the picker is disabled
85
+ */
86
+ disabled: {
87
+ type: BooleanConstructor;
88
+ default: boolean;
89
+ };
90
+ /**
91
+ * @zh 尺寸
92
+ * @en Size
93
+ * @values 'mini', 'small', 'medium', 'large'
94
+ */
95
+ size: {
96
+ type: PropType<"mini" | "small" | "medium" | "large">;
97
+ };
98
+ /**
99
+ * @zh 面板挂载容器
100
+ * @en Mount container for the panel
101
+ */
102
+ popupContainer: {
103
+ type: PropType<string | HTMLElement>;
104
+ };
105
+ }>, () => VNode, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {
106
+ 'update:modelValue': (_value: string, _ev?: Event) => true;
107
+ change: (_value: string, _ev?: Event) => true;
108
+ 'update:show': (_visible: boolean) => true;
109
+ showChange: (_visible: boolean) => true;
110
+ confirm: (_value: string) => true;
111
+ clear: () => true;
112
+ }, string, import('vue').PublicProps, Readonly<import('vue').ExtractPropTypes<{
113
+ /**
114
+ * @zh 颜色值,支持 hex / rgb / hsl(含 alpha)
115
+ * @en Color value, supports hex / rgb / hsl with alpha
116
+ * @vModel
117
+ */
118
+ modelValue: {
119
+ type: StringConstructor;
120
+ default: undefined;
121
+ };
122
+ /**
123
+ * @zh 非受控初值
124
+ * @en Default value for uncontrolled mode
125
+ */
126
+ defaultValue: {
127
+ type: StringConstructor;
128
+ default: undefined;
129
+ };
130
+ /**
131
+ * @zh 面板是否可见
132
+ * @en Whether the panel is visible
133
+ * @vModel
134
+ */
135
+ show: {
136
+ type: BooleanConstructor;
137
+ default: undefined;
138
+ };
139
+ /**
140
+ * @zh 面板默认是否可见
141
+ * @en Whether the panel is visible by default
142
+ */
143
+ defaultShow: {
144
+ type: BooleanConstructor;
145
+ default: boolean;
146
+ };
147
+ /**
148
+ * @zh 可选的颜色格式
149
+ * @en Available color formats
150
+ * @defaultValue ['hex', 'rgb', 'hsl']
151
+ */
152
+ modes: {
153
+ type: PropType<ColorFormat[]>;
154
+ default: () => ColorFormat[];
155
+ };
156
+ /**
157
+ * @zh 是否启用透明度
158
+ * @en Whether alpha is enabled
159
+ * @defaultValue true
160
+ */
161
+ showAlpha: {
162
+ type: BooleanConstructor;
163
+ default: boolean;
164
+ };
165
+ /**
166
+ * @zh 预设色块
167
+ * @en Preset swatches
168
+ */
169
+ swatches: {
170
+ type: PropType<string[]>;
171
+ default: () => never[];
172
+ };
173
+ /**
174
+ * @zh 是否展示确认按钮
175
+ * @en Whether to show the confirm button
176
+ * @defaultValue true
177
+ */
178
+ showConfirm: {
179
+ type: BooleanConstructor;
180
+ default: boolean;
181
+ };
182
+ /**
183
+ * @zh 是否展示清除按钮
184
+ * @en Whether to show the clear button
185
+ * @defaultValue true
186
+ */
187
+ showClear: {
188
+ type: BooleanConstructor;
189
+ default: boolean;
190
+ };
191
+ /**
192
+ * @zh 是否禁用
193
+ * @en Whether the picker is disabled
194
+ */
195
+ disabled: {
196
+ type: BooleanConstructor;
197
+ default: boolean;
198
+ };
199
+ /**
200
+ * @zh 尺寸
201
+ * @en Size
202
+ * @values 'mini', 'small', 'medium', 'large'
203
+ */
204
+ size: {
205
+ type: PropType<"mini" | "small" | "medium" | "large">;
206
+ };
207
+ /**
208
+ * @zh 面板挂载容器
209
+ * @en Mount container for the panel
210
+ */
211
+ popupContainer: {
212
+ type: PropType<string | HTMLElement>;
213
+ };
214
+ }>> & Readonly<{
215
+ onClear?: (() => any) | undefined;
216
+ onChange?: ((_value: string, _ev?: Event | undefined) => any) | undefined;
217
+ onConfirm?: ((_value: string) => any) | undefined;
218
+ "onUpdate:modelValue"?: ((_value: string, _ev?: Event | undefined) => any) | undefined;
219
+ "onUpdate:show"?: ((_visible: boolean) => any) | undefined;
220
+ onShowChange?: ((_visible: boolean) => any) | undefined;
221
+ }>, {
222
+ disabled: boolean;
223
+ defaultValue: string;
224
+ show: boolean;
225
+ modelValue: string;
226
+ modes: ColorFormat[];
227
+ showAlpha: boolean;
228
+ swatches: string[];
229
+ showConfirm: boolean;
230
+ showClear: boolean;
231
+ defaultShow: boolean;
232
+ }, SlotsType<{
233
+ default?: () => unknown;
234
+ trigger?: (props: {
235
+ value: string;
236
+ visible: boolean;
237
+ }) => unknown;
238
+ }>, {}, {}, string, import('vue').ComponentProvideOptions, true, {}, any>;
239
+ export default _default;
@@ -0,0 +1,52 @@
1
+ /**
2
+ * 通用渐变滑轨,色相条与透明度条共用。
3
+ *
4
+ * 差异只在背景:色相条是固定的色相环渐变,透明度条是「透明 → 当前色」。
5
+ * 通过 `background` prop 注入,组件本身不关心颜色语义。
6
+ */
7
+ declare const _default: import('vue').DefineComponent<import('vue').ExtractPropTypes<{
8
+ /** 0-100 的位置百分比 */
9
+ value: {
10
+ type: NumberConstructor;
11
+ required: true;
12
+ };
13
+ /** 滑轨背景(CSS background 值) */
14
+ background: {
15
+ type: StringConstructor;
16
+ required: true;
17
+ };
18
+ disabled: {
19
+ type: BooleanConstructor;
20
+ default: boolean;
21
+ };
22
+ /** 无障碍名称,由父组件传入已本地化的文案 */
23
+ ariaLabel: {
24
+ type: StringConstructor;
25
+ };
26
+ }>, () => VNode, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {
27
+ change: (_value: number) => true;
28
+ }, string, import('vue').PublicProps, Readonly<import('vue').ExtractPropTypes<{
29
+ /** 0-100 的位置百分比 */
30
+ value: {
31
+ type: NumberConstructor;
32
+ required: true;
33
+ };
34
+ /** 滑轨背景(CSS background 值) */
35
+ background: {
36
+ type: StringConstructor;
37
+ required: true;
38
+ };
39
+ disabled: {
40
+ type: BooleanConstructor;
41
+ default: boolean;
42
+ };
43
+ /** 无障碍名称,由父组件传入已本地化的文案 */
44
+ ariaLabel: {
45
+ type: StringConstructor;
46
+ };
47
+ }>> & Readonly<{
48
+ onChange?: ((_value: number) => any) | undefined;
49
+ }>, {
50
+ disabled: boolean;
51
+ }, {}, {}, {}, string, import('vue').ComponentProvideOptions, true, {}, any>;
52
+ export default _default;