@calimero-network/mero-react 4.2.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/dist/index.d.cts CHANGED
@@ -40,11 +40,17 @@ declare enum AppMode {
40
40
  * Connection type for the login modal
41
41
  */
42
42
  declare enum ConnectionType {
43
- /** Show both local and remote options */
43
+ /**
44
+ * @deprecated The login modal no longer has Local/Remote tabs — it always
45
+ * shows node discovery + manual URL entry. Behaves the same as `Remote`.
46
+ */
44
47
  RemoteAndLocal = "remote-and-local",
45
- /** Show only remote option */
48
+ /** Open the login modal (node discovery + manual URL entry) */
46
49
  Remote = "remote",
47
- /** Show only local option */
50
+ /**
51
+ * @deprecated The hardcoded default-local-node view was removed. Behaves
52
+ * the same as `Remote`.
53
+ */
48
54
  Local = "local",
49
55
  /** Custom URL (skip modal) */
50
56
  Custom = "custom"
@@ -233,7 +239,11 @@ declare function themeToCssVars(theme: ResolvedMeroTheme): CSSProperties;
233
239
  declare function cssVar(theme: ResolvedMeroTheme, key: keyof MeroTheme): string;
234
240
 
235
241
  interface ConnectButtonProps {
236
- /** Connection type for login modal */
242
+ /**
243
+ * Connection behaviour. `Custom` (object form) connects straight to the
244
+ * given URL, skipping the modal; every other value opens the LoginModal,
245
+ * which always shows node discovery + manual URL entry.
246
+ */
237
247
  connectionType?: ConnectionType | CustomConnectionConfig;
238
248
  /** Custom class name */
239
249
  className?: string;
@@ -268,23 +278,27 @@ interface LoginModalProps {
268
278
  onConnect: (url: string) => void;
269
279
  /** Callback when modal is closed */
270
280
  onClose: () => void;
271
- /** Connection type determines what options to show */
272
- connectionType: ConnectionType | CustomConnectionConfig;
281
+ /**
282
+ * @deprecated Ignored. The modal always shows node discovery + manual URL
283
+ * entry; the old hardcoded-default "Local" view was removed. Kept so
284
+ * existing call sites keep compiling.
285
+ */
286
+ connectionType?: ConnectionType | CustomConnectionConfig;
273
287
  /** Whether the modal is open */
274
288
  isOpen: boolean;
275
289
  /** Theme overrides — accepts any subset of `MeroTheme` tokens */
276
290
  theme?: MeroTheme;
277
291
  /**
278
- * Ports probed when discovering remote/local nodes. Defaults to the
279
- * well-known Calimero dev ports (2428, 2429, 2528, 2529). Mostly an escape
280
- * hatch for non-standard setups and tests.
292
+ * Ports probed when discovering local nodes. Defaults to the well-known
293
+ * Calimero dev ports (2428, 2429, 2528, 2529). Mostly an escape hatch for
294
+ * non-standard setups and tests.
281
295
  */
282
296
  localNodePorts?: readonly number[];
283
297
  }
284
298
  /**
285
299
  * LoginModal - Connection modal component
286
300
  */
287
- declare function LoginModal({ onConnect, onClose, connectionType, isOpen, theme, localNodePorts, }: LoginModalProps): React.ReactPortal | null;
301
+ declare function LoginModal({ onConnect, onClose, isOpen, theme, localNodePorts, }: LoginModalProps): React.ReactPortal | null;
288
302
 
289
303
  interface CalimeroLogoProps extends React__default.SVGAttributes<SVGSVGElement> {
290
304
  /** Width / height shorthand (applied to both). Default: 24. */
package/dist/index.d.ts CHANGED
@@ -40,11 +40,17 @@ declare enum AppMode {
40
40
  * Connection type for the login modal
41
41
  */
42
42
  declare enum ConnectionType {
43
- /** Show both local and remote options */
43
+ /**
44
+ * @deprecated The login modal no longer has Local/Remote tabs — it always
45
+ * shows node discovery + manual URL entry. Behaves the same as `Remote`.
46
+ */
44
47
  RemoteAndLocal = "remote-and-local",
45
- /** Show only remote option */
48
+ /** Open the login modal (node discovery + manual URL entry) */
46
49
  Remote = "remote",
47
- /** Show only local option */
50
+ /**
51
+ * @deprecated The hardcoded default-local-node view was removed. Behaves
52
+ * the same as `Remote`.
53
+ */
48
54
  Local = "local",
49
55
  /** Custom URL (skip modal) */
50
56
  Custom = "custom"
@@ -233,7 +239,11 @@ declare function themeToCssVars(theme: ResolvedMeroTheme): CSSProperties;
233
239
  declare function cssVar(theme: ResolvedMeroTheme, key: keyof MeroTheme): string;
234
240
 
235
241
  interface ConnectButtonProps {
236
- /** Connection type for login modal */
242
+ /**
243
+ * Connection behaviour. `Custom` (object form) connects straight to the
244
+ * given URL, skipping the modal; every other value opens the LoginModal,
245
+ * which always shows node discovery + manual URL entry.
246
+ */
237
247
  connectionType?: ConnectionType | CustomConnectionConfig;
238
248
  /** Custom class name */
239
249
  className?: string;
@@ -268,23 +278,27 @@ interface LoginModalProps {
268
278
  onConnect: (url: string) => void;
269
279
  /** Callback when modal is closed */
270
280
  onClose: () => void;
271
- /** Connection type determines what options to show */
272
- connectionType: ConnectionType | CustomConnectionConfig;
281
+ /**
282
+ * @deprecated Ignored. The modal always shows node discovery + manual URL
283
+ * entry; the old hardcoded-default "Local" view was removed. Kept so
284
+ * existing call sites keep compiling.
285
+ */
286
+ connectionType?: ConnectionType | CustomConnectionConfig;
273
287
  /** Whether the modal is open */
274
288
  isOpen: boolean;
275
289
  /** Theme overrides — accepts any subset of `MeroTheme` tokens */
276
290
  theme?: MeroTheme;
277
291
  /**
278
- * Ports probed when discovering remote/local nodes. Defaults to the
279
- * well-known Calimero dev ports (2428, 2429, 2528, 2529). Mostly an escape
280
- * hatch for non-standard setups and tests.
292
+ * Ports probed when discovering local nodes. Defaults to the well-known
293
+ * Calimero dev ports (2428, 2429, 2528, 2529). Mostly an escape hatch for
294
+ * non-standard setups and tests.
281
295
  */
282
296
  localNodePorts?: readonly number[];
283
297
  }
284
298
  /**
285
299
  * LoginModal - Connection modal component
286
300
  */
287
- declare function LoginModal({ onConnect, onClose, connectionType, isOpen, theme, localNodePorts, }: LoginModalProps): React.ReactPortal | null;
301
+ declare function LoginModal({ onConnect, onClose, isOpen, theme, localNodePorts, }: LoginModalProps): React.ReactPortal | null;
288
302
 
289
303
  interface CalimeroLogoProps extends React__default.SVGAttributes<SVGSVGElement> {
290
304
  /** Width / height shorthand (applied to both). Default: 24. */
package/dist/index.js CHANGED
@@ -200,9 +200,18 @@ var isBrowser = typeof window !== "undefined";
200
200
  function getPermissionsForMode(mode) {
201
201
  switch (mode) {
202
202
  case "single-context" /* SingleContext */:
203
- return ["context:execute"];
203
+ return ["context:execute", "context:list", "application:list", "blob", "context:alias"];
204
204
  case "multi-context" /* MultiContext */:
205
- return ["context:create", "context:list", "context:execute"];
205
+ return [
206
+ "context:create",
207
+ "context:list",
208
+ "context:execute",
209
+ "application:list",
210
+ "namespace",
211
+ "group",
212
+ "blob",
213
+ "context:alias"
214
+ ];
206
215
  case "admin" /* Admin */:
207
216
  return ["admin"];
208
217
  default:
@@ -579,7 +588,6 @@ function themeToCssVars(theme) {
579
588
  function cssVar(theme, key) {
580
589
  return `var(${MERO_CSS_VARS[key]}, ${theme[key]})`;
581
590
  }
582
- var DEFAULT_LOCAL_NODE_URL = "http://node1.127.0.0.1.nip.io";
583
591
  var CUSTOM_SELECTION = "__custom__";
584
592
  function isValidUrl(urlString) {
585
593
  if (!urlString || urlString.trim() === "") {
@@ -697,29 +705,6 @@ function buildStyles(t) {
697
705
  fontSize: "0.875rem",
698
706
  textAlign: "center"
699
707
  },
700
- radioGroup: {
701
- display: "flex",
702
- gap: "0.75rem",
703
- marginBottom: "1rem",
704
- justifyContent: "center"
705
- },
706
- radioLabel: {
707
- display: "flex",
708
- alignItems: "center",
709
- gap: "0.5rem",
710
- color: text,
711
- cursor: "pointer",
712
- padding: "0.5rem 1rem",
713
- borderRadius: radius,
714
- border: `1px solid ${border}`,
715
- backgroundColor: bgSecondary,
716
- transition: "all 0.15s ease"
717
- },
718
- radioLabelActive: {
719
- border: `1px solid ${accent}`,
720
- backgroundColor: accentGlow,
721
- color: text
722
- },
723
708
  radioList: {
724
709
  display: "flex",
725
710
  flexDirection: "column",
@@ -782,29 +767,6 @@ function buildStyles(t) {
782
767
  marginBottom: "1rem",
783
768
  boxSizing: "border-box"
784
769
  },
785
- localInfo: {
786
- color: textSecondary,
787
- fontSize: "0.875rem",
788
- textAlign: "center",
789
- padding: "0.75rem",
790
- backgroundColor: bgSecondary,
791
- borderRadius: radius,
792
- marginBottom: "1rem",
793
- border: `1px solid ${border}`
794
- },
795
- localInfoCode: {
796
- color: accent
797
- },
798
- noNodeInfo: {
799
- color: textSecondary,
800
- fontSize: "0.875rem",
801
- textAlign: "center",
802
- padding: "0.75rem",
803
- backgroundColor: bgSecondary,
804
- borderRadius: radius,
805
- marginBottom: "1rem",
806
- border: `1px solid ${border}`
807
- },
808
770
  toolbar: {
809
771
  display: "flex",
810
772
  justifyContent: "center",
@@ -875,12 +837,10 @@ function buildStyles(t) {
875
837
  function LoginModal({
876
838
  onConnect,
877
839
  onClose,
878
- connectionType,
879
840
  isOpen,
880
841
  theme,
881
842
  localNodePorts = DEFAULT_LOCAL_NODE_PORTS
882
843
  }) {
883
- const [nodeType, setNodeType] = useState("local");
884
844
  const [selected, setSelected] = useState(CUSTOM_SELECTION);
885
845
  const [discovered, setDiscovered] = useState([]);
886
846
  const [discovering, setDiscovering] = useState(false);
@@ -893,27 +853,16 @@ function LoginModal({
893
853
  () => theme ? themeToCssVars(resolved) : void 0,
894
854
  [theme, resolved]
895
855
  );
896
- const shouldShowLocal = connectionType === "remote-and-local" /* RemoteAndLocal */ || connectionType === "local" /* Local */;
897
- const shouldShowRemote = connectionType === "remote-and-local" /* RemoteAndLocal */ || connectionType === "remote" /* Remote */;
898
- const shouldShowRadioGroup = shouldShowLocal && shouldShowRemote;
899
856
  useEffect(() => {
900
857
  const savedUrl = localStorage.getItem("mero:node_url");
901
858
  if (savedUrl) {
902
859
  setCustomUrl(savedUrl);
903
860
  }
904
861
  }, []);
905
- useEffect(() => {
906
- if (connectionType === "local" /* Local */) {
907
- setNodeType("local");
908
- } else if (connectionType === "remote" /* Remote */) {
909
- setNodeType("remote");
910
- }
911
- }, [connectionType]);
912
862
  const [scanNonce, setScanNonce] = useState(0);
913
863
  const portsKey = useMemo(() => localNodePorts.join(","), [localNodePorts]);
914
- const remoteActive = isOpen && shouldShowRemote && nodeType === "remote";
915
864
  useEffect(() => {
916
- if (!remoteActive) {
865
+ if (!isOpen) {
917
866
  return;
918
867
  }
919
868
  const controller = new AbortController();
@@ -934,16 +883,16 @@ function LoginModal({
934
883
  active = false;
935
884
  controller.abort();
936
885
  };
937
- }, [remoteActive, portsKey, scanNonce]);
886
+ }, [isOpen, portsKey, scanNonce]);
938
887
  const isCustom = selected === CUSTOM_SELECTION;
939
888
  const hasDiscovered = discovered.length > 0;
940
- const canConnect = !loading && (nodeType === "local" ? true : discovering ? false : isCustom ? isValidUrl(customUrl) : true);
889
+ const canConnect = !loading && !discovering && (isCustom ? isValidUrl(customUrl) : true);
941
890
  const canConnectRef = useRef(canConnect);
942
891
  canConnectRef.current = canConnect;
943
892
  const handleConnect = useCallback(async () => {
944
- const targetUrl = nodeType === "local" ? DEFAULT_LOCAL_NODE_URL : selected === CUSTOM_SELECTION ? customUrl : selected;
945
- const usingDiscovered = nodeType === "remote" && selected !== CUSTOM_SELECTION;
946
- if (nodeType === "remote" && !usingDiscovered && !isValidUrl(targetUrl)) {
893
+ const usingDiscovered = selected !== CUSTOM_SELECTION;
894
+ const targetUrl = usingDiscovered ? selected : customUrl;
895
+ if (!usingDiscovered && !isValidUrl(targetUrl)) {
947
896
  return;
948
897
  }
949
898
  const normalizedUrl = targetUrl.replace(/\/+$/, "");
@@ -968,7 +917,7 @@ function LoginModal({
968
917
  setError("Failed to connect. Please check the URL and try again.");
969
918
  setLoading(false);
970
919
  }
971
- }, [nodeType, selected, customUrl, onConnect]);
920
+ }, [selected, customUrl, onConnect]);
972
921
  if (!isOpen) {
973
922
  return null;
974
923
  }
@@ -1018,7 +967,7 @@ function LoginModal({
1018
967
  )
1019
968
  );
1020
969
  };
1021
- const renderRemoteView = () => {
970
+ const renderNodeSection = () => {
1022
971
  if (discovering) {
1023
972
  return /* @__PURE__ */ jsxs("div", { style: styles.discovering, "data-testid": "node-discovering", children: [
1024
973
  /* @__PURE__ */ jsx("div", { style: styles.spinnerSmall }),
@@ -1026,7 +975,7 @@ function LoginModal({
1026
975
  ] });
1027
976
  }
1028
977
  return /* @__PURE__ */ jsxs(Fragment, { children: [
1029
- /* @__PURE__ */ jsx("p", { style: styles.info, children: hasDiscovered ? "Select a discovered node, or enter a node URL manually." : "No local node found. Enter a node URL to continue." }),
978
+ /* @__PURE__ */ jsx("p", { style: styles.info, children: hasDiscovered ? "Select your Calimero node to continue." : "No local node found. Enter a node URL to continue." }),
1030
979
  hasDiscovered && /* @__PURE__ */ jsxs(
1031
980
  "div",
1032
981
  {
@@ -1086,64 +1035,8 @@ function LoginModal({
1086
1035
  /* @__PURE__ */ jsx("p", { children: "Connecting to node..." }),
1087
1036
  /* @__PURE__ */ jsx("div", { style: styles.spinner })
1088
1037
  ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
1089
- shouldShowRadioGroup && /* @__PURE__ */ jsx("p", { style: styles.info, children: "Select your Calimero node type to continue." }),
1090
1038
  error && /* @__PURE__ */ jsx("p", { style: styles.error, children: error }),
1091
- shouldShowRadioGroup && /* @__PURE__ */ jsxs("div", { style: styles.radioGroup, children: [
1092
- /* @__PURE__ */ jsxs(
1093
- "label",
1094
- {
1095
- "data-testid": "node-type-local",
1096
- style: {
1097
- ...styles.radioLabel,
1098
- ...nodeType === "local" ? styles.radioLabelActive : {}
1099
- },
1100
- onClick: () => setNodeType("local"),
1101
- children: [
1102
- /* @__PURE__ */ jsx(
1103
- "input",
1104
- {
1105
- type: "radio",
1106
- value: "local",
1107
- checked: nodeType === "local",
1108
- onChange: () => setNodeType("local"),
1109
- style: { display: "none" }
1110
- }
1111
- ),
1112
- "Local"
1113
- ]
1114
- }
1115
- ),
1116
- /* @__PURE__ */ jsxs(
1117
- "label",
1118
- {
1119
- "data-testid": "node-type-remote",
1120
- style: {
1121
- ...styles.radioLabel,
1122
- ...nodeType === "remote" ? styles.radioLabelActive : {}
1123
- },
1124
- onClick: () => setNodeType("remote"),
1125
- children: [
1126
- /* @__PURE__ */ jsx(
1127
- "input",
1128
- {
1129
- type: "radio",
1130
- value: "remote",
1131
- checked: nodeType === "remote",
1132
- onChange: () => setNodeType("remote"),
1133
- style: { display: "none" }
1134
- }
1135
- ),
1136
- "Remote"
1137
- ]
1138
- }
1139
- )
1140
- ] }),
1141
- nodeType === "local" && shouldShowLocal && /* @__PURE__ */ jsxs("p", { style: styles.localInfo, children: [
1142
- "Using default local node: ",
1143
- /* @__PURE__ */ jsx("br", {}),
1144
- /* @__PURE__ */ jsx("code", { style: styles.localInfoCode, children: DEFAULT_LOCAL_NODE_URL })
1145
- ] }),
1146
- nodeType === "remote" && shouldShowRemote && renderRemoteView(),
1039
+ renderNodeSection(),
1147
1040
  /* @__PURE__ */ jsx("div", { style: styles.buttonGroup, children: /* @__PURE__ */ jsx(
1148
1041
  "button",
1149
1042
  {
@@ -1163,7 +1056,7 @@ function LoginModal({
1163
1056
  return createPortal(modalContent, document.body);
1164
1057
  }
1165
1058
  function ConnectButton({
1166
- connectionType = "remote-and-local" /* RemoteAndLocal */,
1059
+ connectionType = "remote" /* Remote */,
1167
1060
  className,
1168
1061
  style,
1169
1062
  theme,
@@ -1314,7 +1207,6 @@ function ConnectButton({
1314
1207
  isOpen: isModalOpen,
1315
1208
  onConnect: handleModalConnect,
1316
1209
  onClose: () => setIsModalOpen(false),
1317
- connectionType: typeof connectionType === "object" ? "remote-and-local" /* RemoteAndLocal */ : connectionType,
1318
1210
  theme: resolvedTheme ?? theme
1319
1211
  }
1320
1212
  )