@calimero-network/mero-react 4.3.0 → 4.3.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/README.md +5 -5
- package/dist/index.cjs +11 -128
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +24 -10
- package/dist/index.d.ts +24 -10
- package/dist/index.js +11 -128
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -292,7 +292,7 @@ Helpers: `defaultMeroTheme` (the full default palette), `resolveMeroTheme(partia
|
|
|
292
292
|
|
|
293
293
|
| Prop | Type | Default | Notes |
|
|
294
294
|
|------|------|---------|-------|
|
|
295
|
-
| `connectionType` | `ConnectionType \| CustomConnectionConfig` | `
|
|
295
|
+
| `connectionType` | `ConnectionType \| CustomConnectionConfig` | `Remote` | `Custom` connects straight to the given URL, skipping the modal. Every other value opens the LoginModal (node discovery + manual URL entry). |
|
|
296
296
|
| `theme` | `MeroTheme` | — | Partial token override. |
|
|
297
297
|
| `logoOnly` | `boolean` | `false` | Render only the Calimero logo (square button). The label is still announced via `aria-label`. |
|
|
298
298
|
| `label` | `string \| { connect?, connected?, reconnecting? }` | — | Override default labels. Bare string targets the disconnected state. |
|
|
@@ -305,10 +305,10 @@ AppMode.SingleContext // 'single-context'
|
|
|
305
305
|
AppMode.MultiContext // 'multi-context'
|
|
306
306
|
AppMode.Admin // 'admin'
|
|
307
307
|
|
|
308
|
-
ConnectionType.
|
|
309
|
-
ConnectionType.
|
|
310
|
-
ConnectionType.
|
|
311
|
-
ConnectionType.
|
|
308
|
+
ConnectionType.Remote // 'remote' — opens the LoginModal (discovery + manual URL)
|
|
309
|
+
ConnectionType.Custom // 'custom' — skip the modal, connect to a fixed URL
|
|
310
|
+
ConnectionType.RemoteAndLocal // deprecated, same as Remote
|
|
311
|
+
ConnectionType.Local // deprecated, same as Remote
|
|
312
312
|
```
|
|
313
313
|
|
|
314
314
|
## Types
|
package/dist/index.cjs
CHANGED
|
@@ -588,7 +588,6 @@ function themeToCssVars(theme) {
|
|
|
588
588
|
function cssVar(theme, key) {
|
|
589
589
|
return `var(${MERO_CSS_VARS[key]}, ${theme[key]})`;
|
|
590
590
|
}
|
|
591
|
-
var DEFAULT_LOCAL_NODE_URL = "http://node1.127.0.0.1.nip.io";
|
|
592
591
|
var CUSTOM_SELECTION = "__custom__";
|
|
593
592
|
function isValidUrl(urlString) {
|
|
594
593
|
if (!urlString || urlString.trim() === "") {
|
|
@@ -706,29 +705,6 @@ function buildStyles(t) {
|
|
|
706
705
|
fontSize: "0.875rem",
|
|
707
706
|
textAlign: "center"
|
|
708
707
|
},
|
|
709
|
-
radioGroup: {
|
|
710
|
-
display: "flex",
|
|
711
|
-
gap: "0.75rem",
|
|
712
|
-
marginBottom: "1rem",
|
|
713
|
-
justifyContent: "center"
|
|
714
|
-
},
|
|
715
|
-
radioLabel: {
|
|
716
|
-
display: "flex",
|
|
717
|
-
alignItems: "center",
|
|
718
|
-
gap: "0.5rem",
|
|
719
|
-
color: text,
|
|
720
|
-
cursor: "pointer",
|
|
721
|
-
padding: "0.5rem 1rem",
|
|
722
|
-
borderRadius: radius,
|
|
723
|
-
border: `1px solid ${border}`,
|
|
724
|
-
backgroundColor: bgSecondary,
|
|
725
|
-
transition: "all 0.15s ease"
|
|
726
|
-
},
|
|
727
|
-
radioLabelActive: {
|
|
728
|
-
border: `1px solid ${accent}`,
|
|
729
|
-
backgroundColor: accentGlow,
|
|
730
|
-
color: text
|
|
731
|
-
},
|
|
732
708
|
radioList: {
|
|
733
709
|
display: "flex",
|
|
734
710
|
flexDirection: "column",
|
|
@@ -791,29 +767,6 @@ function buildStyles(t) {
|
|
|
791
767
|
marginBottom: "1rem",
|
|
792
768
|
boxSizing: "border-box"
|
|
793
769
|
},
|
|
794
|
-
localInfo: {
|
|
795
|
-
color: textSecondary,
|
|
796
|
-
fontSize: "0.875rem",
|
|
797
|
-
textAlign: "center",
|
|
798
|
-
padding: "0.75rem",
|
|
799
|
-
backgroundColor: bgSecondary,
|
|
800
|
-
borderRadius: radius,
|
|
801
|
-
marginBottom: "1rem",
|
|
802
|
-
border: `1px solid ${border}`
|
|
803
|
-
},
|
|
804
|
-
localInfoCode: {
|
|
805
|
-
color: accent
|
|
806
|
-
},
|
|
807
|
-
noNodeInfo: {
|
|
808
|
-
color: textSecondary,
|
|
809
|
-
fontSize: "0.875rem",
|
|
810
|
-
textAlign: "center",
|
|
811
|
-
padding: "0.75rem",
|
|
812
|
-
backgroundColor: bgSecondary,
|
|
813
|
-
borderRadius: radius,
|
|
814
|
-
marginBottom: "1rem",
|
|
815
|
-
border: `1px solid ${border}`
|
|
816
|
-
},
|
|
817
770
|
toolbar: {
|
|
818
771
|
display: "flex",
|
|
819
772
|
justifyContent: "center",
|
|
@@ -884,12 +837,10 @@ function buildStyles(t) {
|
|
|
884
837
|
function LoginModal({
|
|
885
838
|
onConnect,
|
|
886
839
|
onClose,
|
|
887
|
-
connectionType,
|
|
888
840
|
isOpen,
|
|
889
841
|
theme,
|
|
890
842
|
localNodePorts = DEFAULT_LOCAL_NODE_PORTS
|
|
891
843
|
}) {
|
|
892
|
-
const [nodeType, setNodeType] = react.useState("local");
|
|
893
844
|
const [selected, setSelected] = react.useState(CUSTOM_SELECTION);
|
|
894
845
|
const [discovered, setDiscovered] = react.useState([]);
|
|
895
846
|
const [discovering, setDiscovering] = react.useState(false);
|
|
@@ -902,27 +853,16 @@ function LoginModal({
|
|
|
902
853
|
() => theme ? themeToCssVars(resolved) : void 0,
|
|
903
854
|
[theme, resolved]
|
|
904
855
|
);
|
|
905
|
-
const shouldShowLocal = connectionType === "remote-and-local" /* RemoteAndLocal */ || connectionType === "local" /* Local */;
|
|
906
|
-
const shouldShowRemote = connectionType === "remote-and-local" /* RemoteAndLocal */ || connectionType === "remote" /* Remote */;
|
|
907
|
-
const shouldShowRadioGroup = shouldShowLocal && shouldShowRemote;
|
|
908
856
|
react.useEffect(() => {
|
|
909
857
|
const savedUrl = localStorage.getItem("mero:node_url");
|
|
910
858
|
if (savedUrl) {
|
|
911
859
|
setCustomUrl(savedUrl);
|
|
912
860
|
}
|
|
913
861
|
}, []);
|
|
914
|
-
react.useEffect(() => {
|
|
915
|
-
if (connectionType === "local" /* Local */) {
|
|
916
|
-
setNodeType("local");
|
|
917
|
-
} else if (connectionType === "remote" /* Remote */) {
|
|
918
|
-
setNodeType("remote");
|
|
919
|
-
}
|
|
920
|
-
}, [connectionType]);
|
|
921
862
|
const [scanNonce, setScanNonce] = react.useState(0);
|
|
922
863
|
const portsKey = react.useMemo(() => localNodePorts.join(","), [localNodePorts]);
|
|
923
|
-
const remoteActive = isOpen && shouldShowRemote && nodeType === "remote";
|
|
924
864
|
react.useEffect(() => {
|
|
925
|
-
if (!
|
|
865
|
+
if (!isOpen) {
|
|
926
866
|
return;
|
|
927
867
|
}
|
|
928
868
|
const controller = new AbortController();
|
|
@@ -943,16 +883,16 @@ function LoginModal({
|
|
|
943
883
|
active = false;
|
|
944
884
|
controller.abort();
|
|
945
885
|
};
|
|
946
|
-
}, [
|
|
886
|
+
}, [isOpen, portsKey, scanNonce]);
|
|
947
887
|
const isCustom = selected === CUSTOM_SELECTION;
|
|
948
888
|
const hasDiscovered = discovered.length > 0;
|
|
949
|
-
const canConnect = !loading &&
|
|
889
|
+
const canConnect = !loading && !discovering && (isCustom ? isValidUrl(customUrl) : true);
|
|
950
890
|
const canConnectRef = react.useRef(canConnect);
|
|
951
891
|
canConnectRef.current = canConnect;
|
|
952
892
|
const handleConnect = react.useCallback(async () => {
|
|
953
|
-
const
|
|
954
|
-
const
|
|
955
|
-
if (
|
|
893
|
+
const usingDiscovered = selected !== CUSTOM_SELECTION;
|
|
894
|
+
const targetUrl = usingDiscovered ? selected : customUrl;
|
|
895
|
+
if (!usingDiscovered && !isValidUrl(targetUrl)) {
|
|
956
896
|
return;
|
|
957
897
|
}
|
|
958
898
|
const normalizedUrl = targetUrl.replace(/\/+$/, "");
|
|
@@ -977,7 +917,7 @@ function LoginModal({
|
|
|
977
917
|
setError("Failed to connect. Please check the URL and try again.");
|
|
978
918
|
setLoading(false);
|
|
979
919
|
}
|
|
980
|
-
}, [
|
|
920
|
+
}, [selected, customUrl, onConnect]);
|
|
981
921
|
if (!isOpen) {
|
|
982
922
|
return null;
|
|
983
923
|
}
|
|
@@ -1027,7 +967,7 @@ function LoginModal({
|
|
|
1027
967
|
)
|
|
1028
968
|
);
|
|
1029
969
|
};
|
|
1030
|
-
const
|
|
970
|
+
const renderNodeSection = () => {
|
|
1031
971
|
if (discovering) {
|
|
1032
972
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles.discovering, "data-testid": "node-discovering", children: [
|
|
1033
973
|
/* @__PURE__ */ jsxRuntime.jsx("div", { style: styles.spinnerSmall }),
|
|
@@ -1035,7 +975,7 @@ function LoginModal({
|
|
|
1035
975
|
] });
|
|
1036
976
|
}
|
|
1037
977
|
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
1038
|
-
/* @__PURE__ */ jsxRuntime.jsx("p", { style: styles.info, children: hasDiscovered ? "Select
|
|
978
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { style: styles.info, children: hasDiscovered ? "Select your Calimero node to continue." : "No local node found. Enter a node URL to continue." }),
|
|
1039
979
|
hasDiscovered && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1040
980
|
"div",
|
|
1041
981
|
{
|
|
@@ -1095,64 +1035,8 @@ function LoginModal({
|
|
|
1095
1035
|
/* @__PURE__ */ jsxRuntime.jsx("p", { children: "Connecting to node..." }),
|
|
1096
1036
|
/* @__PURE__ */ jsxRuntime.jsx("div", { style: styles.spinner })
|
|
1097
1037
|
] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
1098
|
-
shouldShowRadioGroup && /* @__PURE__ */ jsxRuntime.jsx("p", { style: styles.info, children: "Select your Calimero node type to continue." }),
|
|
1099
1038
|
error && /* @__PURE__ */ jsxRuntime.jsx("p", { style: styles.error, children: error }),
|
|
1100
|
-
|
|
1101
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
1102
|
-
"label",
|
|
1103
|
-
{
|
|
1104
|
-
"data-testid": "node-type-local",
|
|
1105
|
-
style: {
|
|
1106
|
-
...styles.radioLabel,
|
|
1107
|
-
...nodeType === "local" ? styles.radioLabelActive : {}
|
|
1108
|
-
},
|
|
1109
|
-
onClick: () => setNodeType("local"),
|
|
1110
|
-
children: [
|
|
1111
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1112
|
-
"input",
|
|
1113
|
-
{
|
|
1114
|
-
type: "radio",
|
|
1115
|
-
value: "local",
|
|
1116
|
-
checked: nodeType === "local",
|
|
1117
|
-
onChange: () => setNodeType("local"),
|
|
1118
|
-
style: { display: "none" }
|
|
1119
|
-
}
|
|
1120
|
-
),
|
|
1121
|
-
"Local"
|
|
1122
|
-
]
|
|
1123
|
-
}
|
|
1124
|
-
),
|
|
1125
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
1126
|
-
"label",
|
|
1127
|
-
{
|
|
1128
|
-
"data-testid": "node-type-remote",
|
|
1129
|
-
style: {
|
|
1130
|
-
...styles.radioLabel,
|
|
1131
|
-
...nodeType === "remote" ? styles.radioLabelActive : {}
|
|
1132
|
-
},
|
|
1133
|
-
onClick: () => setNodeType("remote"),
|
|
1134
|
-
children: [
|
|
1135
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1136
|
-
"input",
|
|
1137
|
-
{
|
|
1138
|
-
type: "radio",
|
|
1139
|
-
value: "remote",
|
|
1140
|
-
checked: nodeType === "remote",
|
|
1141
|
-
onChange: () => setNodeType("remote"),
|
|
1142
|
-
style: { display: "none" }
|
|
1143
|
-
}
|
|
1144
|
-
),
|
|
1145
|
-
"Remote"
|
|
1146
|
-
]
|
|
1147
|
-
}
|
|
1148
|
-
)
|
|
1149
|
-
] }),
|
|
1150
|
-
nodeType === "local" && shouldShowLocal && /* @__PURE__ */ jsxRuntime.jsxs("p", { style: styles.localInfo, children: [
|
|
1151
|
-
"Using default local node: ",
|
|
1152
|
-
/* @__PURE__ */ jsxRuntime.jsx("br", {}),
|
|
1153
|
-
/* @__PURE__ */ jsxRuntime.jsx("code", { style: styles.localInfoCode, children: DEFAULT_LOCAL_NODE_URL })
|
|
1154
|
-
] }),
|
|
1155
|
-
nodeType === "remote" && shouldShowRemote && renderRemoteView(),
|
|
1039
|
+
renderNodeSection(),
|
|
1156
1040
|
/* @__PURE__ */ jsxRuntime.jsx("div", { style: styles.buttonGroup, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1157
1041
|
"button",
|
|
1158
1042
|
{
|
|
@@ -1172,7 +1056,7 @@ function LoginModal({
|
|
|
1172
1056
|
return reactDom.createPortal(modalContent, document.body);
|
|
1173
1057
|
}
|
|
1174
1058
|
function ConnectButton({
|
|
1175
|
-
connectionType = "remote
|
|
1059
|
+
connectionType = "remote" /* Remote */,
|
|
1176
1060
|
className,
|
|
1177
1061
|
style,
|
|
1178
1062
|
theme,
|
|
@@ -1323,7 +1207,6 @@ function ConnectButton({
|
|
|
1323
1207
|
isOpen: isModalOpen,
|
|
1324
1208
|
onConnect: handleModalConnect,
|
|
1325
1209
|
onClose: () => setIsModalOpen(false),
|
|
1326
|
-
connectionType: typeof connectionType === "object" ? "remote-and-local" /* RemoteAndLocal */ : connectionType,
|
|
1327
1210
|
theme: resolvedTheme ?? theme
|
|
1328
1211
|
}
|
|
1329
1212
|
)
|