diff --git a/.changeset/stale-laws-drive.md b/.changeset/stale-laws-drive.md new file mode 100644 index 0000000..bbd36be --- /dev/null +++ b/.changeset/stale-laws-drive.md @@ -0,0 +1,7 @@ +--- +"@wethegit/react-modal": major +--- + +Replace the custom modal and focus trap with native `` and `showModal()`. + +BREAKING: Remove `ModalBackdrop` in favor of the native `::backdrop`. Pass the `dialogRef` returned by `useModal` to `Modal` to synchronize native closing with hook state and focus restoration. `Modal` now renders its children directly inside the dialog, centers them, and handles backdrop clicks internally. diff --git a/README.md b/README.md index a4001c7..1f2947e 100644 --- a/README.md +++ b/README.md @@ -25,20 +25,19 @@ import "@wethegit/react-modal/style.css" ## Usage -The `useModal` hook provides mechanisms for hooking into the modal state. We'll need to pass said `state` to the `` component, as shown below. This approach allows us to abstract away state management, which becomes especially useful when [using a URL hash to manage the modal's state](#using-a-url-hash-to-manage-the-modal-state). +The `useModal` hook provides mechanisms for hooking into the modal state. Pass its `dialogRef` to `` so the hook can control that specific dialog's native modality. This approach allows us to abstract away state management, which becomes especially useful when [using a URL hash to manage the modal's state](#using-a-url-hash-to-manage-the-modal-state). The snippet below demonstrates the **minimum** required setup. No focus management, no animations. ```jsx import { Modal, - ModalBackdrop, ModalContent, useModal } from "@wethegit/react-modal" function MyModal() { - const { isOpen, toggle } = useModal() + const { isOpen, toggle, dialogRef } = useModal() return ( <> @@ -47,8 +46,7 @@ function MyModal() { {isOpen && ( - - +

Voluptate Lorem ut minim excepteur sit fugiat anim magna aliquip.

@@ -68,12 +66,11 @@ It's as easy as passing a `hash` prop to the `useModal` hook. The hook will then import { Modal, ModalContent, - ModalBackdrop, useModal } from "@wethegit/react-modal" function MyModal() { - const { isOpen, toggle } = useModal({ + const { isOpen, toggle, dialogRef } = useModal({ hash: "my-modal-hash" }) @@ -84,8 +81,7 @@ function MyModal() { {isOpen && ( - - +

Voluptate Lorem ut minim excepteur sit fugiat anim magna aliquip.

@@ -99,17 +95,15 @@ function MyModal() { ## Full example -Custom transition, focus management and hash-based state management. +Focus management, rendering to a custom element, and hash-based state management. -Use your favorite animation library, [@wethegit/react-hooks](https://wethegit.github.io/react-hooks/use-animate-presence) provides a simple one for these cases. +**Important:** Animation with `useAnimatePresence` is not included in this refactor. Support is deferred to [#155](https://github.com/wethegit/react-modal/issues/155). Render the modal conditionally with `isOpen`, without delaying unmount for an exit animation. ```jsx import { useRef } from 'react' -import { useAnimatePresence } from '@wethegit/react-hooks' import { Modal, ModalContent, - ModalBackdrop, useModal } from "@wethegit/react-modal" @@ -117,18 +111,13 @@ function MyModal() { const triggerButton = useRef(null) const modalRootRef = useRef(null) - const { isOpen, toggle } = useModal({ + const { isOpen, toggle, dialogRef } = useModal({ // `triggerRef` allows the focus to shift to whatever triggered the modal triggerRef: triggerButton, // `hash` will automatically open the modal when hash changes and will also update the hash when the modal opens/closes hash: "modal-with-hash", }) - const { render, animate } = useAnimatePresence({ - isVisible: isOpen, - duration: 800 - }) - return ( <>
- {render && modalRootRef.current && ( - - + >

Voluptate Lorem ut minim excepteur sit fugiat anim magna aliquip.

@@ -39,7 +41,7 @@ function CustomModal() { function CustomModalOnBody() { const triggerButton = useRef(null) const bodyRef = useRef(null) - const { isOpen, toggle } = useModal({ + const { isOpen, toggle, dialogRef } = useModal({ triggerRef: triggerButton, }) @@ -55,10 +57,13 @@ function CustomModalOnBody() { {isOpen && bodyRef.current && ( - - - -

Voluptate Lorem ut minim excepteur sit fugiat anim magna aliquip.

@@ -72,7 +77,7 @@ function CustomModalOnBody() { function ModalWithHash() { const triggerButton = useRef(null) const modalRootRef = useRef(null) - const { isOpen, toggle } = useModal({ + const { isOpen, toggle, dialogRef } = useModal({ triggerRef: triggerButton, hash: "modal-with-hash", }) @@ -85,10 +90,13 @@ function ModalWithHash() {
{isOpen && modalRootRef.current && ( - - + -

Voluptate Lorem ut minim excepteur sit fugiat anim magna aliquip.