Important: This documentation covers Yarn 1 (Classic).
For Yarn 2+ docs and migration guide, see yarnpkg.com.

Package detail

@thumbtack/tp-ui-react-modal-default

thumbtack1UNLICENSEDdeprecated0.3.9

This package is deprecated in favor of the '@thumbtack/thumbprint-react' NPM package.

--- package: '@thumbtack/tp-ui-react-modal-default' kit: component/modal-default.yaml platform: react url: /api/components/component/modal-default/react/ ---

readme


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

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

import Alert from './../../../../www/src/components/alert';

<Alert type="note"> The `ModalHeader`, `ModalTitle`, `ModalDescription`, `ModalConent`, and `ModalFooter` components have been renamed to `ModalDefaultHeader`, `ModalDefaultTitle`, `ModalDefaultDescription`, `ModalDefaultContent`, and `ModalDefaultFooter`. Both component names will work until Design Systems removes the old names in the next major version release.{' '} Learn more about this change. </Alert>

Modals can be opened or closed with a isOpen prop.

Basic modal with a form

The ModalDefault has a curtain (backdrop) at medium and large breakpoints. It appears fullscreen on small devices.

class ModalDefaultDemoBasic 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 });
    }

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

    onCloseFinish() {
        console.log('ModalDefault: `onCloseFinish`');
    }

    onOpenFinish() {
        console.log('ModalDefault: `onOpenFinish`');
    }

    render() {
        return (
            <React.Fragment>
                <Button onClick={this.openModal}>Open modal</Button>
                <ModalDefault
                    isOpen={this.state.isOpen}
                    onCloseClick={this.closeModal}
                    onCloseFinish={this.onCloseFinish}
                    onOpenFinish={this.onOpenFinish}
                >
                    <ModalDefaultHeader>
                        <ModalDefaultTitle>Add a professional license</ModalDefaultTitle>
                        <ModalDefaultDescription>
                            Licenses add credibility to your business and provide more trust for
                            customers.
                        </ModalDefaultDescription>
                    </ModalDefaultHeader>

                    <ModalDefaultContent>
                        <ol className="tp-form-fields">
                            <li className="tp-form-field__item">
                                <Label>License type</Label>
                                <Select value="default" isFullWidth onChange={() => {}}>
                                    <option value="default">Choose one&hellip;</option>
                                </Select>
                            </li>
                            <li className="tp-form-field__item">
                                <Label for="example-license-number">License number</Label>
                                <Input
                                    id="example-license-number"
                                    onChange={() => {}}
                                    placeholder="XX-XXXX-XXXX"
                                />
                            </li>
                        </ol>
                    </ModalDefaultContent>

                    <ModalDefaultFooter>
                        <ButtonRow justify="right">
                            <Button onClick={this.closeModal} width="full-below-small">
                                Submit
                            </Button>
                        </ButtonRow>
                    </ModalDefaultFooter>
                </ModalDefault>
            </React.Fragment>
        );
    }
}

This modal has a sticky footer that is always visible on small screens. The sticky footer is set by using the isSticky prop on the ModalDefaultFooter component.

The isSticky prop has no effect at medium or large breakpoints.

