MCPcopy Create free account
hub / github.com/code-forge-io/react-router-devtools / Modal

Function Modal

docs/app/components/modal.tsx:16–94  ·  view source on GitHub ↗
({
  isOpen,
  onClose,
  children,
  className,
  getInitialFocus,
  restoreFocus = true,
  ariaLabel,
}: ModalProps)

Source from the content-addressed store, hash-verified

14}
15
16export const Modal = ({
17 isOpen,
18 onClose,
19 children,
20 className,
21 getInitialFocus,
22 restoreFocus = true,
23 ariaLabel,
24}: ModalProps) => {
25 const modalRef = useRef<HTMLDivElement>(null)
26 const previouslyFocusedRef = useRef<HTMLElement | null>(null)
27
28 useScrollLock(isOpen)
29
30 useEffect(() => {
31 if (!isOpen) return
32 previouslyFocusedRef.current = document.activeElement as HTMLElement | null
33 return () => {
34 if (restoreFocus) previouslyFocusedRef.current?.focus?.()
35 }
36 }, [isOpen, restoreFocus])
37
38 useEffect(() => {
39 if (!isOpen) return
40 const id = requestAnimationFrame(() => {
41 const candidate = getInitialFocus?.()
42 if (candidate) { candidate.focus(); return }
43 const root = modalRef.current
44 if (!root) return
45 const firstFocusable = root.querySelector<HTMLElement>(
46 'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'
47 )
48 firstFocusable?.focus()
49 })
50 return () => cancelAnimationFrame(id)
51 }, [isOpen, getInitialFocus])
52
53 useEffect(() => {
54 if (!isOpen) return
55 const onKey = (e: KeyboardEvent) => { if (e.key === "Escape") onClose() }
56 window.addEventListener("keydown", onKey)
57 return () => window.removeEventListener("keydown", onKey)
58 }, [isOpen, onClose])
59
60 const handleOverlayPointerDown = (e: React.PointerEvent<HTMLDivElement>) => {
61 const root = modalRef.current
62 if (!root) return
63 if (!root.contains(e.target as Node)) onClose()
64 }
65
66 if (!isOpen) return null
67
68 return (
69 <>
70 <Backdrop onClose={onClose} className="pointer-events-none z-40" />
71 <div
72 className="fixed inset-0 z-50 overflow-y-auto overscroll-contain"
73 onPointerDown={handleOverlayPointerDown}

Callers

nothing calls this directly

Calls 2

useScrollLockFunction · 0.90
cnFunction · 0.90

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…