@openzeppelin/ui-components 1.3.0 → 1.4.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/README.md +14 -0
- package/dist/index.cjs +535 -55
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +246 -12
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +252 -18
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +532 -57
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -3
package/dist/index.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { a as getValidationStateClasses, c as isDuplicateMapKey, d as INTEGER_HTML_PATTERN, f as INTEGER_INPUT_PATTERN, i as getErrorMessage, l as validateField, n as createValidationResult, o as handleValidationError, p as INTEGER_PATTERN, r as formatValidationError, s as hasFieldError, t as ErrorMessage, u as validateMapEntries } from "./ErrorMessage-BqOEJm84.mjs";
|
|
2
2
|
import * as AccordionPrimitive from "@radix-ui/react-accordion";
|
|
3
3
|
import { cva } from "class-variance-authority";
|
|
4
|
-
import { AlertCircle, Calendar as Calendar$1, Check, CheckCircle, CheckCircle2, CheckIcon, ChevronDown, ChevronLeft, ChevronRight, ChevronUp, Circle, CloudOff, Copy, DollarSign, ExternalLink as ExternalLink$1, ExternalLinkIcon, Eye, EyeOff, File, FileText, GripVertical, Hash, Info, Loader2, Menu, Network, Plus, Search, Settings, Timer, Upload, X } from "lucide-react";
|
|
4
|
+
import { AlertCircle, Calendar as Calendar$1, Check, CheckCircle, CheckCircle2, CheckIcon, ChevronDown, ChevronLeft, ChevronRight, ChevronUp, Circle, CloudOff, Copy, DollarSign, ExternalLink as ExternalLink$1, ExternalLinkIcon, Eye, EyeOff, File, FileText, GripVertical, Hash, Info, Loader2, Menu, MoreHorizontal, Network, Pencil, Plus, Search, Settings, Timer, Upload, X } from "lucide-react";
|
|
5
5
|
import * as React$1 from "react";
|
|
6
6
|
import React, { createContext, useCallback, useContext, useEffect, useMemo, useRef, useState } from "react";
|
|
7
7
|
import { cn, getDefaultValueForType, getInvalidUrlMessage, getServiceDisplayName, isValidUrl, truncateMiddle, validateBytesSimple } from "@openzeppelin/ui-utils";
|
|
@@ -103,11 +103,58 @@ const AccordionContent = React$1.forwardRef(({ className, children, variant: var
|
|
|
103
103
|
AccordionContent.displayName = "AccordionContent";
|
|
104
104
|
|
|
105
105
|
//#endregion
|
|
106
|
-
//#region src/components/ui/address-display.
|
|
107
|
-
/**
|
|
108
|
-
|
|
106
|
+
//#region src/components/ui/address-display/context.ts
|
|
107
|
+
/**
|
|
108
|
+
* @internal Shared context instance consumed by both AddressDisplay and
|
|
109
|
+
* AddressLabelProvider. Kept in its own file so component files export
|
|
110
|
+
* only components (required by React Fast Refresh).
|
|
111
|
+
*/
|
|
112
|
+
const AddressLabelContext = createContext(null);
|
|
113
|
+
|
|
114
|
+
//#endregion
|
|
115
|
+
//#region src/components/ui/address-display/address-display.tsx
|
|
116
|
+
/**
|
|
117
|
+
* Displays a blockchain address with optional truncation, copy button,
|
|
118
|
+
* explorer link, and human-readable label.
|
|
119
|
+
*
|
|
120
|
+
* Labels are resolved in priority order:
|
|
121
|
+
* 1. Explicit `label` prop
|
|
122
|
+
* 2. `AddressLabelContext` resolver (via `AddressLabelProvider`)
|
|
123
|
+
* 3. No label (renders address only, identical to previous behavior)
|
|
124
|
+
*
|
|
125
|
+
* Pass `disableLabel` to suppress context-based resolution (e.g. when the
|
|
126
|
+
* surrounding UI already shows a name, such as a contract selector).
|
|
127
|
+
*
|
|
128
|
+
* @example
|
|
129
|
+
* ```tsx
|
|
130
|
+
* // Basic usage (unchanged)
|
|
131
|
+
* <AddressDisplay address="0x742d35Cc..." showCopyButton />
|
|
132
|
+
*
|
|
133
|
+
* // Explicit label
|
|
134
|
+
* <AddressDisplay address="0x742d35Cc..." label="Treasury" />
|
|
135
|
+
*
|
|
136
|
+
* // Auto-resolved via context (no changes needed at call site)
|
|
137
|
+
* <AddressLabelProvider resolveLabel={myResolver}>
|
|
138
|
+
* <AddressDisplay address="0x742d35Cc..." />
|
|
139
|
+
* </AddressLabelProvider>
|
|
140
|
+
*
|
|
141
|
+
* // Suppress label resolution for a specific instance
|
|
142
|
+
* <AddressDisplay address="0x742d35Cc..." disableLabel />
|
|
143
|
+
* ```
|
|
144
|
+
*/
|
|
145
|
+
function AddressDisplay({ address, truncate = true, startChars = 6, endChars = 4, showCopyButton = false, showCopyButtonOnHover = false, explorerUrl, label: labelProp, onLabelEdit: onLabelEditProp, networkId, disableLabel = false, className, ...props }) {
|
|
109
146
|
const [copied, setCopied] = React$1.useState(false);
|
|
110
147
|
const copyTimeoutRef = React$1.useRef(null);
|
|
148
|
+
const resolver = React$1.useContext(AddressLabelContext);
|
|
149
|
+
const resolvedLabel = disableLabel ? void 0 : labelProp ?? resolver?.resolveLabel(address, networkId);
|
|
150
|
+
const contextEditHandler = React$1.useCallback(() => {
|
|
151
|
+
resolver?.onEditLabel?.(address, networkId);
|
|
152
|
+
}, [
|
|
153
|
+
resolver,
|
|
154
|
+
address,
|
|
155
|
+
networkId
|
|
156
|
+
]);
|
|
157
|
+
const editHandler = disableLabel ? void 0 : onLabelEditProp ?? (resolver?.onEditLabel ? contextEditHandler : void 0);
|
|
111
158
|
const displayAddress = truncate ? truncateMiddle(address, startChars, endChars) : address;
|
|
112
159
|
const handleCopy = (e) => {
|
|
113
160
|
e.stopPropagation();
|
|
@@ -124,11 +171,7 @@ function AddressDisplay({ address, truncate = true, startChars = 6, endChars = 4
|
|
|
124
171
|
if (copyTimeoutRef.current) window.clearTimeout(copyTimeoutRef.current);
|
|
125
172
|
};
|
|
126
173
|
}, []);
|
|
127
|
-
const
|
|
128
|
-
/* @__PURE__ */ jsx("span", {
|
|
129
|
-
className: cn("truncate", truncate ? "" : "break-all"),
|
|
130
|
-
children: displayAddress
|
|
131
|
-
}),
|
|
174
|
+
const actionButtons = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
132
175
|
showCopyButton && /* @__PURE__ */ jsx("button", {
|
|
133
176
|
type: "button",
|
|
134
177
|
onClick: handleCopy,
|
|
@@ -143,15 +186,136 @@ function AddressDisplay({ address, truncate = true, startChars = 6, endChars = 4
|
|
|
143
186
|
className: "ml-1.5 shrink-0 text-slate-500 transition-colors hover:text-slate-700",
|
|
144
187
|
"aria-label": "View in explorer",
|
|
145
188
|
children: /* @__PURE__ */ jsx(ExternalLink$1, { className: "h-3.5 w-3.5" })
|
|
189
|
+
}),
|
|
190
|
+
editHandler && /* @__PURE__ */ jsx("button", {
|
|
191
|
+
type: "button",
|
|
192
|
+
onClick: (e) => {
|
|
193
|
+
e.stopPropagation();
|
|
194
|
+
editHandler();
|
|
195
|
+
},
|
|
196
|
+
className: "ml-0 w-0 shrink-0 overflow-hidden text-slate-500 opacity-0 transition-all duration-150 hover:text-slate-700 group-hover:ml-1.5 group-hover:w-3.5 group-hover:opacity-100 focus:ml-1.5 focus:w-3.5 focus:opacity-100",
|
|
197
|
+
"aria-label": "Edit label",
|
|
198
|
+
children: /* @__PURE__ */ jsx(Pencil, { className: "h-3.5 w-3.5" })
|
|
146
199
|
})
|
|
147
200
|
] });
|
|
148
|
-
return /* @__PURE__ */
|
|
201
|
+
if (resolvedLabel) return /* @__PURE__ */ jsxs("div", {
|
|
202
|
+
className: cn("group inline-flex max-w-full flex-col rounded-md bg-slate-100 px-2 py-1", "text-xs text-slate-700", className),
|
|
203
|
+
...props,
|
|
204
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
205
|
+
className: "truncate font-sans font-medium text-slate-900 leading-snug",
|
|
206
|
+
children: resolvedLabel
|
|
207
|
+
}), /* @__PURE__ */ jsxs("div", {
|
|
208
|
+
className: "flex items-center font-mono text-[10px] text-slate-400 leading-snug",
|
|
209
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
210
|
+
className: cn("truncate", truncate ? "" : "break-all"),
|
|
211
|
+
children: displayAddress
|
|
212
|
+
}), actionButtons]
|
|
213
|
+
})]
|
|
214
|
+
});
|
|
215
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
149
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),
|
|
150
217
|
...props,
|
|
151
|
-
children:
|
|
218
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
219
|
+
className: cn("truncate", truncate ? "" : "break-all"),
|
|
220
|
+
children: displayAddress
|
|
221
|
+
}), actionButtons]
|
|
222
|
+
});
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
//#endregion
|
|
226
|
+
//#region src/components/ui/address-display/address-label-context.tsx
|
|
227
|
+
/**
|
|
228
|
+
* Address Label Context
|
|
229
|
+
*
|
|
230
|
+
* Provides a React context for resolving human-readable labels for blockchain
|
|
231
|
+
* addresses. When an `AddressLabelProvider` is mounted, every `AddressDisplay`
|
|
232
|
+
* in the subtree automatically resolves and renders labels without any
|
|
233
|
+
* call-site changes.
|
|
234
|
+
*
|
|
235
|
+
* @example
|
|
236
|
+
* ```tsx
|
|
237
|
+
* import { AddressLabelProvider } from '@openzeppelin/ui-components';
|
|
238
|
+
*
|
|
239
|
+
* function App() {
|
|
240
|
+
* const resolver = useAliasLabelResolver(db);
|
|
241
|
+
* return (
|
|
242
|
+
* <AddressLabelProvider {...resolver}>
|
|
243
|
+
* <MyApp />
|
|
244
|
+
* </AddressLabelProvider>
|
|
245
|
+
* );
|
|
246
|
+
* }
|
|
247
|
+
* ```
|
|
248
|
+
*/
|
|
249
|
+
/**
|
|
250
|
+
* Provides address label resolution to all `AddressDisplay` instances in the
|
|
251
|
+
* subtree. Wrap your application (or a subsection) with this provider and
|
|
252
|
+
* supply a `resolveLabel` function.
|
|
253
|
+
*
|
|
254
|
+
* @param props - Resolver functions and children
|
|
255
|
+
*
|
|
256
|
+
* @example
|
|
257
|
+
* ```tsx
|
|
258
|
+
* <AddressLabelProvider
|
|
259
|
+
* resolveLabel={(addr) => addressBook.get(addr)}
|
|
260
|
+
* onEditLabel={(addr) => openEditor(addr)}
|
|
261
|
+
* >
|
|
262
|
+
* <App />
|
|
263
|
+
* </AddressLabelProvider>
|
|
264
|
+
* ```
|
|
265
|
+
*/
|
|
266
|
+
function AddressLabelProvider({ children, resolveLabel, onEditLabel }) {
|
|
267
|
+
const value = React$1.useMemo(() => ({
|
|
268
|
+
resolveLabel,
|
|
269
|
+
onEditLabel
|
|
270
|
+
}), [resolveLabel, onEditLabel]);
|
|
271
|
+
return /* @__PURE__ */ jsx(AddressLabelContext.Provider, {
|
|
272
|
+
value,
|
|
273
|
+
children
|
|
152
274
|
});
|
|
153
275
|
}
|
|
154
276
|
|
|
277
|
+
//#endregion
|
|
278
|
+
//#region src/components/ui/address-display/use-address-label.ts
|
|
279
|
+
/**
|
|
280
|
+
* Convenience hook for resolving an address label from the nearest
|
|
281
|
+
* `AddressLabelProvider`.
|
|
282
|
+
*
|
|
283
|
+
* Kept in its own file so that `address-label-context.tsx` exports only
|
|
284
|
+
* components (required by React Fast Refresh).
|
|
285
|
+
*/
|
|
286
|
+
/**
|
|
287
|
+
* Convenience hook that resolves a label for a specific address using the
|
|
288
|
+
* nearest `AddressLabelProvider`. Returns `undefined` values when no provider
|
|
289
|
+
* is mounted.
|
|
290
|
+
*
|
|
291
|
+
* @param address - The blockchain address to resolve
|
|
292
|
+
* @param networkId - Optional network identifier for network-specific aliases
|
|
293
|
+
* @returns Resolved label and edit handler for the address
|
|
294
|
+
*
|
|
295
|
+
* @example
|
|
296
|
+
* ```tsx
|
|
297
|
+
* function MyAddress({ address }: { address: string }) {
|
|
298
|
+
* const { label, onEdit } = useAddressLabel(address, 'ethereum-mainnet');
|
|
299
|
+
* return <span>{label ?? address}</span>;
|
|
300
|
+
* }
|
|
301
|
+
* ```
|
|
302
|
+
*/
|
|
303
|
+
function useAddressLabel(address, networkId) {
|
|
304
|
+
const resolver = React$1.useContext(AddressLabelContext);
|
|
305
|
+
const label = resolver?.resolveLabel(address, networkId);
|
|
306
|
+
const onEdit = React$1.useCallback(() => {
|
|
307
|
+
resolver?.onEditLabel?.(address, networkId);
|
|
308
|
+
}, [
|
|
309
|
+
resolver,
|
|
310
|
+
address,
|
|
311
|
+
networkId
|
|
312
|
+
]);
|
|
313
|
+
return {
|
|
314
|
+
label,
|
|
315
|
+
onEdit: resolver?.onEditLabel ? onEdit : void 0
|
|
316
|
+
};
|
|
317
|
+
}
|
|
318
|
+
|
|
155
319
|
//#endregion
|
|
156
320
|
//#region src/components/ui/alert.tsx
|
|
157
321
|
const alertVariants = cva("relative w-full rounded-lg border p-4 [&>svg~*]:pl-7 [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 [&>svg]:text-foreground", {
|
|
@@ -1085,10 +1249,15 @@ function NetworkIcon({ network, className, size = 16, variant = "branded" }) {
|
|
|
1085
1249
|
|
|
1086
1250
|
//#endregion
|
|
1087
1251
|
//#region src/components/ui/network-selector.tsx
|
|
1088
|
-
/** Searchable dropdown selector for blockchain networks with optional grouping. */
|
|
1089
|
-
function NetworkSelector({ networks,
|
|
1252
|
+
/** Searchable dropdown selector for blockchain networks with optional grouping and multi-select. */
|
|
1253
|
+
function NetworkSelector({ networks, getNetworkLabel, getNetworkIcon, getNetworkType, getNetworkId, groupByEcosystem = false, getEcosystem, filterNetwork, className, placeholder = "Select Network", ...modeProps }) {
|
|
1090
1254
|
const [open, setOpen] = React$1.useState(false);
|
|
1091
1255
|
const [searchQuery, setSearchQuery] = React$1.useState("");
|
|
1256
|
+
const isMultiple = modeProps.multiple === true;
|
|
1257
|
+
const selectedNetworkIds = isMultiple ? modeProps.selectedNetworkIds : void 0;
|
|
1258
|
+
const onSelectionChange = isMultiple ? modeProps.onSelectionChange : void 0;
|
|
1259
|
+
const selectedNetwork = !isMultiple ? modeProps.selectedNetwork : void 0;
|
|
1260
|
+
const onSelectNetwork = !isMultiple ? modeProps.onSelectNetwork : void 0;
|
|
1092
1261
|
const filteredNetworks = React$1.useMemo(() => {
|
|
1093
1262
|
if (!searchQuery) return networks;
|
|
1094
1263
|
if (filterNetwork) return networks.filter((n) => filterNetwork(n, searchQuery));
|
|
@@ -1112,34 +1281,79 @@ function NetworkSelector({ networks, selectedNetwork, onSelectNetwork, getNetwor
|
|
|
1112
1281
|
groupByEcosystem,
|
|
1113
1282
|
getEcosystem
|
|
1114
1283
|
]);
|
|
1284
|
+
const isSelected = React$1.useCallback((network) => {
|
|
1285
|
+
if (isMultiple && selectedNetworkIds) return selectedNetworkIds.includes(getNetworkId(network));
|
|
1286
|
+
return selectedNetwork ? getNetworkId(selectedNetwork) === getNetworkId(network) : false;
|
|
1287
|
+
}, [
|
|
1288
|
+
isMultiple,
|
|
1289
|
+
selectedNetworkIds,
|
|
1290
|
+
selectedNetwork,
|
|
1291
|
+
getNetworkId
|
|
1292
|
+
]);
|
|
1293
|
+
const handleSelect = React$1.useCallback((network) => {
|
|
1294
|
+
if (isMultiple && selectedNetworkIds && onSelectionChange) {
|
|
1295
|
+
const id = getNetworkId(network);
|
|
1296
|
+
onSelectionChange(selectedNetworkIds.includes(id) ? selectedNetworkIds.filter((x) => x !== id) : [...selectedNetworkIds, id]);
|
|
1297
|
+
} else if (onSelectNetwork) {
|
|
1298
|
+
onSelectNetwork(network);
|
|
1299
|
+
setOpen(false);
|
|
1300
|
+
}
|
|
1301
|
+
}, [
|
|
1302
|
+
isMultiple,
|
|
1303
|
+
selectedNetworkIds,
|
|
1304
|
+
onSelectionChange,
|
|
1305
|
+
onSelectNetwork,
|
|
1306
|
+
getNetworkId
|
|
1307
|
+
]);
|
|
1308
|
+
const handleClearAll = React$1.useCallback(() => {
|
|
1309
|
+
if (isMultiple && onSelectionChange) onSelectionChange([]);
|
|
1310
|
+
}, [isMultiple, onSelectionChange]);
|
|
1311
|
+
const selectedCount = selectedNetworkIds?.length ?? 0;
|
|
1312
|
+
const renderTrigger = isMultiple ? modeProps.renderTrigger : void 0;
|
|
1115
1313
|
return /* @__PURE__ */ jsxs(DropdownMenu, {
|
|
1116
1314
|
open,
|
|
1117
1315
|
onOpenChange: setOpen,
|
|
1118
1316
|
children: [/* @__PURE__ */ jsx(DropdownMenuTrigger, {
|
|
1119
1317
|
asChild: true,
|
|
1120
|
-
children:
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
}
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1318
|
+
children: (() => {
|
|
1319
|
+
if (isMultiple && renderTrigger) return renderTrigger({
|
|
1320
|
+
selectedCount,
|
|
1321
|
+
open
|
|
1322
|
+
});
|
|
1323
|
+
if (isMultiple) return /* @__PURE__ */ jsxs(Button, {
|
|
1324
|
+
variant: "outline",
|
|
1325
|
+
role: "combobox",
|
|
1326
|
+
"aria-expanded": open,
|
|
1327
|
+
className: cn("w-full justify-between", className),
|
|
1328
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
1329
|
+
className: "truncate text-muted-foreground",
|
|
1330
|
+
children: selectedCount > 0 ? `${selectedCount} network${selectedCount > 1 ? "s" : ""} selected` : placeholder
|
|
1331
|
+
}), /* @__PURE__ */ jsx(ChevronDown, { className: "ml-2 h-4 w-4 shrink-0 opacity-50" })]
|
|
1332
|
+
});
|
|
1333
|
+
return /* @__PURE__ */ jsxs(Button, {
|
|
1334
|
+
variant: "outline",
|
|
1335
|
+
role: "combobox",
|
|
1336
|
+
"aria-expanded": open,
|
|
1337
|
+
className: cn("w-full justify-between", className),
|
|
1338
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
1339
|
+
className: "flex items-center gap-2 truncate",
|
|
1340
|
+
children: selectedNetwork ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1341
|
+
getNetworkIcon?.(selectedNetwork),
|
|
1342
|
+
/* @__PURE__ */ jsx("span", {
|
|
1343
|
+
className: "truncate",
|
|
1344
|
+
children: getNetworkLabel(selectedNetwork)
|
|
1345
|
+
}),
|
|
1346
|
+
getNetworkType && /* @__PURE__ */ jsx("span", {
|
|
1347
|
+
className: "shrink-0 rounded-sm bg-muted px-1.5 py-0.5 text-[10px] font-medium uppercase text-muted-foreground",
|
|
1348
|
+
children: getNetworkType(selectedNetwork)
|
|
1349
|
+
})
|
|
1350
|
+
] }) : /* @__PURE__ */ jsx("span", {
|
|
1351
|
+
className: "text-muted-foreground",
|
|
1352
|
+
children: placeholder
|
|
1136
1353
|
})
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
})
|
|
1141
|
-
}), /* @__PURE__ */ jsx(ChevronDown, { className: "ml-2 h-4 w-4 shrink-0 opacity-50" })]
|
|
1142
|
-
})
|
|
1354
|
+
}), /* @__PURE__ */ jsx(ChevronDown, { className: "ml-2 h-4 w-4 shrink-0 opacity-50" })]
|
|
1355
|
+
});
|
|
1356
|
+
})()
|
|
1143
1357
|
}), /* @__PURE__ */ jsxs(DropdownMenuContent, {
|
|
1144
1358
|
className: "w-[--radix-dropdown-menu-trigger-width] min-w-[240px] p-0",
|
|
1145
1359
|
align: "start",
|
|
@@ -1155,9 +1369,19 @@ function NetworkSelector({ networks, selectedNetwork, onSelectNetwork, getNetwor
|
|
|
1155
1369
|
className: "h-9 w-full border-0 bg-transparent p-0 placeholder:text-muted-foreground focus-visible:ring-0 focus-visible:ring-offset-0",
|
|
1156
1370
|
"aria-label": "Search networks"
|
|
1157
1371
|
})]
|
|
1158
|
-
}), /* @__PURE__ */
|
|
1372
|
+
}), /* @__PURE__ */ jsxs("div", {
|
|
1159
1373
|
className: "max-h-[300px] overflow-y-auto p-1",
|
|
1160
|
-
children:
|
|
1374
|
+
children: [isMultiple && selectedCount > 0 && /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsxs("div", {
|
|
1375
|
+
className: "flex items-center justify-between px-2 py-1.5",
|
|
1376
|
+
children: [/* @__PURE__ */ jsxs("span", {
|
|
1377
|
+
className: "text-xs font-medium text-muted-foreground",
|
|
1378
|
+
children: [selectedCount, " selected"]
|
|
1379
|
+
}), /* @__PURE__ */ jsx("button", {
|
|
1380
|
+
onClick: handleClearAll,
|
|
1381
|
+
className: "text-xs text-muted-foreground hover:text-foreground",
|
|
1382
|
+
children: "Clear all"
|
|
1383
|
+
})]
|
|
1384
|
+
}), /* @__PURE__ */ jsx(DropdownMenuSeparator, {})] }), Object.entries(groupedNetworks).length === 0 ? /* @__PURE__ */ jsx("div", {
|
|
1161
1385
|
className: "py-6 text-center text-sm text-muted-foreground",
|
|
1162
1386
|
children: "No network found."
|
|
1163
1387
|
}) : Object.entries(groupedNetworks).map(([group, groupNetworks], index) => /* @__PURE__ */ jsxs(React$1.Fragment, { children: [
|
|
@@ -1166,12 +1390,16 @@ function NetworkSelector({ networks, selectedNetwork, onSelectNetwork, getNetwor
|
|
|
1166
1390
|
children: group
|
|
1167
1391
|
}),
|
|
1168
1392
|
/* @__PURE__ */ jsx(DropdownMenuGroup, { children: groupNetworks.map((network) => /* @__PURE__ */ jsxs(DropdownMenuItem, {
|
|
1169
|
-
onSelect: () => {
|
|
1170
|
-
|
|
1171
|
-
|
|
1393
|
+
onSelect: (e) => {
|
|
1394
|
+
if (isMultiple) e.preventDefault();
|
|
1395
|
+
handleSelect(network);
|
|
1172
1396
|
},
|
|
1173
1397
|
className: "gap-2",
|
|
1174
1398
|
children: [
|
|
1399
|
+
isMultiple ? /* @__PURE__ */ jsx("div", {
|
|
1400
|
+
className: "flex h-4 w-4 shrink-0 items-center justify-center rounded-sm border border-primary",
|
|
1401
|
+
children: isSelected(network) && /* @__PURE__ */ jsx(Check, { className: "h-3 w-3" })
|
|
1402
|
+
}) : null,
|
|
1175
1403
|
getNetworkIcon?.(network),
|
|
1176
1404
|
/* @__PURE__ */ jsxs("div", {
|
|
1177
1405
|
className: "flex flex-1 items-center gap-2 min-w-0",
|
|
@@ -1183,11 +1411,11 @@ function NetworkSelector({ networks, selectedNetwork, onSelectNetwork, getNetwor
|
|
|
1183
1411
|
children: getNetworkType(network)
|
|
1184
1412
|
})]
|
|
1185
1413
|
}),
|
|
1186
|
-
|
|
1414
|
+
!isMultiple && isSelected(network) && /* @__PURE__ */ jsx(Check, { className: "h-4 w-4 opacity-100" })
|
|
1187
1415
|
]
|
|
1188
1416
|
}, getNetworkId(network))) }),
|
|
1189
1417
|
index < Object.keys(groupedNetworks).length - 1 && /* @__PURE__ */ jsx(DropdownMenuSeparator, {})
|
|
1190
|
-
] }, group))
|
|
1418
|
+
] }, group))]
|
|
1191
1419
|
})]
|
|
1192
1420
|
})]
|
|
1193
1421
|
});
|
|
@@ -1220,6 +1448,32 @@ function NetworkStatusBadge({ network, className }) {
|
|
|
1220
1448
|
});
|
|
1221
1449
|
}
|
|
1222
1450
|
|
|
1451
|
+
//#endregion
|
|
1452
|
+
//#region src/components/ui/overflow-menu.tsx
|
|
1453
|
+
/** Compact "..." dropdown menu for secondary actions. */
|
|
1454
|
+
function OverflowMenu({ items, align = "end", className, "aria-label": ariaLabel = "More actions" }) {
|
|
1455
|
+
if (items.length === 0) return null;
|
|
1456
|
+
return /* @__PURE__ */ jsxs(DropdownMenu, { children: [/* @__PURE__ */ jsx(DropdownMenuTrigger, {
|
|
1457
|
+
asChild: true,
|
|
1458
|
+
children: /* @__PURE__ */ jsx(Button, {
|
|
1459
|
+
variant: "ghost",
|
|
1460
|
+
size: "icon",
|
|
1461
|
+
className: cn("h-8 w-8", className),
|
|
1462
|
+
"aria-label": ariaLabel,
|
|
1463
|
+
children: /* @__PURE__ */ jsx(MoreHorizontal, { className: "h-4 w-4" })
|
|
1464
|
+
})
|
|
1465
|
+
}), /* @__PURE__ */ jsx(DropdownMenuContent, {
|
|
1466
|
+
align,
|
|
1467
|
+
className: "min-w-[140px]",
|
|
1468
|
+
children: items.map((item, index) => /* @__PURE__ */ jsxs(React$1.Fragment, { children: [item.destructive && index > 0 && /* @__PURE__ */ jsx(DropdownMenuSeparator, {}), /* @__PURE__ */ jsxs(DropdownMenuItem, {
|
|
1469
|
+
onClick: item.onSelect,
|
|
1470
|
+
disabled: item.disabled,
|
|
1471
|
+
className: cn(item.destructive && "text-destructive focus:text-destructive"),
|
|
1472
|
+
children: [item.icon, item.label]
|
|
1473
|
+
})] }, item.id))
|
|
1474
|
+
})] });
|
|
1475
|
+
}
|
|
1476
|
+
|
|
1223
1477
|
//#endregion
|
|
1224
1478
|
//#region src/components/ui/progress.tsx
|
|
1225
1479
|
const Progress = React$1.forwardRef(({ className, value, ...props }, ref) => /* @__PURE__ */ jsx(ProgressPrimitive.Root, {
|
|
@@ -1589,6 +1843,15 @@ function ViewContractStateButton({ contractAddress, onToggle }) {
|
|
|
1589
1843
|
});
|
|
1590
1844
|
}
|
|
1591
1845
|
|
|
1846
|
+
//#endregion
|
|
1847
|
+
//#region src/components/fields/address-suggestion/context.ts
|
|
1848
|
+
/**
|
|
1849
|
+
* @internal Shared context instance consumed by both AddressField and
|
|
1850
|
+
* AddressSuggestionProvider. Kept in its own file so component files export
|
|
1851
|
+
* only components (required by React Fast Refresh).
|
|
1852
|
+
*/
|
|
1853
|
+
const AddressSuggestionContext = createContext(null);
|
|
1854
|
+
|
|
1592
1855
|
//#endregion
|
|
1593
1856
|
//#region src/components/fields/utils/accessibility.ts
|
|
1594
1857
|
/**
|
|
@@ -1780,6 +2043,8 @@ function getWidthClasses(width) {
|
|
|
1780
2043
|
|
|
1781
2044
|
//#endregion
|
|
1782
2045
|
//#region src/components/fields/AddressField.tsx
|
|
2046
|
+
const DEBOUNCE_MS = 200;
|
|
2047
|
+
const MAX_SUGGESTIONS = 5;
|
|
1783
2048
|
/**
|
|
1784
2049
|
* Address input field component specifically designed for blockchain addresses via React Hook Form integration.
|
|
1785
2050
|
*
|
|
@@ -1797,11 +2062,82 @@ function getWidthClasses(width) {
|
|
|
1797
2062
|
* - Chain-agnostic design (validation handled by adapters)
|
|
1798
2063
|
* - Full accessibility support with ARIA attributes
|
|
1799
2064
|
* - Keyboard navigation
|
|
2065
|
+
*
|
|
2066
|
+
* Autocomplete suggestions can be provided in two ways:
|
|
2067
|
+
*
|
|
2068
|
+
* 1. **Context-based (zero-config)**: Mount an `AddressSuggestionProvider` in the
|
|
2069
|
+
* component tree. Every `AddressField` below it automatically resolves suggestions.
|
|
2070
|
+
*
|
|
2071
|
+
* 2. **Prop-based (explicit)**: Pass `suggestions` directly. This overrides context.
|
|
2072
|
+
* Pass `suggestions={false}` to opt out when a provider is mounted.
|
|
2073
|
+
*
|
|
2074
|
+
* The suggestion dropdown includes built-in debouncing, keyboard navigation (Arrow keys,
|
|
2075
|
+
* Enter, Escape), click-outside dismissal, and ARIA listbox semantics.
|
|
1800
2076
|
*/
|
|
1801
|
-
function AddressField({ id, label, placeholder, helperText, control, name, width = "full", validation, adapter, readOnly }) {
|
|
2077
|
+
function AddressField({ id, label, placeholder, helperText, control, name, width = "full", validation, adapter, readOnly, suggestions: suggestionsProp, onSuggestionSelect }) {
|
|
1802
2078
|
const isRequired = !!validation?.required;
|
|
1803
2079
|
const errorId = `${id}-error`;
|
|
1804
2080
|
const descriptionId = `${id}-description`;
|
|
2081
|
+
const contextResolver = useContext(AddressSuggestionContext);
|
|
2082
|
+
const containerRef = useRef(null);
|
|
2083
|
+
const lastSetValueRef = useRef("");
|
|
2084
|
+
const [inputValue, setInputValue] = useState("");
|
|
2085
|
+
const [debouncedQuery, setDebouncedQuery] = useState("");
|
|
2086
|
+
const [showSuggestions, setShowSuggestions] = useState(false);
|
|
2087
|
+
const [highlightedIndex, setHighlightedIndex] = useState(-1);
|
|
2088
|
+
const watchedFieldValue = useWatch({
|
|
2089
|
+
control,
|
|
2090
|
+
name
|
|
2091
|
+
});
|
|
2092
|
+
useEffect(() => {
|
|
2093
|
+
const currentFieldValue = watchedFieldValue ?? "";
|
|
2094
|
+
if (currentFieldValue !== lastSetValueRef.current) {
|
|
2095
|
+
lastSetValueRef.current = currentFieldValue;
|
|
2096
|
+
setInputValue(currentFieldValue);
|
|
2097
|
+
}
|
|
2098
|
+
}, [watchedFieldValue]);
|
|
2099
|
+
useEffect(() => {
|
|
2100
|
+
if (!inputValue.trim()) {
|
|
2101
|
+
setDebouncedQuery("");
|
|
2102
|
+
return;
|
|
2103
|
+
}
|
|
2104
|
+
const timer = setTimeout(() => setDebouncedQuery(inputValue), DEBOUNCE_MS);
|
|
2105
|
+
return () => clearTimeout(timer);
|
|
2106
|
+
}, [inputValue]);
|
|
2107
|
+
const suggestionsDisabled = suggestionsProp === false;
|
|
2108
|
+
const resolvedSuggestions = useMemo(() => {
|
|
2109
|
+
if (suggestionsDisabled) return [];
|
|
2110
|
+
if (Array.isArray(suggestionsProp)) return suggestionsProp;
|
|
2111
|
+
if (!contextResolver || !debouncedQuery.trim()) return [];
|
|
2112
|
+
return contextResolver.resolveSuggestions(debouncedQuery).slice(0, MAX_SUGGESTIONS);
|
|
2113
|
+
}, [
|
|
2114
|
+
suggestionsDisabled,
|
|
2115
|
+
suggestionsProp,
|
|
2116
|
+
contextResolver,
|
|
2117
|
+
debouncedQuery
|
|
2118
|
+
]);
|
|
2119
|
+
const hasSuggestions = showSuggestions && resolvedSuggestions.length > 0;
|
|
2120
|
+
useEffect(() => {
|
|
2121
|
+
let active = true;
|
|
2122
|
+
const handleClickOutside = (e) => {
|
|
2123
|
+
if (active && containerRef.current && !containerRef.current.contains(e.target)) setShowSuggestions(false);
|
|
2124
|
+
};
|
|
2125
|
+
document.addEventListener("mousedown", handleClickOutside);
|
|
2126
|
+
return () => {
|
|
2127
|
+
active = false;
|
|
2128
|
+
document.removeEventListener("mousedown", handleClickOutside);
|
|
2129
|
+
};
|
|
2130
|
+
}, []);
|
|
2131
|
+
const handleSuggestionKeyDown = useCallback((e) => {
|
|
2132
|
+
if (!hasSuggestions) return;
|
|
2133
|
+
if (e.key === "ArrowDown") {
|
|
2134
|
+
e.preventDefault();
|
|
2135
|
+
setHighlightedIndex((prev) => prev < resolvedSuggestions.length - 1 ? prev + 1 : 0);
|
|
2136
|
+
} else if (e.key === "ArrowUp") {
|
|
2137
|
+
e.preventDefault();
|
|
2138
|
+
setHighlightedIndex((prev) => prev > 0 ? prev - 1 : resolvedSuggestions.length - 1);
|
|
2139
|
+
}
|
|
2140
|
+
}, [hasSuggestions, resolvedSuggestions.length]);
|
|
1805
2141
|
return /* @__PURE__ */ jsxs("div", {
|
|
1806
2142
|
className: `flex flex-col gap-2 ${width === "full" ? "w-full" : width === "half" ? "w-1/2" : "w-1/3"}`,
|
|
1807
2143
|
children: [label && /* @__PURE__ */ jsxs(Label, {
|
|
@@ -1835,9 +2171,32 @@ function AddressField({ id, label, placeholder, helperText, control, name, width
|
|
|
1835
2171
|
const handleInputChange = (e) => {
|
|
1836
2172
|
const value = e.target.value;
|
|
1837
2173
|
field.onChange(value);
|
|
2174
|
+
lastSetValueRef.current = value;
|
|
2175
|
+
setInputValue(value);
|
|
2176
|
+
setShowSuggestions(value.length > 0);
|
|
2177
|
+
setHighlightedIndex(-1);
|
|
2178
|
+
};
|
|
2179
|
+
const applySuggestion = (suggestion) => {
|
|
2180
|
+
field.onChange(suggestion.value);
|
|
2181
|
+
onSuggestionSelect?.(suggestion);
|
|
2182
|
+
lastSetValueRef.current = suggestion.value;
|
|
2183
|
+
setInputValue(suggestion.value);
|
|
2184
|
+
setShowSuggestions(false);
|
|
2185
|
+
setHighlightedIndex(-1);
|
|
1838
2186
|
};
|
|
1839
2187
|
const handleKeyDown = (e) => {
|
|
1840
|
-
if (e.key === "
|
|
2188
|
+
if (hasSuggestions && e.key === "Enter" && highlightedIndex >= 0) {
|
|
2189
|
+
e.preventDefault();
|
|
2190
|
+
applySuggestion(resolvedSuggestions[highlightedIndex]);
|
|
2191
|
+
return;
|
|
2192
|
+
}
|
|
2193
|
+
if (e.key === "Escape") {
|
|
2194
|
+
if (hasSuggestions) {
|
|
2195
|
+
setShowSuggestions(false);
|
|
2196
|
+
return;
|
|
2197
|
+
}
|
|
2198
|
+
handleEscapeKey(field.onChange, field.value)(e);
|
|
2199
|
+
}
|
|
1841
2200
|
};
|
|
1842
2201
|
const accessibilityProps = getAccessibilityProps({
|
|
1843
2202
|
id,
|
|
@@ -1846,18 +2205,50 @@ function AddressField({ id, label, placeholder, helperText, control, name, width
|
|
|
1846
2205
|
hasHelperText: !!helperText
|
|
1847
2206
|
});
|
|
1848
2207
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1849
|
-
/* @__PURE__ */
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
|
|
2208
|
+
/* @__PURE__ */ jsxs("div", {
|
|
2209
|
+
ref: containerRef,
|
|
2210
|
+
className: "relative",
|
|
2211
|
+
onKeyDown: handleSuggestionKeyDown,
|
|
2212
|
+
children: [/* @__PURE__ */ jsx(Input, {
|
|
2213
|
+
...field,
|
|
2214
|
+
id,
|
|
2215
|
+
placeholder: placeholder || "0x...",
|
|
2216
|
+
className: validationClasses,
|
|
2217
|
+
onChange: handleInputChange,
|
|
2218
|
+
onKeyDown: handleKeyDown,
|
|
2219
|
+
"data-slot": "input",
|
|
2220
|
+
value: field.value ?? "",
|
|
2221
|
+
...accessibilityProps,
|
|
2222
|
+
"aria-describedby": `${helperText ? descriptionId : ""} ${hasError ? errorId : ""}`,
|
|
2223
|
+
"aria-expanded": hasSuggestions,
|
|
2224
|
+
"aria-autocomplete": suggestionsDisabled ? void 0 : "list",
|
|
2225
|
+
"aria-controls": hasSuggestions ? `${id}-suggestions` : void 0,
|
|
2226
|
+
"aria-activedescendant": hasSuggestions && highlightedIndex >= 0 ? `${id}-suggestion-${highlightedIndex}` : void 0,
|
|
2227
|
+
disabled: readOnly
|
|
2228
|
+
}), hasSuggestions && /* @__PURE__ */ jsx("div", {
|
|
2229
|
+
id: `${id}-suggestions`,
|
|
2230
|
+
className: cn("absolute z-50 mt-1 w-full rounded-md border border-border bg-popover shadow-md", "max-h-48 overflow-auto"),
|
|
2231
|
+
role: "listbox",
|
|
2232
|
+
children: resolvedSuggestions.map((s, i) => /* @__PURE__ */ jsxs("button", {
|
|
2233
|
+
id: `${id}-suggestion-${i}`,
|
|
2234
|
+
type: "button",
|
|
2235
|
+
role: "option",
|
|
2236
|
+
"aria-selected": i === highlightedIndex,
|
|
2237
|
+
className: cn("flex w-full flex-col px-3 py-2 text-left text-sm", "hover:bg-accent", i === highlightedIndex && "bg-accent"),
|
|
2238
|
+
onMouseDown: (e) => {
|
|
2239
|
+
e.preventDefault();
|
|
2240
|
+
applySuggestion(s);
|
|
2241
|
+
},
|
|
2242
|
+
onMouseEnter: () => setHighlightedIndex(i),
|
|
2243
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
2244
|
+
className: "font-medium",
|
|
2245
|
+
children: s.label
|
|
2246
|
+
}), /* @__PURE__ */ jsx("span", {
|
|
2247
|
+
className: "truncate font-mono text-xs text-muted-foreground",
|
|
2248
|
+
children: s.value
|
|
2249
|
+
})]
|
|
2250
|
+
}, `${s.value}-${s.description ?? i}`))
|
|
2251
|
+
})]
|
|
1861
2252
|
}),
|
|
1862
2253
|
helperText && /* @__PURE__ */ jsx("div", {
|
|
1863
2254
|
id: descriptionId,
|
|
@@ -1876,6 +2267,90 @@ function AddressField({ id, label, placeholder, helperText, control, name, width
|
|
|
1876
2267
|
}
|
|
1877
2268
|
AddressField.displayName = "AddressField";
|
|
1878
2269
|
|
|
2270
|
+
//#endregion
|
|
2271
|
+
//#region src/components/fields/address-suggestion/address-suggestion-context.tsx
|
|
2272
|
+
/**
|
|
2273
|
+
* Address Suggestion Context
|
|
2274
|
+
*
|
|
2275
|
+
* Provides a React context for resolving address autocomplete suggestions.
|
|
2276
|
+
* When an `AddressSuggestionProvider` is mounted, every `AddressField`
|
|
2277
|
+
* in the subtree automatically renders a suggestion dropdown as the user types.
|
|
2278
|
+
*
|
|
2279
|
+
* @example
|
|
2280
|
+
* ```tsx
|
|
2281
|
+
* import { AddressSuggestionProvider } from '@openzeppelin/ui-components';
|
|
2282
|
+
* import { useAliasSuggestionResolver } from '@openzeppelin/ui-storage';
|
|
2283
|
+
*
|
|
2284
|
+
* function App() {
|
|
2285
|
+
* const resolver = useAliasSuggestionResolver(db);
|
|
2286
|
+
* return (
|
|
2287
|
+
* <AddressSuggestionProvider {...resolver}>
|
|
2288
|
+
* <MyApp />
|
|
2289
|
+
* </AddressSuggestionProvider>
|
|
2290
|
+
* );
|
|
2291
|
+
* }
|
|
2292
|
+
* ```
|
|
2293
|
+
*/
|
|
2294
|
+
/**
|
|
2295
|
+
* Provides address suggestion resolution to all `AddressField` instances in the
|
|
2296
|
+
* subtree. Wrap your application (or a subsection) with this provider and
|
|
2297
|
+
* supply a `resolveSuggestions` function.
|
|
2298
|
+
*
|
|
2299
|
+
* @param props - Resolver function and children
|
|
2300
|
+
*
|
|
2301
|
+
* @example
|
|
2302
|
+
* ```tsx
|
|
2303
|
+
* <AddressSuggestionProvider
|
|
2304
|
+
* resolveSuggestions={(query, networkId) => filterAliases(query, networkId)}
|
|
2305
|
+
* >
|
|
2306
|
+
* <App />
|
|
2307
|
+
* </AddressSuggestionProvider>
|
|
2308
|
+
* ```
|
|
2309
|
+
*/
|
|
2310
|
+
function AddressSuggestionProvider({ children, resolveSuggestions }) {
|
|
2311
|
+
const value = React$1.useMemo(() => ({ resolveSuggestions }), [resolveSuggestions]);
|
|
2312
|
+
return /* @__PURE__ */ jsx(AddressSuggestionContext.Provider, {
|
|
2313
|
+
value,
|
|
2314
|
+
children
|
|
2315
|
+
});
|
|
2316
|
+
}
|
|
2317
|
+
|
|
2318
|
+
//#endregion
|
|
2319
|
+
//#region src/components/fields/address-suggestion/useAddressSuggestions.ts
|
|
2320
|
+
/**
|
|
2321
|
+
* Convenience hook that resolves suggestions for a query string using the
|
|
2322
|
+
* nearest `AddressSuggestionProvider`. Returns an empty array when no provider
|
|
2323
|
+
* is mounted or when the query is empty.
|
|
2324
|
+
*
|
|
2325
|
+
* @param query - Current input value to match against
|
|
2326
|
+
* @param networkId - Optional network identifier for scoping results
|
|
2327
|
+
* @returns Object containing the resolved suggestions array
|
|
2328
|
+
*
|
|
2329
|
+
* @example
|
|
2330
|
+
* ```tsx
|
|
2331
|
+
* function MyField({ query }: { query: string }) {
|
|
2332
|
+
* const { suggestions } = useAddressSuggestions(query, 'ethereum-mainnet');
|
|
2333
|
+
* return (
|
|
2334
|
+
* <ul>
|
|
2335
|
+
* {suggestions.map(s => <li key={s.value}>{s.label}</li>)}
|
|
2336
|
+
* </ul>
|
|
2337
|
+
* );
|
|
2338
|
+
* }
|
|
2339
|
+
* ```
|
|
2340
|
+
*/
|
|
2341
|
+
/** Resolves address suggestions from the nearest `AddressSuggestionProvider`. */
|
|
2342
|
+
function useAddressSuggestions(query, networkId) {
|
|
2343
|
+
const resolver = React$1.useContext(AddressSuggestionContext);
|
|
2344
|
+
return { suggestions: React$1.useMemo(() => {
|
|
2345
|
+
if (!resolver || !query.trim()) return [];
|
|
2346
|
+
return resolver.resolveSuggestions(query, networkId);
|
|
2347
|
+
}, [
|
|
2348
|
+
resolver,
|
|
2349
|
+
query,
|
|
2350
|
+
networkId
|
|
2351
|
+
]) };
|
|
2352
|
+
}
|
|
2353
|
+
|
|
1879
2354
|
//#endregion
|
|
1880
2355
|
//#region src/components/fields/AmountField.tsx
|
|
1881
2356
|
/**
|
|
@@ -5245,5 +5720,5 @@ const Toaster = ({ ...props }) => {
|
|
|
5245
5720
|
};
|
|
5246
5721
|
|
|
5247
5722
|
//#endregion
|
|
5248
|
-
export { Accordion, AccordionContent, AccordionItem, AccordionTrigger, AddressDisplay, AddressField, 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, 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, buttonVariants, computeChildTouched, createFocusManager, createValidationResult, formatValidationError, getAccessibilityProps, getDescribedById, getErrorMessage, getValidationStateClasses, getWidthClasses, handleEscapeKey, handleKeyboardEvent, handleNumericKeys, handleToggleKeys, handleValidationError, hasFieldError, isDuplicateMapKey, useDuplicateKeyIndexes, useMapFieldSync, useNetworkErrorAwareAdapter, useNetworkErrorReporter, useNetworkErrors, validateField, validateMapEntries, validateMapStructure };
|
|
5723
|
+
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, 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 };
|
|
5249
5724
|
//# sourceMappingURL=index.mjs.map
|