Spaces:
Running
Running
Download web/src/hooks/usePreview.ts from nsaroiu/mtg-deck-completion: direct link, hf CLI and curl.
- Browser
- Download file 1.67 kB
-
https://huggingface.co/spaces/nsaroiu/mtg-deck-completion/resolve/main/web/src/hooks/usePreview.ts
- Command line
-
hf download hf://spaces/nsaroiu/mtg-deck-completion/web/src/hooks/usePreview.ts
-
curl -L -o usePreview.ts https://huggingface.co/spaces/nsaroiu/mtg-deck-completion/resolve/main/web/src/hooks/usePreview.ts
1.67 kB
| import { useCallback, useState } from 'react' | |
| import type { CardInfo } from '../api' | |
| // State for the floating card-text preview (components/CardPreview.tsx): | |
| // shown while hovering or keyboard-focusing a card name, only on devices | |
| // with a real pointer -- touch users tap through to Scryfall instead. | |
| export interface PreviewState { | |
| card: CardInfo | |
| x: number | |
| y: number | |
| } | |
| export const PREVIEW_WIDTH = 300 | |
| // Estimate used only to keep the panel on screen; real height varies with text. | |
| const PREVIEW_HEIGHT = 240 | |
| const OFFSET = 18 | |
| function place(x: number, y: number): { x: number; y: number } { | |
| const vw = window.innerWidth | |
| const vh = window.innerHeight | |
| const left = x + OFFSET + PREVIEW_WIDTH > vw ? x - OFFSET - PREVIEW_WIDTH : x + OFFSET | |
| const top = Math.min(Math.max(8, y - PREVIEW_HEIGHT / 2), vh - PREVIEW_HEIGHT - 8) | |
| return { x: Math.max(8, left), y: top } | |
| } | |
| const canHover = () => window.matchMedia('(hover: hover) and (pointer: fine)').matches | |
| export function usePreview() { | |
| const [state, setState] = useState<PreviewState | null>(null) | |
| const show = useCallback((card: CardInfo, e: React.MouseEvent) => { | |
| if (canHover()) setState({ card, ...place(e.clientX, e.clientY) }) | |
| }, []) | |
| const move = useCallback((e: React.MouseEvent) => { | |
| setState((s) => (s ? { ...s, ...place(e.clientX, e.clientY) } : s)) | |
| }, []) | |
| const showAt = useCallback((card: CardInfo, el: HTMLElement) => { | |
| if (!canHover()) return | |
| const r = el.getBoundingClientRect() | |
| setState({ card, ...place(r.right, r.top + r.height / 2) }) | |
| }, []) | |
| const hide = useCallback(() => setState(null), []) | |
| return { state, show, move, showAt, hide } | |
| } | |