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