@openzeppelin/ui-components 1.0.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/LICENSE +661 -0
- package/README.md +148 -0
- package/dist/index-CYn57Ffl.d.ts +2528 -0
- package/dist/index-CYn57Ffl.d.ts.map +1 -0
- package/dist/index-CrEkH28U.d.cts +2528 -0
- package/dist/index-CrEkH28U.d.cts.map +1 -0
- package/dist/index.cjs +5534 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +2528 -0
- package/dist/index.d.ts +2528 -0
- package/dist/index.js +5348 -0
- package/dist/index.js.map +1 -0
- package/package.json +99 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":["React","React","ExternalLink","React","React","React","React","CalendarIcon","React","React","React","React","React","React","React","React","React","React","React","React","validation","selectedVariant","FileIcon","validation","validation","validation","validation","Sonner"],"sources":["../src/components/ui/accordion.tsx","../src/components/ui/address-display.tsx","../src/components/ui/alert.tsx","../src/components/ui/banner.tsx","../src/utils/button-variants.ts","../src/components/ui/button.tsx","../src/components/ui/calendar.tsx","../src/components/ui/card.tsx","../src/components/ui/checkbox.tsx","../src/components/ui/popover.tsx","../src/components/ui/date-range-picker.tsx","../src/components/ui/dialog.tsx","../src/components/ui/dropdown-menu.tsx","../src/components/ui/empty-state.tsx","../src/components/ui/external-link.tsx","../src/components/ui/footer.tsx","../src/components/ui/label.tsx","../src/components/ui/form.tsx","../src/components/ui/header.tsx","../src/components/ui/input.tsx","../src/components/ui/loading-button.tsx","../src/components/icons/MidnightIcon.tsx","../src/components/ui/network-icon.tsx","../src/components/ui/network-selector.tsx","../src/components/ui/network-status-badge.tsx","../src/components/ui/progress.tsx","../src/components/ui/radio-group.tsx","../src/components/ui/select.tsx","../src/components/ui/sidebar/SidebarButton.tsx","../src/components/ui/sidebar/SidebarLayout.tsx","../src/components/ui/sidebar/SidebarSection.tsx","../src/components/ui/tabs.tsx","../src/components/ui/textarea.tsx","../src/components/ui/tooltip.tsx","../src/components/ui/view-contract-state-button.tsx","../src/components/fields/utils/accessibility.ts","../src/components/fields/utils/integerValidation.ts","../src/components/fields/utils/validation.ts","../src/components/fields/utils/ErrorMessage.tsx","../src/components/fields/utils/layout.ts","../src/components/fields/AddressField.tsx","../src/components/fields/AmountField.tsx","../src/components/fields/ArrayField.tsx","../src/components/fields/ArrayObjectField.tsx","../src/components/fields/BaseField.tsx","../src/components/fields/BigIntField.tsx","../src/components/fields/BooleanField.tsx","../src/components/fields/BytesField.tsx","../src/components/fields/CodeEditorField.tsx","../src/components/fields/DateTimeField.tsx","../src/components/fields/EnumField.tsx","../src/components/fields/FileUploadField.tsx","../src/components/fields/MapField/MapField.tsx","../src/components/fields/MapField/MapEntryRow.tsx","../src/components/fields/MapField/hooks/useChildTouched.ts","../src/components/fields/MapField/hooks/useDuplicateKeyIndexes.ts","../src/components/fields/MapField/hooks/useMapFieldSync.ts","../src/components/fields/MapField/validation/validateMapStructure.ts","../src/components/fields/NumberField.tsx","../src/components/fields/ObjectField.tsx","../src/components/fields/PasswordField.tsx","../src/components/fields/RadioField.tsx","../src/components/fields/SelectField.tsx","../src/components/fields/SelectGroupedField.tsx","../src/components/fields/TextAreaField.tsx","../src/components/fields/TextField.tsx","../src/components/fields/UrlField.tsx","../src/components/RelayerDetailsCard/RelayerDetailsCard.tsx","../src/components/network-errors/NetworkErrorContext.ts","../src/components/network-errors/NetworkErrorNotificationProvider.tsx","../src/components/network-errors/useNetworkErrors.ts","../src/components/network-errors/NetworkErrorAwareAdapter.tsx","../src/components/ui/sonner.tsx"],"sourcesContent":["import * as AccordionPrimitive from '@radix-ui/react-accordion';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { ChevronDown } from 'lucide-react';\nimport * as React from 'react';\n\nimport { cn } from '@openzeppelin/ui-utils';\n\nconst accordionItemVariants = cva('', {\n variants: {\n variant: {\n default: 'border-b',\n card: 'mb-3 rounded-lg border bg-card shadow-sm overflow-hidden',\n },\n },\n defaultVariants: {\n variant: 'default',\n },\n});\n\nconst accordionTriggerVariants = cva(\n 'flex flex-1 items-center justify-between font-medium transition-all [&[data-state=open]>svg]:rotate-180',\n {\n variants: {\n variant: {\n default: 'py-4 hover:underline',\n card: 'px-4 py-3 hover:bg-muted/50',\n },\n },\n defaultVariants: {\n variant: 'default',\n },\n }\n);\n\nconst accordionContentVariants = cva(\n 'overflow-hidden text-sm transition-all duration-300 ease-in-out will-change-[height,opacity] data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down',\n {\n variants: {\n variant: {\n default: '',\n card: '',\n },\n },\n defaultVariants: {\n variant: 'default',\n },\n }\n);\n\nconst accordionContentInnerVariants = cva('', {\n variants: {\n variant: {\n default: 'pb-4 pt-0',\n card: 'px-4 pb-4 pt-1',\n },\n },\n defaultVariants: {\n variant: 'default',\n },\n});\n\n// Create a context for the variant\ntype AccordionVariant = 'default' | 'card';\nconst AccordionVariantContext = React.createContext<AccordionVariant>('default');\n\n// Extend the Accordion component to accept and provide variant\ntype AccordionProps = (\n | AccordionPrimitive.AccordionSingleProps\n | AccordionPrimitive.AccordionMultipleProps\n) & {\n variant?: AccordionVariant;\n};\n\nconst Accordion = React.forwardRef<HTMLDivElement, AccordionProps>(\n ({ variant = 'default', ...props }, ref) => (\n <AccordionVariantContext.Provider value={variant}>\n <AccordionPrimitive.Root ref={ref} {...props} />\n </AccordionVariantContext.Provider>\n )\n);\nAccordion.displayName = 'Accordion';\n\ninterface AccordionItemProps\n extends React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Item>,\n VariantProps<typeof accordionItemVariants> {}\n\nconst AccordionItem = React.forwardRef<HTMLDivElement, AccordionItemProps>(\n ({ className, variant: variantProp, ...props }, ref) => {\n const contextVariant = React.useContext(AccordionVariantContext);\n const variant = variantProp ?? contextVariant;\n\n return (\n <AccordionPrimitive.Item\n ref={ref}\n className={cn(accordionItemVariants({ variant }), className)}\n {...props}\n />\n );\n }\n);\nAccordionItem.displayName = 'AccordionItem';\n\ninterface AccordionTriggerProps\n extends React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Trigger>,\n VariantProps<typeof accordionTriggerVariants> {}\n\nconst AccordionTrigger = React.forwardRef<HTMLButtonElement, AccordionTriggerProps>(\n ({ className, children, variant: variantProp, ...props }, ref) => {\n const contextVariant = React.useContext(AccordionVariantContext);\n const variant = variantProp ?? contextVariant;\n\n return (\n <AccordionPrimitive.Header className=\"flex\">\n <AccordionPrimitive.Trigger\n ref={ref}\n className={cn(accordionTriggerVariants({ variant }), className)}\n {...props}\n >\n {children}\n <ChevronDown className=\"h-4 w-4 shrink-0 transition-transform duration-200\" />\n </AccordionPrimitive.Trigger>\n </AccordionPrimitive.Header>\n );\n }\n);\nAccordionTrigger.displayName = 'AccordionTrigger';\n\ninterface AccordionContentProps\n extends React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Content>,\n VariantProps<typeof accordionContentVariants> {}\n\nconst AccordionContent = React.forwardRef<HTMLDivElement, AccordionContentProps>(\n ({ className, children, variant: variantProp, ...props }, ref) => {\n const contextVariant = React.useContext(AccordionVariantContext);\n const variant = variantProp ?? contextVariant;\n\n return (\n <AccordionPrimitive.Content\n ref={ref}\n className={cn(accordionContentVariants({ variant }), className)}\n {...props}\n >\n <div className={cn(accordionContentInnerVariants({ variant }))}>{children}</div>\n </AccordionPrimitive.Content>\n );\n }\n);\nAccordionContent.displayName = 'AccordionContent';\n\nexport { Accordion, AccordionItem, AccordionTrigger, AccordionContent };\nexport type { AccordionProps, AccordionItemProps, AccordionTriggerProps, AccordionContentProps };\n","import { Check, Copy, ExternalLink } from 'lucide-react';\nimport * as React from 'react';\n\nimport { cn, truncateMiddle } from '@openzeppelin/ui-utils';\n\ninterface AddressDisplayProps extends React.HTMLAttributes<HTMLDivElement> {\n /**\n * The blockchain address to display\n */\n address: string;\n\n /**\n * Whether to truncate the address in the middle\n * @default true\n */\n truncate?: boolean;\n\n /**\n * Number of characters to show at the beginning when truncating\n * @default 6\n */\n startChars?: number;\n\n /**\n * Number of characters to show at the end when truncating\n * @default 4\n */\n endChars?: number;\n\n /**\n * Whether to show a copy button\n * @default false\n */\n showCopyButton?: boolean;\n\n /**\n * Whether to show the copy button only on hover\n * @default false\n */\n showCopyButtonOnHover?: boolean;\n\n /**\n * Optional explorer URL to make the address clickable\n */\n explorerUrl?: string;\n\n /**\n * Additional CSS classes\n */\n className?: string;\n}\n\n/** Displays a blockchain address with optional truncation, copy button, and explorer link. */\nexport function AddressDisplay({\n address,\n truncate = true,\n startChars = 6,\n endChars = 4,\n showCopyButton = false,\n showCopyButtonOnHover = false,\n explorerUrl,\n className,\n ...props\n}: AddressDisplayProps): React.ReactElement {\n const [copied, setCopied] = React.useState(false);\n const copyTimeoutRef = React.useRef<number | null>(null);\n\n const displayAddress = truncate ? truncateMiddle(address, startChars, endChars) : address;\n\n const handleCopy = (e: React.MouseEvent): void => {\n e.stopPropagation();\n navigator.clipboard.writeText(address);\n setCopied(true);\n\n if (copyTimeoutRef.current) {\n window.clearTimeout(copyTimeoutRef.current);\n }\n copyTimeoutRef.current = window.setTimeout(() => {\n setCopied(false);\n copyTimeoutRef.current = null;\n }, 2000);\n };\n\n React.useEffect(() => {\n return (): void => {\n if (copyTimeoutRef.current) {\n window.clearTimeout(copyTimeoutRef.current);\n }\n };\n }, []);\n\n const addressContent = (\n <>\n <span className={cn('truncate', truncate ? '' : 'break-all')}>{displayAddress}</span>\n\n {showCopyButton && (\n <button\n type=\"button\"\n onClick={handleCopy}\n className={cn(\n 'shrink-0 text-slate-500',\n !copied && 'hover:text-slate-700',\n showCopyButtonOnHover\n ? // Do not reserve space until hover/focus: width and margin grow on interaction\n 'ml-0 w-0 overflow-hidden opacity-0 transition-all duration-150 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'\n : // Default: always visible with standard spacing\n 'ml-1.5 transition-colors'\n )}\n aria-label={copied ? 'Copied' : 'Copy address'}\n >\n {copied ? (\n <Check className=\"h-3.5 w-3.5 text-emerald-600\" />\n ) : (\n <Copy className=\"h-3.5 w-3.5\" />\n )}\n </button>\n )}\n\n {explorerUrl && (\n <a\n href={explorerUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"ml-1.5 shrink-0 text-slate-500 transition-colors hover:text-slate-700\"\n aria-label=\"View in explorer\"\n >\n <ExternalLink className=\"h-3.5 w-3.5\" />\n </a>\n )}\n </>\n );\n\n return (\n <div\n className={cn(\n 'group inline-flex max-w-full items-center rounded-md bg-slate-100 px-2 py-1',\n 'text-xs font-mono text-slate-700',\n className\n )}\n {...props}\n >\n {addressContent}\n </div>\n );\n}\n","import { cva, type VariantProps } from 'class-variance-authority';\nimport * as React from 'react';\n\nimport { cn } from '@openzeppelin/ui-utils';\n\nconst alertVariants = cva(\n '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',\n {\n variants: {\n variant: {\n default: 'bg-background text-foreground',\n destructive:\n 'border-destructive/50 text-destructive dark:border-destructive [&>svg]:text-destructive',\n success: 'border-green-500/50 text-green-700 dark:border-green-500 [&>svg]:text-green-700',\n },\n },\n defaultVariants: {\n variant: 'default',\n },\n }\n);\n\nconst Alert = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement> & VariantProps<typeof alertVariants>\n>(({ className, variant, ...props }, ref) => (\n <div ref={ref} role=\"alert\" className={cn(alertVariants({ variant }), className)} {...props} />\n));\nAlert.displayName = 'Alert';\n\nconst AlertTitle = React.forwardRef<HTMLParagraphElement, React.HTMLAttributes<HTMLHeadingElement>>(\n ({ className, ...props }, ref) => (\n <h5\n ref={ref}\n className={cn('mb-1 font-medium leading-none tracking-tight', className)}\n {...props}\n />\n )\n);\nAlertTitle.displayName = 'AlertTitle';\n\nconst AlertDescription = React.forwardRef<\n HTMLParagraphElement,\n React.HTMLAttributes<HTMLParagraphElement>\n>(({ className, ...props }, ref) => (\n <div ref={ref} className={cn('text-sm [&_p]:leading-relaxed', className)} {...props} />\n));\nAlertDescription.displayName = 'AlertDescription';\n\nexport { Alert, AlertTitle, AlertDescription };\n","import { X } from 'lucide-react';\nimport * as React from 'react';\n\nimport { cn } from '@openzeppelin/ui-utils';\n\ninterface BannerProps {\n /**\n * The variant/style of the banner\n * @default 'info'\n */\n variant?: 'info' | 'success' | 'warning' | 'error';\n\n /**\n * Title text displayed at the top of the banner\n */\n title?: React.ReactNode;\n\n /**\n * Body text/content of the banner\n */\n children: React.ReactNode;\n\n /**\n * Whether the banner can be dismissed\n * @default true\n */\n dismissible?: boolean;\n\n /**\n * Callback when the banner is dismissed\n */\n onDismiss?: () => void;\n\n /**\n * Icon to display on the left (replaces default based on variant)\n */\n icon?: React.ReactNode;\n\n /**\n * Additional CSS classes\n */\n className?: string;\n}\n\nconst variantStyles: Record<\n string,\n { container: string; icon: string; title: string; body: string }\n> = {\n info: {\n container: 'border-blue-200 bg-blue-50',\n icon: 'text-blue-600',\n title: 'text-blue-900',\n body: 'text-blue-800',\n },\n success: {\n container: 'border-green-200 bg-green-50',\n icon: 'text-green-600',\n title: 'text-green-900',\n body: 'text-green-800',\n },\n warning: {\n container: 'border-amber-200 bg-amber-50',\n icon: 'text-amber-600',\n title: 'text-amber-900',\n body: 'text-amber-800',\n },\n error: {\n container: 'border-red-200 bg-red-50',\n icon: 'text-red-600',\n title: 'text-red-900',\n body: 'text-red-800',\n },\n};\n\n/**\n * Dismissible banner component for notifications and alerts\n * Can be used with various variants (info, success, warning, error)\n */\nexport const Banner = React.forwardRef<HTMLDivElement, BannerProps>(\n ({ className, variant = 'info', title, children, dismissible = true, onDismiss, icon }, ref) => {\n const styles = variantStyles[variant] || variantStyles.info;\n\n return (\n <div\n ref={ref}\n role=\"alert\"\n className={cn('rounded-md border p-4', styles.container, className)}\n >\n <div className=\"flex gap-3\">\n {icon && <div className={cn('mt-0.5 shrink-0', styles.icon)}>{icon}</div>}\n <div className=\"flex-1\">\n {title && <h4 className={cn('mb-2 font-semibold text-sm', styles.title)}>{title}</h4>}\n <div className={cn('text-sm whitespace-pre-line', styles.body)}>{children}</div>\n </div>\n {dismissible && (\n <button\n type=\"button\"\n onClick={onDismiss}\n className={cn('self-start shrink-0 transition-colors hover:opacity-70', styles.icon)}\n aria-label=\"Dismiss banner\"\n >\n <X className=\"h-5 w-5\" />\n </button>\n )}\n </div>\n </div>\n );\n }\n);\nBanner.displayName = 'Banner';\n","import { cva } from 'class-variance-authority';\n\nexport const buttonVariants = cva(\n 'ring-offset-background focus-visible:ring-ring inline-flex items-center justify-center rounded-md text-sm font-medium transition-colors focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:outline-none disabled:pointer-events-none disabled:opacity-50',\n {\n variants: {\n variant: {\n default: 'bg-primary text-primary-foreground hover:bg-primary/90',\n destructive: 'bg-destructive text-destructive-foreground hover:bg-destructive/90',\n outline:\n 'border-input bg-background text-foreground hover:bg-accent hover:text-accent-foreground border',\n secondary: 'bg-secondary text-secondary-foreground hover:bg-secondary/80',\n ghost: 'text-foreground hover:bg-accent hover:text-accent-foreground',\n link: 'text-primary underline-offset-4 hover:underline',\n },\n size: {\n default: 'h-10 px-4 py-2',\n sm: 'h-9 rounded-md px-3',\n lg: 'h-11 rounded-md px-8',\n icon: 'size-10',\n },\n },\n defaultVariants: {\n variant: 'default',\n size: 'default',\n },\n }\n);\n","import { Slot } from '@radix-ui/react-slot';\nimport { type VariantProps } from 'class-variance-authority';\nimport * as React from 'react';\n\nimport { cn } from '@openzeppelin/ui-utils';\n\nimport { buttonVariants } from '../../utils/button-variants';\n\nexport interface ButtonProps\n extends React.ButtonHTMLAttributes<HTMLButtonElement>,\n VariantProps<typeof buttonVariants> {\n asChild?: boolean;\n}\n\nconst Button = React.forwardRef<HTMLButtonElement, ButtonProps>(\n ({ className, variant, size, asChild = false, ...props }, ref) => {\n const Comp = asChild ? Slot : 'button';\n return (\n <Comp\n data-slot=\"button\"\n data-variant={variant || 'default'}\n data-size={size || 'default'}\n className={cn(buttonVariants({ variant, size, className }), 'cursor-pointer')}\n ref={ref}\n {...props}\n />\n );\n }\n);\nButton.displayName = 'Button';\n\nexport { Button };\n","'use client';\n\nimport { ChevronLeft, ChevronRight } from 'lucide-react';\nimport * as React from 'react';\nimport { DayPicker } from 'react-day-picker';\n\nimport { cn } from '@openzeppelin/ui-utils';\n\nimport { buttonVariants } from '../../utils/button-variants';\n\nexport type CalendarProps = React.ComponentProps<typeof DayPicker>;\n\n/**\n * Calendar component built on react-day-picker with shadcn/ui styling.\n * Supports single date, multiple dates, and date range selection modes.\n */\nfunction Calendar({\n className,\n classNames,\n showOutsideDays = true,\n ...props\n}: CalendarProps): React.ReactElement {\n return (\n <DayPicker\n showOutsideDays={showOutsideDays}\n className={cn('p-3', className)}\n classNames={{\n months: 'flex flex-col sm:flex-row gap-2 px-5',\n month: 'flex flex-col gap-4',\n month_caption: 'flex justify-center pt-1 relative items-center w-full',\n caption_label: 'text-sm font-medium',\n nav: 'flex items-center gap-1',\n button_previous: cn(\n buttonVariants({ variant: 'outline' }),\n 'absolute left-1 h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100'\n ),\n button_next: cn(\n buttonVariants({ variant: 'outline' }),\n 'absolute right-1 h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100'\n ),\n month_grid: 'w-full border-collapse space-y-1',\n weekdays: 'flex',\n weekday: 'text-muted-foreground rounded-md w-9 font-normal text-[0.8rem]',\n week: 'flex w-full mt-2',\n day: cn(\n 'relative p-0 text-center text-sm focus-within:relative focus-within:z-20 [&:has([aria-selected])]:bg-accent [&:has([aria-selected].day-outside)]:bg-accent/50 [&:has([aria-selected].day-range-end)]:rounded-r-md',\n props.mode === 'range'\n ? '[&:has(>.day-range-end)]:rounded-r-md [&:has(>.day-range-start)]:rounded-l-md first:[&:has([aria-selected])]:rounded-l-md last:[&:has([aria-selected])]:rounded-r-md'\n : '[&:has([aria-selected])]:rounded-md'\n ),\n day_button: cn(\n buttonVariants({ variant: 'ghost' }),\n 'h-9 w-9 p-0 font-normal aria-selected:opacity-100 rounded-none hover:rounded-none'\n ),\n range_start: 'day-range-start rounded-l-md',\n range_end: 'day-range-end rounded-r-md',\n selected:\n 'bg-zinc-200 dark:bg-zinc-700 text-foreground hover:bg-zinc-200 dark:hover:bg-zinc-700 hover:text-foreground focus:bg-zinc-200 dark:focus:bg-zinc-700 focus:text-foreground',\n today: 'bg-accent text-accent-foreground',\n outside:\n 'day-outside text-muted-foreground opacity-50 aria-selected:bg-accent/50 aria-selected:text-muted-foreground aria-selected:opacity-30',\n disabled: 'text-muted-foreground opacity-50',\n range_middle: 'aria-selected:bg-accent aria-selected:text-accent-foreground',\n hidden: 'invisible',\n ...classNames,\n }}\n components={{\n Chevron: ({ orientation }) => {\n const Icon = orientation === 'left' ? ChevronLeft : ChevronRight;\n return <Icon className=\"h-4 w-4\" />;\n },\n }}\n {...props}\n />\n );\n}\nCalendar.displayName = 'Calendar';\n\nexport { Calendar };\n","import { JSX } from 'react';\n\nimport { cn } from '@openzeppelin/ui-utils';\n\n/** Card container component with rounded borders and shadow. */\nfunction Card({ className, ...props }: React.ComponentProps<'div'>): JSX.Element {\n return (\n <div\n data-slot=\"card\"\n className={cn(\n 'bg-card text-card-foreground flex flex-col rounded-xl border py-6 shadow-sm',\n className\n )}\n {...props}\n />\n );\n}\n\n/** Card header section for title and description. */\nfunction CardHeader({ className, ...props }: React.ComponentProps<'div'>): JSX.Element {\n return (\n <div\n data-slot=\"card-header\"\n className={cn('flex flex-col gap-1.5 px-6', className)}\n {...props}\n />\n );\n}\n\n/** Card title with semibold styling. */\nfunction CardTitle({ className, ...props }: React.ComponentProps<'div'>): JSX.Element {\n return (\n <div\n data-slot=\"card-title\"\n className={cn('leading-none font-semibold', className)}\n {...props}\n />\n );\n}\n\n/** Card description with muted text styling. */\nfunction CardDescription({ className, ...props }: React.ComponentProps<'div'>): JSX.Element {\n return (\n <div\n data-slot=\"card-description\"\n className={cn('text-muted-foreground text-sm', className)}\n {...props}\n />\n );\n}\n\n/** Card content area with horizontal padding. */\nfunction CardContent({ className, ...props }: React.ComponentProps<'div'>): JSX.Element {\n return <div data-slot=\"card-content\" className={cn('px-6', className)} {...props} />;\n}\n\n/** Card footer with flex alignment for actions. */\nfunction CardFooter({ className, ...props }: React.ComponentProps<'div'>): JSX.Element {\n return (\n <div data-slot=\"card-footer\" className={cn('flex items-center px-6', className)} {...props} />\n );\n}\n\nexport { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle };\n","import * as CheckboxPrimitive from '@radix-ui/react-checkbox';\nimport { CheckIcon } from 'lucide-react';\nimport * as React from 'react';\n\nimport { cn } from '@openzeppelin/ui-utils';\n\n/** Checkbox component wrapping Radix UI Checkbox primitive. */\nfunction Checkbox({\n className,\n ...props\n}: React.ComponentProps<typeof CheckboxPrimitive.Root>): React.ReactElement {\n return (\n <CheckboxPrimitive.Root\n data-slot=\"checkbox\"\n className={cn(\n 'border-input data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground data-[state=checked]:border-primary focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive size-4 shrink-0 rounded-[4px] border shadow-xs transition-shadow outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50',\n className\n )}\n {...props}\n >\n <CheckboxPrimitive.Indicator\n data-slot=\"checkbox-indicator\"\n className=\"flex items-center justify-center text-current transition-none\"\n >\n <CheckIcon data-slot=\"checkbox-indicator-icon\" className=\"size-3.5\" />\n </CheckboxPrimitive.Indicator>\n </CheckboxPrimitive.Root>\n );\n}\n\nexport { Checkbox };\n","'use client';\n\nimport * as PopoverPrimitive from '@radix-ui/react-popover';\nimport * as React from 'react';\n\nimport { cn } from '@openzeppelin/ui-utils';\n\nconst Popover = PopoverPrimitive.Root;\n\nconst PopoverTrigger = PopoverPrimitive.Trigger;\n\nconst PopoverAnchor = PopoverPrimitive.Anchor;\n\nconst PopoverContent = React.forwardRef<\n React.ElementRef<typeof PopoverPrimitive.Content>,\n React.ComponentPropsWithoutRef<typeof PopoverPrimitive.Content>\n>(({ className, align = 'center', sideOffset = 4, ...props }, ref) => (\n <PopoverPrimitive.Portal>\n <PopoverPrimitive.Content\n ref={ref}\n align={align}\n sideOffset={sideOffset}\n className={cn(\n 'z-50 w-72 rounded-md border border-border bg-popover p-4 text-popover-foreground shadow-md outline-none',\n 'data-[state=open]:animate-in data-[state=closed]:animate-out',\n 'data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0',\n 'data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95',\n 'data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2',\n 'data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2',\n className\n )}\n {...props}\n />\n </PopoverPrimitive.Portal>\n));\nPopoverContent.displayName = PopoverPrimitive.Content.displayName;\n\nexport { Popover, PopoverAnchor, PopoverContent, PopoverTrigger };\n","'use client';\n\nimport { format } from 'date-fns';\nimport { Calendar as CalendarIcon } from 'lucide-react';\nimport type { DateRange } from 'react-day-picker';\n\nimport { cn } from '@openzeppelin/ui-utils';\n\nimport { Button } from './button';\nimport { Calendar } from './calendar';\nimport { Popover, PopoverContent, PopoverTrigger } from './popover';\n\n/**\n * Props for the DateRangePicker component.\n */\nexport interface DateRangePickerProps {\n /** The selected date range */\n value?: DateRange;\n /** Callback when the date range changes */\n onChange?: (range: DateRange | undefined) => void;\n /** Placeholder text when no date is selected */\n placeholder?: string;\n /** Additional CSS classes */\n className?: string;\n /** Whether the picker is disabled */\n disabled?: boolean;\n /** Number of months to display (default: 2) */\n numberOfMonths?: number;\n /** Alignment of the popover */\n align?: 'start' | 'center' | 'end';\n}\n\n/**\n * DateRangePicker component for selecting a date range.\n * Uses react-day-picker with Radix Popover for a shadcn-styled date range selection.\n *\n * @example\n * ```tsx\n * const [dateRange, setDateRange] = useState<DateRange | undefined>();\n *\n * <DateRangePicker\n * value={dateRange}\n * onChange={setDateRange}\n * placeholder=\"Select date range\"\n * />\n * ```\n */\nfunction DateRangePicker({\n value,\n onChange,\n placeholder = 'Pick a date range',\n className,\n disabled = false,\n numberOfMonths = 2,\n align = 'start',\n}: DateRangePickerProps): React.ReactElement {\n return (\n <div className={cn('grid gap-2', className)}>\n <Popover>\n <PopoverTrigger asChild>\n <Button\n id=\"date-range\"\n variant=\"outline\"\n disabled={disabled}\n className={cn(\n 'w-[280px] justify-start text-left font-normal',\n !value && 'text-muted-foreground'\n )}\n >\n <CalendarIcon className=\"mr-2 h-4 w-4\" />\n {value?.from ? (\n value.to ? (\n <>\n {format(value.from, 'LLL dd, y')} - {format(value.to, 'LLL dd, y')}\n </>\n ) : (\n format(value.from, 'LLL dd, y')\n )\n ) : (\n <span>{placeholder}</span>\n )}\n </Button>\n </PopoverTrigger>\n <PopoverContent className=\"w-auto p-0\" align={align}>\n <Calendar\n autoFocus\n mode=\"range\"\n defaultMonth={value?.from}\n selected={value}\n onSelect={onChange}\n numberOfMonths={numberOfMonths}\n />\n </PopoverContent>\n </Popover>\n </div>\n );\n}\nDateRangePicker.displayName = 'DateRangePicker';\n\nexport { DateRangePicker };\n\n// Re-export DateRange type for convenience\nexport type { DateRange };\n","import * as DialogPrimitive from '@radix-ui/react-dialog';\nimport * as React from 'react';\n\nimport { cn } from '@openzeppelin/ui-utils';\n\nconst Dialog = DialogPrimitive.Root;\n\nconst DialogTrigger = DialogPrimitive.Trigger;\n\nconst DialogPortal = DialogPrimitive.Portal;\n\nconst DialogClose = DialogPrimitive.Close;\n\nconst DialogOverlay = React.forwardRef<\n React.ComponentRef<typeof DialogPrimitive.Overlay>,\n React.ComponentPropsWithoutRef<typeof DialogPrimitive.Overlay>\n>(({ className, ...props }, ref) => (\n <DialogPrimitive.Overlay\n ref={ref}\n className={cn(\n 'data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/80',\n className\n )}\n {...props}\n />\n));\nDialogOverlay.displayName = DialogPrimitive.Overlay.displayName;\n\nconst DialogContent = React.forwardRef<\n React.ComponentRef<typeof DialogPrimitive.Content>,\n React.ComponentPropsWithoutRef<typeof DialogPrimitive.Content>\n>(({ className, children, ...props }, ref) => (\n <DialogPortal>\n <DialogOverlay />\n <DialogPrimitive.Content\n ref={ref}\n className={cn(\n 'bg-background data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 fixed top-[50%] left-[50%] z-50 flex flex-col w-full max-w-lg translate-x-[-50%] translate-y-[-50%] border shadow-lg duration-200 sm:rounded-lg max-h-[90vh]',\n className\n )}\n {...props}\n >\n <DialogPrimitive.Close className=\"ring-offset-background focus:ring-ring data-[state=open]:bg-accent data-[state=open]:text-muted-foreground absolute top-4 right-4 rounded-sm opacity-70 transition-opacity hover:opacity-100 focus:ring-2 focus:ring-offset-2 focus:outline-none disabled:pointer-events-none z-10\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"18\"\n height=\"18\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className=\"lucide lucide-x\"\n >\n <path d=\"M18 6 6 18\" />\n <path d=\"m6 6 12 12\" />\n </svg>\n <span className=\"sr-only\">Close</span>\n </DialogPrimitive.Close>\n <div className=\"overflow-y-auto p-6 flex flex-col gap-4\">{children}</div>\n </DialogPrimitive.Content>\n </DialogPortal>\n));\nDialogContent.displayName = DialogPrimitive.Content.displayName;\n\nconst DialogHeader = ({\n className,\n ...props\n}: React.HTMLAttributes<HTMLDivElement>): React.JSX.Element => (\n <div className={cn('flex flex-col space-y-1.5 text-center sm:text-left', className)} {...props} />\n);\nDialogHeader.displayName = 'DialogHeader';\n\nconst DialogFooter = ({\n className,\n ...props\n}: React.HTMLAttributes<HTMLDivElement>): React.JSX.Element => (\n <div\n className={cn('flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2', className)}\n {...props}\n />\n);\nDialogFooter.displayName = 'DialogFooter';\n\nconst DialogTitle = React.forwardRef<\n React.ComponentRef<typeof DialogPrimitive.Title>,\n React.ComponentPropsWithoutRef<typeof DialogPrimitive.Title>\n>(({ className, ...props }, ref) => (\n <DialogPrimitive.Title\n ref={ref}\n className={cn('text-lg leading-none font-semibold tracking-tight', className)}\n {...props}\n />\n));\nDialogTitle.displayName = DialogPrimitive.Title.displayName;\n\nconst DialogDescription = React.forwardRef<\n React.ComponentRef<typeof DialogPrimitive.Description>,\n React.ComponentPropsWithoutRef<typeof DialogPrimitive.Description>\n>(({ className, ...props }, ref) => (\n <DialogPrimitive.Description\n ref={ref}\n className={cn('text-muted-foreground text-sm', className)}\n {...props}\n />\n));\nDialogDescription.displayName = DialogPrimitive.Description.displayName;\n\nexport {\n Dialog,\n DialogClose,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogOverlay,\n DialogPortal,\n DialogTitle,\n DialogTrigger,\n};\n","'use client';\n\nimport * as DropdownMenuPrimitive from '@radix-ui/react-dropdown-menu';\nimport { Check, ChevronRight, Circle } from 'lucide-react';\nimport * as React from 'react';\n\nimport { cn } from '@openzeppelin/ui-utils';\n\nconst DropdownMenu = DropdownMenuPrimitive.Root;\n\nconst DropdownMenuTrigger = DropdownMenuPrimitive.Trigger;\n\nconst DropdownMenuGroup = DropdownMenuPrimitive.Group;\n\nconst DropdownMenuPortal = DropdownMenuPrimitive.Portal;\n\nconst DropdownMenuSub = DropdownMenuPrimitive.Sub;\n\nconst DropdownMenuRadioGroup = DropdownMenuPrimitive.RadioGroup;\n\nconst DropdownMenuSubTrigger = React.forwardRef<\n React.ComponentRef<typeof DropdownMenuPrimitive.SubTrigger>,\n React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.SubTrigger> & {\n inset?: boolean;\n }\n>(({ className, inset, children, ...props }, ref) => (\n <DropdownMenuPrimitive.SubTrigger\n ref={ref}\n className={cn(\n 'flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-accent data-[state=open]:bg-accent',\n inset && 'pl-8',\n className\n )}\n {...props}\n >\n {children}\n <ChevronRight className=\"ml-auto h-4 w-4\" />\n </DropdownMenuPrimitive.SubTrigger>\n));\nDropdownMenuSubTrigger.displayName = DropdownMenuPrimitive.SubTrigger.displayName;\n\nconst DropdownMenuSubContent = React.forwardRef<\n React.ComponentRef<typeof DropdownMenuPrimitive.SubContent>,\n React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.SubContent>\n>(({ className, ...props }, ref) => (\n <DropdownMenuPrimitive.SubContent\n ref={ref}\n className={cn(\n 'z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-lg data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-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',\n className\n )}\n {...props}\n />\n));\nDropdownMenuSubContent.displayName = DropdownMenuPrimitive.SubContent.displayName;\n\nconst DropdownMenuContent = React.forwardRef<\n React.ComponentRef<typeof DropdownMenuPrimitive.Content>,\n React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Content>\n>(({ className, sideOffset = 4, ...props }, ref) => (\n <DropdownMenuPrimitive.Portal>\n <DropdownMenuPrimitive.Content\n ref={ref}\n sideOffset={sideOffset}\n className={cn(\n 'z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-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',\n className\n )}\n {...props}\n />\n </DropdownMenuPrimitive.Portal>\n));\nDropdownMenuContent.displayName = DropdownMenuPrimitive.Content.displayName;\n\nconst DropdownMenuItem = React.forwardRef<\n React.ComponentRef<typeof DropdownMenuPrimitive.Item>,\n React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Item> & {\n inset?: boolean;\n }\n>(({ className, inset, ...props }, ref) => (\n <DropdownMenuPrimitive.Item\n ref={ref}\n className={cn(\n 'relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50',\n inset && 'pl-8',\n className\n )}\n {...props}\n />\n));\nDropdownMenuItem.displayName = DropdownMenuPrimitive.Item.displayName;\n\nconst DropdownMenuCheckboxItem = React.forwardRef<\n React.ComponentRef<typeof DropdownMenuPrimitive.CheckboxItem>,\n React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.CheckboxItem>\n>(({ className, children, checked, ...props }, ref) => (\n <DropdownMenuPrimitive.CheckboxItem\n ref={ref}\n className={cn(\n 'relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50',\n className\n )}\n checked={checked}\n {...props}\n >\n <span className=\"absolute left-2 flex h-3.5 w-3.5 items-center justify-center\">\n <DropdownMenuPrimitive.ItemIndicator>\n <Check className=\"h-4 w-4\" />\n </DropdownMenuPrimitive.ItemIndicator>\n </span>\n {children}\n </DropdownMenuPrimitive.CheckboxItem>\n));\nDropdownMenuCheckboxItem.displayName = DropdownMenuPrimitive.CheckboxItem.displayName;\n\nconst DropdownMenuRadioItem = React.forwardRef<\n React.ComponentRef<typeof DropdownMenuPrimitive.RadioItem>,\n React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.RadioItem>\n>(({ className, children, ...props }, ref) => (\n <DropdownMenuPrimitive.RadioItem\n ref={ref}\n className={cn(\n 'relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50',\n className\n )}\n {...props}\n >\n <span className=\"absolute left-2 flex h-3.5 w-3.5 items-center justify-center\">\n <DropdownMenuPrimitive.ItemIndicator>\n <Circle className=\"h-2 w-2 fill-current\" />\n </DropdownMenuPrimitive.ItemIndicator>\n </span>\n {children}\n </DropdownMenuPrimitive.RadioItem>\n));\nDropdownMenuRadioItem.displayName = DropdownMenuPrimitive.RadioItem.displayName;\n\nconst DropdownMenuLabel = React.forwardRef<\n React.ComponentRef<typeof DropdownMenuPrimitive.Label>,\n React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Label> & {\n inset?: boolean;\n }\n>(({ className, inset, ...props }, ref) => (\n <DropdownMenuPrimitive.Label\n ref={ref}\n className={cn('px-2 py-1.5 text-sm font-semibold', inset && 'pl-8', className)}\n {...props}\n />\n));\nDropdownMenuLabel.displayName = DropdownMenuPrimitive.Label.displayName;\n\nconst DropdownMenuSeparator = React.forwardRef<\n React.ComponentRef<typeof DropdownMenuPrimitive.Separator>,\n React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Separator>\n>(({ className, ...props }, ref) => (\n <DropdownMenuPrimitive.Separator\n ref={ref}\n className={cn('-mx-1 my-1 h-px bg-muted', className)}\n {...props}\n />\n));\nDropdownMenuSeparator.displayName = DropdownMenuPrimitive.Separator.displayName;\n\nconst DropdownMenuShortcut = ({\n className,\n ...props\n}: React.HTMLAttributes<HTMLSpanElement>): React.ReactNode => {\n return (\n <span className={cn('ml-auto text-xs tracking-widest opacity-60', className)} {...props} />\n );\n};\nDropdownMenuShortcut.displayName = 'DropdownMenuShortcut';\n\nexport {\n DropdownMenu,\n DropdownMenuTrigger,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuCheckboxItem,\n DropdownMenuRadioItem,\n DropdownMenuLabel,\n DropdownMenuSeparator,\n DropdownMenuShortcut,\n DropdownMenuGroup,\n DropdownMenuPortal,\n DropdownMenuSub,\n DropdownMenuSubContent,\n DropdownMenuSubTrigger,\n DropdownMenuRadioGroup,\n};\n","import { FileText } from 'lucide-react';\nimport React from 'react';\n\nexport interface EmptyStateProps {\n /**\n * The icon to display - can be a React component or SVG path\n */\n icon?: React.ReactNode;\n\n /**\n * Main heading text\n */\n title: string;\n\n /**\n * Descriptive text explaining the empty state\n */\n description: string;\n\n /**\n * Additional CSS classes for the container\n */\n className?: string;\n\n /**\n * Size variant for the empty state\n * @default 'default'\n */\n size?: 'small' | 'default' | 'large';\n}\n\n/**\n * Reusable empty state component for showing helpful messages when content is not available\n */\nexport function EmptyState({\n icon,\n title,\n description,\n className = '',\n size = 'default',\n}: EmptyStateProps): React.ReactElement {\n // Default icon using lucide-react\n const defaultIcon = <FileText className=\"h-6 w-6 text-muted-foreground\" />;\n\n // Size-based styling\n const sizeClasses = {\n small: {\n container: 'py-6',\n iconContainer: 'p-2 mb-2',\n title: 'text-base font-medium mb-1',\n description: 'text-xs max-w-sm',\n },\n default: {\n container: 'py-12',\n iconContainer: 'p-3 mb-4',\n title: 'text-lg font-medium mb-2',\n description: 'text-sm max-w-md',\n },\n large: {\n container: 'py-16',\n iconContainer: 'p-4 mb-6',\n title: 'text-xl font-medium mb-3',\n description: 'text-base max-w-lg',\n },\n };\n\n const styles = sizeClasses[size];\n\n return (\n <div\n className={`flex flex-col items-center justify-center text-center ${styles.container} ${className}`}\n >\n <div className={`rounded-full bg-muted ${styles.iconContainer}`}>{icon || defaultIcon}</div>\n <h3 className={`${styles.title}`}>{title}</h3>\n <p className={`text-muted-foreground ${styles.description}`}>{description}</p>\n </div>\n );\n}\n","import { ExternalLinkIcon } from 'lucide-react';\nimport React from 'react';\n\nimport { cn } from '@openzeppelin/ui-utils';\n\n// TODO: Add props\n// interface ExternalLinkProps extends React.AnchorHTMLAttributes<HTMLAnchorElement> {\n// // No additional props needed for basic functionality\n// }\n\n// export const ExternalLink = React.forwardRef<HTMLAnchorElement, ExternalLinkProps>(\nexport const ExternalLink = React.forwardRef<\n HTMLAnchorElement,\n React.AnchorHTMLAttributes<HTMLAnchorElement>\n>(({ children, className, ...props }, ref) => {\n return (\n <a\n ref={ref}\n className={cn(\n 'inline-flex items-center gap-1 text-primary underline-offset-4 hover:underline',\n className\n )}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n {...props}\n >\n {children}\n <ExternalLinkIcon className=\"h-3 w-3 ml-1\" /> {/* Adjust size/margin as needed */}\n </a>\n );\n});\n\nExternalLink.displayName = 'ExternalLink';\n","import { JSX } from 'react';\n\nimport { cn } from '@openzeppelin/ui-utils';\n\n/**\n * Props for the Footer component\n */\nexport interface FooterProps {\n /**\n * Company or organization name for the copyright notice\n * @default 'OpenZeppelin'\n */\n companyName?: string;\n\n /**\n * Copyright year to display\n * @default Current year\n */\n copyrightYear?: number;\n\n /**\n * URL for the privacy policy link\n * @default 'https://www.openzeppelin.com/privacy'\n */\n privacyPolicyUrl?: string;\n\n /**\n * Text for the privacy policy link\n * @default 'Privacy Policy'\n */\n privacyPolicyText?: string;\n\n /**\n * URL for the terms of service link\n * @default 'https://www.openzeppelin.com/tos'\n */\n termsOfServiceUrl?: string;\n\n /**\n * Text for the terms of service link\n * @default 'Terms of Service'\n */\n termsOfServiceText?: string;\n\n /**\n * Whether to show the privacy policy link\n * @default true\n */\n showPrivacyPolicy?: boolean;\n\n /**\n * Whether to show the terms of service link\n * @default true\n */\n showTermsOfService?: boolean;\n\n /**\n * Additional CSS classes for the footer container\n */\n className?: string;\n}\n\n/**\n * Application footer component with customizable legal links and branding.\n *\n * This component provides a consistent footer layout with customizable:\n * - Company name and copyright year\n * - Privacy policy and terms of service links and text\n * - Optional visibility controls for legal links\n * - Custom styling support\n */\nexport const Footer = ({\n companyName = 'OpenZeppelin',\n copyrightYear = new Date().getFullYear(),\n privacyPolicyUrl = 'https://www.openzeppelin.com/privacy',\n privacyPolicyText = 'Privacy Policy',\n termsOfServiceUrl = 'https://www.openzeppelin.com/tos',\n termsOfServiceText = 'Terms of Service',\n showPrivacyPolicy = true,\n showTermsOfService = true,\n className,\n}: FooterProps = {}): JSX.Element => {\n const hasLegalLinks = showPrivacyPolicy || showTermsOfService;\n\n return (\n <footer className={cn('border-t bg-background border-[#F5F5F5]', className)}>\n <div className=\"px-6 py-4 sm:h-12\">\n <div className=\"text-sm text-muted-foreground flex flex-col items-center gap-2 sm:flex-row sm:items-center sm:justify-between\">\n <span>\n © {copyrightYear} {companyName}\n </span>\n {hasLegalLinks && (\n <div className=\"flex flex-col items-center gap-2 sm:flex-row sm:gap-4\">\n {showPrivacyPolicy && (\n <a\n href={privacyPolicyUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"hover:text-foreground transition-colors\"\n >\n {privacyPolicyText}\n </a>\n )}\n {showTermsOfService && (\n <a\n href={termsOfServiceUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"hover:text-foreground transition-colors\"\n >\n {termsOfServiceText}\n </a>\n )}\n </div>\n )}\n </div>\n </div>\n </footer>\n );\n};\n","import * as LabelPrimitive from '@radix-ui/react-label';\nimport * as React from 'react';\n\nimport { cn } from '@openzeppelin/ui-utils';\n\ntype LabelProps = React.ComponentPropsWithoutRef<typeof LabelPrimitive.Root>;\n/**\n * Label component for form fields, following shadcn/ui styling\n */\nconst Label = React.forwardRef<HTMLLabelElement, LabelProps>(({ className, ...props }, ref) => {\n return (\n <LabelPrimitive.Root\n ref={ref}\n data-slot=\"label\"\n className={cn('text-sm leading-none font-medium', className)}\n {...props}\n />\n );\n});\n\nLabel.displayName = LabelPrimitive.Root.displayName;\n\nexport { Label };\n","import * as React from 'react';\nimport type { FieldError, FieldPath, FieldValues, UseFormReturn } from 'react-hook-form';\nimport { Controller, FormProvider, useFormContext } from 'react-hook-form';\n\nimport { cn } from '@openzeppelin/ui-utils';\n\nimport { Label } from './label';\n\n/**\n * Context provider for the form\n */\nconst Form = <TFieldValues extends FieldValues = FieldValues, TContext = unknown>({\n ...props\n}: React.ComponentProps<typeof FormProvider<TFieldValues, TContext>>): React.ReactElement => {\n return <FormProvider {...props} />;\n};\n\n/**\n * Props for form field components\n */\ninterface FormFieldContextValue<\n TFieldValues extends FieldValues = FieldValues,\n TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,\n> {\n name: TName;\n}\n\n/**\n * Context for form field state\n */\nconst FormFieldContext = React.createContext<FormFieldContextValue>({} as FormFieldContextValue);\n\n/**\n * Get form field context\n */\nconst useFormField = (): {\n id: string;\n name: string;\n formItemId: string;\n formDescriptionId: string;\n formMessageId: string;\n error?: FieldError;\n} => {\n const fieldContext = React.useContext(FormFieldContext);\n const itemContext = React.useContext(FormItemContext);\n const { getFieldState, formState } = useFormContext();\n\n const fieldState = getFieldState(fieldContext.name, formState);\n\n if (!fieldContext) {\n throw new Error('useFormField should be used within <FormField>');\n }\n\n const { id } = itemContext;\n\n return {\n id,\n name: fieldContext.name,\n formItemId: `${id}-form-item`,\n formDescriptionId: `${id}-form-item-description`,\n formMessageId: `${id}-form-item-message`,\n error: fieldState.error as FieldError | undefined,\n };\n};\n\n/**\n * Form field component\n */\nconst FormField = <\n TFieldValues extends FieldValues = FieldValues,\n TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,\n>({\n ...props\n}: ControllerProps<TFieldValues, TName>): React.ReactElement => {\n return (\n <FormFieldContext.Provider value={{ name: props.name }}>\n <Controller {...props} />\n </FormFieldContext.Provider>\n );\n};\n\n/**\n * Context for form item state\n */\ninterface FormItemContextValue {\n id: string;\n}\n\nconst FormItemContext = React.createContext<FormItemContextValue>({} as FormItemContextValue);\n\n/**\n * Form item component\n */\nconst FormItem = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(\n ({ className, ...props }, ref) => {\n const id = React.useId();\n\n return (\n <FormItemContext.Provider value={{ id }}>\n <div\n ref={ref}\n data-slot=\"form-item\"\n className={cn('flex flex-col gap-2', className)}\n {...props}\n />\n </FormItemContext.Provider>\n );\n }\n);\nFormItem.displayName = 'FormItem';\n\n/**\n * Form label component\n */\nconst FormLabel = React.forwardRef<HTMLLabelElement, React.ComponentPropsWithoutRef<typeof Label>>(\n ({ className, ...props }, ref) => {\n const { error, formItemId } = useFormField();\n\n return (\n <Label\n ref={ref}\n className={error ? cn('text-destructive', className) : className}\n htmlFor={formItemId}\n {...props}\n />\n );\n }\n);\nFormLabel.displayName = 'FormLabel';\n\n/**\n * Form control component\n */\nconst FormControl = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(\n ({ ...props }, ref) => {\n const { error, formItemId, formDescriptionId, formMessageId } = useFormField();\n\n return (\n <div\n ref={ref}\n id={formItemId}\n aria-describedby={!error ? `${formDescriptionId}` : `${formDescriptionId} ${formMessageId}`}\n aria-invalid={!!error}\n {...props}\n />\n );\n }\n);\nFormControl.displayName = 'FormControl';\n\n/**\n * Form description component\n */\nconst FormDescription = React.forwardRef<\n HTMLParagraphElement,\n React.HTMLAttributes<HTMLParagraphElement>\n>(({ className, ...props }, ref) => {\n const { formDescriptionId } = useFormField();\n\n return (\n <p\n ref={ref}\n id={formDescriptionId}\n data-slot=\"form-description\"\n className={cn('text-muted-foreground text-sm', className)}\n {...props}\n />\n );\n});\nFormDescription.displayName = 'FormDescription';\n\n/**\n * Form error message component\n */\nconst FormMessage = React.forwardRef<\n HTMLParagraphElement,\n React.HTMLAttributes<HTMLParagraphElement>\n>(({ className, children, ...props }, ref) => {\n const { error, formMessageId } = useFormField();\n const body = error ? String(error?.message) : children;\n\n if (!body) {\n return null;\n }\n\n return (\n <p\n ref={ref}\n id={formMessageId}\n data-slot=\"form-message\"\n className={cn('text-destructive text-sm font-medium', className)}\n {...props}\n >\n {body}\n </p>\n );\n});\nFormMessage.displayName = 'FormMessage';\n\n/**\n * Types for form controller props\n */\ntype ControllerProps<\n TFieldValues extends FieldValues = FieldValues,\n TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,\n> = {\n name: TName;\n control?: UseFormReturn<TFieldValues>['control'];\n render: (props: {\n field: {\n value: unknown;\n onChange: (...event: unknown[]) => void;\n onBlur: () => void;\n name: TName;\n ref: React.RefCallback<HTMLInputElement>;\n };\n fieldState: {\n invalid: boolean;\n isTouched: boolean;\n isDirty: boolean;\n error?: unknown;\n };\n formState: UseFormReturn<TFieldValues>['formState'];\n }) => React.ReactElement;\n};\n\nexport { Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage };\n","import { Menu } from 'lucide-react';\nimport React from 'react';\n\nexport interface HeaderProps {\n title?: string;\n /** Open the mobile sidebar */\n onOpenSidebar?: () => void;\n /** Content to display on the right side of the header */\n rightContent?: React.ReactNode;\n}\n\nexport const Header = ({ title, onOpenSidebar, rightContent }: HeaderProps): React.ReactElement => {\n return (\n <header className=\"border-b border-[#F5F5F5] bg-background\">\n <div className=\"flex h-16 items-center px-3 sm:px-4 md:px-5 min-w-0\">\n {/* Mobile menu button */}\n <button\n type=\"button\"\n aria-label=\"Open menu\"\n onClick={onOpenSidebar}\n className=\"mr-2 sm:mr-3 inline-flex items-center justify-center rounded-md p-2 text-primary hover:bg-muted focus:outline-none focus:ring-2 focus:ring-primary xl:hidden\"\n >\n <Menu className=\"size-5\" />\n </button>\n {/* Left side - Title (conditional) */}\n {title && (\n <div className=\"flex items-center min-w-0\">\n <h1 className=\"truncate max-w-[50vw] text-base font-semibold text-foreground\">\n {title}\n </h1>\n </div>\n )}\n\n {/* Right side - Wallet Connection or other content */}\n <div className=\"ml-auto flex items-center\">{rightContent}</div>\n </div>\n </header>\n );\n};\n","import * as React from 'react';\n\nimport { cn } from '@openzeppelin/ui-utils';\n\n/**\n * Input component that follows shadcn/ui styling and accessibility patterns\n */\nexport type InputProps = React.InputHTMLAttributes<HTMLInputElement>;\n\nconst Input = React.forwardRef<HTMLInputElement, InputProps>(\n ({ className, type, ...props }, ref) => {\n return (\n <input\n type={type}\n data-slot=\"input\"\n className={cn(\n 'border-input bg-background ring-offset-background focus-visible:ring-ring placeholder:text-muted-foreground h-10 w-full rounded-md border px-3 py-2 text-sm file:border-0 file:bg-transparent file:text-sm file:font-medium focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:outline-none disabled:cursor-not-allowed disabled:opacity-50',\n className\n )}\n ref={ref}\n {...props}\n />\n );\n }\n);\n\nInput.displayName = 'Input';\n\nexport { Input };\n","import { Slot, Slottable } from '@radix-ui/react-slot';\nimport { type VariantProps } from 'class-variance-authority';\nimport * as React from 'react';\n\nimport { cn } from '@openzeppelin/ui-utils';\n\nimport { buttonVariants } from '../../utils/button-variants';\n\n/**\n * Loading spinner component\n */\nconst Spinner = (): React.ReactElement => (\n <svg\n className=\"mr-2 h-4 w-4 animate-spin\"\n xmlns=\"http://www.w3.org/2000/svg\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n >\n <circle\n className=\"opacity-25\"\n cx=\"12\"\n cy=\"12\"\n r=\"10\"\n stroke=\"currentColor\"\n strokeWidth=\"4\"\n ></circle>\n <path\n className=\"opacity-75\"\n fill=\"currentColor\"\n d=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z\"\n ></path>\n </svg>\n);\n\nexport interface LoadingButtonProps\n extends React.ButtonHTMLAttributes<HTMLButtonElement>,\n VariantProps<typeof buttonVariants> {\n asChild?: boolean;\n loading?: boolean;\n}\n\nconst LoadingButton = React.forwardRef<HTMLButtonElement, LoadingButtonProps>(\n (\n { className, loading = false, children, disabled, variant, size, asChild = false, ...props },\n ref\n ) => {\n const Comp = asChild ? Slot : 'button';\n return (\n <Comp\n data-slot=\"button\"\n data-variant={variant || 'default'}\n data-size={size || 'default'}\n className={cn(buttonVariants({ variant, size, className }))}\n ref={ref}\n disabled={loading || disabled}\n {...props}\n >\n {loading && <Spinner />}\n <Slottable>{children}</Slottable>\n </Comp>\n );\n }\n);\nLoadingButton.displayName = 'LoadingButton';\n\nexport { LoadingButton };\n","import React from 'react';\n\nexport interface MidnightIconProps {\n size?: number;\n className?: string;\n variant?: 'mono' | 'branded';\n}\n\n/**\n * MidnightIcon - SVG icon for the Midnight blockchain\n * Inline SVG to ensure it renders correctly when this package is consumed as a library\n */\nexport function MidnightIcon({\n size = 16,\n className = '',\n variant: _variant,\n}: MidnightIconProps): React.ReactElement {\n // variant is accepted for API consistency but not used as MidnightIcon is always branded\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 789.37 789.37\"\n width={size}\n height={size}\n className={className}\n aria-hidden=\"true\"\n >\n <path\n d=\"m394.69,0C176.71,0,0,176.71,0,394.69s176.71,394.69,394.69,394.69,394.69-176.71,394.69-394.69S612.67,0,394.69,0Zm0,716.6c-177.5,0-321.91-144.41-321.91-321.91S217.18,72.78,394.69,72.78s321.91,144.41,321.91,321.91-144.41,321.91-321.91,321.91Z\"\n fill=\"currentColor\"\n />\n <rect x=\"357.64\" y=\"357.64\" width=\"74.09\" height=\"74.09\" fill=\"currentColor\" />\n <rect x=\"357.64\" y=\"240.66\" width=\"74.09\" height=\"74.09\" fill=\"currentColor\" />\n <rect x=\"357.64\" y=\"123.69\" width=\"74.09\" height=\"74.09\" fill=\"currentColor\" />\n </svg>\n );\n}\n","import React from 'react';\n\nimport type { NetworkConfig } from '@openzeppelin/ui-types';\nimport { cn } from '@openzeppelin/ui-utils';\n\nimport { MidnightIcon } from '../icons/MidnightIcon';\n\nexport interface NetworkIconProps {\n network: Pick<NetworkConfig, 'ecosystem' | 'iconComponent'>;\n className?: string;\n size?: number;\n variant?: 'mono' | 'branded';\n}\n\n/** Displays the appropriate icon for a blockchain network. */\nexport function NetworkIcon({\n network,\n className,\n size = 16,\n variant = 'branded',\n}: NetworkIconProps): React.ReactElement {\n if (network.ecosystem === 'midnight') {\n return <MidnightIcon size={size} variant={variant} className={cn('shrink-0', className)} />;\n }\n\n if (network.iconComponent) {\n return (\n <network.iconComponent size={size} variant={variant} className={cn('shrink-0', className)} />\n );\n }\n\n return (\n <div\n className={cn('bg-muted shrink-0 rounded-full', className)}\n style={{ width: size, height: size }}\n aria-hidden=\"true\"\n />\n );\n}\n","import { Check, ChevronDown, Search } from 'lucide-react';\nimport * as React from 'react';\n\nimport type { NetworkType } from '@openzeppelin/ui-types';\nimport { cn } from '@openzeppelin/ui-utils';\n\nimport {\n Button,\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuGroup,\n DropdownMenuItem,\n DropdownMenuLabel,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n Input,\n} from '.';\n\nexport interface NetworkSelectorProps<T> {\n networks: T[];\n selectedNetwork: T | null;\n onSelectNetwork: (network: T) => void;\n getNetworkLabel: (network: T) => string;\n getNetworkIcon?: (network: T) => React.ReactNode;\n getNetworkType?: (network: T) => NetworkType | undefined;\n getNetworkId: (network: T) => string;\n groupByEcosystem?: boolean;\n getEcosystem?: (network: T) => string;\n filterNetwork?: (network: T, query: string) => boolean;\n className?: string;\n placeholder?: string;\n}\n\n/** Searchable dropdown selector for blockchain networks with optional grouping. */\nexport function NetworkSelector<T>({\n networks,\n selectedNetwork,\n onSelectNetwork,\n getNetworkLabel,\n getNetworkIcon,\n getNetworkType,\n getNetworkId,\n groupByEcosystem = false,\n getEcosystem,\n filterNetwork,\n className,\n placeholder = 'Select Network',\n}: NetworkSelectorProps<T>): React.ReactElement {\n const [open, setOpen] = React.useState(false);\n const [searchQuery, setSearchQuery] = React.useState('');\n\n const filteredNetworks = React.useMemo(() => {\n if (!searchQuery) return networks;\n if (filterNetwork) return networks.filter((n) => filterNetwork(n, searchQuery));\n return networks.filter((n) =>\n getNetworkLabel(n).toLowerCase().includes(searchQuery.toLowerCase())\n );\n }, [networks, searchQuery, filterNetwork, getNetworkLabel]);\n\n const groupedNetworks = React.useMemo(() => {\n if (!groupByEcosystem || !getEcosystem) {\n return { All: filteredNetworks };\n }\n return filteredNetworks.reduce(\n (acc, network) => {\n const ecosystem = getEcosystem(network);\n if (!acc[ecosystem]) {\n acc[ecosystem] = [];\n }\n acc[ecosystem].push(network);\n return acc;\n },\n {} as Record<string, T[]>\n );\n }, [filteredNetworks, groupByEcosystem, getEcosystem]);\n\n return (\n <DropdownMenu open={open} onOpenChange={setOpen}>\n <DropdownMenuTrigger asChild>\n <Button\n variant=\"outline\"\n role=\"combobox\"\n aria-expanded={open}\n className={cn('w-full justify-between', className)}\n >\n <span className=\"flex items-center gap-2 truncate\">\n {selectedNetwork ? (\n <>\n {getNetworkIcon?.(selectedNetwork)}\n <span className=\"truncate\">{getNetworkLabel(selectedNetwork)}</span>\n {getNetworkType && (\n <span className=\"shrink-0 rounded-sm bg-muted px-1.5 py-0.5 text-[10px] font-medium uppercase text-muted-foreground\">\n {getNetworkType(selectedNetwork)}\n </span>\n )}\n </>\n ) : (\n <span className=\"text-muted-foreground\">{placeholder}</span>\n )}\n </span>\n <ChevronDown className=\"ml-2 h-4 w-4 shrink-0 opacity-50\" />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent\n className=\"w-[--radix-dropdown-menu-trigger-width] min-w-[240px] p-0\"\n align=\"start\"\n >\n <div className=\"flex items-center border-b px-3\">\n <Search className=\"mr-2 h-4 w-4 shrink-0 opacity-50\" />\n <Input\n placeholder=\"Search network...\"\n value={searchQuery}\n onChange={(e) => setSearchQuery(e.target.value)}\n onKeyDown={(e) => {\n if (e.key !== 'ArrowDown' && e.key !== 'ArrowUp' && e.key !== 'Enter') {\n e.stopPropagation();\n }\n }}\n className=\"h-9 w-full border-0 bg-transparent p-0 placeholder:text-muted-foreground focus-visible:ring-0 focus-visible:ring-offset-0\"\n aria-label=\"Search networks\"\n />\n </div>\n <div className=\"max-h-[300px] overflow-y-auto p-1\">\n {Object.entries(groupedNetworks).length === 0 ? (\n <div className=\"py-6 text-center text-sm text-muted-foreground\">No network found.</div>\n ) : (\n Object.entries(groupedNetworks).map(([group, groupNetworks], index) => (\n <React.Fragment key={group}>\n {groupByEcosystem && (\n <DropdownMenuLabel className=\"text-xs font-medium text-muted-foreground\">\n {group}\n </DropdownMenuLabel>\n )}\n <DropdownMenuGroup>\n {groupNetworks.map((network) => (\n <DropdownMenuItem\n key={getNetworkId(network)}\n onSelect={() => {\n onSelectNetwork(network);\n setOpen(false);\n }}\n className=\"gap-2\"\n >\n {getNetworkIcon?.(network)}\n <div className=\"flex flex-1 items-center gap-2 min-w-0\">\n <span className=\"truncate\">{getNetworkLabel(network)}</span>\n {getNetworkType && (\n <span className=\"shrink-0 rounded-sm bg-muted px-1.5 py-0.5 text-[10px] font-medium uppercase text-muted-foreground\">\n {getNetworkType(network)}\n </span>\n )}\n </div>\n {selectedNetwork &&\n getNetworkId(selectedNetwork) === getNetworkId(network) && (\n <Check className=\"h-4 w-4 opacity-100\" />\n )}\n </DropdownMenuItem>\n ))}\n </DropdownMenuGroup>\n {index < Object.keys(groupedNetworks).length - 1 && <DropdownMenuSeparator />}\n </React.Fragment>\n ))\n )}\n </div>\n </DropdownMenuContent>\n </DropdownMenu>\n );\n}\n","import React from 'react';\n\nimport type { NetworkConfig } from '@openzeppelin/ui-types';\nimport { cn } from '@openzeppelin/ui-utils';\n\nimport { NetworkIcon } from './network-icon';\n\ninterface NetworkStatusBadgeProps {\n network: NetworkConfig | null;\n className?: string;\n}\n\n// Define constants for consistency\nconst ICON_SIZE = 16;\n\n/**\n * NetworkStatusBadge - Displays network information in a compact badge format\n * Shows the network icon, ecosystem, and name with dashed borders for testnet/devnet\n */\nexport function NetworkStatusBadge({\n network,\n className,\n}: NetworkStatusBadgeProps): React.ReactElement | null {\n if (!network) return null;\n\n const isTestnetLike = network.type === 'testnet' || network.type === 'devnet';\n\n return (\n <div\n className={cn(\n 'inline-flex items-center gap-2 rounded-full bg-muted px-3 py-2',\n isTestnetLike ? 'border-2 border-dashed border-muted-foreground/40' : 'border-0',\n className\n )}\n >\n {/* Network icon */}\n <NetworkIcon network={network} size={ICON_SIZE} />\n\n {/* Combined ecosystem + network name */}\n <div className=\"flex items-baseline gap-1.5\">\n <span className=\"text-xs font-medium text-muted-foreground uppercase\">\n {network.ecosystem}\n </span>\n <span className=\"text-xs font-medium\">{network.name}</span>\n </div>\n </div>\n );\n}\n","import * as ProgressPrimitive from '@radix-ui/react-progress';\nimport * as React from 'react';\n\nimport { cn } from '@openzeppelin/ui-utils';\n\nconst Progress = React.forwardRef<\n React.ElementRef<typeof ProgressPrimitive.Root>,\n React.ComponentPropsWithoutRef<typeof ProgressPrimitive.Root>\n>(({ className, value, ...props }, ref) => (\n <ProgressPrimitive.Root\n ref={ref}\n className={cn(\n 'relative h-2 w-full overflow-hidden rounded-full bg-gray-100 dark:bg-gray-800',\n className\n )}\n {...props}\n >\n <ProgressPrimitive.Indicator\n className=\"bg-primary h-full w-full flex-1 transition-all\"\n style={{ transform: `translateX(-${100 - (value || 0)}%)` }}\n />\n </ProgressPrimitive.Root>\n));\nProgress.displayName = ProgressPrimitive.Root.displayName;\n\nexport { Progress };\n","import * as RadioGroupPrimitive from '@radix-ui/react-radio-group';\nimport { Circle } from 'lucide-react';\nimport * as React from 'react';\n\nimport { cn } from '@openzeppelin/ui-utils';\n\nconst RadioGroup = React.forwardRef<\n HTMLDivElement,\n React.ComponentPropsWithoutRef<typeof RadioGroupPrimitive.Root>\n>(({ className, ...props }, ref) => {\n return (\n <RadioGroupPrimitive.Root\n className={cn('flex flex-col space-y-2', className)}\n data-slot=\"radiogroup\"\n {...props}\n ref={ref}\n />\n );\n});\nRadioGroup.displayName = RadioGroupPrimitive.Root.displayName;\n\nconst RadioGroupItem = React.forwardRef<\n HTMLButtonElement,\n React.ComponentPropsWithoutRef<typeof RadioGroupPrimitive.Item>\n>(({ className, ...props }, ref) => {\n return (\n <RadioGroupPrimitive.Item\n ref={ref}\n className={cn(\n 'border-input bg-background text-primary h-4 w-4 rounded-full border shadow-sm focus:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50',\n className\n )}\n {...props}\n >\n <RadioGroupPrimitive.Indicator className=\"flex items-center justify-center\">\n <Circle className=\"h-2.5 w-2.5 fill-current text-current\" />\n </RadioGroupPrimitive.Indicator>\n </RadioGroupPrimitive.Item>\n );\n});\nRadioGroupItem.displayName = RadioGroupPrimitive.Item.displayName;\n\nexport { RadioGroup, RadioGroupItem };\n","import * as SelectPrimitive from '@radix-ui/react-select';\nimport { Check, ChevronDown, ChevronUp } from 'lucide-react';\nimport * as React from 'react';\n\nimport { cn } from '@openzeppelin/ui-utils';\n\nconst Select = SelectPrimitive.Root;\n\nconst SelectGroup = SelectPrimitive.Group;\n\nconst SelectValue = SelectPrimitive.Value;\n\nconst SelectTrigger = React.forwardRef<\n HTMLButtonElement,\n React.ComponentPropsWithoutRef<typeof SelectPrimitive.Trigger>\n>(({ className, children, ...props }, ref) => (\n <SelectPrimitive.Trigger\n ref={ref}\n data-slot=\"select-trigger\"\n className={cn(\n 'border-input bg-background placeholder:text-muted-foreground flex h-10 w-full items-center justify-between rounded-md border px-3 py-2 text-sm focus:outline-none focus-visible:ring-0 focus-visible:ring-offset-0 focus-visible:outline-none disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1',\n className\n )}\n {...props}\n >\n {children}\n <SelectPrimitive.Icon asChild>\n <ChevronDown className=\"h-4 w-4 opacity-50\" />\n </SelectPrimitive.Icon>\n </SelectPrimitive.Trigger>\n));\nSelectTrigger.displayName = SelectPrimitive.Trigger.displayName;\n\nconst SelectScrollUpButton = React.forwardRef<\n HTMLDivElement,\n React.ComponentPropsWithoutRef<typeof SelectPrimitive.ScrollUpButton>\n>(({ className, ...props }, ref) => (\n <SelectPrimitive.ScrollUpButton\n ref={ref}\n data-slot=\"select-scroll-button\"\n className={className}\n {...props}\n >\n <ChevronUp className=\"h-4 w-4\" />\n </SelectPrimitive.ScrollUpButton>\n));\nSelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName;\n\nconst SelectScrollDownButton = React.forwardRef<\n HTMLDivElement,\n React.ComponentPropsWithoutRef<typeof SelectPrimitive.ScrollDownButton>\n>(({ className, ...props }, ref) => (\n <SelectPrimitive.ScrollDownButton\n ref={ref}\n data-slot=\"select-scroll-button\"\n className={className}\n {...props}\n >\n <ChevronDown className=\"h-4 w-4\" />\n </SelectPrimitive.ScrollDownButton>\n));\nSelectScrollDownButton.displayName = SelectPrimitive.ScrollDownButton.displayName;\n\nconst SelectContent = React.forwardRef<\n HTMLDivElement,\n React.ComponentPropsWithoutRef<typeof SelectPrimitive.Content>\n>(({ className, children, position = 'popper', ...props }, ref) => (\n <SelectPrimitive.Portal>\n <SelectPrimitive.Content\n ref={ref}\n data-slot=\"select-content\"\n className={cn(\n 'bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-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 relative z-50 max-h-96 w-[var(--radix-select-trigger-width)] overflow-hidden rounded-md border shadow-md',\n position === 'popper' &&\n 'data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1',\n className\n )}\n position={position}\n {...props}\n >\n <SelectScrollUpButton />\n <SelectPrimitive.Viewport\n className={cn(\n 'p-1',\n position === 'popper' &&\n 'h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)]'\n )}\n >\n {children}\n </SelectPrimitive.Viewport>\n <SelectScrollDownButton />\n </SelectPrimitive.Content>\n </SelectPrimitive.Portal>\n));\nSelectContent.displayName = SelectPrimitive.Content.displayName;\n\nconst SelectLabel = React.forwardRef<\n HTMLDivElement,\n React.ComponentPropsWithoutRef<typeof SelectPrimitive.Label>\n>(({ className, ...props }, ref) => (\n <SelectPrimitive.Label\n ref={ref}\n data-slot=\"select-label\"\n className={cn('py-1.5 pr-2 pl-8 text-sm font-semibold', className)}\n {...props}\n />\n));\nSelectLabel.displayName = SelectPrimitive.Label.displayName;\n\nconst SelectItem = React.forwardRef<\n HTMLDivElement,\n React.ComponentPropsWithoutRef<typeof SelectPrimitive.Item>\n>(({ className, children, ...props }, ref) => (\n <SelectPrimitive.Item\n ref={ref}\n data-slot=\"select-item\"\n className={cn(\n 'hover:bg-accent relative flex w-full cursor-default items-center rounded-sm py-1.5 pr-2 pl-8 text-sm transition-colors duration-150 outline-none select-none focus:outline-none focus-visible:ring-0 focus-visible:ring-offset-0 focus-visible:outline-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50',\n className\n )}\n {...props}\n >\n <span\n data-slot=\"select-item-indicator\"\n className=\"absolute left-2 flex h-3.5 w-3.5 items-center justify-center\"\n >\n <SelectPrimitive.ItemIndicator>\n <Check className=\"h-4 w-4\" />\n </SelectPrimitive.ItemIndicator>\n </span>\n <SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>\n </SelectPrimitive.Item>\n));\nSelectItem.displayName = SelectPrimitive.Item.displayName;\n\nconst SelectSeparator = React.forwardRef<\n HTMLDivElement,\n React.ComponentPropsWithoutRef<typeof SelectPrimitive.Separator>\n>(({ className, ...props }, ref) => (\n <SelectPrimitive.Separator\n ref={ref}\n data-slot=\"select-separator\"\n className={cn('bg-muted -mx-1 my-1 h-px', className)}\n {...props}\n />\n));\nSelectSeparator.displayName = SelectPrimitive.Separator.displayName;\n\nexport {\n Select,\n SelectContent,\n SelectGroup,\n SelectItem,\n SelectLabel,\n SelectScrollDownButton,\n SelectScrollUpButton,\n SelectSeparator,\n SelectTrigger,\n SelectValue,\n};\n","import React, { ReactNode } from 'react';\n\nimport { cn } from '@openzeppelin/ui-utils';\n\nexport interface SidebarButtonProps {\n icon?: ReactNode;\n children: ReactNode;\n onClick?: () => void;\n size?: 'default' | 'small';\n badge?: string;\n disabled?: boolean;\n isSelected?: boolean;\n /** When provided, renders as an anchor element instead of a button */\n href?: string;\n target?: React.HTMLAttributeAnchorTarget;\n rel?: string;\n className?: string;\n}\n\n/**\n * A styled button component for sidebar actions with consistent styling.\n * Can render as a button or anchor element depending on whether href is provided.\n */\nexport function SidebarButton({\n icon,\n children,\n onClick,\n size = 'default',\n badge,\n disabled = false,\n isSelected = false,\n href,\n target,\n rel,\n className,\n}: SidebarButtonProps): React.ReactElement {\n const height = size === 'small' ? 'h-10' : 'h-11';\n\n const commonClass = cn(\n 'group relative flex items-center gap-2 px-3 py-2.5 rounded-lg font-semibold text-sm transition-colors',\n badge ? 'justify-between' : 'justify-start',\n disabled\n ? 'text-gray-400 cursor-not-allowed'\n : isSelected\n ? 'text-[#111928] bg-neutral-100'\n : 'text-gray-600 hover:text-gray-700 cursor-pointer hover:before:content-[\"\"] hover:before:absolute hover:before:inset-x-0 hover:before:top-1 hover:before:bottom-1 hover:before:bg-muted/80 hover:before:rounded-lg hover:before:-z-10',\n height,\n className\n );\n\n const content = (\n <>\n <div className=\"flex items-center gap-2\">\n {icon}\n {children}\n </div>\n {badge && (\n <span className=\"text-xs px-2 py-1 bg-muted text-muted-foreground rounded-full font-medium\">\n {badge}\n </span>\n )}\n </>\n );\n\n if (href) {\n return (\n <a href={href} target={target} rel={rel} className={commonClass} onClick={onClick}>\n {content}\n </a>\n );\n }\n\n return (\n <button className={commonClass} onClick={disabled ? undefined : onClick} disabled={disabled}>\n {content}\n </button>\n );\n}\n","import React, { ReactNode } from 'react';\n\nimport { cn } from '@openzeppelin/ui-utils';\n\nexport interface SidebarLayoutProps {\n /** Content for the sidebar header (e.g., logo) */\n header?: ReactNode;\n /** Content to be displayed below the header but above the scrollable area */\n subHeader?: ReactNode;\n /** Main scrollable content area */\n children: ReactNode;\n /** Content for the fixed footer (e.g., nav icons) */\n footer?: ReactNode;\n /** Additional CSS classes for the sidebar container */\n className?: string;\n /** Width of the sidebar (default: 289px) */\n width?: number | string;\n /** Background color/class for the sidebar */\n background?: string;\n /** Controls visibility in mobile slide-over */\n mobileOpen?: boolean;\n /** Close handler for mobile slide-over */\n onMobileOpenChange?: (open: boolean) => void;\n /** Aria label for mobile dialog */\n mobileAriaLabel?: string;\n}\n\n/**\n * A flexible sidebar layout component with desktop sidebar and mobile slide-over.\n * Provides slots for header, scrollable content, and footer.\n */\nexport function SidebarLayout({\n header,\n subHeader,\n children,\n footer,\n className,\n width = 289,\n background = 'bg-[rgba(245,245,245,0.31)]',\n mobileOpen,\n onMobileOpenChange,\n mobileAriaLabel = 'Menu',\n}: SidebarLayoutProps): React.ReactElement {\n const widthStyle = typeof width === 'number' ? `${width}px` : width;\n\n return (\n <>\n {/* Desktop Sidebar */}\n <div\n className={cn(\n 'fixed left-0 top-0 z-40 h-full hidden xl:flex xl:flex-col',\n background,\n className\n )}\n style={{ width: widthStyle }}\n >\n {/* Fixed Header */}\n {header && <div className=\"shrink-0 px-8 pt-12\">{header}</div>}\n\n {/* Fixed SubHeader */}\n {subHeader && <div className=\"shrink-0 px-8 mt-6\">{subHeader}</div>}\n\n {/* Scrollable Content Area */}\n <div className=\"flex-1 overflow-y-auto px-8 pb-24\">{children}</div>\n\n {/* Fixed Footer */}\n {footer && <div className=\"pointer-events-auto sticky bottom-0 px-8 py-4\">{footer}</div>}\n </div>\n\n {/* Spacer to push content (desktop only) */}\n <div className=\"hidden xl:block\" style={{ width: widthStyle }} />\n\n {/* Mobile slide-over */}\n {typeof mobileOpen === 'boolean' && onMobileOpenChange && (\n <div\n className={cn(\n 'xl:hidden fixed inset-0 z-50',\n mobileOpen ? 'pointer-events-auto' : 'pointer-events-none'\n )}\n aria-hidden={!mobileOpen}\n >\n {/* Backdrop */}\n <div\n className={cn(\n 'absolute inset-0 bg-black/40 transition-opacity',\n mobileOpen ? 'opacity-100' : 'opacity-0'\n )}\n onClick={() => onMobileOpenChange(false)}\n />\n {/* Panel */}\n <div\n className={cn(\n 'absolute left-0 top-0 h-full w-[85%] max-w-[320px] bg-[rgba(245,245,245,0.98)] shadow-xl transition-transform',\n mobileOpen ? 'translate-x-0' : '-translate-x-full'\n )}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-label={mobileAriaLabel}\n >\n <div className=\"flex h-full flex-col\">\n {/* Mobile Header */}\n {header && <div className=\"shrink-0 px-6 pt-10 pb-4\">{header}</div>}\n\n {/* Mobile SubHeader */}\n {subHeader && <div className=\"shrink-0 px-6 pb-4\">{subHeader}</div>}\n\n {/* Mobile Scrollable Content */}\n <div className=\"flex-1 overflow-y-auto px-6 pb-20\">{children}</div>\n\n {/* Mobile Footer */}\n {footer && <div className=\"px-6 py-4\">{footer}</div>}\n </div>\n </div>\n </div>\n )}\n </>\n );\n}\n","import React, { ReactNode } from 'react';\n\nimport { cn } from '@openzeppelin/ui-utils';\n\nexport interface SidebarSectionProps {\n /** Optional section title displayed above the content */\n title?: string;\n /** Content to render within the section */\n children: ReactNode;\n /** Additional CSS classes */\n className?: string;\n /** CSS classes for the title element */\n titleClassName?: string;\n /** Whether this section should grow to fill available space */\n grow?: boolean;\n}\n\n/**\n * A generic sidebar section wrapper with optional title.\n * Used to group related sidebar items together.\n */\nexport function SidebarSection({\n title,\n children,\n className,\n titleClassName,\n grow = false,\n}: SidebarSectionProps): React.ReactElement {\n return (\n <div className={cn('flex flex-col w-full', grow && 'flex-1', className)}>\n {title && (\n <div className={cn('text-[#5e5e5e] text-xs font-semibold leading-4 mb-1', titleClassName)}>\n {title}\n </div>\n )}\n <div className={cn('flex flex-col', grow && 'flex-1 overflow-hidden')}>{children}</div>\n </div>\n );\n}\n","import * as TabsPrimitive from '@radix-ui/react-tabs';\nimport * as React from 'react';\n\nimport { cn } from '@openzeppelin/ui-utils';\n\n/** Tabs container component wrapping Radix UI Tabs Root. */\nfunction Tabs({\n className,\n ...props\n}: React.ComponentProps<typeof TabsPrimitive.Root>): React.ReactElement {\n return (\n <TabsPrimitive.Root\n data-slot=\"tabs\"\n className={cn('flex w-full max-w-full min-w-0 flex-col gap-2 overflow-x-hidden', className)}\n {...props}\n />\n );\n}\n\n/** Tabs list component containing tab triggers. */\nfunction TabsList({\n className,\n ...props\n}: React.ComponentProps<typeof TabsPrimitive.List>): React.ReactElement {\n return (\n <TabsPrimitive.List\n data-slot=\"tabs-list\"\n className={cn(\n 'bg-muted text-muted-foreground flex h-9 w-full max-w-full min-w-0 items-center justify-start rounded-lg p-1 overflow-x-auto overflow-y-hidden flex-nowrap overscroll-x-contain [scrollbar-width:none] [-ms-overflow-style:none] [&::-webkit-scrollbar]:hidden sm:overflow-visible',\n className\n )}\n {...props}\n />\n );\n}\n\n/** Individual tab trigger button. */\nfunction TabsTrigger({\n className,\n ...props\n}: React.ComponentProps<typeof TabsPrimitive.Trigger>): React.ReactElement {\n return (\n <TabsPrimitive.Trigger\n data-slot=\"tabs-trigger\"\n className={cn(\n \"data-[state=active]:bg-background data-[state=active]:text-foreground focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:outline-ring inline-flex flex-1 items-center justify-center gap-1.5 rounded-md px-2 py-1 text-sm font-medium whitespace-nowrap transition-[color,box-shadow] focus-visible:ring-[3px] focus-visible:outline-1 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:shadow-sm [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n className\n )}\n {...props}\n />\n );\n}\n\n/** Tab content panel displayed when its trigger is active. */\nfunction TabsContent({\n className,\n ...props\n}: React.ComponentProps<typeof TabsPrimitive.Content>): React.ReactElement {\n return (\n <TabsPrimitive.Content\n data-slot=\"tabs-content\"\n className={cn('flex-1 outline-none', className)}\n {...props}\n />\n );\n}\n\nexport { Tabs, TabsContent, TabsList, TabsTrigger };\n","import * as React from 'react';\n\nimport { cn } from '@openzeppelin/ui-utils';\n\nexport type TextareaProps = React.TextareaHTMLAttributes<HTMLTextAreaElement>;\n\nconst Textarea = React.forwardRef<HTMLTextAreaElement, TextareaProps>(\n ({ className, ...props }, ref) => {\n return (\n <textarea\n data-slot=\"textarea\"\n className={cn(\n 'border-input bg-background ring-offset-background focus-visible:ring-ring placeholder:text-muted-foreground aria-invalid:ring-destructive/20 aria-invalid:border-destructive dark:aria-invalid:ring-destructive/40 min-h-16 w-full rounded-md border px-3 py-2 text-sm focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:outline-none disabled:cursor-not-allowed disabled:opacity-50',\n className\n )}\n ref={ref}\n {...props}\n />\n );\n }\n);\nTextarea.displayName = 'Textarea';\n\nexport { Textarea };\n","import * as TooltipPrimitive from '@radix-ui/react-tooltip';\nimport * as React from 'react';\n\nimport { cn } from '@openzeppelin/ui-utils';\n\nconst TooltipProvider = TooltipPrimitive.Provider;\n\nconst Tooltip = TooltipPrimitive.Root;\n\nconst TooltipTrigger = TooltipPrimitive.Trigger;\n\nconst TooltipContent = React.forwardRef<\n React.ComponentRef<typeof TooltipPrimitive.Content>,\n React.ComponentPropsWithoutRef<typeof TooltipPrimitive.Content>\n>(({ className, sideOffset = 4, ...props }, ref) => (\n <TooltipPrimitive.Content\n ref={ref}\n sideOffset={sideOffset}\n className={cn(\n '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',\n className\n )}\n {...props}\n />\n));\nTooltipContent.displayName = TooltipPrimitive.Content.displayName;\n\nexport { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger };\n","import { FileText } from 'lucide-react';\nimport React from 'react';\n\nimport { truncateMiddle } from '@openzeppelin/ui-utils';\n\nimport { Button } from './button';\n\ninterface ViewContractStateButtonProps {\n contractAddress: string | null;\n onToggle: () => void;\n}\n\n/**\n * ViewContractStateButton - A button to toggle the contract state widget\n * Shows the contract address in a truncated format\n */\nexport function ViewContractStateButton({\n contractAddress,\n onToggle,\n}: ViewContractStateButtonProps): React.ReactElement | null {\n if (!contractAddress) return null;\n\n return (\n <Button\n variant=\"outline\"\n size=\"sm\"\n className=\"px-3 py-2 h-auto gap-2 items-start justify-start sm:items-center\"\n onClick={onToggle}\n title=\"Show Contract State\"\n >\n <FileText size={16} className=\"shrink-0 self-center\" />\n <span className=\"flex flex-col sm:flex-row sm:items-center text-left leading-tight\">\n <span className=\"text-sm font-medium\">View Contract State</span>\n <span className=\"text-xs text-muted-foreground sm:ml-1\">\n ({truncateMiddle(contractAddress)})\n </span>\n </span>\n </Button>\n );\n}\n","/**\n * Accessibility utilities for form field components\n */\n\n/**\n * Default aria-describedby ID generator based on field ID\n */\nexport function getDescribedById(\n id: string,\n type: 'error' | 'description' | 'counter' = 'error'\n): string {\n return `${id}-${type}`;\n}\n\n/**\n * Interface for accessibility attributes to be applied to form fields\n */\nexport interface AccessibilityProps {\n /**\n * ARIA attributes for accessibility\n */\n 'aria-invalid'?: boolean;\n 'aria-required'?: boolean;\n 'aria-describedby'?: string;\n 'aria-errormessage'?: string;\n 'aria-labelledby'?: string;\n\n /**\n * Indicates if the input is required\n */\n required?: boolean;\n\n /**\n * Indicates if the input is disabled\n */\n disabled?: boolean;\n\n /**\n * Indicates if the input is readonly\n */\n readOnly?: boolean;\n\n /**\n * Tab index for keyboard navigation\n * Use 0 for normal tab order\n * Use -1 to remove from tab order\n */\n tabIndex?: number;\n}\n\n/**\n * Generates accessibility attributes for form fields\n */\nexport function getAccessibilityProps({\n id,\n hasError = false,\n isRequired = false,\n isDisabled = false,\n isReadOnly = false,\n hasHelperText = false,\n hasCharacterCounter = false,\n}: {\n id: string;\n hasError?: boolean;\n isRequired?: boolean;\n isDisabled?: boolean;\n isReadOnly?: boolean;\n hasHelperText?: boolean;\n hasCharacterCounter?: boolean;\n}): AccessibilityProps {\n // Build aria-describedby referencing multiple elements if needed\n const describedByIds: string[] = [];\n\n if (hasError) {\n describedByIds.push(getDescribedById(id, 'error'));\n }\n\n if (hasHelperText) {\n describedByIds.push(getDescribedById(id, 'description'));\n }\n\n if (hasCharacterCounter) {\n describedByIds.push(getDescribedById(id, 'counter'));\n }\n\n return {\n 'aria-invalid': hasError,\n 'aria-required': isRequired,\n 'aria-describedby': describedByIds.length > 0 ? describedByIds.join(' ') : undefined,\n 'aria-errormessage': hasError ? getDescribedById(id, 'error') : undefined,\n required: isRequired,\n disabled: isDisabled,\n readOnly: isReadOnly,\n tabIndex: isDisabled ? -1 : 0,\n };\n}\n\n/**\n * Utility function to handle keyboard events for interactive elements\n * Helps ensure keyboard users can interact with form controls\n */\nexport function handleKeyboardEvent(\n event: React.KeyboardEvent,\n handlers: {\n onEnter?: () => void;\n onSpace?: () => void;\n onEscape?: () => void;\n onArrowUp?: () => void;\n onArrowDown?: () => void;\n onArrowLeft?: () => void;\n onArrowRight?: () => void;\n onTab?: () => void;\n }\n): void {\n switch (event.key) {\n case 'Enter':\n if (handlers.onEnter) {\n event.preventDefault();\n handlers.onEnter();\n }\n break;\n case ' ':\n if (handlers.onSpace) {\n event.preventDefault();\n handlers.onSpace();\n }\n break;\n case 'Escape':\n if (handlers.onEscape) {\n event.preventDefault();\n handlers.onEscape();\n }\n break;\n case 'ArrowUp':\n if (handlers.onArrowUp) {\n event.preventDefault();\n handlers.onArrowUp();\n }\n break;\n case 'ArrowDown':\n if (handlers.onArrowDown) {\n event.preventDefault();\n handlers.onArrowDown();\n }\n break;\n case 'ArrowLeft':\n if (handlers.onArrowLeft) {\n event.preventDefault();\n handlers.onArrowLeft();\n }\n break;\n case 'ArrowRight':\n if (handlers.onArrowRight) {\n event.preventDefault();\n handlers.onArrowRight();\n }\n break;\n case 'Tab':\n if (handlers.onTab) {\n event.preventDefault();\n handlers.onTab();\n }\n break;\n default:\n break;\n }\n}\n\n/**\n * Field focus management utility\n * For managing focus within a field group or complex form component\n */\nexport function createFocusManager(): {\n focusFirstElement: (container: HTMLElement | null) => void;\n focusElementById: (id: string) => void;\n trapFocus: (event: KeyboardEvent, container: HTMLElement | null) => void;\n} {\n return {\n /**\n * Focus the first focusable element within a container\n */\n focusFirstElement(container: HTMLElement | null): void {\n if (!container) return;\n\n const focusable = container.querySelectorAll<HTMLElement>(\n 'button, [href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])'\n );\n\n if (focusable.length > 0) {\n focusable[0].focus();\n }\n },\n\n /**\n * Focus a specific element by ID\n */\n focusElementById(id: string): void {\n const element = document.getElementById(id);\n if (element) {\n element.focus();\n }\n },\n\n /**\n * Trap focus within a container (for modals, dropdowns, etc.)\n */\n trapFocus(event: KeyboardEvent, container: HTMLElement | null): void {\n if (!container || event.key !== 'Tab') return;\n\n const focusable = Array.from(\n container.querySelectorAll<HTMLElement>(\n 'button, [href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])'\n )\n );\n\n if (focusable.length === 0) return;\n\n const firstElement = focusable[0];\n const lastElement = focusable[focusable.length - 1];\n\n if (event.shiftKey && document.activeElement === firstElement) {\n event.preventDefault();\n lastElement.focus();\n } else if (!event.shiftKey && document.activeElement === lastElement) {\n event.preventDefault();\n firstElement.focus();\n }\n },\n };\n}\n\n/**\n * Provides a handler for Escape key to clear input fields\n *\n * @param onChange - Function to call when value changes\n * @param value - Current value of the input\n * @returns A function to handle the Escape key press\n */\nexport function handleEscapeKey(\n onChange: (value: string) => void,\n value: unknown\n): (e: React.KeyboardEvent) => void {\n return (e: React.KeyboardEvent) => {\n if (e.key === 'Escape') {\n e.preventDefault();\n\n // Only reset if there's a value to clear\n if (value) {\n onChange('');\n } else {\n // If already empty, blur the field\n (e.target as HTMLElement).blur();\n }\n }\n };\n}\n\n/**\n * Provides a handler for Space/Enter keys for toggle components (checkboxes, switches)\n *\n * @param onChange - Function to call when value changes\n * @param value - Current value of the input\n * @returns A function to handle the Space/Enter key press\n */\nexport function handleToggleKeys(\n onChange: (value: boolean) => void,\n value: boolean\n): (e: React.KeyboardEvent) => void {\n return (e: React.KeyboardEvent) => {\n if (e.key === ' ' || e.key === 'Enter') {\n e.preventDefault();\n onChange(!value);\n }\n };\n}\n\n/**\n * Provides a handler for arrow keys for numeric inputs\n *\n * @param onChange - Function to call when value changes\n * @param value - Current numeric value\n * @param step - Step amount for increments/decrements\n * @param min - Minimum allowed value (optional)\n * @param max - Maximum allowed value (optional)\n * @returns A function to handle arrow key presses\n */\nexport function handleNumericKeys(\n onChange: (value: number) => void,\n value: number,\n step: number = 1,\n min?: number,\n max?: number\n): (e: React.KeyboardEvent) => void {\n return (e: React.KeyboardEvent) => {\n if (e.key === 'ArrowUp' || e.key === 'ArrowDown') {\n e.preventDefault();\n const direction = e.key === 'ArrowUp' ? 1 : -1;\n let newValue = typeof value === 'number' ? value + step * direction : 0;\n\n // Apply min/max constraints if provided\n if (typeof min === 'number') newValue = Math.max(min, newValue);\n if (typeof max === 'number') newValue = Math.min(max, newValue);\n\n onChange(newValue);\n }\n };\n}\n","/**\n * Shared integer validation patterns for BigInt fields and validation utilities.\n *\n * These patterns ensure consistent validation across the application.\n */\n\n/**\n * Integer validation pattern - requires at least one digit\n * Used for validation to ensure complete integers are entered\n * Matches: -123, 0, 456\n * Does not match: -, abc, 12.3\n */\nexport const INTEGER_PATTERN = /^-?\\d+$/;\n\n/**\n * Integer input pattern - allows partial input during typing\n * Used during input to allow users to type minus sign first\n * Matches: -, -1, 123, (empty string)\n * Does not match: abc, 12.3\n */\nexport const INTEGER_INPUT_PATTERN = /^-?\\d*$/;\n\n/**\n * HTML pattern attribute for integer inputs\n * Must use [0-9] instead of \\d for HTML5 pattern attribute\n */\nexport const INTEGER_HTML_PATTERN = '-?[0-9]*';\n","/**\n * Validation and error handling utilities for form field components\n */\nimport { FieldError } from 'react-hook-form';\n\nimport { FieldValidation, MapEntry } from '@openzeppelin/ui-types';\n\nimport { INTEGER_PATTERN } from './integerValidation';\n\n/**\n * Determines if a field has an error\n */\nexport function hasFieldError(error: FieldError | undefined): boolean {\n return !!error;\n}\n\n/**\n * Gets appropriate error message from field error\n */\nexport function getErrorMessage(error: FieldError | undefined): string | undefined {\n if (!error) return undefined;\n\n return error.message || 'This field is invalid';\n}\n\n/**\n * Formats validation error messages for display\n */\nexport function formatValidationError(\n error: FieldError | undefined,\n fieldName?: string\n): string | undefined {\n if (!error) return undefined;\n\n const defaultMessage = fieldName ? `${fieldName} is invalid` : 'This field is invalid';\n\n return error.message || defaultMessage;\n}\n\n/**\n * Generates common CSS classes for field validation states\n */\nexport function getValidationStateClasses(\n error: FieldError | undefined,\n touched?: boolean\n): string {\n if (error) {\n return 'border-destructive focus:border-destructive focus:ring-destructive/30';\n }\n\n if (touched) {\n return 'border-success focus:border-success focus:ring-success/30';\n }\n\n return '';\n}\n\n/**\n * Helper for handling form validation errors with React Hook Form\n */\nexport function handleValidationError(\n error: FieldError | undefined,\n id: string\n): {\n errorId: string;\n errorMessage: string | undefined;\n hasError: boolean;\n validationClasses: string;\n} {\n const hasError = hasFieldError(error);\n const errorMessage = getErrorMessage(error);\n const errorId = `${id}-error`;\n const validationClasses = getValidationStateClasses(error);\n\n return {\n errorId,\n errorMessage,\n hasError,\n validationClasses,\n };\n}\n\n/**\n * Creates a validation result object for field components\n */\nexport function createValidationResult(\n id: string,\n error: FieldError | undefined,\n touched?: boolean\n): {\n hasError: boolean;\n errorMessage: string | undefined;\n errorId: string;\n validationClasses: string;\n 'aria-invalid': boolean;\n 'aria-errormessage'?: string;\n} {\n const hasError = hasFieldError(error);\n const errorMessage = getErrorMessage(error);\n const errorId = `${id}-error`;\n const validationClasses = getValidationStateClasses(error, touched);\n\n return {\n hasError,\n errorMessage,\n errorId,\n validationClasses,\n 'aria-invalid': hasError,\n 'aria-errormessage': hasError ? errorId : undefined,\n };\n}\n\n/**\n * Generic field validation function that can be used to validate any field type\n * based on common validation criteria\n */\nexport function validateField(value: unknown, validation?: FieldValidation): string | boolean {\n // Return true if no validation rules are provided\n if (!validation) return true;\n\n // Check if required but empty\n if (validation.required && (value === undefined || value === null || value === '')) {\n return typeof validation.required === 'boolean'\n ? 'This field is required'\n : 'This field is required'; // Always return the standard message for required fields\n }\n\n // Skip other validations if value is empty and not required\n if (value === undefined || value === null || value === '') {\n return true;\n }\n\n // Validate string length\n if (typeof value === 'string') {\n if (validation.minLength && value.length < validation.minLength) {\n return `Minimum length is ${validation.minLength} characters`;\n }\n\n if (validation.maxLength && value.length > validation.maxLength) {\n return `Maximum length is ${validation.maxLength} characters`;\n }\n\n // Validate pattern\n if (validation.pattern) {\n const pattern =\n typeof validation.pattern === 'string'\n ? new RegExp(validation.pattern)\n : validation.pattern;\n\n if (!pattern.test(value)) {\n // Provide more specific error message for integer validation\n if (!INTEGER_PATTERN.test(value) && /\\d/.test(value)) {\n return 'Value must be a valid integer (no decimals)';\n }\n return 'Value does not match the required pattern';\n }\n }\n }\n\n // Validate number range\n if (typeof value === 'number' || (typeof value === 'string' && !isNaN(Number(value)))) {\n const numValue = typeof value === 'number' ? value : Number(value);\n\n if (validation.min !== undefined && numValue < validation.min) {\n return `Minimum value is ${validation.min}`;\n }\n\n if (validation.max !== undefined && numValue > validation.max) {\n return `Maximum value is ${validation.max}`;\n }\n }\n\n // Check field conditions if defined\n if (validation.conditions && validation.conditions.length > 0) {\n // Note: This would need the current form values to evaluate conditions\n // This is intended to be used with React Hook Form's validation context\n // Implementation would depend on how conditions are evaluated in the form context\n }\n\n // If all validations pass\n return true;\n}\n\n/**\n * Map validation utilities\n */\n\n/**\n * Checks if a map entry at the given index has a duplicate key\n * @param entries - Array of map entries\n * @param currentIndex - Index of the entry to check\n * @returns true if the key at currentIndex is duplicated elsewhere in the array\n */\nexport function isDuplicateMapKey(entries: MapEntry[], currentIndex: number): boolean {\n if (!Array.isArray(entries) || entries.length <= 1) {\n return false;\n }\n\n const currentKeyValue = entries[currentIndex]?.key;\n\n // Don't consider empty keys as duplicates\n if (!currentKeyValue || currentKeyValue === '') {\n return false;\n }\n\n // Prefer strict equality to avoid cross-type false positives (e.g., 123 vs \"123\")\n // Treat empty string as non-duplicate as above.\n return entries.some((entry: MapEntry, i: number) => {\n if (i === currentIndex) return false;\n const key = entry?.key;\n if (key === '') return false;\n // If both are strings, compare strings\n if (typeof key === 'string' && typeof currentKeyValue === 'string') {\n return key === currentKeyValue;\n }\n // If both are numbers, compare numbers\n if (typeof key === 'number' && typeof currentKeyValue === 'number') {\n return Number.isNaN(key) ? Number.isNaN(currentKeyValue) : key === currentKeyValue;\n }\n // If both are booleans\n if (typeof key === 'boolean' && typeof currentKeyValue === 'boolean') {\n return key === currentKeyValue;\n }\n // For objects (including dates) fall back to reference equality\n if (\n typeof key === 'object' &&\n key !== null &&\n typeof currentKeyValue === 'object' &&\n currentKeyValue !== null\n ) {\n return key === currentKeyValue;\n }\n // Otherwise, consider different types as different keys\n return false;\n });\n}\n\n/**\n * Validates an array of map entries for duplicate keys\n * @param entries - Array of map entries to validate\n * @returns Validation error message if duplicates found, otherwise undefined\n */\nexport function validateMapEntries(entries: MapEntry[]): string | undefined {\n if (!Array.isArray(entries) || entries.length <= 1) {\n return undefined;\n }\n\n const keys = entries\n .map((entry) => entry?.key)\n .filter((key) => key !== undefined && key !== null && key !== '');\n\n const keyStrings = keys.map((key) => String(key));\n const uniqueKeyStrings = new Set(keyStrings);\n\n if (keyStrings.length !== uniqueKeyStrings.size) {\n return 'Duplicate keys are not allowed';\n }\n\n return undefined;\n}\n","import React from 'react';\nimport { FieldError } from 'react-hook-form';\n\nimport { getErrorMessage } from './validation';\n\ninterface ErrorMessageProps {\n /**\n * The error object from React Hook Form\n */\n error?: FieldError;\n\n /**\n * The ID of the error message for aria-errormessage references\n */\n id: string;\n\n /**\n * Optional custom error message to display instead of the error from React Hook Form\n */\n message?: string;\n\n /**\n * Optional additional CSS classes\n */\n className?: string;\n}\n\n/**\n * Displays validation error messages for form fields\n */\nexport function ErrorMessage({\n error,\n id,\n message,\n className = '',\n}: ErrorMessageProps): React.ReactElement | null {\n const errorMessage = message || getErrorMessage(error);\n\n if (!errorMessage) return null;\n\n return (\n <div id={id} className={`text-destructive mt-1 text-sm ${className}`} role=\"alert\">\n {errorMessage}\n </div>\n );\n}\n","/**\n * Layout utility functions for form components\n */\n\n/**\n * Helper function to get width classes based on the field width\n */\nexport function getWidthClasses(width: 'full' | 'half' | 'third'): string {\n switch (width) {\n case 'half':\n return 'form-field-half';\n case 'third':\n return 'form-field-third';\n case 'full':\n default:\n return 'form-field-full';\n }\n}\n","import React from 'react';\nimport { Controller, FieldValues } from 'react-hook-form';\n\nimport type { ContractAdapter } from '@openzeppelin/ui-types';\n\nimport { Input } from '../ui/input';\nimport { Label } from '../ui/label';\nimport { BaseFieldProps } from './BaseField';\nimport {\n ErrorMessage,\n getAccessibilityProps,\n getValidationStateClasses,\n handleEscapeKey,\n validateField,\n} from './utils';\n\ninterface AddressFieldProps<TFieldValues extends FieldValues = FieldValues>\n extends BaseFieldProps<TFieldValues> {\n adapter?: ContractAdapter;\n}\n\n/**\n * Address input field component specifically designed for blockchain addresses via React Hook Form integration.\n *\n * Architecture flow:\n * 1. Form schemas are generated from contract functions using adapters\n * 2. TransactionForm renders the overall form structure with React Hook Form\n * 3. DynamicFormField selects the appropriate field component (like AddressField) based on field type\n * 4. BaseField provides consistent layout and hook form integration\n * 5. This component handles blockchain address-specific rendering and validation using the passed adapter\n *\n * The component includes:\n * - Integration with React Hook Form\n * - Blockchain address validation through adapter-provided custom validation\n * - Automatic error handling and reporting\n * - Chain-agnostic design (validation handled by adapters)\n * - Full accessibility support with ARIA attributes\n * - Keyboard navigation\n */\nexport function AddressField<TFieldValues extends FieldValues = FieldValues>({\n id,\n label,\n placeholder,\n helperText,\n control,\n name,\n width = 'full',\n validation,\n adapter,\n readOnly,\n}: AddressFieldProps<TFieldValues>): React.ReactElement {\n const isRequired = !!validation?.required;\n const errorId = `${id}-error`;\n const descriptionId = `${id}-description`;\n\n return (\n <div\n className={`flex flex-col gap-2 ${width === 'full' ? 'w-full' : width === 'half' ? 'w-1/2' : 'w-1/3'}`}\n >\n {label && (\n <Label htmlFor={id}>\n {label} {isRequired && <span className=\"text-destructive\">*</span>}\n </Label>\n )}\n\n <Controller\n control={control}\n name={name}\n rules={{\n validate: (value) => {\n // Check required field explicitly first\n if (value === undefined || value === null || value === '') {\n return validation?.required ? 'This field is required' : true;\n }\n\n // Perform standard validations (min, max, pattern, etc.) if they exist\n // Using the existing validateField utility for this part\n const standardValidationResult = validateField(value, validation);\n if (standardValidationResult !== true) {\n return standardValidationResult;\n }\n\n // Perform adapter-specific address validation if adapter exists\n if (adapter && typeof value === 'string') {\n if (!adapter.isValidAddress(value)) {\n return 'Invalid address format for the selected chain';\n }\n }\n\n // If all checks pass\n return true;\n },\n }}\n disabled={readOnly}\n render={({ fieldState: { error, isTouched }, field }) => {\n const hasError = !!error;\n const shouldShowError = hasError && isTouched;\n const validationClasses = getValidationStateClasses(error, isTouched);\n\n // Safely extract the pattern error message. The `pattern` validation rule can be either a\n // RegExp object or an object with a `value` (RegExp) and a `message` (string). This\n // type guard ensures we only try to access `.message` on the correct object type.\n const patternErrorMessage =\n validation?.pattern &&\n typeof validation.pattern === 'object' &&\n 'message' in validation.pattern\n ? (validation.pattern.message as string)\n : undefined;\n\n // Handle input change with validation\n const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>): void => {\n const value = e.target.value;\n field.onChange(value);\n // Note: Validation happens naturally when user leaves the field\n // No need to trigger it programmatically on every change\n };\n\n // Add keyboard accessibility for clearing the field with Escape\n const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>): void => {\n if (e.key === 'Escape') {\n handleEscapeKey(field.onChange, field.value)(e);\n // Note: Validation happens naturally when user leaves the field\n // No need to trigger it programmatically\n }\n };\n\n // Get accessibility attributes\n const accessibilityProps = getAccessibilityProps({\n id,\n hasError,\n isRequired,\n hasHelperText: !!helperText,\n });\n\n return (\n <>\n <Input\n {...field}\n id={id}\n placeholder={placeholder || '0x...'}\n className={validationClasses}\n onChange={handleInputChange}\n onKeyDown={handleKeyDown}\n data-slot=\"input\"\n value={field.value ?? ''}\n {...accessibilityProps}\n aria-describedby={`${helperText ? descriptionId : ''} ${hasError ? errorId : ''}`}\n disabled={readOnly}\n />\n\n {/* Display helper text */}\n {helperText && (\n <div id={descriptionId} className=\"text-muted-foreground text-sm\">\n {helperText}\n </div>\n )}\n\n {/* Display error message */}\n <ErrorMessage\n error={error}\n id={errorId}\n message={shouldShowError ? error?.message || patternErrorMessage : undefined}\n />\n </>\n );\n }}\n />\n </div>\n );\n}\n\n// Set displayName manually for better debugging\nAddressField.displayName = 'AddressField';\n","import React from 'react';\nimport { Controller, FieldValues } from 'react-hook-form';\n\nimport { Input } from '../ui/input';\nimport { Label } from '../ui/label';\nimport { BaseFieldProps } from './BaseField';\nimport {\n ErrorMessage,\n getAccessibilityProps,\n getValidationStateClasses,\n handleEscapeKey,\n handleNumericKeys,\n} from './utils';\n\n/**\n * AmountField component properties\n */\nexport interface AmountFieldProps<TFieldValues extends FieldValues = FieldValues>\n extends BaseFieldProps<TFieldValues> {\n /**\n * Minimum value validation\n */\n min?: number;\n\n /**\n * Maximum value validation\n */\n max?: number;\n\n /**\n * Step value for increment/decrement\n */\n step?: number;\n\n /**\n * Number of decimal places to allow\n */\n decimals?: number;\n\n /**\n * Currency/token symbol to display\n */\n symbol?: string;\n\n /**\n * Position of the symbol (before or after the amount)\n */\n symbolPosition?: 'prefix' | 'suffix';\n\n /**\n * Custom validation function for amount values\n */\n validateAmount?: (value: number) => boolean | string;\n}\n\n/**\n * Amount input field component specifically designed for currency/token amounts with React Hook Form integration.\n *\n * Architecture flow:\n * 1. Form schemas are generated from contract functions using adapters\n * 2. TransactionForm renders the overall form structure with React Hook Form\n * 3. DynamicFormField selects the appropriate field component based on field type\n * 4. BaseField provides consistent layout and hook form integration\n * 5. This component handles amount-specific rendering and validation\n *\n * The component includes:\n * - Integration with React Hook Form\n * - Support for currency/token symbols\n * - Numeric-specific validations (min, max, decimals)\n * - Customizable validation through adapter integration\n * - Automatic error handling and reporting\n * - Full accessibility support with ARIA attributes\n * - Keyboard navigation with arrow keys for numeric increment/decrement\n */\nexport function AmountField<TFieldValues extends FieldValues = FieldValues>({\n id,\n label,\n placeholder,\n helperText,\n control,\n name,\n width = 'full',\n validation,\n min,\n max,\n step = 0.01,\n decimals = 2,\n symbol = '',\n symbolPosition = 'suffix',\n validateAmount,\n}: AmountFieldProps<TFieldValues>): React.ReactElement {\n const isRequired = !!validation?.required;\n const errorId = `${id}-error`;\n const descriptionId = `${id}-description`;\n\n // Formatter for displaying currency/token values\n const formatCurrency = (value: string | number): string => {\n if (value === '' || value === undefined || value === null) return '';\n\n const numValue = typeof value === 'string' ? parseFloat(value) : value;\n if (isNaN(numValue)) return '';\n\n return numValue.toFixed(decimals);\n };\n\n // Parse string input to number\n const parseAmount = (value: string): number => {\n const parsed = parseFloat(value);\n return isNaN(parsed) ? 0 : parsed;\n };\n\n return (\n <div\n className={`flex flex-col gap-2 ${width === 'full' ? 'w-full' : width === 'half' ? 'w-1/2' : 'w-1/3'}`}\n >\n {label && (\n <Label htmlFor={id}>\n {label} {isRequired && <span className=\"text-destructive\">*</span>}\n </Label>\n )}\n\n <Controller\n control={control}\n name={name}\n rules={{\n validate: (value) => {\n // Convert to number for validation\n const numValue = typeof value === 'string' ? parseFloat(value) : value;\n\n // Handle required validation explicitly\n if (value === undefined || value === null || value === '' || isNaN(numValue)) {\n return validation?.required ? 'This field is required' : true;\n }\n\n // Validate min/max constraints\n if (min !== undefined && numValue < min) {\n return `Value must be at least ${min}`;\n }\n\n if (max !== undefined && numValue > max) {\n return `Value must be at most ${max}`;\n }\n\n // Run custom validation if provided\n if (validateAmount && !isNaN(numValue)) {\n const validation = validateAmount(numValue);\n if (validation !== true && typeof validation === 'string') {\n return validation;\n }\n }\n\n return true;\n },\n }}\n render={({ field, fieldState: { error, isTouched } }) => {\n const hasError = !!error?.message;\n const shouldShowError = hasError && isTouched;\n const validationClasses = getValidationStateClasses(error, isTouched);\n\n // Get accessibility attributes\n const accessibilityProps = getAccessibilityProps({\n id,\n hasError,\n isRequired,\n hasHelperText: !!helperText,\n });\n\n // Format display value\n const displayValue = field.value !== undefined && field.value !== null ? field.value : '';\n\n return (\n <>\n <div className=\"relative\">\n {symbol && symbolPosition === 'prefix' && (\n <span className=\"absolute top-1/2 left-3 -translate-y-1/2 text-gray-500\">\n {symbol}\n </span>\n )}\n\n <Input\n {...field}\n id={id}\n type=\"text\"\n inputMode=\"decimal\"\n placeholder={placeholder}\n value={displayValue}\n className={`${validationClasses} ${\n symbol && symbolPosition === 'prefix' ? 'pl-8' : ''\n } ${symbol && symbolPosition === 'suffix' ? 'pr-8' : ''}`}\n data-slot=\"input\"\n {...accessibilityProps}\n aria-describedby={`${helperText ? descriptionId : ''} ${hasError ? errorId : ''}`}\n onChange={(e) => {\n // Allow numeric values and decimal point\n const value = e.target.value;\n if (value === '' || /^-?\\d*\\.?\\d*$/.test(value)) {\n field.onChange(value);\n }\n }}\n onBlur={(e) => {\n // Format on blur\n if (e.target.value) {\n const parsed = parseFloat(e.target.value);\n if (!isNaN(parsed)) {\n field.onChange(formatCurrency(parsed));\n }\n }\n if (field.onBlur) {\n field.onBlur();\n }\n }}\n onKeyDown={(e) => {\n // Handle Escape key\n if (e.key === 'Escape') {\n handleEscapeKey((value) => {\n field.onChange(value === '' ? null : value);\n }, field.value)(e);\n return;\n }\n\n // Handle arrow keys for increment/decrement\n if (e.key === 'ArrowUp' || e.key === 'ArrowDown') {\n handleNumericKeys(\n (newValue) => {\n field.onChange(formatCurrency(newValue));\n },\n parseAmount(field.value || ''),\n step,\n min,\n max\n )(e);\n }\n }}\n />\n\n {symbol && symbolPosition === 'suffix' && (\n <span className=\"absolute top-1/2 right-3 -translate-y-1/2 text-gray-500\">\n {symbol}\n </span>\n )}\n </div>\n\n {/* Display helper text */}\n {helperText && (\n <div id={descriptionId} className=\"text-muted-foreground text-sm\">\n {helperText}\n </div>\n )}\n\n {/* Display error message */}\n <ErrorMessage\n error={error}\n id={errorId}\n message={shouldShowError ? error?.message : undefined}\n />\n </>\n );\n }}\n />\n </div>\n );\n}\n\n// Set displayName manually for better debugging\nAmountField.displayName = 'AmountField';\n","import { GripVertical, Plus, X } from 'lucide-react';\nimport React from 'react';\nimport { Controller, FieldValues, useFieldArray, useFormContext, useWatch } from 'react-hook-form';\n\nimport type { FormFieldType } from '@openzeppelin/ui-types';\n\nimport { Button } from '../ui/button';\nimport { Label } from '../ui/label';\nimport { BaseFieldProps } from './BaseField';\nimport { ErrorMessage, getAccessibilityProps } from './utils';\n\n/**\n * ArrayField component properties\n */\nexport interface ArrayFieldProps<TFieldValues extends FieldValues = FieldValues>\n extends BaseFieldProps<TFieldValues> {\n /**\n * The type of elements in the array (e.g., 'text', 'number', 'blockchain-address')\n */\n elementType?: FormFieldType['type']; // TODO: Consider if a more specific subset of FieldType is relevant here if this component only renders simple types directly.\n\n /**\n * Minimum number of array elements\n */\n minItems?: number;\n\n /**\n * Maximum number of array elements\n */\n maxItems?: number;\n\n /**\n * Base configuration for array element fields.\n * This allows specifying common properties like placeholder, helperText, or specific validation\n * for each element in the array.\n */\n // TODO: Refine elementFieldConfig type. `id` and `name` are derived internally.\n // Consider a type like `Omit<Partial<FormFieldType>, 'id' | 'name'> & { defaultValue?: unknown }`\n // to allow specifying a more complex default value for appended items.\n elementFieldConfig?: Partial<FormFieldType>;\n\n /**\n * Render function for array elements.\n * This is crucial for rendering complex elements or integrating custom field components.\n */\n // TODO: Explore a fallback rendering mechanism if `renderElement` is not provided,\n // especially if `elementType` is a known simple type (e.g., 'text', 'number').\n // This could make the component more self-contained for basic array types.\n renderElement?: (field: FormFieldType, index: number) => React.ReactNode;\n}\n\n/**\n * Array input field component specifically designed for React Hook Form integration.\n *\n * This component provides a dynamic interface for managing array inputs with:\n * - Add/remove functionality for array items\n * - Validation for array length constraints\n * - Integration with existing field components for array elements\n * - Full accessibility support\n *\n * The component reuses existing field components (TextField, NumberField, etc.)\n * for individual array elements, maintaining consistency across the form system.\n *\n * Why the extra guards and synchronization exist (post-mortem/rationale):\n * - In certain runtime states (StrictMode double-invocation, preview remounts, state rehydration\n * from storage), React Hook Form's useFieldArray may not synchronously reflect an `append()`\n * or `remove()` call in the immediately subsequent read (e.g., reading `fields.length` or\n * `getValues(name)` right after the call). This resulted in newly added items (especially\n * falsy defaults like 0/false) appearing briefly and then disappearing, or remove operations\n * not updating the UI.\n * - To make array operations deterministic and resilient across flows (preview form with\n * FormProvider and the wizard's \"Use Hardcoded Value\" without a provider), we:\n * 1) Read a stable snapshot of the array value BEFORE `append()` and, if the immediate\n * post-append read doesn't reflect the addition, we coerce the state to\n * \"previousSnapshot + newValue\" via `setValue` (when context exists) or `replace`.\n * 2) Avoid `remove()` race conditions by always computing the new array via filter and\n * applying it with `replace`, which proved to be the most consistent across contexts.\n * 3) Keep `fields` in sync with the watched array value using a guarded `replace` in an effect.\n * A ref flag (`isReplacingRef`) prevents infinite loops when we ourselves are driving\n * the `replace`.\n * 4) Use optional chaining for form context (`formContext?.control`, `formContext?.getValues`,\n * `formContext?.setValue`) so the component works with either an inherited FormProvider or\n * an explicit `control` prop.\n * 5) Use `queueMicrotask` to reset the guard flag after our `replace` has been scheduled,\n * avoiding an extra timer tick while ensuring the effect observes the final state.\n *\n * Guarantees:\n * - Operations are idempotent: the fallback only runs when the immediate read does not reflect\n * the intended state, so we don't double-append/remove.\n * - Works both with and without FormProvider (preview vs wizard) due to context-agnostic state\n * reads and `replace` fallback.\n */\nexport function ArrayField<TFieldValues extends FieldValues = FieldValues>({\n id,\n label,\n helperText,\n control,\n name,\n width = 'full',\n validation,\n elementType = 'text',\n minItems = 0,\n maxItems,\n elementFieldConfig,\n renderElement,\n readOnly,\n}: ArrayFieldProps<TFieldValues>): React.ReactElement {\n const isRequired = !!validation?.required;\n const errorId = `${id}-error`;\n const descriptionId = `${id}-description`;\n\n // Get form context for nested field registration (may be absent in some builder flows)\n const formContext = useFormContext();\n\n // Use useFieldArray for dynamic array management\n const { fields, append, replace } = useFieldArray({\n control: control || formContext?.control,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n name: name as any, // Type assertion needed due to generic constraints\n // TODO: Investigate if stricter typing for `name` can be achieved to avoid `as any`\n // with react-hook-form's useFieldArray and deeply nested field names.\n });\n\n // Watch current array value in a context-agnostic way (works with provided control)\n const rawWatchedArray = useWatch({ control: control || formContext?.control, name }) as\n | unknown[]\n | undefined;\n const watchedArrayValue = React.useMemo<unknown[]>(() => {\n return Array.isArray(rawWatchedArray) ? rawWatchedArray : [];\n }, [rawWatchedArray]);\n\n // Ensure field array is synchronized with current value length on mount/reset\n // Keep field array synchronized with watched values, but prevent infinite loops\n const isReplacingRef = React.useRef(false);\n React.useEffect(() => {\n if (isReplacingRef.current) {\n // Skip sync if we're in the middle of a replace operation\n return;\n }\n\n if (Array.isArray(watchedArrayValue) && fields.length !== watchedArrayValue.length) {\n isReplacingRef.current = true;\n replace(watchedArrayValue as unknown as never);\n\n // Reset the flag in a microtask to allow the replace to complete without a timer tick\n queueMicrotask(() => {\n isReplacingRef.current = false;\n });\n }\n }, [fields.length, watchedArrayValue, replace]);\n\n // Note: Structural changes are observed via useWatch and the sync effect above; no additional tracking needed here.\n\n // Handle removing an array item with fallback for stale reads\n const handleRemoveItem = (index: number): void => {\n const valuesBeforeRemove = Array.isArray(watchedArrayValue)\n ? (watchedArrayValue as unknown[])\n : ([] as unknown[]);\n\n // Always use the fallback approach for remove to ensure consistency\n const updatedArray = valuesBeforeRemove.filter((_, i) => i !== index);\n\n // Set flag to prevent sync loop during manual replace\n isReplacingRef.current = true;\n replace(updatedArray as unknown as never);\n\n // Reset flag after operation\n queueMicrotask(() => {\n isReplacingRef.current = false;\n });\n };\n\n // Handle adding new array item\n const handleAddItem = (): void => {\n // Determine default value based on element type\n // TODO: Enhance default value generation.\n // 1. Allow `elementFieldConfig.defaultValue` to override this basic logic.\n // 2. For 'object' or 'array-object' elementType (if supported directly later),\n // this would need to be more sophisticated (e.g., an empty object/array).\n // 3. Consider a more generic `getDefaultValueByFieldType` utility if not already used/available.\n const defaultValue =\n elementFieldConfig?.defaultValue !== undefined\n ? elementFieldConfig.defaultValue\n : elementType === 'number' || elementType === 'amount'\n ? 0\n : elementType === 'checkbox'\n ? false\n : ''; // Default for text, address, etc.\n\n // Background and rationale:\n // In certain runtime states (e.g., preview remounts, incidental resets, StrictMode double-invocations),\n // an immediate read right after useFieldArray.append(...) can be stale and still reflect the\n // pre-append array. This manifested as a user-visible bug where adding an item (notably value 0)\n // either did nothing or briefly appeared and then disappeared.\n //\n // To make the operation deterministic, we snapshot the array BEFORE calling append and then\n // verify that the length actually increased. If not, we force-set the array using the snapshot\n // plus the new value. This is safe and idempotent because it only runs when the immediate read\n // did not reflect the append; it does not double-append.\n\n // Set flag to prevent sync interference during add operation\n isReplacingRef.current = true;\n\n const fieldsBeforeAppend = fields.length;\n const valuesBeforeAppend = Array.isArray(watchedArrayValue)\n ? (watchedArrayValue as unknown[])\n : ([] as unknown[]);\n\n append(defaultValue as FieldValues[typeof name]);\n\n // Verify append actually reflected in form state; if not, force set\n const afterAppendFieldsCount =\n (formContext?.getValues?.(name) as unknown[] | undefined)?.length ?? fields.length;\n\n // Fallback: if the immediate read did not reflect the append, coerce to\n // \"previous snapshot + new value\" so the UI consistently renders the new item.\n if (afterAppendFieldsCount <= fieldsBeforeAppend) {\n const baseArray = Array.isArray(valuesBeforeAppend)\n ? (valuesBeforeAppend as unknown[])\n : ([] as unknown[]);\n const coercedArray = [...baseArray, defaultValue] as unknown[];\n\n if (formContext?.setValue) {\n formContext.setValue(name as never, coercedArray as never, {\n shouldDirty: true,\n shouldTouch: true,\n });\n } else {\n // No form context (e.g., builder hardcoded flow). Use useFieldArray.replace to force state.\n replace(coercedArray as unknown as never);\n }\n }\n\n // Reset flag after operation completes\n queueMicrotask(() => {\n isReplacingRef.current = false;\n });\n };\n\n // Check if we can add more items\n const canAddMore = !maxItems || fields.length < maxItems;\n\n // Check if we can remove items\n const canRemove = fields.length > minItems;\n\n // TODO: For future enhancement, consider adding drag-and-drop reordering functionality for array items.\n // The GripVertical icon hints at this, but implementation would require additional libraries/logic.\n\n return (\n <Controller\n control={control || formContext?.control}\n name={name}\n rules={{\n // TODO: Consider if custom validation functions passed via `validation.validate` prop\n // should also be callable here, in addition to these built-in length checks.\n validate: (value) => {\n // Validate array constraints\n if (validation?.required && (!Array.isArray(value) || value.length === 0)) {\n return 'At least one item is required';\n }\n\n if (minItems && Array.isArray(value) && value.length < minItems) {\n return `Minimum ${minItems} item${minItems > 1 ? 's' : ''} required`;\n }\n\n if (maxItems && Array.isArray(value) && value.length > maxItems) {\n return `Maximum ${maxItems} item${maxItems > 1 ? 's' : ''} allowed`;\n }\n\n return true;\n },\n }}\n render={({ fieldState: { error } }) => {\n const hasError = !!error;\n\n // Get accessibility attributes\n const accessibilityProps = getAccessibilityProps({\n id,\n hasError,\n isRequired,\n hasHelperText: !!helperText,\n });\n // TODO: Review aria-controls/aria-labelledby for the \"Add Item\" button and the list of items for improved accessibility.\n\n return (\n <div\n className={`flex flex-col gap-4 ${width === 'full' ? 'w-full' : width === 'half' ? 'w-1/2' : 'w-1/3'}`}\n {...accessibilityProps}\n aria-describedby={`${helperText ? descriptionId : ''} ${hasError ? errorId : ''}`}\n >\n {/* Label */}\n {label && (\n <div className=\"flex items-center justify-between\">\n <Label htmlFor={id}>\n {label} {isRequired && <span className=\"text-destructive\">*</span>}\n </Label>\n </div>\n )}\n\n {/* Array items */}\n <div className=\"space-y-3\">\n {fields.length === 0 ? (\n <div className=\"text-muted-foreground text-sm py-4 text-center border border-dashed rounded-md\">\n No items added yet. Click “Add Item” to begin.\n </div>\n ) : (\n fields.map((field, index) => {\n // Create field configuration for array element\n // Spread elementFieldConfig first to preserve all properties (including enumMetadata, components)\n const elementField: FormFieldType = {\n ...elementFieldConfig, // Include all props from config (enumMetadata, components, etc.)\n id: field.id, // Use RHF field.id for stable, unique keys per item\n name: `${name}.${index}`, // RHF name for the element\n label: elementFieldConfig?.label || '', // Label for the element's field (can be empty if not desired)\n type: elementFieldConfig?.type || elementType, // Prefer elementFieldConfig.type if available\n validation: elementFieldConfig?.validation || {},\n placeholder: elementFieldConfig?.placeholder,\n helperText: elementFieldConfig?.helperText,\n width: 'full', // Typically, elements take full width within their row\n readOnly: elementFieldConfig?.readOnly ?? readOnly, // Inherit readOnly from parent\n };\n\n return (\n <div key={field.id} className=\"flex gap-2 items-center\">\n <div className=\"flex items-center\">\n {/* TODO: The GripVertical icon is purely visual currently.\n If drag-and-drop is implemented, this would be the drag handle.\n Ensure it has appropriate ARIA attributes if it becomes interactive. */}\n <GripVertical className=\"size-4 text-muted-foreground\" />\n </div>\n <div className=\"flex-1\">\n {renderElement ? (\n renderElement(elementField, index)\n ) : (\n // This fallback is okay, but a more robust solution might attempt to\n // render a default UI field based on `elementType` if it's a known simple type.\n <div className=\"text-sm text-muted-foreground\">\n Field type “{elementType}” requires a render function\n </div>\n )}\n </div>\n {!readOnly && canRemove && (\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n onClick={() => handleRemoveItem(index)}\n className=\"size-8 p-0\"\n aria-label={`Remove item ${index + 1}`}\n >\n <X className=\"size-4\" />\n </Button>\n )}\n </div>\n );\n })\n )}\n </div>\n\n {/* Add Item button */}\n {!readOnly && canAddMore && (\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n onClick={handleAddItem}\n className=\"gap-1 w-full sm:w-auto\"\n // TODO: Add aria-live region or other announcement for screen readers when an item is added/removed.\n >\n <Plus className=\"size-3\" />\n Add Item\n </Button>\n )}\n\n {/* Helper text */}\n {helperText && (\n <div id={descriptionId} className=\"text-muted-foreground text-sm\">\n {helperText}\n </div>\n )}\n\n {/* Error message */}\n <ErrorMessage error={error} id={errorId} />\n </div>\n );\n }}\n />\n );\n}\n\n// Set display name for debugging\nArrayField.displayName = 'ArrayField';\n","import { ChevronDown, ChevronRight, GripVertical, Plus, X } from 'lucide-react';\nimport React from 'react';\nimport { Controller, FieldValues, useFieldArray, useFormContext, useWatch } from 'react-hook-form';\n\nimport type {\n ContractAdapter,\n ContractSchema,\n FormFieldType,\n FunctionParameter,\n} from '@openzeppelin/ui-types';\n\nimport { Button } from '../ui/button';\nimport { Card } from '../ui/card';\nimport { Label } from '../ui/label';\nimport { BaseFieldProps } from './BaseField';\nimport { ErrorMessage, getAccessibilityProps } from './utils';\n\n/**\n * ArrayObjectField component properties\n */\nexport interface ArrayObjectFieldProps<TFieldValues extends FieldValues = FieldValues>\n extends BaseFieldProps<TFieldValues> {\n /**\n * The components/properties of each object in the array.\n * Defines the schema for the nested fields within each object item.\n */\n components?: FunctionParameter[]; // TODO: As above, review type for `components`.\n\n /**\n * Minimum number of array elements\n */\n minItems?: number;\n\n /**\n * Maximum number of array elements\n */\n maxItems?: number;\n\n /**\n * Render function for object properties.\n * This function is responsible for rendering each individual property\n * of an object within an array item.\n */\n // TODO: Explore a fallback rendering mechanism if `renderProperty` is not provided,\n // for known simple property types.\n renderProperty?: (\n field: FormFieldType,\n itemIndex: number,\n propertyName: string\n ) => React.ReactNode;\n\n /**\n * Whether items should be collapsible.\n * Useful for managing UI complexity when objects have many properties.\n */\n collapsible?: boolean;\n\n /**\n * Whether items should start collapsed.\n */\n defaultCollapsed?: boolean;\n\n /**\n * The adapter for chain-specific type mapping.\n * Essential for correctly determining field types for object properties.\n */\n adapter?: ContractAdapter;\n\n /**\n * Optional contract schema to enrich nested field generation.\n */\n contractSchema?: ContractSchema;\n}\n\n/**\n * Array of objects input field component specifically designed for React Hook Form integration.\n *\n * This component provides a dynamic interface for managing arrays of composite objects with:\n * - Add/remove functionality for array items\n * - Structured rendering of object properties within each array item\n * - Collapsible items for better UX with complex objects\n * - Validation for array constraints and object properties (though individual property validation is largely via rendered component)\n * - Full accessibility support\n *\n * The component combines the functionality of ArrayField and ObjectField to handle\n * complex nested data structures commonly found in blockchain contracts.\n */\nexport function ArrayObjectField<TFieldValues extends FieldValues = FieldValues>({\n id,\n label,\n helperText,\n control,\n name,\n width = 'full',\n validation,\n components = [],\n minItems = 0,\n maxItems,\n renderProperty,\n collapsible = true,\n defaultCollapsed = false,\n readOnly,\n adapter,\n contractSchema,\n}: ArrayObjectFieldProps<TFieldValues>): React.ReactElement {\n const isRequired = !!validation?.required;\n const errorId = `${id}-error`;\n const descriptionId = `${id}-description`;\n\n // Get form context for nested field registration\n const formContext = useFormContext();\n const effectiveControl = control || formContext.control;\n\n // Use useFieldArray for dynamic array management\n const { fields, append, remove } = useFieldArray({\n control: effectiveControl,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n name: name as any, // Type assertion needed due to generic constraints\n // TODO: Investigate if stricter typing for `name` can be achieved here.\n });\n\n // Track collapsed state for each item\n const [collapsedItems, setCollapsedItems] = React.useState<Record<string, boolean>>(() => {\n // TODO: Initialize collapsedItems based on `fields` from useFieldArray if `defaultCollapsed`\n // needs to apply to dynamically added items after initial render.\n // Current initialization only covers items present on first render.\n // This might require a useEffect hook that syncs with `fields`.\n const initial: Record<string, boolean> = {};\n fields.forEach((field) => {\n initial[field.id] = defaultCollapsed;\n });\n return initial;\n });\n\n // Handle adding new array item\n const handleAddItem = (): void => {\n // Create default object based on components\n const defaultObject: Record<string, unknown> = {};\n components.forEach((component) => {\n // TODO: This default value logic is extensive.\n // 1. Consider moving to a utility function `generateDefaultObject(components: FunctionParameter[]): Record<string, unknown>`.\n // 2. For nested 'tuple' (objects), recursively call this utility to generate deeply nested default structures.\n // Currently, `defaultObject[component.name] = {};` is a shallow empty object.\n // 3. Ensure consistency with any default value generation used elsewhere (e.g., in FormGenerator or core).\n if (component.type.includes('bool')) {\n defaultObject[component.name] = false;\n } else if (component.type.includes('int') || component.type.includes('uint')) {\n defaultObject[component.name] = 0; // Or perhaps '' to align with NumberField's initial controlled state?\n } else if (component.type.includes('[]')) {\n // Array types\n defaultObject[component.name] = [];\n } else if (component.type.startsWith('tuple')) {\n // Object/tuple types\n defaultObject[component.name] = {}; // TODO: Recursive default generation for nested tuples.\n } else {\n // Default for string and other types\n defaultObject[component.name] = '';\n }\n });\n\n // TODO: RHF's `append` type for nested field arrays is complex. `defaultObject` is Record<string, unknown>.\n // Casting to `any` here is a pragmatic approach if precisely matching RHF's expected generic type\n // (e.g., FieldArray<TFieldValues, TFieldName>[number]) proves too difficult for this dynamically built object.\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n append(defaultObject as any);\n };\n\n // Toggle collapsed state for an item\n const toggleCollapsed = (fieldId: string): void => {\n setCollapsedItems((prev) => ({\n ...prev,\n [fieldId]: !prev[fieldId],\n }));\n };\n\n // Check if we can add more items\n const canAddMore = !maxItems || fields.length < maxItems;\n\n // Check if we can remove items\n const canRemove = fields.length > minItems;\n\n // TODO: For future enhancement, consider drag-and-drop reordering for array items.\n // TODO: Performance for very large arrays of complex objects. Virtualization might be needed.\n\n return (\n <Controller\n control={effectiveControl}\n name={name}\n rules={{\n // TODO: Similar to ArrayField, consider integration of custom validation functions.\n validate: (value) => {\n if (validation?.required && (!value || !Array.isArray(value) || value.length === 0)) {\n return 'At least one item is required';\n }\n if (minItems && Array.isArray(value) && value.length < minItems) {\n return `Minimum ${minItems} item${minItems > 1 ? 's' : ''} required`;\n }\n if (maxItems && Array.isArray(value) && value.length > maxItems) {\n return `Maximum ${maxItems} item${maxItems > 1 ? 's' : ''} allowed`;\n }\n return true;\n },\n }}\n render={({ fieldState: { error } }) => {\n const hasError = !!error;\n const accessibilityProps = getAccessibilityProps({\n id,\n hasError,\n isRequired,\n hasHelperText: !!helperText,\n });\n // TODO: Review aria-controls/aria-labelledby for the \"Add Item\" button and the list of items.\n\n return (\n <div\n className={`flex flex-col gap-4 ${width === 'full' ? 'w-full' : width === 'half' ? 'w-1/2' : 'w-1/3'}`}\n {...accessibilityProps}\n aria-describedby={`${helperText ? descriptionId : ''} ${hasError ? errorId : ''}`}\n >\n {label && (\n <div className=\"flex items-center justify-between\">\n <Label htmlFor={id}>\n {label} {isRequired && <span className=\"text-destructive\">*</span>}\n </Label>\n </div>\n )}\n\n <div className=\"space-y-3\">\n {fields.length === 0 ? (\n <div className=\"text-muted-foreground text-sm py-4 text-center border border-dashed rounded-md\">\n No items added yet. Click “Add Item” to begin.\n </div>\n ) : (\n fields.map((field, index) => {\n const isCollapsed = collapsedItems[field.id] ?? defaultCollapsed;\n\n return (\n <Card key={field.id} className=\"p-4\">\n <div className=\"flex items-start justify-between\">\n <div className=\"flex items-center gap-2 flex-1\">\n {/* TODO: Aria attributes for GripVertical if it becomes interactive (drag handle). */}\n <GripVertical className=\"size-4 text-muted-foreground\" />\n {collapsible && (\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n onClick={() => toggleCollapsed(field.id)}\n className=\"p-0 h-auto\"\n aria-label={isCollapsed ? 'Expand item' : 'Collapse item'}\n // TODO: Add aria-expanded={!isCollapsed} and aria-controls={`item-content-${field.id}`}\n >\n {isCollapsed ? (\n <ChevronRight className=\"h-4 w-4\" />\n ) : (\n <ChevronDown className=\"h-4 w-4\" />\n )}\n </Button>\n )}\n {isCollapsed && (\n <div className=\"flex items-center gap-4 text-sm text-muted-foreground ml-2\">\n <CollapsedSummary\n name={name}\n index={index}\n components={components}\n control={effectiveControl}\n />\n </div>\n )}\n </div>\n {!readOnly && canRemove && (\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n onClick={() => remove(index)}\n aria-label={`Remove item ${index + 1}`}\n >\n <X className=\"h-4 w-4\" />\n </Button>\n )}\n </div>\n\n {!isCollapsed && (\n <div className=\"space-y-4 mt-4\">\n {((): React.ReactNode[] => {\n return components.map((component) => {\n // Generate field using adapter to get full configuration including elementType for arrays\n if (!adapter) {\n throw new Error(\n `ArrayObjectField: No adapter provided for field generation. Cannot generate field for \"${component.name}\"`\n );\n }\n\n const generatedField = adapter.generateDefaultField(\n component,\n contractSchema\n );\n\n // Override with array object-specific configuration\n const propertyField: FormFieldType = {\n ...generatedField, // Include elementType and other adapter-specific properties\n id: `${id}-${index}-${component.name}`,\n name: `${name}.${index}.${component.name}`,\n label: component.displayName || component.name,\n validation: {\n ...generatedField.validation, // Preserve validation from adapter (includes min/max bounds)\n required: validation?.required, // Override required from parent\n },\n placeholder: `Enter ${component.displayName || component.name}`,\n helperText:\n component.description ||\n (generatedField.type === 'number' ? 'Numbers only' : undefined),\n width: 'full',\n readOnly,\n // Pass components for nested objects\n ...(component.components && {\n components: component.components,\n }),\n // TODO: Consider passing `adapter` down to nested `propertyField` if it's an object/array-object.\n };\n\n return (\n <div key={component.name}>\n {renderProperty ? (\n renderProperty(propertyField, index, component.name)\n ) : (\n <div className=\"text-sm text-muted-foreground\">\n Property “{component.name}” requires a render\n function\n </div>\n )}\n </div>\n );\n });\n })()}\n </div>\n )}\n </Card>\n );\n })\n )}\n </div>\n\n {/* Add Item button */}\n {!readOnly && canAddMore && (\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n onClick={handleAddItem}\n className=\"gap-1 w-full sm:w-auto\"\n >\n {/* TODO: Add aria-live region or other announcement for item add/remove. */}\n <Plus className=\"h-3 w-3\" />\n Add Item\n </Button>\n )}\n\n {helperText && (\n <div id={descriptionId} className=\"text-muted-foreground text-sm\">\n {helperText}\n </div>\n )}\n <ErrorMessage error={error} id={errorId} />\n </div>\n );\n }}\n />\n );\n}\n\n/**\n * Component to display collapsed item summary\n * TODO: This component is quite specific to ArrayObjectField.\n * If similar summaries are needed elsewhere, consider making it more generic\n * or moving it to a shared utils/components location.\n */\nfunction CollapsedSummary({\n name,\n index,\n components,\n control,\n}: {\n name: string;\n index: number;\n components: FunctionParameter[];\n control: FieldValues['control']; // TODO: useFormContext<TFieldValues>['control'] for better type safety if possible\n}): React.ReactElement {\n // Watch all values for this item\n // TODO: `useWatch` can be performance-intensive if the object is large and updates frequently.\n // If performance issues arise, consider optimizing what's watched or how often.\n const itemValues = useWatch({\n control,\n name: `${name}.${index}`, // Watch the entire object at this index\n });\n\n const summaryItems = components\n .slice(0, 3)\n .map((component) => {\n const fieldValue = itemValues?.[component.name];\n const displayValue =\n fieldValue !== undefined && fieldValue !== '' && fieldValue !== 0 && fieldValue !== false\n ? String(fieldValue).length > 20\n ? `${String(fieldValue).substring(0, 20)}...`\n : String(fieldValue)\n : null;\n\n return displayValue ? (\n <span key={component.name} className=\"flex items-center gap-1\">\n <span className=\"font-medium\">{component.displayName || component.name}:</span>\n <span className=\"text-foreground\">{displayValue}</span>\n </span>\n ) : null;\n })\n .filter(Boolean);\n\n const isEmpty =\n !itemValues ||\n Object.values(itemValues).every(\n (value) => value === undefined || value === '' || value === 0 || value === false\n );\n\n if (isEmpty && summaryItems.length === 0) {\n // Ensure we don't show \"Empty item\" if summaryItems has content\n return <span className=\"italic\">Empty item</span>;\n }\n\n return (\n <>\n {summaryItems.length > 0 ? (\n summaryItems\n ) : (\n <span className=\"italic\">Item has values (not shown in summary)</span>\n )}\n {/* TODO: The \"+ X more\" count should be accurate based on total properties vs. shown in summary.\n If summaryItems is empty but the item is not (due to values not fitting summary criteria),\n this count might be misleading.\n Consider `components.length - (actually displayed count in summaryItems)`\n */}\n {components.length > 3 &&\n summaryItems.length < components.length && ( // Only show \"more\" if not all are summarized or could be summarized\n <span className=\"text-xs\">+{components.length - summaryItems.length} more</span>\n )}\n </>\n );\n}\n\n// Set display name for debugging\nArrayObjectField.displayName = 'ArrayObjectField';\n","import { type ForwardedRef, type ReactElement, type ReactNode } from 'react';\nimport type { Control, FieldPath, FieldValues } from 'react-hook-form';\n\nimport { type FieldValidation } from '@openzeppelin/ui-types';\n\nimport { getWidthClasses } from './utils/layout';\n\nimport {\n FormControl,\n FormDescription,\n FormField,\n FormItem,\n FormLabel,\n FormMessage,\n} from '../ui/form';\n\n/**\n * Base props shared by all field components\n *\n * @template TFieldValues The field values type from React Hook Form\n */\nexport interface BaseFieldProps<TFieldValues extends FieldValues = FieldValues> {\n /**\n * Unique identifier for the field\n */\n id: string;\n\n /**\n * Label text to display\n */\n label: string;\n\n /**\n * Placeholder text when empty\n */\n placeholder?: string;\n\n /**\n * Helper text to display below the field\n */\n helperText?: string;\n\n /**\n * Field width for layout\n */\n width?: 'full' | 'half' | 'third';\n\n /**\n * Validation rules for the field\n */\n validation?: FieldValidation;\n\n /**\n * Form control from React Hook Form\n */\n control: Control<TFieldValues>;\n\n /**\n * Field name in the form\n */\n name: FieldPath<TFieldValues>;\n\n /**\n * Whether the field should be displayed as read-only/disabled.\n * @default false\n */\n readOnly?: boolean;\n}\n\n/**\n * BaseField component to provide a consistent layout for form fields\n *\n * @important This component is the foundation of the app rendering architecture and should\n * ONLY be used by field-specific components within the system, not as a standalone component.\n *\n * Architecture role:\n * 1. Provides a consistent layout structure for all field types\n * 2. Handles integration with React Hook Form through the FormField component\n * 3. Manages common rendering aspects like labels, error messages, and help text\n * 4. Delegates actual input rendering to field-specific components via renderInput\n *\n * Field component hierarchy:\n * - TransactionForm (top-level renderer)\n * - DynamicFormField (field type selector)\n * - Specific field components (TextField, NumberField, etc.)\n * - BaseField (common field structure - this component)\n * - Actual input element rendered by renderInput\n *\n * This component should only be extended by field-specific components like\n * TextField, NumberField, and AddressField - it is not meant for direct use in forms.\n */\nexport function BaseField<TFieldValues extends FieldValues = FieldValues>({\n id,\n label,\n helperText,\n control,\n name,\n width = 'full',\n renderInput,\n}: BaseFieldProps<TFieldValues> & {\n renderInput: (\n field: Record<string, unknown>,\n props: { id: string; ref?: ForwardedRef<HTMLElement> }\n ) => ReactNode;\n ref?: ForwardedRef<HTMLElement>;\n}): ReactElement {\n return (\n <FormField\n control={control}\n name={name}\n render={({ field }) => (\n <FormItem className={getWidthClasses(width)}>\n <FormLabel htmlFor={id}>{label}</FormLabel>\n <FormControl>{renderInput(field, { id })}</FormControl>\n {helperText && <FormDescription id={`${id}-description`}>{helperText}</FormDescription>}\n <FormMessage id={`${id}-error`} />\n </FormItem>\n )}\n />\n );\n}\n\n// Set displayName properly\nBaseField.displayName = 'BaseField';\n","import React from 'react';\nimport { Controller, FieldValues } from 'react-hook-form';\n\nimport { Input } from '../ui/input';\nimport { Label } from '../ui/label';\nimport { BaseFieldProps } from './BaseField';\nimport {\n ErrorMessage,\n getAccessibilityProps,\n getValidationStateClasses,\n handleEscapeKey,\n INTEGER_HTML_PATTERN,\n INTEGER_INPUT_PATTERN,\n INTEGER_PATTERN,\n validateField,\n} from './utils';\n\n/**\n * BigIntField component properties\n */\nexport interface BigIntFieldProps<TFieldValues extends FieldValues = FieldValues>\n extends BaseFieldProps<TFieldValues> {\n /**\n * Custom validation function for big integer string values\n */\n validateBigInt?: (value: string) => boolean | string;\n}\n\n/**\n * Big integer input field component for large numbers beyond JavaScript's Number precision.\n *\n * This component is designed for blockchain integer types like uint128, uint256, int128, int256\n * that can hold values larger than JavaScript's Number.MAX_SAFE_INTEGER (2^53 - 1).\n *\n * Architecture flow:\n * 1. Form schemas are generated from contract functions using adapters\n * 2. TransactionForm renders the overall form structure with React Hook Form\n * 3. DynamicFormField selects BigIntField for large integer types\n * 4. This component handles string-based integer input with validation\n * 5. Adapters convert the string to BigInt when submitting transactions\n *\n * The component includes:\n * - Integer-only validation (no decimals allowed)\n * - String-based storage to avoid JavaScript Number precision issues\n * - Integration with React Hook Form\n * - Automatic error handling and reporting\n * - Full accessibility support with ARIA attributes\n * - Keyboard navigation\n */\nexport function BigIntField<TFieldValues extends FieldValues = FieldValues>({\n id,\n label,\n placeholder,\n helperText,\n control,\n name,\n width = 'full',\n validation,\n validateBigInt,\n readOnly,\n}: BigIntFieldProps<TFieldValues>): React.ReactElement {\n const isRequired = !!validation?.required;\n const errorId = `${id}-error`;\n const descriptionId = `${id}-description`;\n\n // Ensure validation includes integer-only pattern\n // This will be handled by validateField utility, avoiding duplication\n const enhancedValidation = {\n ...validation,\n pattern: validation?.pattern || INTEGER_PATTERN,\n };\n\n // Validation function for big integer strings\n const validateBigIntValue = (value: string): string | true => {\n // Run standard validation with integer pattern (includes pattern validation)\n const standardValidation = validateField(value, enhancedValidation);\n if (standardValidation !== true) return standardValidation as string;\n\n // Run custom validator if provided\n if (validateBigInt) {\n const customValidation = validateBigInt(value);\n if (customValidation !== true && typeof customValidation === 'string') {\n return customValidation;\n }\n }\n\n return true;\n };\n\n return (\n <div\n className={`flex flex-col gap-2 ${width === 'full' ? 'w-full' : width === 'half' ? 'w-1/2' : 'w-1/3'}`}\n >\n {label && (\n <Label htmlFor={id}>\n {label} {isRequired && <span className=\"text-destructive\">*</span>}\n </Label>\n )}\n\n <Controller\n control={control}\n name={name}\n rules={{\n validate: (value) => {\n // Skip validation if empty and check required separately\n if (value === undefined || value === null || value === '') {\n return validation?.required ? 'This field is required' : true;\n }\n\n // Handle incomplete inputs\n if (value === '-') {\n return 'Please enter a complete number';\n }\n\n // For string values, validate as big integer\n if (typeof value === 'string') {\n return validateBigIntValue(value);\n }\n\n // Convert numbers to strings (in case value is accidentally a number)\n if (typeof value === 'number') {\n return validateBigIntValue(value.toString());\n }\n\n return true;\n },\n }}\n disabled={readOnly}\n render={({ field, fieldState: { error, isTouched } }) => {\n const hasError = !!error;\n const shouldShowError = hasError && isTouched;\n const validationClasses = getValidationStateClasses(error, isTouched);\n\n // Handle input change\n const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>): void => {\n const rawValue = e.target.value;\n\n // Allow empty string\n if (rawValue === '') {\n field.onChange('');\n return;\n }\n\n // Allow standalone minus sign for negative numbers\n if (rawValue === '-') {\n field.onChange(rawValue);\n return;\n }\n\n // Check if the input is a valid integer format\n // Allow only digits and optional leading minus sign (using input pattern)\n if (INTEGER_INPUT_PATTERN.test(rawValue)) {\n field.onChange(rawValue);\n }\n // If invalid format, don't update (prevents non-numeric input)\n };\n\n // Handle keyboard events\n const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>): void => {\n // Allow only numeric characters, backspace, delete, tab, escape, enter, arrows, hyphen\n const allowedKeys = [\n '0',\n '1',\n '2',\n '3',\n '4',\n '5',\n '6',\n '7',\n '8',\n '9',\n 'Backspace',\n 'Delete',\n 'Tab',\n 'Escape',\n 'Enter',\n 'ArrowLeft',\n 'ArrowRight',\n 'ArrowUp',\n 'ArrowDown',\n '-',\n ];\n\n // Allow Ctrl/Cmd+A, C, V, X, Z for common editing operations\n if (\n (e.ctrlKey || e.metaKey) &&\n ['a', 'c', 'v', 'x', 'z'].includes(e.key.toLowerCase())\n ) {\n return;\n }\n\n if (!allowedKeys.includes(e.key) && !e.ctrlKey && !e.metaKey) {\n e.preventDefault();\n }\n\n // Handle escape key to clear input\n if (e.key === 'Escape') {\n handleEscapeKey(field.onChange, field.value)(e);\n return;\n }\n };\n\n // Get accessibility attributes\n const accessibilityProps = getAccessibilityProps({\n id,\n hasError,\n isRequired,\n hasHelperText: !!helperText,\n });\n\n return (\n <>\n <Input\n {...field}\n value={field.value ?? ''}\n id={id}\n placeholder={placeholder || 'Enter integer value'}\n type=\"text\"\n className={validationClasses}\n onKeyDown={handleKeyDown}\n data-slot=\"input\"\n onChange={handleInputChange}\n inputMode=\"numeric\"\n pattern={INTEGER_HTML_PATTERN}\n {...accessibilityProps}\n aria-describedby={`${helperText ? descriptionId : ''} ${hasError ? errorId : ''}`}\n disabled={readOnly}\n />\n\n {/* Display helper text */}\n {helperText && (\n <div id={descriptionId} className=\"text-muted-foreground text-sm\">\n {helperText}\n </div>\n )}\n\n {/* Display error message */}\n <ErrorMessage\n error={error}\n id={errorId}\n message={shouldShowError ? error?.message : undefined}\n />\n </>\n );\n }}\n />\n </div>\n );\n}\n\n// Set displayName manually for better debugging\nBigIntField.displayName = 'BigIntField';\n","import React from 'react';\nimport { Controller, FieldPath, FieldValues, PathValue } from 'react-hook-form';\n\nimport { Checkbox } from '../ui/checkbox';\nimport { Label } from '../ui/label';\nimport { BaseFieldProps } from './BaseField';\nimport {\n ErrorMessage,\n getAccessibilityProps,\n getValidationStateClasses,\n handleToggleKeys,\n validateField,\n} from './utils';\n\n/**\n * BooleanField component properties\n */\nexport interface BooleanFieldProps<TFieldValues extends FieldValues = FieldValues>\n extends BaseFieldProps<TFieldValues> {\n /**\n * Custom validation function for boolean values\n */\n validateBoolean?: (value: boolean) => boolean | string;\n}\n\n/**\n * Boolean input field component (checkbox) specifically designed for React Hook Form integration.\n *\n * Architecture flow:\n * 1. Form schemas are generated from contract functions using adapters\n * 2. TransactionForm renders the overall form structure with React Hook Form\n * 3. DynamicFormField selects the appropriate field component (like BooleanField) based on field type\n * 4. BaseField provides consistent layout and hook form integration\n * 5. This component handles boolean-specific rendering and validation\n *\n * The component includes:\n * - Integration with React Hook Form\n * - Checkbox-specific behavior\n * - Customizable validation through adapter integration\n * - Automatic error handling and reporting\n * - Full accessibility support with ARIA attributes\n * - Keyboard navigation with Space/Enter for toggling\n */\nexport function BooleanField<TFieldValues extends FieldValues = FieldValues>({\n id,\n label,\n helperText,\n control,\n name,\n width = 'full',\n validation,\n validateBoolean,\n readOnly,\n}: BooleanFieldProps<TFieldValues>): React.ReactElement {\n const isRequired = !!validation?.required;\n const errorId = `${id}-error`;\n const descriptionId = `${id}-description`;\n\n // Function to validate boolean values\n const validateBooleanValue = (value: boolean): string | true => {\n // Run standard validation first\n const standardValidation = validateField(value, validation);\n if (standardValidation !== true) return standardValidation as string;\n\n // Then run custom validator if provided\n if (validateBoolean) {\n const customValidation = validateBoolean(value);\n if (customValidation !== true && typeof customValidation === 'string') {\n return customValidation;\n }\n }\n\n return true;\n };\n\n return (\n <div\n className={`flex flex-col gap-2 ${width === 'full' ? 'w-full' : width === 'half' ? 'w-1/2' : 'w-1/3'}`}\n >\n <Controller\n control={control}\n name={name}\n defaultValue={false as PathValue<TFieldValues, FieldPath<TFieldValues>>}\n rules={{\n validate: (value) => {\n // Handle required validation specifically\n if (value === undefined || value === null) {\n return validation?.required ? 'This field is required' : true;\n }\n\n // For boolean values\n if (typeof value === 'boolean') {\n // If required, it means a boolean value (true or false) must be present.\n // The check for undefined/null above handles the case where it's not set.\n // So, if it's a boolean (true or false), it passes the required check here.\n return validateBooleanValue(value);\n }\n\n return true;\n },\n }}\n disabled={readOnly}\n render={({ field, fieldState: { error, isTouched } }) => {\n const hasError = !!error;\n const validationClasses = getValidationStateClasses(error, isTouched);\n\n // Handle checkbox change with validation\n const handleCheckedChange = (checked: boolean | 'indeterminate'): void => {\n const value = checked === true;\n field.onChange(value);\n\n // Trigger validation if required and unchecked\n if (isRequired && !value) {\n setTimeout(() => field.onBlur(), 0);\n }\n };\n\n // Add keyboard accessibility for toggle\n const handleKeyDown = (e: React.KeyboardEvent<HTMLButtonElement>): void => {\n handleToggleKeys(field.onChange, !!field.value)(e);\n\n // Trigger validation for required fields\n if (e.key === ' ' || e.key === 'Enter') {\n if (isRequired) {\n setTimeout(() => field.onBlur(), 0);\n }\n }\n };\n\n // Get accessibility attributes\n const accessibilityProps = getAccessibilityProps({\n id,\n hasError,\n isRequired,\n isDisabled: readOnly,\n hasHelperText: !!helperText,\n });\n\n return (\n <>\n <div className=\"flex items-center space-x-2\">\n <Checkbox\n {...field}\n id={id}\n checked={!!field.value}\n onCheckedChange={handleCheckedChange}\n className={validationClasses}\n onKeyDown={handleKeyDown}\n disabled={readOnly}\n {...accessibilityProps}\n aria-describedby={`${helperText ? descriptionId : ''} ${hasError ? errorId : ''}`}\n />\n <Label htmlFor={id}>\n {label} {isRequired && <span className=\"text-destructive\">*</span>}\n </Label>\n </div>\n\n {helperText && (\n <div id={descriptionId} className=\"text-muted-foreground pl-6 text-sm\">\n {helperText}\n </div>\n )}\n\n <ErrorMessage error={error} id={errorId} className=\"pl-6\" />\n </>\n );\n }}\n />\n </div>\n );\n}\n\nBooleanField.displayName = 'BooleanField';\n","import React from 'react';\nimport { Controller, FieldValues } from 'react-hook-form';\n\nimport { validateBytesSimple } from '@openzeppelin/ui-utils';\n\nimport { Label } from '../ui/label';\nimport { Textarea } from '../ui/textarea';\nimport { BaseFieldProps } from './BaseField';\nimport {\n ErrorMessage,\n getAccessibilityProps,\n getValidationStateClasses,\n handleEscapeKey,\n} from './utils';\n\n/**\n * BytesField component properties\n */\nexport interface BytesFieldProps<TFieldValues extends FieldValues = FieldValues>\n extends BaseFieldProps<TFieldValues> {\n /**\n * Number of rows for the textarea\n */\n rows?: number;\n\n /**\n * Maximum length in bytes (not characters)\n */\n maxBytes?: number;\n\n /**\n * Whether to accept hex, base64, or both formats\n */\n acceptedFormats?: 'hex' | 'base64' | 'both';\n\n /**\n * Whether to automatically add/remove 0x prefix for hex values\n */\n autoPrefix?: boolean;\n\n /**\n * Whether to allow 0x prefix in hex input (defaults to true)\n */\n allowHexPrefix?: boolean;\n}\n\n/**\n * Specialized input field for bytes data with built-in hex/base64 validation.\n *\n * This component provides proper validation for blockchain bytes data including:\n * - Hex encoding validation (with optional 0x prefix support)\n * - Base64 encoding validation\n * - Byte length validation\n * - Format detection and conversion\n *\n * Key props for EVM compatibility:\n * - `allowHexPrefix`: Whether to accept 0x prefixed input (defaults to true)\n * - `autoPrefix`: Whether to automatically add 0x prefixes (defaults to false)\n *\n * These are separate concerns - you can accept 0x input without auto-adding prefixes.\n *\n * Architecture flow:\n * 1. Form schemas are generated from contract functions using adapters\n * 2. TransactionForm renders the overall form structure with React Hook Form\n * 3. DynamicFormField selects BytesField for 'bytes' field types\n * 4. BaseField provides consistent layout and hook form integration\n * 5. This component handles bytes-specific validation and formatting\n */\nexport function BytesField<TFieldValues extends FieldValues = FieldValues>({\n id,\n label,\n helperText,\n control,\n name,\n width = 'full',\n validation,\n placeholder = 'Enter hex or base64 encoded bytes',\n rows = 3,\n maxBytes,\n acceptedFormats = 'both',\n autoPrefix = false,\n allowHexPrefix = true,\n readOnly,\n}: BytesFieldProps<TFieldValues>): React.ReactElement {\n const isRequired = !!validation?.required;\n const errorId = `${id}-error`;\n const descriptionId = `${id}-description`;\n\n /**\n * Validates bytes input format and encoding using validator.js\n */\n const validateBytesField = (value: string): boolean | string => {\n return validateBytesSimple(value, {\n acceptedFormats,\n maxBytes,\n allowHexPrefix, // Allow prefix based on explicit prop (defaults to true)\n });\n };\n\n /**\n * Formats the input value (adds 0x prefix if needed)\n */\n const formatValue = (value: string): string => {\n if (!value || !autoPrefix) return value;\n\n const cleanValue = value.trim().replace(/\\s+/g, '');\n const withoutPrefix = cleanValue.startsWith('0x') ? cleanValue.slice(2) : cleanValue;\n\n // Only add prefix for valid hex that doesn't already have it\n if (withoutPrefix && /^[0-9a-fA-F]*$/.test(withoutPrefix) && withoutPrefix.length % 2 === 0) {\n return cleanValue.startsWith('0x') ? cleanValue : `0x${cleanValue}`;\n }\n\n return cleanValue;\n };\n\n return (\n <div\n className={`flex flex-col gap-2 ${width === 'full' ? 'w-full' : width === 'half' ? 'w-1/2' : 'w-1/3'}`}\n >\n {label && (\n <Label htmlFor={id}>\n {label} {isRequired && <span className=\"text-destructive\">*</span>}\n </Label>\n )}\n\n <Controller\n control={control}\n name={name}\n disabled={readOnly}\n rules={{\n validate: (value) => {\n // Handle required validation explicitly\n if (value === undefined || value === null || value === '') {\n return validation?.required ? 'This field is required' : true;\n }\n\n // Run bytes-specific validation using validator.js\n return validateBytesField(value);\n },\n }}\n render={({ field, fieldState: { error, isTouched } }) => {\n const hasError = !!error;\n const shouldShowError = hasError && (isTouched || validation?.required);\n const validationClasses = getValidationStateClasses(error, isTouched);\n\n // Get accessibility attributes\n const accessibilityProps = getAccessibilityProps({\n id,\n hasError,\n isRequired,\n isDisabled: readOnly,\n hasHelperText: !!helperText,\n });\n\n return (\n <>\n <Textarea\n id={id}\n name={field.name}\n ref={field.ref}\n placeholder={placeholder}\n rows={rows}\n className={validationClasses}\n disabled={readOnly}\n value={field.value ?? ''}\n onChange={(e) => {\n // Only update value without formatting for better performance\n field.onChange(e.target.value);\n }}\n onBlur={(e) => {\n // Apply formatting on blur when user finishes typing\n const formatted = formatValue(e.target.value);\n field.onChange(formatted);\n // Register field as touched with React Hook Form\n field.onBlur();\n }}\n onKeyDown={handleEscapeKey(field.onChange, field.value)}\n {...accessibilityProps}\n aria-describedby={`${helperText ? descriptionId : ''} ${hasError ? errorId : ''}`.trim()}\n />\n\n {/* Display helper text with format hint */}\n {helperText && (\n <div id={descriptionId} className=\"text-muted-foreground text-sm\">\n {helperText}\n <div className=\"text-xs text-muted-foreground mt-1\">\n {acceptedFormats === 'hex' && 'Hex format (e.g., 48656c6c6f or 0x48656c6c6f)'}\n {acceptedFormats === 'base64' && 'Base64 format (e.g., SGVsbG8=)'}\n {acceptedFormats === 'both' &&\n 'Hex (e.g., 48656c6c6f) or Base64 (e.g., SGVsbG8=) format'}\n {maxBytes && ` • Max ${maxBytes} bytes`}\n </div>\n </div>\n )}\n\n {/* Display error message */}\n <ErrorMessage\n error={error}\n id={errorId}\n message={shouldShowError ? error?.message : undefined}\n />\n </>\n );\n }}\n />\n </div>\n );\n}\n\n// Set displayName manually for better debugging\nBytesField.displayName = 'BytesField';\n","import CodeEditor from '@uiw/react-textarea-code-editor';\nimport CodeEditorNoHighlight from '@uiw/react-textarea-code-editor/nohighlight';\nimport React from 'react';\nimport { Controller, type Control, type FieldValues, type Path } from 'react-hook-form';\n\nimport { ErrorMessage } from './utils';\n\n/**\n * CodeEditorField component properties\n */\nexport interface CodeEditorFieldProps<TFieldValues extends FieldValues = FieldValues> {\n /**\n * Unique identifier for the field\n */\n id: string;\n\n /**\n * Optional CSS class name for the container\n */\n className?: string;\n\n /**\n * Field name for form control\n */\n name: Path<TFieldValues>;\n\n /**\n * React Hook Form control object\n */\n control: Control<TFieldValues>;\n\n /**\n * Field label\n */\n label?: string;\n\n /**\n * Helper text displayed below the field\n */\n helperText?: string;\n\n /**\n * Placeholder text when empty\n */\n placeholder?: string;\n\n /**\n * Programming language for syntax highlighting\n */\n language?: string;\n\n /**\n * Editor theme\n */\n theme?: string;\n\n /**\n * Editor height\n */\n height?: string;\n\n /**\n * Editor maximum height (with scrollbar for overflow)\n */\n maxHeight?: string;\n\n /**\n * Content size threshold for disabling syntax highlighting (default: 5000 chars)\n */\n performanceThreshold?: number;\n\n /**\n * Whether the field is required\n */\n required?: boolean;\n\n /**\n * Whether the field is disabled\n */\n disabled?: boolean;\n\n /**\n * Whether the field is read-only\n */\n readOnly?: boolean;\n\n /**\n * Custom validation function for code values\n */\n validateCode?: (value: string) => boolean | string;\n}\n\n/**\n * CodeEditorField provides syntax-highlighted code editing with form integration.\n *\n * Features:\n * - Syntax highlighting via @uiw/react-textarea-code-editor\n * - React Hook Form integration with Controller\n * - Configurable language support (JSON, TypeScript, etc.)\n * - Performance optimizations with smart highlighting\n * - Constrained height with automatic scrolling\n * - Design system styling integration\n *\n * @example\n * ```tsx\n * <CodeEditorField\n * id=\"contractAbi\"\n * name=\"contractSchema\"\n * control={control}\n * label=\"Contract ABI\"\n * language=\"json\"\n * placeholder=\"Paste your ABI JSON here...\"\n * />\n * ```\n */\nexport function CodeEditorField<TFieldValues extends FieldValues = FieldValues>({\n id,\n name,\n control,\n label,\n helperText,\n placeholder = '',\n language = 'json',\n theme = 'light',\n height = '200px',\n maxHeight = '400px',\n performanceThreshold = 5000,\n required = false,\n disabled = false,\n readOnly = false,\n validateCode,\n className,\n}: CodeEditorFieldProps<TFieldValues>): React.ReactElement {\n // Convert height strings to numbers for native props with robust parsing\n function extractPixelValue(val: string | number, fallback: number): number {\n if (typeof val === 'number') return val;\n const match = typeof val === 'string' ? val.match(/^(\\d+)\\s*px$/) : null;\n if (match) return parseInt(match[1], 10);\n return fallback;\n }\n const minHeightNum = extractPixelValue(height, 200);\n const maxHeightNum = extractPixelValue(maxHeight, 400);\n\n return (\n <div className={className}>\n {label && (\n <label htmlFor={id} className=\"block text-sm font-medium text-foreground mb-2\">\n {label}\n {required && <span className=\"text-destructive ml-1\">*</span>}\n </label>\n )}\n\n <Controller\n name={name}\n control={control}\n rules={{\n required: required ? 'This field is required' : false,\n // Move validation to onBlur to avoid expensive operations on every keystroke\n validate: {\n validCode: (value: string) => {\n if (!validateCode || !value) return true;\n\n const validation = validateCode(value);\n if (typeof validation === 'string') {\n return validation;\n }\n if (validation === false) {\n return 'Invalid code format';\n }\n return true;\n },\n },\n }}\n render={({ field: { onChange, onBlur, value }, fieldState: { error } }) => {\n // Check if content is too large for syntax highlighting\n const contentSize = (value || '').length;\n const shouldDisableHighlighting = contentSize > performanceThreshold;\n const EditorComponent = shouldDisableHighlighting ? CodeEditorNoHighlight : CodeEditor;\n\n // Update form immediately to prevent controlled component conflicts\n const handleChange = (event: React.ChangeEvent<HTMLTextAreaElement>): void => {\n onChange(event.target.value); // Immediate update for controlled component\n };\n\n // Simple blur handler\n const handleBlur = (): void => {\n onBlur();\n };\n\n return (\n <div className=\"space-y-2\">\n <div\n className=\"w-full rounded-md border border-input bg-background ring-offset-background focus-within:ring-2 focus-within:ring-ring focus-within:ring-offset-2 disabled:cursor-not-allowed resize-y\"\n style={{\n maxHeight: `${maxHeightNum}px`,\n overflow: 'auto',\n overflowX: 'hidden', // Prevent horizontal scrolling and expansion\n minHeight: `${minHeightNum}px`,\n resize: 'vertical',\n }}\n >\n <EditorComponent\n id={id}\n value={value || ''}\n language={language}\n placeholder={placeholder}\n onChange={handleChange}\n onBlur={handleBlur}\n padding={12}\n minHeight={minHeightNum}\n data-color-mode={theme as 'light' | 'dark'}\n disabled={disabled}\n readOnly={readOnly}\n data-testid={`${id}-code-editor${shouldDisableHighlighting ? '-no-highlight' : ''}`}\n className=\"text-sm placeholder:text-muted-foreground\"\n style={{\n fontFamily:\n 'ui-monospace, SFMono-Regular, \"SF Mono\", Consolas, \"Liberation Mono\", Menlo, monospace',\n fontSize: '14px',\n border: 'none',\n backgroundColor: 'transparent',\n width: '100%',\n wordWrap: 'break-word', // Break long words to prevent horizontal overflow\n whiteSpace: 'pre-wrap', // Preserve formatting while allowing wrapping\n overflowWrap: 'break-word', // Modern CSS property for word breaking\n }}\n />\n </div>\n\n <ErrorMessage error={error} id={`${id}-error`} />\n\n {helperText && !error && (\n <p className=\"text-sm text-muted-foreground\" id={`${id}-helper`}>\n {helperText}\n </p>\n )}\n </div>\n );\n }}\n />\n </div>\n );\n}\n\nCodeEditorField.displayName = 'CodeEditorField';\n","import React from 'react';\nimport { Controller, FieldValues } from 'react-hook-form';\n\nimport { Input } from '../ui/input';\nimport { Label } from '../ui/label';\nimport { BaseFieldProps } from './BaseField';\nimport {\n ErrorMessage,\n getAccessibilityProps,\n getValidationStateClasses,\n handleEscapeKey,\n validateField,\n} from './utils';\n\n/**\n * DateTimeField component properties\n */\nexport interface DateTimeFieldProps<TFieldValues extends FieldValues = FieldValues>\n extends BaseFieldProps<TFieldValues> {\n /**\n * Placeholder text displayed when the field is empty\n */\n placeholder?: string;\n\n /**\n * If true, clears the field when user clicks Escape; otherwise just blurs\n */\n clearOnEscape?: boolean;\n}\n\n/**\n * Datetime-local input field component specifically designed for React Hook Form integration.\n *\n * Architecture flow:\n * 1. Form schemas are generated from contract functions using adapters\n * 2. TransactionForm renders the overall form structure with React Hook Form\n * 3. DynamicFormField selects the appropriate field component (like DateTimeField) based on field type\n * 4. BaseField provides consistent layout and hook form integration\n * 5. This component handles date-time specific rendering, conversion, and validation\n *\n * The component includes:\n * - Integration with React Hook Form\n * - Conversion between input value (YYYY-MM-DDTHH:mm) and ISO 8601 strings (toISOString)\n * - Customizable validation through adapter integration\n * - Automatic error handling and reporting\n * - Full accessibility support with ARIA attributes\n * - Keyboard navigation with Escape-to-clear behavior\n */\nexport function DateTimeField<TFieldValues extends FieldValues = FieldValues>({\n id,\n label,\n placeholder,\n helperText,\n control,\n name,\n width = 'full',\n validation,\n readOnly,\n clearOnEscape = true,\n}: DateTimeFieldProps<TFieldValues>): React.ReactElement {\n /**\n * TODO: Replace native datetime-local input with a styled popover-based\n * calendar/time picker (Radix Popover + Select) to match the design system.\n * Maintain ISO 8601 value semantics and provide a mobile fallback to native input.\n */\n const isRequired = !!validation?.required;\n const errorId = `${id}-error`;\n const descriptionId = `${id}-description`;\n\n // Validate ISO 8601 string or empty according to validation rules\n const validateDateValue = (value: string): string | true => {\n const validationResult = validateField(value, validation);\n return validationResult === true ? true : (validationResult as string);\n };\n\n return (\n <div\n className={`flex flex-col gap-2 ${width === 'full' ? 'w-full' : width === 'half' ? 'w-1/2' : 'w-1/3'}`}\n >\n {label && (\n <Label htmlFor={id}>\n {label} {isRequired && <span className=\"text-destructive\">*</span>}\n </Label>\n )}\n\n <Controller\n control={control}\n name={name}\n rules={{\n validate: (value) => {\n if (value === undefined || value === null || value === '') {\n return validation?.required ? 'This field is required' : true;\n }\n if (typeof value === 'string') {\n return validateDateValue(value);\n }\n return true;\n },\n }}\n disabled={readOnly}\n render={({ field, fieldState: { error, isTouched } }) => {\n const hasError = !!error;\n const shouldShowError = hasError && isTouched;\n const validationClasses = getValidationStateClasses(error, isTouched);\n\n const handleChange = (e: React.ChangeEvent<HTMLInputElement>): void => {\n const raw = e.target.value; // YYYY-MM-DDTHH:mm or ''\n if (!raw) {\n field.onChange('');\n return;\n }\n // Preserve the exact local selection instead of converting to UTC.\n // Store as ISO-like local string with timezone offset maintained by parsing components.\n const [datePart, timePart] = raw.split('T');\n const [year, month, day] = datePart.split('-').map((s) => Number(s));\n const [hours, minutes] = timePart.split(':').map((s) => Number(s));\n const localDate = new Date(year, month - 1, day, hours, minutes, 0, 0);\n // Serialize back to local YYYY-MM-DDTHH:mm string so the value remains what the user picked\n const pad = (n: number): string => String(n).padStart(2, '0');\n const serialized = `${localDate.getFullYear()}-${pad(localDate.getMonth() + 1)}-${pad(localDate.getDate())}T${pad(localDate.getHours())}:${pad(localDate.getMinutes())}`;\n field.onChange(serialized);\n };\n\n const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>): void => {\n if (e.key === 'Escape') {\n if (clearOnEscape) {\n handleEscapeKey(field.onChange as (v: string) => void, field.value)(e);\n } else {\n (e.target as HTMLElement).blur();\n }\n }\n };\n\n const accessibilityProps = getAccessibilityProps({\n id,\n hasError,\n isRequired,\n hasHelperText: !!helperText,\n isDisabled: !!readOnly,\n });\n\n const formatDateTimeLocal = (val: unknown): string => {\n if (!val) return '';\n try {\n const d = new Date(val as string);\n if (isNaN(d.getTime())) return '';\n const pad = (n: number): string => String(n).padStart(2, '0');\n const year = d.getFullYear();\n const month = pad(d.getMonth() + 1);\n const day = pad(d.getDate());\n const hours = pad(d.getHours());\n const minutes = pad(d.getMinutes());\n // Return a local datetime string for the input value to avoid timezone shifts\n return `${year}-${month}-${day}T${hours}:${minutes}`;\n } catch {\n return '';\n }\n };\n\n const inputValue: string = formatDateTimeLocal(field.value);\n\n return (\n <>\n <Input\n {...field}\n id={id}\n placeholder={placeholder}\n className={validationClasses}\n onChange={handleChange}\n onKeyDown={handleKeyDown}\n data-slot=\"input\"\n value={inputValue}\n type=\"datetime-local\"\n {...accessibilityProps}\n aria-describedby={`${helperText ? descriptionId : ''} ${hasError ? errorId : ''}`}\n disabled={readOnly}\n />\n\n {helperText && (\n <div id={descriptionId} className=\"text-muted-foreground text-sm\">\n {helperText}\n </div>\n )}\n\n <ErrorMessage\n error={error}\n id={errorId}\n message={shouldShowError ? error?.message : undefined}\n />\n </>\n );\n }}\n />\n </div>\n );\n}\n\nDateTimeField.displayName = 'DateTimeField';\n","import React from 'react';\nimport { Controller, FieldValues } from 'react-hook-form';\n\nimport type { EnumValue, FormFieldType, FunctionParameter } from '@openzeppelin/ui-types';\nimport { cn } from '@openzeppelin/ui-utils';\n\nimport { Input } from '../ui/input';\nimport { Label } from '../ui/label';\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '../ui/select';\nimport { Textarea } from '../ui/textarea';\nimport { BaseFieldProps } from './BaseField';\nimport {\n ErrorMessage,\n getAccessibilityProps,\n getValidationStateClasses,\n validateField,\n} from './utils';\n\n/**\n * Enum variant definition\n */\nexport interface EnumVariant {\n /** Name of the variant (e.g., 'One', 'Two', 'Three') */\n name: string;\n /** Type of variant: 'void' for unit variants, 'tuple' for variants with payload, 'integer' for numeric enums */\n type: 'void' | 'tuple' | 'integer';\n /** For tuple variants: array of payload type names (e.g., ['U32', 'ScString']) */\n payloadTypes?: string[];\n /** Optional nested component definitions for tuple payload entries */\n payloadComponents?: (FunctionParameter[] | undefined)[];\n /** For integer variants: the numeric value */\n value?: number;\n /** Flag indicating if this variant has a single Tuple payload (for serialization) */\n isSingleTuplePayload?: boolean;\n}\n\n/**\n * Enum metadata extracted from contract spec\n */\nexport interface EnumMetadata {\n /** Name of the enum type */\n name: string;\n /** Array of variants in the enum */\n variants: EnumVariant[];\n /** True if all variants are unit variants (no payloads), suitable for simple select/radio */\n isUnitOnly: boolean;\n}\n\n/**\n * Enum field value structure for blockchain enum types\n */\nexport type EnumFieldValue = EnumValue;\n\n/**\n * EnumField component properties\n */\nexport interface EnumFieldProps<TFieldValues extends FieldValues = FieldValues>\n extends BaseFieldProps<TFieldValues> {\n /**\n * Enum metadata containing variant information\n */\n enumMetadata?: EnumMetadata;\n\n /**\n * Custom validation function for enum values\n */\n validateEnum?: (value: EnumFieldValue) => boolean | string;\n\n /**\n * Render function for payload input fields.\n * This allows the parent component to provide appropriate field components\n * based on the payload type, maintaining separation of concerns.\n */\n renderPayloadField?: (field: FormFieldType, payloadIndex: number) => React.ReactNode;\n}\n\n/**\n * Composite enum field component for blockchain enum types.\n *\n * This component handles both unit enums (simple variants) and tagged enums (variants with payloads).\n * For unit enums, it renders as a simple select dropdown.\n * For tagged enums, it renders a variant picker plus conditional input fields for payload data.\n *\n * The value format is designed to be chain-agnostic:\n * - Unit variants: { tag: \"VariantName\" }\n * - Tuple variants: { tag: \"VariantName\", values: [...] }\n */\nexport function EnumField<TFieldValues extends FieldValues = FieldValues>({\n id,\n label,\n placeholder = 'Select variant',\n helperText,\n control,\n name,\n width = 'full',\n validation,\n enumMetadata,\n validateEnum,\n renderPayloadField,\n readOnly,\n}: EnumFieldProps<TFieldValues>): React.ReactElement {\n const isRequired = !!validation?.required;\n const errorId = `${id}-error`;\n const descriptionId = `${id}-description`;\n\n // Use consistent width classes\n const widthClass = width === 'full' ? 'w-full' : width === 'half' ? 'w-1/2' : 'w-1/3';\n\n // If no enum metadata or empty variants, fallback to a simple text input with helper text\n if (!enumMetadata || enumMetadata.variants.length === 0) {\n return (\n <div className={cn('flex flex-col gap-2', widthClass)}>\n {label && (\n <Label htmlFor={id}>\n {label} {isRequired && <span className=\"text-destructive\">*</span>}\n </Label>\n )}\n\n <Controller\n control={control}\n name={name}\n disabled={readOnly}\n rules={{\n validate: (value) => {\n // Use standard validation first\n const standardValidation = validateField(value, validation);\n if (standardValidation !== true) {\n return standardValidation;\n }\n\n // If it's a string, try to validate it as JSON\n if (typeof value === 'string') {\n try {\n const parsed = JSON.parse(value);\n // Check if it has the required 'tag' property\n if (!parsed.tag) {\n return 'JSON must have a \"tag\" property specifying the enum variant';\n }\n } catch {\n return 'Invalid JSON format. Please enter valid JSON like {\"tag\":\"VariantName\"}';\n }\n }\n\n // If it's an object, check if it has the required 'tag' property\n if (typeof value === 'object' && value !== null) {\n if (!('tag' in value)) {\n return 'Enum value must have a \"tag\" property specifying the variant';\n }\n }\n\n return true;\n },\n }}\n render={({ field, fieldState: { error, isTouched } }) => {\n const hasError = !!error;\n const validationClasses = getValidationStateClasses(error, isTouched);\n\n // Get accessibility attributes\n const accessibilityProps = getAccessibilityProps({\n id,\n hasError,\n isRequired,\n hasHelperText: !!helperText,\n });\n\n return (\n <>\n <div className=\"space-y-2\">\n <div className=\"p-3 border border-border rounded-md bg-muted\">\n <p className=\"text-sm text-muted-foreground\">\n Enum metadata not available. Please enter the value in JSON format.\n </p>\n <p className=\"text-xs text-muted-foreground mt-1\">\n Example: {`{\"tag\":\"One\"}`} or {`{\"tag\":\"Two\",\"values\":[42]}`}\n </p>\n </div>\n\n <Textarea\n id={id}\n {...accessibilityProps}\n className={cn('min-h-[80px]', validationClasses)}\n placeholder={`{\"tag\":\"One\"} or {\"tag\":\"Two\",\"values\":[42]}`}\n value={\n typeof field.value === 'string'\n ? field.value\n : JSON.stringify(field.value || {})\n }\n onChange={(e) => {\n try {\n // Try to parse as JSON, if successful store as object\n const parsed = JSON.parse(e.target.value);\n field.onChange(parsed);\n } catch {\n // If parsing fails, store as string (user is still typing)\n field.onChange(e.target.value);\n }\n }}\n onBlur={field.onBlur}\n name={field.name}\n disabled={readOnly}\n />\n </div>\n\n {helperText && (\n <div id={descriptionId} className=\"text-muted-foreground text-sm\">\n {helperText}\n </div>\n )}\n\n <ErrorMessage error={error} id={errorId} />\n </>\n );\n }}\n />\n </div>\n );\n }\n\n return (\n <div className={cn('flex flex-col gap-2', widthClass)}>\n {label && (\n <Label htmlFor={id}>\n {label} {isRequired && <span className=\"text-destructive\">*</span>}\n </Label>\n )}\n\n <Controller\n control={control}\n name={name}\n disabled={readOnly}\n rules={{\n validate: (value) => {\n // Use standard validation first\n const standardValidation = validateField(value, validation);\n if (standardValidation !== true) {\n return standardValidation;\n }\n\n // Handle enum-specific validation\n if (!value || !value.tag) {\n return validation?.required ? 'This field is required' : true;\n }\n\n // Run custom validation if provided\n if (validateEnum && value) {\n const customValidation = validateEnum(value);\n if (customValidation !== true && typeof customValidation === 'string') {\n return customValidation;\n }\n }\n\n return true;\n },\n }}\n render={({ field, fieldState: { error } }) => {\n const hasError = !!error;\n const currentValue: EnumFieldValue = field.value || { tag: '' };\n\n // Get accessibility attributes\n const accessibilityProps = getAccessibilityProps({\n id,\n hasError,\n isRequired,\n hasHelperText: !!helperText,\n });\n\n // Handle variant selection\n const handleVariantChange = (selectedTag: string): void => {\n const selectedVariant = enumMetadata.variants.find((v) => v.name === selectedTag);\n if (!selectedVariant) return;\n\n if (selectedVariant.type === 'void' || selectedVariant.type === 'integer') {\n // Unit variant - just set the tag\n field.onChange({ tag: selectedTag });\n } else {\n // Tuple variant - initialize with empty values (chain-agnostic)\n const initialValues = new Array(selectedVariant.payloadTypes?.length || 0).fill('');\n\n field.onChange({\n tag: selectedTag,\n values: initialValues,\n });\n }\n };\n\n // Handle payload value changes for tuple variants (chain-agnostic)\n const handlePayloadChange = (index: number, value: string): void => {\n const newValues = [...(currentValue.values || [])];\n // Simple chain-agnostic structure - just store the raw values\n newValues[index] = value;\n const newEnumValue = { ...currentValue, values: newValues };\n field.onChange(newEnumValue);\n };\n\n const selectedVariant = enumMetadata.variants.find((v) => v.name === currentValue.tag);\n\n return (\n <>\n {/* Variant Picker */}\n <Select\n value={currentValue.tag}\n onValueChange={handleVariantChange}\n disabled={readOnly}\n >\n <SelectTrigger id={id} {...accessibilityProps}>\n <SelectValue placeholder={placeholder} />\n </SelectTrigger>\n <SelectContent>\n {enumMetadata.variants.map((variant) => (\n <SelectItem key={variant.name} value={variant.name}>\n {variant.name}\n {variant.type === 'integer' && variant.value !== undefined && (\n <span className=\"text-muted-foreground ml-2\">({variant.value})</span>\n )}\n {variant.type === 'tuple' && variant.payloadTypes && (\n <span className=\"text-muted-foreground ml-2\">\n ({variant.payloadTypes.join(', ')})\n </span>\n )}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n\n {/* Conditional Payload Inputs for Tuple Variants */}\n {selectedVariant &&\n selectedVariant.type === 'tuple' &&\n selectedVariant.payloadTypes && (\n <div className=\"ml-4 space-y-2 border-l-2 border-border pl-4\">\n <p className=\"text-sm text-muted-foreground\">\n Enter values for {selectedVariant.name}:\n </p>\n {selectedVariant.payloadTypes.map((payloadType, index) => {\n // Create field configuration for payload input\n const payloadField: FormFieldType = {\n id: `${id}-payload-${index}`,\n name: `${name}.values.${index}`,\n label: payloadType,\n type: 'text' as FormFieldType['type'],\n validation: {},\n placeholder: `Enter ${payloadType} value`,\n helperText: undefined,\n width: 'full',\n originalParameterType: payloadType,\n readOnly: readOnly, // Inherit readOnly state from parent\n ...(selectedVariant.payloadComponents?.[index] && {\n components: selectedVariant.payloadComponents[index],\n }),\n };\n\n return (\n <div key={index} className=\"flex flex-col gap-1\">\n {renderPayloadField ? (\n renderPayloadField(payloadField, index)\n ) : (\n // Fallback to basic input if no render function provided\n <div className=\"flex flex-col gap-2\">\n <Label htmlFor={`${id}-payload-${index}`} className=\"text-sm\">\n {payloadType}\n </Label>\n <Input\n id={`${id}-payload-${index}`}\n type=\"text\"\n placeholder={`Enter ${payloadType} value`}\n value={(currentValue.values?.[index] as string) || ''}\n onChange={(e) => handlePayloadChange(index, e.target.value)}\n disabled={readOnly}\n />\n </div>\n )}\n </div>\n );\n })}\n </div>\n )}\n\n {/* Display helper text */}\n {helperText && (\n <div id={descriptionId} className=\"text-muted-foreground text-sm\">\n {helperText}\n </div>\n )}\n\n {/* Display error message */}\n <ErrorMessage error={error} id={errorId} />\n </>\n );\n }}\n />\n </div>\n );\n}\n\n// Set displayName manually for better debugging\nEnumField.displayName = 'EnumField';\n","import { AlertCircle, CheckCircle2, File as FileIcon, Upload, X } from 'lucide-react';\nimport { useRef, useState } from 'react';\nimport { Controller, FieldValues } from 'react-hook-form';\n\nimport { Button } from '../ui/button';\nimport { Label } from '../ui/label';\nimport { BaseFieldProps } from './BaseField';\nimport { ErrorMessage, getAccessibilityProps, validateField } from './utils';\n\n/**\n * FileUploadField component properties\n */\nexport interface FileUploadFieldProps<TFieldValues extends FieldValues = FieldValues>\n extends BaseFieldProps<TFieldValues> {\n /**\n * Accepted file types (e.g., \".zip,.tar.gz\")\n */\n accept?: string;\n /**\n * Maximum file size in bytes\n */\n maxSize?: number;\n /**\n * Whether to convert the file to base64 string\n */\n convertToBase64?: boolean;\n}\n\n/**\n * File upload field component specifically designed for React Hook Form integration.\n *\n * Architecture flow:\n * 1. Form schemas are generated from contract functions using adapters\n * 2. TransactionForm renders the overall form structure with React Hook Form\n * 3. DynamicFormField selects the appropriate field component (like FileUploadField) based on field type\n * 4. BaseField provides consistent layout and hook form integration\n * 5. This component handles file upload-specific rendering and validation\n *\n * The component includes:\n * - Integration with React Hook Form\n * - File type and size validation\n * - Optional conversion to base64 for storage\n * - Visual feedback for selected files\n * - Automatic error handling and reporting\n * - Full accessibility support with ARIA attributes\n * - Keyboard navigation\n */\n/**\n * Format bytes to human-readable size\n */\nfunction formatFileSize(bytes: number): string {\n if (bytes === 0) return '0 Bytes';\n const k = 1024;\n const sizes = ['Bytes', 'KB', 'MB', 'GB'];\n const i = Math.floor(Math.log(bytes) / Math.log(k));\n return `${parseFloat((bytes / Math.pow(k, i)).toFixed(2))} ${sizes[i]}`;\n}\n\n/** File upload field component with drag-and-drop support. */\nexport function FileUploadField<TFieldValues extends FieldValues = FieldValues>({\n id,\n label,\n placeholder = 'Drop your file here or click to browse',\n helperText,\n control,\n name,\n width = 'full',\n validation,\n readOnly,\n accept,\n maxSize,\n convertToBase64 = false,\n}: FileUploadFieldProps<TFieldValues>): React.ReactElement {\n const fileInputRef = useRef<HTMLInputElement>(null);\n const [fileName, setFileName] = useState<string>('');\n const [fileSize, setFileSize] = useState<number>(0);\n const [isProcessing, setIsProcessing] = useState(false);\n const [isDragOver, setIsDragOver] = useState(false);\n const [uploadStatus, setUploadStatus] = useState<'idle' | 'success' | 'error'>('idle');\n\n const handleFileToBase64 = (file: File): Promise<string> => {\n return new Promise((resolve, reject) => {\n const reader = new FileReader();\n reader.onload = (): void => {\n if (typeof reader.result === 'string') {\n // Remove data URL prefix to get just base64\n const parts = reader.result.split(',');\n if (parts.length !== 2) {\n reject(new Error('Invalid data URL format'));\n return;\n }\n const base64 = parts[1];\n resolve(base64);\n } else {\n reject(new Error('Failed to convert file to base64'));\n }\n };\n reader.onerror = (): void => {\n reject(reader.error);\n };\n reader.readAsDataURL(file);\n });\n };\n\n const handleFileChange = async (\n file: File | null,\n onChange: (value: string | File) => void\n ): Promise<void> => {\n if (!file) {\n setFileName('');\n setFileSize(0);\n setUploadStatus('idle');\n onChange('');\n return;\n }\n\n // Validate file size\n if (maxSize && file.size > maxSize) {\n const maxSizeMB = (maxSize / (1024 * 1024)).toFixed(2);\n onChange('');\n setFileName('');\n setFileSize(0);\n setUploadStatus('error');\n // This will trigger validation error through React Hook Form\n throw new Error(`File size exceeds ${maxSizeMB} MB limit`);\n }\n\n setFileName(file.name);\n setFileSize(file.size);\n setUploadStatus('idle');\n\n // Immediately set the File object so required-field checks pass\n // and upstream loaders can proceed without waiting for conversion.\n onChange(file);\n\n // If base64 conversion is requested, convert in background and\n // replace the value once ready (keeps UI responsive and avoids\n // triggering preflight missing-field errors).\n if (!convertToBase64) {\n setUploadStatus('success');\n return;\n }\n\n setIsProcessing(true);\n\n try {\n const base64 = await handleFileToBase64(file);\n onChange(base64);\n setUploadStatus('success');\n } catch {\n onChange('');\n setFileName('');\n setFileSize(0);\n setUploadStatus('error');\n } finally {\n setIsProcessing(false);\n }\n };\n\n const handleDragOver = (e: React.DragEvent<HTMLDivElement>): void => {\n e.preventDefault();\n e.stopPropagation();\n if (!readOnly && !isProcessing) {\n setIsDragOver(true);\n }\n };\n\n const handleDragLeave = (e: React.DragEvent<HTMLDivElement>): void => {\n e.preventDefault();\n e.stopPropagation();\n setIsDragOver(false);\n };\n\n const handleDrop = (\n e: React.DragEvent<HTMLDivElement>,\n onChange: (value: string | File) => void\n ): void => {\n e.preventDefault();\n e.stopPropagation();\n setIsDragOver(false);\n\n if (readOnly || isProcessing) return;\n\n const file = e.dataTransfer.files?.[0] || null;\n if (file) {\n handleFileChange(file, onChange);\n }\n };\n\n const clearFile = (onChange: (value: string | File) => void): void => {\n if (fileInputRef.current) {\n fileInputRef.current.value = '';\n }\n setFileName('');\n setFileSize(0);\n setUploadStatus('idle');\n onChange('');\n };\n\n return (\n <Controller\n control={control}\n name={name}\n rules={{\n validate: (value) => {\n if (!value) return validateField(value, validation);\n\n // Additional file-specific validations\n if (\n maxSize &&\n value &&\n typeof value === 'object' &&\n 'size' in value &&\n value.size > maxSize\n ) {\n const maxSizeMB = (maxSize / (1024 * 1024)).toFixed(2);\n return `File size must be less than ${maxSizeMB} MB`;\n }\n\n return validateField(value, validation);\n },\n }}\n disabled={readOnly}\n render={({ field: { onChange, onBlur }, fieldState: { error } }) => {\n const fieldId = `${id}-field`;\n const errorId = `${fieldId}-error`;\n const hasError = !!error;\n const widthClass = width === 'full' ? 'w-full' : width === 'half' ? 'w-1/2' : 'w-1/3';\n\n // Build helper text with file requirements\n const requirementsText = [];\n if (accept) {\n const types = accept\n .split(',')\n .map((t) => t.trim())\n .join(', ');\n requirementsText.push(`Accepted types: ${types}`);\n }\n if (maxSize) {\n requirementsText.push(`Max size: ${formatFileSize(maxSize)}`);\n }\n const fullHelperText = helperText || requirementsText.join(' • ');\n\n return (\n <div className={`flex flex-col gap-2 ${widthClass}`}>\n <Label htmlFor={fieldId}>\n {label}\n {validation?.required && <span className=\"text-red-500 ml-1\">*</span>}\n </Label>\n\n {/* Hidden file input */}\n <input\n ref={fileInputRef}\n id={fieldId}\n type=\"file\"\n accept={accept}\n disabled={readOnly || isProcessing}\n onBlur={onBlur}\n onChange={(e) => {\n const file = e.target.files?.[0] || null;\n handleFileChange(file, onChange);\n }}\n className=\"hidden\"\n {...getAccessibilityProps({\n id: fieldId,\n hasError,\n isRequired: validation?.required,\n isDisabled: readOnly || isProcessing,\n })}\n />\n\n {/* Drop zone / Upload area */}\n <div\n onDragOver={handleDragOver}\n onDragLeave={handleDragLeave}\n onDrop={(e) => handleDrop(e, onChange)}\n onClick={() => {\n if (!readOnly && !isProcessing && !fileName) {\n fileInputRef.current?.click();\n }\n }}\n className={`\n relative rounded-lg border-2 border-dashed transition-all duration-200\n ${\n isDragOver\n ? 'border-primary bg-primary/5'\n : hasError\n ? 'border-destructive bg-destructive/5'\n : fileName\n ? 'border-border bg-muted/30'\n : 'border-border bg-background hover:border-primary/50 hover:bg-muted/50'\n }\n ${readOnly || isProcessing ? 'cursor-not-allowed opacity-60' : fileName ? 'cursor-default' : 'cursor-pointer'}\n p-6\n `}\n >\n {!fileName ? (\n // Empty state - show upload prompt\n <div className=\"flex flex-col items-center justify-center gap-3 text-center\">\n <div\n className={`rounded-full p-3 transition-colors ${\n isDragOver ? 'bg-primary/10' : 'bg-muted'\n }`}\n >\n <Upload\n className={`h-8 w-8 transition-colors ${\n isDragOver ? 'text-primary' : 'text-muted-foreground'\n }`}\n />\n </div>\n <div className=\"space-y-1\">\n <p className=\"text-sm font-medium\">\n {isDragOver ? 'Drop file here' : placeholder}\n </p>\n {fullHelperText && !isDragOver && (\n <p className=\"text-xs text-muted-foreground\">{fullHelperText}</p>\n )}\n </div>\n </div>\n ) : (\n // File selected state\n <div className=\"flex items-start gap-4\">\n <div\n className={`rounded-lg p-2 ${\n uploadStatus === 'success'\n ? 'bg-success/10'\n : uploadStatus === 'error'\n ? 'bg-destructive/10'\n : 'bg-muted'\n }`}\n >\n <FileIcon\n className={`h-8 w-8 ${\n uploadStatus === 'success'\n ? 'text-success'\n : uploadStatus === 'error'\n ? 'text-destructive'\n : 'text-muted-foreground'\n }`}\n />\n </div>\n <div className=\"flex-1 min-w-0 space-y-1\">\n <div className=\"flex items-start justify-between gap-2\">\n <div className=\"min-w-0 flex-1\">\n <p className=\"text-sm font-medium truncate\">{fileName}</p>\n <p className=\"text-xs text-muted-foreground\">\n {formatFileSize(fileSize)}\n {isProcessing && ' • Processing...'}\n </p>\n </div>\n <div className=\"flex items-center gap-2 shrink-0\">\n {uploadStatus === 'success' && !isProcessing && (\n <CheckCircle2 className=\"h-5 w-5 text-success\" />\n )}\n {uploadStatus === 'error' && (\n <AlertCircle className=\"h-5 w-5 text-destructive\" />\n )}\n {!readOnly && !isProcessing && (\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n onClick={(e) => {\n e.stopPropagation();\n clearFile(onChange);\n }}\n className=\"h-8 w-8 p-0\"\n >\n <X className=\"h-4 w-4\" />\n </Button>\n )}\n </div>\n </div>\n {!isProcessing && (\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n disabled={readOnly}\n onClick={(e) => {\n e.stopPropagation();\n fileInputRef.current?.click();\n }}\n className=\"mt-2\"\n >\n Change file\n </Button>\n )}\n </div>\n </div>\n )}\n </div>\n\n <ErrorMessage error={error} id={errorId} />\n </div>\n );\n }}\n />\n );\n}\n","import { Plus, X } from 'lucide-react';\nimport React from 'react';\nimport { Controller, FieldValues, useFieldArray, useFormContext, useWatch } from 'react-hook-form';\n\nimport type { FormFieldType } from '@openzeppelin/ui-types';\nimport { getDefaultValueForType } from '@openzeppelin/ui-utils';\n\nimport { Button } from '../../ui/button';\nimport { Label } from '../../ui/label';\nimport { BaseFieldProps } from '../BaseField';\nimport { ErrorMessage, getAccessibilityProps } from '../utils';\nimport {\n computeChildTouched,\n MapEntryRow,\n useDuplicateKeyIndexes,\n useMapFieldSync,\n validateMapStructure,\n} from './index';\n\n/**\n * Helper function to format a label with an optional type hint\n */\nfunction formatLabeledType(baseLabel: string, typeHint?: string): string {\n if (!typeHint) {\n return baseLabel;\n }\n return `${baseLabel} (${typeHint})`;\n}\n\n/**\n * Helper function to create a default map entry with appropriate default values for key and value types\n */\nfunction createDefaultEntry(mapMetadata?: MapFieldProps['mapMetadata']): {\n key: unknown;\n value: unknown;\n} {\n return {\n key: mapMetadata?.keyFieldConfig?.type\n ? getDefaultValueForType(mapMetadata.keyFieldConfig.type)\n : '',\n value: mapMetadata?.valueFieldConfig?.type\n ? getDefaultValueForType(mapMetadata.valueFieldConfig.type)\n : '',\n };\n}\n\n/**\n * MapField component properties\n */\nexport interface MapFieldProps<TFieldValues extends FieldValues = FieldValues>\n extends BaseFieldProps<TFieldValues> {\n /**\n * Map metadata containing key and value type information\n */\n mapMetadata?: {\n keyType?: string;\n valueType?: string;\n keyFieldConfig?: Partial<FormFieldType>;\n valueFieldConfig?: Partial<FormFieldType>;\n };\n\n /**\n * Minimum number of map entries\n */\n minItems?: number;\n\n /**\n * Render function for map keys.\n * This allows the parent component to provide appropriate field components\n * based on the key type, maintaining separation of concerns.\n */\n renderKeyField?: (field: FormFieldType, entryIndex: number) => React.ReactNode;\n\n /**\n * Render function for map values.\n * This allows the parent component to provide appropriate field components\n * based on the value type, maintaining separation of concerns.\n */\n renderValueField?: (field: FormFieldType, entryIndex: number) => React.ReactNode;\n}\n\n/**\n * Map (key-value dictionary) input field component specifically designed for React Hook Form integration.\n *\n * This component provides a dynamic interface for managing map/dictionary inputs with:\n * - Add/remove functionality for key-value pairs\n * - Validation for map size constraints\n * - Integration with existing field components for keys and values\n * - Chain-agnostic data format (array of {key, value} objects)\n * - Full accessibility support\n *\n * Architecture flow:\n * 1. Form schemas are generated from contract functions using adapters\n * 2. TransactionForm renders the overall form structure with React Hook Form\n * 3. DynamicFormField selects the appropriate field component (like MapField) based on field type\n * 4. BaseField provides consistent layout and hook form integration\n * 5. This component handles map-specific rendering and validation\n *\n * The component stores data in a chain-agnostic format as an array of {key, value} objects.\n * The adapter is responsible for converting this to the chain-specific format (e.g., SorobanMapEntry[])\n * when submitting to the blockchain.\n */\nexport function MapField<TFieldValues extends FieldValues = FieldValues>({\n id,\n label,\n helperText,\n control,\n name,\n width = 'full',\n validation,\n mapMetadata,\n minItems = 0,\n renderKeyField,\n renderValueField,\n readOnly,\n}: MapFieldProps<TFieldValues>): React.ReactElement {\n const isRequired = !!validation?.required;\n const errorId = `${id}-error`;\n const descriptionId = `${id}-description`;\n\n // Get form context for field array operations\n const formContext = useFormContext();\n const effectiveControl = control || formContext.control;\n\n // Use field array for dynamic key-value pairs\n const { fields, append, remove, replace } = useFieldArray({\n control: effectiveControl,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n name: name as any, // Type assertion needed due to generic constraints\n });\n\n // Watch the map field value for duplicate key checking and initialization\n const watchedValue = useWatch({\n control: effectiveControl,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n name: name as any, // Type assertion needed due to generic constraints\n });\n const watchedValueKey = React.useMemo(() => JSON.stringify(watchedValue), [watchedValue]);\n\n // Keep field array synchronized with watched values\n const isReplacingRef = useMapFieldSync(watchedValue, fields.length, replace);\n\n /*\n * Keep the parent MapField error in sync without calling trigger:\n * - If any child has an error and the parent is required -> set a parent error\n * - Else use the structural validation result\n * This avoids re-entrancy loops that can happen when calling trigger during Preview.\n */\n React.useEffect(() => {\n if (!formContext) return;\n if (isReplacingRef.current) return;\n\n const mapArray = Array.isArray(watchedValue)\n ? (watchedValue as Array<{ key?: unknown; value?: unknown }>)\n : [];\n\n let childHasError = false;\n for (let i = 0; i < mapArray.length; i++) {\n const keyPath = `${name}.${i}.key`;\n const valuePath = `${name}.${i}.value`;\n const keyError = (formContext.formState.errors as Record<string, { message?: string }>)[\n keyPath\n ]?.message;\n const valueError = (formContext.formState.errors as Record<string, { message?: string }>)[\n valuePath\n ]?.message;\n if (keyError || valueError) {\n childHasError = true;\n break;\n }\n }\n\n const structural = validateMapStructure({\n value: watchedValue,\n required: !!validation?.required,\n minItems,\n });\n\n let nextMessage: string | undefined;\n if (childHasError && validation?.required) {\n nextMessage = 'This field is required';\n } else if (structural !== true) {\n nextMessage = structural;\n }\n\n const currentMessage = ((formContext.formState.errors as Record<string, { message?: string }>)[\n name as string\n ]?.message || undefined) as string | undefined;\n\n if (nextMessage && nextMessage !== currentMessage) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n formContext.setError(name as any, { type: 'manual', message: nextMessage });\n } else if (!nextMessage && currentMessage) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n formContext.clearErrors(name as any);\n }\n }, [\n formContext,\n name,\n watchedValue,\n watchedValueKey,\n validation?.required,\n minItems,\n isReplacingRef,\n ]);\n\n const duplicateKeyIndexes = useDuplicateKeyIndexes(watchedValue);\n\n return (\n <div\n className={`flex flex-col gap-2 ${width === 'full' ? 'w-full' : width === 'half' ? 'w-1/2' : 'w-1/3'}`}\n >\n {label && (\n <Label htmlFor={id}>\n {label} {isRequired && <span className=\"text-destructive\">*</span>}\n </Label>\n )}\n\n <Controller\n control={effectiveControl}\n name={name}\n disabled={readOnly}\n rules={{\n validate: (value) =>\n validateMapStructure({ value, required: !!validation?.required, minItems }),\n }}\n render={({ fieldState: { error, isTouched } }) => {\n // Check if any child fields have been touched to correctly determine\n // when to show the parent validation message.\n const anyChildTouched = computeChildTouched(formContext, name, watchedValue);\n const effectivelyTouched = isTouched || anyChildTouched;\n const hasError = !!error?.message;\n\n // Determine if the error message should be shown.\n // For required fields, we want to show the error immediately if the field is invalid.\n // For other fields, we only show it after the user has interacted with the component.\n const shouldShowError = hasError && (effectivelyTouched || isRequired);\n\n // Get accessibility attributes\n const accessibilityProps = getAccessibilityProps({\n id,\n hasError,\n isRequired,\n hasHelperText: !!helperText,\n });\n\n // Add new map item\n const handleAddEntry = (): void => {\n // Set flag to prevent sync interference during add operation\n isReplacingRef.current = true;\n append(createDefaultEntry(mapMetadata) as FieldValues[typeof name]);\n\n // Reset flag after operation\n queueMicrotask(() => {\n isReplacingRef.current = false;\n });\n };\n\n // Remove map item\n const handleRemoveEntry = (index: number): void => {\n if (fields.length > minItems) {\n // Set flag to prevent sync interference during remove operation\n isReplacingRef.current = true;\n remove(index);\n\n // Reset flag after operation\n queueMicrotask(() => {\n isReplacingRef.current = false;\n });\n }\n };\n\n return (\n <>\n <div\n className=\"space-y-3\"\n {...accessibilityProps}\n aria-describedby={`${helperText ? descriptionId : ''} ${hasError ? errorId : ''}`.trim()}\n >\n {fields.length === 0 ? (\n <div className=\"text-muted-foreground text-sm p-4 border border-dashed border-border rounded-md text-center\">\n No items added yet. Click “Add Item” to begin.\n </div>\n ) : (\n fields.map((field, index) => {\n // Create field configurations for key and value, following ArrayField pattern\n const isDuplicateKey = duplicateKeyIndexes.has(index);\n\n const keyField: FormFieldType = {\n ...mapMetadata?.keyFieldConfig,\n id: `${id}-key-${index}`,\n name: `${name}.${index}.key`,\n label: formatLabeledType(\n 'Key',\n mapMetadata?.keyFieldConfig?.originalParameterType || mapMetadata?.keyType\n ),\n type: mapMetadata?.keyFieldConfig?.type || 'text',\n validation: { required: true, ...mapMetadata?.keyFieldConfig?.validation },\n placeholder: mapMetadata?.keyFieldConfig?.placeholder || 'Enter key',\n width: 'full',\n readOnly: readOnly,\n originalParameterType: mapMetadata?.keyFieldConfig?.originalParameterType,\n };\n\n const valueField: FormFieldType = {\n ...mapMetadata?.valueFieldConfig,\n id: `${id}-value-${index}`,\n name: `${name}.${index}.value`,\n label: formatLabeledType(\n 'Value',\n mapMetadata?.valueFieldConfig?.originalParameterType ||\n mapMetadata?.valueType\n ),\n type: mapMetadata?.valueFieldConfig?.type || 'text',\n validation: { required: true, ...mapMetadata?.valueFieldConfig?.validation },\n placeholder: mapMetadata?.valueFieldConfig?.placeholder || 'Enter value',\n width: 'full',\n readOnly: readOnly,\n originalParameterType: mapMetadata?.valueFieldConfig?.originalParameterType,\n };\n\n return (\n <div\n key={field.id}\n className=\"flex items-start gap-2 p-3 border border-border rounded-md bg-background\"\n >\n <MapEntryRow\n keyField={keyField}\n valueField={valueField}\n isDuplicateKey={isDuplicateKey}\n renderKeyField={renderKeyField}\n renderValueField={renderValueField}\n index={index}\n />\n\n {!readOnly && fields.length > minItems && (\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n onClick={() => handleRemoveEntry(index)}\n className=\"size-8 p-0\"\n aria-label={`Remove item ${index + 1}`}\n >\n <X className=\"size-4\" />\n </Button>\n )}\n </div>\n );\n })\n )}\n\n {/* Add Item Button */}\n {!readOnly && (\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n className=\"w-full\"\n onClick={handleAddEntry}\n >\n <Plus className=\"h-4 w-4 mr-2\" />\n Add Item\n </Button>\n )}\n </div>\n\n {/* Helper text */}\n {helperText && (\n <div id={descriptionId} className=\"text-muted-foreground text-sm\">\n {helperText}\n </div>\n )}\n\n {/* Error message */}\n <ErrorMessage\n message={shouldShowError ? error?.message : undefined}\n error={error}\n id={errorId}\n />\n </>\n );\n }}\n />\n </div>\n );\n}\n\n// Set displayName manually for better debugging\nMapField.displayName = 'MapField';\n","import React from 'react';\n\nimport type { FormFieldType } from '@openzeppelin/ui-types';\n\ninterface Props {\n keyField: FormFieldType;\n valueField: FormFieldType;\n isDuplicateKey: boolean;\n renderKeyField?: (field: FormFieldType, entryIndex: number) => React.ReactNode;\n renderValueField?: (field: FormFieldType, entryIndex: number) => React.ReactNode;\n index: number;\n}\n\n/** Renders a single key-value entry row in a map field. */\nexport function MapEntryRow({\n keyField,\n valueField,\n isDuplicateKey,\n renderKeyField,\n renderValueField,\n index,\n}: Props): React.ReactElement {\n return (\n <div className=\"flex-1 grid grid-cols-1 gap-2 md:grid-cols-2\">\n <div className=\"flex flex-col gap-1\">\n {renderKeyField ? (\n <>\n {renderKeyField(keyField, index)}\n {isDuplicateKey && (\n <div className=\"text-destructive mt-1 text-sm\" role=\"alert\">\n Duplicate keys are not allowed\n </div>\n )}\n </>\n ) : (\n <div className=\"text-sm text-muted-foreground p-2 border border-dashed border-border rounded\">\n Key field type “{keyField.type}” requires a render function\n </div>\n )}\n </div>\n\n <div className=\"flex flex-col gap-1 md:items-center md:justify-center\">\n {renderValueField ? (\n renderValueField(valueField, index)\n ) : (\n <div className=\"text-sm text-muted-foreground p-2 border border-dashed border-border rounded\">\n Value field type “{valueField.type}” requires a render function\n </div>\n )}\n </div>\n </div>\n );\n}\n","import { UseFormReturn } from 'react-hook-form';\n\n/** Computes whether any child field in a map has been touched. */\nexport function computeChildTouched(\n formContext: UseFormReturn | undefined,\n name: string,\n watchedValue: unknown\n): boolean {\n const mapArray = Array.isArray(watchedValue)\n ? (watchedValue as Array<{ key?: unknown; value?: unknown }>)\n : [];\n if (!formContext || mapArray.length === 0) return false;\n\n for (let i = 0; i < mapArray.length; i++) {\n const keyPath = `${name}.${i}.key` as const;\n const valuePath = `${name}.${i}.value` as const;\n const keyState = formContext.getFieldState(keyPath, formContext.formState);\n const valueState = formContext.getFieldState(valuePath, formContext.formState);\n if (keyState.isTouched || valueState.isTouched) return true;\n }\n return false;\n}\n","import React from 'react';\n\n/** Hook that returns indexes of map entries with duplicate keys. */\nexport function useDuplicateKeyIndexes(watchedValue: unknown): Set<number> {\n return React.useMemo(() => {\n const duplicates = new Set<number>();\n if (!Array.isArray(watchedValue)) return duplicates;\n\n const keyCounts = new Map<string, number[]>();\n watchedValue.forEach((item: { key?: unknown }, index: number) => {\n const key = item?.key;\n if (key !== undefined && key !== null && key !== '') {\n const keyStr = String(key);\n if (!keyCounts.has(keyStr)) keyCounts.set(keyStr, []);\n keyCounts.get(keyStr)!.push(index);\n }\n });\n\n for (const [, indexes] of keyCounts) {\n if (indexes.length > 1) {\n indexes.forEach((i) => duplicates.add(i));\n }\n }\n return duplicates;\n }, [watchedValue]);\n}\n","import React from 'react';\n\n/**\n * Keeps a field array synchronized with a watched value's length using replace,\n * while preventing infinite loops via a guard ref.\n */\nexport function useMapFieldSync<TReplaceValue>(\n watchedValue: unknown,\n fieldsLength: number,\n replace: (value: TReplaceValue) => void\n): ReturnType<typeof React.useRef<boolean>> {\n const isReplacingRef = React.useRef(false);\n\n React.useEffect(() => {\n if (isReplacingRef.current) return;\n\n if (Array.isArray(watchedValue) && fieldsLength !== watchedValue.length) {\n isReplacingRef.current = true;\n replace(watchedValue as TReplaceValue);\n queueMicrotask(() => {\n isReplacingRef.current = false;\n });\n }\n }, [fieldsLength, watchedValue, replace]);\n\n return isReplacingRef;\n}\n","import { isMapEntryArray, MapEntry } from '@openzeppelin/ui-types';\n\nimport { validateMapEntries } from '../../utils/validation';\n\ninterface ValidateArgs {\n value: unknown;\n required: boolean;\n minItems?: number;\n}\n\n/** Validates a map field's structure including duplicates and required entries. */\nexport function validateMapStructure({ value, required, minItems }: ValidateArgs): string | true {\n // Validate that the value is actually an array of MapEntry objects\n if (!isMapEntryArray(value)) {\n if (required) return 'This field is required';\n return true;\n }\n\n const mapArray: MapEntry[] = value;\n\n const duplicateError = validateMapEntries(mapArray);\n if (duplicateError) return duplicateError;\n\n const hasPartial = mapArray.some((entry: MapEntry) => {\n const key = entry.key;\n const val = entry.value;\n const keyEmpty = key === '' || key == null;\n const valEmpty = val === '' || val == null;\n return (keyEmpty && !valEmpty) || (!keyEmpty && valEmpty);\n });\n if (hasPartial) return 'All key-value pairs must be completed';\n\n const validEntries = mapArray.filter((entry: MapEntry) => {\n const key = entry.key;\n const val = entry.value;\n return key !== '' && key != null && val !== '' && val != null;\n });\n\n if (required && validEntries.length === 0) return 'This field is required';\n\n if (minItems && validEntries.length < minItems) {\n return `At least ${minItems} item${minItems > 1 ? 's' : ''} required`;\n }\n\n return true;\n}\n","import React from 'react';\nimport { Controller, FieldValues } from 'react-hook-form';\n\nimport { Input } from '../ui/input';\nimport { Label } from '../ui/label';\nimport { BaseFieldProps } from './BaseField';\nimport {\n ErrorMessage,\n getAccessibilityProps,\n getValidationStateClasses,\n handleEscapeKey,\n validateField,\n} from './utils';\n\n/**\n * NumberField component properties\n */\nexport interface NumberFieldProps<TFieldValues extends FieldValues = FieldValues>\n extends BaseFieldProps<TFieldValues> {\n /**\n * Minimum value validation\n */\n min?: number;\n\n /**\n * Maximum value validation\n */\n max?: number;\n\n /**\n * Step value for increment/decrement\n */\n step?: number;\n\n /**\n * Custom validation function for number values\n */\n validateNumber?: (value: number) => boolean | string;\n}\n\n/**\n * Number input field component specifically designed for React Hook Form integration.\n *\n * Architecture flow:\n * 1. Form schemas are generated from contract functions using adapters\n * 2. TransactionForm renders the overall form structure with React Hook Form\n * 3. DynamicFormField selects the appropriate field component (like NumberField) based on field type\n * 4. BaseField provides consistent layout and hook form integration\n * 5. This component handles number-specific rendering and validation\n *\n * The component includes:\n * - Integration with React Hook Form\n * - Numeric-specific validations (min, max, step)\n * - Customizable validation through adapter integration\n * - Automatic error handling and reporting\n * - Full accessibility support with ARIA attributes\n * - Keyboard navigation with arrow keys for numeric increment/decrement\n */\nexport function NumberField<TFieldValues extends FieldValues = FieldValues>({\n id,\n label,\n placeholder,\n helperText,\n control,\n name,\n width = 'full',\n validation,\n min,\n max,\n step = 1,\n validateNumber,\n readOnly,\n}: NumberFieldProps<TFieldValues>): React.ReactElement {\n const isRequired = !!validation?.required;\n const errorId = `${id}-error`;\n const descriptionId = `${id}-description`;\n\n // Create merged validation that includes min/max from props\n const mergedValidation = {\n ...validation,\n min: validation?.min !== undefined ? validation.min : min,\n max: validation?.max !== undefined ? validation.max : max,\n };\n\n // Regular expressions for number validation\n const NUMBER_REGEX = {\n // Allow optional minus sign, digits, optional decimal point, more digits\n VALID_FORMAT: /^-?\\d*\\.?\\d*$/,\n // Complete number (more strict than the format check)\n COMPLETE_NUMBER: /^-?\\d+\\.?\\d*$/,\n };\n\n // Common validation for numeric values\n const validateNumericValue = (value: number): string | true => {\n // Run standard validation\n const standardValidation = validateField(value, mergedValidation);\n if (standardValidation !== true) return standardValidation as string;\n\n // Run custom validator if provided\n if (validateNumber) {\n const customValidation = validateNumber(value);\n if (customValidation !== true && typeof customValidation === 'string') {\n return customValidation;\n }\n }\n\n return true;\n };\n\n return (\n <div\n className={`flex flex-col gap-2 ${width === 'full' ? 'w-full' : width === 'half' ? 'w-1/2' : 'w-1/3'}`}\n >\n {label && (\n <Label htmlFor={id}>\n {label} {isRequired && <span className=\"text-destructive\">*</span>}\n </Label>\n )}\n\n <Controller\n control={control}\n name={name}\n rules={{\n validate: (value) => {\n // Skip validation if empty and check required separately\n if (value === undefined || value === null || value === '') {\n return mergedValidation?.required ? 'This field is required' : true;\n }\n\n // Handle incomplete number inputs\n if (value === '-') {\n return 'Please enter a complete number';\n }\n\n // Handle decimal point at the end\n if (typeof value === 'string' && value.endsWith('.')) {\n return 'Please enter a complete decimal number';\n }\n\n // For string values that passed our format check but aren't complete numbers\n if (typeof value === 'string') {\n // Parse the validated string to a number\n const parsedNum = parseFloat(value);\n if (isNaN(parsedNum)) {\n return 'Invalid number'; // Explicitly return error for NaN\n }\n return validateNumericValue(parsedNum);\n }\n\n // For already numeric values\n if (typeof value === 'number') {\n return validateNumericValue(value);\n }\n\n return true;\n },\n }}\n disabled={readOnly}\n render={({ field, fieldState: { error, isTouched } }) => {\n const hasError = !!error;\n const shouldShowError = hasError && isTouched;\n const validationClasses = getValidationStateClasses(error, isTouched);\n\n // Handle input change\n const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>): void => {\n const rawValue = e.target.value;\n\n // Check if the input matches our valid number format\n const isValidNumberFormat = NUMBER_REGEX.VALID_FORMAT.test(rawValue);\n\n if (!isValidNumberFormat && rawValue !== '') {\n // Don't update the field value for invalid formats\n // This prevents entering invalid characters\n return;\n }\n\n // For valid format or empty string\n if (rawValue === '') {\n // Empty value\n field.onChange('');\n } else if (rawValue === '-') {\n // Allow standalone minus for user to continue typing\n field.onChange(rawValue);\n } else if (rawValue.endsWith('.')) {\n // Allow numbers ending with decimal point for user to continue typing\n field.onChange(rawValue);\n } else {\n // Convert to number for valid numeric values\n const numValue = parseFloat(rawValue);\n field.onChange(isNaN(numValue) ? rawValue : numValue);\n }\n\n // Note: Validation happens naturally when user leaves the field\n // No need to trigger it programmatically on every change\n };\n\n // Handle keyboard events\n const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>): void => {\n // Allow only numeric characters, backspace, delete, tab, escape, enter, arrows, period, hyphen\n // This is a basic filter; more complex scenarios might need a more robust solution\n const allowedKeys = [\n '0',\n '1',\n '2',\n '3',\n '4',\n '5',\n '6',\n '7',\n '8',\n '9',\n 'Backspace',\n 'Delete',\n 'Tab',\n 'Escape',\n 'Enter',\n 'ArrowLeft',\n 'ArrowRight',\n 'ArrowUp',\n 'ArrowDown',\n '.',\n '-',\n ];\n\n // Allow Ctrl/Cmd+A, C, V, X, Z for common editing operations\n if (\n (e.ctrlKey || e.metaKey) &&\n ['a', 'c', 'v', 'x', 'z'].includes(e.key.toLowerCase())\n ) {\n return;\n }\n\n if (!allowedKeys.includes(e.key) && !e.ctrlKey && !e.metaKey) {\n e.preventDefault();\n }\n\n // Handle escape key to clear input\n if (e.key === 'Escape') {\n handleEscapeKey(field.onChange, field.value)(e);\n return;\n }\n\n // Handle arrow keys for increment/decrement\n if (e.key === 'ArrowUp' || e.key === 'ArrowDown') {\n e.preventDefault(); // Prevent default browser behavior\n\n // Get current value as number or default to 0\n let currentValue = 0;\n if (typeof field.value === 'number') {\n currentValue = field.value;\n } else if (\n typeof field.value === 'string' &&\n NUMBER_REGEX.COMPLETE_NUMBER.test(field.value)\n ) {\n currentValue = parseFloat(field.value);\n }\n\n // Calculate new value based on step, respecting min/max\n const increment = e.key === 'ArrowUp' ? step : -step;\n const newValue = Math.min(\n max !== undefined ? max : Infinity,\n Math.max(min !== undefined ? min : -Infinity, currentValue + increment)\n );\n\n // Update the field\n field.onChange(newValue);\n // Note: Validation happens naturally, no need to trigger it programmatically\n }\n };\n\n // Get accessibility attributes\n const accessibilityProps = getAccessibilityProps({\n id,\n hasError,\n isRequired,\n hasHelperText: !!helperText,\n });\n\n return (\n <>\n <Input\n {...field}\n value={field.value ?? ''}\n id={id}\n placeholder={placeholder}\n type=\"text\"\n min={min}\n max={max}\n step={step}\n className={validationClasses}\n onKeyDown={handleKeyDown}\n data-slot=\"input\"\n onChange={handleInputChange}\n inputMode=\"decimal\"\n pattern=\"-?[0-9]*\\.?[0-9]*\"\n {...accessibilityProps}\n aria-describedby={`${helperText ? descriptionId : ''} ${hasError ? errorId : ''}`}\n disabled={readOnly}\n />\n\n {/* Display helper text */}\n {helperText && (\n <div id={descriptionId} className=\"text-muted-foreground text-sm\">\n {helperText}\n </div>\n )}\n\n {/* Display error message */}\n <ErrorMessage\n error={error}\n id={errorId}\n message={shouldShowError ? error?.message : undefined}\n />\n </>\n );\n }}\n />\n </div>\n );\n}\n\n// Set displayName manually for better debugging\nNumberField.displayName = 'NumberField';\n","import React from 'react';\nimport { Control, Controller, FieldValues, useFormContext } from 'react-hook-form';\n\nimport type {\n ContractAdapter,\n ContractSchema,\n FormFieldType,\n FunctionParameter,\n} from '@openzeppelin/ui-types';\n\n// TODO: Consider if FunctionParameter is the most appropriate type for `components` here,\n// or if a UI-specific version of a component/property definition would be more robust.\n\nimport { Card } from '../ui/card';\nimport { Label } from '../ui/label';\nimport { BaseFieldProps } from './BaseField';\nimport { ErrorMessage, getAccessibilityProps } from './utils';\n\n/**\n * ObjectField component properties\n */\nexport interface ObjectFieldProps<TFieldValues extends FieldValues = FieldValues>\n extends BaseFieldProps<TFieldValues> {\n /**\n * The components/properties of the object.\n * These define the schema for the nested fields within the object.\n */\n components?: FunctionParameter[]; // TODO: As above, review type for `components`.\n\n /**\n * Render function for object properties.\n * This is crucial for rendering complex properties or integrating custom field components.\n */\n // TODO: Explore a fallback rendering mechanism if `renderProperty` is not provided,\n // especially for known simple property types (e.g., 'text', 'number').\n // This could make the component more self-contained for basic object structures.\n renderProperty?: (field: FormFieldType, propertyName: string) => React.ReactNode;\n\n /**\n * Whether to show the object in a card container.\n * Useful for visually grouping object properties.\n */\n // TODO: Consider more advanced layout options beyond a simple card,\n // e.g., tabs, accordions for very complex objects, or grid layouts.\n showCard?: boolean;\n\n /**\n * The adapter for chain-specific type mapping.\n * Essential for correctly determining field types for object properties.\n */\n adapter?: ContractAdapter;\n\n /**\n * Optional contract schema for nested metadata (structs/enums).\n */\n contractSchema?: ContractSchema;\n}\n\n/**\n * Object (composite/nested) input field component specifically designed for React Hook Form integration.\n *\n * This component provides a structured interface for managing object inputs with:\n * - Nested field rendering based on object components\n * - Validation for required properties (currently, the object itself can be required)\n * - Integration with existing field components for object properties\n * - Full accessibility support\n *\n * The component reuses existing field components for individual properties,\n * maintaining consistency across the form system while supporting complex nested structures.\n */\nexport function ObjectField<TFieldValues extends FieldValues = FieldValues>({\n id,\n label,\n helperText,\n control,\n name,\n width = 'full',\n validation,\n components = [],\n renderProperty,\n showCard = true,\n readOnly,\n adapter,\n contractSchema,\n}: ObjectFieldProps<TFieldValues>): React.ReactElement {\n const isRequired = !!validation?.required;\n const errorId = `${id}-error`;\n const descriptionId = `${id}-description`;\n\n // Get form context for nested field registration\n const formContext = useFormContext();\n const effectiveControl = control || formContext.control;\n\n // TODO: Consider performance implications for very large/deeply nested objects.\n // For extremely complex objects, virtualization or other rendering strategies might be needed.\n\n return (\n <Controller\n control={effectiveControl as Control<FieldValues>}\n name={name}\n rules={{\n // TODO: Expand validation capabilities for objects.\n // Current validation only checks if the object itself is required.\n // Future: Allow schema-level validation for individual properties within the object,\n // or a custom validate function that receives the whole object value.\n validate: (value) => {\n // Validate object constraints\n if (\n validation?.required &&\n (!value || typeof value !== 'object' || Array.isArray(value))\n ) {\n return 'This field is required';\n }\n\n // Additional object validation can be added here (e.g., based on `components` schema)\n return true;\n },\n }}\n render={({ fieldState: { error } }) => {\n const hasError = !!error;\n\n // Get accessibility attributes\n const accessibilityProps = getAccessibilityProps({\n id,\n hasError,\n isRequired,\n hasHelperText: !!helperText,\n });\n\n const content = (\n <>\n {/* Object properties */}\n <div className=\"space-y-4\">\n {components.length === 0 ? (\n <div className=\"text-muted-foreground text-sm\">\n No properties defined for this object\n </div>\n ) : (\n components.map((component) => {\n // Generate field using adapter to get full configuration including elementType for arrays\n if (!adapter) {\n throw new Error(\n `ObjectField: No adapter provided for field generation. Cannot generate field for \"${component.name}\"`\n );\n }\n\n const generatedField = adapter.generateDefaultField(component, contractSchema);\n\n // Override with object-specific configuration\n const propertyField: FormFieldType = {\n ...generatedField, // Include elementType and other adapter-specific properties\n id: `${id}-${component.name}`,\n name: `${name}.${component.name}`,\n label: component.displayName || component.name,\n // Validation merging precedence:\n // 1. Spread generatedField.validation (adapter-provided bounds, etc.)\n // 2. Override 'required' from parent validation if specified\n // This preserves min/max bounds while allowing parent to control required state\n validation: {\n ...generatedField.validation, // Preserve validation from adapter (includes min/max bounds)\n required: validation?.required, // Override required from parent\n },\n placeholder: `Enter ${component.displayName || component.name}`,\n helperText:\n component.description ||\n (generatedField.type === 'number' ? 'Numbers only' : undefined),\n width: 'full',\n readOnly,\n // Pass components for nested objects (tuples within a struct)\n ...(component.components && {\n components: component.components,\n }),\n };\n\n return (\n <div key={component.name}>\n {renderProperty ? (\n renderProperty(propertyField, component.name)\n ) : (\n // This fallback is okay, but a more robust solution might attempt to\n // render a default UI field based on `propertyField.type` if it's a known simple type.\n <div className=\"text-sm text-muted-foreground\">\n Property “{component.name}” requires a render function\n </div>\n )}\n </div>\n );\n })\n )}\n </div>\n\n {/* Helper text for the entire object */}\n {helperText && (\n <div id={descriptionId} className=\"text-muted-foreground text-sm mt-2\">\n {helperText}\n </div>\n )}\n\n {/* Error message for the entire object */}\n <ErrorMessage error={error} id={errorId} />\n </>\n );\n\n return (\n <div\n className={`flex flex-col gap-2 ${width === 'full' ? 'w-full' : width === 'half' ? 'w-1/2' : 'w-1/3'}`}\n {...accessibilityProps}\n aria-describedby={`${helperText ? descriptionId : ''} ${hasError ? errorId : ''}`}\n >\n {/* Label for the entire object */}\n {label && (\n <Label htmlFor={id}>\n {label} {isRequired && <span className=\"text-destructive\">*</span>}\n </Label>\n )}\n\n {/* TODO: Conditional rendering of Card based on `showCard` and `components.length`.\n Perhaps don't render a card if there are no components or if showCard is false.\n Currently, an empty card might be rendered if components is empty but showCard is true. */}\n {showCard ? <Card className=\"p-4\">{content}</Card> : content}\n </div>\n );\n }}\n />\n );\n}\n\n// Set display name for debugging\nObjectField.displayName = 'ObjectField';\n","import { Eye, EyeOff } from 'lucide-react';\nimport React, { useState } from 'react';\nimport { Controller, FieldValues } from 'react-hook-form';\n\nimport { Button } from '../ui/button';\nimport { Input } from '../ui/input';\nimport { Label } from '../ui/label';\nimport { BaseFieldProps } from './BaseField';\nimport {\n ErrorMessage,\n getAccessibilityProps,\n getValidationStateClasses,\n handleEscapeKey,\n validateField,\n} from './utils';\n\n/**\n * PasswordField component properties\n */\nexport interface PasswordFieldProps<TFieldValues extends FieldValues = FieldValues>\n extends BaseFieldProps<TFieldValues> {\n /**\n * Placeholder text displayed when the field is empty\n */\n placeholder?: string;\n\n /**\n * Whether to show the password visibility toggle button\n * @default true\n */\n showToggle?: boolean;\n}\n\n/**\n * Password input field component specifically designed for React Hook Form integration.\n *\n * Architecture flow:\n * 1. Form schemas are generated from contract functions using adapters\n * 2. TransactionForm renders the overall form structure with React Hook Form\n * 3. DynamicFormField selects the appropriate field component (like PasswordField) based on field type\n * 4. BaseField provides consistent layout and hook form integration\n * 5. This component handles password-specific rendering and validation\n *\n * The component includes:\n * - Integration with React Hook Form\n * - Password visibility toggle functionality\n * - Password-specific validations (minLength, maxLength, pattern)\n * - Customizable validation through adapter integration\n * - Automatic error handling and reporting\n * - Full accessibility support with ARIA attributes\n * - Keyboard navigation\n */\nexport function PasswordField<TFieldValues extends FieldValues = FieldValues>({\n id,\n label,\n placeholder,\n helperText,\n control,\n name,\n width = 'full',\n validation,\n readOnly,\n showToggle = true,\n}: PasswordFieldProps<TFieldValues>): React.ReactElement {\n const [showPassword, setShowPassword] = useState(false);\n const isRequired = !!validation?.required;\n const errorId = `${id}-error`;\n const descriptionId = `${id}-description`;\n\n // Function for validating password values\n const validatePasswordValue = (value: string): string | true => {\n const validationResult = validateField(value, validation);\n return validationResult === true ? true : (validationResult as string);\n };\n\n // Toggle password visibility\n const togglePasswordVisibility = (): void => {\n setShowPassword((prev) => !prev);\n };\n\n return (\n <div\n className={`flex flex-col gap-2 ${width === 'full' ? 'w-full' : width === 'half' ? 'w-1/2' : 'w-1/3'}`}\n >\n {label && (\n <Label htmlFor={id}>\n {label} {isRequired && <span className=\"text-destructive\">*</span>}\n </Label>\n )}\n\n <Controller\n control={control}\n name={name}\n rules={{\n validate: (value) => {\n // Handle required validation explicitly\n if (value === undefined || value === null || value === '') {\n return validation?.required ? 'This field is required' : true;\n }\n\n // Validate password values\n if (typeof value === 'string') {\n return validatePasswordValue(value);\n }\n\n return true;\n },\n }}\n disabled={readOnly}\n render={({ field, fieldState: { error, isTouched } }) => {\n const hasError = !!error;\n const shouldShowError = hasError && isTouched;\n const validationClasses = getValidationStateClasses(error, isTouched);\n\n // Handle input change with validation for required fields\n const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>): void => {\n const value = e.target.value;\n field.onChange(value);\n\n // Trigger validation if the field is required and empty\n if (isRequired && value === '') {\n setTimeout(() => field.onBlur(), 0);\n }\n };\n\n // Handle keyboard events\n const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>): void => {\n if (e.key === 'Escape') {\n handleEscapeKey(field.onChange, field.value)(e);\n\n // If required, trigger validation after clearing\n if (isRequired) {\n setTimeout(() => field.onBlur(), 0);\n }\n }\n };\n\n // Get accessibility attributes\n const accessibilityProps = getAccessibilityProps({\n id,\n hasError,\n isRequired,\n hasHelperText: !!helperText,\n });\n\n return (\n <>\n <div className=\"relative\">\n <Input\n {...field}\n id={id}\n type={showPassword ? 'text' : 'password'}\n placeholder={placeholder}\n className={`${validationClasses} ${showToggle ? 'pr-10' : ''}`}\n onChange={handleInputChange}\n onKeyDown={handleKeyDown}\n data-slot=\"input\"\n value={field.value ?? ''}\n {...accessibilityProps}\n aria-describedby={`${helperText ? descriptionId : ''} ${hasError ? errorId : ''}`}\n disabled={readOnly}\n />\n {showToggle && !readOnly && (\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n className=\"absolute right-0 top-0 h-full px-3 py-2 hover:bg-transparent\"\n onClick={togglePasswordVisibility}\n aria-label={showPassword ? 'Hide password' : 'Show password'}\n >\n {showPassword ? (\n <EyeOff className=\"h-4 w-4 text-muted-foreground\" />\n ) : (\n <Eye className=\"h-4 w-4 text-muted-foreground\" />\n )}\n </Button>\n )}\n </div>\n\n {/* Display helper text */}\n {helperText && (\n <div id={descriptionId} className=\"text-muted-foreground text-sm\">\n {helperText}\n </div>\n )}\n\n {/* Display error message */}\n <ErrorMessage\n error={error}\n id={errorId}\n message={shouldShowError ? error?.message : undefined}\n />\n </>\n );\n }}\n />\n </div>\n );\n}\n\n// Set displayName manually for better debugging\nPasswordField.displayName = 'PasswordField';\n","import React from 'react';\nimport { Controller, FieldValues } from 'react-hook-form';\n\nimport { Label } from '../ui/label';\nimport { BaseFieldProps } from './BaseField';\nimport { ErrorMessage, getAccessibilityProps } from './utils';\n\n/**\n * Option item for radio fields\n */\nexport interface RadioOption {\n /**\n * Value to be submitted with the form\n */\n value: string;\n\n /**\n * Display label for the option\n */\n label: string;\n\n /**\n * Whether this option is disabled\n */\n disabled?: boolean;\n}\n\n/**\n * RadioField component properties\n */\nexport interface RadioFieldProps<TFieldValues extends FieldValues = FieldValues>\n extends BaseFieldProps<TFieldValues> {\n /**\n * Available options for selection\n */\n options?: RadioOption[];\n\n /**\n * Direction of radio options layout\n */\n layout?: 'horizontal' | 'vertical';\n\n /**\n * Custom validation function for radio values\n */\n validateRadio?: (value: string) => boolean | string;\n}\n\n/**\n * Radio button field component specifically designed for React Hook Form integration.\n *\n * Architecture flow:\n * 1. Form schemas are generated from contract functions using adapters\n * 2. TransactionForm renders the overall form structure with React Hook Form\n * 3. DynamicFormField selects the appropriate field component based on field type\n * 4. BaseField provides consistent layout and hook form integration\n * 5. This component handles radio-specific rendering and validation\n *\n * The component includes:\n * - Integration with React Hook Form\n * - Customizable options list\n * - Horizontal or vertical layout options\n * - Customizable validation through adapter integration\n * - Automatic error handling and reporting\n * - Full accessibility support with ARIA attributes\n */\nexport function RadioField<TFieldValues extends FieldValues = FieldValues>({\n id,\n label,\n helperText,\n control,\n name,\n width = 'full',\n validation,\n options = [],\n layout = 'vertical',\n validateRadio,\n}: RadioFieldProps<TFieldValues>): React.ReactElement {\n const isRequired = !!validation?.required;\n const errorId = `${id}-error`;\n const descriptionId = `${id}-description`;\n const radioGroupId = `${id}-group`;\n\n return (\n <div\n className={`flex flex-col gap-2 ${width === 'full' ? 'w-full' : width === 'half' ? 'w-1/2' : 'w-1/3'}`}\n >\n {label && (\n <Label htmlFor={radioGroupId} className=\"text-sm font-medium\">\n {label} {isRequired && <span className=\"text-destructive\">*</span>}\n </Label>\n )}\n\n <Controller\n control={control}\n name={name}\n rules={{\n validate: (value) => {\n // Handle required validation explicitly\n if (value === undefined || value === null || value === '') {\n return validation?.required ? 'This field is required' : true;\n }\n\n // Run custom validation if provided\n if (validateRadio && value) {\n const validation = validateRadio(value);\n if (validation !== true && typeof validation === 'string') {\n return validation;\n }\n }\n\n return true;\n },\n }}\n render={({ field, fieldState: { error } }) => {\n const hasError = !!error;\n\n // Group accessibility attributes\n const groupAccessibilityProps = getAccessibilityProps({\n id: radioGroupId,\n hasError,\n isRequired,\n hasHelperText: !!helperText,\n });\n\n return (\n <>\n <div\n id={radioGroupId}\n role=\"radiogroup\"\n className={`flex ${layout === 'vertical' ? 'flex-col gap-3' : 'flex-row flex-wrap gap-4'}`}\n aria-describedby={`${helperText ? descriptionId : ''} ${hasError ? errorId : ''}`}\n {...groupAccessibilityProps}\n >\n {options.map((option, index) => {\n const optionId = `${id}-option-${index}`;\n const isSelected = field.value === option.value;\n const isDisabled = option.disabled;\n\n return (\n <label\n key={option.value}\n htmlFor={optionId}\n className={`group relative flex cursor-pointer items-center gap-2 rounded-lg px-3 py-2 transition-all duration-150 ${\n isDisabled ? 'cursor-not-allowed opacity-50' : 'hover:bg-muted/50'\n } ${isSelected && !hasError ? 'bg-primary/5' : ''}`}\n >\n <input\n type=\"radio\"\n id={optionId}\n value={option.value}\n disabled={isDisabled}\n checked={isSelected}\n onChange={() => field.onChange(option.value)}\n className=\"sr-only\"\n aria-describedby={hasError ? errorId : undefined}\n />\n\n {/* Custom Radio Button */}\n <div className=\"relative flex size-4 items-center justify-center\">\n <div\n className={`absolute size-4 rounded-full border-2 transition-all duration-150 ${\n isSelected\n ? hasError\n ? 'border-destructive bg-destructive/10'\n : 'border-primary bg-primary/10'\n : hasError\n ? 'border-destructive/50'\n : 'border-muted-foreground/40 group-hover:border-muted-foreground/60'\n } ${!isDisabled && 'group-hover:scale-105'}`}\n />\n\n {/* Inner dot for selected state */}\n <div\n className={`absolute size-1.5 rounded-full transition-all duration-150 ${\n isSelected\n ? hasError\n ? 'bg-destructive scale-100 opacity-100'\n : 'bg-primary scale-100 opacity-100'\n : 'scale-0 opacity-0'\n }`}\n />\n </div>\n\n {/* Label text */}\n <span\n className={`text-sm transition-colors duration-150 ${\n isDisabled\n ? 'text-muted-foreground'\n : isSelected\n ? hasError\n ? 'text-destructive font-medium'\n : 'text-foreground font-medium'\n : 'text-foreground'\n }`}\n >\n {option.label}\n </span>\n\n {/* Focus ring */}\n <div\n className={`absolute -inset-1 rounded-lg ring-2 ring-primary ring-offset-2 ring-offset-background transition-opacity duration-150 ${\n isSelected && !isDisabled\n ? 'opacity-0 focus-within:opacity-100'\n : 'opacity-0'\n }`}\n />\n </label>\n );\n })}\n </div>\n\n {/* Display helper text */}\n {helperText && (\n <div id={descriptionId} className=\"text-sm text-muted-foreground\">\n {helperText}\n </div>\n )}\n\n {/* Display error message */}\n <ErrorMessage error={error} id={errorId} />\n </>\n );\n }}\n />\n </div>\n );\n}\n\n// Set displayName manually for better debugging\nRadioField.displayName = 'RadioField';\n","import React from 'react';\nimport { Controller, FieldValues } from 'react-hook-form';\n\nimport { cn } from '@openzeppelin/ui-utils';\n\nimport { Label } from '../ui/label';\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '../ui/select';\nimport { BaseFieldProps } from './BaseField';\nimport { ErrorMessage } from './utils';\n\n/**\n * Option item for select fields\n */\nexport interface SelectOption {\n /**\n * Value to be submitted with the form\n */\n value: string;\n\n /**\n * Display label for the option\n */\n label: string;\n\n /**\n * Whether this option is disabled\n */\n disabled?: boolean;\n}\n\n/**\n * SelectField component properties\n */\nexport interface SelectFieldProps<TFieldValues extends FieldValues = FieldValues>\n extends BaseFieldProps<TFieldValues> {\n /**\n * Available options for selection\n */\n options?: SelectOption[];\n\n /**\n * Custom validation function for select values\n */\n validateSelect?: (value: string) => boolean | string;\n\n /**\n * Optional default value used when the field has no value yet\n */\n defaultValue?: string;\n}\n\n/**\n * Select dropdown field component specifically designed for React Hook Form integration.\n *\n * Architecture flow:\n * 1. Form schemas are generated from contract functions using adapters\n * 2. TransactionForm renders the overall form structure with React Hook Form\n * 3. DynamicFormField selects the appropriate field component based on field type\n * 4. BaseField provides consistent layout and hook form integration\n * 5. This component handles radio-specific rendering and validation\n *\n * The component includes:\n * - Integration with React Hook Form\n * - Customizable options list\n * - Horizontal or vertical layout options\n * - Customizable validation through adapter integration\n * - Automatic error handling and reporting\n * - Full accessibility support with ARIA attributes\n */\nexport function SelectField<TFieldValues extends FieldValues = FieldValues>({\n id,\n label,\n placeholder = 'Select an option',\n helperText,\n control,\n name,\n width = 'full',\n validation,\n options = [],\n validateSelect,\n defaultValue,\n}: SelectFieldProps<TFieldValues>): React.ReactElement {\n const isRequired = !!validation?.required;\n const errorId = `${id}-error`;\n const descriptionId = `${id}-description`;\n\n // Determine width values\n const widthPercentage = width === 'full' ? '100%' : width === 'half' ? '50%' : '33.333%';\n const widthClass = width === 'full' ? 'w-full' : width === 'half' ? 'w-1/2' : 'w-1/3';\n\n return (\n <div className={cn('flex flex-col gap-2', widthClass)} style={{ width: widthPercentage }}>\n {label && (\n <Label htmlFor={id}>\n {label} {isRequired && <span className=\"text-destructive\">*</span>}\n </Label>\n )}\n\n <Controller\n control={control}\n name={name}\n defaultValue={defaultValue as unknown as undefined}\n rules={{\n validate: (value) => {\n // Handle required validation explicitly\n if (value === undefined || value === null || value === '') {\n return validation?.required ? 'This field is required' : true;\n }\n\n // Run custom validation if provided\n if (validateSelect && value) {\n const validation = validateSelect(value);\n if (validation !== true && typeof validation === 'string') {\n return validation;\n }\n }\n\n return true;\n },\n }}\n render={({ field, fieldState: { error } }) => {\n const hasError = !!error;\n\n // Get accessibility attributes\n const accessibilityAttrs = {\n 'aria-invalid': hasError,\n 'aria-required': isRequired,\n 'aria-describedby':\n `${helperText ? descriptionId : ''} ${hasError ? errorId : ''}`.trim(),\n };\n\n // Ensure we properly handle the onValueChange event\n const handleValueChange = (newValue: string): void => {\n field.onChange(newValue);\n };\n\n return (\n <>\n <Select\n defaultValue={field.value}\n onValueChange={handleValueChange}\n value={field.value}\n >\n <SelectTrigger id={id} {...accessibilityAttrs}>\n <SelectValue placeholder={placeholder} />\n </SelectTrigger>\n <SelectContent\n // Ensure dropdown width matches trigger width\n style={{\n width: 'var(--radix-select-trigger-width)',\n maxWidth: 'var(--radix-select-trigger-width)',\n }}\n >\n {options.length === 0 ? (\n <div className=\"px-2 py-1.5 text-sm text-muted-foreground\">\n No options available\n </div>\n ) : (\n options.map((option) => (\n <SelectItem\n key={option.value}\n value={option.value}\n disabled={option.disabled}\n >\n {option.label}\n </SelectItem>\n ))\n )}\n </SelectContent>\n </Select>\n\n {/* Display helper text */}\n {helperText && (\n <div id={descriptionId} className=\"text-muted-foreground text-sm\">\n {helperText}\n </div>\n )}\n\n {/* Display error message */}\n <ErrorMessage error={error} id={errorId} />\n </>\n );\n }}\n />\n </div>\n );\n}\n\n// Set displayName manually for better debugging\nSelectField.displayName = 'SelectField';\n","import React from 'react';\nimport { Controller, FieldValues } from 'react-hook-form';\n\nimport { cn } from '@openzeppelin/ui-utils';\n\nimport { Label } from '../ui/label';\nimport {\n Select,\n SelectContent,\n SelectGroup,\n SelectItem,\n SelectLabel,\n SelectSeparator,\n SelectTrigger,\n SelectValue,\n} from '../ui/select';\nimport { BaseFieldProps } from './BaseField';\nimport { ErrorMessage } from './utils';\n\n/**\n * Option item for select fields with visual indicators\n */\nexport interface GroupedSelectOption {\n /**\n * Value to be submitted with the form\n */\n value: string;\n\n /**\n * Display label for the option\n */\n label: string;\n\n /**\n * Whether this option is disabled\n */\n disabled?: boolean;\n\n /**\n * Custom CSS class to apply to the option\n */\n className?: string;\n}\n\n/**\n * Option group structure\n */\nexport interface OptionGroup {\n /**\n * Group label to display\n */\n label: string;\n\n /**\n * Options within this group\n */\n options: GroupedSelectOption[];\n}\n\n/**\n * SelectGroupedField component properties\n */\nexport interface SelectGroupedFieldProps<TFieldValues extends FieldValues = FieldValues>\n extends BaseFieldProps<TFieldValues> {\n /**\n * Available option groups for selection\n */\n groups?: OptionGroup[];\n\n /**\n * Custom validation function for select values\n */\n validateSelect?: (value: string) => boolean | string;\n}\n\n/**\n * Select dropdown field component with grouped options specifically designed for React Hook Form integration.\n *\n * Architecture flow:\n * 1. Form schemas are generated from contract functions using adapters\n * 2. TransactionForm renders the overall form structure with React Hook Form\n * 3. DynamicFormField selects the appropriate field component based on field type\n * 4. BaseField provides consistent layout and hook form integration\n * 5. This component handles radio-specific rendering and validation\n *\n * The component includes:\n * - Integration with React Hook Form\n * - Customizable options list\n * - Horizontal or vertical layout options\n * - Customizable validation through adapter integration\n * - Automatic error handling and reporting\n * - Full accessibility support with ARIA attributes\n */\nexport function SelectGroupedField<TFieldValues extends FieldValues = FieldValues>({\n id,\n label,\n placeholder = 'Select an option',\n helperText,\n control,\n name,\n width = 'full',\n validation,\n groups = [],\n validateSelect,\n}: SelectGroupedFieldProps<TFieldValues>): React.ReactElement {\n const isRequired = !!validation?.required;\n const errorId = `${id}-error`;\n const descriptionId = `${id}-description`;\n\n // Determine width values\n const widthPercentage = width === 'full' ? '100%' : width === 'half' ? '50%' : '33.333%';\n const widthClass = width === 'full' ? 'w-full' : width === 'half' ? 'w-1/2' : 'w-1/3';\n\n return (\n <div className={cn('flex flex-col gap-2', widthClass)} style={{ width: widthPercentage }}>\n {label && (\n <Label htmlFor={id}>\n {label} {isRequired && <span className=\"text-destructive\">*</span>}\n </Label>\n )}\n\n <Controller\n control={control}\n name={name}\n rules={{\n validate: (value) => {\n // Handle required validation explicitly\n if (value === undefined || value === null || value === '') {\n return validation?.required ? 'This field is required' : true;\n }\n\n // Run custom validation if provided\n if (validateSelect && value) {\n const validation = validateSelect(value);\n if (validation !== true && typeof validation === 'string') {\n return validation;\n }\n }\n\n return true;\n },\n }}\n render={({ field, fieldState: { error } }) => {\n const hasError = !!error;\n\n // Get accessibility attributes\n const accessibilityAttrs = {\n 'aria-invalid': hasError,\n 'aria-required': isRequired,\n 'aria-describedby':\n `${helperText ? descriptionId : ''} ${hasError ? errorId : ''}`.trim(),\n };\n\n // Ensure we properly handle the onValueChange event\n const handleValueChange = (newValue: string): void => {\n field.onChange(newValue);\n };\n\n return (\n <>\n <Select\n defaultValue={field.value}\n onValueChange={handleValueChange}\n value={field.value}\n >\n <SelectTrigger id={id} {...accessibilityAttrs}>\n <SelectValue placeholder={placeholder} />\n </SelectTrigger>\n <SelectContent\n // Ensure dropdown width matches trigger width\n style={{\n width: 'var(--radix-select-trigger-width)',\n maxWidth: 'var(--radix-select-trigger-width)',\n }}\n >\n {groups.map((group, groupIndex) => (\n <React.Fragment key={`group-${groupIndex}`}>\n {groupIndex > 0 && <SelectSeparator />}\n <SelectGroup>\n <SelectLabel>{group.label}</SelectLabel>\n {group.options.map((option) => (\n <SelectItem\n key={option.value}\n value={option.value}\n disabled={option.disabled}\n className={cn(option.className, option.disabled && 'opacity-50')}\n >\n <span>{option.label}</span>\n </SelectItem>\n ))}\n </SelectGroup>\n </React.Fragment>\n ))}\n </SelectContent>\n </Select>\n\n {/* Display helper text */}\n {helperText && (\n <div id={descriptionId} className=\"text-muted-foreground text-sm\">\n {helperText}\n </div>\n )}\n\n {/* Display error message */}\n <ErrorMessage error={error} id={errorId} />\n </>\n );\n }}\n />\n </div>\n );\n}\n\n// Set displayName manually for better debugging\nSelectGroupedField.displayName = 'SelectGroupedField';\n","import React from 'react';\nimport { Controller, FieldValues } from 'react-hook-form';\n\nimport { Label } from '../ui/label';\nimport { Textarea } from '../ui/textarea';\nimport { BaseFieldProps } from './BaseField';\nimport {\n ErrorMessage,\n getAccessibilityProps,\n getValidationStateClasses,\n handleEscapeKey,\n} from './utils';\n\n/**\n * TextAreaField component properties\n */\nexport interface TextAreaFieldProps<TFieldValues extends FieldValues = FieldValues>\n extends BaseFieldProps<TFieldValues> {\n /**\n * Number of rows for the textarea\n */\n rows?: number;\n\n /**\n * Maximum characters allowed in textarea\n */\n maxLength?: number;\n\n /**\n * Custom validation function for textarea values\n */\n validateTextArea?: (value: string) => boolean | string;\n}\n\n/**\n * Multi-line text input field component specifically designed for React Hook Form integration.\n *\n * Architecture flow:\n * 1. Form schemas are generated from contract functions using adapters\n * 2. TransactionForm renders the overall form structure with React Hook Form\n * 3. DynamicFormField selects the appropriate field component based on field type\n * 4. BaseField provides consistent layout and hook form integration\n * 5. This component handles textarea-specific rendering and validation\n *\n * The component includes:\n * - Integration with React Hook Form\n * - Resizable multi-line text input\n * - Character limit support\n * - Customizable validation through adapter integration\n * - Automatic error handling and reporting\n * - Full accessibility support with ARIA attributes\n * - Keyboard navigation with Escape to clear\n */\nexport function TextAreaField<TFieldValues extends FieldValues = FieldValues>({\n id,\n label,\n placeholder,\n helperText,\n control,\n name,\n width = 'full',\n validation,\n rows = 4,\n maxLength,\n validateTextArea,\n}: TextAreaFieldProps<TFieldValues>): React.ReactElement {\n const isRequired = !!validation?.required;\n const errorId = `${id}-error`;\n const descriptionId = `${id}-description`;\n\n return (\n <div\n className={`flex flex-col gap-2 ${width === 'full' ? 'w-full' : width === 'half' ? 'w-1/2' : 'w-1/3'}`}\n >\n {label && (\n <Label htmlFor={id}>\n {label} {isRequired && <span className=\"text-destructive\">*</span>}\n </Label>\n )}\n\n <Controller\n control={control}\n name={name}\n rules={{\n validate: (value) => {\n // Handle required validation explicitly\n if (value === undefined || value === null || value === '') {\n return validation?.required ? 'This field is required' : true;\n }\n\n // Run custom validation if provided\n if (validateTextArea && value) {\n const validation = validateTextArea(value);\n if (validation !== true && typeof validation === 'string') {\n return validation;\n }\n }\n\n // Check maximum length\n if (maxLength && typeof value === 'string' && value.length > maxLength) {\n return `Maximum length is ${maxLength} characters`;\n }\n\n return true;\n },\n }}\n render={({ field, fieldState: { error, isTouched } }) => {\n const hasError = !!error;\n const shouldShowError = hasError && isTouched;\n const validationClasses = getValidationStateClasses(error, isTouched);\n\n // Get accessibility attributes\n const accessibilityProps = getAccessibilityProps({\n id,\n hasError,\n isRequired,\n hasHelperText: !!helperText,\n });\n\n return (\n <>\n <Textarea\n {...field}\n id={id}\n placeholder={placeholder}\n rows={rows}\n maxLength={maxLength}\n className={validationClasses}\n value={field.value ?? ''}\n {...accessibilityProps}\n aria-describedby={`${helperText ? descriptionId : ''} ${hasError ? errorId : ''}`}\n onKeyDown={handleEscapeKey((value) => {\n if (typeof field.onChange === 'function') {\n field.onChange(value);\n }\n }, field.value)}\n />\n\n {/* Display character count if maxLength is provided */}\n {maxLength && typeof field.value === 'string' && (\n <div className=\"text-muted-foreground text-right text-xs\">\n {field.value.length}/{maxLength}\n </div>\n )}\n\n {/* Display helper text */}\n {helperText && (\n <div id={descriptionId} className=\"text-muted-foreground text-sm\">\n {helperText}\n </div>\n )}\n\n {/* Display error message */}\n <ErrorMessage\n error={error}\n id={errorId}\n message={shouldShowError ? error?.message : undefined}\n />\n </>\n );\n }}\n />\n </div>\n );\n}\n\n// Set displayName manually for better debugging\nTextAreaField.displayName = 'TextAreaField';\n","import React from 'react';\nimport { Controller, FieldValues } from 'react-hook-form';\n\nimport { Input } from '../ui/input';\nimport { Label } from '../ui/label';\nimport { BaseFieldProps } from './BaseField';\nimport {\n ErrorMessage,\n getAccessibilityProps,\n getValidationStateClasses,\n handleEscapeKey,\n validateField,\n} from './utils';\n\n/**\n * TextField component properties\n */\nexport interface TextFieldProps<TFieldValues extends FieldValues = FieldValues>\n extends BaseFieldProps<TFieldValues> {\n /**\n * Placeholder text displayed when the field is empty\n */\n placeholder?: string;\n}\n\n/**\n * Text input field component specifically designed for React Hook Form integration.\n *\n * Architecture flow:\n * 1. Form schemas are generated from contract functions using adapters\n * 2. TransactionForm renders the overall form structure with React Hook Form\n * 3. DynamicFormField selects the appropriate field component (like TextField) based on field type\n * 4. BaseField provides consistent layout and hook form integration\n * 5. This component handles text-specific rendering and validation\n *\n * The component includes:\n * - Integration with React Hook Form\n * - Text-specific validations (minLength, maxLength, pattern)\n * - Customizable validation through adapter integration\n * - Automatic error handling and reporting\n * - Full accessibility support with ARIA attributes\n * - Keyboard navigation\n */\nexport function TextField<TFieldValues extends FieldValues = FieldValues>({\n id,\n label,\n placeholder,\n helperText,\n control,\n name,\n width = 'full',\n validation,\n readOnly,\n}: TextFieldProps<TFieldValues>): React.ReactElement {\n const isRequired = !!validation?.required;\n const errorId = `${id}-error`;\n const descriptionId = `${id}-description`;\n\n // Function for validating text values\n const validateTextValue = (value: string): string | true => {\n const validationResult = validateField(value, validation);\n return validationResult === true ? true : (validationResult as string);\n };\n\n return (\n <div\n className={`flex flex-col gap-2 ${width === 'full' ? 'w-full' : width === 'half' ? 'w-1/2' : 'w-1/3'}`}\n >\n {label && (\n <Label htmlFor={id}>\n {label} {isRequired && <span className=\"text-destructive\">*</span>}\n </Label>\n )}\n\n <Controller\n control={control}\n name={name}\n rules={{\n validate: (value) => {\n // Handle required validation explicitly\n if (value === undefined || value === null || value === '') {\n return validation?.required ? 'This field is required' : true;\n }\n\n // Validate text values\n if (typeof value === 'string') {\n return validateTextValue(value);\n }\n\n return true;\n },\n }}\n disabled={readOnly}\n render={({ field, fieldState: { error, isTouched } }) => {\n const hasError = !!error;\n const shouldShowError = hasError && isTouched;\n const validationClasses = getValidationStateClasses(error, isTouched);\n\n // Handle input change with validation for required fields\n const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>): void => {\n const value = e.target.value;\n field.onChange(value);\n // Note: Validation happens naturally when user leaves the field\n // No need to trigger it programmatically on every change\n };\n\n // Handle keyboard events\n const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>): void => {\n if (e.key === 'Escape') {\n handleEscapeKey(field.onChange, field.value)(e);\n // Note: Validation happens naturally when user leaves the field\n // No need to trigger it programmatically\n }\n };\n\n // Get accessibility attributes\n const accessibilityProps = getAccessibilityProps({\n id,\n hasError,\n isRequired,\n hasHelperText: !!helperText,\n });\n\n return (\n <>\n <Input\n {...field}\n id={id}\n placeholder={placeholder}\n className={validationClasses}\n onChange={handleInputChange}\n onKeyDown={handleKeyDown}\n data-slot=\"input\"\n value={field.value ?? ''}\n {...accessibilityProps}\n aria-describedby={`${helperText ? descriptionId : ''} ${hasError ? errorId : ''}`}\n disabled={readOnly}\n />\n\n {/* Display helper text */}\n {helperText && (\n <div id={descriptionId} className=\"text-muted-foreground text-sm\">\n {helperText}\n </div>\n )}\n\n {/* Display error message */}\n <ErrorMessage\n error={error}\n id={errorId}\n message={shouldShowError ? error?.message : undefined}\n />\n </>\n );\n }}\n />\n </div>\n );\n}\n\n// Set displayName manually for better debugging\nTextField.displayName = 'TextField';\n","import React from 'react';\nimport { Controller, FieldValues } from 'react-hook-form';\n\nimport { getInvalidUrlMessage, isValidUrl } from '@openzeppelin/ui-utils';\n\nimport { Input } from '../ui/input';\nimport { Label } from '../ui/label';\nimport { BaseFieldProps } from './BaseField';\nimport {\n ErrorMessage,\n getAccessibilityProps,\n getValidationStateClasses,\n handleEscapeKey,\n validateField,\n} from './utils';\n\n/**\n * URL input field component specifically designed for React Hook Form integration.\n */\nexport function UrlField<TFieldValues extends FieldValues = FieldValues>({\n id,\n label,\n placeholder,\n helperText,\n control,\n name,\n width = 'full',\n validation,\n readOnly,\n}: BaseFieldProps<TFieldValues>): React.ReactElement {\n const isRequired = !!validation?.required;\n const errorId = `${id}-error`;\n const descriptionId = `${id}-description`;\n\n return (\n <div\n className={`flex flex-col gap-2 ${width === 'full' ? 'w-full' : width === 'half' ? 'w-1/2' : 'w-1/3'}`}\n >\n {label && (\n <Label htmlFor={id}>\n {label} {isRequired && <span className=\"text-destructive\">*</span>}\n </Label>\n )}\n\n <Controller\n control={control}\n name={name}\n rules={{\n validate: (value) => {\n // Check required field explicitly first\n if (value === undefined || value === null || value === '') {\n return validation?.required ? 'This field is required' : true;\n }\n\n // Perform standard validations (min, max, pattern, etc.) if they exist\n const standardValidationResult = validateField(value, validation);\n if (standardValidationResult !== true) {\n return standardValidationResult;\n }\n\n // Perform URL-specific validation using the shared validator\n if (typeof value === 'string' && value && !isValidUrl(value)) {\n return getInvalidUrlMessage();\n }\n\n // If all checks pass\n return true;\n },\n }}\n disabled={readOnly}\n render={({ field, fieldState: { error, isTouched } }) => {\n const hasError = !!error;\n const shouldShowError = hasError && isTouched;\n const validationClasses = getValidationStateClasses(error, isTouched);\n\n // Handle input change with validation\n const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>): void => {\n const value = e.target.value;\n field.onChange(value);\n\n // Trigger validation if the field is required and empty\n if (isRequired && value === '') {\n setTimeout(() => field.onBlur(), 0);\n }\n };\n\n // Add keyboard accessibility for clearing the field with Escape\n const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>): void => {\n if (e.key === 'Escape') {\n handleEscapeKey(field.onChange, field.value)(e);\n\n // If required, trigger validation after clearing\n if (isRequired) {\n setTimeout(() => field.onBlur(), 0);\n }\n }\n };\n\n // Get accessibility attributes\n const accessibilityProps = getAccessibilityProps({\n id,\n hasError,\n isRequired,\n hasHelperText: !!helperText,\n });\n\n return (\n <>\n <Input\n {...field}\n id={id}\n type=\"url\"\n placeholder={placeholder || 'https://example.com'}\n className={validationClasses}\n onChange={handleInputChange}\n onKeyDown={handleKeyDown}\n data-slot=\"input\"\n value={field.value ?? ''}\n {...accessibilityProps}\n aria-describedby={`${helperText ? descriptionId : ''} ${hasError ? errorId : ''}`}\n disabled={readOnly}\n />\n\n {/* Display helper text */}\n {helperText && (\n <div id={descriptionId} className=\"text-muted-foreground text-sm\">\n {helperText}\n </div>\n )}\n\n {/* Display error message */}\n <ErrorMessage\n error={error}\n id={errorId}\n message={shouldShowError ? error?.message : undefined}\n />\n </>\n );\n }}\n />\n </div>\n );\n}\n\nUrlField.displayName = 'UrlField';\n","import {\n AlertCircle,\n CheckCircle,\n DollarSign,\n Hash,\n Info,\n Loader2,\n Network,\n Timer,\n} from 'lucide-react';\nimport React from 'react';\n\nimport type { RelayerDetails, RelayerDetailsRich } from '@openzeppelin/ui-types';\nimport { cn } from '@openzeppelin/ui-utils';\n\nimport { AddressDisplay } from '../ui/address-display';\n\nexport interface RelayerDetailsCardProps {\n details: RelayerDetails;\n enhancedDetails?: RelayerDetailsRich | null;\n loading?: boolean;\n className?: string;\n /** Optional UI labels to override default copy */\n labels?: Partial<{\n detailsTitle: string;\n active: string;\n paused: string;\n systemDisabled: string;\n network: string;\n relayerId: string;\n balance: string;\n nonce: string;\n pending: string;\n lastTransaction: string;\n }>;\n}\n\nexport const RelayerDetailsCard: React.FC<RelayerDetailsCardProps> = ({\n details,\n enhancedDetails,\n loading = false,\n className,\n labels,\n}) => {\n const displayDetails = enhancedDetails || details;\n\n const l = {\n detailsTitle: labels?.detailsTitle || 'Relayer Details',\n active: labels?.active || 'Active',\n paused: labels?.paused || 'Paused',\n systemDisabled: labels?.systemDisabled || 'System Disabled',\n network: labels?.network || 'Network',\n relayerId: labels?.relayerId || 'Relayer ID',\n balance: labels?.balance || 'Balance',\n nonce: labels?.nonce || 'Nonce',\n pending: labels?.pending || 'Pending Transactions',\n lastTransaction: labels?.lastTransaction || 'Last Transaction',\n } as const;\n\n // Format timestamp for display\n const formatTimestamp = (timestamp: string): string => {\n try {\n const date = new Date(timestamp);\n return date.toLocaleString();\n } catch {\n return timestamp;\n }\n };\n\n return (\n <div\n className={cn(\n 'flex flex-col sm:flex-row sm:items-start space-y-3 sm:space-y-0 sm:space-x-3 p-3 bg-slate-50 rounded-md',\n className\n )}\n >\n <Info className=\"size-5 text-primary mt-0.5 flex-shrink-0 hidden sm:block\" />\n <div className=\"space-y-3 flex-1 min-w-0\">\n <div>\n <h4 className=\"text-sm font-medium mb-2\">{l.detailsTitle}</h4>\n\n {/* Relayer Name and Status */}\n <div className=\"flex flex-col sm:flex-row sm:items-center sm:justify-between mb-2 space-y-1 sm:space-y-0\">\n <p className=\"text-sm font-medium text-foreground truncate\">{displayDetails.name}</p>\n <span\n className={cn(\n 'inline-flex items-center px-2 py-1 rounded-full text-xs font-medium self-start',\n displayDetails.paused || enhancedDetails?.systemDisabled\n ? 'bg-red-100 text-red-800'\n : 'bg-green-100 text-green-800'\n )}\n >\n {displayDetails.paused || enhancedDetails?.systemDisabled ? (\n <>\n <AlertCircle className=\"size-3 mr-1\" />\n {enhancedDetails?.systemDisabled ? l.systemDisabled : l.paused}\n </>\n ) : (\n <>\n <CheckCircle className=\"size-3 mr-1\" />\n {l.active}\n </>\n )}\n </span>\n </div>\n\n {/* Relayer Address */}\n <div className=\"mb-3\">\n <AddressDisplay\n className=\"w-full sm:w-auto\"\n address={displayDetails.address}\n truncate={true}\n startChars={6}\n endChars={4}\n showCopyButton\n />\n </div>\n\n {/* Additional Details */}\n <div className=\"space-y-1 pt-2 border-t border-slate-200\">\n <div className=\"flex items-center gap-2\">\n <Network className=\"size-3.5 text-muted-foreground flex-shrink-0\" />\n <p className=\"text-xs text-muted-foreground truncate\">\n <span className=\"font-medium\">{l.network}:</span> {displayDetails.network}\n </p>\n </div>\n\n <div className=\"flex items-start gap-2\">\n <Hash className=\"size-3.5 text-muted-foreground flex-shrink-0 mt-0.5\" />\n <div className=\"text-xs text-muted-foreground min-w-0 flex-1\">\n <span className=\"font-medium\">{l.relayerId}:</span>{' '}\n <code className=\"font-mono text-xs bg-slate-100 px-1 py-0.5 rounded break-all\">\n {displayDetails.relayerId}\n </code>\n </div>\n </div>\n </div>\n\n {/* Enhanced Details Section */}\n {loading && (\n <div className=\"mt-3 flex items-center gap-2 text-xs text-muted-foreground\">\n <Loader2 className=\"size-3 animate-spin\" />\n Loading additional details...\n </div>\n )}\n\n {!loading && enhancedDetails && (\n <div className=\"mt-3 pt-3 border-t border-slate-200 space-y-2\">\n {/* Balance */}\n {enhancedDetails.balance && (\n <div className=\"flex items-center gap-2 text-xs\">\n <DollarSign className=\"size-3.5 text-muted-foreground flex-shrink-0\" />\n <div className=\"text-muted-foreground min-w-0 flex-1\">\n <span className=\"font-medium\">{l.balance}:</span>{' '}\n <span className=\"break-all\">{enhancedDetails.balance}</span>\n </div>\n </div>\n )}\n\n {/* Nonce */}\n {enhancedDetails.nonce && (\n <div className=\"flex items-center gap-2 text-xs\">\n <Hash className=\"size-3.5 text-muted-foreground flex-shrink-0\" />\n <span className=\"text-muted-foreground\">\n <span className=\"font-medium\">{l.nonce}:</span> {enhancedDetails.nonce}\n </span>\n </div>\n )}\n\n {/* Pending Transactions */}\n {enhancedDetails.pendingTransactionsCount !== undefined && (\n <div className=\"flex items-center gap-2 text-xs\">\n <Timer className=\"size-3.5 text-muted-foreground flex-shrink-0\" />\n <span className=\"text-muted-foreground\">\n <span className=\"font-medium\">{l.pending}:</span>{' '}\n {enhancedDetails.pendingTransactionsCount}\n </span>\n </div>\n )}\n\n {/* Last Transaction */}\n {enhancedDetails.lastConfirmedTransactionTimestamp && (\n <div className=\"flex items-start gap-2 text-xs\">\n <CheckCircle className=\"size-3.5 text-muted-foreground mt-0.5 flex-shrink-0\" />\n <div className=\"text-muted-foreground min-w-0 flex-1\">\n <span className=\"font-medium\">{l.lastTransaction}:</span>\n <br />\n <span className=\"text-xs break-words\">\n {formatTimestamp(enhancedDetails.lastConfirmedTransactionTimestamp)}\n </span>\n </div>\n </div>\n )}\n </div>\n )}\n </div>\n\n {/* Warning if relayer is paused or system disabled */}\n {(displayDetails.paused || enhancedDetails?.systemDisabled) && (\n <div className=\"bg-red-50 border border-red-200 rounded-md p-2\">\n <p className=\"text-xs text-red-700 flex items-start gap-1\">\n <AlertCircle className=\"size-3 mt-0.5 flex-shrink-0\" />\n <span className=\"min-w-0 flex-1\">\n {enhancedDetails?.systemDisabled\n ? 'This relayer has been disabled by the system and cannot process transactions.'\n : 'This relayer is currently paused and cannot process transactions.'}\n </span>\n </p>\n </div>\n )}\n </div>\n </div>\n );\n};\n","import { createContext } from 'react';\n\nimport type { NetworkErrorContextValue } from './useNetworkErrors';\n\nexport const NetworkErrorContext = createContext<NetworkErrorContextValue | undefined>(undefined);\n","'use client';\n\nimport { toast } from 'sonner';\nimport { useCallback, useMemo, useRef, useState } from 'react';\n\nimport { NetworkErrorContext } from './NetworkErrorContext';\nimport type { NetworkError, NetworkErrorType } from './useNetworkErrors';\n\ninterface NetworkErrorNotificationProviderProps {\n children: React.ReactNode;\n}\n\n/** Provider component for managing and displaying network error notifications. */\nexport function NetworkErrorNotificationProvider({\n children,\n}: NetworkErrorNotificationProviderProps): React.ReactNode {\n const [errors, setErrors] = useState<NetworkError[]>([]);\n const [openNetworkSettingsHandler, setOpenNetworkSettingsHandler] = useState<\n ((networkId: string) => void) | undefined\n >();\n const errorDedupeRef = useRef<Map<string, number>>(new Map());\n\n const reportNetworkError = useCallback(\n (type: NetworkErrorType, networkId: string, networkName: string, message: string) => {\n // Create a unique key for deduplication\n const dedupeKey = `${type}-${networkId}-${message}`;\n const now = Date.now();\n const lastReported = errorDedupeRef.current.get(dedupeKey);\n\n // Dedupe errors that occur within 5 seconds\n if (lastReported && now - lastReported < 5000) {\n return;\n }\n\n errorDedupeRef.current.set(dedupeKey, now);\n\n const error: NetworkError = {\n id: `${type}-${networkId}-${now}`,\n type,\n networkId,\n networkName,\n message,\n timestamp: now,\n };\n\n setErrors((prev) => {\n const newErrors = [...prev, error];\n return newErrors;\n });\n\n // Show toast notification with action button\n const typeLabel = type === 'rpc' ? 'RPC' : 'Explorer';\n toast.error(`${typeLabel} Error - ${networkName}`, {\n description: message,\n duration: 10000, // Show for 10 seconds\n action: openNetworkSettingsHandler\n ? {\n label: 'Configure',\n onClick: (): void => {\n openNetworkSettingsHandler(networkId);\n },\n }\n : undefined,\n });\n\n // Auto-remove error after 1 minute\n setTimeout(() => {\n setErrors((prev) => prev.filter((e) => e.id !== error.id));\n errorDedupeRef.current.delete(dedupeKey);\n }, 60000);\n },\n [openNetworkSettingsHandler]\n );\n\n const clearError = useCallback((id: string) => {\n setErrors((prev) => prev.filter((e) => e.id !== id));\n }, []);\n\n const clearAllErrors = useCallback(() => {\n setErrors([]);\n errorDedupeRef.current.clear();\n }, []);\n\n const stableSetHandler = useCallback((handler: (networkId: string) => void) => {\n setOpenNetworkSettingsHandler(() => handler);\n }, []);\n\n const value = useMemo(\n () => ({\n errors,\n reportNetworkError,\n clearError,\n clearAllErrors,\n onOpenNetworkSettings: openNetworkSettingsHandler,\n setOpenNetworkSettingsHandler: stableSetHandler,\n }),\n [\n errors,\n reportNetworkError,\n clearError,\n clearAllErrors,\n openNetworkSettingsHandler,\n stableSetHandler,\n ]\n );\n\n return <NetworkErrorContext.Provider value={value}>{children}</NetworkErrorContext.Provider>;\n}\n","'use client';\n\nimport { useCallback, useContext } from 'react';\n\nimport type { ContractAdapter } from '@openzeppelin/ui-types';\n\nimport { NetworkErrorContext } from './NetworkErrorContext';\n\nexport type NetworkErrorType = 'rpc' | 'explorer';\n\nexport interface NetworkError {\n id: string;\n type: NetworkErrorType;\n networkId: string;\n networkName: string;\n message: string;\n timestamp: number;\n}\n\nexport interface NetworkErrorContextValue {\n errors: NetworkError[];\n reportNetworkError: (\n type: NetworkErrorType,\n networkId: string,\n networkName: string,\n message: string\n ) => void;\n clearError: (id: string) => void;\n clearAllErrors: () => void;\n onOpenNetworkSettings?: (networkId: string) => void;\n setOpenNetworkSettingsHandler: (handler: (networkId: string) => void) => void;\n}\n\n/** Hook to access network error reporting and management functions. */\nexport function useNetworkErrors(): NetworkErrorContextValue {\n const context = useContext(NetworkErrorContext);\n if (!context) {\n throw new Error('useNetworkErrors must be used within NetworkErrorNotificationProvider');\n }\n return context;\n}\n\n/**\n * Hook for reporting network errors for a specific adapter\n */\nexport function useNetworkErrorReporter(adapter: ContractAdapter | null): {\n reportRpcError: (message: string) => void;\n reportExplorerError: (message: string) => void;\n} {\n const { reportNetworkError } = useNetworkErrors();\n\n const reportRpcError = useCallback(\n (message: string) => {\n if (!adapter) return;\n reportNetworkError('rpc', adapter.networkConfig.id, adapter.networkConfig.name, message);\n },\n [adapter, reportNetworkError]\n );\n\n const reportExplorerError = useCallback(\n (message: string) => {\n if (!adapter) return;\n reportNetworkError('explorer', adapter.networkConfig.id, adapter.networkConfig.name, message);\n },\n [adapter, reportNetworkError]\n );\n\n return {\n reportRpcError,\n reportExplorerError,\n };\n}\n","'use client';\n\nimport { useEffect, useRef } from 'react';\n\nimport type { ContractAdapter } from '@openzeppelin/ui-types';\n\nimport { useNetworkErrors } from './useNetworkErrors';\n\n/**\n * Creates an adapter proxy that intercepts and reports network errors\n */\nexport function useNetworkErrorAwareAdapter(\n adapter: ContractAdapter | null\n): ContractAdapter | null {\n const { reportNetworkError } = useNetworkErrors();\n const wrappedAdapterRef = useRef<ContractAdapter | null>(null);\n\n useEffect(() => {\n if (!adapter) {\n wrappedAdapterRef.current = null;\n return;\n }\n\n // Create a proxy that wraps the adapter to intercept errors\n const wrappedAdapter = new Proxy(adapter, {\n get(target, prop, receiver): unknown {\n const value = Reflect.get(target, prop, receiver);\n\n // Wrap async methods that might throw network errors\n if (\n typeof value === 'function' &&\n (prop === 'queryViewFunction' || prop === 'loadContract')\n ) {\n return async (...args: unknown[]) => {\n try {\n return await value.apply(target, args);\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : 'Unknown error';\n\n // Check if it's an RPC error\n if (\n errorMessage.toLowerCase().includes('rpc') ||\n errorMessage.toLowerCase().includes('network') ||\n errorMessage.toLowerCase().includes('timeout') ||\n errorMessage.toLowerCase().includes('fetch') ||\n errorMessage.toLowerCase().includes('connection')\n ) {\n reportNetworkError(\n 'rpc',\n target.networkConfig.id,\n target.networkConfig.name,\n errorMessage\n );\n }\n\n // Check if it's an explorer error\n if (\n errorMessage.toLowerCase().includes('explorer') ||\n errorMessage.toLowerCase().includes('etherscan') ||\n errorMessage.toLowerCase().includes('api key') ||\n errorMessage.toLowerCase().includes('abi') ||\n errorMessage.toLowerCase().includes('verified')\n ) {\n reportNetworkError(\n 'explorer',\n target.networkConfig.id,\n target.networkConfig.name,\n errorMessage\n );\n }\n\n // Re-throw the error to maintain normal error handling\n throw error;\n }\n };\n }\n\n return value;\n },\n }) as ContractAdapter;\n\n wrappedAdapterRef.current = wrappedAdapter;\n }, [adapter, reportNetworkError]);\n\n return wrappedAdapterRef.current;\n}\n","import { useTheme } from 'next-themes';\nimport { Toaster as Sonner, ToasterProps } from 'sonner';\nimport { JSX } from 'react';\n\nconst Toaster = ({ ...props }: ToasterProps): JSX.Element => {\n const { theme = 'system' } = useTheme();\n\n return (\n <Sonner\n theme={theme as ToasterProps['theme']}\n className=\"toaster group\"\n toastOptions={{\n classNames: {\n toast:\n 'group toast group-[.toaster]:bg-gray-900 group-[.toaster]:text-gray-50 group-[.toaster]:border-gray-800 group-[.toaster]:shadow-lg',\n description: 'group-[.toast]:text-gray-400',\n actionButton:\n 'group-[.toast]:bg-white group-[.toast]:text-gray-900 group-[.toast]:hover:bg-gray-100 group-[.toast]:font-medium group-[.toast]:border-0',\n cancelButton:\n 'group-[.toast]:bg-gray-800 group-[.toast]:text-gray-300 group-[.toast]:hover:bg-gray-700',\n error:\n 'group-[.toast]:!bg-red-950 group-[.toast]:!text-red-50 group-[.toast]:!border-red-900',\n },\n }}\n {...props}\n />\n );\n};\n\nexport { Toaster };\n"],"mappings":"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"}
|