@openzeppelin/ui-components 1.5.0 → 1.7.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 +97 -27
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +52 -2
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +53 -3
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +96 -27
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -3
package/dist/index.mjs
CHANGED
|
@@ -6,6 +6,7 @@ import * as React$1 from "react";
|
|
|
6
6
|
import React, { createContext, useCallback, useContext, useEffect, useId, useMemo, useRef, useState } from "react";
|
|
7
7
|
import { cn, getDefaultValueForType, getInvalidUrlMessage, getServiceDisplayName, isValidUrl, truncateMiddle, validateBytesSimple } from "@openzeppelin/ui-utils";
|
|
8
8
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
9
|
+
import * as TooltipPrimitive from "@radix-ui/react-tooltip";
|
|
9
10
|
import { Slot, Slottable } from "@radix-ui/react-slot";
|
|
10
11
|
import { DayPicker } from "react-day-picker";
|
|
11
12
|
import * as CheckboxPrimitive from "@radix-ui/react-checkbox";
|
|
@@ -20,11 +21,14 @@ import * as RadioGroupPrimitive from "@radix-ui/react-radio-group";
|
|
|
20
21
|
import * as SelectPrimitive from "@radix-ui/react-select";
|
|
21
22
|
import * as CollapsiblePrimitive from "@radix-ui/react-collapsible";
|
|
22
23
|
import * as TabsPrimitive from "@radix-ui/react-tabs";
|
|
23
|
-
import * as TooltipPrimitive from "@radix-ui/react-tooltip";
|
|
24
24
|
import { isMapEntryArray } from "@openzeppelin/ui-types";
|
|
25
25
|
import { Toaster as Toaster$1, toast } from "sonner";
|
|
26
26
|
import { useTheme } from "next-themes";
|
|
27
27
|
|
|
28
|
+
//#region src/version.ts
|
|
29
|
+
const VERSION = "1.7.0";
|
|
30
|
+
|
|
31
|
+
//#endregion
|
|
28
32
|
//#region src/components/ui/accordion.tsx
|
|
29
33
|
const accordionItemVariants = cva("", {
|
|
30
34
|
variants: { variant: {
|
|
@@ -102,6 +106,19 @@ const AccordionContent = React$1.forwardRef(({ className, children, variant: var
|
|
|
102
106
|
});
|
|
103
107
|
AccordionContent.displayName = "AccordionContent";
|
|
104
108
|
|
|
109
|
+
//#endregion
|
|
110
|
+
//#region src/components/ui/tooltip.tsx
|
|
111
|
+
const TooltipProvider = TooltipPrimitive.Provider;
|
|
112
|
+
const Tooltip = TooltipPrimitive.Root;
|
|
113
|
+
const TooltipTrigger = TooltipPrimitive.Trigger;
|
|
114
|
+
const TooltipContent = React$1.forwardRef(({ className, sideOffset = 4, ...props }, ref) => /* @__PURE__ */ jsx(TooltipPrimitive.Portal, { children: /* @__PURE__ */ jsx(TooltipPrimitive.Content, {
|
|
115
|
+
ref,
|
|
116
|
+
sideOffset,
|
|
117
|
+
className: cn("bg-primary text-primary-foreground animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 overflow-hidden rounded-md px-3 py-1.5 text-xs", className),
|
|
118
|
+
...props
|
|
119
|
+
}) }));
|
|
120
|
+
TooltipContent.displayName = TooltipPrimitive.Content.displayName;
|
|
121
|
+
|
|
105
122
|
//#endregion
|
|
106
123
|
//#region src/components/ui/address-display/context.ts
|
|
107
124
|
/**
|
|
@@ -114,8 +131,20 @@ const AddressLabelContext = createContext(null);
|
|
|
114
131
|
//#endregion
|
|
115
132
|
//#region src/components/ui/address-display/address-display.tsx
|
|
116
133
|
/**
|
|
134
|
+
* True when the primary input can hover (e.g. desktop with mouse).
|
|
135
|
+
* Touch-first phones typically report false. SSR assumes hover-capable.
|
|
136
|
+
*/
|
|
137
|
+
function usePrefersHover() {
|
|
138
|
+
return React$1.useSyncExternalStore(React$1.useCallback((onStoreChange) => {
|
|
139
|
+
if (typeof window === "undefined" || typeof window.matchMedia === "undefined") return () => {};
|
|
140
|
+
const mq = window.matchMedia("(hover: hover)");
|
|
141
|
+
mq.addEventListener("change", onStoreChange);
|
|
142
|
+
return () => mq.removeEventListener("change", onStoreChange);
|
|
143
|
+
}, []), () => typeof window !== "undefined" && typeof window.matchMedia !== "undefined" ? window.matchMedia("(hover: hover)").matches : true, () => true);
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
117
146
|
* Displays a blockchain address with optional truncation, copy button,
|
|
118
|
-
* explorer link, and human-readable label.
|
|
147
|
+
* explorer link, tooltip, and human-readable label.
|
|
119
148
|
*
|
|
120
149
|
* Labels are resolved in priority order:
|
|
121
150
|
* 1. Explicit `label` prop
|
|
@@ -140,11 +169,22 @@ const AddressLabelContext = createContext(null);
|
|
|
140
169
|
*
|
|
141
170
|
* // Suppress label resolution for a specific instance
|
|
142
171
|
* <AddressDisplay address="0x742d35Cc..." disableLabel />
|
|
172
|
+
*
|
|
173
|
+
* // Reveal full address on hover (still truncated when idle)
|
|
174
|
+
* <AddressDisplay address="0x742d35Cc..." untruncateOnHover />
|
|
175
|
+
*
|
|
176
|
+
* // Tooltip with full address on hover + copy icon on hover
|
|
177
|
+
* <AddressDisplay address="0x742d35Cc..." showTooltip showCopyButton showCopyButtonOnHover />
|
|
178
|
+
*
|
|
179
|
+
* // Inline variant (no chip background) — useful inside wallet bars
|
|
180
|
+
* <AddressDisplay address="0x742d35Cc..." variant="inline" showTooltip showCopyButton />
|
|
143
181
|
* ```
|
|
144
182
|
*/
|
|
145
|
-
function AddressDisplay({ address, truncate = true, startChars = 6, endChars = 4, showCopyButton = false, showCopyButtonOnHover = false, explorerUrl, label: labelProp, onLabelEdit: onLabelEditProp, networkId, disableLabel = false, className, ...props }) {
|
|
183
|
+
function AddressDisplay({ address, truncate = true, untruncateOnHover = false, startChars = 6, endChars = 4, showCopyButton = false, showCopyButtonOnHover = false, explorerUrl, label: labelProp, onLabelEdit: onLabelEditProp, networkId, disableLabel = false, showTooltip = false, variant = "chip", className, onPointerEnter, onPointerLeave, onMouseEnter, onMouseLeave, onClick, ...props }) {
|
|
146
184
|
const [copied, setCopied] = React$1.useState(false);
|
|
185
|
+
const [isHovered, setIsHovered] = React$1.useState(false);
|
|
147
186
|
const copyTimeoutRef = React$1.useRef(null);
|
|
187
|
+
const prefersHover = usePrefersHover();
|
|
148
188
|
const resolver = React$1.useContext(AddressLabelContext);
|
|
149
189
|
const resolvedLabel = disableLabel ? void 0 : labelProp ?? resolver?.resolveLabel(address, networkId);
|
|
150
190
|
const contextEditHandler = React$1.useCallback(() => {
|
|
@@ -155,7 +195,25 @@ function AddressDisplay({ address, truncate = true, startChars = 6, endChars = 4
|
|
|
155
195
|
networkId
|
|
156
196
|
]);
|
|
157
197
|
const editHandler = disableLabel ? void 0 : onLabelEditProp ?? (resolver?.onEditLabel ? contextEditHandler : void 0);
|
|
158
|
-
const
|
|
198
|
+
const canUntruncate = untruncateOnHover && truncate && !showTooltip;
|
|
199
|
+
const showFullAddress = !truncate || canUntruncate && isHovered;
|
|
200
|
+
const displayAddress = showFullAddress ? address : truncateMiddle(address, startChars, endChars);
|
|
201
|
+
const addressTextClassName = cn(!showFullAddress && "truncate", (showFullAddress || !truncate) && "break-all");
|
|
202
|
+
const expandInteractionClassName = canUntruncate && !prefersHover ? "cursor-pointer" : void 0;
|
|
203
|
+
const handlePointerEnter = (e) => {
|
|
204
|
+
if (canUntruncate && prefersHover) setIsHovered(true);
|
|
205
|
+
onPointerEnter?.(e);
|
|
206
|
+
onMouseEnter?.(e);
|
|
207
|
+
};
|
|
208
|
+
const handlePointerLeave = (e) => {
|
|
209
|
+
if (canUntruncate && prefersHover) setIsHovered(false);
|
|
210
|
+
onPointerLeave?.(e);
|
|
211
|
+
onMouseLeave?.(e);
|
|
212
|
+
};
|
|
213
|
+
const handleUntruncateClick = (e) => {
|
|
214
|
+
if (canUntruncate && !prefersHover) setIsHovered((open) => !open);
|
|
215
|
+
onClick?.(e);
|
|
216
|
+
};
|
|
159
217
|
const handleCopy = (e) => {
|
|
160
218
|
e.stopPropagation();
|
|
161
219
|
navigator.clipboard.writeText(address);
|
|
@@ -171,6 +229,7 @@ function AddressDisplay({ address, truncate = true, startChars = 6, endChars = 4
|
|
|
171
229
|
if (copyTimeoutRef.current) window.clearTimeout(copyTimeoutRef.current);
|
|
172
230
|
};
|
|
173
231
|
}, []);
|
|
232
|
+
const isChip = variant === "chip";
|
|
174
233
|
const actionButtons = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
175
234
|
showCopyButton && /* @__PURE__ */ jsx("button", {
|
|
176
235
|
type: "button",
|
|
@@ -183,6 +242,9 @@ function AddressDisplay({ address, truncate = true, startChars = 6, endChars = 4
|
|
|
183
242
|
href: explorerUrl,
|
|
184
243
|
target: "_blank",
|
|
185
244
|
rel: "noopener noreferrer",
|
|
245
|
+
onClick: (e) => {
|
|
246
|
+
e.stopPropagation();
|
|
247
|
+
},
|
|
186
248
|
className: "ml-1.5 shrink-0 text-slate-500 transition-colors hover:text-slate-700",
|
|
187
249
|
"aria-label": "View in explorer",
|
|
188
250
|
children: /* @__PURE__ */ jsx(ExternalLink$1, { className: "h-3.5 w-3.5" })
|
|
@@ -198,28 +260,48 @@ function AddressDisplay({ address, truncate = true, startChars = 6, endChars = 4
|
|
|
198
260
|
children: /* @__PURE__ */ jsx(Pencil, { className: "h-3.5 w-3.5" })
|
|
199
261
|
})
|
|
200
262
|
] });
|
|
201
|
-
|
|
202
|
-
|
|
263
|
+
const shouldShowTooltip = showTooltip && truncate;
|
|
264
|
+
const wrapWithTooltip = (content) => {
|
|
265
|
+
if (!shouldShowTooltip) return content;
|
|
266
|
+
return /* @__PURE__ */ jsx(TooltipProvider, {
|
|
267
|
+
delayDuration: 300,
|
|
268
|
+
children: /* @__PURE__ */ jsxs(Tooltip, { children: [/* @__PURE__ */ jsx(TooltipTrigger, {
|
|
269
|
+
asChild: true,
|
|
270
|
+
children: content
|
|
271
|
+
}), /* @__PURE__ */ jsx(TooltipContent, {
|
|
272
|
+
className: "font-mono text-xs",
|
|
273
|
+
children: address
|
|
274
|
+
})] })
|
|
275
|
+
});
|
|
276
|
+
};
|
|
277
|
+
if (resolvedLabel) return wrapWithTooltip(/* @__PURE__ */ jsxs("div", {
|
|
278
|
+
className: cn("group inline-flex max-w-full min-w-0 flex-col", isChip && "rounded-md bg-slate-100 px-2 py-1", "text-xs text-slate-700", expandInteractionClassName, className),
|
|
279
|
+
onPointerEnter: handlePointerEnter,
|
|
280
|
+
onPointerLeave: handlePointerLeave,
|
|
281
|
+
onClick: handleUntruncateClick,
|
|
203
282
|
...props,
|
|
204
283
|
children: [/* @__PURE__ */ jsx("span", {
|
|
205
284
|
className: "truncate font-sans font-medium text-slate-900 leading-snug",
|
|
206
285
|
children: resolvedLabel
|
|
207
286
|
}), /* @__PURE__ */ jsxs("div", {
|
|
208
|
-
className: "flex items-center font-mono text-[10px] text-slate-400 leading-snug",
|
|
287
|
+
className: "flex min-w-0 items-center font-mono text-[10px] text-slate-400 leading-snug",
|
|
209
288
|
children: [/* @__PURE__ */ jsx("span", {
|
|
210
|
-
className:
|
|
289
|
+
className: addressTextClassName,
|
|
211
290
|
children: displayAddress
|
|
212
291
|
}), actionButtons]
|
|
213
292
|
})]
|
|
214
|
-
});
|
|
215
|
-
return /* @__PURE__ */ jsxs("div", {
|
|
216
|
-
className: cn("group inline-flex max-w-full items-center rounded-md bg-slate-100 px-2 py-1", "text-xs font-mono text-slate-700", className),
|
|
293
|
+
}));
|
|
294
|
+
return wrapWithTooltip(/* @__PURE__ */ jsxs("div", {
|
|
295
|
+
className: cn("group inline-flex max-w-full min-w-0 items-center", isChip && "rounded-md bg-slate-100 px-2 py-1", "text-xs font-mono text-slate-700", expandInteractionClassName, className),
|
|
296
|
+
onPointerEnter: handlePointerEnter,
|
|
297
|
+
onPointerLeave: handlePointerLeave,
|
|
298
|
+
onClick: handleUntruncateClick,
|
|
217
299
|
...props,
|
|
218
300
|
children: [/* @__PURE__ */ jsx("span", {
|
|
219
|
-
className:
|
|
301
|
+
className: addressTextClassName,
|
|
220
302
|
children: displayAddress
|
|
221
303
|
}), actionButtons]
|
|
222
|
-
});
|
|
304
|
+
}));
|
|
223
305
|
}
|
|
224
306
|
|
|
225
307
|
//#endregion
|
|
@@ -1796,19 +1878,6 @@ const Textarea = React$1.forwardRef(({ className, ...props }, ref) => {
|
|
|
1796
1878
|
});
|
|
1797
1879
|
Textarea.displayName = "Textarea";
|
|
1798
1880
|
|
|
1799
|
-
//#endregion
|
|
1800
|
-
//#region src/components/ui/tooltip.tsx
|
|
1801
|
-
const TooltipProvider = TooltipPrimitive.Provider;
|
|
1802
|
-
const Tooltip = TooltipPrimitive.Root;
|
|
1803
|
-
const TooltipTrigger = TooltipPrimitive.Trigger;
|
|
1804
|
-
const TooltipContent = React$1.forwardRef(({ className, sideOffset = 4, ...props }, ref) => /* @__PURE__ */ jsx(TooltipPrimitive.Content, {
|
|
1805
|
-
ref,
|
|
1806
|
-
sideOffset,
|
|
1807
|
-
className: cn("bg-primary text-primary-foreground animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 overflow-hidden rounded-md px-3 py-1.5 text-xs", className),
|
|
1808
|
-
...props
|
|
1809
|
-
}));
|
|
1810
|
-
TooltipContent.displayName = TooltipPrimitive.Content.displayName;
|
|
1811
|
-
|
|
1812
1881
|
//#endregion
|
|
1813
1882
|
//#region src/components/ui/view-contract-state-button.tsx
|
|
1814
1883
|
/**
|
|
@@ -6260,5 +6329,5 @@ const Toaster = ({ ...props }) => {
|
|
|
6260
6329
|
};
|
|
6261
6330
|
|
|
6262
6331
|
//#endregion
|
|
6263
|
-
export { Accordion, AccordionContent, AccordionItem, AccordionTrigger, AddressDisplay, AddressField, AddressLabelProvider, AddressSuggestionProvider, Alert, AlertDescription, AlertTitle, AmountField, ArrayField, ArrayObjectField, Banner, BaseField, BigIntField, BooleanField, Button, BytesField, Calendar, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Checkbox, DateRangePicker, DateTimeField, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, EcosystemDropdown, EcosystemIcon, EmptyState, EnumField, ErrorMessage, ExternalLink, FileUploadField, Footer, Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage, Header, INTEGER_HTML_PATTERN, INTEGER_INPUT_PATTERN, INTEGER_PATTERN, Input, Label, LoadingButton, MapEntryRow, MapField, MidnightIcon, NetworkErrorNotificationProvider, NetworkIcon, NetworkSelector, NetworkServiceErrorBanner, NetworkStatusBadge, NumberField, ObjectField, OverflowMenu, PasswordField, Popover, PopoverAnchor, PopoverContent, PopoverTrigger, Progress, RadioField, RadioGroup, RadioGroupItem, RelayerDetailsCard, Select, SelectContent, SelectField, SelectGroup, SelectGroupedField, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, SidebarButton, SidebarGroup, SidebarLayout, SidebarSection, Tabs, TabsContent, TabsList, TabsTrigger, TextAreaField, TextField, Textarea, Toaster, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, UrlField, ViewContractStateButton, WizardLayout, WizardNavigation, WizardStepper, buttonVariants, computeChildTouched, createFocusManager, createValidationResult, formatValidationError, getAccessibilityProps, getDescribedById, getErrorMessage, getValidationStateClasses, getWidthClasses, handleEscapeKey, handleKeyboardEvent, handleNumericKeys, handleToggleKeys, handleValidationError, hasFieldError, isDuplicateMapKey, useAddressLabel, useAddressSuggestions, useDuplicateKeyIndexes, useMapFieldSync, useNetworkErrorAwareAdapter, useNetworkErrorReporter, useNetworkErrors, validateField, validateMapEntries, validateMapStructure };
|
|
6332
|
+
export { Accordion, AccordionContent, AccordionItem, AccordionTrigger, AddressDisplay, AddressField, AddressLabelProvider, AddressSuggestionProvider, Alert, AlertDescription, AlertTitle, AmountField, ArrayField, ArrayObjectField, Banner, BaseField, BigIntField, BooleanField, Button, BytesField, Calendar, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Checkbox, DateRangePicker, DateTimeField, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, EcosystemDropdown, EcosystemIcon, EmptyState, EnumField, ErrorMessage, ExternalLink, FileUploadField, Footer, Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage, Header, INTEGER_HTML_PATTERN, INTEGER_INPUT_PATTERN, INTEGER_PATTERN, Input, Label, LoadingButton, MapEntryRow, MapField, MidnightIcon, NetworkErrorNotificationProvider, NetworkIcon, NetworkSelector, NetworkServiceErrorBanner, NetworkStatusBadge, NumberField, ObjectField, OverflowMenu, PasswordField, Popover, PopoverAnchor, PopoverContent, PopoverTrigger, Progress, RadioField, RadioGroup, RadioGroupItem, RelayerDetailsCard, Select, SelectContent, SelectField, SelectGroup, SelectGroupedField, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, SidebarButton, SidebarGroup, SidebarLayout, SidebarSection, Tabs, TabsContent, TabsList, TabsTrigger, TextAreaField, TextField, Textarea, Toaster, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, UrlField, VERSION, ViewContractStateButton, WizardLayout, WizardNavigation, WizardStepper, buttonVariants, computeChildTouched, createFocusManager, createValidationResult, formatValidationError, getAccessibilityProps, getDescribedById, getErrorMessage, getValidationStateClasses, getWidthClasses, handleEscapeKey, handleKeyboardEvent, handleNumericKeys, handleToggleKeys, handleValidationError, hasFieldError, isDuplicateMapKey, useAddressLabel, useAddressSuggestions, useDuplicateKeyIndexes, useMapFieldSync, useNetworkErrorAwareAdapter, useNetworkErrorReporter, useNetworkErrors, validateField, validateMapEntries, validateMapStructure };
|
|
6264
6333
|
//# sourceMappingURL=index.mjs.map
|