1.1.0 • Published 2 years ago

@yet3/use-modal v1.1.0

Weekly downloads
-
License
MIT
Repository
github
Last release
2 years ago

useModal

GitHub license npm

React hook that makes using modals easier.

Table of Contents

Installation

yarn add @yet3/use-modal

or with npm

npm install @yet3/use-modal

Simple usage

import { useModal } from '@yet3/use-modal';

const MyModal = () => {
  return ( 
    ...
  )
}

const Component = () => {
  const modal = useModal(MyModal)

  return (
    <div>
      <button onClick={modal.open}>Open modal</button>
      {modal.component}
    </div>
  )
}

Options

export interface BackdropOptions {
  backdropColor: string;
  closeOnBackdropClick?: boolean
  onBackdropClick?: (d: {closeModal: ModalCloseFunc}) => void | null | false
  backdropStyle?: CSSProperties
}

export interface CommonOptions {
  closeAfter?: null | false | number;
  portalElement?: PortalElement | null;

  backdropColor?: string | null | false;
  backdrop?: boolean | null | JSX.Element | ((children: ReactNode, opts: BackdropOptions) => JSX.Element);
  closeOnBackdropClick?: boolean
  onBackdropClick?: (d: {closeModal: ModalCloseFunc}) => void | null | false
  backdropStyle?: CSSProperties
  modalWrapper?: false | null | ((children: ReactNode, opts: ModalWrapperOptions) => JSX.Element) | JSX.Element;
}

// Options passed via UseModal.setOptions(Options)
export interface UseModalOptions extends CommonOptions {
  startOpen?: boolean;
}

// Options passed to useModal(Options) hook
export interface UseModalHookOptions<P extends ModalProps> extends CommonOptions {
  startOpen?: boolean;
  props?: Partial<P>;
}

// Options passed to open/toggle functions
export interface ModalOptions<P extends ModalProps> extends CommonOptions {
  props?: P;
}

useModal

useModal hook returns:

  • isOpen: boolean - whether modal is open
  • open: (options?: ModalOptions) => void - function to open modal
  • close: () => void - function to close modal
  • toggle: (options?: ModalOptions) => void - function to open/close modal
  • component: ReactPortal | null - modal's portal
  • options: ModalOptions | null - when modal's open will return its options otherwise will return null

UseModal

Other type

  • ModalCloseFunc: () => void
  • ModalBaseProps:
    • closeModal: ModalCloseFunc - function passed to every modal that allows to close it

Examples

With props

import { useModal, ModalBaseProps } from '@yet3/use-modal';

interface ModalProps extends ModalBaseProps {
  text: string;
  color?: string;
}

const MyModal = ({ closeModal, text, color = 'black' }: ModalProps) => {
  return (
    <aside
      style={{
        position: 'fixed',
        top: '50%',
        left: '50%',
        transform: 'translate(-50%, -50%)',
        backgroundColor: 'white',
        border: '1px solid rgb(150, 150, 150)',
        padding: 16,
      }}
    >
      <header style={{ fontSize: 18, fontWeight: 'bold' }}>Super cool modal</header>
      <main style={{ color: color }}>{text}</main>
      <footer>
        <button onClick={closeModal} style={{ border: '1px solid rgb(200, 200, 200)', padding: 4, cursor: 'pointer' }}>
          Close
        </button>
      </footer>
    </aside>
  );
};

const Component = () => {
  const modal = useModal(MyModal, { props: { color: 'red' } });

  return (
    <div>
      <button onClick={() => modal.open({ props: { text: 'Super cool text' } })}>Open modal</button>
      {modal.component}
    </div>
  );
};

With modalWrapper

import { useModal, ModalBaseProps, UseModal } from '../../src';

UseModal.setOptions({
  modalWrapper: (
    <aside
      style={{
        position: 'fixed',
        top: '50%',
        left: '50%',
        transform: 'translate(-50%, -50%)',
        backgroundColor: 'white',
        border: '1px solid rgb(150, 150, 150)',
        padding: 16,
      }}
    />
  ),
});

const FirstModal = ({ closeModal }: ModalBaseProps) => {
  return (
    <>
      <span>First Modal</span>
      <button
        onClick={closeModal}
        style={{ marginLeft: 5, border: '1px solid rgb(200, 200, 200)', padding: 4, cursor: 'pointer' }}
      >
        Close
      </button>
    </>
  );
};

const SecondModal = ({ closeModal }: ModalBaseProps) => {
  return (
    <>
      <span>Second Modal</span>
      <button
        onClick={closeModal}
        style={{ marginLeft: 5, border: '1px solid rgb(200, 200, 200)', padding: 4, cursor: 'pointer' }}
      >
        Close
      </button>
    </>
  );
};

const Component = () => {
  const modal1 = useModal(FirstModal);
  const modal2 = useModal(SecondModal, {
    backdropColor: 'rgba(255, 100, 100, 0.7)',
  });

  return (
    <div style={{ display: 'flex', flexDirection: 'column' }}>
      <button onClick={() => modal1.toggle()}>Toggle modal 1</button>
      <button onClick={() => modal2.toggle()}>Toggle modal 2</button>
      {modal1.component}
      {modal2.component}
    </div>
  );
};