@valcis/brand 2.0.5 → 2.1.1

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.
package/dist/index.js CHANGED
@@ -48,11 +48,21 @@ __export(index_exports, {
48
48
  L_PATH: () => L_PATH,
49
49
  Logo: () => Logo,
50
50
  S_PATH: () => S_PATH,
51
+ Spinner: () => Spinner,
51
52
  VIEWBOXES: () => VIEWBOXES,
52
53
  V_CALLIGRAPHIC_FULL_TRANSFORM: () => V_CALLIGRAPHIC_FULL_TRANSFORM,
53
54
  V_CALLIGRAPHIC_PATH: () => V_CALLIGRAPHIC_PATH,
55
+ Watermark: () => Watermark,
56
+ background: () => background,
57
+ border: () => border,
58
+ colors: () => colors,
59
+ cssVariables: () => cssVariables,
54
60
  getDevInfo: () => getDevInfo,
55
- useDevInfo: () => useDevInfo
61
+ primary: () => primary,
62
+ semantic: () => semantic,
63
+ text: () => text,
64
+ useDevInfo: () => useDevInfo,
65
+ useTheme: () => useTheme
56
66
  });
57
67
  module.exports = __toCommonJS(index_exports);
58
68
 
@@ -106,7 +116,7 @@ var Logo = ({
106
116
  const width = px * (variant === "full" ? ratio : 1);
107
117
  const height = px * (variant === "full" ? 1 : 1 / ratio);
108
118
  const accent = accentColor ?? "var(--valcis-logo-accent, var(--primary, currentColor))";
109
- const text = textColor ?? "var(--valcis-logo-text, currentColor)";
119
+ const text2 = textColor ?? "var(--valcis-logo-text, currentColor)";
110
120
  const isDecorative = !ariaLabel;
111
121
  const cursorAnimation = isAnimated && variant === "full" ? `
112
122
  @keyframes valcis-cursor-blink {
@@ -146,16 +156,16 @@ var Logo = ({
146
156
  variant === "icon" && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
147
157
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: BRACKET_LEFT_PATH, fill: accent }),
148
158
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: BRACKET_RIGHT_PATH, fill: accent }),
149
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("g", { transform: "translate(30.85, 25.15) scale(1.15, 1.1) translate(-30.85, -25.15)", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: V_CALLIGRAPHIC_PATH, fill: text }) })
159
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("g", { transform: "translate(30.85, 25.15) scale(1.15, 1.1) translate(-30.85, -25.15)", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: V_CALLIGRAPHIC_PATH, fill: text2 }) })
150
160
  ] }),
151
161
  variant === "full" && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("g", { transform: "scale(1,-1) translate(0,-640)", children: [
152
162
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("g", { transform: "translate(0,0)", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: CHEVRON_RIGHT_FULL_PATH, fill: accent }) }),
153
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("g", { transform: "translate(600,0)", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("g", { transform: V_CALLIGRAPHIC_FULL_TRANSFORM, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: V_CALLIGRAPHIC_PATH, fill: text }) }) }),
154
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("g", { transform: "translate(1260,0)", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: A_PATH, fill: text }) }),
155
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("g", { transform: "translate(1860,0)", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: L_PATH, fill: text }) }),
156
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("g", { transform: "translate(2460,0)", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: C_PATH, fill: text }) }),
157
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("g", { transform: "translate(3060,0)", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: I_PATH, fill: text }) }),
158
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("g", { transform: "translate(3660,0)", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: S_PATH, fill: text }) }),
163
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("g", { transform: "translate(600,0)", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("g", { transform: V_CALLIGRAPHIC_FULL_TRANSFORM, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: V_CALLIGRAPHIC_PATH, fill: text2 }) }) }),
164
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("g", { transform: "translate(1260,0)", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: A_PATH, fill: text2 }) }),
165
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("g", { transform: "translate(1860,0)", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: L_PATH, fill: text2 }) }),
166
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("g", { transform: "translate(2460,0)", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: C_PATH, fill: text2 }) }),
167
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("g", { transform: "translate(3060,0)", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: I_PATH, fill: text2 }) }),
168
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("g", { transform: "translate(3660,0)", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: S_PATH, fill: text2 }) }),
159
169
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("g", { transform: "translate(4260,0)", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
160
170
  "path",
161
171
  {
@@ -215,7 +225,7 @@ function useDevInfo(initialData, customUrl) {
215
225
  const response = await fetch(url, {
216
226
  signal: controller.signal,
217
227
  cache: "no-store",
218
- headers: { "Accept": "application/json" }
228
+ headers: { Accept: "application/json" }
219
229
  });
220
230
  if (!response.ok) throw new Error("Fetch failed");
221
231
  const data = await response.json();
@@ -266,7 +276,7 @@ var Footer = ({
266
276
  accentColor,
267
277
  backgroundColor,
268
278
  textColor,
269
- border = "top",
279
+ border: border2 = "top",
270
280
  padding = "normal",
271
281
  align = "center",
272
282
  position = "sticky",
@@ -307,8 +317,8 @@ var Footer = ({
307
317
  const logoColors = LOGO_COLORS[theme];
308
318
  const pad = typeof padding === "string" ? PADDING_MAP[padding] : { x: padding.x ?? "1rem", y: padding.y ?? "1rem" };
309
319
  const borderColor = c.border;
310
- const borderTop = border === true || border === "top" || border === "both" ? `1px solid ${borderColor}` : "none";
311
- const borderBottom = border === "bottom" || border === "both" ? `1px solid ${borderColor}` : "none";
320
+ const borderTop = border2 === true || border2 === "top" || border2 === "both" ? `1px solid ${borderColor}` : "none";
321
+ const borderBottom = border2 === "bottom" || border2 === "both" ? `1px solid ${borderColor}` : "none";
312
322
  const positionStyles = {};
313
323
  if (position === "sticky") {
314
324
  positionStyles.position = "sticky";
@@ -388,11 +398,17 @@ var Footer = ({
388
398
  "aria-label": `Visitar sitio web de ${devInfo.brand} (abre en nueva pesta\xF1a)`,
389
399
  children: logoElement
390
400
  }
391
- ) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: {
392
- display: "inline-flex",
393
- alignItems: "center",
394
- padding: "0.35rem 0.5rem"
395
- }, children: logoElement });
401
+ ) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
402
+ "span",
403
+ {
404
+ style: {
405
+ display: "inline-flex",
406
+ alignItems: "center",
407
+ padding: "0.35rem 0.5rem"
408
+ },
409
+ children: logoElement
410
+ }
411
+ );
396
412
  return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
397
413
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("style", { children: dynamicStyles }),
398
414
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
@@ -431,7 +447,7 @@ async function getDevInfo(customUrl) {
431
447
  const url = customUrl || DEV_INFO_URL;
432
448
  const response = await fetch(url, {
433
449
  signal: controller.signal,
434
- headers: { "Accept": "application/json" }
450
+ headers: { Accept: "application/json" }
435
451
  });
436
452
  if (!response.ok) {
437
453
  throw new Error(`HTTP ${response.status}`);
@@ -451,6 +467,299 @@ async function getDevInfo(customUrl) {
451
467
  clearTimeout(timeoutId);
452
468
  }
453
469
  }
470
+
471
+ // src/components/Watermark.tsx
472
+ var import_react3 = __toESM(require("react"));
473
+ var import_jsx_runtime3 = require("react/jsx-runtime");
474
+ var POSITION_STYLES = {
475
+ "top-left": { top: "1rem", left: "1rem" },
476
+ "top-right": { top: "1rem", right: "1rem" },
477
+ "bottom-left": { bottom: "1rem", left: "1rem" },
478
+ "bottom-right": { bottom: "1rem", right: "1rem" },
479
+ center: { top: "50%", left: "50%", transform: "translate(-50%, -50%)" }
480
+ };
481
+ var Watermark = ({
482
+ position = "bottom-right",
483
+ opacity = 0.3,
484
+ size = 48,
485
+ rotation = 0,
486
+ showOnHover = false,
487
+ className
488
+ }) => {
489
+ const styleHash = import_react3.default.useId().replace(/:/g, "");
490
+ const watermarkClass = `__valcis-watermark-${styleHash}`;
491
+ const positionStyle = POSITION_STYLES[position] || POSITION_STYLES["bottom-right"];
492
+ const baseStyles = {
493
+ position: "absolute",
494
+ ...positionStyle,
495
+ opacity: showOnHover ? 0 : opacity,
496
+ transition: "opacity 0.3s ease",
497
+ pointerEvents: "none",
498
+ zIndex: 10,
499
+ transform: `${positionStyle.transform || ""} rotate(${rotation}deg)`.trim()
500
+ };
501
+ const hoverStyles = showOnHover ? `
502
+ .${watermarkClass} { opacity: 0; }
503
+ *:hover > .${watermarkClass} { opacity: ${opacity}; }
504
+ ` : "";
505
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
506
+ hoverStyles && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("style", { children: hoverStyles }),
507
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: `${watermarkClass} ${className || ""}`.trim(), style: baseStyles, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Logo, { variant: "full", size, animated: false }) })
508
+ ] });
509
+ };
510
+
511
+ // src/components/Spinner.tsx
512
+ var import_react4 = __toESM(require("react"));
513
+ var import_jsx_runtime4 = require("react/jsx-runtime");
514
+ var SIZE_MAP2 = {
515
+ sm: 24,
516
+ md: 32,
517
+ lg: 48,
518
+ xl: 64
519
+ };
520
+ var Spinner = ({
521
+ size = "md",
522
+ animation = "pulse",
523
+ accentColor,
524
+ textColor,
525
+ label = "Cargando...",
526
+ className
527
+ }) => {
528
+ const styleHash = import_react4.default.useId().replace(/:/g, "");
529
+ const spinnerClass = `__valcis-spinner-${styleHash}`;
530
+ const px = typeof size === "number" ? size : SIZE_MAP2[size] ?? 32;
531
+ const animations = {
532
+ pulse: `
533
+ @keyframes valcis-spinner-pulse-${styleHash} {
534
+ 0%, 100% { opacity: 1; transform: scale(1); }
535
+ 50% { opacity: 0.5; transform: scale(0.95); }
536
+ }
537
+ @media (prefers-reduced-motion: no-preference) {
538
+ .${spinnerClass} { animation: valcis-spinner-pulse-${styleHash} 1.5s ease-in-out infinite; }
539
+ }
540
+ `,
541
+ spin: `
542
+ @keyframes valcis-spinner-spin-${styleHash} {
543
+ 0% { transform: rotate(0deg); }
544
+ 100% { transform: rotate(360deg); }
545
+ }
546
+ @media (prefers-reduced-motion: no-preference) {
547
+ .${spinnerClass} { animation: valcis-spinner-spin-${styleHash} 1.2s linear infinite; }
548
+ }
549
+ `,
550
+ bounce: `
551
+ @keyframes valcis-spinner-bounce-${styleHash} {
552
+ 0%, 100% { transform: translateY(0); }
553
+ 50% { transform: translateY(-25%); }
554
+ }
555
+ @media (prefers-reduced-motion: no-preference) {
556
+ .${spinnerClass} { animation: valcis-spinner-bounce-${styleHash} 0.8s ease-in-out infinite; }
557
+ }
558
+ `
559
+ };
560
+ const containerStyles = {
561
+ display: "inline-flex",
562
+ alignItems: "center",
563
+ justifyContent: "center"
564
+ };
565
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
566
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("style", { children: animations[animation] }),
567
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
568
+ "div",
569
+ {
570
+ className: `${spinnerClass} ${className || ""}`.trim(),
571
+ style: containerStyles,
572
+ role: "status",
573
+ "aria-label": label,
574
+ children: [
575
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
576
+ Logo,
577
+ {
578
+ variant: "icon",
579
+ size: px,
580
+ animated: false,
581
+ accentColor,
582
+ textColor
583
+ }
584
+ ),
585
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
586
+ "span",
587
+ {
588
+ style: {
589
+ position: "absolute",
590
+ width: 1,
591
+ height: 1,
592
+ padding: 0,
593
+ margin: -1,
594
+ overflow: "hidden",
595
+ clip: "rect(0, 0, 0, 0)",
596
+ whiteSpace: "nowrap",
597
+ border: 0
598
+ },
599
+ children: label
600
+ }
601
+ )
602
+ ]
603
+ }
604
+ )
605
+ ] });
606
+ };
607
+
608
+ // src/shared/hooks/useTheme.ts
609
+ var import_react5 = require("react");
610
+ function getSavedTheme() {
611
+ if (typeof window === "undefined") return null;
612
+ try {
613
+ const saved = localStorage.getItem("valcis-theme");
614
+ if (saved === "light" || saved === "dark") return saved;
615
+ } catch {
616
+ }
617
+ return null;
618
+ }
619
+ function getSystemTheme() {
620
+ if (typeof window === "undefined") return "light";
621
+ return window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
622
+ }
623
+ function useTheme() {
624
+ const [manualTheme, setManualTheme] = (0, import_react5.useState)(getSavedTheme);
625
+ const [systemTheme, setSystemTheme] = (0, import_react5.useState)(getSystemTheme);
626
+ (0, import_react5.useEffect)(() => {
627
+ if (typeof window === "undefined") return;
628
+ const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
629
+ const handleChange = (e) => {
630
+ setSystemTheme(e.matches ? "dark" : "light");
631
+ };
632
+ mediaQuery.addEventListener("change", handleChange);
633
+ return () => {
634
+ mediaQuery.removeEventListener("change", handleChange);
635
+ };
636
+ }, []);
637
+ const theme = manualTheme ?? systemTheme;
638
+ const setTheme = (0, import_react5.useCallback)((newTheme) => {
639
+ setManualTheme(newTheme);
640
+ if (typeof window === "undefined") return;
641
+ try {
642
+ if (newTheme) {
643
+ localStorage.setItem("valcis-theme", newTheme);
644
+ } else {
645
+ localStorage.removeItem("valcis-theme");
646
+ }
647
+ } catch {
648
+ }
649
+ }, []);
650
+ const toggleTheme = (0, import_react5.useCallback)(() => {
651
+ setTheme(theme === "dark" ? "light" : "dark");
652
+ }, [theme, setTheme]);
653
+ return {
654
+ theme,
655
+ isDark: theme === "dark",
656
+ isLight: theme === "light",
657
+ setTheme,
658
+ toggleTheme
659
+ };
660
+ }
661
+
662
+ // src/theme/colors.ts
663
+ var primary = {
664
+ /** Azul principal */
665
+ DEFAULT: "#3B82F6",
666
+ /** Azul claro (para dark mode) */
667
+ light: "#60A5FA",
668
+ /** Azul oscuro (hover) */
669
+ dark: "#2563EB",
670
+ /** Azul muy claro (backgrounds) */
671
+ 50: "#EFF6FF",
672
+ 100: "#DBEAFE",
673
+ 200: "#BFDBFE",
674
+ 300: "#93C5FD",
675
+ 400: "#60A5FA",
676
+ 500: "#3B82F6",
677
+ 600: "#2563EB",
678
+ 700: "#1D4ED8",
679
+ 800: "#1E40AF",
680
+ 900: "#1E3A8A"
681
+ };
682
+ var text = {
683
+ /** Texto principal (light mode) */
684
+ DEFAULT: "#1E293B",
685
+ /** Texto principal (dark mode) */
686
+ dark: "#F1F5F9",
687
+ /** Texto secundario (light mode) */
688
+ muted: "#64748B",
689
+ /** Texto secundario (dark mode) */
690
+ mutedDark: "#94A3B8"
691
+ };
692
+ var background = {
693
+ /** Fondo claro */
694
+ light: "#FFFFFF",
695
+ /** Fondo oscuro */
696
+ dark: "#0F172A",
697
+ /** Fondo gris claro */
698
+ muted: "#F8FAFC",
699
+ /** Fondo gris oscuro */
700
+ mutedDark: "#1E293B"
701
+ };
702
+ var border = {
703
+ /** Borde claro */
704
+ light: "#E2E8F0",
705
+ /** Borde oscuro */
706
+ dark: "#334155"
707
+ };
708
+ var semantic = {
709
+ success: "#22C55E",
710
+ warning: "#F59E0B",
711
+ error: "#EF4444",
712
+ info: "#3B82F6"
713
+ };
714
+ var colors = {
715
+ primary,
716
+ text,
717
+ background,
718
+ border,
719
+ semantic
720
+ };
721
+ var cssVariables = `
722
+ :root {
723
+ /* Primary */
724
+ --valcis-primary: ${primary.DEFAULT};
725
+ --valcis-primary-light: ${primary.light};
726
+ --valcis-primary-dark: ${primary.dark};
727
+
728
+ /* Text */
729
+ --valcis-text: ${text.DEFAULT};
730
+ --valcis-text-muted: ${text.muted};
731
+
732
+ /* Background */
733
+ --valcis-bg: ${background.light};
734
+ --valcis-bg-muted: ${background.muted};
735
+
736
+ /* Border */
737
+ --valcis-border: ${border.light};
738
+
739
+ /* Logo espec\xEDficos */
740
+ --valcis-logo-accent: ${primary.DEFAULT};
741
+ --valcis-logo-text: ${text.DEFAULT};
742
+ }
743
+
744
+ @media (prefers-color-scheme: dark) {
745
+ :root {
746
+ --valcis-primary: ${primary.light};
747
+ --valcis-primary-light: ${primary[300]};
748
+ --valcis-primary-dark: ${primary.DEFAULT};
749
+
750
+ --valcis-text: ${text.dark};
751
+ --valcis-text-muted: ${text.mutedDark};
752
+
753
+ --valcis-bg: ${background.dark};
754
+ --valcis-bg-muted: ${background.mutedDark};
755
+
756
+ --valcis-border: ${border.dark};
757
+
758
+ --valcis-logo-accent: ${primary.light};
759
+ --valcis-logo-text: ${text.dark};
760
+ }
761
+ }
762
+ `.trim();
454
763
  // Annotate the CommonJS export names for ESM import in node:
455
764
  0 && (module.exports = {
456
765
  ASPECT_RATIOS,
@@ -471,9 +780,19 @@ async function getDevInfo(customUrl) {
471
780
  L_PATH,
472
781
  Logo,
473
782
  S_PATH,
783
+ Spinner,
474
784
  VIEWBOXES,
475
785
  V_CALLIGRAPHIC_FULL_TRANSFORM,
476
786
  V_CALLIGRAPHIC_PATH,
787
+ Watermark,
788
+ background,
789
+ border,
790
+ colors,
791
+ cssVariables,
477
792
  getDevInfo,
478
- useDevInfo
793
+ primary,
794
+ semantic,
795
+ text,
796
+ useDevInfo,
797
+ useTheme
479
798
  });