@calimero-network/mero-react 2.0.1 → 2.2.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
@@ -4,7 +4,30 @@ export * from '@calimero-network/mero-js';
4
4
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
5
5
  import { createPortal } from 'react-dom';
6
6
 
7
- // src/context/MeroContext.tsx
7
+ // #style-inject:#style-inject
8
+ function styleInject(css, { insertAt } = {}) {
9
+ if (typeof document === "undefined") return;
10
+ const head = document.head || document.getElementsByTagName("head")[0];
11
+ const style = document.createElement("style");
12
+ style.type = "text/css";
13
+ if (insertAt === "top") {
14
+ if (head.firstChild) {
15
+ head.insertBefore(style, head.firstChild);
16
+ } else {
17
+ head.appendChild(style);
18
+ }
19
+ } else {
20
+ head.appendChild(style);
21
+ }
22
+ if (style.styleSheet) {
23
+ style.styleSheet.cssText = css;
24
+ } else {
25
+ style.appendChild(document.createTextNode(css));
26
+ }
27
+ }
28
+
29
+ // src/components/styles.css
30
+ 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');
8
31
 
9
32
  // src/types.ts
10
33
  var AppMode = /* @__PURE__ */ ((AppMode2) => {
@@ -369,6 +392,101 @@ function useMero() {
369
392
  }
370
393
  return context;
371
394
  }
395
+ function CalimeroLogo({
396
+ size = 24,
397
+ color,
398
+ style,
399
+ ...rest
400
+ }) {
401
+ return /* @__PURE__ */ jsxs(
402
+ "svg",
403
+ {
404
+ width: size,
405
+ height: size,
406
+ viewBox: "0 0 193 193",
407
+ fill: color ?? "currentColor",
408
+ style,
409
+ xmlns: "http://www.w3.org/2000/svg",
410
+ "aria-hidden": "true",
411
+ ...rest,
412
+ children: [
413
+ /* @__PURE__ */ jsx(
414
+ "path",
415
+ {
416
+ fillRule: "evenodd",
417
+ clipRule: "evenodd",
418
+ 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"
419
+ }
420
+ ),
421
+ /* @__PURE__ */ jsx(
422
+ "path",
423
+ {
424
+ fillRule: "evenodd",
425
+ clipRule: "evenodd",
426
+ 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"
427
+ }
428
+ ),
429
+ /* @__PURE__ */ jsx(
430
+ "path",
431
+ {
432
+ fillRule: "evenodd",
433
+ clipRule: "evenodd",
434
+ 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"
435
+ }
436
+ )
437
+ ]
438
+ }
439
+ );
440
+ }
441
+
442
+ // src/theme.ts
443
+ var defaultMeroTheme = Object.freeze({
444
+ primary: "#a5ff11",
445
+ primaryHover: "#8ed40d",
446
+ primaryText: "#0d1117",
447
+ background: "#0d1117",
448
+ backgroundSecondary: "#161b22",
449
+ backgroundTertiary: "#1c2128",
450
+ border: "#30363d",
451
+ text: "#e6edf3",
452
+ textSecondary: "#8b949e",
453
+ error: "#ff6b6b",
454
+ overlay: "rgba(0, 0, 0, 0.75)",
455
+ radius: "8px"
456
+ });
457
+ function resolveMeroTheme(theme) {
458
+ if (!theme) return { ...defaultMeroTheme };
459
+ const filtered = Object.fromEntries(
460
+ Object.entries(theme).filter(
461
+ ([, v]) => v !== void 0 && typeof v === "string" && v.trim() !== ""
462
+ )
463
+ );
464
+ return { ...defaultMeroTheme, ...filtered };
465
+ }
466
+ var MERO_CSS_VARS = {
467
+ background: "--mero-bg",
468
+ backgroundSecondary: "--mero-bg-secondary",
469
+ backgroundTertiary: "--mero-bg-tertiary",
470
+ text: "--mero-text",
471
+ textSecondary: "--mero-text-secondary",
472
+ primary: "--mero-accent",
473
+ primaryHover: "--mero-accent-hover",
474
+ primaryText: "--mero-on-primary",
475
+ border: "--mero-border",
476
+ error: "--mero-error",
477
+ overlay: "--mero-overlay",
478
+ radius: "--mero-radius"
479
+ };
480
+ function themeToCssVars(theme) {
481
+ const vars = {};
482
+ for (const key of Object.keys(MERO_CSS_VARS)) {
483
+ vars[MERO_CSS_VARS[key]] = theme[key];
484
+ }
485
+ return vars;
486
+ }
487
+ function cssVar(theme, key) {
488
+ return `var(${MERO_CSS_VARS[key]}, ${theme[key]})`;
489
+ }
372
490
  function isValidUrl(urlString) {
373
491
  if (!urlString || urlString.trim() === "") {
374
492
  return false;
@@ -397,161 +515,194 @@ function isValidUrl(urlString) {
397
515
  return false;
398
516
  }
399
517
  }
400
- var styles = {
401
- overlay: {
402
- position: "fixed",
403
- top: 0,
404
- left: 0,
405
- right: 0,
406
- bottom: 0,
407
- backgroundColor: "rgba(0, 0, 0, 0.75)",
408
- display: "flex",
409
- alignItems: "center",
410
- justifyContent: "center",
411
- zIndex: 1e4,
412
- padding: "1rem"
413
- },
414
- content: {
415
- backgroundColor: "#1f2937",
416
- borderRadius: "12px",
417
- padding: "2rem",
418
- maxWidth: "400px",
419
- width: "100%",
420
- position: "relative",
421
- border: "1px solid #374151",
422
- boxShadow: "0 25px 50px -12px rgba(0, 0, 0, 0.5)"
423
- },
424
- closeButton: {
425
- position: "absolute",
426
- top: "1rem",
427
- right: "1rem",
428
- background: "none",
429
- border: "none",
430
- fontSize: "1.5rem",
431
- color: "#9ca3af",
432
- cursor: "pointer",
433
- padding: "0.25rem",
434
- lineHeight: 1
435
- },
436
- header: {
437
- display: "flex",
438
- flexDirection: "column",
439
- alignItems: "center",
440
- gap: "0.75rem",
441
- marginBottom: "1.5rem"
442
- },
443
- title: {
444
- fontSize: "1.25rem",
445
- fontWeight: 600,
446
- color: "#f3f4f6",
447
- margin: 0
448
- },
449
- info: {
450
- color: "#9ca3af",
451
- textAlign: "center",
452
- marginBottom: "1.5rem",
453
- fontSize: "0.875rem"
454
- },
455
- error: {
456
- color: "#ef4444",
457
- backgroundColor: "rgba(239, 68, 68, 0.1)",
458
- border: "1px solid rgba(239, 68, 68, 0.3)",
459
- borderRadius: "6px",
460
- padding: "0.75rem",
461
- marginBottom: "1rem",
462
- fontSize: "0.875rem",
463
- textAlign: "center"
464
- },
465
- radioGroup: {
466
- display: "flex",
467
- gap: "1rem",
468
- marginBottom: "1rem",
469
- justifyContent: "center"
470
- },
471
- radioLabel: {
472
- display: "flex",
473
- alignItems: "center",
474
- gap: "0.5rem",
475
- color: "#e5e7eb",
476
- cursor: "pointer",
477
- padding: "0.5rem 1rem",
478
- borderRadius: "6px",
479
- border: "1px solid #374151",
480
- backgroundColor: "#111827",
481
- transition: "all 0.2s"
482
- },
483
- radioLabelActive: {
484
- borderColor: "#3b82f6",
485
- backgroundColor: "rgba(59, 130, 246, 0.1)"
486
- },
487
- input: {
488
- width: "100%",
489
- padding: "0.75rem 1rem",
490
- borderRadius: "6px",
491
- border: "1px solid #374151",
492
- backgroundColor: "#111827",
493
- color: "#f3f4f6",
494
- fontSize: "0.875rem",
495
- outline: "none",
496
- marginBottom: "1rem",
497
- boxSizing: "border-box"
498
- },
499
- localInfo: {
500
- color: "#9ca3af",
501
- fontSize: "0.875rem",
502
- textAlign: "center",
503
- padding: "0.75rem",
504
- backgroundColor: "#111827",
505
- borderRadius: "6px",
506
- marginBottom: "1rem"
507
- },
508
- buttonGroup: {
509
- display: "flex",
510
- justifyContent: "center"
511
- },
512
- button: {
513
- padding: "0.75rem 2rem",
514
- borderRadius: "6px",
515
- border: "none",
516
- fontSize: "0.875rem",
517
- fontWeight: 600,
518
- cursor: "pointer",
519
- backgroundColor: "#3b82f6",
520
- color: "white",
521
- transition: "all 0.2s"
522
- },
523
- buttonDisabled: {
524
- opacity: 0.5,
525
- cursor: "not-allowed"
526
- },
527
- loading: {
528
- display: "flex",
529
- flexDirection: "column",
530
- alignItems: "center",
531
- gap: "1rem",
532
- padding: "2rem",
533
- color: "#9ca3af"
534
- },
535
- spinner: {
536
- width: "2rem",
537
- height: "2rem",
538
- border: "3px solid #374151",
539
- borderTopColor: "#3b82f6",
540
- borderRadius: "50%",
541
- animation: "spin 1s linear infinite"
542
- }
543
- };
518
+ function tint(color, percent) {
519
+ return `color-mix(in srgb, ${color} ${percent}%, transparent)`;
520
+ }
521
+ function buildStyles(t) {
522
+ const bg = cssVar(t, "background");
523
+ const bgSecondary = cssVar(t, "backgroundSecondary");
524
+ const text = cssVar(t, "text");
525
+ const textSecondary = cssVar(t, "textSecondary");
526
+ const accent = cssVar(t, "primary");
527
+ const onPrimary = cssVar(t, "primaryText");
528
+ const border = cssVar(t, "border");
529
+ const error = cssVar(t, "error");
530
+ const overlay = cssVar(t, "overlay");
531
+ const radius = cssVar(t, "radius");
532
+ const errorBg = tint(error, 10);
533
+ const errorBorder = tint(error, 30);
534
+ const accentGlow = tint(accent, 15);
535
+ return {
536
+ overlay: {
537
+ position: "fixed",
538
+ top: 0,
539
+ left: 0,
540
+ right: 0,
541
+ bottom: 0,
542
+ backgroundColor: overlay,
543
+ display: "flex",
544
+ alignItems: "center",
545
+ justifyContent: "center",
546
+ zIndex: 1e4,
547
+ padding: "1rem",
548
+ animation: "meroFadeIn 0.2s ease-out"
549
+ },
550
+ content: {
551
+ backgroundColor: bg,
552
+ borderRadius: radius,
553
+ padding: "2rem",
554
+ maxWidth: "420px",
555
+ width: "100%",
556
+ position: "relative",
557
+ border: `1px solid ${border}`,
558
+ boxShadow: `0 25px 50px -12px rgba(0, 0, 0, 0.6), 0 0 0 1px ${accentGlow}`,
559
+ animation: "meroSlideIn 0.25s ease-out",
560
+ color: text
561
+ },
562
+ closeButton: {
563
+ position: "absolute",
564
+ top: "0.75rem",
565
+ right: "0.75rem",
566
+ background: "none",
567
+ border: "none",
568
+ fontSize: "1.5rem",
569
+ color: textSecondary,
570
+ cursor: "pointer",
571
+ padding: "0.25rem",
572
+ lineHeight: 1
573
+ },
574
+ header: {
575
+ display: "flex",
576
+ flexDirection: "column",
577
+ alignItems: "center",
578
+ gap: "0.75rem",
579
+ marginBottom: "1.5rem"
580
+ },
581
+ title: {
582
+ fontSize: "1.25rem",
583
+ fontWeight: 600,
584
+ color: text,
585
+ margin: 0
586
+ },
587
+ info: {
588
+ color: textSecondary,
589
+ textAlign: "center",
590
+ marginBottom: "1.5rem",
591
+ fontSize: "0.875rem"
592
+ },
593
+ error: {
594
+ color: error,
595
+ backgroundColor: errorBg,
596
+ border: `1px solid ${errorBorder}`,
597
+ borderRadius: radius,
598
+ padding: "0.75rem",
599
+ marginBottom: "1rem",
600
+ fontSize: "0.875rem",
601
+ textAlign: "center"
602
+ },
603
+ radioGroup: {
604
+ display: "flex",
605
+ gap: "0.75rem",
606
+ marginBottom: "1rem",
607
+ justifyContent: "center"
608
+ },
609
+ radioLabel: {
610
+ display: "flex",
611
+ alignItems: "center",
612
+ gap: "0.5rem",
613
+ color: text,
614
+ cursor: "pointer",
615
+ padding: "0.5rem 1rem",
616
+ borderRadius: radius,
617
+ border: `1px solid ${border}`,
618
+ backgroundColor: bgSecondary,
619
+ transition: "all 0.15s ease"
620
+ },
621
+ radioLabelActive: {
622
+ borderColor: accent,
623
+ backgroundColor: accentGlow,
624
+ color: text
625
+ },
626
+ input: {
627
+ width: "100%",
628
+ padding: "0.75rem 1rem",
629
+ borderRadius: radius,
630
+ border: `1px solid ${border}`,
631
+ backgroundColor: bgSecondary,
632
+ color: text,
633
+ fontSize: "0.875rem",
634
+ outline: "none",
635
+ marginBottom: "1rem",
636
+ boxSizing: "border-box"
637
+ },
638
+ localInfo: {
639
+ color: textSecondary,
640
+ fontSize: "0.875rem",
641
+ textAlign: "center",
642
+ padding: "0.75rem",
643
+ backgroundColor: bgSecondary,
644
+ borderRadius: radius,
645
+ marginBottom: "1rem",
646
+ border: `1px solid ${border}`
647
+ },
648
+ localInfoCode: {
649
+ color: accent
650
+ },
651
+ buttonGroup: {
652
+ display: "flex",
653
+ justifyContent: "center"
654
+ },
655
+ button: {
656
+ padding: "0.75rem 2rem",
657
+ borderRadius: radius,
658
+ border: "none",
659
+ fontSize: "0.875rem",
660
+ fontWeight: 600,
661
+ cursor: "pointer",
662
+ backgroundColor: accent,
663
+ color: onPrimary,
664
+ transition: "all 0.15s ease"
665
+ },
666
+ buttonDisabled: {
667
+ opacity: 0.5,
668
+ cursor: "not-allowed"
669
+ },
670
+ loading: {
671
+ display: "flex",
672
+ flexDirection: "column",
673
+ alignItems: "center",
674
+ gap: "1rem",
675
+ padding: "2rem",
676
+ color: textSecondary
677
+ },
678
+ spinner: {
679
+ width: "2rem",
680
+ height: "2rem",
681
+ border: `3px solid ${border}`,
682
+ borderTopColor: accent,
683
+ borderRadius: "50%",
684
+ animation: "meroSpin 1s linear infinite"
685
+ }
686
+ };
687
+ }
544
688
  function LoginModal({
545
689
  onConnect,
546
690
  onClose,
547
691
  connectionType,
548
- isOpen
692
+ isOpen,
693
+ theme
549
694
  }) {
550
695
  const [nodeType, setNodeType] = useState("local");
551
696
  const [nodeUrl, setNodeUrl2] = useState("");
552
697
  const [isValid, setIsValid] = useState(true);
553
698
  const [loading, setLoading] = useState(false);
554
699
  const [error, setError] = useState(null);
700
+ const resolved = useMemo(() => resolveMeroTheme(theme), [theme]);
701
+ const styles = useMemo(() => buildStyles(resolved), [resolved]);
702
+ const themeVars = useMemo(
703
+ () => theme ? themeToCssVars(resolved) : void 0,
704
+ [theme, resolved]
705
+ );
555
706
  const shouldShowLocal = connectionType === "remote-and-local" /* RemoteAndLocal */ || connectionType === "local" /* Local */;
556
707
  const shouldShowRemote = connectionType === "remote-and-local" /* RemoteAndLocal */ || connectionType === "remote" /* Remote */;
557
708
  const shouldShowRadioGroup = shouldShowLocal && shouldShowRemote;
@@ -602,14 +753,14 @@ function LoginModal({
602
753
  }
603
754
  const modalContent = /* @__PURE__ */ jsxs(Fragment, { children: [
604
755
  /* @__PURE__ */ jsx("style", { children: `
605
- @keyframes spin {
606
- to { transform: rotate(360deg); }
607
- }
756
+ @keyframes meroSpin { to { transform: rotate(360deg); } }
757
+ @keyframes meroFadeIn { from { opacity: 0; } to { opacity: 1; } }
758
+ @keyframes meroSlideIn { from { transform: translateY(-12px); opacity: 0; } to { transform: translateY(0); opacity: 1; } }
608
759
  ` }),
609
- /* @__PURE__ */ jsx("div", { style: styles.overlay, onClick: onClose, children: /* @__PURE__ */ jsxs("div", { style: styles.content, onClick: (e) => e.stopPropagation(), children: [
760
+ /* @__PURE__ */ jsx("div", { style: { ...themeVars, ...styles.overlay }, onClick: onClose, children: /* @__PURE__ */ jsxs("div", { style: styles.content, onClick: (e) => e.stopPropagation(), children: [
610
761
  /* @__PURE__ */ jsx("button", { style: styles.closeButton, onClick: onClose, children: "\xD7" }),
611
762
  /* @__PURE__ */ jsxs("div", { style: styles.header, children: [
612
- /* @__PURE__ */ jsx(MeroLogo, {}),
763
+ /* @__PURE__ */ jsx(CalimeroLogo, { size: 44, color: cssVar(resolved, "primary") }),
613
764
  /* @__PURE__ */ jsx("h1", { style: styles.title, children: "Connect to Calimero" })
614
765
  ] }),
615
766
  loading ? /* @__PURE__ */ jsxs("div", { style: styles.loading, children: [
@@ -638,7 +789,7 @@ function LoginModal({
638
789
  style: { display: "none" }
639
790
  }
640
791
  ),
641
- "\u{1F3E0} Local"
792
+ "Local"
642
793
  ]
643
794
  }
644
795
  ),
@@ -661,7 +812,7 @@ function LoginModal({
661
812
  style: { display: "none" }
662
813
  }
663
814
  ),
664
- "\u{1F310} Remote"
815
+ "Remote"
665
816
  ]
666
817
  }
667
818
  )
@@ -683,7 +834,7 @@ function LoginModal({
683
834
  ) : shouldShowLocal ? /* @__PURE__ */ jsxs("p", { style: styles.localInfo, children: [
684
835
  "Using default local node: ",
685
836
  /* @__PURE__ */ jsx("br", {}),
686
- /* @__PURE__ */ jsx("code", { style: { color: "#60a5fa" }, children: "http://node1.127.0.0.1.nip.io" })
837
+ /* @__PURE__ */ jsx("code", { style: styles.localInfoCode, children: "http://node1.127.0.0.1.nip.io" })
687
838
  ] }) : null }),
688
839
  /* @__PURE__ */ jsx("div", { style: styles.buttonGroup, children: /* @__PURE__ */ jsx(
689
840
  "button",
@@ -702,28 +853,26 @@ function LoginModal({
702
853
  ] });
703
854
  return createPortal(modalContent, document.body);
704
855
  }
705
- function MeroLogo() {
706
- return /* @__PURE__ */ jsx(
707
- "svg",
708
- {
709
- width: "40",
710
- height: "40",
711
- viewBox: "0 0 24 24",
712
- fill: "#3b82f6",
713
- xmlns: "http://www.w3.org/2000/svg",
714
- children: /* @__PURE__ */ 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" })
715
- }
716
- );
717
- }
718
856
  function ConnectButton({
719
857
  connectionType = "remote-and-local" /* RemoteAndLocal */,
720
858
  className,
721
- style
859
+ style,
860
+ theme,
861
+ logoOnly = false,
862
+ label
722
863
  }) {
723
864
  const { isAuthenticated, connectToNode, logout, nodeUrl, isOnline } = useMero();
724
865
  const [isDropdownOpen, setIsDropdownOpen] = useState(false);
725
866
  const [isModalOpen, setIsModalOpen] = useState(false);
726
867
  const dropdownRef = useRef(null);
868
+ const resolvedTheme = useMemo(
869
+ () => theme ? resolveMeroTheme(theme) : null,
870
+ [theme]
871
+ );
872
+ const themeVars = useMemo(
873
+ () => resolvedTheme ? themeToCssVars(resolvedTheme) : void 0,
874
+ [resolvedTheme]
875
+ );
727
876
  useEffect(() => {
728
877
  const handleClickOutside = (event) => {
729
878
  if (dropdownRef.current && !dropdownRef.current.contains(event.target)) {
@@ -737,6 +886,15 @@ function ConnectButton({
737
886
  if (!isAuthenticated || !nodeUrl) return "#";
738
887
  return new URL("admin-dashboard/", nodeUrl).toString();
739
888
  }, [isAuthenticated, nodeUrl]);
889
+ const labels = useMemo(() => {
890
+ const overrides = typeof label === "string" ? { connect: label } : label;
891
+ return {
892
+ connect: overrides?.connect ?? "Connect",
893
+ connected: overrides?.connected ?? "Connected",
894
+ reconnecting: overrides?.reconnecting ?? "Reconnecting..."
895
+ };
896
+ }, [label]);
897
+ const buttonClassName = logoOnly ? "mero-logo-only" : "";
740
898
  const handleConnect = () => {
741
899
  if (typeof connectionType === "object" && connectionType.type === "custom" /* Custom */) {
742
900
  connectToNode(connectionType.url);
@@ -749,94 +907,109 @@ function ConnectButton({
749
907
  connectToNode(url);
750
908
  };
751
909
  if (isAuthenticated && !isOnline) {
910
+ return /* @__PURE__ */ jsx(
911
+ "div",
912
+ {
913
+ className: "mero-connect-container",
914
+ style: { ...themeVars, display: "inline-block" },
915
+ children: /* @__PURE__ */ jsxs(
916
+ "button",
917
+ {
918
+ className: ["mero-connect-button", "mero-reconnecting", buttonClassName, className].filter(Boolean).join(" "),
919
+ style,
920
+ disabled: true,
921
+ "aria-label": labels.reconnecting,
922
+ title: logoOnly ? labels.reconnecting : void 0,
923
+ children: [
924
+ /* @__PURE__ */ jsx(CalimeroLogo, { size: 18, className: "mero-logo" }),
925
+ !logoOnly && labels.reconnecting
926
+ ]
927
+ }
928
+ )
929
+ }
930
+ );
931
+ }
932
+ if (isAuthenticated) {
752
933
  return /* @__PURE__ */ jsxs(
753
- "button",
934
+ "div",
754
935
  {
755
- className: `mero-connect-button mero-reconnecting ${className || ""}`,
756
- style,
757
- disabled: true,
936
+ ref: dropdownRef,
937
+ className: "mero-connect-container",
938
+ style: { ...themeVars, position: "relative", display: "inline-block" },
758
939
  children: [
759
- /* @__PURE__ */ jsx(MeroLogo2, {}),
760
- "Reconnecting..."
940
+ /* @__PURE__ */ jsxs(
941
+ "button",
942
+ {
943
+ className: ["mero-connect-button", "mero-connected", buttonClassName, className].filter(Boolean).join(" "),
944
+ style,
945
+ onClick: () => setIsDropdownOpen((prev) => !prev),
946
+ "aria-label": labels.connected,
947
+ title: logoOnly ? labels.connected : void 0,
948
+ children: [
949
+ /* @__PURE__ */ jsx(CalimeroLogo, { size: 18, className: "mero-logo" }),
950
+ !logoOnly && labels.connected
951
+ ]
952
+ }
953
+ ),
954
+ isDropdownOpen && /* @__PURE__ */ jsxs("div", { className: "mero-dropdown", children: [
955
+ /* @__PURE__ */ jsx("div", { className: "mero-dropdown-info", title: nodeUrl || "", children: nodeUrl }),
956
+ /* @__PURE__ */ jsx(
957
+ "a",
958
+ {
959
+ href: dashboardUrl,
960
+ target: "_blank",
961
+ rel: "noopener noreferrer",
962
+ className: "mero-dropdown-item",
963
+ children: "Dashboard"
964
+ }
965
+ ),
966
+ /* @__PURE__ */ jsx(
967
+ "button",
968
+ {
969
+ className: "mero-dropdown-item",
970
+ onClick: () => {
971
+ setIsDropdownOpen(false);
972
+ logout();
973
+ },
974
+ children: "Log out"
975
+ }
976
+ )
977
+ ] })
761
978
  ]
762
979
  }
763
980
  );
764
981
  }
765
- if (isAuthenticated) {
766
- return /* @__PURE__ */ jsxs("div", { ref: dropdownRef, className: "mero-connect-container", style: { position: "relative", display: "inline-block" }, children: [
767
- /* @__PURE__ */ jsxs(
768
- "button",
769
- {
770
- className: `mero-connect-button mero-connected ${className || ""}`,
771
- style,
772
- onClick: () => setIsDropdownOpen((prev) => !prev),
773
- children: [
774
- /* @__PURE__ */ jsx(MeroLogo2, {}),
775
- "Connected"
776
- ]
777
- }
778
- ),
779
- isDropdownOpen && /* @__PURE__ */ jsxs("div", { className: "mero-dropdown", children: [
780
- /* @__PURE__ */ jsx("div", { className: "mero-dropdown-info", title: nodeUrl || "", children: nodeUrl }),
781
- /* @__PURE__ */ jsx(
782
- "a",
982
+ return /* @__PURE__ */ jsxs(
983
+ "div",
984
+ {
985
+ className: "mero-connect-container",
986
+ style: { ...themeVars, display: "inline-block" },
987
+ children: [
988
+ /* @__PURE__ */ jsxs(
989
+ "button",
783
990
  {
784
- href: dashboardUrl,
785
- target: "_blank",
786
- rel: "noopener noreferrer",
787
- className: "mero-dropdown-item",
788
- children: "Dashboard"
991
+ className: ["mero-connect-button", buttonClassName, className].filter(Boolean).join(" "),
992
+ style,
993
+ onClick: handleConnect,
994
+ "aria-label": labels.connect,
995
+ title: logoOnly ? labels.connect : void 0,
996
+ children: [
997
+ /* @__PURE__ */ jsx(CalimeroLogo, { size: 18, className: "mero-logo" }),
998
+ !logoOnly && labels.connect
999
+ ]
789
1000
  }
790
1001
  ),
791
1002
  /* @__PURE__ */ jsx(
792
- "button",
1003
+ LoginModal,
793
1004
  {
794
- className: "mero-dropdown-item",
795
- onClick: () => {
796
- setIsDropdownOpen(false);
797
- logout();
798
- },
799
- children: "Log out"
1005
+ isOpen: isModalOpen,
1006
+ onConnect: handleModalConnect,
1007
+ onClose: () => setIsModalOpen(false),
1008
+ connectionType: typeof connectionType === "object" ? "remote-and-local" /* RemoteAndLocal */ : connectionType,
1009
+ theme: resolvedTheme ?? theme
800
1010
  }
801
1011
  )
802
- ] })
803
- ] });
804
- }
805
- return /* @__PURE__ */ jsxs(Fragment, { children: [
806
- /* @__PURE__ */ jsxs(
807
- "button",
808
- {
809
- className: `mero-connect-button ${className || ""}`,
810
- style,
811
- onClick: handleConnect,
812
- children: [
813
- /* @__PURE__ */ jsx(MeroLogo2, {}),
814
- "Connect"
815
- ]
816
- }
817
- ),
818
- /* @__PURE__ */ jsx(
819
- LoginModal,
820
- {
821
- isOpen: isModalOpen,
822
- onConnect: handleModalConnect,
823
- onClose: () => setIsModalOpen(false),
824
- connectionType: typeof connectionType === "object" ? "remote-and-local" /* RemoteAndLocal */ : connectionType
825
- }
826
- )
827
- ] });
828
- }
829
- function MeroLogo2() {
830
- return /* @__PURE__ */ jsx(
831
- "svg",
832
- {
833
- className: "mero-logo",
834
- width: "24",
835
- height: "24",
836
- viewBox: "0 0 24 24",
837
- fill: "currentColor",
838
- xmlns: "http://www.w3.org/2000/svg",
839
- children: /* @__PURE__ */ 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" })
1012
+ ]
840
1013
  }
841
1014
  );
842
1015
  }
@@ -1937,6 +2110,6 @@ function useDetachContextFromGroup() {
1937
2110
  return { detachContextFromGroup, loading, error };
1938
2111
  }
1939
2112
 
1940
- export { AppMode, ConnectButton, ConnectionType, LoginModal, MeroContext, MeroProvider, clearAllStorage, clearApplicationId, clearContextId, clearContextIdentity, clearNodeUrl, getApplicationId, getContextId, getContextIdentity, getNodeUrl, localStorageTokenStorage, setApplicationId, setContextId, setContextIdentity, setNodeUrl, useAddGroupMembers, useApplicationContexts, useContextDiscovery, useContextGroup, useContexts, useCreateContext, useCreateGroupInNamespace, useCreateNamespace, useCreateNamespaceInvitation, useDeleteContext, useDeleteGroup, useDeleteNamespace, useDetachContextFromGroup, useExecute, useGroupCapabilities, useGroupContexts, useGroupInfo, useGroupInvitations, useGroupMembers, useGroupUpgradeStatus, useJoinContext, useJoinGroup, useJoinNamespace, useMero, useNamespace, useNamespaceGroups, useNamespaceIdentity, useNamespaces, useNamespacesForApplication, useNestGroup, useRegisterGroupSigningKey, useRemoveGroupMembers, useRetryGroupUpgrade, useSetDefaultCapabilities, useSetGroupAlias, useSetMemberAlias, useSetSubgroupVisibility, useSetTeeAdmissionPolicy, useSubgroups, useSubscription, useSyncGroup, useUnnestGroup, useUpdateGroupSettings, useUpdateMemberRole, useUpgradeGroup };
2113
+ export { AppMode, CalimeroLogo, ConnectButton, ConnectionType, LoginModal, MERO_CSS_VARS, MeroContext, MeroProvider, clearAllStorage, clearApplicationId, clearContextId, clearContextIdentity, clearNodeUrl, cssVar, defaultMeroTheme, getApplicationId, getContextId, getContextIdentity, getNodeUrl, localStorageTokenStorage, resolveMeroTheme, setApplicationId, setContextId, setContextIdentity, setNodeUrl, themeToCssVars, useAddGroupMembers, useApplicationContexts, useContextDiscovery, useContextGroup, useContexts, useCreateContext, useCreateGroupInNamespace, useCreateNamespace, useCreateNamespaceInvitation, useDeleteContext, useDeleteGroup, useDeleteNamespace, useDetachContextFromGroup, useExecute, useGroupCapabilities, useGroupContexts, useGroupInfo, useGroupInvitations, useGroupMembers, useGroupUpgradeStatus, useJoinContext, useJoinGroup, useJoinNamespace, useMero, useNamespace, useNamespaceGroups, useNamespaceIdentity, useNamespaces, useNamespacesForApplication, useNestGroup, useRegisterGroupSigningKey, useRemoveGroupMembers, useRetryGroupUpgrade, useSetDefaultCapabilities, useSetGroupAlias, useSetMemberAlias, useSetSubgroupVisibility, useSetTeeAdmissionPolicy, useSubgroups, useSubscription, useSyncGroup, useUnnestGroup, useUpdateGroupSettings, useUpdateMemberRole, useUpgradeGroup };
1941
2114
  //# sourceMappingURL=index.js.map
1942
2115
  //# sourceMappingURL=index.js.map