@openzeppelin/ui-components 3.4.0 → 3.5.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
@@ -38,7 +38,7 @@ let sonner = require("sonner");
38
38
  let next_themes = require("next-themes");
39
39
 
40
40
  //#region src/version.ts
41
- const VERSION = "3.4.0";
41
+ const VERSION = "3.5.0";
42
42
 
43
43
  //#endregion
44
44
  //#region src/components/ui/accordion.tsx
@@ -276,7 +276,7 @@ function sanitizeVerifiedNameForDisplay(name) {
276
276
  * <AddressDisplay address="G..." truncateWhenLabeled />
277
277
  * ```
278
278
  */
279
- function AddressDisplay({ address, truncate: truncateProp, truncateWhenLabeled = false, untruncateOnHover = false, startChars = 6, endChars = 4, showCopyButton = false, showCopyButtonOnHover = false, explorerUrl, label: labelProp, onLabelEdit: onLabelEditProp, networkId, disableLabel = false, showTooltip = false, variant = "chip", avatar, avatarVariant = "fill", resolvedName, className, onPointerEnter, onPointerLeave, onMouseEnter, onMouseLeave, onClick, ...props }) {
279
+ function AddressDisplay({ address, truncate: truncateProp, truncateWhenLabeled = false, untruncateOnHover = false, startChars = 6, endChars = 4, showCopyButton = false, showCopyButtonOnHover = false, explorerUrl, label: labelProp, onLabelEdit: onLabelEditProp, networkId, disableLabel = false, showTooltip = false, variant = "chip", avatar, avatarVariant = "fill", resolvedName, showCrossNetworkFallbackDisclaimer = true, className, onPointerEnter, onPointerLeave, onMouseEnter, onMouseLeave, onClick, ...props }) {
280
280
  const [copied, setCopied] = react.useState(false);
281
281
  const [isHovered, setIsHovered] = react.useState(false);
282
282
  const copyTimeoutRef = react.useRef(null);
@@ -287,6 +287,13 @@ function AddressDisplay({ address, truncate: truncateProp, truncateWhenLabeled =
287
287
  const record = disableLabel ? void 0 : resolvedName ?? nameResolver?.resolveAddressName(address, networkId);
288
288
  const ensName = record?.forwardVerified === true ? sanitizeVerifiedNameForDisplay(record.name) : void 0;
289
289
  const effectiveLabel = resolvedLabel ?? ensName;
290
+ const showFallbackNote = showCrossNetworkFallbackDisclaimer && ensName !== void 0 && effectiveLabel === ensName && record !== void 0 && (0, _openzeppelin_ui_utils.isCrossNetworkFallback)(record.provenance);
291
+ const fallbackNote = (() => {
292
+ if (!showFallbackNote) return void 0;
293
+ const networks = (0, _openzeppelin_ui_utils.getFallbackNetworks)(record.provenance);
294
+ if (networks === void 0) return void 0;
295
+ return (0, _openzeppelin_ui_utils.nameResolutionCrossNetworkFallbackMessage)(networks, (0, _openzeppelin_ui_utils.crossNetworkFallbackMessageNames)(networks, nameResolver?.resolveNetworkLabel));
296
+ })();
290
297
  const effectiveTruncate = truncateProp !== void 0 ? truncateProp : truncateWhenLabeled ? Boolean(effectiveLabel) : true;
291
298
  const contextEditHandler = react.useCallback(() => {
292
299
  resolver?.onEditLabel?.(address, networkId);
@@ -387,9 +394,29 @@ function AddressDisplay({ address, truncate: truncateProp, truncateWhenLabeled =
387
394
  });
388
395
  };
389
396
  if (effectiveLabel) {
390
- const labelColumn = /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
391
- className: "truncate font-sans font-medium text-slate-900 leading-snug",
392
- children: effectiveLabel
397
+ const labelColumn = /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
398
+ className: "inline-flex min-w-0 max-w-full items-center gap-1",
399
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
400
+ className: "truncate font-sans font-medium text-slate-900 leading-snug",
401
+ children: effectiveLabel
402
+ }), fallbackNote && showCrossNetworkFallbackDisclaimer ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TooltipProvider, {
403
+ delayDuration: 300,
404
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(Tooltip, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(TooltipTrigger, {
405
+ asChild: true,
406
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
407
+ type: "button",
408
+ className: "inline-flex shrink-0 rounded-sm text-amber-500 outline-none focus-visible:ring-2 focus-visible:ring-amber-500/50",
409
+ "aria-label": fallbackNote,
410
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.TriangleAlert, {
411
+ className: "h-3 w-3",
412
+ "aria-hidden": true
413
+ })
414
+ })
415
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TooltipContent, {
416
+ className: "max-w-xs font-sans text-xs font-normal normal-case",
417
+ children: fallbackNote
418
+ })] })
419
+ }) : null]
393
420
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
394
421
  className: "flex min-w-0 items-center font-mono text-[10px] text-slate-400 leading-snug",
395
422
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
@@ -553,8 +580,11 @@ function useAddressLabel(address, networkId) {
553
580
  *
554
581
  * @param props - Resolver function and children
555
582
  */
556
- function AddressNameProvider({ children, resolveAddressName }) {
557
- const value = react.useMemo(() => ({ resolveAddressName }), [resolveAddressName]);
583
+ function AddressNameProvider({ children, resolveAddressName, resolveNetworkLabel }) {
584
+ const value = react.useMemo(() => ({
585
+ resolveAddressName,
586
+ resolveNetworkLabel
587
+ }), [resolveAddressName, resolveNetworkLabel]);
558
588
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(AddressNameContext.Provider, {
559
589
  value,
560
590
  children
@@ -3409,7 +3439,7 @@ function normalizeResolvedName(value) {
3409
3439
  * The component stays capability-free: it never reads a runtime or wallet
3410
3440
  * state; everything arrives through the injected context (INV-118).
3411
3441
  */
3412
- function AddressField({ id, label, placeholder, helperText, control, name, width = "full", validation, addressing, readOnly, suggestions: suggestionsProp, onSuggestionSelect, onResolvedNameChange }) {
3442
+ function AddressField({ id, label, placeholder, helperText, control, name, width = "full", validation, addressing, readOnly, suggestions: suggestionsProp, onSuggestionSelect, onResolvedNameChange, showCrossNetworkFallbackDisclaimer = true }) {
3413
3443
  const isRequired = !!validation?.required;
3414
3444
  const errorId = `${id}-error`;
3415
3445
  const descriptionId = `${id}-description`;
@@ -3419,6 +3449,7 @@ function AddressField({ id, label, placeholder, helperText, control, name, width
3419
3449
  const isValidName = resolver?.isValidName;
3420
3450
  const activeNetworkId = resolver?.activeNetworkId;
3421
3451
  const activeNetworkName = resolver?.activeNetworkName;
3452
+ const resolveNetworkLabel = resolver?.resolveNetworkLabel;
3422
3453
  const lastSetValueRef = (0, react.useRef)("");
3423
3454
  const [inputValue, setInputValue] = (0, react.useState)("");
3424
3455
  const watchedFieldValue = (0, react_hook_form.useWatch)({
@@ -3609,12 +3640,18 @@ function AddressField({ id, label, placeholder, helperText, control, name, width
3609
3640
  className: "text-destructive text-sm",
3610
3641
  children: (0, _openzeppelin_ui_utils.nameResolutionChainScopeMismatchMessage)({ activeNetworkName })
3611
3642
  });
3643
+ const fallbackNetworks = showCrossNetworkFallbackDisclaimer && (0, _openzeppelin_ui_utils.isCrossNetworkFallback)(resolution.data.provenance) ? (0, _openzeppelin_ui_utils.getFallbackNetworks)(resolution.data.provenance) : void 0;
3644
+ const fallbackMessage = fallbackNetworks && (0, _openzeppelin_ui_utils.nameResolutionCrossNetworkFallbackMessage)(fallbackNetworks, (0, _openzeppelin_ui_utils.crossNetworkFallbackMessageNames)(fallbackNetworks, resolveNetworkLabel));
3612
3645
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
3613
3646
  className: "text-sm",
3614
- children: ["Resolved to ", /* @__PURE__ */ (0, react_jsx_runtime.jsx)("code", {
3647
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", { children: ["Resolved to ", /* @__PURE__ */ (0, react_jsx_runtime.jsx)("code", {
3615
3648
  className: "font-mono",
3616
3649
  children: resolution.data.address
3617
- })]
3650
+ })] }), fallbackMessage ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
3651
+ className: "mt-1 block text-muted-foreground text-xs",
3652
+ role: "note",
3653
+ children: fallbackMessage
3654
+ }) : null]
3618
3655
  });
3619
3656
  case "error": {
3620
3657
  const networkName = resolution.error.code === "UNSUPPORTED_NETWORK" ? resolution.error.networkId || void 0 : void 0;
@@ -4294,17 +4331,19 @@ function useAddressSuggestions(query, networkId) {
4294
4331
  *
4295
4332
  * @param props - Injected resolver functions and children
4296
4333
  */
4297
- function NameResolverProvider({ children, isValidName, resolveName, activeNetworkId, activeNetworkName }) {
4334
+ function NameResolverProvider({ children, isValidName, resolveName, activeNetworkId, activeNetworkName, resolveNetworkLabel }) {
4298
4335
  const value = react.useMemo(() => ({
4299
4336
  isValidName,
4300
4337
  resolveName,
4301
4338
  activeNetworkId,
4302
- activeNetworkName
4339
+ activeNetworkName,
4340
+ resolveNetworkLabel
4303
4341
  }), [
4304
4342
  isValidName,
4305
4343
  resolveName,
4306
4344
  activeNetworkId,
4307
- activeNetworkName
4345
+ activeNetworkName,
4346
+ resolveNetworkLabel
4308
4347
  ]);
4309
4348
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(NameResolverContext.Provider, {
4310
4349
  value,