@@ -12,15 +12,15 @@ import {
12
12
} from "@/components/ui/form" ;
13
13
import { Input } from "@/components/ui/input" ;
14
14
import {
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" ;
21
19
import { Textarea } from "@/components/ui/textarea" ;
22
20
import { useThirdwebClient } from "@/constants/thirdweb.client" ;
21
+ import { cn } from "@/lib/utils" ;
23
22
import { useQueryClient } from "@tanstack/react-query" ;
23
+ import { useState } from "react" ;
24
24
import type { UseFormReturn } from "react-hook-form" ;
25
25
26
26
import { MultiNetworkSelector } from "@/components/blocks/NetworkSelectors" ;
@@ -74,6 +74,10 @@ export function FilterDetailsStep({
74
74
: [ ] ;
75
75
const contractAddresses = form . watch ( "addresses" ) || "" ;
76
76
77
+ // Popover open state hooks moved to top level
78
+ const [ eventPopoverOpen , setEventPopoverOpen ] = useState ( false ) ;
79
+ const [ functionPopoverOpen , setFunctionPopoverOpen ] = useState ( false ) ;
80
+
77
81
return (
78
82
< >
79
83
< div className = "mb-4" >
@@ -305,97 +309,108 @@ export function FilterDetailsStep({
305
309
{ watchFilterType === "event" &&
306
310
Object . keys ( fetchedAbis ) . length > 0 &&
307
311
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 }
319
316
>
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
+ >
322
325
{ field . value
323
326
? eventSignatures . find (
324
327
( sig ) => sig . signature === field . value ,
325
328
) ?. 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 >
355
362
) : watchFilterType === "transaction" &&
356
363
Object . keys ( fetchedTxAbis ) . length > 0 &&
357
364
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 }
369
369
>
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
+ >
372
378
{ field . value
373
379
? functionSignatures . find (
374
380
( sig ) => sig . signature === field . value ,
375
381
) ?. 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 >
399
414
) : (
400
415
< Input
401
416
placeholder = {
0 commit comments