This component provides the modal context to your app. It does not have any required props and renders nothing in the DOM. This is where the global settings are defined.
import react from 'react'; import { ModalProvider } from '@faceless-ui/modal; export const MyApp = () = ( <ModalProvider> ... </ModalProvider> );
zIndex
Applies z-index to the <ModalContainer>
. If generateCSS
is false
, this prop is ignored. Defaults to 9999
.
transTime
The transition duration of modals and the modal container, in milliseconds. Defaults to 250
.
handleParamChange
If true, will set and reset the ?modal=
URL parameter using pushState
from the History API. If sent a callback, will execute your function with a slug for you to handle, see Routing for more details.
trapFocus
Traps and restores focus on using focus-trap
, a popular-open source package. When a modal is opened, the first tab index of the modal becomes focused, and subsequent tabs are cycled through the modal without returning back to the original document. When the modal is closed, focus is restored to the element used to open the modal. Defaults to true
.
trapFocusOptions
Additional options passed to focus-trap
.
classPrefix
Prepends onto onto every generated class name, useful for unique name-spacing within complex stylesheets.
generateCSS
Generates a tiny CSS stylesheet (~650B), rendered at the root of the provider. This is used for core positioning and transition timing, not visual styling. Defaults to true
.
minifyCSS
Minifies the result of generateCSS
. Defaults to true
.
modalState
An object of every registered modal, keyed by their slug. Each modal has the following properties:
slug
- The slug of the modalisOpen
- true
if the modal is open, false
if closedopenedOn
- the timestamp of when the modal was openedopenModal(slug: string)
Opens the given slug and fires handleParamChange
.
oneModalIsOpen
True when at least one modal has the isOpen
property. The <ModalContainer>
will undergo transition every time this changes.
isModalOpen(slug: string)
A function used to determine if a particular modal is currently open.
toggleModal(slug: string)
Takes the slug of any modal and opens or closes that modal based on its current status, using the openModal
and closeModal
methods.
closeAllModals()
Closes all modals and fires handleParamChange
. Unlocks all body scroll locks.
closeOnBlur
Enables a click event on the <ModalContainer>
that, when clicked, will close all modals.
setCloseOnBlur()
Used internally to set the global closeOnBlur
status. Fired each time a modal is opened based on its own closeOnBlur
prop.
bodyScrollIsLocked
The current state of body scroll lock, useful when multiple modals differ in lockBodyScroll
.
setBodyScrollLock(set: boolean)
Enables and disables scroll on the HTML body using body-scroll-lock
. Fired by lockBodyScroll
on each modal individually. Check bodyScrollIsLocked
for the global status after overrides.
containerRef
A reference to <ModalContainer>
, where each modal portals into.
setContainerRef(ref: React.MutableRefObject<HTMLElement>)
Used by <ModalContainer>
to populate containerRef
on mount.
...settings
All settings are spread into the context.
This component will add an element to the DOM where every modal will portal into. It will receive transition classes when any modal is opened.
import react from 'react'; import { ModalContainer } from '@faceless-ui/modal; export const MyApp = () = ( <ModalContainer> ... </ModalContainer> );
htmlElement
Customize the HTML element that is rendered in the DOM. Defaults to div
.
...rest
All other props are spread onto the DOM element as HTML attributes.
Each modal is portaled into the <ModalContainer>
and receives transition classes when opened or closed. The only required prop is a unique slug
.
import react from 'react'; import { Modal } from '@faceless-ui/modal; export const MyModal = () => { return ( <Modal slug="my-modal"> ... </Modal> ) };
You can also pass a function as a child to conveniently access modal context. Although could access the same context with the useModal
hook, this would require a child component, see the official Rules of Hooks.
import react from 'react'; import { Modal } from '@faceless-ui/modal; export const MyModal = () => { return ( <Modal slug="my-modal"> {(modalContext) => { return ( ... ) }} </Modal> ) };
slug*
A unique identifier for this modal.
closeOnBlur
Will close the modal when the user clicks outside of it. Defaults to true.
lockBodyScroll
Will prevent the document from scrolling while the modal is open. Defaults to true.
classPrefix
Prepends onto onto every generated class name, useful for unique name-spacing within complex stylesheets.
htmlElement
Customize the HTML element that is rendered in the DOM. Defaults to dialog
.
...rest
All other props are spread onto the DOM element as HTML attributes.
This is a button that will open or close a modal based on its current status. It's a simple wrapper around the useModal
hook. It's only required prop is a unique slug
.
import react from 'react'; import { ModalToggler } from '@faceless-ui/modal; export const MyComponent = () => { return ( <ModalToggler slug="my-modal"> ... </ModalToggler> ) };
slug*
The unique slug
of the modal to open or close.
htmlElement
Customize the HTML element that is rendered in the DOM. Defaults to div
.
...rest
All other props are spread onto the DOM element as HTML attributes.
This is a hook you can use to access the modal context.
import react from 'react'; import { useModal } from '@faceless-ui/modal; export const MyComponent = () => { const modal = useModal(); return ( ... ) };
For advanced setups, use this higher order component to create your own modal entirely from scratch. Wrap your React component with this HOC to have it function as a modal. It will attach the modal context into the props of the wrapped component. The second argument is the unique slug
.
import react from 'react'; import { asModal } from '@faceless-ui/modal; export const MyModal = asModal((props) => { const { modal } = props; return ( ... ) }, 'my-modal');
This package strictly follows the WAI-ARIA pattern for dialogs:
<Modal>
is a <dialog>
element with the following properties:
open
is toggled true
or false
based on isModalOpen
aria-modal
is true
aria-label
is the slug
of the <Modal>
<ModalToggler>
is a <button>
element with the following properties:
type
is button
aria-expanded
is toggled true
or false
based on isModalOpen
aria-controls
is the slug
of the <Modal>
aria-label
is Open modal SLUG
or Close modal SLUG
based on isModalOpen
trapFocus
esc
key closes the modal in sequential ordercloseOnBlur
All types can be directly imported.
import { ModalProviderProps, IModalContext, ModalContainerProps, ModalProps } from '@faceless-ui/modal/dist/types';