1.0.2 • Published 1 year ago

react-attached-modal-portal v1.0.2

Weekly downloads
-
License
MIT
Repository
github
Last release
1 year ago

react-attached-modal-portal

React modal which attaches to selected parent. It will automatically calculate is it enough space under the button and place the modal below or above the button.

NPM version npm-typescriptLicense]github-license-url

Installation:

npm install react-attached-modal-portal --save

or

yarn add react-attached-modal-portal

React Modal With Scroll And Mobile View

Usage:

For correct position work of AttachedModal you need to pass your button and ref:

import React, { useRef, useState } from 'react';

import { AttachedModal } from 'react-attached-modal-portal';

const App = () => {
  const [selected, setSelected] = useState(5);
  const [isOpen, setIsOpen] = useState(false);
  const ref = useRef<HTMLButtonElement>(null);

  return (
    <AttachedModal
      isOpen={isOpen}
      buttonRect={ref.current?.getBoundingClientRect()}
      setIsOpen={setIsOpen}
      withScroll
      OpenModalBtn={
        <button ref={ref} onClick={() => setIsOpen(true)}>
          Open
        </button>
      }
      Header={
        <div style={{ display: 'flex', justifyContent: 'space-between', padding: 10 }}>
          <span style={{ fontWeight: 'bold' }}>Header</span>
          <button onClick={() => setIsOpen(false)}>X</button>
        </div>
      }
      Footer={
        <div style={{ padding: 10 }}>
          <button autoFocus onClick={() => setSelected(0)}>
            Clear
          </button>
        </div>
      }
    >
      <div style={{ padding: 10, overflow: 'hidden' }}>
        {[...new Array(selected)].map((_value, index) => (
          <div key={index}>
            Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry
            standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to
            make a type specimen book. It has survived not only five centuries, but also the leap into electronic
            typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset
            sheets containing Lorem Ipsum passages, and more recently with desktop publishi
          </div>
        ))}
      </div>
    </AttachedModal>
  );
};

Other options such as Header, withScroll etc are optional. If you pass withScroll it will add scroll to the body of the modal and will save the position of scroll after closing modal.

Attached modal Customized

Usage:

If you want to customize styles based on AttachedModal properties you can use useAttachedModalContext: For correct using you need to add AttachedModalContextProvider above the AttachedModal component.

import React, { useRef, useState } from 'react';

import { AttachedModal, useAttachedModalContext, AttachedModalContextProvider } from 'react-attached-modal-portal';

const App = () => {
  const [selected, setSelected] = useState(5);
  const [isOpen, setIsOpen] = useState(false);

  const ref = useRef<HTMLButtonElement>(null);

  const { isMobile, canModalFitBelowButton } = useAttachedModalContext();

  const desktopBackground = canModalFitBelowButton ? 'green' : 'orange';

  return (
    <AttachedModal
      isOpen={isOpen}
      buttonRect={ref.current?.getBoundingClientRect()}
      setIsOpen={setIsOpen}
      withScroll
      OpenModalBtn={
        <button ref={ref} onClick={() => setIsOpen(true)}>
          Open
        </button>
      }
      Header={
        <div style={{ display: 'flex', justifyContent: 'space-between', padding: 10 }}>
          <span style={{ fontWeight: 'bold' }}>Header</span>
          <button onClick={() => setIsOpen(false)}>X</button>
        </div>
      }
      Footer={
        <div style={{ padding: 10 }}>
          <button autoFocus onClick={() => setSelected(0)}>
            Clear
          </button>
        </div>
      }
      wrapperStyles={{
        background: isMobile ? 'purple' : desktopBackground,
        color: isMobile ? 'white' : 'black',
      }}
    >
      <div style={{ padding: 10, overflow: 'hidden' }}>
        {[...new Array(selected)].map((_value, index) => (
          <div key={index}>
            Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry
            standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to
            make a type specimen book. It has survived not only five centuries, but also the leap into electronic
            typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset
            sheets containing Lorem Ipsum passages, and more recently with desktop publishi
          </div>
        ))}
      </div>
    </AttachedModal>
  );
};


root.render(
  <React.StrictMode>
    <AttachedModalContextProvider>
      <App />
    </AttachedModalContextProvider>
  </React.StrictMode>,
);

Other options such as Header, withScroll etc are optional. If you pass withScroll it will add scroll to the body of the modal and will save the position of scroll after closing modal.

Props AttachedModal:

NameTypeDescription
HeaderReact.ReactNodeHeader of Modal
FooterReact.ReactNodeFooter of Modal
isOpenbooleanState of Modal
setIsOpenReact.Dispatch<React.SetStateAction<boolean>>Handler to change state of Modal
withScrollbooleanProp to add scroll to the body of Modal with remembering position of scroll
wrapperStylesReact.CSSPropertiesStyles for Wrapper
bodyStylesReact.CSSPropertiesStyles for body
buttonRectDOMRectButton parameters
OpenModalBtnReact.ReactElementButton with which you will open modal

If you want to support

Give a ⭐️ to project if you like it!

1.0.2

1 year ago

1.0.1

1 year ago

1.0.0

1 year ago