@fab1o978/react-ui 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 (58) hide show
  1. package/README.md +73 -0
  2. package/dist/components/Badge/index.cjs +47 -0
  3. package/dist/components/Badge/index.cjs.map +1 -0
  4. package/dist/components/Badge/index.css +112 -0
  5. package/dist/components/Badge/index.css.map +1 -0
  6. package/dist/components/Badge/index.d.cts +14 -0
  7. package/dist/components/Badge/index.d.ts +14 -0
  8. package/dist/components/Badge/index.js +45 -0
  9. package/dist/components/Badge/index.js.map +1 -0
  10. package/dist/components/Button/index.cjs +64 -0
  11. package/dist/components/Button/index.cjs.map +1 -0
  12. package/dist/components/Button/index.css +159 -0
  13. package/dist/components/Button/index.css.map +1 -0
  14. package/dist/components/Button/index.d.cts +13 -0
  15. package/dist/components/Button/index.d.ts +13 -0
  16. package/dist/components/Button/index.js +58 -0
  17. package/dist/components/Button/index.js.map +1 -0
  18. package/dist/components/ColorPicker/index.cjs +523 -0
  19. package/dist/components/ColorPicker/index.cjs.map +1 -0
  20. package/dist/components/ColorPicker/index.css +308 -0
  21. package/dist/components/ColorPicker/index.css.map +1 -0
  22. package/dist/components/ColorPicker/index.d.cts +35 -0
  23. package/dist/components/ColorPicker/index.d.ts +35 -0
  24. package/dist/components/ColorPicker/index.js +521 -0
  25. package/dist/components/ColorPicker/index.js.map +1 -0
  26. package/dist/components/Input/index.cjs +86 -0
  27. package/dist/components/Input/index.cjs.map +1 -0
  28. package/dist/components/Input/index.css +170 -0
  29. package/dist/components/Input/index.css.map +1 -0
  30. package/dist/components/Input/index.d.cts +15 -0
  31. package/dist/components/Input/index.d.ts +15 -0
  32. package/dist/components/Input/index.js +80 -0
  33. package/dist/components/Input/index.js.map +1 -0
  34. package/dist/components/RainCanvas/index.cjs +227 -0
  35. package/dist/components/RainCanvas/index.cjs.map +1 -0
  36. package/dist/components/RainCanvas/index.css +32 -0
  37. package/dist/components/RainCanvas/index.css.map +1 -0
  38. package/dist/components/RainCanvas/index.d.cts +12 -0
  39. package/dist/components/RainCanvas/index.d.ts +12 -0
  40. package/dist/components/RainCanvas/index.js +225 -0
  41. package/dist/components/RainCanvas/index.js.map +1 -0
  42. package/dist/components/Timeline/index.cjs +169 -0
  43. package/dist/components/Timeline/index.cjs.map +1 -0
  44. package/dist/components/Timeline/index.css +247 -0
  45. package/dist/components/Timeline/index.css.map +1 -0
  46. package/dist/components/Timeline/index.d.cts +22 -0
  47. package/dist/components/Timeline/index.d.ts +22 -0
  48. package/dist/components/Timeline/index.js +167 -0
  49. package/dist/components/Timeline/index.js.map +1 -0
  50. package/dist/index.cjs +993 -0
  51. package/dist/index.cjs.map +1 -0
  52. package/dist/index.css +1019 -0
  53. package/dist/index.css.map +1 -0
  54. package/dist/index.d.cts +7 -0
  55. package/dist/index.d.ts +7 -0
  56. package/dist/index.js +982 -0
  57. package/dist/index.js.map +1 -0
  58. package/package.json +69 -0
