@chenzy-design/core 0.2.1 → 0.4.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 (283) hide show
  1. package/dist/ai-chat-dialogue.d.ts +300 -0
  2. package/dist/ai-chat-dialogue.d.ts.map +1 -0
  3. package/dist/ai-chat-dialogue.js +699 -0
  4. package/dist/ai-chat-dialogue.js.map +1 -0
  5. package/dist/ai-chat-dialogue.test.d.ts +2 -0
  6. package/dist/ai-chat-dialogue.test.d.ts.map +1 -0
  7. package/dist/ai-chat-dialogue.test.js +338 -0
  8. package/dist/ai-chat-dialogue.test.js.map +1 -0
  9. package/dist/ai-chat-input.d.ts +191 -0
  10. package/dist/ai-chat-input.d.ts.map +1 -0
  11. package/dist/ai-chat-input.js +274 -0
  12. package/dist/ai-chat-input.js.map +1 -0
  13. package/dist/ai-chat-input.test.d.ts +2 -0
  14. package/dist/ai-chat-input.test.d.ts.map +1 -0
  15. package/dist/ai-chat-input.test.js +339 -0
  16. package/dist/ai-chat-input.test.js.map +1 -0
  17. package/dist/audio-player.d.ts +154 -0
  18. package/dist/audio-player.d.ts.map +1 -0
  19. package/dist/audio-player.js +254 -0
  20. package/dist/audio-player.js.map +1 -0
  21. package/dist/audio-player.test.d.ts +2 -0
  22. package/dist/audio-player.test.d.ts.map +1 -0
  23. package/dist/audio-player.test.js +275 -0
  24. package/dist/audio-player.test.js.map +1 -0
  25. package/dist/back-top.d.ts +4 -1
  26. package/dist/back-top.d.ts.map +1 -1
  27. package/dist/back-top.js +5 -2
  28. package/dist/back-top.js.map +1 -1
  29. package/dist/back-top.test.js +3 -2
  30. package/dist/back-top.test.js.map +1 -1
  31. package/dist/calendar.d.ts +132 -44
  32. package/dist/calendar.d.ts.map +1 -1
  33. package/dist/calendar.js +413 -70
  34. package/dist/calendar.js.map +1 -1
  35. package/dist/calendar.test.js +160 -76
  36. package/dist/calendar.test.js.map +1 -1
  37. package/dist/chat.d.ts +172 -0
  38. package/dist/chat.d.ts.map +1 -0
  39. package/dist/chat.js +210 -0
  40. package/dist/chat.js.map +1 -0
  41. package/dist/chat.test.d.ts +2 -0
  42. package/dist/chat.test.d.ts.map +1 -0
  43. package/dist/chat.test.js +181 -0
  44. package/dist/chat.test.js.map +1 -0
  45. package/dist/code-highlight.d.ts +30 -0
  46. package/dist/code-highlight.d.ts.map +1 -0
  47. package/dist/code-highlight.js +37 -0
  48. package/dist/code-highlight.js.map +1 -0
  49. package/dist/code-highlight.test.d.ts +2 -0
  50. package/dist/code-highlight.test.d.ts.map +1 -0
  51. package/dist/code-highlight.test.js +36 -0
  52. package/dist/code-highlight.test.js.map +1 -0
  53. package/dist/collapsible.d.ts +41 -0
  54. package/dist/collapsible.d.ts.map +1 -0
  55. package/dist/collapsible.js +33 -0
  56. package/dist/collapsible.js.map +1 -0
  57. package/dist/collapsible.test.d.ts +2 -0
  58. package/dist/collapsible.test.d.ts.map +1 -0
  59. package/dist/collapsible.test.js +57 -0
  60. package/dist/collapsible.test.js.map +1 -0
  61. package/dist/color-value.d.ts +60 -0
  62. package/dist/color-value.d.ts.map +1 -0
  63. package/dist/color-value.js +165 -0
  64. package/dist/color-value.js.map +1 -0
  65. package/dist/color-value.test.d.ts +2 -0
  66. package/dist/color-value.test.d.ts.map +1 -0
  67. package/dist/color-value.test.js +104 -0
  68. package/dist/color-value.test.js.map +1 -0
  69. package/dist/config-provider.d.ts +76 -37
  70. package/dist/config-provider.d.ts.map +1 -1
  71. package/dist/config-provider.js +107 -32
  72. package/dist/config-provider.js.map +1 -1
  73. package/dist/config-provider.test.js +123 -60
  74. package/dist/config-provider.test.js.map +1 -1
  75. package/dist/cropper.d.ts +164 -0
  76. package/dist/cropper.d.ts.map +1 -0
  77. package/dist/cropper.js +841 -0
  78. package/dist/cropper.js.map +1 -0
  79. package/dist/cropper.test.d.ts +2 -0
  80. package/dist/cropper.test.d.ts.map +1 -0
  81. package/dist/cropper.test.js +259 -0
  82. package/dist/cropper.test.js.map +1 -0
  83. package/dist/drag-move.d.ts +119 -0
  84. package/dist/drag-move.d.ts.map +1 -0
  85. package/dist/drag-move.js +237 -0
  86. package/dist/drag-move.js.map +1 -0
  87. package/dist/drag-move.test.d.ts +2 -0
  88. package/dist/drag-move.test.d.ts.map +1 -0
  89. package/dist/drag-move.test.js +304 -0
  90. package/dist/drag-move.test.js.map +1 -0
  91. package/dist/editable.d.ts +24 -4
  92. package/dist/editable.d.ts.map +1 -1
  93. package/dist/editable.js +18 -0
  94. package/dist/editable.js.map +1 -1
  95. package/dist/editable.test.js +55 -2
  96. package/dist/editable.test.js.map +1 -1
  97. package/dist/ellipsis.d.ts +13 -0
  98. package/dist/ellipsis.d.ts.map +1 -1
  99. package/dist/ellipsis.js +36 -0
  100. package/dist/ellipsis.js.map +1 -1
  101. package/dist/ellipsis.test.js +37 -1
  102. package/dist/ellipsis.test.js.map +1 -1
  103. package/dist/form-path.d.ts +19 -0
  104. package/dist/form-path.d.ts.map +1 -0
  105. package/dist/form-path.js +97 -0
  106. package/dist/form-path.js.map +1 -0
  107. package/dist/form-path.test.d.ts +2 -0
  108. package/dist/form-path.test.d.ts.map +1 -0
  109. package/dist/form-path.test.js +57 -0
  110. package/dist/form-path.test.js.map +1 -0
  111. package/dist/form-validate.d.ts +13 -0
  112. package/dist/form-validate.d.ts.map +1 -0
  113. package/dist/form-validate.js +204 -0
  114. package/dist/form-validate.js.map +1 -0
  115. package/dist/form.d.ts +91 -18
  116. package/dist/form.d.ts.map +1 -1
  117. package/dist/form.js +170 -115
  118. package/dist/form.js.map +1 -1
  119. package/dist/form.test.js +349 -76
  120. package/dist/form.test.js.map +1 -1
  121. package/dist/highlight.d.ts +42 -32
  122. package/dist/highlight.d.ts.map +1 -1
  123. package/dist/highlight.js +67 -41
  124. package/dist/highlight.js.map +1 -1
  125. package/dist/highlight.test.js +73 -32
  126. package/dist/highlight.test.js.map +1 -1
  127. package/dist/hotkeys.d.ts +151 -0
  128. package/dist/hotkeys.d.ts.map +1 -0
  129. package/dist/hotkeys.js +188 -0
  130. package/dist/hotkeys.js.map +1 -0
  131. package/dist/hotkeys.test.d.ts +2 -0
  132. package/dist/hotkeys.test.d.ts.map +1 -0
  133. package/dist/hotkeys.test.js +170 -0
  134. package/dist/hotkeys.test.js.map +1 -0
  135. package/dist/index.d.ts +33 -17
  136. package/dist/index.d.ts.map +1 -1
  137. package/dist/index.js +32 -13
  138. package/dist/index.js.map +1 -1
  139. package/dist/input.d.ts +34 -0
  140. package/dist/input.d.ts.map +1 -0
  141. package/dist/input.js +54 -0
  142. package/dist/input.js.map +1 -0
  143. package/dist/input.test.d.ts +2 -0
  144. package/dist/input.test.d.ts.map +1 -0
  145. package/dist/input.test.js +56 -0
  146. package/dist/input.test.js.map +1 -0
  147. package/dist/markdown-render.d.ts +49 -0
  148. package/dist/markdown-render.d.ts.map +1 -0
  149. package/dist/markdown-render.js +61 -0
  150. package/dist/markdown-render.js.map +1 -0
  151. package/dist/markdown-render.test.d.ts +2 -0
  152. package/dist/markdown-render.test.d.ts.map +1 -0
  153. package/dist/markdown-render.test.js +106 -0
  154. package/dist/markdown-render.test.js.map +1 -0
  155. package/dist/notification.d.ts +40 -31
  156. package/dist/notification.d.ts.map +1 -1
  157. package/dist/notification.js +86 -70
  158. package/dist/notification.js.map +1 -1
  159. package/dist/notification.test.js +62 -39
  160. package/dist/notification.test.js.map +1 -1
  161. package/dist/numeral.d.ts +32 -0
  162. package/dist/numeral.d.ts.map +1 -0
  163. package/dist/numeral.js +67 -0
  164. package/dist/numeral.js.map +1 -0
  165. package/dist/numeral.test.d.ts +2 -0
  166. package/dist/numeral.test.d.ts.map +1 -0
  167. package/dist/numeral.test.js +59 -0
  168. package/dist/numeral.test.js.map +1 -0
  169. package/dist/overflow-list.d.ts +9 -40
  170. package/dist/overflow-list.d.ts.map +1 -1
  171. package/dist/overflow-list.js +9 -70
  172. package/dist/overflow-list.js.map +1 -1
  173. package/dist/overflow-list.test.js +1 -122
  174. package/dist/overflow-list.test.js.map +1 -1
  175. package/dist/pagination.d.ts +17 -0
  176. package/dist/pagination.d.ts.map +1 -1
  177. package/dist/pagination.js +48 -0
  178. package/dist/pagination.js.map +1 -1
  179. package/dist/pagination.test.js +40 -1
  180. package/dist/pagination.test.js.map +1 -1
  181. package/dist/pincode.d.ts +79 -0
  182. package/dist/pincode.d.ts.map +1 -0
  183. package/dist/pincode.js +119 -0
  184. package/dist/pincode.js.map +1 -0
  185. package/dist/pincode.test.d.ts +2 -0
  186. package/dist/pincode.test.d.ts.map +1 -0
  187. package/dist/pincode.test.js +151 -0
  188. package/dist/pincode.test.js.map +1 -0
  189. package/dist/progress.d.ts +32 -30
  190. package/dist/progress.d.ts.map +1 -1
  191. package/dist/progress.js +257 -64
  192. package/dist/progress.js.map +1 -1
  193. package/dist/progress.test.js +50 -47
  194. package/dist/progress.test.js.map +1 -1
  195. package/dist/resizable.d.ts +200 -0
  196. package/dist/resizable.d.ts.map +1 -0
  197. package/dist/resizable.js +329 -0
  198. package/dist/resizable.js.map +1 -0
  199. package/dist/resizable.test.d.ts +2 -0
  200. package/dist/resizable.test.d.ts.map +1 -0
  201. package/dist/resizable.test.js +302 -0
  202. package/dist/resizable.test.js.map +1 -0
  203. package/dist/scroll-list.d.ts +69 -62
  204. package/dist/scroll-list.d.ts.map +1 -1
  205. package/dist/scroll-list.js +103 -144
  206. package/dist/scroll-list.js.map +1 -1
  207. package/dist/scroll-list.test.js +100 -110
  208. package/dist/scroll-list.test.js.map +1 -1
  209. package/dist/sidebar.d.ts +46 -0
  210. package/dist/sidebar.d.ts.map +1 -0
  211. package/dist/sidebar.js +65 -0
  212. package/dist/sidebar.js.map +1 -0
  213. package/dist/sidebar.test.d.ts +2 -0
  214. package/dist/sidebar.test.d.ts.map +1 -0
  215. package/dist/sidebar.test.js +88 -0
  216. package/dist/sidebar.test.js.map +1 -0
  217. package/dist/spin.d.ts +5 -5
  218. package/dist/spin.d.ts.map +1 -1
  219. package/dist/spin.js +13 -39
  220. package/dist/spin.js.map +1 -1
  221. package/dist/spin.test.js +2 -26
  222. package/dist/spin.test.js.map +1 -1
  223. package/dist/toast.d.ts +33 -30
  224. package/dist/toast.d.ts.map +1 -1
  225. package/dist/toast.js +77 -72
  226. package/dist/toast.js.map +1 -1
  227. package/dist/toast.test.js +63 -37
  228. package/dist/toast.test.js.map +1 -1
  229. package/dist/tree.d.ts +22 -5
  230. package/dist/tree.d.ts.map +1 -1
  231. package/dist/tree.js +61 -9
  232. package/dist/tree.js.map +1 -1
  233. package/dist/tree.test.js +72 -1
  234. package/dist/tree.test.js.map +1 -1
  235. package/dist/user-guide.d.ts +73 -0
  236. package/dist/user-guide.d.ts.map +1 -0
  237. package/dist/user-guide.js +95 -0
  238. package/dist/user-guide.js.map +1 -0
  239. package/dist/user-guide.test.d.ts +2 -0
  240. package/dist/user-guide.test.d.ts.map +1 -0
  241. package/dist/user-guide.test.js +109 -0
  242. package/dist/user-guide.test.js.map +1 -0
  243. package/dist/video-player.d.ts +196 -0
  244. package/dist/video-player.d.ts.map +1 -0
  245. package/dist/video-player.js +461 -0
  246. package/dist/video-player.js.map +1 -0
  247. package/dist/video-player.test.d.ts +2 -0
  248. package/dist/video-player.test.d.ts.map +1 -0
  249. package/dist/video-player.test.js +435 -0
  250. package/dist/video-player.test.js.map +1 -0
  251. package/package.json +17 -1
  252. package/dist/banner.d.ts +0 -19
  253. package/dist/banner.d.ts.map +0 -1
  254. package/dist/banner.js +0 -20
  255. package/dist/banner.js.map +0 -1
  256. package/dist/banner.test.d.ts +0 -2
  257. package/dist/banner.test.d.ts.map +0 -1
  258. package/dist/banner.test.js +0 -29
  259. package/dist/banner.test.js.map +0 -1
  260. package/dist/breakpoints.d.ts +0 -30
  261. package/dist/breakpoints.d.ts.map +0 -1
  262. package/dist/breakpoints.js +0 -45
  263. package/dist/breakpoints.js.map +0 -1
  264. package/dist/breakpoints.test.d.ts +0 -2
  265. package/dist/breakpoints.test.d.ts.map +0 -1
  266. package/dist/breakpoints.test.js +0 -46
  267. package/dist/breakpoints.test.js.map +0 -1
  268. package/dist/lottie-icon.d.ts +0 -88
  269. package/dist/lottie-icon.d.ts.map +0 -1
  270. package/dist/lottie-icon.js +0 -84
  271. package/dist/lottie-icon.js.map +0 -1
  272. package/dist/lottie-icon.test.d.ts +0 -2
  273. package/dist/lottie-icon.test.d.ts.map +0 -1
  274. package/dist/lottie-icon.test.js +0 -88
  275. package/dist/lottie-icon.test.js.map +0 -1
  276. package/dist/sider.d.ts +0 -26
  277. package/dist/sider.d.ts.map +0 -1
  278. package/dist/sider.js +0 -55
  279. package/dist/sider.js.map +0 -1
  280. package/dist/sider.test.d.ts +0 -2
  281. package/dist/sider.test.d.ts.map +0 -1
  282. package/dist/sider.test.js +0 -29
  283. package/dist/sider.test.js.map +0 -1
