---

name: Modal
menu: Components

---

import PropsTable from 'website-src/components/PropsTable'
import React, { useState } from 'react'
import Modal from './Modal'
import Text from '../Text/Text'
import Button from '../Button/Button'
import cactusTheme from '@repay/cactus-theme'
import { LiveProvider, LiveEditor, LiveError, LivePreview } from 'react-live'
import { livePreviewStyle } from '../helpers/constants'

# Modal

The `Modal` component is a simple modal with dark overlay background.
It supports a wide range of styling props for flexible sizing at any screen size.

### Try it out

export const code = `() => {
  const [modalOpen, setModalOpen] = React.useState(false)
  return modalOpen ? (
    <Modal
      variant="action"
      isOpen={modalOpen}
      onClose={() => setModalOpen(false)}
      modalLabel="Modal Label"
      closeButtonProps={{ label: 'Close Label' }}
    >
      <Text as="h1">This is a Modal</Text>
    </Modal>
  ) : (
    <Button variant="action" onClick={() => setModalOpen(true)}>
      Open Modal
    </Button>
  )
}`

<LiveProvider code={code} scope={{ Modal, Button, Text }}>
  <LiveEditor style={livePreviewStyle} style={livePreviewStyle} />
  <LiveError />
  <LivePreview />
</LiveProvider>

## Best practices

The `Modal` component locks all other user interactions on the web page until the user takes an action.
It acts as a container that can contain any children the developer wants to put in it;
note that its children are not rendered unless the modal is open, so effects are
not run and any state internal to those components is reset when the modal is closed.

The `modalLabel` prop is the modal's `aria-label`; most of the other props are for styling.
`closeButtonProps` are passed directly to the `IconButton` used as the close button for the modal;
in addition to the `IconButton` props, you can also pass `top`, `left`, and/or `right` to position the button.

#### Styling

Like other cactus components, the Modal uses `styled-system` for responsive styling.
It has default margins, padding, and max-width which can be overridden;
you can also set height & width (and min & max), text-align, and flex properties.
Margins in particular are not very noticeable unless the modal overflows the screen;
in that case the overlay will scroll and there will be at least _margin_ space around the modal.

If you override the width/max-width, you should usually account for different screen sizes,
e.g. by passing something like `width={['90%', '75%', '50%']}` to make the modal relatively larger at small screen sizes.

Flex needs special mention: the modal is inside an `inline-flex` container with `flex-direction: row`.
Generally setting width/height will be better, but item props like `flexGrow` are supported.
You can also turn the modal into a flex container using a special shortcut prop:

```
// A simple boolean value makes the modal into a flex container.
<Modal flexFlow>
  <div>Default flex settings:</div>
  <div>flexDirection="column"</div>
  <div>alignItems="center"</div>
</Modal>
// You can also pass valid values for CSS flex-flow:
<Modal flexFlow="row-reverse wrap">
  <div>I'll be to the right</div>
  <div>And I'll be on the left</div>
</Modal>
```

## Properties

<PropsTable of={Modal} fileName="Modal/Modal.tsx" />
