react-modal

repository·master·Indexed 27 days ago

https://github.com/reactjs/react-modal

An accessible modal dialog component for React.JS applications (version 3.16.3) designed to handle focus management and accessibility requirements. It features focus trapping, focus restoration, and support for ARIA attributes. The library provides tools for configuring screenreader accessibility via Modal.setAppElement(), custom styling through CSS classes or a style prop, and flexible portal mounting options.

Tokens
5.5K
Snippets
12
Records
22
Agent score
91%

What's inside react-modal

  1. Implement CSS transitions for opening and closing modals

    master

    You can implement fade transitions for the modal overlay by using specific CSS classes. To apply a global fade transition to all modals, add the following CSS to your project:

    .ReactModal__Overlay {
        opacity: 0;
        transition: opacity 2000ms ease-in-out;
    }
    
    .ReactModal__Overlay--after-open {
        opacity: 1;
    }
    
    .ReactModal__Overlay--before-close {
        opacity: 0;
    }

    To apply transitions to a specific modal only, define custom class names in your CSS and pass them to the className prop of the <Modal /> component as an object.

    .ReactModal__Overlay {
        opacity: 0;
        transition: opacity 2000ms ease-in-out;
    }
    
    .ReactModal__Overlay--after-open{
        opacity: 1;
    }
    
    .ReactModal__Overlay--before-close{
        opacity: 0;
    }
  2. Install react-modal via CDN

    master

    For React CDN applications, add the following script tag after your React CDN scripts and before your own JavaScript files.

    <script src="https://cdnjs.cloudflare.com/ajax/libs/react-modal/3.14.3/react-modal.min.js"
                integrity="sha512-MY2jfK3DBnVzdS2V8MXo5lRtr0mNRroUI9hoLVv2/yL3vrJTam3VzASuKQ96fLEpyYIT4a8o7YgtUs5lPjiLVQ=="
                crossorigin="anonymous"
                referrerpolicy="no-referrer"></script>
  3. Customize Modal styles using the style prop

    master

    You can pass a style object to the Modal component to customize the appearance of the overlay and the content. The styles provided via the style prop are merged with the library's default styles.

    Note: If you specify a CSS class for the overlay or the content using the className prop, the default styles for that specific component will be disabled.

    <Modal
      ...
      style={{
        overlay: {
          position: 'fixed',
          top: 0,
          left: 0,
          right: 0,
          bottom: 0,
          backgroundColor: 'rgba(255, 255, 255, 0.75)'
        },
        content: {
          position: 'absolute',
          top: '40px',
          left: '40px',
          right: '40px',
          bottom: '40px',
          border: '1px solid #ccc',
          background: '#fff',
          overflow: 'auto',
          WebkitOverflowScrolling: 'touch',
          borderRadius: '4px',
          outline: 'none',
          padding: '20px'
        }
      }}
      ...
    >
  4. Use a custom parent node for the modal portal

    master

    By default, the modal portal is appended to the document's body. To attach the modal to a different parent element, provide a function to the parentSelector prop that returns the desired element.

    Important: Ensure your appElement is set correctly. The app element should not be a parent of the modal to prevent the modal content from being hidden from screen readers while open.

    <Modal
      // ...
      parentSelector={() => document.querySelector('#root')}>
      <p>Modal Content.</p>
    </Modal>
  5. Install react-modal in a React CDN app

    master

    To use react-modal in an application using React via CDN, add the following script tag after your React CDN scripts and before your own JavaScript files. You can then use the <Modal> tag within your app.

    <script src="https://cdnjs.cloudflare.com/ajax/libs/react-modal/3.14.3/react-modal.min.js"
                integrity="sha512-MY2jfK3DBnVzdS2V8MXo5lRtr0mNRroUI9hoLVv2/yL3vrJTam3VzASuKQ96fLEpyYIT4a8o7YgtUs5lPjiLVQ=="
                crossorigin="anonymous"
                referrerpolicy="no-referrer"></script>
  6. Configure the app element for screenreader accessibility

    master

    To ensure screenreader users do not interact with background content while a modal is open, react-modal uses the aria-hidden attribute on your application's root element. You must call Modal.setAppElement with a CSS selector or a DOM element before any modals are opened.

    If you are already managing aria-hidden on your app content manually, you can pass the ariaHideApp={false} prop to the Modal component to suppress warnings.

  7. Avoid conditional rendering when using transitions in React 16

    master

    If you are using React 16, close transitions will only work if you use the isOpen prop to toggle visibility. Do not conditionally render the <Modal /> component itself, as the React 16 Portal API does not allow intervention during the unmounting process, which prevents the close transition from playing.

    Incorrect (Conditional Rendering):

    {this.state.showModal && <Modal ... />}

    Correct (Using isOpen prop):

    <Modal
      closeTimeoutMS={200}
      isOpen={this.state.showModal}
      contentLabel="modal"
      onRequestClose={() => this.toggleModal()}
    >
      <h2 >Add modal content here</h2>
    </Modal>
  8. Use the ReactModal component

    master

    The isOpen prop is the only required prop for the ReactModal component, which determines if the modal is visible. Below is a comprehensive example of the available props and options.

    import ReactModal from 'react-modal';
    
    <ReactModal
      isOpen={
        false
      /* Boolean describing if the modal should be shown or not. */}
    
      onAfterOpen={
        handleAfterOpenFunc
      /* Function that will be run after the modal has opened. */}
    
      onAfterClose={
        handleAfterCloseFunc
      /* Function that will be run after the modal has closed. */}
    
      onRequestClose={
        handleRequestCloseFunc
      /* Function that will be run when the modal is requested
         to be closed (either by clicking on overlay or pressing ESC).
         Note: It is not called if isOpen is changed by other means. */}
    
      closeTimeoutMS={
        0
      /* Number indicating the milliseconds to wait before closing
         the modal. */}
    
      style={
        { overlay: {}, content: {} }
      /* Object indicating styles to be used for the modal.
         It has two keys, `overlay` and `content`.
         See the `Styles` section for more details. */}
    
      contentLabel={
        "Example Modal"
      /* String indicating how the content container should be announced
         to screenreaders */}
    
      portalClassName={
        "ReactModalPortal"
      /* String className to be applied to the portal.
         See the `Styles` section for more details. */}
    
      overlayClassName={
        "ReactModal__Overlay"
      /* String className to be applied to the overlay.
         See the `Styles` section for more details. */}
    
      id={
        "some-id"
      /* String id to be applied to the content div. */}
    
      className={
        "ReactModal__Content"
      /* String className to be applied to the modal content.
         See the `Styles` section for more details. */}
    
      bodyOpenClassName={
        "ReactModal__Body--open"
      /* String className to be applied to the modal ownerDocument.body
         (must be a constant string).
         This attribute when set as `null` doesn't add any class
         to document.body.
         See the `Styles` section for more details. */}
    
      htmlOpenClassName={
        "ReactModal__Html--open"
      /* String className to be applied to the modal ownerDocument.html
         (must be a constant string).
         This attribute is `null` by default.
         See the `Styles` section for more details. */}
    
      ariaHideApp={
        true
      /* Boolean indicating if the appElement should be hidden */}
    
      shouldFocusAfterRender={
        true
      /* Boolean indicating if the modal should be focused after render. */}
    
      shouldCloseOnOverlayClick={
        true
      /* Boolean indicating if clicking the overlay should close the modal */}
    
      shouldCloseOnEsc={
        true
      /* Boolean indicating if pressing the esc key should close the modal
         Note: By disabling the esc key from closing the modal
         you may introduce an accessibility issue. */}
    
      shouldReturnFocusAfterClose={
        true
      /* Boolean indicating if the modal should restore focus to the element
         that had focus prior to its display. */}
    
      role={
        "dialog"
      /* String indicating the role of the modal, allowing the 'dialog' role
         to be applied if desired. This attribute is `dialog` by default. */}
    
      preventScroll={
        false
      /* Boolean indicating if the modal should use the preventScroll flag when
         restoring focus to the element that had focus prior to its display. */}
    
      parentSelector={
        () => document.body
      /* Function that will be called to get the parent element
         that the modal will be attached to. */}
    
      aria={
        {
          labelledby: "heading",
          describedby: "full_description"
        }
      /* Additional aria attributes (optional). */}
    
      data={
        { background: "green" }
      /* Additional data attributes (optional). */}
    
      testId={
        ""
      /* String testId that renders a data-testid attribute in the DOM,
        useful for testing. */}
    
      overlayRef={
        setOverlayRef
      /* Overlay ref callback. */}
    
      contentRef={
        setContentRef
      /* Content ref callback. */}
    
      overlayElement={
        (props, contentElement) => <div {...props}>{contentElement}</div>
      /* Custom Overlay element. */}
    
      contentElement={
        (props, children) => <div {...props}>{children}</div>
      /* Custom Content element. */}
      >
        <p>Modal Content</p>
    </ReactModal>
  9. Configure accessibility with setAppElement

    master

    To ensure the modal is accessible, you must bind the modal to your application's root element using Modal.setAppElement(). This allows screen readers to correctly identify the main content and the modal context.

    import Modal from 'react-modal';
    
    // Replace '#yourAppElement' with the ID of your application's root element
    Modal.setAppElement('#yourAppElement');
  10. Style the modal content and overlay with CSS classes

    master

    Use the className and overlayClassName props to apply CSS classes to the modal content and the overlay.

    Each prop can be:

    1. A single string containing the class name.
    2. An object with the following keys:
      • base: Always applied.
      • afterOpen: Applied after the modal has been opened.
      • beforeClose: Applied when the modal requests to close (e.g., via Escape key or overlay click).

    Important Notes:

    • If you use afterOpen or beforeClose for transitions, you must set the closeTimeoutMS prop to a non-zero value (matching your transition length) so the beforeClose class has time to be visible.
    • Specifying className or overlayClassName disables the default inline styles for those elements.
    • If no classes are provided, react-modal applies default classes using the ReactModal__Overlay and ReactModal__Content prefixes.
  11. Configure closeTimeoutMS for transitions

    master

    To ensure transitions work correctly, you must inform the <Modal /> component of the duration required for the animation using the closeTimeoutMS prop. The value provided to closeTimeoutMS (in milliseconds) must match the duration used in your CSS transition property.

    <Modal closeTimeoutMS={2000} />