@calimero-network/mero-react 1.1.0 → 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.cjs CHANGED
@@ -5,7 +5,30 @@ var meroJs = require('@calimero-network/mero-js');
5
5
  var jsxRuntime = require('react/jsx-runtime');
6
6
  var reactDom = require('react-dom');
7
7
 
8
- // src/context/MeroContext.tsx
8
+ // #style-inject:#style-inject
9
+ function styleInject(css, { insertAt } = {}) {
10
+ if (typeof document === "undefined") return;
11
+ const head = document.head || document.getElementsByTagName("head")[0];
12
+ const style = document.createElement("style");
13
+ style.type = "text/css";
14
+ if (insertAt === "top") {
15
+ if (head.firstChild) {
16
+ head.insertBefore(style, head.firstChild);
17
+ } else {
18
+ head.appendChild(style);
19
+ }
20
+ } else {
21
+ head.appendChild(style);
22
+ }
23
+ if (style.styleSheet) {
24
+ style.styleSheet.cssText = css;
25
+ } else {
26
+ style.appendChild(document.createTextNode(css));
27
+ }
28
+ }
29
+
30
+ // src/components/styles.css
31
+ styleInject(':root {\n --mero-bg: #0d1117;\n --mero-bg-secondary: #161b22;\n --mero-bg-tertiary: #1c2128;\n --mero-text: #e6edf3;\n --mero-text-secondary: #8b949e;\n --mero-accent: #a5ff11;\n --mero-accent-hover: #8ed40d;\n --mero-on-primary: #0d1117;\n --mero-error: #ff6b6b;\n --mero-border: #30363d;\n --mero-disabled: #555555;\n --mero-shadow: rgba(0, 0, 0, 0.5);\n --mero-overlay: rgba(0, 0, 0, 0.75);\n --mero-radius: 8px;\n}\n.mero-connect-button {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n padding: 10px 20px;\n background-color: var(--mero-accent);\n border: 1px solid var(--mero-accent);\n border-radius: var(--mero-radius);\n cursor: pointer;\n font-size: 14px;\n font-weight: 600;\n letter-spacing: 0.01em;\n color: var(--mero-on-primary);\n transition:\n background-color 0.15s ease,\n border-color 0.15s ease,\n box-shadow 0.15s ease,\n transform 0.1s ease;\n min-width: 140px;\n box-sizing: border-box;\n font-family:\n "Inter",\n -apple-system,\n BlinkMacSystemFont,\n "Segoe UI",\n Roboto,\n Oxygen,\n Ubuntu,\n sans-serif;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n line-height: 1;\n}\n.mero-connect-button:hover:not(.mero-connected):not(.mero-reconnecting) {\n background-color: var(--mero-accent-hover);\n border-color: var(--mero-accent-hover);\n box-shadow: 0 0 0 4px rgba(165, 255, 17, 0.18);\n box-shadow: 0 0 0 4px color-mix(in srgb, var(--mero-accent) 18%, transparent);\n}\n.mero-connect-button:active:not(.mero-connected):not(.mero-reconnecting) {\n transform: translateY(1px);\n}\n.mero-connect-button:focus-visible {\n outline: none;\n box-shadow: 0 0 0 3px rgba(165, 255, 17, 0.45);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mero-accent) 45%, transparent);\n}\n.mero-connect-button.mero-logo-only {\n min-width: 0;\n width: 40px;\n height: 40px;\n padding: 0;\n gap: 0;\n}\n.mero-connect-button.mero-connected {\n background-color: var(--mero-accent);\n color: var(--mero-on-primary);\n border-color: var(--mero-accent);\n}\n.mero-connect-button.mero-connected:hover {\n background-color: var(--mero-accent-hover);\n border-color: var(--mero-accent-hover);\n}\n.mero-connect-button.mero-reconnecting {\n background-color: var(--mero-bg-secondary);\n color: var(--mero-text-secondary);\n border-color: var(--mero-border);\n cursor: not-allowed;\n}\n.mero-connect-container {\n position: relative;\n display: inline-block;\n}\n.mero-dropdown {\n position: absolute;\n top: 100%;\n left: 0;\n background-color: var(--mero-bg-secondary);\n border: 1px solid var(--mero-border);\n border-radius: var(--mero-radius);\n margin-top: 6px;\n padding: 0;\n z-index: 1001;\n width: 100%;\n min-width: 180px;\n overflow: hidden;\n box-shadow: 0 8px 24px var(--mero-shadow);\n}\n.mero-dropdown-info {\n padding: 10px 16px;\n color: var(--mero-text-secondary);\n font-size: 13px;\n border-bottom: 1px solid var(--mero-border);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n max-width: 220px;\n}\n.mero-dropdown-item {\n display: block;\n width: 100%;\n padding: 10px 16px;\n background: none;\n border: none;\n color: var(--mero-text);\n text-align: left;\n cursor: pointer;\n font-size: 14px;\n text-decoration: none;\n font-family: inherit;\n}\n.mero-dropdown-item:hover {\n background-color: var(--mero-accent);\n color: var(--mero-on-primary);\n}\n.mero-logo {\n width: 24px;\n height: 24px;\n color: currentColor;\n}\n@keyframes meroFadeIn {\n from {\n opacity: 0;\n }\n to {\n opacity: 1;\n }\n}\n@keyframes meroSlideIn {\n from {\n transform: translateY(-12px);\n opacity: 0;\n }\n to {\n transform: translateY(0);\n opacity: 1;\n }\n}\n@keyframes meroSpin {\n to {\n transform: rotate(360deg);\n }\n}\n');
9
32
 
