| 169 | } |
| 170 | |
| 171 | function ZoomImageModal(props: { |
| 172 | src: string; |
| 173 | alt: string; |
| 174 | crossOrigin: React.ComponentPropsWithoutRef<'img'>['crossOrigin']; |
| 175 | onClose: () => void; |
| 176 | }) { |
| 177 | const { src, alt, crossOrigin, onClose } = props; |
| 178 | |
| 179 | const buttonRef = React.useRef<HTMLButtonElement>(null); |
| 180 | |
| 181 | React.useEffect(() => { |
| 182 | const handleKeyDown = (event: KeyboardEvent) => { |
| 183 | if (event.key === 'Escape') { |
| 184 | onClose(); |
| 185 | } |
| 186 | }; |
| 187 | |
| 188 | document.addEventListener('keydown', handleKeyDown); |
| 189 | |
| 190 | return () => { |
| 191 | document.removeEventListener('keydown', handleKeyDown); |
| 192 | }; |
| 193 | }, [onClose]); |
| 194 | |
| 195 | React.useEffect(() => { |
| 196 | buttonRef.current?.focus(); |
| 197 | }, []); |
| 198 | |
| 199 | return ( |
| 200 | <div |
| 201 | data-testid="zoom-image-modal" |
| 202 | className={classNames( |
| 203 | styles.zoomModal, |
| 204 | tcls( |
| 205 | 'fixed', |
| 206 | 'inset-0', |
| 207 | 'z-50', |
| 208 | 'flex', |
| 209 | 'items-center', |
| 210 | 'justify-center', |
| 211 | 'bg-tint-base/4', |
| 212 | 'backdrop-blur-2xl', |
| 213 | 'p-8' |
| 214 | ) |
| 215 | )} |
| 216 | onClick={onClose} |
| 217 | > |
| 218 | <img |
| 219 | src={src} |
| 220 | alt={alt} |
| 221 | crossOrigin={crossOrigin} |
| 222 | className={tcls('max-w-full', 'max-h-full', 'object-contain', 'bg-tint-base')} |
| 223 | /> |
| 224 | |
| 225 | <button |
| 226 | ref={buttonRef} |
| 227 | className={tcls( |
| 228 | 'absolute', |