class ModalDefaultDemoStickyTall 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 });
    }

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

    render() {
        return (
            <React.Fragment>
                <Button onClick={this.openModal}>Open modal</Button>
                <ModalDefault isOpen={this.state.isOpen} onCloseClick={this.closeModal}>
                    <ModalDefaultHeader>
                        <ModalDefaultTitle>Add a professional license</ModalDefaultTitle>
                        <ModalDefaultDescription>
                            Licenses add credibility to your business and provide more trust for
                            customers.
                        </ModalDefaultDescription>
                    </ModalDefaultHeader>

                    <ModalDefaultContent>
                        <ol className="tp-form-fields">
                            <li className="tp-form-field__item">
                                <Label>License type</Label>
                                <Select value="default" isFullWidth onChange={() => {}}>
                                    <option value="default">Choose one&hellip;</option>
                                </Select>
                            </li>
                            <li className="tp-form-field__item">
                                <Label for="example-license-number">License number</Label>
                                <Input
                                    id="example-license-number"
                                    onChange={() => {}}
                                    placeholder="XX-XXXX-XXXX"
                                />
                            </li>
                            <li className="tp-form-field__item">
                                <Label for="example-license-number">License number</Label>
                                <Input
                                    id="example-license-number"
                                    onChange={() => {}}
                                    placeholder="XX-XXXX-XXXX"
                                />
                            </li>
                            <li className="tp-form-field__item">
                                <Label for="example-license-number">License number</Label>
                                <Input
                                    id="example-license-number"
                                    onChange={() => {}}
                                    placeholder="XX-XXXX-XXXX"
                                />
                            </li>
                            <li className="tp-form-field__item">
                                <Label for="example-license-number">License number</Label>
                                <Input
                                    id="example-license-number"
                                    onChange={() => {}}
                                    placeholder="XX-XXXX-XXXX"
                                />
                            </li>
                            <li className="tp-form-field__item">
                                <Label for="example-license-number">License number</Label>
                                <Input
                                    id="example-license-number"
                                    onChange={() => {}}
                                    placeholder="XX-XXXX-XXXX"
                                />
                            </li>
                            <li className="tp-form-field__item">
                                <Label for="example-license-number">License number</Label>
                                <Input
                                    id="example-license-number"
                                    onChange={() => {}}
                                    placeholder="XX-XXXX-XXXX"
                                />
                            </li>
                            <li className="tp-form-field__item">
                                <Label for="example-license-number">License number</Label>
                                <Input
                                    id="example-license-number"
                                    onChange={() => {}}
                                    placeholder="XX-XXXX-XXXX"
                                />
                            </li>
                            <li className="tp-form-field__item">
                                <Label for="example-license-number">License number</Label>
                                <Input
                                    id="example-license-number"
                                    onChange={() => {}}
                                    placeholder="XX-XXXX-XXXX"
                                />
                            </li>
                            <li className="tp-form-field__item">
                                <Label for="example-license-number">License number</Label>
                                <Input
                                    id="example-license-number"
                                    onChange={() => {}}
                                    placeholder="XX-XXXX-XXXX"
                                />
                            </li>
                        </ol>
                    </ModalDefaultContent>

                    <ModalDefaultFooter isSticky>
                        <ButtonRow justify="right">
                            <Button onClick={this.closeModal} width="full-below-small">
                                Submit
                            </Button>
                        </ButtonRow>
                    </ModalDefaultFooter>
                </ModalDefault>
            </React.Fragment>
        );
    }
}

This modal does not have a default, non-sticky footer. You'll have to scroll to view the button within the ModalDefaultFooter.

