@@ -12,15 +12,15 @@ import {
1212} from "@/components/ui/form" ;
1313import { Input } from "@/components/ui/input" ;
1414import {
15- Select ,
16- SelectContent ,
17- SelectItem ,
18- SelectTrigger ,
19- SelectValue ,
20- } from "@/components/ui/select" ;
15+ Popover ,
16+ PopoverContent ,
17+ PopoverTrigger ,
18+ } from "@/components/ui/popover" ;
2119import { Textarea } from "@/components/ui/textarea" ;
2220import { useThirdwebClient } from "@/constants/thirdweb.client" ;
21+ import { cn } from "@/lib/utils" ;
2322import { useQueryClient } from "@tanstack/react-query" ;
23+ import { useState } from "react" ;
2424import type { UseFormReturn } from "react-hook-form" ;
2525
2626import { MultiNetworkSelector } from "@/components/blocks/NetworkSelectors" ;
@@ -74,6 +74,10 @@ export function FilterDetailsStep({
7474 : [ ] ;
7575 const contractAddresses = form . watch ( "addresses" ) || "" ;
7676
77+ // Popover open state hooks moved to top level
78+ const [ eventPopoverOpen , setEventPopoverOpen ] = useState ( false ) ;
79+ const [ functionPopoverOpen , setFunctionPopoverOpen ] = useState ( false ) ;
80+
7781 return (
7882 < >
7983 < div className = "mb-4" >
@@ -305,97 +309,108 @@ export function FilterDetailsStep({
305309 { watchFilterType === "event" &&
306310 Object . keys ( fetchedAbis ) . length > 0 &&
307311 eventSignatures . length > 0 ? (
308- < Select
309- value = { field . value }
310- onValueChange = { ( value ) => {
311- field . onChange ( value ) ;
312- // Find the selected event
313- const selectedEvent = eventSignatures . find (
314- ( sig ) => sig . signature === value ,
315- ) ;
316- // Set the ABI for the event
317- form . setValue ( "sigHashAbi" , selectedEvent ?. abi || "" ) ;
318- } }
312+ < Popover
313+ modal
314+ open = { eventPopoverOpen }
315+ onOpenChange = { setEventPopoverOpen }
319316 >
320- < SelectTrigger >
321- < SelectValue placeholder = "Select an event signature" >
317+ < PopoverTrigger asChild >
318+ < button
319+ type = "button"
320+ className = { cn (
321+ "h-10 w-full rounded-md border bg-background px-3 py-2 text-left text-sm focus:outline-none focus:ring-2 focus:ring-ring disabled:opacity-50" ,
322+ ! field . value && "text-muted-foreground" ,
323+ ) }
324+ >
322325 { field . value
323326 ? eventSignatures . find (
324327 ( sig ) => sig . signature === field . value ,
325328 ) ?. name || ""
326- : null }
327- </ SelectValue >
328- </ SelectTrigger >
329- < SelectContent className = "max-h-60 overflow-y-auto" >
330- { eventSignatures . map ( ( event ) => {
331- // Truncate the hash for display purposes
332- const truncatedHash = truncateMiddle (
333- event . signature ,
334- 6 ,
335- 4 ,
336- ) ;
337-
338- return (
339- < SelectItem
340- key = { event . signature }
341- value = { event . signature }
342- title = { event . name }
343- >
344- < div className = "flex flex-col" >
345- < span className = "font-medium" > { event . name } </ span >
346- < span className = "text-muted-foreground text-xs" >
347- Signature: { truncatedHash }
348- </ span >
349- </ div >
350- </ SelectItem >
351- ) ;
352- } ) }
353- </ SelectContent >
354- </ Select >
329+ : "Select an event signature" }
330+ </ button >
331+ </ PopoverTrigger >
332+ < PopoverContent
333+ className = "max-h-60 w-[--radix-popover-trigger-width] overflow-y-auto p-0"
334+ align = "start"
335+ >
336+ < ul className = "divide-y divide-border" >
337+ { eventSignatures . map ( ( event ) => (
338+ < li key = { event . signature } >
339+ < button
340+ type = "button"
341+ className = { cn (
342+ "w-full px-4 py-2 text-left text-sm hover:bg-accent focus:bg-accent" ,
343+ field . value === event . signature && "bg-accent" ,
344+ ) }
345+ onClick = { ( ) => {
346+ field . onChange ( event . signature ) ;
347+ form . setValue ( "sigHashAbi" , event . abi || "" ) ;
348+ setEventPopoverOpen ( false ) ;
349+ } }
350+ >
351+ < div className = "font-medium" > { event . name } </ div >
352+ < div className = "text-muted-foreground text-xs" >
353+ Signature:{ " " }
354+ { truncateMiddle ( event . signature , 6 , 4 ) }
355+ </ div >
356+ </ button >
357+ </ li >
358+ ) ) }
359+ </ ul >
360+ </ PopoverContent >
361+ </ Popover >
355362 ) : watchFilterType === "transaction" &&
356363 Object . keys ( fetchedTxAbis ) . length > 0 &&
357364 functionSignatures . length > 0 ? (
358- < Select
359- value = { field . value }
360- onValueChange = { ( value ) => {
361- field . onChange ( value ) ;
362- // Find the selected function
363- const selectedFunction = functionSignatures . find (
364- ( sig ) => sig . signature === value ,
365- ) ;
366- // Set the ABI for the function
367- form . setValue ( "sigHashAbi" , selectedFunction ?. abi || "" ) ;
368- } }
365+ < Popover
366+ modal
367+ open = { functionPopoverOpen }
368+ onOpenChange = { setFunctionPopoverOpen }
369369 >
370- < SelectTrigger className = "max-w-full" >
371- < SelectValue placeholder = "Select a function signature" >
370+ < PopoverTrigger asChild >
371+ < button
372+ type = "button"
373+ className = { cn (
374+ "h-10 w-full rounded-md border bg-background px-3 py-2 text-left text-sm focus:outline-none focus:ring-2 focus:ring-ring disabled:opacity-50" ,
375+ ! field . value && "text-muted-foreground" ,
376+ ) }
377+ >
372378 { field . value
373379 ? functionSignatures . find (
374380 ( sig ) => sig . signature === field . value ,
375381 ) ?. name || ""
376- : null }
377- </ SelectValue >
378- </ SelectTrigger >
379- < SelectContent className = "max-h-60 max-w-[600px] overflow-y-auto" >
380- { functionSignatures . map ( ( func ) => (
381- < SelectItem
382- key = { func . signature }
383- value = { func . signature }
384- title = { func . signature }
385- className = "w-full overflow-x-auto"
386- >
387- < div className = "flex w-full flex-col" >
388- < span className = "overflow-x-auto whitespace-nowrap pb-1 font-medium" >
389- { func . name }
390- </ span >
391- < span className = "overflow-x-auto text-muted-foreground text-xs" >
392- Selector: { func . signature }
393- </ span >
394- </ div >
395- </ SelectItem >
396- ) ) }
397- </ SelectContent >
398- </ Select >
382+ : "Select a function signature" }
383+ </ button >
384+ </ PopoverTrigger >
385+ < PopoverContent
386+ className = "max-h-60 w-[--radix-popover-trigger-width] overflow-y-auto p-0"
387+ align = "start"
388+ >
389+ < ul className = "divide-y divide-border" >
390+ { functionSignatures . map ( ( func ) => (
391+ < li key = { func . signature } >
392+ < button
393+ type = "button"
394+ className = { cn (
395+ "w-full px-4 py-2 text-left text-sm hover:bg-accent focus:bg-accent" ,
396+ field . value === func . signature && "bg-accent" ,
397+ ) }
398+ onClick = { ( ) => {
399+ field . onChange ( func . signature ) ;
400+ form . setValue ( "sigHashAbi" , func . abi || "" ) ;
401+ setFunctionPopoverOpen ( false ) ;
402+ } }
403+ >
404+ < div className = "font-medium" > { func . name } </ div >
405+ < div className = "text-muted-foreground text-xs" >
406+ Selector: { func . signature }
407+ </ div >
408+ </ button >
409+ </ li >
410+ ) ) }
411+ </ ul >
412+ </ PopoverContent >
413+ </ Popover >
399414 ) : (
400415 < Input
401416 placeholder = {
0 commit comments