@chenzy-design/core 0.1.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 (310) hide show
  1. package/LICENSE +21 -0
  2. package/dist/back-top.d.ts +16 -0
  3. package/dist/back-top.d.ts.map +1 -0
  4. package/dist/back-top.js +29 -0
  5. package/dist/back-top.js.map +1 -0
  6. package/dist/back-top.test.d.ts +2 -0
  7. package/dist/back-top.test.d.ts.map +1 -0
  8. package/dist/back-top.test.js +44 -0
  9. package/dist/back-top.test.js.map +1 -0
  10. package/dist/banner.d.ts +19 -0
  11. package/dist/banner.d.ts.map +1 -0
  12. package/dist/banner.js +20 -0
  13. package/dist/banner.js.map +1 -0
  14. package/dist/banner.test.d.ts +2 -0
  15. package/dist/banner.test.d.ts.map +1 -0
  16. package/dist/banner.test.js +29 -0
  17. package/dist/banner.test.js.map +1 -0
  18. package/dist/breakpoints.d.ts +30 -0
  19. package/dist/breakpoints.d.ts.map +1 -0
  20. package/dist/breakpoints.js +45 -0
  21. package/dist/breakpoints.js.map +1 -0
  22. package/dist/breakpoints.test.d.ts +2 -0
  23. package/dist/breakpoints.test.d.ts.map +1 -0
  24. package/dist/breakpoints.test.js +46 -0
  25. package/dist/breakpoints.test.js.map +1 -0
  26. package/dist/calendar.d.ts +63 -0
  27. package/dist/calendar.d.ts.map +1 -0
  28. package/dist/calendar.js +94 -0
  29. package/dist/calendar.js.map +1 -0
  30. package/dist/calendar.test.d.ts +2 -0
  31. package/dist/calendar.test.d.ts.map +1 -0
  32. package/dist/calendar.test.js +88 -0
  33. package/dist/calendar.test.js.map +1 -0
  34. package/dist/cascader.d.ts +64 -0
  35. package/dist/cascader.d.ts.map +1 -0
  36. package/dist/cascader.js +79 -0
  37. package/dist/cascader.js.map +1 -0
  38. package/dist/cascader.test.d.ts +2 -0
  39. package/dist/cascader.test.d.ts.map +1 -0
  40. package/dist/cascader.test.js +107 -0
  41. package/dist/cascader.test.js.map +1 -0
  42. package/dist/color.d.ts +70 -0
  43. package/dist/color.d.ts.map +1 -0
  44. package/dist/color.js +217 -0
  45. package/dist/color.js.map +1 -0
  46. package/dist/color.test.d.ts +2 -0
  47. package/dist/color.test.d.ts.map +1 -0
  48. package/dist/color.test.js +161 -0
  49. package/dist/color.test.js.map +1 -0
  50. package/dist/config-provider.d.ts +57 -0
  51. package/dist/config-provider.d.ts.map +1 -0
  52. package/dist/config-provider.js +49 -0
  53. package/dist/config-provider.js.map +1 -0
  54. package/dist/config-provider.test.d.ts +2 -0
  55. package/dist/config-provider.test.d.ts.map +1 -0
  56. package/dist/config-provider.test.js +76 -0
  57. package/dist/config-provider.test.js.map +1 -0
  58. package/dist/copyable.d.ts +43 -0
  59. package/dist/copyable.d.ts.map +1 -0
  60. package/dist/copyable.js +102 -0
  61. package/dist/copyable.js.map +1 -0
  62. package/dist/copyable.test.d.ts +2 -0
  63. package/dist/copyable.test.d.ts.map +1 -0
  64. package/dist/copyable.test.js +97 -0
  65. package/dist/copyable.test.js.map +1 -0
  66. package/dist/date.d.ts +86 -0
  67. package/dist/date.d.ts.map +1 -0
  68. package/dist/date.js +226 -0
  69. package/dist/date.js.map +1 -0
  70. package/dist/date.test.d.ts +2 -0
  71. package/dist/date.test.d.ts.map +1 -0
  72. package/dist/date.test.js +171 -0
  73. package/dist/date.test.js.map +1 -0
  74. package/dist/dismiss.d.ts +28 -0
  75. package/dist/dismiss.d.ts.map +1 -0
  76. package/dist/dismiss.js +42 -0
  77. package/dist/dismiss.js.map +1 -0
  78. package/dist/editable.d.ts +59 -0
  79. package/dist/editable.d.ts.map +1 -0
  80. package/dist/editable.js +85 -0
  81. package/dist/editable.js.map +1 -0
  82. package/dist/editable.test.d.ts +2 -0
  83. package/dist/editable.test.d.ts.map +1 -0
  84. package/dist/editable.test.js +111 -0
  85. package/dist/editable.test.js.map +1 -0
  86. package/dist/ellipsis.d.ts +76 -0
  87. package/dist/ellipsis.d.ts.map +1 -0
  88. package/dist/ellipsis.js +99 -0
  89. package/dist/ellipsis.js.map +1 -0
  90. package/dist/ellipsis.test.d.ts +2 -0
  91. package/dist/ellipsis.test.d.ts.map +1 -0
  92. package/dist/ellipsis.test.js +94 -0
  93. package/dist/ellipsis.test.js.map +1 -0
  94. package/dist/floating.d.ts +78 -0
  95. package/dist/floating.d.ts.map +1 -0
  96. package/dist/floating.js +169 -0
  97. package/dist/floating.js.map +1 -0
  98. package/dist/floating.test.d.ts +2 -0
  99. package/dist/floating.test.d.ts.map +1 -0
  100. package/dist/floating.test.js +169 -0
  101. package/dist/floating.test.js.map +1 -0
  102. package/dist/focus-trap.d.ts +24 -0
  103. package/dist/focus-trap.d.ts.map +1 -0
  104. package/dist/focus-trap.js +64 -0
  105. package/dist/focus-trap.js.map +1 -0
  106. package/dist/form.d.ts +131 -0
  107. package/dist/form.d.ts.map +1 -0
  108. package/dist/form.js +257 -0
  109. package/dist/form.js.map +1 -0
  110. package/dist/form.test.d.ts +2 -0
  111. package/dist/form.test.d.ts.map +1 -0
  112. package/dist/form.test.js +323 -0
  113. package/dist/form.test.js.map +1 -0
  114. package/dist/highlight.d.ts +57 -0
  115. package/dist/highlight.d.ts.map +1 -0
  116. package/dist/highlight.js +124 -0
  117. package/dist/highlight.js.map +1 -0
  118. package/dist/highlight.test.d.ts +2 -0
  119. package/dist/highlight.test.d.ts.map +1 -0
  120. package/dist/highlight.test.js +155 -0
  121. package/dist/highlight.test.js.map +1 -0
  122. package/dist/id.d.ts +4 -0
  123. package/dist/id.d.ts.map +1 -0
  124. package/dist/id.js +14 -0
  125. package/dist/id.js.map +1 -0
  126. package/dist/id.test.d.ts +2 -0
  127. package/dist/id.test.d.ts.map +1 -0
  128. package/dist/id.test.js +13 -0
  129. package/dist/id.test.js.map +1 -0
  130. package/dist/index.d.ts +46 -0
  131. package/dist/index.d.ts.map +1 -0
  132. package/dist/index.js +45 -0
  133. package/dist/index.js.map +1 -0
  134. package/dist/inert-background.d.ts +27 -0
  135. package/dist/inert-background.d.ts.map +1 -0
  136. package/dist/inert-background.js +92 -0
  137. package/dist/inert-background.js.map +1 -0
  138. package/dist/inert-background.test.d.ts +2 -0
  139. package/dist/inert-background.test.d.ts.map +1 -0
  140. package/dist/inert-background.test.js +62 -0
  141. package/dist/inert-background.test.js.map +1 -0
  142. package/dist/input-number.d.ts +34 -0
  143. package/dist/input-number.d.ts.map +1 -0
  144. package/dist/input-number.js +69 -0
  145. package/dist/input-number.js.map +1 -0
  146. package/dist/input-number.test.d.ts +2 -0
  147. package/dist/input-number.test.d.ts.map +1 -0
  148. package/dist/input-number.test.js +74 -0
  149. package/dist/input-number.test.js.map +1 -0
  150. package/dist/list-selection.d.ts +38 -0
  151. package/dist/list-selection.d.ts.map +1 -0
  152. package/dist/list-selection.js +61 -0
  153. package/dist/list-selection.js.map +1 -0
  154. package/dist/list-selection.test.d.ts +2 -0
  155. package/dist/list-selection.test.d.ts.map +1 -0
  156. package/dist/list-selection.test.js +61 -0
  157. package/dist/list-selection.test.js.map +1 -0
  158. package/dist/live-announcer.d.ts +38 -0
  159. package/dist/live-announcer.d.ts.map +1 -0
  160. package/dist/live-announcer.js +89 -0
  161. package/dist/live-announcer.js.map +1 -0
  162. package/dist/live-announcer.test.d.ts +2 -0
  163. package/dist/live-announcer.test.d.ts.map +1 -0
  164. package/dist/live-announcer.test.js +70 -0
  165. package/dist/live-announcer.test.js.map +1 -0
  166. package/dist/lottie-icon.d.ts +88 -0
  167. package/dist/lottie-icon.d.ts.map +1 -0
  168. package/dist/lottie-icon.js +84 -0
  169. package/dist/lottie-icon.js.map +1 -0
  170. package/dist/lottie-icon.test.d.ts +2 -0
  171. package/dist/lottie-icon.test.d.ts.map +1 -0
  172. package/dist/lottie-icon.test.js +88 -0
  173. package/dist/lottie-icon.test.js.map +1 -0
  174. package/dist/notification.d.ts +61 -0
  175. package/dist/notification.d.ts.map +1 -0
  176. package/dist/notification.js +133 -0
  177. package/dist/notification.js.map +1 -0
  178. package/dist/notification.test.d.ts +2 -0
  179. package/dist/notification.test.d.ts.map +1 -0
  180. package/dist/notification.test.js +103 -0
  181. package/dist/notification.test.js.map +1 -0
  182. package/dist/overflow-list.d.ts +102 -0
  183. package/dist/overflow-list.d.ts.map +1 -0
  184. package/dist/overflow-list.js +159 -0
  185. package/dist/overflow-list.js.map +1 -0
  186. package/dist/overflow-list.test.d.ts +2 -0
  187. package/dist/overflow-list.test.d.ts.map +1 -0
  188. package/dist/overflow-list.test.js +223 -0
  189. package/dist/overflow-list.test.js.map +1 -0
  190. package/dist/pagination.d.ts +51 -0
  191. package/dist/pagination.d.ts.map +1 -0
  192. package/dist/pagination.js +127 -0
  193. package/dist/pagination.js.map +1 -0
  194. package/dist/pagination.test.d.ts +2 -0
  195. package/dist/pagination.test.d.ts.map +1 -0
  196. package/dist/pagination.test.js +147 -0
  197. package/dist/pagination.test.js.map +1 -0
  198. package/dist/progress.d.ts +64 -0
  199. package/dist/progress.d.ts.map +1 -0
  200. package/dist/progress.js +92 -0
  201. package/dist/progress.js.map +1 -0
  202. package/dist/progress.test.d.ts +2 -0
  203. package/dist/progress.test.d.ts.map +1 -0
  204. package/dist/progress.test.js +79 -0
  205. package/dist/progress.test.js.map +1 -0
  206. package/dist/resize-observer.d.ts +133 -0
  207. package/dist/resize-observer.d.ts.map +1 -0
  208. package/dist/resize-observer.js +358 -0
  209. package/dist/resize-observer.js.map +1 -0
  210. package/dist/resize-observer.test.d.ts +2 -0
  211. package/dist/resize-observer.test.d.ts.map +1 -0
  212. package/dist/resize-observer.test.js +377 -0
  213. package/dist/resize-observer.test.js.map +1 -0
  214. package/dist/roving.d.ts +26 -0
  215. package/dist/roving.d.ts.map +1 -0
  216. package/dist/roving.js +61 -0
  217. package/dist/roving.js.map +1 -0
  218. package/dist/roving.test.d.ts +2 -0
  219. package/dist/roving.test.d.ts.map +1 -0
  220. package/dist/roving.test.js +48 -0
  221. package/dist/roving.test.js.map +1 -0
  222. package/dist/scroll-list.d.ts +81 -0
  223. package/dist/scroll-list.d.ts.map +1 -0
  224. package/dist/scroll-list.js +175 -0
  225. package/dist/scroll-list.js.map +1 -0
  226. package/dist/scroll-list.test.d.ts +2 -0
  227. package/dist/scroll-list.test.d.ts.map +1 -0
  228. package/dist/scroll-list.test.js +135 -0
  229. package/dist/scroll-list.test.js.map +1 -0
  230. package/dist/scroll-lock.d.ts +11 -0
  231. package/dist/scroll-lock.d.ts.map +1 -0
  232. package/dist/scroll-lock.js +45 -0
  233. package/dist/scroll-lock.js.map +1 -0
  234. package/dist/scroll-lock.test.d.ts +2 -0
  235. package/dist/scroll-lock.test.d.ts.map +1 -0
  236. package/dist/scroll-lock.test.js +55 -0
  237. package/dist/scroll-lock.test.js.map +1 -0
  238. package/dist/sider.d.ts +26 -0
  239. package/dist/sider.d.ts.map +1 -0
  240. package/dist/sider.js +55 -0
  241. package/dist/sider.js.map +1 -0
  242. package/dist/sider.test.d.ts +2 -0
  243. package/dist/sider.test.d.ts.map +1 -0
  244. package/dist/sider.test.js +29 -0
  245. package/dist/sider.test.js.map +1 -0
  246. package/dist/spin.d.ts +25 -0
  247. package/dist/spin.d.ts.map +1 -0
  248. package/dist/spin.js +96 -0
  249. package/dist/spin.js.map +1 -0
  250. package/dist/spin.test.d.ts +2 -0
  251. package/dist/spin.test.d.ts.map +1 -0
  252. package/dist/spin.test.js +80 -0
  253. package/dist/spin.test.js.map +1 -0
  254. package/dist/table.d.ts +101 -0
  255. package/dist/table.d.ts.map +1 -0
  256. package/dist/table.js +244 -0
  257. package/dist/table.js.map +1 -0
  258. package/dist/table.test.d.ts +2 -0
  259. package/dist/table.test.d.ts.map +1 -0
  260. package/dist/table.test.js +184 -0
  261. package/dist/table.test.js.map +1 -0
  262. package/dist/textarea.d.ts +48 -0
  263. package/dist/textarea.d.ts.map +1 -0
  264. package/dist/textarea.js +76 -0
  265. package/dist/textarea.js.map +1 -0
  266. package/dist/textarea.test.d.ts +2 -0
  267. package/dist/textarea.test.d.ts.map +1 -0
  268. package/dist/textarea.test.js +77 -0
  269. package/dist/textarea.test.js.map +1 -0
  270. package/dist/time.d.ts +93 -0
  271. package/dist/time.d.ts.map +1 -0
  272. package/dist/time.js +181 -0
  273. package/dist/time.js.map +1 -0
  274. package/dist/time.test.d.ts +2 -0
  275. package/dist/time.test.d.ts.map +1 -0
  276. package/dist/time.test.js +159 -0
  277. package/dist/time.test.js.map +1 -0
  278. package/dist/toast.d.ts +60 -0
  279. package/dist/toast.d.ts.map +1 -0
  280. package/dist/toast.js +135 -0
  281. package/dist/toast.js.map +1 -0
  282. package/dist/toast.test.d.ts +2 -0
  283. package/dist/toast.test.d.ts.map +1 -0
  284. package/dist/toast.test.js +127 -0
  285. package/dist/toast.test.js.map +1 -0
  286. package/dist/tree.d.ts +129 -0
  287. package/dist/tree.d.ts.map +1 -0
  288. package/dist/tree.js +351 -0
  289. package/dist/tree.js.map +1 -0
  290. package/dist/tree.test.d.ts +2 -0
  291. package/dist/tree.test.d.ts.map +1 -0
  292. package/dist/tree.test.js +291 -0
  293. package/dist/tree.test.js.map +1 -0
  294. package/dist/upload.d.ts +62 -0
  295. package/dist/upload.d.ts.map +1 -0
  296. package/dist/upload.js +85 -0
  297. package/dist/upload.js.map +1 -0
  298. package/dist/upload.test.d.ts +2 -0
  299. package/dist/upload.test.d.ts.map +1 -0
  300. package/dist/upload.test.js +169 -0
  301. package/dist/upload.test.js.map +1 -0
  302. package/dist/virtual-list.d.ts +83 -0
  303. package/dist/virtual-list.d.ts.map +1 -0
  304. package/dist/virtual-list.js +143 -0
  305. package/dist/virtual-list.js.map +1 -0
  306. package/dist/virtual-list.test.d.ts +2 -0
  307. package/dist/virtual-list.test.d.ts.map +1 -0
  308. package/dist/virtual-list.test.js +148 -0
  309. package/dist/virtual-list.test.js.map +1 -0
  310. package/package.json +22 -0
