Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 | import { useDisclosure } from "@chakra-ui/react";
import {
useContext,
useState,
createContext,
FunctionComponent,
MouseEventHandler,
useCallback,
} from "react";
import {
PREFERS_WARN_ON_EXTERNAL_LINK_CLICK,
ExternalLinkPrompt,
ExternalLinkPromptOptions,
} from "./constants";
import { ExternalLinkWarningModal } from "./ExternalLinkWarningModal";
const ExternalLinkWarningContext = createContext<ExternalLinkPrompt>(
({ onClick }) => onClick
);
export const useExternalLinkWarning = () =>
useContext(ExternalLinkWarningContext);
export const ExternalLinkWarningProvider: FunctionComponent = ({
children,
}) => {
const [modalOption, setModalOptions] =
useState<ExternalLinkPromptOptions | null>(null);
const { isOpen, onOpen, onClose } = useDisclosure({
// Reset the modal options when closed
onClose: () => {
setModalOptions(null);
},
});
// Determines initial state from localStorage. If no value is found, default to showing warning
const [shouldWarn, setShouldWarn] = useState(() => {
try {
const saved =
localStorage.getItem(PREFERS_WARN_ON_EXTERNAL_LINK_CLICK) ?? "true";
return JSON.parse(saved);
} catch {
return true;
}
});
// Takes in an href & onClick to set options for modal. If it should warn the user, it will wrap the onClick
// With additional logic to show the modal
const withPrompt = useCallback<ExternalLinkPrompt>(
({ href, onClick }) => {
if (!shouldWarn) return onClick;
const handler: MouseEventHandler<HTMLAnchorElement> = (e) => {
setModalOptions({ href, onClick });
e.preventDefault();
onOpen();
};
return handler;
},
[onOpen, shouldWarn]
);
return (
<ExternalLinkWarningContext.Provider value={withPrompt}>
{children}
<ExternalLinkWarningModal
isOpen={isOpen}
onClose={onClose}
setShouldWarn={setShouldWarn}
{...modalOption}
/>
</ExternalLinkWarningContext.Provider>
);
};
|