package/dist/index.cjs ADDED
@@ -0,0 +1,993 @@
1
+ 'use strict';
2
+
3
+ var React = require('react');
4
+ var jsxRuntime = require('react/jsx-runtime');
5
+
6
+ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
7
+
8
+ var React__default = /*#__PURE__*/_interopDefault(React);
9
+
10
+ // src/components/Button/Button.tsx
11
+
12
+ // src/components/Button/Button.module.scss
13
+ var Button_module_default = {
14
+ button: "Button_module_button",
15
+ primary: "Button_module_primary",
16
+ secondary: "Button_module_secondary",
17
+ danger: "Button_module_danger",
18
+ ghost: "Button_module_ghost",
19
+ sm: "Button_module_sm",
20
+ md: "Button_module_md",
21
+ lg: "Button_module_lg",
22
+ fullWidth: "Button_module_fullWidth",
23
+ loading: "Button_module_loading",
24
+ spinner: "Button_module_spinner",
25
+ spin: "Button_module_spin"
26
+ };
27
+ var Button = React__default.default.forwardRef(
28
+ ({
29
+ variant = "primary",
30
+ size = "md",
31
+ loading = false,
32
+ fullWidth = false,
33
+ disabled,
34
+ children,
35
+ className,
36
+ ...props
37
+ }, ref) => {
38
+ return /* @__PURE__ */ jsxRuntime.jsxs(
39
+ "button",
40
+ {
41
+ ref,
42
+ disabled: disabled || loading,
43
+ className: [
44
+ Button_module_default.button,
45
+ Button_module_default[variant],
46
+ Button_module_default[size],
47
+ fullWidth ? Button_module_default.fullWidth : "",
48
+ loading ? Button_module_default.loading : "",
49
+ className ?? ""
50
+ ].filter(Boolean).join(" "),
51
+ ...props,
52
+ children: [
53
+ loading && /* @__PURE__ */ jsxRuntime.jsx("span", { className: Button_module_default.spinner, "aria-hidden": "true" }),
54
+ children
55
+ ]
56
+ }
57
+ );
58
+ }
59
+ );
60
+ Button.displayName = "Button";
61
+
62
+ // src/components/Input/Input.module.scss
63
+ var Input_module_default = {
64
+ wrapper: "Input_module_wrapper",
65
+ fullWidth: "Input_module_fullWidth",
66
+ label: "Input_module_label",
67
+ inputWrapper: "Input_module_inputWrapper",
68
+ input: "Input_module_input",
69
+ error: "Input_module_error",
70
+ sm: "Input_module_sm",
71
+ md: "Input_module_md",
72
+ lg: "Input_module_lg",
73
+ adornment: "Input_module_adornment",
74
+ adornmentEnd: "Input_module_adornmentEnd",
75
+ withStart: "Input_module_withStart",
76
+ withEnd: "Input_module_withEnd",
77
+ helperText: "Input_module_helperText",
78
+ errorText: "Input_module_errorText"
79
+ };
80
+ var Input = React__default.default.forwardRef(
81
+ ({
82
+ label,
83
+ helperText,
84
+ errorText,
85
+ size = "md",
86
+ fullWidth = false,
87
+ startAdornment,
88
+ endAdornment,
89
+ id,
90
+ className,
91
+ ...props
92
+ }, ref) => {
93
+ const inputId = id ?? (label ? label.toLowerCase().replace(/\s+/g, "-") : void 0);
94
+ const hasError = Boolean(errorText);
95
+ return /* @__PURE__ */ jsxRuntime.jsxs(
96
+ "div",
97
+ {
98
+ className: [
99
+ Input_module_default.wrapper,
100
+ fullWidth ? Input_module_default.fullWidth : ""
101
+ ].filter(Boolean).join(" "),
102
+ children: [
103
+ label && /* @__PURE__ */ jsxRuntime.jsx("label", { htmlFor: inputId, className: Input_module_default.label, children: label }),
104
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: [Input_module_default.inputWrapper, Input_module_default[size]].join(" "), children: [
105
+ startAdornment && /* @__PURE__ */ jsxRuntime.jsx("span", { className: Input_module_default.adornment, children: startAdornment }),
106
+ /* @__PURE__ */ jsxRuntime.jsx(
107
+ "input",
108
+ {
109
+ ref,
110
+ id: inputId,
111
+ className: [
112
+ Input_module_default.input,
113
+ hasError ? Input_module_default.error : "",
114
+ startAdornment ? Input_module_default.withStart : "",
115
+ endAdornment ? Input_module_default.withEnd : "",
116
+ className ?? ""
117
+ ].filter(Boolean).join(" "),
118
+ "aria-invalid": hasError,
119
+ "aria-describedby": errorText ? `${inputId}-error` : helperText ? `${inputId}-helper` : void 0,
120
+ ...props
121
+ }
122
+ ),
123
+ endAdornment && /* @__PURE__ */ jsxRuntime.jsx("span", { className: [Input_module_default.adornment, Input_module_default.adornmentEnd].join(" "), children: endAdornment })
124
+ ] }),
125
+ errorText && /* @__PURE__ */ jsxRuntime.jsx("span", { id: `${inputId}-error`, className: Input_module_default.errorText, children: errorText }),
126
+ helperText && !errorText && /* @__PURE__ */ jsxRuntime.jsx("span", { id: `${inputId}-helper`, className: Input_module_default.helperText, children: helperText })
127
+ ]
128
+ }
129
+ );
130
+ }
131
+ );
132
+ Input.displayName = "Input";
133
+
134
+ // src/components/Badge/Badge.module.scss
135
+ var Badge_module_default = {
136
+ badge: "Badge_module_badge",
137
+ sm: "Badge_module_sm",
138
+ md: "Badge_module_md",
139
+ default: "Badge_module_default",
140
+ primary: "Badge_module_primary",
141
+ success: "Badge_module_success",
142
+ warning: "Badge_module_warning",
143
+ danger: "Badge_module_danger",
144
+ dotIndicator: "Badge_module_dotIndicator"
145
+ };
146
+ var Badge = ({
147
+ variant = "default",
148
+ size = "md",
149
+ dot = false,
150
+ children,
151
+ className
152
+ }) => {
153
+ return /* @__PURE__ */ jsxRuntime.jsxs(
154
+ "span",
155
+ {
156
+ className: [
157
+ Badge_module_default.badge,
158
+ Badge_module_default[variant],
159
+ Badge_module_default[size],
160
+ dot ? Badge_module_default.dot : "",
161
+ className ?? ""
162
+ ].filter(Boolean).join(" "),
163
+ children: [
164
+ dot && /* @__PURE__ */ jsxRuntime.jsx("span", { className: Badge_module_default.dotIndicator, "aria-hidden": "true" }),
165
+ children
166
+ ]
167
+ }
168
+ );
169
+ };
170
+
171
+ // src/components/RainCanvas/RainCanvas.module.scss
172
+ var RainCanvas_module_default = {
173
+ wrapper: "RainCanvas_module_wrapper",
174
+ trailCanvas: "RainCanvas_module_trailCanvas",
175
+ content: "RainCanvas_module_content",
176
+ dropContainer: "RainCanvas_module_dropContainer"
177
+ };
178
+ var _nextId = 0;
179
+ function randomBetween(a, b) {
180
+ return a + Math.random() * (b - a);
181
+ }
182
+ function createStaticDrop(width, height) {
183
+ return {
184
+ id: _nextId++,
185
+ kind: "static",
186
+ x: randomBetween(10, width - 10),
187
+ y: randomBetween(10, height - 10),
188
+ radius: randomBetween(4, 11),
189
+ age: 0,
190
+ maxAge: randomBetween(120, 400),
191
+ speed: 0,
192
+ trail: []
193
+ };
194
+ }
195
+ var RainCanvas = ({
196
+ dropCount = 55,
197
+ background = "linear-gradient(160deg, #0f172a 0%, #1e3a5f 60%, #0f2a4a 100%)",
198
+ children,
199
+ className,
200
+ style
201
+ }) => {
202
+ const wrapperRef = React.useRef(null);
203
+ const trailCanvasRef = React.useRef(null);
204
+ const dropContainerRef = React.useRef(null);
205
+ const dropsRef = React.useRef([]);
206
+ const nodeMapRef = React.useRef(/* @__PURE__ */ new Map());
207
+ const rafRef = React.useRef(0);
208
+ const filterIdRef = React.useRef(`rnf-${Math.random().toString(36).slice(2, 7)}`);
209
+ React.useEffect(() => {
210
+ const wrapper = wrapperRef.current;
211
+ const trailCanvas = trailCanvasRef.current;
212
+ const dropContainer = dropContainerRef.current;
213
+ if (!wrapper || !trailCanvas || !dropContainer) return;
214
+ const trailCtx = trailCanvas.getContext("2d");
215
+ if (!trailCtx) return;
216
+ const filterId2 = filterIdRef.current;
217
+ const resize = () => {
218
+ const w = wrapper.offsetWidth;
219
+ const h = wrapper.offsetHeight;
220
+ trailCanvas.width = w;
221
+ trailCanvas.height = h;
222
+ dropsRef.current = Array.from(
223
+ { length: dropCount },
224
+ () => createStaticDrop(w, h)
225
+ );
226
+ };
227
+ resize();
228
+ const ro = new ResizeObserver(resize);
229
+ ro.observe(wrapper);
230
+ function getOrCreateNode(drop) {
231
+ let node = nodeMapRef.current.get(drop.id);
232
+ if (!node) {
233
+ node = document.createElement("div");
234
+ node.style.cssText = `
235
+ position: absolute;
236
+ backdrop-filter: url(#${filterId2}) brightness(1.12);
237
+ -webkit-backdrop-filter: url(#${filterId2}) brightness(1.12);
238
+ box-shadow:
239
+ inset 0 0 0 1px rgba(255,255,255,0.4),
240
+ inset -2px -3px 6px rgba(255,255,255,0.18),
241
+ inset 2px 2px 4px rgba(0, 40, 120, 0.15);
242
+ background: radial-gradient(
243
+ circle at 32% 30%,
244
+ rgba(255,255,255,0.30) 0%,
245
+ rgba(255,255,255,0.05) 45%,
246
+ transparent 65%
247
+ );
248
+ pointer-events: none;
249
+ will-change: transform;
250
+ `;
251
+ dropContainer.appendChild(node);
252
+ nodeMapRef.current.set(drop.id, node);
253
+ }
254
+ return node;
255
+ }
256
+ function removeNode(id) {
257
+ const node = nodeMapRef.current.get(id);
258
+ if (node) {
259
+ node.remove();
260
+ nodeMapRef.current.delete(id);
261
+ }
262
+ }
263
+ function syncNode(drop) {
264
+ const node = getOrCreateNode(drop);
265
+ const isSliding = drop.kind === "sliding";
266
+ const h = isSliding ? drop.radius * 2.4 : drop.radius * 2;
267
+ const br = isSliding ? "50% 50% 55% 55%" : "50%";
268
+ node.style.left = `${drop.x - drop.radius}px`;
269
+ node.style.top = `${drop.y - drop.radius}px`;
270
+ node.style.width = `${drop.radius * 2}px`;
271
+ node.style.height = `${h}px`;
272
+ node.style.borderRadius = br;
273
+ }
274
+ const tick = () => {
275
+ const { width, height } = trailCanvas;
276
+ trailCtx.fillStyle = "rgba(0,0,0,0.04)";
277
+ trailCtx.fillRect(0, 0, width, height);
278
+ const next = [];
279
+ for (const drop of dropsRef.current) {
280
+ if (drop.kind === "static") {
281
+ drop.age++;
282
+ syncNode(drop);
283
+ if (drop.age >= drop.maxAge) {
284
+ removeNode(drop.id);
285
+ next.push({
286
+ ...drop,
287
+ id: _nextId++,
288
+ kind: "sliding",
289
+ speed: randomBetween(1.5, 3.5),
290
+ trail: []
291
+ });
292
+ } else {
293
+ next.push(drop);
294
+ }
295
+ } else {
296
+ drop.trail.push({ x: drop.x, y: drop.y });
297
+ if (drop.trail.length > 24) drop.trail.shift();
298
+ if (drop.trail.length > 1) {
299
+ trailCtx.beginPath();
300
+ trailCtx.moveTo(drop.trail[0].x, drop.trail[0].y);
301
+ for (let i = 1; i < drop.trail.length; i++) {
302
+ trailCtx.lineTo(drop.trail[i].x, drop.trail[i].y);
303
+ }
304
+ trailCtx.strokeStyle = "rgba(160, 200, 255, 0.18)";
305
+ trailCtx.lineWidth = drop.radius * 0.7;
306
+ trailCtx.lineCap = "round";
307
+ trailCtx.stroke();
308
+ }
309
+ drop.y += drop.speed;
310
+ drop.speed += 0.06;
311
+ syncNode(drop);
312
+ if (drop.y - drop.radius > height) {
313
+ removeNode(drop.id);
314
+ next.push(createStaticDrop(width, height));
315
+ } else {
316
+ next.push(drop);
317
+ }
318
+ }
319
+ }
320
+ dropsRef.current = next;
321
+ rafRef.current = requestAnimationFrame(tick);
322
+ };
323
+ rafRef.current = requestAnimationFrame(tick);
324
+ return () => {
325
+ cancelAnimationFrame(rafRef.current);
326
+ ro.disconnect();
327
+ nodeMapRef.current.forEach((node) => node.remove());
328
+ nodeMapRef.current.clear();
329
+ };
330
+ }, [dropCount]);
331
+ const filterId = filterIdRef.current;
332
+ return /* @__PURE__ */ jsxRuntime.jsxs(
333
+ "div",
334
+ {
335
+ ref: wrapperRef,
336
+ className: [RainCanvas_module_default.wrapper, className ?? ""].filter(Boolean).join(" "),
337
+ style: { background, ...style },
338
+ children: [
339
+ /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "0", height: "0", style: { position: "absolute" }, children: /* @__PURE__ */ jsxRuntime.jsx("defs", { children: /* @__PURE__ */ jsxRuntime.jsxs(
340
+ "filter",
341
+ {
342
+ id: filterId,
343
+ x: "-20%",
344
+ y: "-20%",
345
+ width: "140%",
346
+ height: "140%",
347
+ colorInterpolationFilters: "sRGB",
348
+ children: [
349
+ /* @__PURE__ */ jsxRuntime.jsx(
350
+ "feTurbulence",
351
+ {
352
+ type: "turbulence",
353
+ baseFrequency: "0.07 0.04",
354
+ numOctaves: "2",
355
+ result: "noise",
356
+ children: /* @__PURE__ */ jsxRuntime.jsx(
357
+ "animate",
358
+ {
359
+ attributeName: "seed",
360
+ values: "1;20;1",
361
+ dur: "5s",
362
+ repeatCount: "indefinite"
363
+ }
364
+ )
365
+ }
366
+ ),
367
+ /* @__PURE__ */ jsxRuntime.jsx(
368
+ "feDisplacementMap",
369
+ {
370
+ in: "SourceGraphic",
371
+ in2: "noise",
372
+ scale: "22",
373
+ xChannelSelector: "R",
374
+ yChannelSelector: "G"
375
+ }
376
+ )
377
+ ]
378
+ }
379
+ ) }) }),
380
+ /* @__PURE__ */ jsxRuntime.jsx("canvas", { ref: trailCanvasRef, className: RainCanvas_module_default.trailCanvas }),
381
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: RainCanvas_module_default.content, children }),
382
+ /* @__PURE__ */ jsxRuntime.jsx("div", { ref: dropContainerRef, className: RainCanvas_module_default.dropContainer })
383
+ ]
384
+ }
385
+ );
386
+ };
387
+
388
+ // src/components/Timeline/Timeline.module.scss
389
+ var Timeline_module_default = {
390
+ timeline: "Timeline_module_timeline",
391
+ vertical: "Timeline_module_vertical",
392
+ item: "Timeline_module_item",
393
+ track: "Timeline_module_track",
394
+ connector: "Timeline_module_connector",
395
+ content: "Timeline_module_content",
396
+ last: "Timeline_module_last",
397
+ horizontal: "Timeline_module_horizontal",
398
+ dot: "Timeline_module_dot",
399
+ iconSlot: "Timeline_module_iconSlot",
400
+ completed: "Timeline_module_completed",
401
+ dotIn: "Timeline_module_dotIn",
402
+ active: "Timeline_module_active",
403
+ pulse: "Timeline_module_pulse",
404
+ pending: "Timeline_module_pending",
405
+ label: "Timeline_module_label",
406
+ title: "Timeline_module_title",
407
+ description: "Timeline_module_description",
408
+ connectorHidden: "Timeline_module_connectorHidden",
409
+ connectorDone: "Timeline_module_connectorDone"
410
+ };
411
+
412
+ // src/utils/color.ts
413
+ function hexToHsl(hex) {
414
+ const r = parseInt(hex.slice(1, 3), 16) / 255;
415
+ const g = parseInt(hex.slice(3, 5), 16) / 255;
416
+ const b = parseInt(hex.slice(5, 7), 16) / 255;
417
+ const max = Math.max(r, g, b);
418
+ const min = Math.min(r, g, b);
419
+ const l = (max + min) / 2;
420
+ let h = 0;
421
+ let s = 0;
422
+ if (max !== min) {
423
+ const d = max - min;
424
+ s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
425
+ switch (max) {
426
+ case r:
427
+ h = ((g - b) / d + (g < b ? 6 : 0)) / 6;
428
+ break;
429
+ case g:
430
+ h = ((b - r) / d + 2) / 6;
431
+ break;
432
+ case b:
433
+ h = ((r - g) / d + 4) / 6;
434
+ break;
435
+ }
436
+ }
437
+ return [h * 360, s * 100, l * 100];
438
+ }
439
+ function hslToHex(h, s, l) {
440
+ const sl = s / 100;
441
+ const ll = l / 100;
442
+ const a = sl * Math.min(ll, 1 - ll);
443
+ const f = (n) => {
444
+ const k = (n + h / 30) % 12;
445
+ const color = ll - a * Math.max(Math.min(k - 3, 9 - k, 1), -1);
446
+ return Math.round(255 * color).toString(16).padStart(2, "0");
447
+ };
448
+ return `#${f(0)}${f(8)}${f(4)}`;
449
+ }
450
+ function hslToRgb(h, s, l) {
451
+ const sl = s / 100;
452
+ const ll = l / 100;
453
+ const a = sl * Math.min(ll, 1 - ll);
454
+ const f = (n) => {
455
+ const k = (n + h / 30) % 12;
456
+ return Math.round(255 * (ll - a * Math.max(Math.min(k - 3, 9 - k, 1), -1)));
457
+ };
458
+ return { r: f(0), g: f(8), b: f(4) };
459
+ }
460
+ function rgbToHsl(r, g, b) {
461
+ const rr = r / 255, gg = g / 255, bb = b / 255;
462
+ const max = Math.max(rr, gg, bb);
463
+ const min = Math.min(rr, gg, bb);
464
+ const l = (max + min) / 2;
465
+ let h = 0, s = 0;
466
+ if (max !== min) {
467
+ const d = max - min;
468
+ s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
469
+ switch (max) {
470
+ case rr:
471
+ h = ((gg - bb) / d + (gg < bb ? 6 : 0)) / 6;
472
+ break;
473
+ case gg:
474
+ h = ((bb - rr) / d + 2) / 6;
475
+ break;
476
+ case bb:
477
+ h = ((rr - gg) / d + 4) / 6;
478
+ break;
479
+ }
480
+ }
481
+ return [h * 360, s * 100, l * 100];
482
+ }
483
+ function hslToRgba(h, s, l, alpha) {
484
+ const { r, g, b } = hslToRgb(h, s, l);
485
+ return `rgba(${r}, ${g}, ${b}, ${alpha})`;
486
+ }
487
+ function buildColorValue(h, s, l, a) {
488
+ const { r, g, b } = hslToRgb(h, s, l);
489
+ const hex = hslToHex(h, s, l);
490
+ const alphaHex = Math.round(a * 255).toString(16).padStart(2, "0");
491
+ const hR = Math.round(h), sR = Math.round(s), lR = Math.round(l);
492
+ const aR = Math.round(a * 100) / 100;
493
+ return {
494
+ hex,
495
+ hexa: `${hex}${alphaHex}`,
496
+ hsl: `hsl(${hR}, ${sR}%, ${lR}%)`,
497
+ hsla: `hsla(${hR}, ${sR}%, ${lR}%, ${aR})`,
498
+ rgb: `rgb(${r}, ${g}, ${b})`,
499
+ rgba: `rgba(${r}, ${g}, ${b}, ${aR})`,
500
+ h,
501
+ s,
502
+ l,
503
+ a
504
+ };
505
+ }
506
+ function deriveAccent(hex) {
507
+ const [h, s, l] = hexToHsl(hex);
508
+ return {
509
+ base: hex,
510
+ dot: hslToHex(h, s, Math.min(l + 12, 95)),
511
+ track: hex,
512
+ ring: hex,
513
+ glow: hslToRgba(h, s, l, 0.3),
514
+ light: hslToHex(h, Math.max(s - 20, 0), Math.min(l + 45, 96))
515
+ };
516
+ }
517
+ function accentToCssVars(tokens, prefix) {
518
+ return {
519
+ [`--${prefix}-accent`]: tokens.base,
520
+ [`--${prefix}-accent-dot`]: tokens.dot,
521
+ [`--${prefix}-accent-track`]: tokens.track,
522
+ [`--${prefix}-accent-ring`]: tokens.ring,
523
+ [`--${prefix}-accent-glow`]: tokens.glow,
524
+ [`--${prefix}-accent-light`]: tokens.light
525
+ };
526
+ }
527
+ var CheckIcon = () => /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "10", height: "10", viewBox: "0 0 10 10", fill: "none", children: /* @__PURE__ */ jsxRuntime.jsx(
528
+ "path",
529
+ {
530
+ d: "M1.5 5L4 7.5L8.5 2.5",
531
+ stroke: "currentColor",
532
+ strokeWidth: "1.8",
533
+ strokeLinecap: "round",
534
+ strokeLinejoin: "round"
535
+ }
536
+ ) });
537
+ var Timeline = ({
538
+ items,
539
+ orientation = "vertical",
540
+ accent,
541
+ className
542
+ }) => {
543
+ const accentVars = accent ? accentToCssVars(deriveAccent(accent), "timeline") : {};
544
+ return /* @__PURE__ */ jsxRuntime.jsx(
545
+ "ol",
546
+ {
547
+ className: [
548
+ Timeline_module_default.timeline,
549
+ Timeline_module_default[orientation],
550
+ className ?? ""
551
+ ].filter(Boolean).join(" "),
552
+ style: accentVars,
553
+ children: items.map((item, index) => {
554
+ const status = item.status ?? "pending";
555
+ const isLast = index === items.length - 1;
556
+ return /* @__PURE__ */ jsxRuntime.jsxs(
557
+ "li",
558
+ {
559
+ className: [Timeline_module_default.item, Timeline_module_default[status], isLast ? Timeline_module_default.last : ""].filter(Boolean).join(" "),
560
+ style: { "--dot-delay": `${index * 0.08}s` },
561
+ children: [
562
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: Timeline_module_default.track, children: [
563
+ orientation === "horizontal" && /* @__PURE__ */ jsxRuntime.jsx("div", { className: [
564
+ Timeline_module_default.connector,
565
+ index === 0 ? Timeline_module_default.connectorHidden : "",
566
+ index > 0 && items[index - 1].status === "completed" ? Timeline_module_default.connectorDone : ""
567
+ ].filter(Boolean).join(" ") }),
568
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: Timeline_module_default.dot, children: status === "completed" && (item.icon ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: Timeline_module_default.iconSlot, children: item.icon }) : /* @__PURE__ */ jsxRuntime.jsx(CheckIcon, {})) }),
569
+ (orientation === "horizontal" || !isLast) && /* @__PURE__ */ jsxRuntime.jsx("div", { className: [
570
+ Timeline_module_default.connector,
571
+ orientation === "horizontal" && isLast ? Timeline_module_default.connectorHidden : "",
572
+ status === "completed" ? Timeline_module_default.connectorDone : ""
573
+ ].filter(Boolean).join(" ") })
574
+ ] }),
575
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: Timeline_module_default.content, children: [
576
+ item.label && /* @__PURE__ */ jsxRuntime.jsx("span", { className: Timeline_module_default.label, children: item.label }),
577
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: Timeline_module_default.title, children: item.title }),
578
+ item.description && /* @__PURE__ */ jsxRuntime.jsx("p", { className: Timeline_module_default.description, children: item.description })
579
+ ] })
580
+ ]
581
+ },
582
+ item.id
583
+ );
584
+ })
585
+ }
586
+ );
587
+ };
588
+
589
+ // src/components/ColorPicker/ColorPicker.module.scss
590
+ var ColorPicker_module_default = {
591
+ colorPicker: "ColorPicker_module_colorPicker",
592
+ topRow: "ColorPicker_module_topRow",
593
+ discWrapper: "ColorPicker_module_discWrapper",
594
+ disc: "ColorPicker_module_disc",
595
+ dot: "ColorPicker_module_dot",
596
+ lSlider: "ColorPicker_module_lSlider",
597
+ lThumb: "ColorPicker_module_lThumb",
598
+ alphaSlider: "ColorPicker_module_alphaSlider",
599
+ alphaThumb: "ColorPicker_module_alphaThumb",
600
+ previewSwatch: "ColorPicker_module_previewSwatch",
601
+ eyedropperBtn: "ColorPicker_module_eyedropperBtn",
602
+ inputSection: "ColorPicker_module_inputSection",
603
+ tabs: "ColorPicker_module_tabs",
604
+ tab: "ColorPicker_module_tab",
605
+ tabActive: "ColorPicker_module_tabActive",
606
+ inputWrapper: "ColorPicker_module_inputWrapper",
607
+ inputAddon: "ColorPicker_module_inputAddon",
608
+ input: "ColorPicker_module_input",
609
+ inputCopyBtn: "ColorPicker_module_inputCopyBtn",
610
+ recents: "ColorPicker_module_recents",
611
+ recentsLabel: "ColorPicker_module_recentsLabel",
612
+ swatches: "ColorPicker_module_swatches",
613
+ recentSwatch: "ColorPicker_module_recentSwatch"
614
+ };
615
+ var DISC = 200;
616
+ var CopyIcon = () => /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "14", height: "14", viewBox: "0 0 14 14", fill: "none", children: [
617
+ /* @__PURE__ */ jsxRuntime.jsx("rect", { x: "5", y: "5", width: "7", height: "7", rx: "1.5", stroke: "currentColor", strokeWidth: "1.4" }),
618
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M2 9V2.5A.5.5 0 0 1 2.5 2H9", stroke: "currentColor", strokeWidth: "1.4", strokeLinecap: "round" })
619
+ ] });
620
+ var CheckIcon2 = () => /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "14", height: "14", viewBox: "0 0 14 14", fill: "none", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M2.5 7L5.5 10L11.5 4", stroke: "currentColor", strokeWidth: "1.6", strokeLinecap: "round", strokeLinejoin: "round" }) });
621
+ var EyedropperIcon = () => /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "14", height: "14", viewBox: "0 0 14 14", fill: "none", children: [
622
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M9.5 2.5L11.5 4.5L6 10L3 11L4 8L9.5 2.5Z", stroke: "currentColor", strokeWidth: "1.4", strokeLinejoin: "round" }),
623
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M8 4L10 6", stroke: "currentColor", strokeWidth: "1.4", strokeLinecap: "round" }),
624
+ /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "2.5", cy: "11.5", r: "1", fill: "currentColor" })
625
+ ] });
626
+ function formatValue(mode, h, s, l, r, g, b, hex) {
627
+ if (mode === "hex") return hex.replace("#", "");
628
+ if (mode === "hsl") return `${Math.round(h)} ${Math.round(s)} ${Math.round(l)}`;
629
+ return `${r} ${g} ${b}`;
630
+ }
631
+ function parseValue(mode, raw) {
632
+ if (mode === "hex") {
633
+ const clean = raw.replace(/^#/, "");
634
+ if (!/^[0-9a-fA-F]{6}$/.test(clean)) return null;
635
+ const [h, s, l] = hexToHsl(`#${clean}`);
636
+ return [h, s, l];
637
+ }
638
+ const parts = raw.trim().split(/[\s,]+/).map(Number);
639
+ if (parts.length !== 3 || parts.some(isNaN)) return null;
640
+ if (mode === "hsl") {
641
+ const [h, s, l] = parts;
642
+ if (h < 0 || h > 360 || s < 0 || s > 100 || l < 0 || l > 100) return null;
643
+ return [h, s, l];
644
+ }
645
+ const [r, g, b] = parts;
646
+ if ([r, g, b].some((v) => v < 0 || v > 255)) return null;
647
+ return rgbToHsl(r, g, b);
648
+ }
649
+ var ColorInput = ({ mode, h, s, l, r, g, b, hex, onChange, onCopy, copied }) => {
650
+ const [draft, setDraft] = React.useState(() => formatValue(mode, h, s, l, r, g, b, hex));
651
+ const [focused, setFocused] = React.useState(false);
652
+ React.useEffect(() => {
653
+ if (!focused) setDraft(formatValue(mode, h, s, l, r, g, b, hex));
654
+ }, [focused, mode, h, s, l, r, g, b, hex]);
655
+ const placeholder = mode === "hex" ? "3b82f6" : mode === "hsl" ? "217 91 60" : "59 130 246";
656
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: ColorPicker_module_default.inputWrapper, children: [
657
+ mode === "hex" && /* @__PURE__ */ jsxRuntime.jsx("span", { className: ColorPicker_module_default.inputAddon, children: "#" }),
658
+ /* @__PURE__ */ jsxRuntime.jsx(
659
+ "input",
660
+ {
661
+ className: ColorPicker_module_default.input,
662
+ value: draft,
663
+ placeholder,
664
+ spellCheck: false,
665
+ onFocus: () => setFocused(true),
666
+ onBlur: () => setFocused(false),
667
+ onChange: (e) => {
668
+ const raw = e.target.value;
669
+ setDraft(raw);
670
+ const result = parseValue(mode, raw);
671
+ if (result) onChange(...result);
672
+ }
673
+ }
674
+ ),
675
+ /* @__PURE__ */ jsxRuntime.jsx("button", { className: ColorPicker_module_default.inputCopyBtn, onClick: onCopy, tabIndex: -1, title: "Copia", children: copied ? /* @__PURE__ */ jsxRuntime.jsx(CheckIcon2, {}) : /* @__PURE__ */ jsxRuntime.jsx(CopyIcon, {}) })
676
+ ] });
677
+ };
678
+ function parseInitial(value) {
679
+ if (value?.startsWith("#")) {
680
+ const [h, s, l] = hexToHsl(value);
681
+ return [h, s, l, 1];
682
+ }
683
+ return [217, 91, 60, 1];
684
+ }
685
+ var ColorPicker = ({
686
+ value,
687
+ onChange,
688
+ showAlpha = true,
689
+ recentColors = [],
690
+ accent,
691
+ className
692
+ }) => {
693
+ const init = parseInitial(value);
694
+ const [h, setH] = React.useState(init[0]);
695
+ const [s, setS] = React.useState(init[1]);
696
+ const [l, setL] = React.useState(init[2]);
697
+ const [a, setA] = React.useState(init[3]);
698
+ const [mode, setMode] = React.useState("hex");
699
+ const [copied, setCopied] = React.useState(false);
700
+ const [hasEyeDropper, setHasEyeDropper] = React.useState(false);
701
+ const canvasRef = React.useRef(null);
702
+ React.useEffect(() => {
703
+ setHasEyeDropper(typeof window !== "undefined" && "EyeDropper" in window);
704
+ }, []);
705
+ React.useEffect(() => {
706
+ if (value?.startsWith("#")) {
707
+ const [nh, ns, nl] = hexToHsl(value);
708
+ setH(nh);
709
+ setS(ns);
710
+ setL(nl);
711
+ }
712
+ }, [value]);
713
+ React.useEffect(() => {
714
+ const canvas = canvasRef.current;
715
+ if (!canvas) return;
716
+ const ctx = canvas.getContext("2d");
717
+ if (!ctx) return;
718
+ const img = ctx.createImageData(DISC, DISC);
719
+ const data = img.data;
720
+ const cx = DISC / 2;
721
+ const cy = DISC / 2;
722
+ const radius = DISC / 2;
723
+ for (let py = 0; py < DISC; py++) {
724
+ for (let px = 0; px < DISC; px++) {
725
+ const dx = px - cx;
726
+ const dy = py - cy;
727
+ const r = Math.sqrt(dx * dx + dy * dy);
728
+ const idx = (py * DISC + px) * 4;
729
+ if (r > radius) {
730
+ data[idx + 3] = 0;
731
+ continue;
732
+ }
733
+ const theta = Math.atan2(dy, dx) * 180 / Math.PI;
734
+ const hue = (theta + 360) % 360;
735
+ const sat = r / radius * 100;
736
+ const { r: rr2, g: gg2, b: bb2 } = hslToRgb(hue, sat, l);
737
+ data[idx] = rr2;
738
+ data[idx + 1] = gg2;
739
+ data[idx + 2] = bb2;
740
+ data[idx + 3] = r > radius - 1 ? Math.round(255 * (radius - r)) : 255;
741
+ }
742
+ }
743
+ ctx.putImageData(img, 0, 0);
744
+ }, [l]);
745
+ const notify = React.useCallback(
746
+ (nh, ns, nl, na) => {
747
+ onChange?.(buildColorValue(nh, ns, nl, na));
748
+ },
749
+ [onChange]
750
+ );
751
+ const updateDisc = React.useCallback(
752
+ (clientX, clientY, rect) => {
753
+ const cx = rect.left + rect.width / 2;
754
+ const cy = rect.top + rect.height / 2;
755
+ const dx = clientX - cx;
756
+ const dy = clientY - cy;
757
+ const r = Math.sqrt(dx * dx + dy * dy);
758
+ const radius = rect.width / 2;
759
+ const clampedR = Math.min(r, radius);
760
+ const theta = Math.atan2(dy, dx) * 180 / Math.PI;
761
+ const nh = (theta + 360) % 360;
762
+ const ns = clampedR / radius * 100;
763
+ setH(nh);
764
+ setS(ns);
765
+ notify(nh, ns, l, a);
766
+ },
767
+ [l, a, notify]
768
+ );
769
+ const handleDiscPointerDown = React.useCallback(
770
+ (e) => {
771
+ e.currentTarget.setPointerCapture(e.pointerId);
772
+ updateDisc(e.clientX, e.clientY, e.currentTarget.getBoundingClientRect());
773
+ },
774
+ [updateDisc]
775
+ );
776
+ const handleDiscPointerMove = React.useCallback(
777
+ (e) => {
778
+ if (e.buttons === 0) return;
779
+ updateDisc(e.clientX, e.clientY, e.currentTarget.getBoundingClientRect());
780
+ },
781
+ [updateDisc]
782
+ );
783
+ const updateL = React.useCallback(
784
+ (clientX, rect) => {
785
+ const nl = Math.max(0, Math.min(100, (clientX - rect.left) / rect.width * 100));
786
+ setL(nl);
787
+ notify(h, s, nl, a);
788
+ },
789
+ [h, s, a, notify]
790
+ );
791
+ const handleLPointerDown = React.useCallback(
792
+ (e) => {
793
+ e.currentTarget.setPointerCapture(e.pointerId);
794
+ updateL(e.clientX, e.currentTarget.getBoundingClientRect());
795
+ },
796
+ [updateL]
797
+ );
798
+ const handleLPointerMove = React.useCallback(
799
+ (e) => {
800
+ if (e.buttons === 0) return;
801
+ updateL(e.clientX, e.currentTarget.getBoundingClientRect());
802
+ },
803
+ [updateL]
804
+ );
805
+ const updateA = React.useCallback(
806
+ (clientX, rect) => {
807
+ const na = Math.max(0, Math.min(1, (clientX - rect.left) / rect.width));
808
+ setA(na);
809
+ notify(h, s, l, na);
810
+ },
811
+ [h, s, l, notify]
812
+ );
813
+ const handleAPointerDown = React.useCallback(
814
+ (e) => {
815
+ e.currentTarget.setPointerCapture(e.pointerId);
816
+ updateA(e.clientX, e.currentTarget.getBoundingClientRect());
817
+ },
818
+ [updateA]
819
+ );
820
+ const handleAPointerMove = React.useCallback(
821
+ (e) => {
822
+ if (e.buttons === 0) return;
823
+ updateA(e.clientX, e.currentTarget.getBoundingClientRect());
824
+ },
825
+ [updateA]
826
+ );
827
+ const { r: rr, g: gg, b: bb } = hslToRgb(h, s, l);
828
+ const hexStr = hslToHex(h, s, l);
829
+ const rgbStr = `rgb(${rr}, ${gg}, ${bb})`;
830
+ const colorValue = buildColorValue(h, s, l, a);
831
+ const dotX = DISC / 2 + s / 100 * (DISC / 2) * Math.cos(h * Math.PI / 180);
832
+ const dotY = DISC / 2 + s / 100 * (DISC / 2) * Math.sin(h * Math.PI / 180);
833
+ const lGradient = `linear-gradient(to right,
834
+ hsl(${h}, ${s}%, 5%),
835
+ hsl(${h}, ${s}%, 50%),
836
+ hsl(${h}, ${s}%, 95%))`;
837
+ const alphaGradient = `linear-gradient(to right, transparent, ${rgbStr})`;
838
+ const handleEyeDropper = async () => {
839
+ if (!window.EyeDropper) return;
840
+ try {
841
+ const result = await new window.EyeDropper().open();
842
+ const [nh, ns, nl] = hexToHsl(result.sRGBHex);
843
+ setH(nh);
844
+ setS(ns);
845
+ setL(nl);
846
+ notify(nh, ns, nl, a);
847
+ } catch {
848
+ }
849
+ };
850
+ const handleCopy = () => {
851
+ const text = mode === "hex" ? colorValue.hexa : mode === "hsl" ? colorValue.hsla : colorValue.rgba;
852
+ navigator.clipboard.writeText(text).then(() => {
853
+ setCopied(true);
854
+ setTimeout(() => setCopied(false), 1500);
855
+ });
856
+ };
857
+ const handleSwatch = (color) => {
858
+ const [nh, ns, nl] = hexToHsl(color);
859
+ setH(nh);
860
+ setS(ns);
861
+ setL(nl);
862
+ notify(nh, ns, nl, a);
863
+ };
864
+ const accentVars = accent ? accentToCssVars(deriveAccent(accent), "colorpicker") : {};
865
+ mode === "hex" ? colorValue.hexa : mode === "hsl" ? colorValue.hsla : colorValue.rgba;
866
+ return /* @__PURE__ */ jsxRuntime.jsxs(
867
+ "div",
868
+ {
869
+ className: [ColorPicker_module_default.colorPicker, className ?? ""].filter(Boolean).join(" "),
870
+ style: accentVars,
871
+ children: [
872
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: ColorPicker_module_default.topRow, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: ColorPicker_module_default.discWrapper, children: [
873
+ /* @__PURE__ */ jsxRuntime.jsx(
874
+ "canvas",
875
+ {
876
+ ref: canvasRef,
877
+ width: DISC,
878
+ height: DISC,
879
+ className: ColorPicker_module_default.disc,
880
+ onPointerDown: handleDiscPointerDown,
881
+ onPointerMove: handleDiscPointerMove
882
+ }
883
+ ),
884
+ /* @__PURE__ */ jsxRuntime.jsx(
885
+ "div",
886
+ {
887
+ className: ColorPicker_module_default.dot,
888
+ style: {
889
+ left: dotX,
890
+ top: dotY,
891
+ borderColor: l > 55 ? "rgba(0,0,0,0.5)" : "rgba(255,255,255,0.85)"
892
+ }
893
+ }
894
+ )
895
+ ] }) }),
896
+ /* @__PURE__ */ jsxRuntime.jsx(
897
+ "div",
898
+ {
899
+ className: ColorPicker_module_default.lSlider,
900
+ style: { backgroundImage: lGradient },
901
+ onPointerDown: handleLPointerDown,
902
+ onPointerMove: handleLPointerMove,
903
+ children: /* @__PURE__ */ jsxRuntime.jsx(
904
+ "div",
905
+ {
906
+ className: ColorPicker_module_default.lThumb,
907
+ style: { left: `${l}%` }
908
+ }
909
+ )
910
+ }
911
+ ),
912
+ showAlpha && /* @__PURE__ */ jsxRuntime.jsx(
913
+ "div",
914
+ {
915
+ className: ColorPicker_module_default.alphaSlider,
916
+ style: { backgroundImage: alphaGradient },
917
+ onPointerDown: handleAPointerDown,
918
+ onPointerMove: handleAPointerMove,
919
+ children: /* @__PURE__ */ jsxRuntime.jsx(
920
+ "div",
921
+ {
922
+ className: ColorPicker_module_default.alphaThumb,
923
+ style: { left: `${a * 100}%` }
924
+ }
925
+ )
926
+ }
927
+ ),
928
+ /* @__PURE__ */ jsxRuntime.jsx(
929
+ "div",
930
+ {
931
+ className: ColorPicker_module_default.previewSwatch,
932
+ style: { background: showAlpha ? colorValue.rgba : hexStr },
933
+ children: hasEyeDropper && /* @__PURE__ */ jsxRuntime.jsx("button", { className: ColorPicker_module_default.eyedropperBtn, onClick: handleEyeDropper, title: "Pick color", children: /* @__PURE__ */ jsxRuntime.jsx(EyedropperIcon, {}) })
934
+ }
935
+ ),
936
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: ColorPicker_module_default.inputSection, children: [
937
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: ColorPicker_module_default.tabs, children: ["hex", "hsl", "rgb"].map((m) => /* @__PURE__ */ jsxRuntime.jsx(
938
+ "button",
939
+ {
940
+ className: [ColorPicker_module_default.tab, mode === m ? ColorPicker_module_default.tabActive : ""].filter(Boolean).join(" "),
941
+ onClick: () => setMode(m),
942
+ children: m.toUpperCase()
943
+ },
944
+ m
945
+ )) }),
946
+ /* @__PURE__ */ jsxRuntime.jsx(
947
+ ColorInput,
948
+ {
949
+ mode,
950
+ h,
951
+ s,
952
+ l,
953
+ r: rr,
954
+ g: gg,
955
+ b: bb,
956
+ hex: hexStr,
957
+ onChange: (nh, ns, nl) => {
958
+ setH(nh);
959
+ setS(ns);
960
+ setL(nl);
961
+ notify(nh, ns, nl, a);
962
+ },
963
+ onCopy: handleCopy,
964
+ copied
965
+ }
966
+ )
967
+ ] }),
968
+ recentColors.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: ColorPicker_module_default.recents, children: [
969
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: ColorPicker_module_default.recentsLabel, children: "Recent" }),
970
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: ColorPicker_module_default.swatches, children: recentColors.slice(0, 8).map((c, i) => /* @__PURE__ */ jsxRuntime.jsx(
971
+ "button",
972
+ {
973
+ className: ColorPicker_module_default.recentSwatch,
974
+ style: { background: c },
975
+ onClick: () => handleSwatch(c),
976
+ title: c
977
+ },
978
+ i
979
+ )) })
980
+ ] })
981
+ ]
982
+ }
983
+ );
984
+ };
985
+
986
+ exports.Badge = Badge;
987
+ exports.Button = Button;
988
+ exports.ColorPicker = ColorPicker;
989
+ exports.Input = Input;
990
+ exports.RainCanvas = RainCanvas;
991
+ exports.Timeline = Timeline;
992
+ //# sourceMappingURL=index.cjs.map
993
+ //# sourceMappingURL=index.cjs.map