class ModalDefaultDemoTall 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 });
    }

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

    render() {
        return (
            <React.Fragment>
                <Button onClick={this.openModal}>Open modal</Button>
                <ModalDefault isOpen={this.state.isOpen} onCloseClick={this.closeModal}>
                    <ModalDefaultHeader>
                        <ModalDefaultTitle>Add a professional license</ModalDefaultTitle>
                        <ModalDefaultDescription>
                            Licenses add credibility to your business and provide more trust for
                            customers.
                        </ModalDefaultDescription>
                    </ModalDefaultHeader>

                    <ModalDefaultContent>
                        <ol className="tp-form-fields">
                            <li className="tp-form-field__item">
                                <Label>License type</Label>
                                <Select value="default" isFullWidth onChange={() => {}}>
                                    <option value="default">Choose one&hellip;</option>
                                </Select>
                            </li>
                            <li className="tp-form-field__item">
                                <Label for="example-license-number">License number</Label>
                                <Input
                                    id="example-license-number"
                                    onChange={() => {}}
                                    placeholder="XX-XXXX-XXXX"
                                />
                            </li>
                            <li className="tp-form-field__item">
                                <Label for="example-license-number">License number</Label>
                                <Input
                                    id="example-license-number"
                                    onChange={() => {}}
                                    placeholder="XX-XXXX-XXXX"
                                />
                            </li>
                            <li className="tp-form-field__item">
                                <Label for="example-license-number">License number</Label>
                                <Input
                                    id="example-license-number"
                                    onChange={() => {}}
                                    placeholder="XX-XXXX-XXXX"
                                />
                            </li>
                            <li className="tp-form-field__item">
                                <Label for="example-license-number">License number</Label>
                                <Input
                                    id="example-license-number"
                                    onChange={() => {}}
                                    placeholder="XX-XXXX-XXXX"
                                />
                            </li>
                            <li className="tp-form-field__item">
                                <Label for="example-license-number">License number</Label>
                                <Input
                                    id="example-license-number"
                                    onChange={() => {}}
                                    placeholder="XX-XXXX-XXXX"
                                />
                            </li>
                            <li className="tp-form-field__item">
                                <Label for="example-license-number">License number</Label>
                                <Input
                                    id="example-license-number"
                                    onChange={() => {}}
                                    placeholder="XX-XXXX-XXXX"
                                />
                            </li>
                            <li className="tp-form-field__item">
                                <Label for="example-license-number">License number</Label>
                                <Input
                                    id="example-license-number"
                                    onChange={() => {}}
                                    placeholder="XX-XXXX-XXXX"
                                />
                            </li>
                            <li className="tp-form-field__item">
                                <Label for="example-license-number">License number</Label>
                                <Input
                                    id="example-license-number"
                                    onChange={() => {}}
                                    placeholder="XX-XXXX-XXXX"
                                />
                            </li>
                            <li className="tp-form-field__item">
                                <Label for="example-license-number">License number</Label>
                                <Input
                                    id="example-license-number"
                                    onChange={() => {}}
                                    placeholder="XX-XXXX-XXXX"
                                />
                            </li>
                        </ol>
                    </ModalDefaultContent>

                    <ModalDefaultFooter>
                        <ButtonRow justify="right">
                            <Button onClick={this.closeModal} width="full-below-small">
                                Submit
                            </Button>
                        </ButtonRow>
                    </ModalDefaultFooter>
                </ModalDefault>
            </React.Fragment>
        );
    }
}

Narrow modal

It's possible to render narrow modals with the width prop.

class ModalDefaultDemoNarrow 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 });
    }

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

    render() {
        return (
            <React.Fragment>
                <Button onClick={this.openModal}>Open modal</Button>
                <ModalDefault
                    isOpen={this.state.isOpen}
                    width="narrow"
                    onCloseClick={this.closeModal}
                >
                    <ModalDefaultHeader>
                        <ModalDefaultTitle>Add a professional license</ModalDefaultTitle>
                        <ModalDefaultDescription>
                            Licenses add credibility to your business and provide more trust for
                            customers.
                        </ModalDefaultDescription>
                    </ModalDefaultHeader>

                    <ModalDefaultContent>
                        <ol className="tp-form-fields">
                            <li className="tp-form-field__item">
                                <Label>License type</Label>
                                <Select value="default" isFullWidth onChange={() => {}}>
                                    <option value="default">Choose one&hellip;</option>
                                </Select>
                            </li>
                            <li className="tp-form-field__item">
                                <Label for="example-license-number">License number</Label>
                                <Input
                                    id="example-license-number"
                                    onChange={() => {}}
                                    placeholder="XX-XXXX-XXXX"
                                />
                            </li>
                        </ol>
                    </ModalDefaultContent>

                    <ModalDefaultFooter>
                        <ButtonRow justify="right">
                            <Button onClick={this.closeModal} width="full-below-small">
                                Submit
                            </Button>
                        </ButtonRow>
                    </ModalDefaultFooter>
                </ModalDefault>
            </React.Fragment>
        );
    }
}

