From 18f009afe1508a5e132a0e16dcfd361714ab572b Mon Sep 17 00:00:00 2001 From: John Paul Larkin Date: Wed, 17 Jan 2024 09:42:06 +0000 Subject: [PATCH] pass close fn/forwardref to promptlink --- components/Nav/MobileNav.tsx | 22 ++++- components/Nav/Nav.tsx | 8 +- components/PromptService/PromptLink.tsx | 118 ++++++++++++++---------- 3 files changed, 96 insertions(+), 52 deletions(-) diff --git a/components/Nav/MobileNav.tsx b/components/Nav/MobileNav.tsx index 310c2d2f..21c43ec9 100644 --- a/components/Nav/MobileNav.tsx +++ b/components/Nav/MobileNav.tsx @@ -2,7 +2,7 @@ import { type UserNavigationItem } from "@/types/types"; import { Disclosure, Transition } from "@headlessui/react"; import { type Session } from "next-auth"; import { PromptLink as Link } from "../PromptService/PromptLink"; -import { type FunctionComponent } from "react"; +import { MutableRefObject, useRef, type FunctionComponent } from "react"; import { navigation, subNav, userSubNav } from "../../config/site_settings"; function classNames(...classes: string[]) { @@ -12,11 +12,18 @@ function classNames(...classes: string[]) { interface MobileNavProps { session: Session | null; userNavigation: UserNavigationItem[]; + close?: ( + focusableElement?: + | HTMLElement + | MutableRefObject + | undefined, + ) => void; } const MobileNav: FunctionComponent = ({ session, userNavigation, + close, }) => { return ( = ({ ))}
- +
@@ -123,9 +130,16 @@ const NavItem: FunctionComponent = ({ item }) => { interface SubNavProps { session: Session | null; + close?: ( + focusableElement?: + | HTMLElement + | MutableRefObject + | undefined, + ) => void; } -const SubNav: FunctionComponent = ({ session }) => { +const SubNav: FunctionComponent = ({ session, close }) => { + const disclosureButtonRef = useRef(null); const data = session ? userSubNav : subNav; return ( <> @@ -134,6 +148,8 @@ const SubNav: FunctionComponent = ({ session }) => { { return ( - {({ open }) => ( + {({ close, open }) => ( <>
@@ -197,7 +197,11 @@ const Nav = ({ session }: { session: Session | null }) => {
- + )}
diff --git a/components/PromptService/PromptLink.tsx b/components/PromptService/PromptLink.tsx index 0d169ab4..0d033b99 100644 --- a/components/PromptService/PromptLink.tsx +++ b/components/PromptService/PromptLink.tsx @@ -1,66 +1,90 @@ import { useRouter } from "next/navigation"; import { usePrompt } from "@/components/PromptService/PromptContext"; -import type { ReactNode } from "react"; +import type { MutableRefObject, ReactNode } from "react"; import { useEffect, useState } from "react"; import Link from "next/link"; import { PromptDialog } from "./PromptDialog"; +import React from "react"; interface LinkProps { to: string; children: ReactNode; className?: string; + close?: ( + focusableElement?: + | HTMLElement + | MutableRefObject + | undefined, + ) => void; } -export const PromptLink = ({ to, children, className }: LinkProps) => { - const router = useRouter(); - const { unsavedChanges } = usePrompt(); - const [hasPrompt, setHasPrompt] = useState(false); - const [showModal, setShowModal] = useState(false); +const PromptLink = React.forwardRef( + ( + { to, children, className, close }: LinkProps, + ref: React.Ref, + ) => { + const router = useRouter(); + const { unsavedChanges } = usePrompt(); + const [hasPrompt, setHasPrompt] = useState(false); + const [showModal, setShowModal] = useState(false); - const handleNavigation = (event) => { - event.preventDefault(); + const handleNavigation = ( + event: React.MouseEvent, + ) => { + event.preventDefault(); - if (unsavedChanges) { - setHasPrompt(true); - setShowModal(true); - return false; - } else { + if (unsavedChanges) { + setHasPrompt(true); + setShowModal(true); + return false; + } else { + if (close !== undefined) close(); + router.push(to); + } + }; + + const confirmNavigation = () => { + setShowModal(false); + setHasPrompt(false); + if (close !== undefined) close(); router.push(to); - } - }; + }; - const confirmNavigation = () => { - setShowModal(false); - setHasPrompt(false); - router.push(to); - }; + const cancelNavigation = () => { + setShowModal(false); + return false; + }; - const cancelNavigation = () => { - setShowModal(false); - return false; - }; + useEffect(() => { + if (hasPrompt === true) { + setHasPrompt(false); + } + }, [hasPrompt]); - useEffect(() => { - if (hasPrompt === true) { - setHasPrompt(false); - } - }, [hasPrompt]); + return ( + <> + + {children} + + {showModal && ( + + )} + + ); + }, +); - return ( - <> - - {children} - - {showModal && ( - - )} - - ); -}; +PromptLink.displayName = "PromptLink"; +export { PromptLink };