0.1.7 • Published 5 years ago

@thumbtack/tp-ui-react-modal-curtain v0.1.7

Weekly downloads
-
License
UNLICENSED
Repository
github
Last release
5 years ago

package: '@thumbtack/tp-ui-react-modal-curtain' kit: component/modal-curtain.yaml platform: react

url: /api/components/component/modal-curtain/react/

Examples

The ModalCurtain component makes it easy to create an accessible overlay that contains content and covers the page. It contains a few powerful features:

  • Focus trap: Move the browser's focus to the first interactive element within the children. Trap the focus within the ModalCurtain while it is open, preventing users from accidentally tabbing to the page underneath.
  • Scroll lock: Prevent the page from scrolling while the ModalCurtain is open.
  • Append to the body tag: Move the HTML to end of the DOM, right before the </body> tag. This greatly decreases the chance of running into z-index issues.
  • Listen for Esc key press: Run a function to close the ModalCurtain if the user presses Esc.
  • Close on ModalCurtain click: Make it easy to close the modal if the ModalCurtain is clicked on.

The ModalCurtain component CSS handles positioning, overflow, z-index, visibility, and opacity. It does not include background colors, padding, transitions, or other opinionated styles since the component was designed to be versatile.

ModalCurtain with a basic modal

This example contains a ModalCurtain with a basic modal and no transition. Because there is no transition, the stage prop only cycles between entered and exited.

class ModalCurtainDemo extends React.Component {
    constructor() {
        super();

        this.state = {
            isOpen: false,
        };

        this.closeModal = this.closeModal.bind(this);
        this.openModal = this.openModal.bind(this);
    }

    closeModal() {
        this.setState({ isOpen: false });
        console.log('ModalCurtain `onCloseClick` fired');
    }

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

    render() {
        return (
            <div>
                <Button onClick={this.openModal}>Open Modal</Button>

                <ModalCurtain
                    stage={this.state.isOpen ? 'entered' : 'exited'}
                    onCloseClick={this.closeModal}
                >
                    {({ curtainClassName, curtainOnClick }) => (
                        <div
                            className={curtainClassName}
                            onClick={curtainOnClick}
                            style={{
                                backgroundColor: 'rgba(0, 0, 0, 0.5)',
                                padding: '24px',
                            }}
                        >
                            <div
                                style={{
                                    backgroundColor: 'white',
                                    maxWidth: '500px',
                                    margin: 'auto',
                                    padding: '24px',
                                }}
                            >
                                Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum
                                dapibus est nec eros congue, ac dapibus ipsum cursus. Quisque at
                                odio viverra, consequat metus a, commodo ipsum. Donec sodales sapien
                                in luctus sodales. Vivamus ornare mauris in arcu maximus placerat.
                                Cras vitae interdum ipsum. Proin convallis quis elit quis
                                pellentesque. Curabitur a ex eget neque congue tempor sed ut felis.
                                Vivamus in erat ac lacus vehicula condimentum. Nam fringilla
                                molestie facilisis. Etiam eros nisl, mattis et sagittis non, blandit
                                vel nisl. Duis blandit condimentum lorem, sed convallis sapien
                                porttitor vitae. Curabitur molestie, massa et molestie aliquam, odio
                                purus rhoncus sem, a sodales ipsum nisi ac nibh. Nunc in dapibus
                                mauris. Pellentesque rhoncus id arcu at auctor.
                                <div style={{ marginTop: '24px' }}>
                                    <Button onClick={this.closeModal}>Close Modal</Button>
                                </div>
                            </div>
                        </div>
                    )}
                </ModalCurtain>
            </div>
        );
    }
}

ModalCurtain with a full screen takeover

The ModalCurtain component works well for full-screen takeovers. This example doesn't use curtainOnClick since we don't want to close the curtain when clicking on the backdrop.

class ModalCurtainDemo extends React.Component {
    constructor() {
        super();

        this.state = {
            isOpen: false,
        };

        this.closeModal = this.closeModal.bind(this);
        this.openModal = this.openModal.bind(this);
    }

    closeModal() {
        this.setState({ isOpen: false });
        console.log('ModalCurtain `onCloseClick` fired');
    }

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

    render() {
        return (
            <div>
                <Button onClick={this.openModal}>Open Modal</Button>

                <ModalCurtain
                    stage={this.state.isOpen ? 'entered' : 'exited'}
                    onCloseClick={this.closeModal}
                >
                    {({ curtainClassName, curtainOnClick }) => (
                        <div
                            className={curtainClassName}
                            style={{
                                backgroundColor: 'white',
                                padding: '24px',
                            }}
                        >
                            <div
                                style={{
                                    maxWidth: '500px',
                                    margin: 'auto',
                                }}
                            >
                                Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum
                                dapibus est nec eros congue, ac dapibus ipsum cursus. Quisque at
                                odio viverra, consequat metus a, commodo ipsum. Donec sodales sapien
                                in luctus sodales. Vivamus ornare mauris in arcu maximus placerat.
                                Cras vitae interdum ipsum. Proin convallis quis elit quis
                                pellentesque. Curabitur a ex eget neque congue tempor sed ut felis.
                                Vivamus in erat ac lacus vehicula condimentum. Nam fringilla
                                molestie facilisis. Etiam eros nisl, mattis et sagittis non, blandit
                                vel nisl. Duis blandit condimentum lorem, sed convallis sapien
                                porttitor vitae. Curabitur molestie, massa et molestie aliquam, odio
                                purus rhoncus sem, a sodales ipsum nisi ac nibh. Nunc in dapibus
                                mauris. Pellentesque rhoncus id arcu at auctor.
                                <div style={{ marginTop: '24px' }}>
                                    <Button onClick={this.closeModal}>Close Modal</Button>
                                </div>
                            </div>
                        </div>
                    )}
                </ModalCurtain>
            </div>
        );
    }
}