package/dist/color.js ADDED
@@ -0,0 +1,217 @@
1
+ /**
2
+ * 颜色空间转换纯函数(framework-agnostic)。
3
+ * 红线 #2:转换为纯函数,渲染层只做格式化派生。
4
+ * 角度 h: 0-360;s/v/l/a: 0-1;r/g/b: 0-255。
5
+ */
6
+ export function clamp01(n) {
7
+ return Math.min(1, Math.max(0, n));
8
+ }
9
+ function clampByte(n) {
10
+ return Math.min(255, Math.max(0, Math.round(n)));
11
+ }
12
+ /** 解析 hex 字符串(#rgb / #rgba / #rrggbb / #rrggbbaa,带不带 # 均可)。失败返回 null。 */
13
+ export function parseHex(input) {
14
+ let h = input.trim().replace(/^#/, '');
15
+ if (/^[0-9a-fA-F]{3}$/.test(h) || /^[0-9a-fA-F]{4}$/.test(h)) {
16
+ h = h
17
+ .split('')
18
+ .map((c) => c + c)
19
+ .join('');
20
+ }
21
+ if (/^[0-9a-fA-F]{6}$/.test(h)) {
22
+ return {
23
+ r: parseInt(h.slice(0, 2), 16),
24
+ g: parseInt(h.slice(2, 4), 16),
25
+ b: parseInt(h.slice(4, 6), 16),
26
+ a: 1,
27
+ };
28
+ }
29
+ if (/^[0-9a-fA-F]{8}$/.test(h)) {
30
+ return {
31
+ r: parseInt(h.slice(0, 2), 16),
32
+ g: parseInt(h.slice(2, 4), 16),
33
+ b: parseInt(h.slice(4, 6), 16),
34
+ a: parseInt(h.slice(6, 8), 16) / 255,
35
+ };
36
+ }
37
+ return null;
38
+ }
39
+ function toHex2(n) {
40
+ return clampByte(n).toString(16).padStart(2, '0');
41
+ }
42
+ /** RGB → hex 字符串。 */
43
+ export function rgbToHex(rgb, options = {}) {
44
+ const { alpha = true, uppercase = true } = options;
45
+ let out = `#${toHex2(rgb.r)}${toHex2(rgb.g)}${toHex2(rgb.b)}`;
46
+ if (alpha && rgb.a < 1)
47
+ out += toHex2(rgb.a * 255);
48
+ return uppercase ? out.toUpperCase() : out.toLowerCase();
49
+ }
50
+ /** RGB → HSV。 */
51
+ export function rgbToHsv(rgb) {
52
+ const r = rgb.r / 255;
53
+ const g = rgb.g / 255;
54
+ const b = rgb.b / 255;
55
+ const maxC = Math.max(r, g, b);
56
+ const minC = Math.min(r, g, b);
57
+ const delta = maxC - minC;
58
+ let h = 0;
59
+ if (delta !== 0) {
60
+ if (maxC === r)
61
+ h = ((g - b) / delta) % 6;
62
+ else if (maxC === g)
63
+ h = (b - r) / delta + 2;
64
+ else
65
+ h = (r - g) / delta + 4;
66
+ h *= 60;
67
+ if (h < 0)
68
+ h += 360;
69
+ }
70
+ const s = maxC === 0 ? 0 : delta / maxC;
71
+ const v = maxC;
72
+ return { h, s, v, a: rgb.a };
73
+ }
74
+ /** HSV → RGB。 */
75
+ export function hsvToRgb({ h, s, v, a }) {
76
+ const hh = ((h % 360) + 360) % 360;
77
+ const c = v * s;
78
+ const x = c * (1 - Math.abs(((hh / 60) % 2) - 1));
79
+ const m = v - c;
80
+ let rgb;
81
+ if (hh < 60)
82
+ rgb = [c, x, 0];
83
+ else if (hh < 120)
84
+ rgb = [x, c, 0];
85
+ else if (hh < 180)
86
+ rgb = [0, c, x];
87
+ else if (hh < 240)
88
+ rgb = [0, x, c];
89
+ else if (hh < 300)
90
+ rgb = [x, 0, c];
91
+ else
92
+ rgb = [c, 0, x];
93
+ const [r, g, b] = rgb;
94
+ return {
95
+ r: clampByte((r + m) * 255),
96
+ g: clampByte((g + m) * 255),
97
+ b: clampByte((b + m) * 255),
98
+ a,
99
+ };
100
+ }
101
+ /** HSV → HSL(同一色相,转换 s/l)。 */
102
+ export function hsvToHsl({ h, s, v, a }) {
103
+ const l = v * (1 - s / 2);
104
+ const sl = l === 0 || l === 1 ? 0 : (v - l) / Math.min(l, 1 - l);
105
+ return { h, s: sl, l, a };
106
+ }
107
+ /** HSL → HSV。 */
108
+ export function hslToHsv({ h, s, l, a }) {
109
+ const v = l + s * Math.min(l, 1 - l);
110
+ const sv = v === 0 ? 0 : 2 * (1 - l / v);
111
+ return { h, s: sv, v, a };
112
+ }
113
+ /** RGB → HSL(经 HSV 桥接)。 */
114
+ export function rgbToHsl(rgb) {
115
+ return hsvToHsl(rgbToHsv(rgb));
116
+ }
117
+ /** HSL → RGB(经 HSV 桥接)。 */
118
+ export function hslToRgb(hsl) {
119
+ return hsvToRgb(hslToHsv(hsl));
120
+ }
121
+ /** hex → HSV。失败返回黑色不透明。 */
122
+ export function hexToHsv(hex) {
123
+ const rgb = parseHex(hex);
124
+ if (!rgb)
125
+ return { h: 0, s: 0, v: 0, a: 1 };
126
+ return rgbToHsv(rgb);
127
+ }
128
+ /** HSV → hex。 */
129
+ export function hsvToHex(hsv, options) {
130
+ return rgbToHex(hsvToRgb(hsv), options);
131
+ }
132
+ /**
133
+ * 把 HSV 状态格式化为指定 format 的可读字符串(用于输入框显示)。
134
+ * rgb: rgb(r, g, b) / rgba(r, g, b, a)
135
+ * hsv: hsv(h, s%, v%) / hsva(h, s%, v%, a)
136
+ * hsl: hsl(h, s%, l%) / hsla(h, s%, l%, a)
137
+ */
138
+ export function formatColor(hsv, format, options = {}) {
139
+ const { uppercase = true } = options;
140
+ const showAlpha = options.alpha ?? hsv.a < 1;
141
+ const round = (n) => Math.round(n);
142
+ const roundA = (n) => Math.round(n * 100) / 100;
143
+ switch (format) {
144
+ case 'rgb': {
145
+ const { r, g, b, a } = hsvToRgb(hsv);
146
+ return showAlpha
147
+ ? `rgba(${r}, ${g}, ${b}, ${roundA(a)})`
148
+ : `rgb(${r}, ${g}, ${b})`;
149
+ }
150
+ case 'hsv': {
151
+ const h = round(hsv.h);
152
+ const s = round(hsv.s * 100);
153
+ const v = round(hsv.v * 100);
154
+ return showAlpha
155
+ ? `hsva(${h}, ${s}%, ${v}%, ${roundA(hsv.a)})`
156
+ : `hsv(${h}, ${s}%, ${v}%)`;
157
+ }
158
+ case 'hsl': {
159
+ const hsl = hsvToHsl(hsv);
160
+ const h = round(hsl.h);
161
+ const s = round(hsl.s * 100);
162
+ const l = round(hsl.l * 100);
163
+ return showAlpha
164
+ ? `hsla(${h}, ${s}%, ${l}%, ${roundA(hsl.a)})`
165
+ : `hsl(${h}, ${s}%, ${l}%)`;
166
+ }
167
+ case 'hex':
168
+ default:
169
+ return hsvToHex(hsv, { alpha: showAlpha, uppercase });
170
+ }
171
+ }
172
+ /**
173
+ * 解析任意 format 的输入字符串为 HSV。失败返回 null(不改值)。
174
+ * 兼容 hex / rgb()/rgba() / hsv()/hsva() / hsl()/hsla(),逗号或空格分隔均可。
175
+ */
176
+ export function parseColor(input, format) {
177
+ const str = input.trim();
178
+ // hex 始终尝试(最常见)
179
+ if (format === 'hex') {
180
+ const rgb = parseHex(str);
181
+ return rgb ? rgbToHsv(rgb) : null;
182
+ }
183
+ const nums = (str.match(/-?\d*\.?\d+/g) ?? []).map(Number);
184
+ // 数字不足以构成目标格式时,退化尝试把输入当 hex 解析(用户可能粘了 hex)。
185
+ if (nums.length < 3) {
186
+ const rgb = parseHex(str);
187
+ return rgb ? rgbToHsv(rgb) : null;
188
+ }
189
+ const c0 = nums[0];
190
+ const c1 = nums[1];
191
+ const c2 = nums[2];
192
+ const alphaVal = nums.length >= 4 ? clamp01(nums[3]) : 1;
193
+ if (format === 'rgb') {
194
+ return rgbToHsv({
195
+ r: clampByte(c0),
196
+ g: clampByte(c1),
197
+ b: clampByte(c2),
198
+ a: alphaVal,
199
+ });
200
+ }
201
+ if (format === 'hsv') {
202
+ return {
203
+ h: ((c0 % 360) + 360) % 360,
204
+ s: clamp01(c1 / 100),
205
+ v: clamp01(c2 / 100),
206
+ a: alphaVal,
207
+ };
208
+ }
209
+ // hsl
210
+ return hslToHsv({
211
+ h: ((c0 % 360) + 360) % 360,
212
+ s: clamp01(c1 / 100),
213
+ l: clamp01(c2 / 100),
214
+ a: alphaVal,
215
+ });
216
+ }
217
+ //# sourceMappingURL=color.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"color.js","sourceRoot":"","sources":["../src/color.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAyBH,MAAM,UAAU,OAAO,CAAC,CAAS;IAC/B,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AACrC,CAAC;AAED,SAAS,SAAS,CAAC,CAAS;IAC1B,OAAO,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACnD,CAAC;AAED,yEAAyE;AACzE,MAAM,UAAU,QAAQ,CAAC,KAAa;IACpC,IAAI,CAAC,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;IACvC,IAAI,kBAAkB,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,kBAAkB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;QAC7D,CAAC,GAAG,CAAC;aACF,KAAK,CAAC,EAAE,CAAC;aACT,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC;aACjB,IAAI,CAAC,EAAE,CAAC,CAAC;IACd,CAAC;IACD,IAAI,kBAAkB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;QAC/B,OAAO;YACL,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC;YAC9B,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC;YAC9B,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC;YAC9B,CAAC,EAAE,CAAC;SACL,CAAC;IACJ,CAAC;IACD,IAAI,kBAAkB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;QAC/B,OAAO;YACL,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC;YAC9B,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC;YAC9B,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC;YAC9B,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG;SACrC,CAAC;IACJ,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,MAAM,CAAC,CAAS;IACvB,OAAO,SAAS,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;AACpD,CAAC;AASD,qBAAqB;AACrB,MAAM,UAAU,QAAQ,CAAC,GAAQ,EAAE,UAA2B,EAAE;IAC9D,MAAM,EAAE,KAAK,GAAG,IAAI,EAAE,SAAS,GAAG,IAAI,EAAE,GAAG,OAAO,CAAC;IACnD,IAAI,GAAG,GAAG,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;IAC9D,IAAI,KAAK,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC;QAAE,GAAG,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC;IACnD,OAAO,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC;AAC3D,CAAC;AAED,iBAAiB;AACjB,MAAM,UAAU,QAAQ,CAAC,GAAQ;IAC/B,MAAM,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC;IACtB,MAAM,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC;IACtB,MAAM,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC;IACtB,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;IAC/B,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;IAC/B,MAAM,KAAK,GAAG,IAAI,GAAG,IAAI,CAAC;IAC1B,IAAI,CAAC,GAAG,CAAC,CAAC;IACV,IAAI,KAAK,KAAK,CAAC,EAAE,CAAC;QAChB,IAAI,IAAI,KAAK,CAAC;YAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC;aACrC,IAAI,IAAI,KAAK,CAAC;YAAE,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,KAAK,GAAG,CAAC,CAAC;;YACxC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,KAAK,GAAG,CAAC,CAAC;QAC7B,CAAC,IAAI,EAAE,CAAC;QACR,IAAI,CAAC,GAAG,CAAC;YAAE,CAAC,IAAI,GAAG,CAAC;IACtB,CAAC;IACD,MAAM,CAAC,GAAG,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,IAAI,CAAC;IACxC,MAAM,CAAC,GAAG,IAAI,CAAC;IACf,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE,CAAC;AAC/B,CAAC;AAED,iBAAiB;AACjB,MAAM,UAAU,QAAQ,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAO;IAC1C,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,GAAG,GAAG,CAAC,GAAG,GAAG,CAAC;IACnC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAChB,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IAClD,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAChB,IAAI,GAA6B,CAAC;IAClC,IAAI,EAAE,GAAG,EAAE;QAAE,GAAG,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;SACxB,IAAI,EAAE,GAAG,GAAG;QAAE,GAAG,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;SAC9B,IAAI,EAAE,GAAG,GAAG;QAAE,GAAG,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;SAC9B,IAAI,EAAE,GAAG,GAAG;QAAE,GAAG,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;SAC9B,IAAI,EAAE,GAAG,GAAG;QAAE,GAAG,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;;QAC9B,GAAG,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;IACrB,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,GAAG,GAAG,CAAC;IACtB,OAAO;QACL,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC;QAC3B,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC;QAC3B,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC;QAC3B,CAAC;KACF,CAAC;AACJ,CAAC;AAED,8BAA8B;AAC9B,MAAM,UAAU,QAAQ,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAO;IAC1C,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;IAC1B,MAAM,EAAE,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACjE,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC;AAC5B,CAAC;AAED,iBAAiB;AACjB,MAAM,UAAU,QAAQ,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAO;IAC1C,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACrC,MAAM,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;IACzC,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC;AAC5B,CAAC;AAED,2BAA2B;AAC3B,MAAM,UAAU,QAAQ,CAAC,GAAQ;IAC/B,OAAO,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC;AACjC,CAAC;AAED,2BAA2B;AAC3B,MAAM,UAAU,QAAQ,CAAC,GAAQ;IAC/B,OAAO,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC;AACjC,CAAC;AAED,2BAA2B;AAC3B,MAAM,UAAU,QAAQ,CAAC,GAAW;IAClC,MAAM,GAAG,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC;IAC1B,IAAI,CAAC,GAAG;QAAE,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC;IAC5C,OAAO,QAAQ,CAAC,GAAG,CAAC,CAAC;AACvB,CAAC;AAED,iBAAiB;AACjB,MAAM,UAAU,QAAQ,CAAC,GAAQ,EAAE,OAAyB;IAC1D,OAAO,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC,CAAC;AAC1C,CAAC;AASD;;;;;GAKG;AACH,MAAM,UAAU,WAAW,CACzB,GAAQ,EACR,MAAmB,EACnB,UAAyB,EAAE;IAE3B,MAAM,EAAE,SAAS,GAAG,IAAI,EAAE,GAAG,OAAO,CAAC;IACrC,MAAM,SAAS,GAAG,OAAO,CAAC,KAAK,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;IAC7C,MAAM,KAAK,GAAG,CAAC,CAAS,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAC3C,MAAM,MAAM,GAAG,CAAC,CAAS,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,GAAG,CAAC,GAAG,GAAG,CAAC;IACxD,QAAQ,MAAM,EAAE,CAAC;QACf,KAAK,KAAK,CAAC,CAAC,CAAC;YACX,MAAM,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC;YACrC,OAAO,SAAS;gBACd,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,MAAM,CAAC,CAAC,CAAC,GAAG;gBACxC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC;QAC9B,CAAC;QACD,KAAK,KAAK,CAAC,CAAC,CAAC;YACX,MAAM,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;YACvB,MAAM,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC;YAC7B,MAAM,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC;YAC7B,OAAO,SAAS;gBACd,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG;gBAC9C,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC;QAChC,CAAC;QACD,KAAK,KAAK,CAAC,CAAC,CAAC;YACX,MAAM,GAAG,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC;YAC1B,MAAM,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;YACvB,MAAM,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC;YAC7B,MAAM,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC;YAC7B,OAAO,SAAS;gBACd,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG;gBAC9C,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC;QAChC,CAAC;QACD,KAAK,KAAK,CAAC;QACX;YACE,OAAO,QAAQ,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,CAAC,CAAC;IAC1D,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,UAAU,CAAC,KAAa,EAAE,MAAmB;IAC3D,MAAM,GAAG,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;IACzB,gBAAgB;IAChB,IAAI,MAAM,KAAK,KAAK,EAAE,CAAC;QACrB,MAAM,GAAG,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC;QAC1B,OAAO,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACpC,CAAC;IACD,MAAM,IAAI,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,cAAc,CAAC,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IAC3D,4CAA4C;IAC5C,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACpB,MAAM,GAAG,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC;QAC1B,OAAO,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACpC,CAAC;IACD,MAAM,EAAE,GAAG,IAAI,CAAC,CAAC,CAAE,CAAC;IACpB,MAAM,EAAE,GAAG,IAAI,CAAC,CAAC,CAAE,CAAC;IACpB,MAAM,EAAE,GAAG,IAAI,CAAC,CAAC,CAAE,CAAC;IACpB,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC1D,IAAI,MAAM,KAAK,KAAK,EAAE,CAAC;QACrB,OAAO,QAAQ,CAAC;YACd,CAAC,EAAE,SAAS,CAAC,EAAE,CAAC;YAChB,CAAC,EAAE,SAAS,CAAC,EAAE,CAAC;YAChB,CAAC,EAAE,SAAS,CAAC,EAAE,CAAC;YAChB,CAAC,EAAE,QAAQ;SACZ,CAAC,CAAC;IACL,CAAC;IACD,IAAI,MAAM,KAAK,KAAK,EAAE,CAAC;QACrB,OAAO;YACL,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,GAAG,CAAC,GAAG,GAAG,CAAC,GAAG,GAAG;YAC3B,CAAC,EAAE,OAAO,CAAC,EAAE,GAAG,GAAG,CAAC;YACpB,CAAC,EAAE,OAAO,CAAC,EAAE,GAAG,GAAG,CAAC;YACpB,CAAC,EAAE,QAAQ;SACZ,CAAC;IACJ,CAAC;IACD,MAAM;IACN,OAAO,QAAQ,CAAC;QACd,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,GAAG,CAAC,GAAG,GAAG,CAAC,GAAG,GAAG;QAC3B,CAAC,EAAE,OAAO,CAAC,EAAE,GAAG,GAAG,CAAC;QACpB,CAAC,EAAE,OAAO,CAAC,EAAE,GAAG,GAAG,CAAC;QACpB,CAAC,EAAE,QAAQ;KACZ,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=color.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"color.test.d.ts","sourceRoot":"","sources":["../src/color.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,161 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import { parseHex, rgbToHex, rgbToHsv, hsvToRgb, hsvToHsl, hslToHsv, rgbToHsl, hslToRgb, hexToHsv, hsvToHex, formatColor, parseColor, clamp01, } from './color.js';
3
+ describe('clamp01', () => {
4
+ it('clamps to [0,1]', () => {
5
+ expect(clamp01(-1)).toBe(0);
6
+ expect(clamp01(2)).toBe(1);
7
+ expect(clamp01(0.5)).toBe(0.5);
8
+ });
9
+ });
10
+ describe('parseHex', () => {
11
+ it('parses 6-digit hex', () => {
12
+ expect(parseHex('#ff0000')).toEqual({ r: 255, g: 0, b: 0, a: 1 });
13
+ });
14
+ it('parses without #', () => {
15
+ expect(parseHex('00ff00')).toEqual({ r: 0, g: 255, b: 0, a: 1 });
16
+ });
17
+ it('expands 3-digit hex', () => {
18
+ expect(parseHex('#f00')).toEqual({ r: 255, g: 0, b: 0, a: 1 });
19
+ });
20
+ it('expands 4-digit hex with alpha', () => {
21
+ expect(parseHex('#f008')?.a).toBeCloseTo(0x88 / 255, 5);
22
+ });
23
+ it('parses 8-digit hex alpha', () => {
24
+ expect(parseHex('#0000ff80')?.a).toBeCloseTo(0x80 / 255, 5);
25
+ });
26
+ it('returns null on garbage', () => {
27
+ expect(parseHex('nope')).toBeNull();
28
+ expect(parseHex('#12345')).toBeNull();
29
+ });
30
+ });
31
+ describe('rgbToHex', () => {
32
+ it('formats uppercase by default', () => {
33
+ expect(rgbToHex({ r: 255, g: 0, b: 0, a: 1 })).toBe('#FF0000');
34
+ });
35
+ it('lowercase option', () => {
36
+ expect(rgbToHex({ r: 255, g: 0, b: 0, a: 1 }, { uppercase: false })).toBe('#ff0000');
37
+ });
38
+ it('appends alpha when a<1', () => {
39
+ expect(rgbToHex({ r: 0, g: 0, b: 0, a: 0.5 })).toBe('#00000080');
40
+ });
41
+ it('omits alpha when alpha:false', () => {
42
+ expect(rgbToHex({ r: 0, g: 0, b: 0, a: 0.5 }, { alpha: false })).toBe('#000000');
43
+ });
44
+ });
45
+ describe('rgb <-> hsv', () => {
46
+ it('red round-trips', () => {
47
+ const hsv = rgbToHsv({ r: 255, g: 0, b: 0, a: 1 });
48
+ expect(hsv.h).toBeCloseTo(0, 5);
49
+ expect(hsv.s).toBeCloseTo(1, 5);
50
+ expect(hsv.v).toBeCloseTo(1, 5);
51
+ expect(hsvToRgb(hsv)).toEqual({ r: 255, g: 0, b: 0, a: 1 });
52
+ });
53
+ it('green hue is 120', () => {
54
+ expect(rgbToHsv({ r: 0, g: 255, b: 0, a: 1 }).h).toBeCloseTo(120, 5);
55
+ });
56
+ it('blue hue is 240', () => {
57
+ expect(rgbToHsv({ r: 0, g: 0, b: 255, a: 1 }).h).toBeCloseTo(240, 5);
58
+ });
59
+ it('white has s=0 v=1', () => {
60
+ const hsv = rgbToHsv({ r: 255, g: 255, b: 255, a: 1 });
61
+ expect(hsv.s).toBe(0);
62
+ expect(hsv.v).toBeCloseTo(1, 5);
63
+ });
64
+ it('arbitrary color round-trips within rounding', () => {
65
+ const orig = { r: 123, g: 45, b: 200, a: 0.7 };
66
+ const back = hsvToRgb(rgbToHsv(orig));
67
+ expect(back.r).toBeCloseTo(123, 0);
68
+ expect(back.g).toBeCloseTo(45, 0);
69
+ expect(back.b).toBeCloseTo(200, 0);
70
+ expect(back.a).toBeCloseTo(0.7, 5);
71
+ });
72
+ });
73
+ describe('hsv <-> hsl', () => {
74
+ it('red hsv -> hsl', () => {
75
+ const hsl = hsvToHsl({ h: 0, s: 1, v: 1, a: 1 });
76
+ expect(hsl.h).toBe(0);
77
+ expect(hsl.s).toBeCloseTo(1, 5);
78
+ expect(hsl.l).toBeCloseTo(0.5, 5);
79
+ });
80
+ it('round-trips', () => {
81
+ const hsv = { h: 210, s: 0.6, v: 0.8, a: 0.5 };
82
+ const back = hslToHsv(hsvToHsl(hsv));
83
+ expect(back.h).toBeCloseTo(hsv.h, 5);
84
+ expect(back.s).toBeCloseTo(hsv.s, 5);
85
+ expect(back.v).toBeCloseTo(hsv.v, 5);
86
+ expect(back.a).toBeCloseTo(hsv.a, 5);
87
+ });
88
+ });
89
+ describe('rgb <-> hsl bridges', () => {
90
+ it('rgbToHsl red', () => {
91
+ const hsl = rgbToHsl({ r: 255, g: 0, b: 0, a: 1 });
92
+ expect(hsl.l).toBeCloseTo(0.5, 5);
93
+ });
94
+ it('hslToRgb round-trip', () => {
95
+ const back = hslToRgb(rgbToHsl({ r: 12, g: 200, b: 99, a: 1 }));
96
+ expect(back.r).toBeCloseTo(12, 0);
97
+ expect(back.g).toBeCloseTo(200, 0);
98
+ expect(back.b).toBeCloseTo(99, 0);
99
+ });
100
+ });
101
+ describe('hex <-> hsv helpers', () => {
102
+ it('hexToHsv invalid -> black', () => {
103
+ expect(hexToHsv('zzz')).toEqual({ h: 0, s: 0, v: 0, a: 1 });
104
+ });
105
+ it('hsvToHex red', () => {
106
+ expect(hsvToHex({ h: 0, s: 1, v: 1, a: 1 })).toBe('#FF0000');
107
+ });
108
+ });
109
+ describe('formatColor', () => {
110
+ const red = { h: 0, s: 1, v: 1, a: 1 };
111
+ const semiRed = { h: 0, s: 1, v: 1, a: 0.5 };
112
+ it('hex', () => {
113
+ expect(formatColor(red, 'hex')).toBe('#FF0000');
114
+ });
115
+ it('rgb', () => {
116
+ expect(formatColor(red, 'rgb')).toBe('rgb(255, 0, 0)');
117
+ });
118
+ it('rgba when alpha<1', () => {
119
+ expect(formatColor(semiRed, 'rgb')).toBe('rgba(255, 0, 0, 0.5)');
120
+ });
121
+ it('hsv', () => {
122
+ expect(formatColor(red, 'hsv')).toBe('hsv(0, 100%, 100%)');
123
+ });
124
+ it('hsl', () => {
125
+ expect(formatColor(red, 'hsl')).toBe('hsl(0, 100%, 50%)');
126
+ });
127
+ it('hsla when alpha<1', () => {
128
+ expect(formatColor(semiRed, 'hsl')).toBe('hsla(0, 100%, 50%, 0.5)');
129
+ });
130
+ });
131
+ describe('parseColor', () => {
132
+ it('parses rgb()', () => {
133
+ const hsv = parseColor('rgb(255, 0, 0)', 'rgb');
134
+ expect(hsv).not.toBeNull();
135
+ expect(hsvToHex(hsv)).toBe('#FF0000');
136
+ });
137
+ it('parses rgba()', () => {
138
+ const hsv = parseColor('rgba(0, 0, 0, 0.5)', 'rgb');
139
+ expect(hsv?.a).toBeCloseTo(0.5, 5);
140
+ });
141
+ it('parses hsl()', () => {
142
+ const hsv = parseColor('hsl(120, 100%, 50%)', 'hsl');
143
+ expect(hsvToHex(hsv)).toBe('#00FF00');
144
+ });
145
+ it('parses hsv()', () => {
146
+ const hsv = parseColor('hsv(240, 100%, 100%)', 'hsv');
147
+ expect(hsvToHex(hsv)).toBe('#0000FF');
148
+ });
149
+ it('parses hex in hex mode', () => {
150
+ expect(hsvToHex(parseColor('#00ff00', 'hex'))).toBe('#00FF00');
151
+ });
152
+ it('falls back to hex when non-hex mode gets a hex string', () => {
153
+ const hsv = parseColor('#0000ff', 'rgb');
154
+ expect(hsvToHex(hsv)).toBe('#0000FF');
155
+ });
156
+ it('returns null on garbage', () => {
157
+ expect(parseColor('nope', 'hex')).toBeNull();
158
+ expect(parseColor('rgb(1, 2)', 'rgb')).toBeNull();
159
+ });
160
+ });
161
+ //# sourceMappingURL=color.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"color.test.js","sourceRoot":"","sources":["../src/color.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,57 @@
1
+ /**
2
+ * createConfigProvider helpers — framework-agnostic config merge logic.
3
+ * Pure functions only: shallow-merge a child config over a parent so that
4
+ * `undefined` fields inherit from the parent (nearest-wins). The svelte layer
5
+ * owns context injection. See specs/components/other/ConfigProvider.spec.md §3.
6
+ */
7
+ /**
8
+ * 主题:'auto' 跟随系统 prefers-color-scheme 自动在 light/dark 间切换。
9
+ * 'light' | 'dark' 行为完全不变(向后兼容)。
10
+ */
11
+ export type ConfigTheme = 'light' | 'dark' | 'auto';
12
+ /** 实际落到 DOM 的主题(auto 解析后只会是这两者之一)。 */
13
+ export type AppliedTheme = 'light' | 'dark';
14
+ export type ConfigDir = 'ltr' | 'rtl';
15
+ export type ConfigSize = 'small' | 'default' | 'large';
16
+ /**
17
+ * 降级动画开关:true 强制降级、false 强制开启、'auto' 跟随系统
18
+ * prefers-reduced-motion。
19
+ */
20
+ export type ReducedMotionInput = boolean | 'auto';
21
+ /** A partial config as passed to a ConfigProvider (undefined = inherit). */
22
+ export interface ConfigInput {
23
+ theme?: ConfigTheme;
24
+ dir?: ConfigDir;
25
+ size?: ConfigSize;
26
+ zIndexBase?: number;
27
+ transition?: boolean;
28
+ reducedMotion?: ReducedMotionInput;
29
+ }
30
+ /** A fully-resolved config (every field present). */
31
+ export interface ResolvedConfig {
32
+ theme: ConfigTheme;
33
+ dir: ConfigDir;
34
+ size: ConfigSize;
35
+ zIndexBase: number;
36
+ transition: boolean;
37
+ reducedMotion: ReducedMotionInput;
38
+ }
39
+ export declare const DEFAULT_CONFIG: ResolvedConfig;
40
+ /**
41
+ * Shallow-merge a child config over a resolved parent: each field of `child`
42
+ * overrides the parent only when explicitly provided (not undefined), so
43
+ * omitting a field inherits the parent's value.
44
+ */
45
+ export declare function mergeConfig(parent: ResolvedConfig, child: ConfigInput): ResolvedConfig;
46
+ /**
47
+ * 把配置主题解析为实际落到 DOM 的主题:'auto' 时跟随系统是否偏好暗色,
48
+ * 其余原样返回。纯函数(红线 #2),不读 window,系统态由调用方注入。
49
+ */
50
+ export declare function resolveAppliedTheme(theme: ConfigTheme, systemPrefersDark: boolean): AppliedTheme;
51
+ /**
52
+ * 解析最终是否降级动画:显式 boolean 优先,'auto' 跟随系统
53
+ * prefers-reduced-motion。纯函数(红线 #2),系统态由调用方注入。
54
+ * 返回 true 表示应降级(reduce)。
55
+ */
56
+ export declare function resolveReducedMotion(input: ReducedMotionInput, systemReduced: boolean): boolean;
57
+ //# sourceMappingURL=config-provider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-provider.d.ts","sourceRoot":"","sources":["../src/config-provider.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;;GAGG;AACH,MAAM,MAAM,WAAW,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,CAAC;AACpD,sCAAsC;AACtC,MAAM,MAAM,YAAY,GAAG,OAAO,GAAG,MAAM,CAAC;AAC5C,MAAM,MAAM,SAAS,GAAG,KAAK,GAAG,KAAK,CAAC;AACtC,MAAM,MAAM,UAAU,GAAG,OAAO,GAAG,SAAS,GAAG,OAAO,CAAC;AACvD;;;GAGG;AACH,MAAM,MAAM,kBAAkB,GAAG,OAAO,GAAG,MAAM,CAAC;AAElD,4EAA4E;AAC5E,MAAM,WAAW,WAAW;IAC1B,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,GAAG,CAAC,EAAE,SAAS,CAAC;IAChB,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,aAAa,CAAC,EAAE,kBAAkB,CAAC;CACpC;AAED,qDAAqD;AACrD,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,WAAW,CAAC;IACnB,GAAG,EAAE,SAAS,CAAC;IACf,IAAI,EAAE,UAAU,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,OAAO,CAAC;IACpB,aAAa,EAAE,kBAAkB,CAAC;CACnC;AAED,eAAO,MAAM,cAAc,EAAE,cAO5B,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,cAAc,EAAE,KAAK,EAAE,WAAW,GAAG,cAAc,CAStF;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,WAAW,EAAE,iBAAiB,EAAE,OAAO,GAAG,YAAY,CAGhG;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,kBAAkB,EAAE,aAAa,EAAE,OAAO,GAAG,OAAO,CAG/F"}
@@ -0,0 +1,49 @@
1
+ /**
2
+ * createConfigProvider helpers — framework-agnostic config merge logic.
3
+ * Pure functions only: shallow-merge a child config over a parent so that
4
+ * `undefined` fields inherit from the parent (nearest-wins). The svelte layer
5
+ * owns context injection. See specs/components/other/ConfigProvider.spec.md §3.
6
+ */
7
+ export const DEFAULT_CONFIG = {
8
+ theme: 'light',
9
+ dir: 'ltr',
10
+ size: 'default',
11
+ zIndexBase: 1000,
12
+ transition: true,
13
+ reducedMotion: 'auto',
14
+ };
15
+ /**
16
+ * Shallow-merge a child config over a resolved parent: each field of `child`
17
+ * overrides the parent only when explicitly provided (not undefined), so
18
+ * omitting a field inherits the parent's value.
19
+ */
20
+ export function mergeConfig(parent, child) {
21
+ return {
22
+ theme: child.theme ?? parent.theme,
23
+ dir: child.dir ?? parent.dir,
24
+ size: child.size ?? parent.size,
25
+ zIndexBase: child.zIndexBase ?? parent.zIndexBase,
26
+ transition: child.transition ?? parent.transition,
27
+ reducedMotion: child.reducedMotion ?? parent.reducedMotion,
28
+ };
29
+ }
30
+ /**
31
+ * 把配置主题解析为实际落到 DOM 的主题:'auto' 时跟随系统是否偏好暗色,
32
+ * 其余原样返回。纯函数(红线 #2),不读 window,系统态由调用方注入。
33
+ */
34
+ export function resolveAppliedTheme(theme, systemPrefersDark) {
35
+ if (theme === 'auto')
36
+ return systemPrefersDark ? 'dark' : 'light';
37
+ return theme;
38
+ }
39
+ /**
40
+ * 解析最终是否降级动画:显式 boolean 优先,'auto' 跟随系统
41
+ * prefers-reduced-motion。纯函数(红线 #2),系统态由调用方注入。
42
+ * 返回 true 表示应降级(reduce)。
43
+ */
44
+ export function resolveReducedMotion(input, systemReduced) {
45
+ if (typeof input === 'boolean')
46
+ return input;
47
+ return systemReduced;
48
+ }
49
+ //# sourceMappingURL=config-provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-provider.js","sourceRoot":"","sources":["../src/config-provider.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAqCH,MAAM,CAAC,MAAM,cAAc,GAAmB;IAC5C,KAAK,EAAE,OAAO;IACd,GAAG,EAAE,KAAK;IACV,IAAI,EAAE,SAAS;IACf,UAAU,EAAE,IAAI;IAChB,UAAU,EAAE,IAAI;IAChB,aAAa,EAAE,MAAM;CACtB,CAAC;AAEF;;;;GAIG;AACH,MAAM,UAAU,WAAW,CAAC,MAAsB,EAAE,KAAkB;IACpE,OAAO;QACL,KAAK,EAAE,KAAK,CAAC,KAAK,IAAI,MAAM,CAAC,KAAK;QAClC,GAAG,EAAE,KAAK,CAAC,GAAG,IAAI,MAAM,CAAC,GAAG;QAC5B,IAAI,EAAE,KAAK,CAAC,IAAI,IAAI,MAAM,CAAC,IAAI;QAC/B,UAAU,EAAE,KAAK,CAAC,UAAU,IAAI,MAAM,CAAC,UAAU;QACjD,UAAU,EAAE,KAAK,CAAC,UAAU,IAAI,MAAM,CAAC,UAAU;QACjD,aAAa,EAAE,KAAK,CAAC,aAAa,IAAI,MAAM,CAAC,aAAa;KAC3D,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,mBAAmB,CAAC,KAAkB,EAAE,iBAA0B;IAChF,IAAI,KAAK,KAAK,MAAM;QAAE,OAAO,iBAAiB,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC;IAClE,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,oBAAoB,CAAC,KAAyB,EAAE,aAAsB;IACpF,IAAI,OAAO,KAAK,KAAK,SAAS;QAAE,OAAO,KAAK,CAAC;IAC7C,OAAO,aAAa,CAAC;AACvB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=config-provider.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-provider.test.d.ts","sourceRoot":"","sources":["../src/config-provider.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,76 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import { mergeConfig, DEFAULT_CONFIG, resolveAppliedTheme, resolveReducedMotion, } from './config-provider.js';
3
+ describe('mergeConfig', () => {
4
+ it('returns parent values when child provides nothing', () => {
5
+ expect(mergeConfig(DEFAULT_CONFIG, {})).toEqual(DEFAULT_CONFIG);
6
+ });
7
+ it('overrides only explicitly-provided fields', () => {
8
+ const merged = mergeConfig(DEFAULT_CONFIG, { theme: 'dark' });
9
+ expect(merged.theme).toBe('dark');
10
+ expect(merged.dir).toBe('ltr'); // inherited
11
+ expect(merged.size).toBe('default'); // inherited
12
+ });
13
+ it('omitted fields inherit the parent (not overwritten)', () => {
14
+ const parent = { ...DEFAULT_CONFIG, theme: 'dark', size: 'large' };
15
+ // child omits theme/size entirely → they inherit
16
+ const merged = mergeConfig(parent, { dir: 'rtl' });
17
+ expect(merged.theme).toBe('dark'); // inherited
18
+ expect(merged.dir).toBe('rtl'); // overridden
19
+ expect(merged.size).toBe('large'); // inherited
20
+ });
21
+ it('nested merge: inner only overrides dir, keeps outer theme/locale-adjacent fields', () => {
22
+ const outer = mergeConfig(DEFAULT_CONFIG, { theme: 'dark', size: 'small' });
23
+ const inner = mergeConfig(outer, { dir: 'rtl' });
24
+ expect(inner).toEqual({
25
+ theme: 'dark',
26
+ dir: 'rtl',
27
+ size: 'small',
28
+ zIndexBase: 1000,
29
+ transition: true,
30
+ reducedMotion: 'auto',
31
+ });
32
+ });
33
+ it('merges numeric and boolean fields', () => {
34
+ const merged = mergeConfig(DEFAULT_CONFIG, { zIndexBase: 2000, transition: false });
35
+ expect(merged.zIndexBase).toBe(2000);
36
+ expect(merged.transition).toBe(false);
37
+ // transition:false must override (not be treated as "missing" by ??)
38
+ expect(mergeConfig({ ...DEFAULT_CONFIG, transition: false }, {}).transition).toBe(false);
39
+ });
40
+ it('default reducedMotion is auto; inherits and overrides', () => {
41
+ expect(DEFAULT_CONFIG.reducedMotion).toBe('auto');
42
+ expect(mergeConfig(DEFAULT_CONFIG, {}).reducedMotion).toBe('auto');
43
+ expect(mergeConfig(DEFAULT_CONFIG, { reducedMotion: true }).reducedMotion).toBe(true);
44
+ // reducedMotion:false must override auto (not be treated as missing by ??)
45
+ expect(mergeConfig({ ...DEFAULT_CONFIG, reducedMotion: 'auto' }, { reducedMotion: false }).reducedMotion).toBe(false);
46
+ });
47
+ it('theme=auto inherits/overrides like other fields', () => {
48
+ expect(mergeConfig(DEFAULT_CONFIG, { theme: 'auto' }).theme).toBe('auto');
49
+ // inner auto over outer dark wins (nearest)
50
+ const outer = mergeConfig(DEFAULT_CONFIG, { theme: 'dark' });
51
+ expect(mergeConfig(outer, { theme: 'auto' }).theme).toBe('auto');
52
+ });
53
+ });
54
+ describe('resolveAppliedTheme', () => {
55
+ it('passes through light/dark regardless of system', () => {
56
+ expect(resolveAppliedTheme('light', true)).toBe('light');
57
+ expect(resolveAppliedTheme('light', false)).toBe('light');
58
+ expect(resolveAppliedTheme('dark', false)).toBe('dark');
59
+ expect(resolveAppliedTheme('dark', true)).toBe('dark');
60
+ });
61
+ it('auto follows system prefers-color-scheme', () => {
62
+ expect(resolveAppliedTheme('auto', true)).toBe('dark');
63
+ expect(resolveAppliedTheme('auto', false)).toBe('light');
64
+ });
65
+ });
66
+ describe('resolveReducedMotion', () => {
67
+ it('explicit boolean wins over system', () => {
68
+ expect(resolveReducedMotion(true, false)).toBe(true);
69
+ expect(resolveReducedMotion(false, true)).toBe(false);
70
+ });
71
+ it('auto follows system prefers-reduced-motion', () => {
72
+ expect(resolveReducedMotion('auto', true)).toBe(true);
73
+ expect(resolveReducedMotion('auto', false)).toBe(false);
74
+ });
75
+ });
76
+ //# sourceMappingURL=config-provider.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-provider.test.js","sourceRoot":"","sources":["../src/config-provider.test.ts"],"names":[],"mappings":"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"}