11import { createSignal , Show , mergeProps } from "solid-js"
22import { useTransContext } from "@gd/i18n"
3- import { Spinner } from "@gd/ui"
3+ import { Popover , PopoverContent , PopoverTrigger , Spinner } from "@gd/ui"
44
55interface ImagePickerProps {
66 imageUrl : ( ) => string | null
@@ -18,7 +18,7 @@ interface ImagePickerProps {
1818
1919const ImagePicker = ( props : ImagePickerProps ) => {
2020 const [ t ] = useTransContext ( )
21- const [ showConfirmDelete , setShowConfirmDelete ] = createSignal ( false )
21+ const [ isPopoverOpen , setIsPopoverOpen ] = createSignal ( false )
2222
2323 const merged = mergeProps (
2424 {
@@ -49,24 +49,17 @@ const ImagePicker = (props: ImagePickerProps) => {
4949 const handleDeleteClick = async ( e : MouseEvent ) => {
5050 e . preventDefault ( )
5151 e . stopPropagation ( )
52- if ( merged . confirmDelete ) {
53- setShowConfirmDelete ( true )
54- } else {
52+ if ( ! merged . confirmDelete ) {
5553 await props . onDelete ?.( )
5654 }
55+ // If confirmDelete is true, the Popover handles showing the confirmation
5756 }
5857
5958 const handleConfirmDelete = async ( ) => {
60- setShowConfirmDelete ( false )
59+ setIsPopoverOpen ( false )
6160 await props . onDelete ?.( )
6261 }
6362
64- const handleCancelDelete = ( e ?: MouseEvent ) => {
65- e ?. preventDefault ( )
66- e ?. stopPropagation ( )
67- setShowConfirmDelete ( false )
68- }
69-
7063 return (
7164 < div class = "relative" >
7265 { /* Main picker area */ }
@@ -93,20 +86,6 @@ const ImagePicker = (props: ImagePickerProps) => {
9386 </ div >
9487 </ Show >
9588
96- { /* Delete button - top right corner, appears only when hovering near it */ }
97- < Show
98- when = { merged . deletable && props . imageUrl ( ) && ! showConfirmDelete ( ) }
99- >
100- < div class = "group/delete absolute -right-3.5 -top-3.5 z-10 p-1.5" >
101- < div
102- class = "cursor-pointer rounded-full bg-darkSlate-800 p-1 opacity-0 transition-opacity group-hover/delete:opacity-100"
103- onClick = { handleDeleteClick }
104- >
105- < div class = "i-hugeicons:delete-02 h-5 w-5 text-red-500 transition-all hover:text-red-400" />
106- </ div >
107- </ div >
108- </ Show >
109-
11089 { /* Loading overlay */ }
11190 < Show when = { props . isLoading ?.( ) } >
11291 < div class = "absolute inset-0 flex items-center justify-center rounded-xl bg-black/70" >
@@ -115,27 +94,61 @@ const ImagePicker = (props: ImagePickerProps) => {
11594 </ Show >
11695 </ div >
11796
118- { /* Confirmation dialog (inline popover style) */ }
119- < Show when = { showConfirmDelete ( ) } >
120- < div
121- class = "absolute left-full top-0 z-50 ml-2 flex items-center gap-2 whitespace-nowrap rounded-md border border-solid border-darkSlate-600 bg-darkSlate-800 px-3 py-2 shadow-md animate-in fade-in zoom-in-95"
122- onClick = { ( e ) => e . stopPropagation ( ) }
123- >
124- < span class = "text-sm text-lightSlate-200" >
125- { t ( "general:_trn_delete" ) } ?
126- </ span >
127- < button
128- class = "rounded p-1 text-lightSlate-500 transition-colors hover:bg-darkSlate-700 hover:text-lightSlate-100"
129- onClick = { handleCancelDelete }
97+ { /* Delete button with confirmation popover */ }
98+ < Show when = { merged . deletable && props . imageUrl ( ) } >
99+ < div class = "absolute -right-3.5 -top-3.5 z-10" >
100+ < Show
101+ when = { merged . confirmDelete }
102+ fallback = {
103+ < div class = "group/delete p-1.5" >
104+ < div
105+ class = "cursor-pointer rounded-full bg-darkSlate-800 p-1 opacity-0 transition-opacity group-hover/delete:opacity-100"
106+ onClick = { handleDeleteClick }
107+ >
108+ < div class = "i-hugeicons:delete-02 h-5 w-5 text-red-500 transition-all hover:text-red-400" />
109+ </ div >
110+ </ div >
111+ }
130112 >
131- < div class = "i-hugeicons:cancel-01 h-5 w-5" />
132- </ button >
133- < button
134- class = "rounded p-1 text-red-500 transition-colors hover:bg-red-500/20 hover:text-red-400"
135- onClick = { handleConfirmDelete }
136- >
137- < div class = "i-hugeicons:tick-02 h-5 w-5" />
138- </ button >
113+ < Popover
114+ open = { isPopoverOpen ( ) }
115+ onOpenChange = { setIsPopoverOpen }
116+ placement = "right"
117+ >
118+ < PopoverTrigger
119+ as = "div"
120+ class = "group/delete p-1.5"
121+ onClick = { ( e : MouseEvent ) => e . stopPropagation ( ) }
122+ >
123+ < div class = "cursor-pointer rounded-full bg-darkSlate-800 p-1 opacity-0 transition-opacity group-hover/delete:opacity-100" >
124+ < div class = "i-hugeicons:delete-02 h-5 w-5 text-red-500 transition-all hover:text-red-400" />
125+ </ div >
126+ </ PopoverTrigger >
127+ < PopoverContent
128+ class = "w-auto !p-2"
129+ hideCloseButton
130+ onClick = { ( e : MouseEvent ) => e . stopPropagation ( ) }
131+ >
132+ < div class = "flex items-center gap-2 whitespace-nowrap" >
133+ < span class = "text-sm text-lightSlate-200" >
134+ { t ( "general:_trn_delete" ) } ?
135+ </ span >
136+ < button
137+ class = "rounded p-1 text-lightSlate-500 transition-colors hover:bg-darkSlate-700 hover:text-lightSlate-100"
138+ onClick = { ( ) => setIsPopoverOpen ( false ) }
139+ >
140+ < div class = "i-hugeicons:cancel-01 h-5 w-5" />
141+ </ button >
142+ < button
143+ class = "rounded p-1 text-red-500 transition-colors hover:bg-red-500/20 hover:text-red-400"
144+ onClick = { handleConfirmDelete }
145+ >
146+ < div class = "i-hugeicons:tick-02 h-5 w-5" />
147+ </ button >
148+ </ div >
149+ </ PopoverContent >
150+ </ Popover >
151+ </ Show >
139152 </ div >
140153 </ Show >
141154 </ div >
0 commit comments