Socket
Socket
Sign inDemoInstall

@weahead/react-customizable-modal

Package Overview
Dependencies
5
Maintainers
6
Versions
6
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

    @weahead/react-customizable-modal

A fully customizable and accessable react modal with hook primitives.


Version published
Weekly downloads
61
decreased by-46.49%
Maintainers
6
Created
Weekly downloads
 

Readme

Source

react-customizable-modal

A fully customizable and accessable react modal with hook primitives.

Motivation

There are several modal implementations in react, but none of them offered the flexibility to have total controll of the components being rendered so that you could use what ever animation library we wanted.

Features

  • Easy out of the box Modal component.
  • Exposes the underlying hooks to make it possible to compose them as you see fit.

Demos

Default builtin Modal Animated modal with react-spring Swipe up from below

Code Examples

Basic Modal

import { Modal } from "@weahead/react-customizable-modal";

function App() {
  const [isOpen, setIsOpen] = useState(false);
  return (
    <div>
      <button
        onClick={() => {
          setIsOpen(true);
        }}
      >
        Open modal
      </button>
      <Modal
        isOpen={isOpen}
        onEscape={() => {
          setIsOpen(false);
        }}
        onOverlayClick={() => {
          setIsOpen(false);
        }}
      >
        <button
          onClick={() => {
            setIsOpen(false);
          }}
        >
          Close
        </button>
      </Modal>
    </div>
  );
}

Custom Modal with custom overlay

CustomModal.jsx

import React from "react";
import {
  useTrapFocus,
  useBodyScrollLock,
  useCloseOnEsc,
  ModalPortal
} from "react-customizable-modal";

function Overlay({ children }) {
  return (
    <div
      style={{
        display: "flex",
        justifyContent: "center",
        alignItems: "center",
        position: "fixed",
        top: 0,
        bottom: 0,
        left: 0,
        right: 0
      }}
    >
      {children}
    </div>
  );
}

export default function CustomModal({ isOpen, onClose, children }) {
  useBodyScrollLock();
  useCloseOnEsc(onClose);
  const modalRef = useTrapFocus();
  return (
    isOpen && (
      <ModalPortal id={`customModal`}>
        <Overlay>
          <div
            ref={modalRef}
            style={{
              width: 500,
              height: 400,
              backgroundColor: "#fff",
              padding: 20,
              position: "absolute"
            }}
          >
            <button onClick={onClose}>Close modal</button>
            {children}
          </div>
        </Overlay>
      </ModalPortal>
    )
  );
}

App.jsx

import CustomModal from "CustomModal.jsx";
function App() {
  const [isOpen, setIsOpen] = useState(false);
  return (
    <div>
      <button
        onClick={() => {
          setIsOpen(true);
        }}
      >
        Open modal
      </button>

      <CustomModal
        isOpen={isOpen}
        onClose={() => {
          setIsOpen(false);
        }}
      >
        This is a custom modal
      </CustomModal>
    </div>
  );
}

Installation

npm i @weahead/react-customizable-modal

OR

yarn add @weahead/react-customizable-modal

API Reference

Components

ModalPortal

a simple wrapper around React.createPortal function, but it also removes the div from the DOM on unmount

Props
PropRequiredDescription
idyesthis will give the DOMnode that is created to hold the modal content an id if there already is a DOMnode with that id it will reuse that for the new modal
childrenyesThis is the content of the portal, usually the entire modal, including the overlay
Modal

A basic Modal component ready for use, if you dont want to implement your own. it uses only the hooks and components from this packagfe

Props
PropRequiredDescription
idyesthis will give the DOMnode that is created to hold the modal content an id if there already is a DOMnode with that id it will reuse that for the new modal
isOpenyesthis will be used to create the portal for the modal and mount the modal
rolenofor a11y purposes we can set the role for our modal, it defaults to dialog
ariaHideAppnosets a aria hide on the div with id of 'root'
shouldFocusAfterRendernodefaults to true and sets the focus on the modal div
onOverlayClicknolets you pass in a function that is triggered when clicking on the overlay, you might want to pass a function that sets the isOpen prop to false IE closing the modal
shouldReturnFocusAfterClosenodefaults to true, will return focus to last focus element before the modal was opened
onEscapenolets you pass a function to that is triggered if you press the ESC key while the modal is active, often you want to close the modal
childrenyesthe content of the modal

Hooks

useTrapFocus

import {useTrapFocus} from '@weahead/react-customizable-modal'

used to trap focus inside of the modal component

const modalRef = useTrapFocus(options);
// returns a ref that needs to be given to the element that you want to trap focus within
<div ref={modalRef}>focus will be trapped in this div</div>;
optionrequireddescription
focusOnRendernodefaults to true, will focus the modal container
returnFocusnodefaults to true, will return focus to last focused element when the component that uses this hook unmounts
useAriaHide

import {useAriaHide} from '@weahead/react-customizable-modal'

sets the aria-hidden attribute on the element with the id passed in and removes is when the component that uses this hook is unmounted

useAriaHide(id); //often `id` would be 'root'
argumentrequireddescription
idyesadd the aria-hide attribute to the element with the id
useBodyScrollLock

import {useBodyScrollLock} from '@weahead/react-customizable-modal'

this is taken from usehooks all credit goes to them. it locks the body from scrolling while the component that uses this hook is rendered.

useBodyScrollLock();
useHandleKeyPress

import {useHandleKeyPress} from '@weahead/react-customizable-modal'

this hook is used by the useCloseOnEsc hook and other internal components it lets you provide a function that is executed on every keypress while the component that uses this hook is mounted

useHandleKeyPress(e => {
  console.log(e.keyCode);
});
argumentrequireddescription
callbackyesgets called with every keypress
useCloseOnEsc

import {useCloseOnEsc} from '@weahead/react-customizable-modal'

this hook is used by the useHandleKeyPress hook but only triggers the callback if the escape key is pressed

useCloseOnEsc(() => {
  console.log("ESC key was pressed");
});
argumentrequireddescription
callbackyesgets called when escape is pressed

https://github.com/reactjs/react-modal https://github.com/davidtheclark/tabbable/blob/master/index.js https://github.com/davidtheclark/focus-trap#focustrap--createfocustrapelement-createoptions

Keywords

FAQs

Last updated on 20 Feb 2020

Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Packages

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc