@valcis/brand 2.0.4 → 2.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.
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
 
@@ -92,22 +102,23 @@ function resolveSize(size) {
92
102
  var Logo = ({
93
103
  variant = "icon",
94
104
  size = 24,
95
- animated = false,
105
+ animated,
96
106
  accentColor,
97
107
  textColor,
98
108
  className,
99
109
  style,
100
110
  ariaLabel
101
111
  }) => {
112
+ const isAnimated = animated ?? variant === "full";
102
113
  const px = resolveSize(size);
103
114
  const viewBox = VIEWBOXES[variant] ?? VIEWBOXES.icon;
104
115
  const ratio = ASPECT_RATIOS[variant] ?? ASPECT_RATIOS.icon;
105
116
  const width = px * (variant === "full" ? ratio : 1);
106
117
  const height = px * (variant === "full" ? 1 : 1 / ratio);
107
118
  const accent = accentColor ?? "var(--valcis-logo-accent, var(--primary, currentColor))";
108
- const text = textColor ?? "var(--valcis-logo-text, currentColor)";
119
+ const text2 = textColor ?? "var(--valcis-logo-text, currentColor)";
109
120
  const isDecorative = !ariaLabel;
110
- const cursorAnimation = animated && variant === "full" ? `
121
+ const cursorAnimation = isAnimated && variant === "full" ? `
111
122
  @keyframes valcis-cursor-blink {
112
123
  0%, 100% { opacity: 1; }
113
124
  50% { opacity: 0; }
@@ -116,7 +127,7 @@ var Logo = ({
116
127
  .valcis-cursor-blink { animation: valcis-cursor-blink 1s step-end infinite; }
117
128
  }
118
129
  ` : void 0;
119
- const pulseAnimation = animated && variant === "icon" ? `
130
+ const pulseAnimation = isAnimated && variant === "icon" ? `
120
131
  @keyframes valcis-logo-pulse {
121
132
  0%, 100% { opacity: 1; }
122
133
  50% { opacity: 0.6; }
@@ -136,7 +147,7 @@ var Logo = ({
136
147
  fill: "none",
137
148
  width,
138
149
  height,
139
- className: [animated && variant === "icon" ? "valcis-logo-animated" : "", className].filter(Boolean).join(" ") || void 0,
150
+ className: [isAnimated && variant === "icon" ? "valcis-logo-animated" : "", className].filter(Boolean).join(" ") || void 0,
140
151
  style,
141
152
  role: "img",
142
153
  "aria-hidden": isDecorative ? true : void 0,
@@ -145,22 +156,22 @@ var Logo = ({
145
156
  variant === "icon" && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
146
157
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: BRACKET_LEFT_PATH, fill: accent }),
147
158
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: BRACKET_RIGHT_PATH, fill: accent }),
148
- /* @__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 }) })
149
160
  ] }),
150
161
  variant === "full" && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("g", { transform: "scale(1,-1) translate(0,-640)", children: [
151
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 }) }),
152
- /* @__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 }) }) }),
153
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("g", { transform: "translate(1260,0)", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: A_PATH, fill: text }) }),
154
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("g", { transform: "translate(1860,0)", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: L_PATH, fill: text }) }),
155
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("g", { transform: "translate(2460,0)", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: C_PATH, fill: text }) }),
156
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("g", { transform: "translate(3060,0)", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: I_PATH, fill: text }) }),
157
- /* @__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 }) }),
158
169
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("g", { transform: "translate(4260,0)", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
159
170
  "path",
160
171
  {
161
172
  d: CURSOR_PATH,
162
173
  fill: accent,
163
- className: animated ? "valcis-cursor-blink" : void 0
174
+ className: isAnimated ? "valcis-cursor-blink" : void 0
164
175
  }
165
176
  ) })
166
177
  ] })
@@ -214,7 +225,7 @@ function useDevInfo(initialData, customUrl) {
214
225
  const response = await fetch(url, {
215
226
  signal: controller.signal,
216
227
  cache: "no-store",
217
- headers: { "Accept": "application/json" }
228
+ headers: { Accept: "application/json" }
218
229
  });
219
230
  if (!response.ok) throw new Error("Fetch failed");
220
231
  const data = await response.json();
@@ -265,7 +276,7 @@ var Footer = ({
265
276
  accentColor,
266
277
  backgroundColor,
267
278
  textColor,
268
- border = "top",
279
+ border: border2 = "top",
269
280
  padding = "normal",
270
281
  align = "center",
271
282
  position = "sticky",
@@ -306,8 +317,8 @@ var Footer = ({
306
317
  const logoColors = LOGO_COLORS[theme];
307
318
  const pad = typeof padding === "string" ? PADDING_MAP[padding] : { x: padding.x ?? "1rem", y: padding.y ?? "1rem" };
308
319
  const borderColor = c.border;
309
- const borderTop = border === true || border === "top" || border === "both" ? `1px solid ${borderColor}` : "none";
310
- 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";
311
322
  const positionStyles = {};
312
323
  if (position === "sticky") {
313
324
  positionStyles.position = "sticky";
@@ -387,11 +398,17 @@ var Footer = ({
387
398
  "aria-label": `Visitar sitio web de ${devInfo.brand} (abre en nueva pesta\xF1a)`,
388
399
  children: logoElement
389
400
  }
390
- ) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: {
391
- display: "inline-flex",
392
- alignItems: "center",
393
- padding: "0.35rem 0.5rem"
394
- }, 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
+ );
395
412
  return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
396
413
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("style", { children: dynamicStyles }),
397
414
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
@@ -430,7 +447,7 @@ async function getDevInfo(customUrl) {
430
447
  const url = customUrl || DEV_INFO_URL;
431
448
  const response = await fetch(url, {
432
449
  signal: controller.signal,
433
- headers: { "Accept": "application/json" }
450
+ headers: { Accept: "application/json" }
434
451
  });
435
452
  if (!response.ok) {
436
453
  throw new Error(`HTTP ${response.status}`);
@@ -450,6 +467,299 @@ async function getDevInfo(customUrl) {
450
467
  clearTimeout(timeoutId);
451
468
  }
452
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();
453
763
  // Annotate the CommonJS export names for ESM import in node:
454
764
  0 && (module.exports = {
455
765
  ASPECT_RATIOS,
@@ -470,9 +780,19 @@ async function getDevInfo(customUrl) {
470
780
  L_PATH,
471
781
  Logo,
472
782
  S_PATH,
783
+ Spinner,
473
784
  VIEWBOXES,
474
785
  V_CALLIGRAPHIC_FULL_TRANSFORM,
475
786
  V_CALLIGRAPHIC_PATH,
787
+ Watermark,
788
+ background,
789
+ border,
790
+ colors,
791
+ cssVariables,
476
792
  getDevInfo,
477
- useDevInfo
793
+ primary,
794
+ semantic,
795
+ text,
796
+ useDevInfo,
797
+ useTheme
478
798
  });