#Modal Setup


yarn add @faceless-ui/modal

First, wrap your app with the provider. This component does not render anything and should be nearest to the top of your app as possible. This is where the global settings are defined.

Anywhere inside of this, render the <ModalContainer>. This is where each modal will portal into so its best to keep this relatively high in your tree.

import React from 'react';
import { ModalProvider, ModalContainer } from '@faceless-ui/modal';

export const MyApp = () => {
  return (
    <ModalProvider transTime={250}>
      <ModalContainer />

Now to create a modal, render a <Modal> component anywhere in your app. The only required prop is the unique slug that identifies this modal. Then, the simplest way to open and close the modal is to use the <ModalToggler> component. It takes the slug of any modal and toggles it open or closed based on the current state of that modal.

import React from 'react';
import { Modal, ModalToggler } from '@faceless-ui/modal';

export const MyComponent = () => {
  return (
      <Modal slug="my-modal">
          Hello, world!
      <ModalToggler slug="my-modal">

Alternatively, you could build your own button. To do this, the toggleModal method can be directly accessed from the modal context with the useModal hook.

import React from 'react';
import { useModal } from '@faceless-ui/modal';

export const MyComponent = (props) => {
  const { toggleModal } = useModal();

  return (
      onClick={() => toggleModal('my-modal')}

It is also possible to open and close modals with the URL or your router, see Routing for full details. For more advanced setups, see the full API reference.


The modal component uses React Transition Group to animate the opening and closing of the modal based on transTime. This will add and remove transition classes to your DOM element which you can target from a stylesheet.

Here's a basic example in SCSS that fades a modal in and out. You can easily customize these classes using classPrefix prop.

.modal {
  will-change: opacity;
  transition: opacity 250ms linear; // NOTE: must match your 'transTime' prop
  opacity: 0;

  &:global(.modal-item--enterDone) {
    opacity: 1;

  &:global(.modal-item--exitDone) {
    opacity: 0;