10
33
  // src/types.ts
11
34
  var AppMode = /* @__PURE__ */ ((AppMode2) => {
@@ -370,6 +393,101 @@ function useMero() {
370
393
  }
371
394
  return context;
372
395
  }
396
+ function CalimeroLogo({
397
+ size = 24,
398
+ color,
399
+ style,
400
+ ...rest
401
+ }) {
402
+ return /* @__PURE__ */ jsxRuntime.jsxs(
403
+ "svg",
404
+ {
405
+ width: size,
406
+ height: size,
407
+ viewBox: "0 0 193 193",
408
+ fill: color ?? "currentColor",
409
+ style,
410
+ xmlns: "http://www.w3.org/2000/svg",
411
+ "aria-hidden": "true",
412
+ ...rest,
413
+ children: [
414
+ /* @__PURE__ */ jsxRuntime.jsx(
415
+ "path",
416
+ {
417
+ fillRule: "evenodd",
418
+ clipRule: "evenodd",
419
+ d: "M13.5969 23.2235C63.4924 -4.81833 123.53 2.55678 148.374 10.0273C153.006 11.4201 155.606 16.2198 154.181 20.7478C152.757 25.2758 147.846 27.8173 143.214 26.4245C120.866 19.7045 66.3988 13.3369 22.3442 38.0961C21.3748 38.6409 20.8298 39.6384 20.8808 40.6778C22.5544 74.7376 40.6646 139.735 103.059 173.709C107.293 176.015 108.813 181.238 106.455 185.377C104.096 189.516 98.7523 191.002 94.5186 188.696C24.7767 150.721 5.18199 78.7606 3.35124 41.5008C2.98177 33.9812 6.96683 26.9496 13.5969 23.2235Z"
420
+ }
421
+ ),
422
+ /* @__PURE__ */ jsxRuntime.jsx(
423
+ "path",
424
+ {
425
+ fillRule: "evenodd",
426
+ clipRule: "evenodd",
427
+ d: "M180.214 22.5271C185.054 22.2785 189.183 25.9121 189.437 30.6429C192.776 92.7591 159.782 138.316 138.517 157.587C133.185 162.419 125.221 164.303 117.934 161.241C102.817 154.887 88.1835 141.52 76.3001 128.189C64.2403 114.66 54.1712 100.2 48.3006 90.492C45.8345 86.4139 47.2173 81.1537 51.3891 78.743C55.561 76.3323 60.9421 77.684 63.4082 81.7621C68.803 90.6832 78.2588 104.272 89.5315 116.919C100.981 129.763 113.488 140.698 124.866 145.48C125.179 145.612 125.851 145.671 126.586 145.006C145.206 128.132 174.903 87.1988 171.912 31.5431C171.657 26.8122 175.374 22.7756 180.214 22.5271Z"
428
+ }
429
+ ),
430
+ /* @__PURE__ */ jsxRuntime.jsx(
431
+ "path",
432
+ {
433
+ fillRule: "evenodd",
434
+ clipRule: "evenodd",
435
+ d: "M85.9137 55.4487C70.263 57.0264 57.2007 60.7039 50.4014 63.4262C45.9168 65.2218 40.7922 63.1236 38.9553 58.7397C37.1184 54.3559 39.2649 49.3464 43.7495 47.5508C52.2083 44.164 66.9167 40.1173 84.1135 38.3837C101.323 36.649 121.62 37.1693 140.947 43.4423C149.244 46.1351 155.088 53.9217 154.482 62.8728C153.225 81.429 144.514 100.403 127.158 122.145C124.177 125.88 118.663 126.546 114.842 123.631C111.021 120.717 110.341 115.327 113.322 111.592C129.481 91.3484 136.032 75.6017 136.971 61.7394C137.02 61.0029 136.547 60.0904 135.417 59.7238C119.18 54.4537 101.552 53.8722 85.9137 55.4487Z"
436
+ }
437
+ )
438
+ ]
439
+ }
440
+ );
441
+ }
442
+
443
+ // src/theme.ts
444
+ var defaultMeroTheme = Object.freeze({
445
+ primary: "#a5ff11",
446
+ primaryHover: "#8ed40d",
447
+ primaryText: "#0d1117",
448
+ background: "#0d1117",
449
+ backgroundSecondary: "#161b22",
450
+ backgroundTertiary: "#1c2128",
451
+ border: "#30363d",
452
+ text: "#e6edf3",
453
+ textSecondary: "#8b949e",
454
+ error: "#ff6b6b",
455
+ overlay: "rgba(0, 0, 0, 0.75)",
456
+ radius: "8px"
457
+ });
458
+ function resolveMeroTheme(theme) {
459
+ if (!theme) return { ...defaultMeroTheme };
460
+ const filtered = Object.fromEntries(
461
+ Object.entries(theme).filter(
462
+ ([, v]) => v !== void 0 && typeof v === "string" && v.trim() !== ""
463
+ )
464
+ );
465
+ return { ...defaultMeroTheme, ...filtered };
466
+ }
467
+ var MERO_CSS_VARS = {
468
+ background: "--mero-bg",
469
+ backgroundSecondary: "--mero-bg-secondary",
470
+ backgroundTertiary: "--mero-bg-tertiary",
471
+ text: "--mero-text",
472
+ textSecondary: "--mero-text-secondary",
473
+ primary: "--mero-accent",
474
+ primaryHover: "--mero-accent-hover",
475
+ primaryText: "--mero-on-primary",
476
+ border: "--mero-border",
477
+ error: "--mero-error",
478
+ overlay: "--mero-overlay",
479
+ radius: "--mero-radius"
480
+ };
481
+ function themeToCssVars(theme) {
482
+ const vars = {};
483
+ for (const key of Object.keys(MERO_CSS_VARS)) {
484
+ vars[MERO_CSS_VARS[key]] = theme[key];
485
+ }
486
+ return vars;
487
+ }
488
+ function cssVar(theme, key) {
489
+ return `var(${MERO_CSS_VARS[key]}, ${theme[key]})`;
490
+ }
373
491
  function isValidUrl(urlString) {
374
492
  if (!urlString || urlString.trim() === "") {
375
493
  return false;
@@ -398,161 +516,194 @@ function isValidUrl(urlString) {
398
516
  return false;
399
517
  }
400
518
  }
401
- var styles = {
402
- overlay: {
403
- position: "fixed",
404
- top: 0,
405
- left: 0,
406
- right: 0,
407
- bottom: 0,
408
- backgroundColor: "rgba(0, 0, 0, 0.75)",
409
- display: "flex",
410
- alignItems: "center",
411
- justifyContent: "center",
412
- zIndex: 1e4,
413
- padding: "1rem"
414
- },
415
- content: {
416
- backgroundColor: "#1f2937",
417
- borderRadius: "12px",
418
- padding: "2rem",
419
- maxWidth: "400px",
420
- width: "100%",
421
- position: "relative",
422
- border: "1px solid #374151",
423
- boxShadow: "0 25px 50px -12px rgba(0, 0, 0, 0.5)"
424
- },
425
- closeButton: {
426
- position: "absolute",
427
- top: "1rem",
428
- right: "1rem",
429
- background: "none",
430
- border: "none",
431
- fontSize: "1.5rem",
432
- color: "#9ca3af",
433
- cursor: "pointer",
434
- padding: "0.25rem",
435
- lineHeight: 1
436
- },
437
- header: {
438
- display: "flex",
439
- flexDirection: "column",
440
- alignItems: "center",
441
- gap: "0.75rem",
442
- marginBottom: "1.5rem"
443
- },
444
- title: {
445
- fontSize: "1.25rem",
446
- fontWeight: 600,
447
- color: "#f3f4f6",
448
- margin: 0
449
- },
450
- info: {
451
- color: "#9ca3af",
452
- textAlign: "center",
453
- marginBottom: "1.5rem",
454
- fontSize: "0.875rem"
455
- },
456
- error: {
457
- color: "#ef4444",
458
- backgroundColor: "rgba(239, 68, 68, 0.1)",
459
- border: "1px solid rgba(239, 68, 68, 0.3)",
460
- borderRadius: "6px",
461
- padding: "0.75rem",
462
- marginBottom: "1rem",
463
- fontSize: "0.875rem",
464
- textAlign: "center"
465
- },
466
- radioGroup: {
467
- display: "flex",
468
- gap: "1rem",
469
- marginBottom: "1rem",
470
- justifyContent: "center"
471
- },
472
- radioLabel: {
473
- display: "flex",
474
- alignItems: "center",
475
- gap: "0.5rem",
476
- color: "#e5e7eb",
477
- cursor: "pointer",
478
- padding: "0.5rem 1rem",
479
- borderRadius: "6px",
480
- border: "1px solid #374151",
481
- backgroundColor: "#111827",
482
- transition: "all 0.2s"
483
- },
484
- radioLabelActive: {
485
- borderColor: "#3b82f6",
486
- backgroundColor: "rgba(59, 130, 246, 0.1)"
487
- },
488
- input: {
489
- width: "100%",
490
- padding: "0.75rem 1rem",
491
- borderRadius: "6px",
492
- border: "1px solid #374151",
493
- backgroundColor: "#111827",
494
- color: "#f3f4f6",
495
- fontSize: "0.875rem",
496
- outline: "none",
497
- marginBottom: "1rem",
498
- boxSizing: "border-box"
499
- },
500
- localInfo: {
501
- color: "#9ca3af",
502
- fontSize: "0.875rem",
503
- textAlign: "center",
504
- padding: "0.75rem",
505
- backgroundColor: "#111827",
506
- borderRadius: "6px",
507
- marginBottom: "1rem"
508
- },
509
- buttonGroup: {
510
- display: "flex",
511
- justifyContent: "center"
512
- },
513
- button: {
514
- padding: "0.75rem 2rem",
515
- borderRadius: "6px",
516
- border: "none",
517
- fontSize: "0.875rem",
518
- fontWeight: 600,
519
- cursor: "pointer",
520
- backgroundColor: "#3b82f6",
521
- color: "white",
522
- transition: "all 0.2s"
523
- },
524
- buttonDisabled: {
525
- opacity: 0.5,
526
- cursor: "not-allowed"
527
- },
528
- loading: {
529
- display: "flex",
530
- flexDirection: "column",
531
- alignItems: "center",
532
- gap: "1rem",
533
- padding: "2rem",
534
- color: "#9ca3af"
535
- },
536
- spinner: {
537
- width: "2rem",
538
- height: "2rem",
539
- border: "3px solid #374151",
540
- borderTopColor: "#3b82f6",
541
- borderRadius: "50%",
542
- animation: "spin 1s linear infinite"
543
- }
544
- };
519
+ function tint(color, percent) {
520
+ return `color-mix(in srgb, ${color} ${percent}%, transparent)`;
521
+ }
522
+ function buildStyles(t) {
523
+ const bg = cssVar(t, "background");
524
+ const bgSecondary = cssVar(t, "backgroundSecondary");
525
+ const text = cssVar(t, "text");
526
+ const textSecondary = cssVar(t, "textSecondary");
527
+ const accent = cssVar(t, "primary");
528
+ const onPrimary = cssVar(t, "primaryText");
529
+ const border = cssVar(t, "border");
530
+ const error = cssVar(t, "error");
531
+ const overlay = cssVar(t, "overlay");
532
+ const radius = cssVar(t, "radius");
533
+ const errorBg = tint(error, 10);
534
+ const errorBorder = tint(error, 30);
535
+ const accentGlow = tint(accent, 15);
536
+ return {
537
+ overlay: {
538
+ position: "fixed",
539
+ top: 0,
540
+ left: 0,
541
+ right: 0,
542
+ bottom: 0,
543
+ backgroundColor: overlay,
544
+ display: "flex",
545
+ alignItems: "center",
546
+ justifyContent: "center",
547
+ zIndex: 1e4,
548
+ padding: "1rem",
549
+ animation: "meroFadeIn 0.2s ease-out"
550
+ },
551
+ content: {
552
+ backgroundColor: bg,
553
+ borderRadius: radius,
554
+ padding: "2rem",
555
+ maxWidth: "420px",
556
+ width: "100%",
557
+ position: "relative",
558
+ border: `1px solid ${border}`,
559
+ boxShadow: `0 25px 50px -12px rgba(0, 0, 0, 0.6), 0 0 0 1px ${accentGlow}`,
560
+ animation: "meroSlideIn 0.25s ease-out",
561
+ color: text
562
+ },
563
+ closeButton: {
564
+ position: "absolute",
565
+ top: "0.75rem",
566
+ right: "0.75rem",
567
+ background: "none",
568
+ border: "none",
569
+ fontSize: "1.5rem",
570
+ color: textSecondary,
571
+ cursor: "pointer",
572
+ padding: "0.25rem",
573
+ lineHeight: 1
574
+ },
575
+ header: {
576
+ display: "flex",
577
+ flexDirection: "column",
578
+ alignItems: "center",
579
+ gap: "0.75rem",
580
+ marginBottom: "1.5rem"
581
+ },
582
+ title: {
583
+ fontSize: "1.25rem",
584
+ fontWeight: 600,
585
+ color: text,
586
+ margin: 0
587
+ },
588
+ info: {
589
+ color: textSecondary,
590
+ textAlign: "center",
591
+ marginBottom: "1.5rem",
592
+ fontSize: "0.875rem"
593
+ },
594
+ error: {
595
+ color: error,
596
+ backgroundColor: errorBg,
597
+ border: `1px solid ${errorBorder}`,
598
+ borderRadius: radius,
599
+ padding: "0.75rem",
600
+ marginBottom: "1rem",
601
+ fontSize: "0.875rem",
602
+ textAlign: "center"
603
+ },
604
+ radioGroup: {
605
+ display: "flex",
606
+ gap: "0.75rem",
607
+ marginBottom: "1rem",
608
+ justifyContent: "center"
609
+ },
610
+ radioLabel: {
611
+ display: "flex",
612
+ alignItems: "center",
613
+ gap: "0.5rem",
614
+ color: text,
615
+ cursor: "pointer",
616
+ padding: "0.5rem 1rem",
617
+ borderRadius: radius,
618
+ border: `1px solid ${border}`,
619
+ backgroundColor: bgSecondary,
620
+ transition: "all 0.15s ease"
621
+ },
622
+ radioLabelActive: {
623
+ borderColor: accent,
624
+ backgroundColor: accentGlow,
625
+ color: text
626
+ },
627
+ input: {
628
+ width: "100%",
629
+ padding: "0.75rem 1rem",
630
+ borderRadius: radius,
631
+ border: `1px solid ${border}`,
632
+ backgroundColor: bgSecondary,
633
+ color: text,
634
+ fontSize: "0.875rem",
635
+ outline: "none",
636
+ marginBottom: "1rem",
637
+ boxSizing: "border-box"
638
+ },
639
+ localInfo: {
640
+ color: textSecondary,
641
+ fontSize: "0.875rem",
642
+ textAlign: "center",
643
+ padding: "0.75rem",
644
+ backgroundColor: bgSecondary,
645
+ borderRadius: radius,
646
+ marginBottom: "1rem",
647
+ border: `1px solid ${border}`
648
+ },
649
+ localInfoCode: {
650
+ color: accent
651
+ },
652
+ buttonGroup: {
653
+ display: "flex",
654
+ justifyContent: "center"
655
+ },
656
+ button: {
657
+ padding: "0.75rem 2rem",
658
+ borderRadius: radius,
659
+ border: "none",
660
+ fontSize: "0.875rem",
661
+ fontWeight: 600,
662
+ cursor: "pointer",
663
+ backgroundColor: accent,
664
+ color: onPrimary,
665
+ transition: "all 0.15s ease"
666
+ },
667
+ buttonDisabled: {
668
+ opacity: 0.5,
669
+ cursor: "not-allowed"
670
+ },
671
+ loading: {
672
+ display: "flex",
673
+ flexDirection: "column",
674
+ alignItems: "center",
675
+ gap: "1rem",
676
+ padding: "2rem",
677
+ color: textSecondary
678
+ },
679
+ spinner: {
680
+ width: "2rem",
681
+ height: "2rem",
682
+ border: `3px solid ${border}`,
683
+ borderTopColor: accent,
684
+ borderRadius: "50%",
685
+ animation: "meroSpin 1s linear infinite"
686
+ }
687
+ };
688
+ }
545
689
  function LoginModal({
546
690
  onConnect,
547
691
  onClose,
548
692
  connectionType,
549
- isOpen
693
+ isOpen,
694
+ theme
550
695
  }) {
551
696
  const [nodeType, setNodeType] = react.useState("local");
552
697
  const [nodeUrl, setNodeUrl2] = react.useState("");
553
698
  const [isValid, setIsValid] = react.useState(true);
554
699
  const [loading, setLoading] = react.useState(false);
555
700
  const [error, setError] = react.useState(null);
701
+ const resolved = react.useMemo(() => resolveMeroTheme(theme), [theme]);
702
+ const styles = react.useMemo(() => buildStyles(resolved), [resolved]);
703
+ const themeVars = react.useMemo(
704
+ () => theme ? themeToCssVars(resolved) : void 0,
705
+ [theme, resolved]
706
+ );
556
707
  const shouldShowLocal = connectionType === "remote-and-local" /* RemoteAndLocal */ || connectionType === "local" /* Local */;
557
708
  const shouldShowRemote = connectionType === "remote-and-local" /* RemoteAndLocal */ || connectionType === "remote" /* Remote */;
558
709
  const shouldShowRadioGroup = shouldShowLocal && shouldShowRemote;
@@ -603,14 +754,14 @@ function LoginModal({
603
754
  }
604
755
  const modalContent = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
605
756
  /* @__PURE__ */ jsxRuntime.jsx("style", { children: `
606
- @keyframes spin {
607
- to { transform: rotate(360deg); }
608
- }
757
+ @keyframes meroSpin { to { transform: rotate(360deg); } }
758
+ @keyframes meroFadeIn { from { opacity: 0; } to { opacity: 1; } }
759
+ @keyframes meroSlideIn { from { transform: translateY(-12px); opacity: 0; } to { transform: translateY(0); opacity: 1; } }
609
760
  ` }),
610
- /* @__PURE__ */ jsxRuntime.jsx("div", { style: styles.overlay, onClick: onClose, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles.content, onClick: (e) => e.stopPropagation(), children: [
761
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: { ...themeVars, ...styles.overlay }, onClick: onClose, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles.content, onClick: (e) => e.stopPropagation(), children: [
611
762
  /* @__PURE__ */ jsxRuntime.jsx("button", { style: styles.closeButton, onClick: onClose, children: "\xD7" }),
612
763
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles.header, children: [
613
- /* @__PURE__ */ jsxRuntime.jsx(MeroLogo, {}),
764
+ /* @__PURE__ */ jsxRuntime.jsx(CalimeroLogo, { size: 44, color: cssVar(resolved, "primary") }),
614
765
  /* @__PURE__ */ jsxRuntime.jsx("h1", { style: styles.title, children: "Connect to Calimero" })
615
766
  ] }),
616
767
  loading ? /* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles.loading, children: [
@@ -639,7 +790,7 @@ function LoginModal({
639
790
  style: { display: "none" }
640
791
  }
641
792
  ),
642
- "\u{1F3E0} Local"
793
+ "Local"
643
794
  ]
644
795
  }
645
796
  ),
@@ -662,7 +813,7 @@ function LoginModal({
662
813
  style: { display: "none" }
663
814
  }
664
815
  ),
665
- "\u{1F310} Remote"
816
+ "Remote"
666
817
  ]
667
818
  }
668
819
  )
@@ -684,7 +835,7 @@ function LoginModal({
684
835
  ) : shouldShowLocal ? /* @__PURE__ */ jsxRuntime.jsxs("p", { style: styles.localInfo, children: [
685
836
  "Using default local node: ",
686
837
  /* @__PURE__ */ jsxRuntime.jsx("br", {}),
687
- /* @__PURE__ */ jsxRuntime.jsx("code", { style: { color: "#60a5fa" }, children: "http://node1.127.0.0.1.nip.io" })
838
+ /* @__PURE__ */ jsxRuntime.jsx("code", { style: styles.localInfoCode, children: "http://node1.127.0.0.1.nip.io" })
688
839
  ] }) : null }),
689
840
  /* @__PURE__ */ jsxRuntime.jsx("div", { style: styles.buttonGroup, children: /* @__PURE__ */ jsxRuntime.jsx(
690
841
  "button",
@@ -703,28 +854,26 @@ function LoginModal({
703
854
  ] });
704
855
  return reactDom.createPortal(modalContent, document.body);
705
856
  }
706
- function MeroLogo() {
707
- return /* @__PURE__ */ jsxRuntime.jsx(
708
- "svg",
709
- {
710
- width: "40",
711
- height: "40",
712
- viewBox: "0 0 24 24",
713
- fill: "#3b82f6",
714
- xmlns: "http://www.w3.org/2000/svg",
715
- children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8zm-1-13h2v6h-2zm0 8h2v2h-2z" })
716
- }
717
- );
718
- }
719
857
  function ConnectButton({
720
858
  connectionType = "remote-and-local" /* RemoteAndLocal */,
721
859
  className,
722
- style
860
+ style,
861
+ theme,
862
+ logoOnly = false,
863
+ label
723
864
  }) {
724
865
  const { isAuthenticated, connectToNode, logout, nodeUrl, isOnline } = useMero();
725
866
  const [isDropdownOpen, setIsDropdownOpen] = react.useState(false);
726
867
  const [isModalOpen, setIsModalOpen] = react.useState(false);
727
868
  const dropdownRef = react.useRef(null);
869
+ const resolvedTheme = react.useMemo(
870
+ () => theme ? resolveMeroTheme(theme) : null,
871
+ [theme]
872
+ );
873
+ const themeVars = react.useMemo(
874
+ () => resolvedTheme ? themeToCssVars(resolvedTheme) : void 0,
875
+ [resolvedTheme]
876
+ );
728
877
  react.useEffect(() => {
729
878
  const handleClickOutside = (event) => {
730
879
  if (dropdownRef.current && !dropdownRef.current.contains(event.target)) {
@@ -738,6 +887,15 @@ function ConnectButton({
738
887
  if (!isAuthenticated || !nodeUrl) return "#";
739
888
  return new URL("admin-dashboard/", nodeUrl).toString();
740
889
  }, [isAuthenticated, nodeUrl]);
890
+ const labels = react.useMemo(() => {
891
+ const overrides = typeof label === "string" ? { connect: label } : label;
892
+ return {
893
+ connect: overrides?.connect ?? "Connect",
894
+ connected: overrides?.connected ?? "Connected",
895
+ reconnecting: overrides?.reconnecting ?? "Reconnecting..."
896
+ };
897
+ }, [label]);
898
+ const buttonClassName = logoOnly ? "mero-logo-only" : "";
741
899
  const handleConnect = () => {
742
900
  if (typeof connectionType === "object" && connectionType.type === "custom" /* Custom */) {
743
901
  connectToNode(connectionType.url);
@@ -750,94 +908,109 @@ function ConnectButton({
750
908
  connectToNode(url);
751
909
  };
752
910
  if (isAuthenticated && !isOnline) {
911
+ return /* @__PURE__ */ jsxRuntime.jsx(
912
+ "div",
913
+ {
914
+ className: "mero-connect-container",
915
+ style: { ...themeVars, display: "inline-block" },
916
+ children: /* @__PURE__ */ jsxRuntime.jsxs(
917
+ "button",
918
+ {
919
+ className: ["mero-connect-button", "mero-reconnecting", buttonClassName, className].filter(Boolean).join(" "),
920
+ style,
921
+ disabled: true,
922
+ "aria-label": labels.reconnecting,
923
+ title: logoOnly ? labels.reconnecting : void 0,
924
+ children: [
925
+ /* @__PURE__ */ jsxRuntime.jsx(CalimeroLogo, { size: 18, className: "mero-logo" }),
926
+ !logoOnly && labels.reconnecting
927
+ ]
928
+ }
929
+ )
930
+ }
931
+ );
932
+ }
933
+ if (isAuthenticated) {
753
934
  return /* @__PURE__ */ jsxRuntime.jsxs(
754
- "button",
935
+ "div",
755
936
  {
756
- className: `mero-connect-button mero-reconnecting ${className || ""}`,
757
- style,
758
- disabled: true,
937
+ ref: dropdownRef,
938
+ className: "mero-connect-container",
939
+ style: { ...themeVars, position: "relative", display: "inline-block" },
759
940
  children: [
760
- /* @__PURE__ */ jsxRuntime.jsx(MeroLogo2, {}),
761
- "Reconnecting..."
941
+ /* @__PURE__ */ jsxRuntime.jsxs(
942
+ "button",
943
+ {
944
+ className: ["mero-connect-button", "mero-connected", buttonClassName, className].filter(Boolean).join(" "),
945
+ style,
946
+ onClick: () => setIsDropdownOpen((prev) => !prev),
947
+ "aria-label": labels.connected,
948
+ title: logoOnly ? labels.connected : void 0,
949
+ children: [
950
+ /* @__PURE__ */ jsxRuntime.jsx(CalimeroLogo, { size: 18, className: "mero-logo" }),
951
+ !logoOnly && labels.connected
952
+ ]
953
+ }
954
+ ),
955
+ isDropdownOpen && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mero-dropdown", children: [
956
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mero-dropdown-info", title: nodeUrl || "", children: nodeUrl }),
957
+ /* @__PURE__ */ jsxRuntime.jsx(
958
+ "a",
959
+ {
960
+ href: dashboardUrl,
961
+ target: "_blank",
962
+ rel: "noopener noreferrer",
963
+ className: "mero-dropdown-item",
964
+ children: "Dashboard"
965
+ }
966
+ ),
967
+ /* @__PURE__ */ jsxRuntime.jsx(
968
+ "button",
969
+ {
970
+ className: "mero-dropdown-item",
971
+ onClick: () => {
972
+ setIsDropdownOpen(false);
973
+ logout();
974
+ },
975
+ children: "Log out"
976
+ }
977
+ )
978
+ ] })
762
979
  ]
763
980
  }
764
981
  );
765
982
  }
766
- if (isAuthenticated) {
767
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { ref: dropdownRef, className: "mero-connect-container", style: { position: "relative", display: "inline-block" }, children: [
768
- /* @__PURE__ */ jsxRuntime.jsxs(
769
- "button",
770
- {
771
- className: `mero-connect-button mero-connected ${className || ""}`,
772
- style,
773
- onClick: () => setIsDropdownOpen((prev) => !prev),
774
- children: [
775
- /* @__PURE__ */ jsxRuntime.jsx(MeroLogo2, {}),
776
- "Connected"
777
- ]
778
- }
779
- ),
780
- isDropdownOpen && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mero-dropdown", children: [
781
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mero-dropdown-info", title: nodeUrl || "", children: nodeUrl }),
782
- /* @__PURE__ */ jsxRuntime.jsx(
783
- "a",
983
+ return /* @__PURE__ */ jsxRuntime.jsxs(
984
+ "div",
985
+ {
986
+ className: "mero-connect-container",
987
+ style: { ...themeVars, display: "inline-block" },
988
+ children: [
989
+ /* @__PURE__ */ jsxRuntime.jsxs(
990
+ "button",
784
991
  {
785
- href: dashboardUrl,
786
- target: "_blank",
787
- rel: "noopener noreferrer",
788
- className: "mero-dropdown-item",
789
- children: "Dashboard"
992
+ className: ["mero-connect-button", buttonClassName, className].filter(Boolean).join(" "),
993
+ style,
994
+ onClick: handleConnect,
995
+ "aria-label": labels.connect,
996
+ title: logoOnly ? labels.connect : void 0,
997
+ children: [
998
+ /* @__PURE__ */ jsxRuntime.jsx(CalimeroLogo, { size: 18, className: "mero-logo" }),
999
+ !logoOnly && labels.connect
1000
+ ]
790
1001
  }
791
1002
  ),
792
1003
  /* @__PURE__ */ jsxRuntime.jsx(
793
- "button",
1004
+ LoginModal,
794
1005
  {
795
- className: "mero-dropdown-item",
796
- onClick: () => {
797
- setIsDropdownOpen(false);
798
- logout();
799
- },
800
- children: "Log out"
1006
+ isOpen: isModalOpen,
1007
+ onConnect: handleModalConnect,
1008
+ onClose: () => setIsModalOpen(false),
1009
+ connectionType: typeof connectionType === "object" ? "remote-and-local" /* RemoteAndLocal */ : connectionType,
1010
+ theme: resolvedTheme ?? theme
801
1011
  }
802
1012
  )
803
- ] })
804
- ] });
805
- }
806
- return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
807
- /* @__PURE__ */ jsxRuntime.jsxs(
808
- "button",
809
- {
810
- className: `mero-connect-button ${className || ""}`,
811
- style,
812
- onClick: handleConnect,
813
- children: [
814
- /* @__PURE__ */ jsxRuntime.jsx(MeroLogo2, {}),
815
- "Connect"
816
- ]
817
- }
818
- ),
819
- /* @__PURE__ */ jsxRuntime.jsx(
820
- LoginModal,
821
- {
822
- isOpen: isModalOpen,
823
- onConnect: handleModalConnect,
824
- onClose: () => setIsModalOpen(false),
825
- connectionType: typeof connectionType === "object" ? "remote-and-local" /* RemoteAndLocal */ : connectionType
826
- }
827
- )
828
- ] });
829
- }
830
- function MeroLogo2() {
831
- return /* @__PURE__ */ jsxRuntime.jsx(
832
- "svg",
833
- {
834
- className: "mero-logo",
835
- width: "24",
836
- height: "24",
837
- viewBox: "0 0 24 24",
838
- fill: "currentColor",
839
- xmlns: "http://www.w3.org/2000/svg",
840
- children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8zm-1-13h2v6h-2zm0 8h2v2h-2z" })
1013
+ ]
841
1014
  }
842
1015
  );
843
1016
  }
@@ -1725,17 +1898,17 @@ function useSetDefaultCapabilities() {
1725
1898
  );
1726
1899
  return { setDefaultCapabilities, loading, error };
1727
1900
  }
1728
- function useSetDefaultVisibility() {
1901
+ function useSetSubgroupVisibility() {
1729
1902
  const { mero } = useMero();
1730
1903
  const { loading, error, run } = useAsyncMutation();
1731
- const setDefaultVisibility = react.useCallback(
1904
+ const setSubgroupVisibility = react.useCallback(
1732
1905
  async (groupId, request) => {
1733
1906
  if (!mero) return null;
1734
- return run(() => mero.admin.setDefaultVisibility(groupId, request));
1907
+ return run(() => mero.admin.setSubgroupVisibility(groupId, request));
1735
1908
  },
1736
1909
  [mero, run]
1737
1910
  );
1738
- return { setDefaultVisibility, loading, error };
1911
+ return { setSubgroupVisibility, loading, error };
1739
1912
  }
1740
1913
  function useSetTeeAdmissionPolicy() {
1741
1914
  const { mero } = useMero();
@@ -1939,9 +2112,11 @@ function useDetachContextFromGroup() {
1939
2112
  }
1940
2113
 
1941
2114
  exports.AppMode = AppMode;
2115
+ exports.CalimeroLogo = CalimeroLogo;
1942
2116
  exports.ConnectButton = ConnectButton;
1943
2117
  exports.ConnectionType = ConnectionType;
1944
2118
  exports.LoginModal = LoginModal;
2119
+ exports.MERO_CSS_VARS = MERO_CSS_VARS;
1945
2120
  exports.MeroContext = MeroContext;
1946
2121
  exports.MeroProvider = MeroProvider;
1947
2122
  exports.clearAllStorage = clearAllStorage;
@@ -1949,15 +2124,19 @@ exports.clearApplicationId = clearApplicationId;
1949
2124
  exports.clearContextId = clearContextId;
1950
2125
  exports.clearContextIdentity = clearContextIdentity;
1951
2126
  exports.clearNodeUrl = clearNodeUrl;
2127
+ exports.cssVar = cssVar;
2128
+ exports.defaultMeroTheme = defaultMeroTheme;
1952
2129
  exports.getApplicationId = getApplicationId;
1953
2130
  exports.getContextId = getContextId;
1954
2131
  exports.getContextIdentity = getContextIdentity;
1955
2132
  exports.getNodeUrl = getNodeUrl;
1956
2133
  exports.localStorageTokenStorage = localStorageTokenStorage;
2134
+ exports.resolveMeroTheme = resolveMeroTheme;
1957
2135
  exports.setApplicationId = setApplicationId;
1958
2136
  exports.setContextId = setContextId;
1959
2137
  exports.setContextIdentity = setContextIdentity;
1960
2138
  exports.setNodeUrl = setNodeUrl;
2139
+ exports.themeToCssVars = themeToCssVars;
1961
2140
  exports.useAddGroupMembers = useAddGroupMembers;
1962
2141
  exports.useApplicationContexts = useApplicationContexts;
1963
2142
  exports.useContextDiscovery = useContextDiscovery;
@@ -1992,9 +2171,9 @@ exports.useRegisterGroupSigningKey = useRegisterGroupSigningKey;
1992
2171
  exports.useRemoveGroupMembers = useRemoveGroupMembers;
1993
2172
  exports.useRetryGroupUpgrade = useRetryGroupUpgrade;
1994
2173
  exports.useSetDefaultCapabilities = useSetDefaultCapabilities;
1995
- exports.useSetDefaultVisibility = useSetDefaultVisibility;
1996
2174
  exports.useSetGroupAlias = useSetGroupAlias;
1997
2175
  exports.useSetMemberAlias = useSetMemberAlias;
2176
+ exports.useSetSubgroupVisibility = useSetSubgroupVisibility;
1998
2177
  exports.useSetTeeAdmissionPolicy = useSetTeeAdmissionPolicy;
1999
2178
  exports.useSubgroups = useSubgroups;
2000
2179
  exports.useSubscription = useSubscription;