Document how to use Alert Dialog with TypeScript
Subject
Alert Dialog
Description
The docs for Alert Dialog don't show how to use it with TypeScript, and TypeScript usage is a little counterintuitive. (Roughly) following the docs like this:
const UnsubscribeAlert = ({
isOpen,
onClose,
onUnsubscribe,
isUnsubscribing,
}: {
isOpen: boolean;
onClose: () => void;
onUnsubscribe: () => void;
isUnsubscribing: boolean;
}) => {
const cancelRef = useRef();
return (
<AlertDialog
isOpen={isOpen}
leastDestructiveRef={cancelRef}
onClose={onClose}
>
<AlertDialogOverlay>
<AlertDialogContent>
<AlertDialogHeader fontSize="lg" fontWeight="bold">
Unsubscribe
</AlertDialogHeader>
<AlertDialogBody>
Are you sure? If you unsubscribe you will retain access until your
current subscription ends. After that you will lose access to all
but the first 10 entries you created and be unable to create new
ones.
</AlertDialogBody>
<AlertDialogFooter>
<Button ref={cancelRef} onClick={onClose}>
Cancel
</Button>
<Button
colorScheme="red"
onClick={onUnsubscribe}
ml={3}
disabled={isUnsubscribing}
isLoading={isUnsubscribing}
loadingText="Unsubscribing..."
>
Unsubscribe
</Button>
</AlertDialogFooter>
</AlertDialogContent>
</AlertDialogOverlay>
</AlertDialog>
);
};
Gives the following error for leastDestructiveRef:
Type 'MutableRefObject<undefined>' is not assignable to type 'RefObject<FocusableElement>'.
Types of property 'current' are incompatible.
Type 'undefined' is not assignable to type 'FocusableElement | null'.ts(2322)
and for ref:
Type 'MutableRefObject<undefined>' is not assignable to type 'LegacyRef<HTMLButtonElement> | undefined'.
Type 'MutableRefObject<undefined>' is not assignable to type 'RefObject<HTMLButtonElement>'.
Types of property 'current' are incompatible.
Type 'undefined' is not assignable to type 'HTMLButtonElement | null'.ts(2322)
Doing cancelRef.current = null; doesn't fix it. The first two errors remain unchanged and the line for cancelRef.current = null; has an error of:
Type 'null' is not assignable to type 'undefined'.
Doing useRef<null>() fixes that third error but not the first two.
It looks like leastDestructiveRef wants RefObject<FocusableElement>. I see that RefObject can be imported from React but I'm not sure where to get FocusableElement. VSCode doesn't provide any recommendations. So I ended up doing this which got rid of the errors but isn't ideal.
const cancelRef: RefObject<any> = useRef();
Hello,
FocusableElement is any focusable element (element or other, exposing a focus() method), in our case a button.
So you should use HTMLButtonElement for typing your ref. You also need to type your ref with null to comply with leastDestructiveRef and ref props typing, you can do something like that :
const buttonRef = useRef<HTMLButtonElement>(null);
TypeScript will infer null type from default value.
Gotcha, thanks.
Hi! This issue has been automatically marked as stale because lack of recent activity. It will be closed if no further activity occurs within 5 days. Thank you for your contributions.