1.0.0 • Published 3 years ago

@bdenzer/react-modal v1.0.0

Weekly downloads
238
License
MIT
Repository
github
Last release
3 years ago

@bdenzer/react-modal

Simple Modal Component For React

Styled by default to look like Bootstrap's Modal, but it is highly customizable.

Installation

yarn add @bdenzer/react-modal\ or\ npm install @bdenzer/react-modal --save

See The Demo Here

Getting Started

It is best practice to put a modal component at the 'top level'. In React 16.2+ this is even easier using React.Fragment. This advice is not specific to a particular component - nesting a modal inside an element that has it's CSS position set will cause it to render in the wrong place.

Required Props

  • shouldShowModal: boolean
  • closeModal: function

Optional Props

  • title: string
  • customStyle - object containing JS style objects - see 'Adding Custom Styles' Demo below
  • onlyCloseWithButton: boolean - by default the modal will close if you click outside of the main modal area, use onlyCloseWithButton to remove this behavior

Minimal Example ---- ( TypeScript Example Here )

  import React, { Component } from 'react';
  import Modal from '@bdenzer/react-modal';

  export default class App extends Component {
    constructor(props) {
      super(props);
      this.state = {
        shouldShowModal: false
      }
      this.closeModal = this.closeModal.bind(this);
      this.openModal = this.openModal.bind(this);
    }

    closeModal() {
      this.setState({ shouldShowModal: false });
    }

    openModal() {
      this.setState({ shouldShowModal: true });
    }

    render() {
      return (
        <div>
          <Modal
            closeModal={this.closeModal}
            shouldShowModal={this.state.shouldShowModal}
          >
            This is some text inside the modal
          </Modal>
          <button onClick={this.openModal}>Open Modal</button>
        </div>
      );
    }
  }

Customizing The Styles

Every element in the modal has it's own id so you can use Styled Components, Emotion, SCSS, LESS, CSS... Or you can set the customStyle prop with a JS style object (<React.CSSProperties> in TypeScript).

Here is a full list of the style options

customStyle propCSS IDDescription
animationTime: number(ms)set in customStyle propsetting it via CSS will be a headache
closeButton#modal-closeButtonsquare box in top right corner
closeButtonHover#modal-closeButton:hoverhovered state of the close button
closeButtonText#modal-closeButtonTextthe 'X' inside the close button
hoveredButtonText#modal-closeButton:hover #modal-closeButtonTextthe 'X' while the outer button is hovered
modalBackground#modal-modalBackgroundthe outer, semi-transparent section
modalBackgroundOpen#modal-modalBackground.openfinal position of open animation
modalBackgroundTransition#modal-modalBackground.transitionstarting point of open animation
modalBody#modal-modalBodyunder the modalHeader
modalHeader#modal-modalHeadertop row, the title and closeButton
modalInner#modal-modalInnermodalHeader + modalBody (everything that is not modalBackground)
modalTitle#modal-modalTitletext in the top left of the modal

Scroll down to see styling examples, and you can also see a more complicated example that I used in the Demo - Code - Demo

Removing Animation\ Setting animationTime to 0 will make the modal show without animating in/out.

Example - Adding Custom Styles in JS

  import React, { Component } from 'react';
  import Modal from '@bdenzer/react-modal';

  export default class App extends Component {
    constructor(props) {
      super(props);
      this.state = {
        shouldShowModal: false
      }
      this.closeModal = this.closeModal.bind(this);
      this.openModal = this.openModal.bind(this);
    }

    closeModal() {
      this.setState({ shouldShowModal: false });
    }

    openModal() {
      this.setState({ shouldShowModal: true });
    }

    render() {
      const modalStyle = {
        animationTime: 400,
        modalHeader: {
          backgroundColor: 'green'
        },
        modalTitle: {
          color: 'white'
        },
        closeButtonText: {
          color: 'white'
        },
        hoveredButtonText: {
          fontWeight: 'bold'
        }
      };

      return (
        <div>
          <Modal
            closeModal={this.closeModal}
            customStyle={modalStyle}
            shouldShowModal={this.state.shouldShowModal}
            title="Demo Modal"
          >
            This is some text inside the modal
          </Modal>
          <button onClick={this.openModal}>Open Modal</button>
        </div>
      );
    }
  }

Example - Adding Custom Styles in TypeScript

Import { ICustomModalStyle } to make your life easier

  import * as React from 'react';

  import Modal, { ICustomModalStyle } from '@bdenzer/react-modal';

  interface IAppState {
    shouldShowModal: boolean;
  }

  export default class App extends React.Component<{}, IAppState> {
    constructor(props: {}) {
      super(props);
      this.state = {
        shouldShowModal: false
      }
      this.closeModal = this.closeModal.bind(this);
      this.openModal = this.openModal.bind(this);
    }

    public render(): JSX.Element {
      const modalStyle: ICustomModalStyle = {
        animationTime: 400,
        closeButtonText: {
          color: 'white'
        },
        hoveredButtonText: {
          fontWeight: 'bold'
        },
        modalHeader: {
          backgroundColor: 'green'
        },
        modalTitle: {
          color: 'white'
        }
      };
      return (
        <div>
          <Modal
            closeModal={this.closeModal}
            customStyle={modalStyle}
            shouldShowModal={this.state.shouldShowModal}
            title="React Modal in TypeScript"
          >
            This is some text inside the modal
          </Modal>
          <button onClick={this.openModal}>Open Modal</button>
        </div>
      );
    }

    private closeModal(): void {
      this.setState({ shouldShowModal: false });
    }

    private openModal(): void {
      this.setState({ shouldShowModal: true });
    }
  }

Contributing

There are basically 2 projects inside the repo - the Modal Component (./src/Modal) and the Demo (./demo). Only the Modal gets published to NPM but the demo is where you'll test any changes that you make.

  • yarn start - build / serve the demo, default is http://localhost:3000 but check your console output if you are already using port 3000.
  • yarn test - run tests
  • yarn test:watch - run tests on save

Add tests if you are changing any functionality.

Known Issues

yarn test:watch throws ENOSPC error on Linux

If you run into this issue, you'll need to increase the number of 'watchers' on your system. Run echo fs.inotify.max_user_watches=524288 | sudo tee -a /etc/sysctl.conf && sudo sysctl -p to fix. (From this issue in the Jest repository.)