UNPKG

@kiwicom/orbit-components

Version:

Orbit-components is a React component library which provides developers with the easiest possible way of building Kiwi.com's products.

290 lines 16.5 kB
import * as React from "react"; import type { Props } from "./types"; /** * @orbit-doc-start * README * ---------- * # Modal * * To implement Modal component into your project you'll need to the import at least the Modal and the [ModalSection](#modalsection): * * ```jsx * import Modal, { ModalSection } from "@kiwicom/orbit-components/lib/Modal"; * ``` * * > You might need the Portal also. See it's [docs](https://orbit.kiwi/utilities/portal/). * * After adding import into your project you can use it simply like: * * ```jsx * <Modal> * <ModalSection>Hello World!</ModalSection> * </Modal> * ``` * * The Modal component has big variety of usage, please check examples for usage [below](#use-cases). * * ## Props * * Table below contains all types of the props available in the Modal component. * * | Name | Type | Default | Description | * | :------------------ | :------------------------- | :--------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | * | children | `React.Node` | | The content of the Modal. [See Subcomponents](#subcomponents) | * | triggerRef | `React.RefObject` | | The ref to the element which triggers the Modal. | * | lockScrolling | `boolean` | `true` | Whether to prevent scrolling of the rest of the page while Modal is open. This is on by default to provide a better user experience. | * | scrollingElementRef | ref (object or function) | | The scrolling element, which depends on the viewport. | * | dataTest | `string` | | Optional prop for testing purposes. | * | id | `string` | | Set `id` for `Modal`. | * | fixedFooter | `boolean` | `false` | If `true` the ModalFooter will be fixed to the bottom of window. | * | isMobileFullPage | `boolean` | `false` | If `true` the Modal will look like a page on mobile devices. | * | size | [`enum`](#modal-enum) | `"normal"` | The maximum width of the Modal on desktop viewport. | * | onClose | `event => void \| Promise` | | Function 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](#functional-specs). | * | preventOverlayClose | `boolean` | | Property 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. | * | hasCloseButton | `boolean` | `true` | Defines whether the Modal displays a close button. If you disable this, we recommend adding some kind of an alternative. | * | disableAnimation | `boolean` | `false` | Defines whether the Modal performs the slide in animation on mobile. If you want to improve your [CLS](https://web.dev/cls/) score, you might want to set this to `true`. | * | mobileHeader | `boolean` | `true` | If `false` the ModalHeader will not have MobileHeader and CloseContainer. | * | labelClose | `string` | | The label for the close button. It is required all the time, unless `hasCloseButton` is explicitly set to `false`. | * | onScroll | `event => void \| Promise` | | Function for handling `onScroll` event. [See Functional specs](#functional-specs). | * | ariaLabelledby | `string` | | The `aria-labelledby` attribute of the Modal. It should be used if `title` is not defined on the ModalHeader. | * | ariaDescribedby | `string` | | The `aria-describedby` attribute of the Modal. It should be used if `description` is not defined on the ModalHeader. | * | ariaLabel | `string` | | The `aria-label` attribute of the Modal. It should be used if `title` is not defined on the ModalHeader and `ariaLabelledby` is undefined. | * * ### 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: * * ```jsx * 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: * * ```jsx * 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: * * ```jsx * 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 * * ```jsx * import Modal, { ModalSection } from "@kiwicom/orbit-components/lib/Modal"; * ``` * * #### Usage * * ```jsx * <Modal> * <ModalSection suppressed>Hello World!</ModalSection> * </Modal> * ``` * * #### Props * * Table below contains all types of the props in the ModalSection component. * * | Name | Type | Default | Description | * | :----------- | :----------- | :------ | :------------------------------------------------------ | * | **children** | `React.Node` | | Content of the ModalSection component. | * | dataTest | `string` | | Optional prop for testing purposes. | * | suppressed | `boolean` | `false` | If `true` the ModalSection will have cloudy background. | * * ### ModalHeader * * ```jsx * import Modal, { ModalHeader } from "@kiwicom/orbit-components/lib/Modal"; * ``` * * #### Usage * * ```jsx * <Modal> * <ModalHeader title="Orbit design system">Hello World!</ModalHeader> * </Modal> * ``` * * #### Props * * Table below contains all types of the props in the ModalHeader component. * * | Name | Type | Default | Description | * | :----------- | :----------------------------------- | :------ | :----------------------------------------------------- | * | children | `React.Node` | | The content of the ModalHeader. | * | dataTest | `string` | | Optional prop for testing purposes. | * | description | `React.Node` | | The displayed description of the ModalHeader. | * | illustration | `React.Element<typeof Illustration>` | | The displayed Illustration of the ModalHeader. | * | suppressed | `boolean` | `false` | If `true` the ModalHeader will have cloudy background. | * | title | `React.Node` | | The displayed title of the ModalHeader. | * * ### ModalFooter * * ```jsx * import Modal, { ModalFooter } from "@kiwicom/orbit-components/lib/Modal"; * * // and probably Button * import Button from "@kiwicom/orbit-components/lib/Button"; * ``` * * #### Usage: * * ```jsx * <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. * * | Name | Type | Default | Description | * | :----------- | :-------------------------- | :---------- | :----------------------------------------------------------------------------------------------- | * | **children** | `React.Node` | | The content of the ModalFooter. | * | dataTest | `string` | | Optional prop for testing purposes. | * | flex | `string` or `Array<string>` | `"0 1 auto` | The flex attribute(s) for children of the ModalFooter. [See Functional specs](#functional-specs) | * * #### ModalFooter Functional specs * * - You can set up different `flex` attribute for every children, or use one for all. See [flex property docs](https://www.w3schools.com/cssref/css3_pr_flex.asp) 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.: * * ```jsx * // 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 * ------------- * # Accessibility * * ## Modal * * The Modal component has been designed with accessibility in mind. * * To ease the keyboard navigation, when opening a modal, the focus is moved to the first focusable element inside the modal. It is also impossible to focus anything outside of the modal while it is open. * When closing the modal, the focus can be moved back to the element that triggered the modal automatically, if the prop `triggerRef` is defined with a ref to that element. * * Besides that, assistive ARIA attributes are applied automatically to the modal and its children, to ensure that screen readers can announce the modal and its content correctly. * * If you prefer, you can also provide those attributes manually, as described in the table below: * * | Name | Type | Description | * | :-------------- | :------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | * | ariaLabelledby | `string` | The `id` of an element that serves as a label (title) for the modal. | * | ariaDescribedby | `string` | The `id` of an element that serves as a description for the modal. | * | ariaLabel | `string` | Text that labels the modal content. Think of it as the title of the modal. This should be used if `title` is not passed to `ModalHeader` and `ariaLabelledby` is undefined. | * * All the props above are optional, but recommended to use to ensure the best experience for all users. * * If you use a ModalHeader with `title` and `description` props defined, they are automatically assigned as `aria-labelledby` and `aria-describedby`, respectively. * However, if needed, you can overwrite the values by passing the corresponding props. * * The `ariaLabelledby` and `ariaDescribedby` props can reference multiple ids, separated by a space. * The elements with those ids can be hidden, so that their text is only announced by screen readers. * * Be mindful that all descriptive texts, even if invisible on the screen, should be translated and provide context for users of assistive technologies. * * * @orbit-doc-end */ declare const Modal: ({ size, scrollingElementRef, children, onClose, triggerRef, fixedFooter, isMobileFullPage, preventOverlayClose, onScroll, hasCloseButton, mobileHeader, disableAnimation, dataTest, id, labelClose, lockScrolling, ariaLabel, ariaLabelledby, ariaDescribedby, ref, }: Props) => React.JSX.Element; export default Modal; export { default as ModalHeader } from "./ModalHeader"; export { default as ModalSection } from "./ModalSection"; export { default as ModalFooter } from "./ModalFooter"; //# sourceMappingURL=index.d.ts.map