@@ -1,20 +1,22 @@
1
1
  /**
2
- * createProgress helpers — framework-agnostic progress math & a11y.
3
- * Pure functions only: percent clamping, status resolution, circle/dashboard
4
- * SVG geometry, and progressbar aria props. No DOM, no framework deps.
5
- * See specs/components/feedback/Progress.spec.md §3.
2
+ * createProgress helpers — framework-agnostic progress math, colour & a11y.
3
+ * Pure functions only: percent clamping, circle SVG geometry (Semi single-ring
4
+ * dashoffset model), segmented-stroke colour resolution (generateColor, mirrors
5
+ * semi-foundation/progress/generates.ts) and progressbar aria props. No DOM,
6
+ * no framework deps. Strictly aligned to Semi Design Progress.
6
7
  */
7
- export type ProgressStatus = 'normal' | 'success' | 'error' | 'warning';
8
- export type ProgressType = 'line' | 'circle' | 'dashboard';
9
- export type GapPosition = 'top' | 'bottom' | 'left' | 'right';
10
- /** Clamp any input to an integer-friendly 0..100 (NaN/±∞ → 0/100). */
8
+ export type ProgressType = 'line' | 'circle';
9
+ export type ProgressDirection = 'horizontal' | 'vertical';
10
+ export type ProgressSize = 'default' | 'small' | 'large';
11
+ export type StrokeLinecap = 'round' | 'square';
12
+ /** A segment of the segmented-stroke colour array. */
13
+ export interface StrokeSet {
14
+ percent: number;
15
+ color: string;
16
+ }
17
+ export type StrokeArr = StrokeSet[];
18
+ /** Clamp any input to 0..100 (values outside the range snap to the bound). */
11
19
  export declare function clampPercent(percent: number): number;
