react-hyper-modal
    TypeScript icon, indicating that this package has built-in type declarations

    1.2.11 • Public • Published

    React hyper modal

    Fully customizable and accessible modal react component

    Welcome to the react hyper modal repository 😄 I want to introduce you to an awesome react component for displaying modal windows

    license Coverage Status Build Status min minzip

    Live demo

    Check also the new stackable content feature!

    Table of contents

    Installation

    You can use npm or yarn package managers
    $ npm i --save react-hyper-modal

    or

    $ yarn add react-hyper-modal

    Usage

    Controlled modal component

    import React from 'react';
    import HyperModal from 'react-hyper-modal';
     
    ...
     
    class MyComponent extends React.Component {
      constructor(props) {
        super(props);
        this.state = {
          isModalOpen: false,
        };
      }
     
      ...
     
      openModal => this.setState({ isModalOpen: true });
      closeModal => this.setState({ isModalOpen: false });
     
      ...
     
      render() {
        const { isModalOpen } = this.state;
        return (
          <HyperModal
            isOpen={isModalOpen}
            requestClose={this.closeModal}
          >
            Your awesome modal content
          </HyperModal>
        );
      }
    }

    Uncontrolled modal component

    import React from 'react';
    import HyperModal from 'react-hyper-modal';
     
    ...
     
    const MyComponent = () => {
      return (
        <HyperModal
          renderOpenButton={(requestOpen) => {
            return (
              <button onClick={requestOpen}>Open uncontrolled modal</button>
            );
          }
        />
      );
    }

    Stackable content example

    To use stackable content you should use ModalStack component and children as function. Every child of ModalStack will represent a different layout.

    import React from 'react';
    import HyperModal, { ModalStack, ModalStackProps } from 'react-hyper-modal';
     
    ...
     
    const Component = () => {
      const [index, setIndex] = React.useState(0)
      return (
        <HyperModal
          stackable
          stackableIndex={index}
          renderOpenButton={requestOpen => (
            <button type="button" className={styles.button} onClick={requestOpen}>Open stackable modal</button>
          )}
        >
          {(props: ModalStackProps) => (
            <ModalStack {...props}> // !!! It's very important to provide props to ModalStack
              <div style={{ color: 'red' }}>
                <div>1</div>
                <button onClick={() => setIndex(1)}>open nested</button>
                <button onClick={() => props.handleClose()}>close</button>
              </div>
              <div>
                <div>2</div>
                <button onClick={() => setIndex(2)}>open nested</button>
                <button onClick={() => setIndex(0)}>close nested</button>
                <button>close</button>
              </div>
              <div>
                <div>3</div>
                <button onClick={() => setIndex(1)}>close nested</button>
                <button onClick={() => props.handleClose()}>close</button>
              </div>
            </ModalStack>
          )}
        </HyperModal>
      )
    }

    That's it! 🍰✨

    Properties

    You can find props types and default props below the table.

    * - required for controlled modal component
    Props Description
    afterClose callback that is called after closing
    ariaEnabled enable ARIA properties
    ariaProps custom ARIA properties
    beforeClose callback that is called before closing
    childrenMode describing if the modal content should be rendered as React Children
    classes overriding default modal class names
    closeDebounceTimeout time to close modal
    closeIconPosition position of close button
    closeOnCloseIconClick close the modal by pressing close button
    closeOnDimmerClick close the modal by pressing on dimmer
    closeOnEscClick close the modal by pressing ESC
    dimmerEnabled describing if the dimmer should be shown or not
    isFullscreen describing if the modal should be shown in full screen or not
    isOpen * describing if the modal should be shown or not
    modalContentRef reference to the modal content div
    modalWrapperRef reference to the modal wrapper div
    portalMode describing if the modal should be rendered in React Portal or not
    portalNode HTML node to create React Portal
    position setting the modal position
    renderCloseIcon callback for rendering custom close button
    renderContent callback for rendering custom modal content
    renderOpenButton callback or boolean describing if the modal should be uncontrolled component
    requestClose * callback to close the modal
    stackable make content stackable
    stackableIndex stack length
    stackContentSettings stackable content settings
    unmountOnClose describing if the modal should be unmounted when close

    Default properties

    {
      ariaEnabled: true,
      ariaProps: {
        'aria-describedby': 'hyper-modal-description',
        'aria-labelledby': 'hyper-modal-title',
        role: 'dialog',
      },
      disableScroll: true,
      childrenMode: true,
      closeDebounceTimeout: 0,
      closeIconPosition: {
        vertical: 'top' as const,
        horizontal: 'rightas const,
      },
      closeOnCloseIconClick: true,
      closeOnDimmerClick: true,
      closeOnEscClick: true,
      dimmerEnabled: true,
      isFullscreen: false,
      portalMode: false,
      position: {
        alignItems: 'centeras const,
        justifyContent: 'centeras const,
      },
      stackable: false,
      stackableIndex: 0,
      stackContentSettings: {
        widthRatio: 4,
        topOffsetRatio: 2,
        transition: 'all 0.3s ease',
        opacityRatio: 0.2,
      } 
    }

    Types

    type TModalPosition = 'flex-start' | 'center' | 'flex-end';
    type THorizontalPosition = 'left' | 'center' | 'right';
    type TVerticalPosition = 'top' | 'middle' | 'bottom';
     
    interface IClassNamesProps {
      closeIconClassName?: string;
      contentClassName?: string;
      dimmerClassName?: string;
      portalWrapperClassName?: string;
      wrapperClassName?: string;
    }
     
    interface IARIAProps {
      'aria-describedby'?: string;
      'aria-labelledby'?: string;
      role?: string;
    }
     
    interface IPositionProps {
      alignItems?: TModalPosition;
      justifyContent?: TModalPosition;
    }
     
    interface ICloseIconPosition {
      horizontal?: THorizontalPosition;
      vertical?: TVerticalPosition;
    }
     
    interface IModalProps {
      afterClose?: () => void;
      ariaEnabled?: boolean;
      ariaProps?: IARIAProps;
      beforeClose?: () => void;
      childrenMode?: boolean;
      classes?: IClassNamesProps;
      closeDebounceTimeout?: number;
      closeIconPosition?: ICloseIconPosition;
      closeOnCloseIconClick?: boolean;
      closeOnDimmerClick?: boolean;
      closeOnEscClick?: boolean;
      dimmerEnabled?: boolean;
      isFullscreen?: boolean;
      isOpen: boolean;
      modalContentRef?: React.RefObject<HTMLDivElement>;
      modalWrapperRef?: React.RefObject<HTMLDivElement>;
      portalMode?: boolean;
      portalNode?: HTMLElement;
      position?: IPositionProps;
      renderCloseIcon?: () => JSX.Element | null | string;
      renderContent?: () => JSX.Element | JSX.Element[] | null | string;
      renderOpenButton?: boolean | ((requestOpen: () => void) => JSX.Element | string);
      requestClose: () => void;
      unmountOnClose?: boolean;
    }

    Contributing

    Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.

    Please make sure to update tests as appropriate.

    License

    MIT

    Install

    npm i react-hyper-modal

    DownloadsWeekly Downloads

    4,396

    Version

    1.2.11

    License

    MIT

    Unpacked Size

    160 kB

    Total Files

    27

    Last publish

    Collaborators

    • alekseymakhankov