Modal

Forces users to complete an action before continuing.

Modal

To implement Modal component into your project you’ll need to the import at least the Modal and the ModalSection:

import Modal, { ModalSection } from "@kiwicom/orbit-components/lib/Modal";

You might need the Portal also. See it’s docs.

After adding import into your project you can use it simply like:

<Modal>
<ModalSection>Hello World!</ModalSection>
</Modal>

The Modal component has big variety of usage, please check examples for usage below.

Props

Table below contains all types of the props available in the Modal component.

NameTypeDefaultDescription
childrenReact.NodeThe content of the Modal. See Subcomponents
lockScrollingbooleantrueWhether to prevent scrolling of the rest of the page while Modal is open. This is on by default to provide a better user experience.
scrollingElementRefref (object or function)The scrolling element, which depends on the viewport
dataTeststringOptional prop for testing purposes.
idstringSet id for Modal
fixedFooterbooleanfalseIf true the ModalFooter will be fixed to the bottom of window.
isMobileFullPagebooleanfalseIf true the Modal will look like a page on mobile devices.
sizeenum"normal"The maximum width of the Modal on desktop viewport.
onCloseevent => void \| PromiseFunction for handling onClose event. If you don’t pass any function the Close button will not be displayed and it will not be possible to close the Modal. See Functional specs
preventOverlayClosebooleanProperty for preventing closing of modal when there is a action on overlay. BEWARE: This should be used only in very specials edge-cases! It breaks user experience.
hasCloseButtonbooleantrueDefines whether the Modal displays a close button. If you disable this, we recommend adding some kind of an alternative.
autoFocusbooleantrueThe autofocus attribute of the Modal, see this docs.
disableAnimationbooleanfalseDefines whether the Modal performs the slide in animation on mobile. If you want to improve your CLS score, you might want to set this to true.
mobileHeaderbooleantrueIf false the ModalHeader will not have MobileHeader and CloseContainer
labelClosestringCloseThe label for the close button.

Modal enum

size
"extraSmall"
"small"
"normal"
"large
"extraLarge"

Functional specs

  • To select the Close Button element for testing purposes, use [data-test=“ModalCloseButton”] selector.

  • To type a reference you’re passing to a modal, use the following example:

    const modalRef = React.useRef<React.ElementRef<typeof Modal> | null>(null)
  • You might want to get the current scroll position of a Modal component, which might change based on media queries. Reading it constantly would degrade performance. Instead, get it on demand by using the getScrollPosition method in a Modal instance like this:

    class Component extends React.Component {
    const modalRef = React.useRef<React.ElementRef<typeof Modal> | null>(null)
    const getScroll = () => {
    if (modalRef.current) {
    setLocalScrollPosition(modalRef.current.getScrollPosition());
    }
    };
    render() {
    return (
    <Modal ref={modalRef}>
    Some content.
    </Modal>
    );
    }
    }
  • To set the scroll position of a Modal component, use the setScrollPosition method in a Modal instance like this:

    class Component extends React.Component {
    const modalRef = React.useRef<React.ElementRef<typeof Modal> | null>(null)
    setScroll = () => {
    if (modalRef.current) {
    modalRef.current.setScrollPosition(100);
    }
    };
    render() {
    return (
    <Modal ref={modalRef}>
    <ModalSection>Example usage of setting up the scrollTop position</ModalSection>
    <ModalFooter>
    <Button onClick={this.setScroll}>Change scrollTop</Button>
    </ModalFooter>
    </Modal>
    );
    }
    }

Subcomponents

Modal component offers a good flexibility and many variations in its usage. There are three subcomponents which you might use.

ModalSection

import Modal, { ModalSection } from "@kiwicom/orbit-components/lib/Modal";

Usage

<Modal>
<ModalSection suppressed>Hello World!</ModalSection>
</Modal>

Props

Table below contains all types of the props in the ModalSection component.

NameTypeDefaultDescription
childrenReact.NodeContent of the ModalSection component.
dataTeststringOptional prop for testing purposes.
suppressedbooleanfalseIf true the ModalSection will have cloudy background.

ModalHeader

import Modal, { ModalHeader } from "@kiwicom/orbit-components/lib/Modal";

Usage

<Modal>
<ModalHeader title="Orbit design system">Hello World!</ModalHeader>
</Modal>

Props

Table below contains all types of the props in the ModalHeader component.

NameTypeDefaultDescription
childrenReact.NodeThe content of the ModalHeader.
dataTeststringOptional prop for testing purposes.
descriptionReact.NodeThe displayed description of the ModalHeader.
illustrationReact.Element<typeof Illustration>The displayed Illustration of the ModalHeader.
suppressedbooleanfalseIf true the ModalHeader will have cloudy background.
titleReact.NodeThe displayed title of the ModalHeader.

ModalFooter

import Modal, { ModalFooter } from "@kiwicom/orbit-components/lib/Modal";
// and probably Button
import Button from "@kiwicom/orbit-components/lib/Button";

Usage:

<Modal fixedFooter>
<ModalFooter flex={["0 0 auto", "1 1 100%"]}>
<Button type="secondary" iconLeft={<ChevronBackward />}>
Back
</Button>
<Button block>Continue to Payment</Button>
</ModalFooter>
</Modal>

Props

Table below contains all types of the props in the ModalFooter component.

NameTypeDefaultDescription
childrenReact.NodeThe content of the ModalFooter.
dataTeststringOptional prop for testing purposes.
flexstring or Array<string>"0 1 autoThe flex attribute(s) for children of the ModalFooter. See Functional specs

ModalFooter Functional specs

  • You can set up different flex attribute for every children, or use one for all. See flex property docs for more information.

Use cases

Although this component offers good flexibility of usage, there are tiny limitations for usage.

Wrapper ModalSections

If you need to wrap the children into custom component, wrap all of the children into one wrapper, e.g.:

// good
<Modal fixedFooter>
<CustomWrapper>
<ModalHeader />
<ModalSection>
My content
</ModalSection>
<ModalSection>
My content
</ModalSection>
<ModalFooter />
</CustomWrapper>
</Modal>
// bad, the CSS styles will be broken
<Modal fixedFooter>
<ModalHeader />
<CustomWrapper>
<ModalSection>
My content
</ModalSection>
<ModalSection>
My content
</ModalSection>
</CustomWrapper>
<ModalFooter />
</Modal>

Accessibility

  • When Modal is closed return focus to the element that opened the modal. You can use onClose callback function to achieve this.