12
- /**
13
- * Resolve the effective status. When status is left at 'normal' and the bar is
14
- * full, optionally promote to 'success' (successWhenFull). An explicitly set
15
- * error/warning/success is always respected.
16
- */
17
- export declare function resolveStatus(percent: number, status: ProgressStatus, successWhenFull?: boolean): ProgressStatus;
18
20
  export interface CirclePathInput {
19
21
  /** diameter in px */
20
22
  width: number;
@@ -22,43 +24,43 @@ export interface CirclePathInput {
22
24
  strokeWidth: number;
23
25
  /** percent 0..100 */
24
26
  percent: number;
25
- /** open-gap angle for dashboard (0 for full circle) */
26
- gapDegree?: number;
27
- gapPosition?: GapPosition;
28
27
  }
29
28
  export interface CirclePathProps {
30
29
  radius: number;
31
30
  /** center coordinate (width/2) */
32
31
  center: number;
33
- /** full stroke length of the track (accounting for the gap) */
32
+ /** full stroke length of the ring */
34
33
  circumference: number;
35
- /** dasharray for the track */
36
- trackDash: string;
37
- /** dashoffset for the filled stroke (maps percent → arc length) */
38
- fillDash: string;
39
- /** rotation transform so the start sits at the right place */
40
- rotation: number;
34
+ /** dasharray for both track and fill: `${c} ${c}` */
35
+ strokeDasharray: string;
36
+ /** dashoffset for the filled ring (maps percent → arc length) */
37
+ strokeDashoffset: number;
41
38
  }
42
39
  /**
43
- * Compute SVG geometry for circle/dashboard. The visible track spans
44
- * (360 - gapDegree) degrees; the fill covers `percent`% of that span.
40
+ * Compute SVG geometry for the circle ring, mirroring Semi:
41
+ * radius = (width - strokeWidth) / 2
42
+ * circumference = radius * 2π
43
+ * dashoffset = (1 - percent/100) * circumference
44
+ * The visual −90° start rotation is applied via CSS on the inner ring.
45
45
  */
46
46
  export declare function getCirclePathProps(input: CirclePathInput): CirclePathProps;
47
+ /** Resolve the stroke colour for the current percent (Semi-aligned). */
48
+ export declare function generateColor(s: StrokeArr, percent: number, gradient: boolean): string | undefined;
47
49
  export interface RootAriaInput {
48
50
  percent: number;
49
- indeterminate?: boolean;
50
51
  label?: string;
52
+ labelledBy?: string;
51
53
  valueText?: string;
52
54
  }
53
55
  export interface RootAriaProps {
54
56
  role: 'progressbar';
55
57
  'aria-valuemin': 0;
56
58
  'aria-valuemax': 100;
57
- 'aria-valuenow'?: number;
59
+ 'aria-valuenow': number;
58
60
  'aria-valuetext'?: string;
59
61
  'aria-label'?: string;
60
- 'aria-busy'?: true;
62
+ 'aria-labelledby'?: string;
61
63
  }
62
- /** Build progressbar aria props; indeterminate omits valuenow + sets busy. */
64
+ /** Build progressbar aria props. `aria-valuenow` always reflects the clamped percent. */
63
65
  export declare function getRootAriaProps(input: RootAriaInput): RootAriaProps;
64
66
  //# sourceMappingURL=progress.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"progress.d.ts","sourceRoot":"","sources":["../src/progress.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,MAAM,cAAc,GAAG,QAAQ,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS,CAAC;AACxE,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,QAAQ,GAAG,WAAW,CAAC;AAC3D,MAAM,MAAM,WAAW,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,OAAO,CAAC;AAE9D,sEAAsE;AACtE,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAKpD;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAC3B,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,cAAc,EACtB,eAAe,UAAQ,GACtB,cAAc,CAIhB;AAED,MAAM,WAAW,eAAe;IAC9B,qBAAqB;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,yBAAyB;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,qBAAqB;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,uDAAuD;IACvD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,WAAW,CAAC;CAC3B;AAED,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,kCAAkC;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,+DAA+D;IAC/D,aAAa,EAAE,MAAM,CAAC;IACtB,8BAA8B;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,mEAAmE;IACnE,QAAQ,EAAE,MAAM,CAAC;IACjB,8DAA8D;IAC9D,QAAQ,EAAE,MAAM,CAAC;CAClB;AAmBD;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,eAAe,GAAG,eAAe,CA0B1E;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,aAAa,CAAC;IACpB,eAAe,EAAE,CAAC,CAAC;IACnB,eAAe,EAAE,GAAG,CAAC;IACrB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,IAAI,CAAC;CACpB;AAED,8EAA8E;AAC9E,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,aAAa,GAAG,aAAa,CAcpE"}
1
+ {"version":3,"file":"progress.d.ts","sourceRoot":"","sources":["../src/progress.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,QAAQ,CAAC;AAC7C,MAAM,MAAM,iBAAiB,GAAG,YAAY,GAAG,UAAU,CAAC;AAC1D,MAAM,MAAM,YAAY,GAAG,SAAS,GAAG,OAAO,GAAG,OAAO,CAAC;AACzD,MAAM,MAAM,aAAa,GAAG,OAAO,GAAG,QAAQ,CAAC;AAE/C,sDAAsD;AACtD,MAAM,WAAW,SAAS;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;CACf;AACD,MAAM,MAAM,SAAS,GAAG,SAAS,EAAE,CAAC;AAEpC,8EAA8E;AAC9E,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAIpD;AAED,MAAM,WAAW,eAAe;IAC9B,qBAAqB;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,yBAAyB;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,qBAAqB;IACrB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,kCAAkC;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,qCAAqC;IACrC,aAAa,EAAE,MAAM,CAAC;IACtB,qDAAqD;IACrD,eAAe,EAAE,MAAM,CAAC;IACxB,iEAAiE;IACjE,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,eAAe,GAAG,eAAe,CAc1E;AAiBD,wEAAwE;AACxE,wBAAgB,aAAa,CAC3B,CAAC,EAAE,SAAS,EACZ,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,OAAO,GAChB,MAAM,GAAG,SAAS,CAQpB;AA0ND,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,aAAa,CAAC;IACpB,eAAe,EAAE,CAAC,CAAC;IACnB,eAAe,EAAE,GAAG,CAAC;IACrB,eAAe,EAAE,MAAM,CAAC;IACxB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,yFAAyF;AACzF,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,aAAa,GAAG,aAAa,CAWpE"}
package/dist/progress.js CHANGED
@@ -1,92 +1,285 @@
1
1
  /**
2
- * createProgress helpers — framework-agnostic progress math & a11y.
3
- * Pure functions only: percent clamping, status resolution, circle/dashboard
4
- * SVG geometry, and progressbar aria props. No DOM, no framework deps.
5
- * See specs/components/feedback/Progress.spec.md §3.
2
+ * createProgress helpers — framework-agnostic progress math, colour & a11y.
3
+ * Pure functions only: percent clamping, circle SVG geometry (Semi single-ring
4
+ * dashoffset model), segmented-stroke colour resolution (generateColor, mirrors
5
+ * semi-foundation/progress/generates.ts) and progressbar aria props. No DOM,
6
+ * no framework deps. Strictly aligned to Semi Design Progress.
6
7
  */
7
- /** Clamp any input to an integer-friendly 0..100 (NaN/±∞ 0/100). */
8
+ /** Clamp any input to 0..100 (values outside the range snap to the bound). */
8
9
  export function clampPercent(percent) {
9
- if (Number.isNaN(percent))
10
- return 0;
11
- if (percent < 0)
12
- return 0;
13
10
  if (percent > 100)
14
11
  return 100;
12
+ if (percent < 0)
13
+ return 0;
15
14
  return percent;
16
15
  }
17
16
  /**
18
- * Resolve the effective status. When status is left at 'normal' and the bar is
19
- * full, optionally promote to 'success' (successWhenFull). An explicitly set
20
- * error/warning/success is always respected.
21
- */
22
- export function resolveStatus(percent, status, successWhenFull = false) {
23
- if (status !== 'normal')
24
- return status;
25
- if (successWhenFull && clampPercent(percent) >= 100)
26
- return 'success';
27
- return 'normal';
28
- }
29
- /** rotation (deg) that places the gap/start according to gapPosition */
30
- function startRotation(gapPosition, gapDegree) {
31
- // base: a full circle starts at 3 o'clock; rotate -90 to start at top.
32
- switch (gapPosition) {
33
- case 'top':
34
- return -90 + gapDegree / 2;
35
- case 'bottom':
36
- return 90 + gapDegree / 2;
37
- case 'left':
38
- return 180 + gapDegree / 2;
39
- case 'right':
40
- return 0 + gapDegree / 2;
41
- default:
42
- return 90 + gapDegree / 2;
43
- }
44
- }
45
- /**
46
- * Compute SVG geometry for circle/dashboard. The visible track spans
47
- * (360 - gapDegree) degrees; the fill covers `percent`% of that span.
17
+ * Compute SVG geometry for the circle ring, mirroring Semi:
18
+ * radius = (width - strokeWidth) / 2
19
+ * circumference = radius *
20
+ * dashoffset = (1 - percent/100) * circumference
21
+ * The visual −90° start rotation is applied via CSS on the inner ring.
48
22
  */
49
23
  export function getCirclePathProps(input) {
50
- const { width, strokeWidth, gapDegree = 0, gapPosition = 'bottom' } = input;
24
+ const { width, strokeWidth } = input;
51
25
  const percent = clampPercent(input.percent);
52
26
  const center = width / 2;
53
- const radius = center - strokeWidth / 2;
54
- const perimeter = 2 * Math.PI * radius;
55
- // visible portion of the perimeter (full perimeter minus the gap)
56
- const visibleRatio = (360 - gapDegree) / 360;
57
- const visibleLen = perimeter * visibleRatio;
58
- const gapLen = perimeter - visibleLen;
59
- // track: draw visibleLen, then leave gapLen empty
60
- const trackDash = `${visibleLen} ${gapLen}`;
61
- // fill: draw percent% of the visible length, rest is offset
62
- const fillLen = (visibleLen * percent) / 100;
63
- const fillDash = `${fillLen} ${perimeter - fillLen}`;
27
+ const radius = (width - strokeWidth) / 2;
28
+ const circumference = radius * 2 * Math.PI;
29
+ const strokeDashoffset = (1 - percent / 100) * circumference;
64
30
  return {
65
31
  radius,
66
32
  center,
67
- circumference: perimeter,
68
- trackDash,
69
- fillDash,
70
- rotation: startRotation(gapPosition, gapDegree),
33
+ circumference,
34
+ strokeDasharray: `${circumference} ${circumference}`,
35
+ strokeDashoffset,
71
36
  };
72
37
  }
73
- /** Build progressbar aria props; indeterminate omits valuenow + sets busy. */
38
+ // ————————————————————————————————————————————————————————————————
39
+ // Segmented-stroke colour resolution — direct port of Semi's generates.ts.
40
+ // `stroke` may be a plain colour string (returned as-is) or an ordered array
41
+ // of {percent, color}; generateColor picks/blends the colour for the current
42
+ // percent. With `gradient=true`, colours between two anchors are interpolated.
43
+ // ————————————————————————————————————————————————————————————————
44
+ const STROKE_DEFAULT = 'var(--cd-color-success)';
45
+ /** Resolve the stroke colour for the current percent (Semi-aligned). */
46
+ export function generateColor(s, percent, gradient) {
47
+ try {
48
+ const color = generate(s, percent, gradient);
49
+ if (color !== undefined && color !== '')
50
+ return color;
51
+ }
52
+ catch {
53
+ return undefined;
54
+ }
55
+ return undefined;
56
+ }
57
+ function generate(s, percent, gradient) {
58
+ s.sort((a, b) => a.percent - b.percent);
59
+ if (s[0].percent > percent) {
60
+ return STROKE_DEFAULT;
61
+ }
62
+ const endS = s[s.length - 1];
63
+ if (endS.percent < percent) {
64
+ return formatToHex(endS.color);
65
+ }
66
+ for (const [index, item] of s.entries()) {
67
+ if (item.percent === percent) {
68
+ return formatToHex(item.color);
69
+ }
70
+ if (percent > item.percent)
71
+ continue;
72
+ // index-1 恒有效:s[0].percent <= percent(上方早返回保证),故进入此分支时 index >= 1。
73
+ const oldItem = s[index - 1];
74
+ if (!gradient) {
75
+ return formatToHex(oldItem.color);
76
+ }
77
+ return generateGradients({
78
+ startColor: formatToHex(oldItem.color),
79
+ endColor: formatToHex(item.color),
80
+ size: item.percent - oldItem.percent - 1,
81
+ }, percent - oldItem.percent - 1);
82
+ }
83
+ return undefined;
84
+ }
85
+ function generateGradients(g, index) {
86
+ const { startColor, endColor, size } = g;
87
+ const sA = startColor.split('');
88
+ const eA = endColor.split('');
89
+ const rC = [parseInt(`${sA[1]}${sA[2]}`, 16), parseInt(`${eA[1]}${eA[2]}`, 16)];
90
+ const gC = [parseInt(`${sA[3]}${sA[4]}`, 16), parseInt(`${eA[3]}${eA[4]}`, 16)];
91
+ const bC = [parseInt(`${sA[5]}${sA[6]}`, 16), parseInt(`${eA[5]}${eA[6]}`, 16)];
92
+ const aC = [parseInt(`${sA[7]}${sA[8]}`, 16), parseInt(`${eA[7]}${eA[8]}`, 16)];
93
+ const rStep = (rC[0] - rC[1]) / (size + 1);
94
+ const gStep = (gC[0] - gC[1]) / (size + 1);
95
+ const bStep = (bC[0] - bC[1]) / (size + 1);
96
+ const aStep = (aC[0] - aC[1]) / (size + 1);
97
+ function tHex(i) {
98
+ const rS = Math.round(rC[0] - rStep * (i + 1)).toString(16);
99
+ const gS = Math.round(gC[0] - gStep * (i + 1)).toString(16);
100
+ const bS = Math.round(bC[0] - bStep * (i + 1)).toString(16);
101
+ const h = `${padTwo(rS)}${padTwo(gS)}${padTwo(bS)}`;
102
+ const t = Math.floor(aStep * (i + 1) + aC[1]).toString(16);
103
+ return toHex.Hex(`#${h}`, t);
104
+ }
105
+ function padTwo(str) {
106
+ if (str.length === 1)
107
+ return `0${str}`;
108
+ if (str.length === 0)
109
+ return '00';
110
+ return str;
111
+ }
112
+ if (typeof index === 'undefined') {
113
+ const gradientColorArr = [startColor];
114
+ for (let i = 0; i < size; i += 1) {
115
+ gradientColorArr.push(tHex(i));
116
+ }
117
+ return gradientColorArr;
118
+ }
119
+ return tHex(index);
120
+ }
121
+ /** Resolve any supported colour type (Hex/Hsl(a)/Rgb(a)/Semi tokens) to hex. */
122
+ function formatToHex(color) {
123
+ color = color.trim().toLowerCase();
124
+ if (REG_S.hex.test(color)) {
125
+ return toHex.Hex(color, undefined);
126
+ }
127
+ if (REG_S.hslA.test(color)) {
128
+ return toHex.Hex(toHex.HslA(color), undefined);
129
+ }
130
+ if (REG_S.rgbA.test(color)) {
131
+ return toHex.Hex(toHex.RgbA(color), undefined);
132
+ }
133
+ if (REG_S.semiDesignTokens.test(color)) {
134
+ if (DESIGN_TOKENS.ALONG.indexOf(color) !== -1) {
135
+ return toHex.DesignToken(color);
136
+ }
137
+ if (DESIGN_TOKENS.SEQUENCE.indexOf(color) !== -1) {
138
+ return toHex.DesignToken(`${color}-5`);
139
+ }
140
+ return toHex.DesignToken(`${color}`);
141
+ }
142
+ return undefined;
143
+ }
144
+ const toHex = {
145
+ Hex(color, transparency) {
146
+ color = color.replace('#', '');
147
+ if (color.length === 8)
148
+ return `#${color}`;
149
+ if (color.length === 6)
150
+ return `#${color}${transparency || 'ff'}`;
151
+ if (color.length === 3) {
152
+ color = color
153
+ .split('')
154
+ .map((c) => c + c)
155
+ .join('');
156
+ }
157
+ return `#${color}${transparency || 'ff'}`;
158
+ },
159
+ DesignToken(color) {
160
+ // Only resolvable in the browser after the real DOM exists.
161
+ if (typeof window === 'undefined')
162
+ return undefined;
163
+ const variable = getComputedStyle(document.body).getPropertyValue(`--cd-${color}`);
164
+ if (variable === '')
165
+ return undefined;
166
+ const rgba = `rgba(${variable}, 1)`;
167
+ return toHex.RgbA(rgba);
168
+ },
169
+ HslA(color) {
170
+ const hsla = REG_S.hslA.exec(color);
171
+ const h = parseInt(hsla[2]);
172
+ const s = parseInt(hsla[3]) / 100;
173
+ const l = parseInt(hsla[4]) / 100;
174
+ const a = hsla[5];
175
+ const c = (1 - Math.abs(2 * l - 1)) * s;
176
+ const x = c * (1 - Math.abs(((h / 60) % 2) - 1));
177
+ const m = l - c / 2;
178
+ let r = 0;
179
+ let g = 0;
180
+ let b = 0;
181
+ if (0 <= h && h < 60) {
182
+ r = c;
183
+ g = x;
184
+ b = 0;
185
+ }
186
+ else if (60 <= h && h < 120) {
187
+ r = x;
188
+ g = c;
189
+ b = 0;
190
+ }
191
+ else if (120 <= h && h < 180) {
192
+ r = 0;
193
+ g = c;
194
+ b = x;
195
+ }
196
+ else if (180 <= h && h < 240) {
197
+ r = 0;
198
+ g = x;
199
+ b = c;
200
+ }
201
+ else if (240 <= h && h < 300) {
202
+ r = x;
203
+ g = 0;
204
+ b = c;
205
+ }
206
+ else if (300 <= h && h < 360) {
207
+ r = c;
208
+ g = 0;
209
+ b = x;
210
+ }
211
+ const rS = Math.round((r + m) * 255).toString(16);
212
+ const gS = Math.round((g + m) * 255).toString(16);
213
+ const bS = Math.round((b + m) * 255).toString(16);
214
+ return toHex.utils.pAL(rS, gS, bS, a);
215
+ },
216
+ RgbA(color) {
217
+ const rgba = REG_S.rgbA.exec(color);
218
+ const r = parseInt(rgba[2], 10).toString(16);
219
+ const g = parseInt(rgba[3], 10).toString(16);
220
+ const b = parseInt(rgba[4], 10).toString(16);
221
+ const a = rgba[5];
222
+ return toHex.utils.pAL(r, g, b, a);
223
+ },
224
+ utils: {
225
+ pAL(r, g, b, a) {
226
+ if (r.length === 1)
227
+ r = '0' + r;
228
+ if (g.length === 1)
229
+ g = '0' + g;
230
+ if (b.length === 1)
231
+ b = '0' + b;
232
+ if (typeof a !== 'undefined') {
233
+ let aHex = Math.round(parseInt(a) * 255).toString(16);
234
+ if (aHex.length === 1)
235
+ aHex = '0' + aHex;
236
+ return '#' + r + g + b + aHex;
237
+ }
238
+ return '#' + r + g + b;
239
+ },
240
+ },
241
+ };
242
+ const REG_S = {
243
+ hex: /^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$/,
244
+ hslA: /(hsl)a?\(\s*?(\d+),?\s*?(\d+)%,?\s*?(\d+)%,?\s*?\/?(\s*?[\d.]+)?\s*?\)/,
245
+ rgbA: /(rgb)a?\(\s*?(\d+),?\s*?(\d+),?\s*?(\d+),?\s*?\/?(\s*?[\d.]+)?\s*?\)/,
246
+ semiDesignTokens: /(\w+)?-?(\w+)-?(\d)?/,
247
+ };
248
+ const DESIGN_TOKENS = {
249
+ ALONG: ['black', 'white'],
250
+ SEQUENCE: [
251
+ 'amber',
252
+ 'blue',
253
+ 'cyan',
254
+ 'green',
255
+ 'grey',
256
+ 'indigo',
257
+ 'light-blue',
258
+ 'light-green',
259
+ 'lime',
260
+ 'orange',
261
+ 'pink',
262
+ 'purple',
263
+ 'red',
264
+ 'teal',
265
+ 'violet',
266
+ 'yellow',
267
+ ],
268
+ };
269
+ /** Build progressbar aria props. `aria-valuenow` always reflects the clamped percent. */
74
270
  export function getRootAriaProps(input) {
75
271
  const props = {
76
272
  role: 'progressbar',
77
273
  'aria-valuemin': 0,
78
274
  'aria-valuemax': 100,
275
+ 'aria-valuenow': clampPercent(input.percent),
79
276
  };
80
- if (input.indeterminate) {
81
- props['aria-busy'] = true;
82
- }
83
- else {
84
- props['aria-valuenow'] = clampPercent(input.percent);
85
- if (input.valueText)
86
- props['aria-valuetext'] = input.valueText;
87
- }
277
+ if (input.valueText)
278
+ props['aria-valuetext'] = input.valueText;
88
279
  if (input.label)
89
280
  props['aria-label'] = input.label;
281
+ if (input.labelledBy)
282
+ props['aria-labelledby'] = input.labelledBy;
90
283
  return props;
91
284
  }
92
285
  //# sourceMappingURL=progress.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"progress.js","sourceRoot":"","sources":["../src/progress.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"progress.js","sourceRoot":"","sources":["../src/progress.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAcH,8EAA8E;AAC9E,MAAM,UAAU,YAAY,CAAC,OAAe;IAC1C,IAAI,OAAO,GAAG,GAAG;QAAE,OAAO,GAAG,CAAC;IAC9B,IAAI,OAAO,GAAG,CAAC;QAAE,OAAO,CAAC,CAAC;IAC1B,OAAO,OAAO,CAAC;AACjB,CAAC;AAuBD;;;;;;GAMG;AACH,MAAM,UAAU,kBAAkB,CAAC,KAAsB;IACvD,MAAM,EAAE,KAAK,EAAE,WAAW,EAAE,GAAG,KAAK,CAAC;IACrC,MAAM,OAAO,GAAG,YAAY,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAC5C,MAAM,MAAM,GAAG,KAAK,GAAG,CAAC,CAAC;IACzB,MAAM,MAAM,GAAG,CAAC,KAAK,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC;IACzC,MAAM,aAAa,GAAG,MAAM,GAAG,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC;IAC3C,MAAM,gBAAgB,GAAG,CAAC,CAAC,GAAG,OAAO,GAAG,GAAG,CAAC,GAAG,aAAa,CAAC;IAC7D,OAAO;QACL,MAAM;QACN,MAAM;QACN,aAAa;QACb,eAAe,EAAE,GAAG,aAAa,IAAI,aAAa,EAAE;QACpD,gBAAgB;KACjB,CAAC;AACJ,CAAC;AAED,mEAAmE;AACnE,2EAA2E;AAC3E,6EAA6E;AAC7E,6EAA6E;AAC7E,+EAA+E;AAC/E,mEAAmE;AAEnE,MAAM,cAAc,GAAG,yBAAyB,CAAC;AAQjD,wEAAwE;AACxE,MAAM,UAAU,aAAa,CAC3B,CAAY,EACZ,OAAe,EACf,QAAiB;IAEjB,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,QAAQ,CAAC,CAAC,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC;QAC7C,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,EAAE;YAAE,OAAO,KAAe,CAAC;IAClE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,SAAS,QAAQ,CACf,CAAY,EACZ,OAAe,EACf,QAAiB;IAEjB,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC;IACxC,IAAI,CAAC,CAAC,CAAC,CAAE,CAAC,OAAO,GAAG,OAAO,EAAE,CAAC;QAC5B,OAAO,cAAc,CAAC;IACxB,CAAC;IACD,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAE,CAAC;IAC9B,IAAI,IAAI,CAAC,OAAO,GAAG,OAAO,EAAE,CAAC;QAC3B,OAAO,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACjC,CAAC;IACD,KAAK,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC;QACxC,IAAI,IAAI,CAAC,OAAO,KAAK,OAAO,EAAE,CAAC;YAC7B,OAAO,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACjC,CAAC;QACD,IAAI,OAAO,GAAG,IAAI,CAAC,OAAO;YAAE,SAAS;QACrC,mEAAmE;QACnE,MAAM,OAAO,GAAG,CAAC,CAAC,KAAK,GAAG,CAAC,CAAE,CAAC;QAC9B,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,OAAO,WAAW,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QACpC,CAAC;QACD,OAAO,iBAAiB,CACtB;YACE,UAAU,EAAE,WAAW,CAAC,OAAO,CAAC,KAAK,CAAW;YAChD,QAAQ,EAAE,WAAW,CAAC,IAAI,CAAC,KAAK,CAAW;YAC3C,IAAI,EAAE,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,GAAG,CAAC;SACzC,EACD,OAAO,GAAG,OAAO,CAAC,OAAO,GAAG,CAAC,CACpB,CAAC;IACd,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,SAAS,iBAAiB,CACxB,CAAgB,EAChB,KAAyB;IAEzB,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,IAAI,EAAE,GAAG,CAAC,CAAC;IACzC,MAAM,EAAE,GAAG,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAChC,MAAM,EAAE,GAAG,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAC9B,MAAM,EAAE,GAAG,CAAC,QAAQ,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,QAAQ,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC;IAChF,MAAM,EAAE,GAAG,CAAC,QAAQ,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,QAAQ,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC;IAChF,MAAM,EAAE,GAAG,CAAC,QAAQ,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,QAAQ,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC;IAChF,MAAM,EAAE,GAAG,CAAC,QAAQ,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,QAAQ,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC;IAChF,MAAM,KAAK,GAAG,CAAC,EAAE,CAAC,CAAC,CAAE,GAAG,EAAE,CAAC,CAAC,CAAE,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC;IAC7C,MAAM,KAAK,GAAG,CAAC,EAAE,CAAC,CAAC,CAAE,GAAG,EAAE,CAAC,CAAC,CAAE,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC;IAC7C,MAAM,KAAK,GAAG,CAAC,EAAE,CAAC,CAAC,CAAE,GAAG,EAAE,CAAC,CAAC,CAAE,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC;IAC7C,MAAM,KAAK,GAAG,CAAC,EAAE,CAAC,CAAC,CAAE,GAAG,EAAE,CAAC,CAAC,CAAE,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC;IAC7C,SAAS,IAAI,CAAC,CAAS;QACrB,MAAM,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAE,GAAG,KAAK,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;QAC7D,MAAM,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAE,GAAG,KAAK,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;QAC7D,MAAM,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAE,GAAG,KAAK,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;QAC7D,MAAM,CAAC,GAAG,GAAG,MAAM,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC;QACpD,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAE,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;QAC5D,OAAO,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;IAC/B,CAAC;IACD,SAAS,MAAM,CAAC,GAAW;QACzB,IAAI,GAAG,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,IAAI,GAAG,EAAE,CAAC;QACvC,IAAI,GAAG,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,IAAI,CAAC;QAClC,OAAO,GAAG,CAAC;IACb,CAAC;IACD,IAAI,OAAO,KAAK,KAAK,WAAW,EAAE,CAAC;QACjC,MAAM,gBAAgB,GAAG,CAAC,UAAU,CAAC,CAAC;QACtC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;YACjC,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;QACjC,CAAC;QACD,OAAO,gBAAgB,CAAC;IAC1B,CAAC;IACD,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC;AACrB,CAAC;AAED,gFAAgF;AAChF,SAAS,WAAW,CAAC,KAAa;IAChC,KAAK,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACnC,IAAI,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QAC1B,OAAO,KAAK,CAAC,GAAG,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;IACrC,CAAC;IACD,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QAC3B,OAAO,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,SAAS,CAAC,CAAC;IACjD,CAAC;IACD,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QAC3B,OAAO,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,SAAS,CAAC,CAAC;IACjD,CAAC;IACD,IAAI,KAAK,CAAC,gBAAgB,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QACvC,IAAI,aAAa,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;YAC9C,OAAO,KAAK,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;QAClC,CAAC;QACD,IAAI,aAAa,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;YACjD,OAAO,KAAK,CAAC,WAAW,CAAC,GAAG,KAAK,IAAI,CAAC,CAAC;QACzC,CAAC;QACD,OAAO,KAAK,CAAC,WAAW,CAAC,GAAG,KAAK,EAAE,CAAC,CAAC;IACvC,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,MAAM,KAAK,GAAG;IACZ,GAAG,CAAC,KAAa,EAAE,YAAgC;QACjD,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;QAC/B,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,IAAI,KAAK,EAAE,CAAC;QAC3C,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,IAAI,KAAK,GAAG,YAAY,IAAI,IAAI,EAAE,CAAC;QAClE,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACvB,KAAK,GAAG,KAAK;iBACV,KAAK,CAAC,EAAE,CAAC;iBACT,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC;iBACjB,IAAI,CAAC,EAAE,CAAC,CAAC;QACd,CAAC;QACD,OAAO,IAAI,KAAK,GAAG,YAAY,IAAI,IAAI,EAAE,CAAC;IAC5C,CAAC;IACD,WAAW,CAAC,KAAa;QACvB,4DAA4D;QAC5D,IAAI,OAAO,MAAM,KAAK,WAAW;YAAE,OAAO,SAAS,CAAC;QACpD,MAAM,QAAQ,GAAG,gBAAgB,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,gBAAgB,CAAC,QAAQ,KAAK,EAAE,CAAC,CAAC;QACnF,IAAI,QAAQ,KAAK,EAAE;YAAE,OAAO,SAAS,CAAC;QACtC,MAAM,IAAI,GAAG,QAAQ,QAAQ,MAAM,CAAC;QACpC,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC1B,CAAC;IACD,IAAI,CAAC,KAAa;QAChB,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAoB,CAAC;QACvD,MAAM,CAAC,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAE,CAAC,CAAC;QAC7B,MAAM,CAAC,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAE,CAAC,GAAG,GAAG,CAAC;QACnC,MAAM,CAAC,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAE,CAAC,GAAG,GAAG,CAAC;QACnC,MAAM,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;QACxC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QACjD,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACpB,IAAI,CAAC,GAAW,CAAC,CAAC;QAClB,IAAI,CAAC,GAAW,CAAC,CAAC;QAClB,IAAI,CAAC,GAAW,CAAC,CAAC;QAClB,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC;YACrB,CAAC,GAAG,CAAC,CAAC;YACN,CAAC,GAAG,CAAC,CAAC;YACN,CAAC,GAAG,CAAC,CAAC;QACR,CAAC;aAAM,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,GAAG,EAAE,CAAC;YAC9B,CAAC,GAAG,CAAC,CAAC;YACN,CAAC,GAAG,CAAC,CAAC;YACN,CAAC,GAAG,CAAC,CAAC;QACR,CAAC;aAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,GAAG,EAAE,CAAC;YAC/B,CAAC,GAAG,CAAC,CAAC;YACN,CAAC,GAAG,CAAC,CAAC;YACN,CAAC,GAAG,CAAC,CAAC;QACR,CAAC;aAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,GAAG,EAAE,CAAC;YAC/B,CAAC,GAAG,CAAC,CAAC;YACN,CAAC,GAAG,CAAC,CAAC;YACN,CAAC,GAAG,CAAC,CAAC;QACR,CAAC;aAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,GAAG,EAAE,CAAC;YAC/B,CAAC,GAAG,CAAC,CAAC;YACN,CAAC,GAAG,CAAC,CAAC;YACN,CAAC,GAAG,CAAC,CAAC;QACR,CAAC;aAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,GAAG,EAAE,CAAC;YAC/B,CAAC,GAAG,CAAC,CAAC;YACN,CAAC,GAAG,CAAC,CAAC;YACN,CAAC,GAAG,CAAC,CAAC;QACR,CAAC;QACD,MAAM,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;QAClD,MAAM,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;QAClD,MAAM,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;QAClD,OAAO,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC;IACxC,CAAC;IACD,IAAI,CAAC,KAAa;QAChB,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAoB,CAAC;QACvD,MAAM,CAAC,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAE,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;QAC9C,MAAM,CAAC,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAE,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;QAC9C,MAAM,CAAC,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAE,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;QAC9C,MAAM,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,OAAO,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;IACrC,CAAC;IACD,KAAK,EAAE;QACL,GAAG,CAAC,CAAS,EAAE,CAAS,EAAE,CAAS,EAAE,CAAqB;YACxD,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC;gBAAE,CAAC,GAAG,GAAG,GAAG,CAAC,CAAC;YAChC,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC;gBAAE,CAAC,GAAG,GAAG,GAAG,CAAC,CAAC;YAChC,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC;gBAAE,CAAC,GAAG,GAAG,GAAG,CAAC,CAAC;YAChC,IAAI,OAAO,CAAC,KAAK,WAAW,EAAE,CAAC;gBAC7B,IAAI,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;gBACtD,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;oBAAE,IAAI,GAAG,GAAG,GAAG,IAAI,CAAC;gBACzC,OAAO,GAAG,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC;YAChC,CAAC;YACD,OAAO,GAAG,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACzB,CAAC;KACF;CACF,CAAC;AAEF,MAAM,KAAK,GAAG;IACZ,GAAG,EAAE,mDAAmD;IACxD,IAAI,EAAE,wEAAwE;IAC9E,IAAI,EAAE,sEAAsE;IAC5E,gBAAgB,EAAE,sBAAsB;CACzC,CAAC;AAEF,MAAM,aAAa,GAAG;IACpB,KAAK,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC;IACzB,QAAQ,EAAE;QACR,OAAO;QACP,MAAM;QACN,MAAM;QACN,OAAO;QACP,MAAM;QACN,QAAQ;QACR,YAAY;QACZ,aAAa;QACb,MAAM;QACN,QAAQ;QACR,MAAM;QACN,QAAQ;QACR,KAAK;QACL,MAAM;QACN,QAAQ;QACR,QAAQ;KACT;CACF,CAAC;AAuBF,yFAAyF;AACzF,MAAM,UAAU,gBAAgB,CAAC,KAAoB;IACnD,MAAM,KAAK,GAAkB;QAC3B,IAAI,EAAE,aAAa;QACnB,eAAe,EAAE,CAAC;QAClB,eAAe,EAAE,GAAG;QACpB,eAAe,EAAE,YAAY,CAAC,KAAK,CAAC,OAAO,CAAC;KAC7C,CAAC;IACF,IAAI,KAAK,CAAC,SAAS;QAAE,KAAK,CAAC,gBAAgB,CAAC,GAAG,KAAK,CAAC,SAAS,CAAC;IAC/D,IAAI,KAAK,CAAC,KAAK;QAAE,KAAK,CAAC,YAAY,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC;IACnD,IAAI,KAAK,CAAC,UAAU;QAAE,KAAK,CAAC,iBAAiB,CAAC,GAAG,KAAK,CAAC,UAAU,CAAC;IAClE,OAAO,KAAK,CAAC;AACf,CAAC"}
@@ -1,64 +1,67 @@
1
1
  import { describe, expect, it } from 'vitest';
2
- import { clampPercent, resolveStatus, getCirclePathProps, getRootAriaProps, } from './progress.js';
2
+ import { clampPercent, getCirclePathProps, generateColor, getRootAriaProps, } from './progress.js';
3
3
  describe('clampPercent', () => {
4
- it('clamps to 0..100 and handles NaN', () => {
4
+ it('clamps to 0..100', () => {
5
5
  expect(clampPercent(50)).toBe(50);
6
6
  expect(clampPercent(-10)).toBe(0);
7
7
  expect(clampPercent(120)).toBe(100);
8
- expect(clampPercent(Number.NaN)).toBe(0);
9
8
  expect(clampPercent(0)).toBe(0);
10
9
  expect(clampPercent(100)).toBe(100);
11
10
  });
12
11
  });
13
- describe('resolveStatus', () => {
14
- it('respects an explicit status', () => {
15
- expect(resolveStatus(100, 'error')).toBe('error');
16
- expect(resolveStatus(50, 'warning')).toBe('warning');
12
+ describe('getCirclePathProps', () => {
13
+ it('computes radius/circumference (Semi single-ring model)', () => {
14
+ const p = getCirclePathProps({ width: 72, strokeWidth: 4, percent: 0 });
15
+ expect(p.center).toBe(36);
16
+ expect(p.radius).toBe(34); // (72 - 4) / 2
17
+ expect(p.circumference).toBeCloseTo(2 * Math.PI * 34, 5);
18
+ expect(p.strokeDasharray).toBe(`${p.circumference} ${p.circumference}`);
19
+ });
20
+ it('dashoffset is (1 - percent/100) * circumference', () => {
21
+ const p0 = getCirclePathProps({ width: 72, strokeWidth: 4, percent: 0 });
22
+ expect(p0.strokeDashoffset).toBeCloseTo(p0.circumference, 5);
23
+ const p50 = getCirclePathProps({ width: 72, strokeWidth: 4, percent: 50 });
24
+ expect(p50.strokeDashoffset).toBeCloseTo(p50.circumference * 0.5, 5);
25
+ const p100 = getCirclePathProps({ width: 72, strokeWidth: 4, percent: 100 });
26
+ expect(p100.strokeDashoffset).toBeCloseTo(0, 5);
17
27
  });
18
- it('promotes to success when full and successWhenFull', () => {
19
- expect(resolveStatus(100, 'normal', true)).toBe('success');
20
- expect(resolveStatus(99, 'normal', true)).toBe('normal');
21
- expect(resolveStatus(100, 'normal', false)).toBe('normal');
28
+ it('clamps percent before computing offset', () => {
29
+ const p = getCirclePathProps({ width: 100, strokeWidth: 6, percent: 150 });
30
+ expect(p.strokeDashoffset).toBeCloseTo(0, 5);
22
31
  });
23
32
  });
24
- describe('getCirclePathProps', () => {
25
- it('computes radius/perimeter for a full circle', () => {
26
- const p = getCirclePathProps({ width: 120, strokeWidth: 8, percent: 0 });
27
- expect(p.center).toBe(60);
28
- expect(p.radius).toBe(56); // 60 - 8/2
29
- expect(p.circumference).toBeCloseTo(2 * Math.PI * 56, 5);
33
+ describe('generateColor (segmented stroke)', () => {
34
+ const strokeArr = [
35
+ { percent: 20, color: '#ff0000' },
36
+ { percent: 60, color: '#00ff00' },
37
+ { percent: 100, color: '#0000ff' },
38
+ ];
39
+ it('returns default when percent is below the first anchor', () => {
40
+ expect(generateColor(strokeArr, 10, false)).toBe('var(--cd-color-success)');
41
+ });
42
+ it('returns the last colour when percent exceeds the last anchor', () => {
43
+ expect(generateColor([{ percent: 50, color: '#ff0000' }], 80, false)).toBe('#ff0000ff');
44
+ });
45
+ it('returns exact colour on an anchor', () => {
46
+ expect(generateColor(strokeArr, 60, false)).toBe('#00ff00ff');
30
47
  });
31
- it('fill length is proportional to percent (full circle)', () => {
32
- const r = 56;
33
- const perim = 2 * Math.PI * r;
34
- const p = getCirclePathProps({ width: 120, strokeWidth: 8, percent: 50 });
35
- const fillLen = Number(p.fillDash.split(' ')[0]);
36
- expect(fillLen).toBeCloseTo(perim * 0.5, 4);
48
+ it('non-gradient picks the lower anchor colour between anchors', () => {
49
+ // 40 is between 20(#ff0000) and 60(#00ff00) → lower anchor red
50
+ expect(generateColor(strokeArr, 40, false)).toBe('#ff0000ff');
37
51
  });
38
- it('dashboard gap reduces the visible track length', () => {
39
- const r = 56;
40
- const perim = 2 * Math.PI * r;
41
- const p = getCirclePathProps({
42
- width: 120,
43
- strokeWidth: 8,
44
- percent: 100,
45
- gapDegree: 90,
46
- });
47
- // visible track = 270/360 of perimeter
48
- const trackLen = Number(p.trackDash.split(' ')[0]);
49
- expect(trackLen).toBeCloseTo(perim * (270 / 360), 4);
50
- // 100% fill covers the full visible track
51
- const fillLen = Number(p.fillDash.split(' ')[0]);
52
- expect(fillLen).toBeCloseTo(trackLen, 4);
52
+ it('gradient interpolates between two anchors', () => {
53
+ const c = generateColor(strokeArr, 40, true);
54
+ expect(typeof c).toBe('string');
55
+ expect(c).toMatch(/^#[0-9a-f]{8}$/);
56
+ // blended red→green: some green appears, red drops from ff
57
+ expect(c).not.toBe('#ff0000ff');
53
58
  });
54
- it('rotation differs by gapPosition', () => {
55
- const top = getCirclePathProps({ width: 100, strokeWidth: 6, percent: 0, gapDegree: 60, gapPosition: 'top' });
56
- const bottom = getCirclePathProps({ width: 100, strokeWidth: 6, percent: 0, gapDegree: 60, gapPosition: 'bottom' });
57
- expect(top.rotation).not.toBe(bottom.rotation);
59
+ it('accepts rgb/hsl colour inputs', () => {
60
+ expect(generateColor([{ percent: 0, color: 'rgb(255, 0, 0)' }], 50, false)).toBe('#ff0000ff');
58
61
  });
59
62
  });
60
63
  describe('getRootAriaProps', () => {
61
- it('emits valuenow for determinate progress', () => {
64
+ it('always emits valuenow (clamped)', () => {
62
65
  const a = getRootAriaProps({ percent: 42, label: '上传进度', valueText: '42% 完成' });
63
66
  expect(a.role).toBe('progressbar');
64
67
  expect(a['aria-valuenow']).toBe(42);
@@ -67,10 +70,10 @@ describe('getRootAriaProps', () => {
67
70
  expect(a['aria-valuetext']).toBe('42% 完成');
68
71
  expect(a['aria-label']).toBe('上传进度');
69
72
  });
70
- it('omits valuenow and sets busy when indeterminate', () => {
71
- const a = getRootAriaProps({ percent: 50, indeterminate: true });
72
- expect(a['aria-valuenow']).toBeUndefined();
73
- expect(a['aria-busy']).toBe(true);
73
+ it('supports labelledby', () => {
74
+ const a = getRootAriaProps({ percent: 30, labelledBy: 'lbl' });
75
+ expect(a['aria-labelledby']).toBe('lbl');
76
+ expect(a['aria-label']).toBeUndefined();
74
77
  });
75
78
  it('clamps valuenow', () => {
76
79
  expect(getRootAriaProps({ percent: 150 })['aria-valuenow']).toBe(100);