changelog

Changelog

Unreleased

0.3.9 - 2019-01-08

Deprecated

  • [Patch] Rename ModalHeader to ModalDefaultHeader, ModalTitle to ModalDefaultTitle, ModalDescription to ModalDefaultDescription, ModalContent to ModalDefaultContent, ModalFooter to ModalDefaultFooter, and AnimatedWrapper to ModalDefaultAnimatedWrapper. The old names will continue to work until the next major version release. (#1440)

0.3.8 - 2018-12-03

Changed

  • [Patch] Use a tilde for Sass imports (#1256)

0.3.7 - 2018-12-03

Changed

  • [Patch] Upgrade to latest version of eslint.

0.3.6 - 2018-11-27

Changed

  • [Patch] Publish package to public NPM.

0.3.5 - 2018-10-31

Changed

  • [Patch] Simplify padding for the element that wraps the children.

Fixed

  • [Patch] Revert change in #1196 that broke animation on mobile. (#1331)

0.3.4 - 2018-10-22

Changed

  • [Patch] Use latest version of Thumbprint Tokens.

0.3.3 - 2018-10-10

Changed

  • [Patch] Convert to use MDX.

0.3.2 - 2018-10-04

Changed

  • [Patch] Use latest version of Thumbprint Icons.

0.3.1 - 2018-10-03

Changed

  • [Patch] Move examples to README.mdx. (#1251)
  • [Patch] Remove field added to state that wasn't being used.
  • [Patch] Remove margin-bottom off of modalTitle and instead apply margin-top to modalDescription when modalTitle precedes it. (#1221)

0.3.0 - 2018-09-17

Added

  • [Minor] Export an AnimatedWrapper component.

0.2.10 - 2018-09-12

Changed

  • [Patch] Upgrade version of Prettier and Thumbprint Tokens.

Fixed

  • [Patch] Ensure items inside modal are not interactive when modal is closed. (#635)

0.2.9 - 2018-09-04

Changed

  • [Patch] Use latest version of tp-ui-react-button.

0.2.8 - 2018-08-29

Fixed

  • [Patch] Change close button position and header height to match design spec. (#1054)

0.2.7 - 2018-08-21

Changed

  • [Patch] Use latest version of Thumbprint Tokens.

0.2.6 - 2018-08-17

Changed

  • [Patch] Use latest version of Thumbprint Tokens.

0.2.5 - 2018-08-10

Changed

  • [Patch] Use latest version of tp-ui-react-button.

0.2.4 - 2018-07-30

Fixed

  • [Patch] ModalContent styles were referencing the wrong class.
  • [Patch] Rename CSS module classes for additional clarity.
  • [Patch] Use padding, not margin, for ModalContent to avoid collapsing margins.

0.2.3 - 2018-07-27

Changed

  • [Patch] Use latest version of tp-ui-react-button.

0.2.2 - 2018-07-26

Changed

  • [Patch] Add ModalContent to improve spacing between sections if there is only a ModalHeader and ModalFooter.

0.2.1 - 2018-07-25

Changed

  • [Patch] Use latest version of Thumbprint Icons.

0.2.0 - 2018-07-23

Added

  • [Minor] Add shouldCloseOnCurtainClick. (#1015)

0.1.3 - 2018-07-20

Fixed

  • [Patch] Maintain space for the close button even if the close button is hidden. (#1017)
  • [Patch] Modal will no longer shink depending on the width of the content. (#1016)

0.1.2 - 2018-07-19

Changed

  • [Patch] Use latest version of @thumbtack/tp-ui-react-button.

0.1.1 - 2018-07-19

  • [Patch] Use latest version of Thumbprint Icons.

0.1.0 - 2018-07-19

Added

  • [Minor] Create first version of tp-ui-react-modal-default. It is a replacement for tp-ui-react-modal-standard.