Components
Modal
Modals are used to overlay content above an interface. They are intended to capture the user's attention in order to inform or shift focus to a pertinent task.
Always specify a appElementSelector
property to trap keyboard focus in the modal and hide the rest of the app content temporarily.
import { Modal } from '@sproutsocial/racine'
() => {const [open, setOpen] = useState(false)const toggleModal = () => setOpen(!open)return (<Box><Button appearance="secondary" onClick={toggleModal} width={1}>Open modal</Button><Modal//appElementSelector='___gatsby'isOpen={open}onClose={toggleModal}closeButtonLabel="Close this modal"label="Assign Chatbot"zIndex={900}><Modal.Headertitle="Assign Chatbot"subtitle="The chatbot will respond to customers from this profile."/><Modal.Content><Text fontSize={300} color="text.body">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed doeiusmod tempor incididunt ut labore et dolore magna aliqua. Loremipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmodtempor incididunt ut labore et dolore magna aliqua. Lorem ipsumdolor sit amet, consectetur adipiscing elit, sed do eiusmod temporincididunt ut labore et dolore magna aliqua.</Text></Modal.Content><Modal.Footer><Box display="flex" justifyContent="flex-end"><Button appearance="unstyled" onClick={toggleModal} mr={400}>Go back</Button><Button appearance="primary" onClick={toggleModal} px={500}>Submit</Button></Box></Modal.Footer></Modal></Box>)}
Properties
Name | Type | Default | Description | Required? |
---|---|---|---|---|
appElementSelector | string | section of app to aria hide for the modal | ||
isOpen | boolean | trigger to open or close the modal | ||
label | string | label for screen readers to announce the modal | ||
children | React.ReactNode | body content of the modal | ||
onClose | () => void | callback for close | ||
closeButtonLabel | string | aria-label for modal X | ||
zIndex | number | 6 | Controls the z-index CSS property | |
width | string number | "800px" | The max width of the modal container | |
data | string string | boolean | number | Custom attributes to be added to the modals container
Each key will be prepended with "data-" when rendered in the DOM |
Subcomponents
Modal Header
The Modal.Header
subcomponent is optional (not all Modals have to have headers), but if a header is present it should always be rendered as the first child of the Modal.
The following example shows a Modal header with a title and subtitle. Note: when rendered within an actual Modal, a close button will also be shown.
<Modal.Headertitle="Assign Chatbot"subtitle="The chatbot will respond to customers from this profile."/>
This title and subtitle configuration is the default, but if you would like to create your own header you can do so by passing children:
<Modal.Header bordered><Boxdisplay="flex"alignItems="center"justifyContent="space-between"width={1}><Text as="div" fontSize={400} fontWeight="semibold">Custom header</Text><Button appearance="primary">Some action</Button></Box></Modal.Header>
Note that the bordered
prop is needed on a custom header if the bottom border is desired. If children are provided, the title and subtitle props are ignored.
Modal Close Button
The Modal.CloseButton
subcomponent renders an icon button (using the icon) that will close the parent Modal when clicked.
Modal Content
The Modal.Content
subcomponent is a simple wrapper used to contain the content of a Modal (any items not within the header or footer), and ensures that the contents scroll when appropriate.
Modal Footer
The Modal.Footer
subcomponent renders it's children with the appropriate padding and border for the footer of a Modal. This component should always be rendered after an instance of Modal.Content
.
<Modal.Footer>Footer content</Modal.Footer>
Recipes
Modal with empty or no header
Modal headers can be omitted altogether, or they can render only a close button if neither a title, subtitle, or children prop is passed to the Modal.Header
subcomponent.
This should only be done with the first item in the modal body is an image or illustration. If the modal body begins with text, a bordered header with a title or subtitle should be used.
The following example shows a modal rendering an empty header, which displays only a close button in the upper right corner.
() => {const [open, setOpen] = useState(false)const toggleModal = () => setOpen(!open)return (<Box><Button appearance="secondary" onClick={toggleModal} width={1}>Open modal</Button><Modal//appElementSelector='___gatsby'isOpen={open}onClose={toggleModal}closeButtonLabel="Close this modal"label="Example Modal"zIndex={900}><Modal.Header /><Modal.Content><Boxmb={500}display="flex"alignItems="center"flexDirection="column"><Box width="400px" height="400px" bg="neutral.200" /><TextfontSize={400}fontWeight="bold"color="text.headline"pt={600}>Some headline</Text><TextfontSize={300}textAlign="center"color="text.body"pt={450}px={500}>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed doeiusmod tempor incididunt ut labore et dolore magna aliqua. Loremipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmodtempor incididunt ut labore et dolore magna aliqua.</Text></Box></Modal.Content><Modal.Footer><Box display="flex" justifyContent="flex-end"><Button appearance="primary" onClick={toggleModal}>Close modal</Button></Box></Modal.Footer></Modal></Box>)}
Expressive modal
() => {const [open, setOpen] = useState(false)const toggleModal = () => setOpen(!open)return (<Box><Button appearance="secondary" onClick={toggleModal} width={1}>Open modal</Button><ModalisOpen={open}onClose={toggleModal}closeButtonLabel="Close this modal"label="Example Modal"zIndex={900}bg="blue.400"width="30%"><Modal.Header><Box display="flex" flexDirection="row-reverse" width={1}><Modal.CloseButton color="neutral.0" /></Box></Modal.Header><Imagealt="expressive illustration"mb={600}src={withPrefix('/illus.svg')}/><Boxwidth="100%"bg="neutral.0"p={600}display="flex"flexDirection="column"><TextfontSize={400}color="text.headline"fontWeight={700}textAlign="center"pb={400}>Engagement makes the world go 'round.</Text><Text fontSize={200} textAlign="center" color="text.body">We care about how you engage with your customers and we’re here tomake that experience as smooth and seamless as possible.</Text></Box><Modal.Footer><Box display="flex" justifyContent="flex-end"><Button appearance="primary" onClick={toggleModal} minWidth={120}>Thanks</Button></Box></Modal.Footer></Modal></Box>)}
Destructive confirmation
() => {const [open, setOpen] = useState(false)const toggleModal = () => setOpen(!open)return (<Box><Button appearance="secondary" onClick={toggleModal} width={1}>Open modal</Button><ModalisOpen={open}onClose={toggleModal}closeButtonLabel="Close this modal"label="Example Modal"zIndex={900}width="30%"><Modal.Headertitle="Delete profiles?"subtitle="This action can not be undone."></Modal.Header><Modal.Content><Text as='div' py={300} fontSize={300} color="text.body">Deleting this profile will remove it from all groups as well asremove any messages associated with this profile. Are you sure youwant to proceed?</Text></Modal.Content><Modal.Footer><Box display="flex" justifyContent="flex-end"><Button appearance="unstyled" onClick={toggleModal} mr={400}>Cancel</Button><Buttonappearance="destructive"onClick={toggleModal}minWidth="120px">Confirm</Button></Box></Modal.Footer></Modal></Box>)}
Free form modal
This example showcases the freedom and flexibility we have within Modal.Content
() => {const [open, setOpen] = useState(false)const toggleModal = () => setOpen(!open)return (<Box><Button appearance="secondary" onClick={toggleModal} width={1}>Open modal</Button><ModalisOpen={open}onClose={toggleModal}closeButtonLabel="Close this modal"label="Example Modal"zIndex={900}><Modal.Header bordered><Boxdisplay="flex"alignItems="center"justifyContent="space-between"width={1}><Box display="flex" flexDirection="column"><Text fontSize={400} fontWeight="bold" color="text.headline">Free form experience</Text><Text fontSize={200} color="text.subtext">Browse and select things from the list as you please, nothing isrequired.</Text></Box><Box display="flex"><Button mr={350} appearance="unstyled" onClick={toggleModal}>Cancel</Button><ButtonminWidth="120px"appearance="primary"onClick={toggleModal}>Complete</Button></Box></Box></Modal.Header><Modal.Content display="flex"><Box width={1 / 2} display="flex" flexDirection="column" pr={450}><TextfontWeight={700}fontSize={300}color="text.headline"mb={400}>An informational headline</Text><Text fontSize={200} color="text.body" mb={350}>Authoritatively integrate installed base deliverables withoutworldwide intellectual capital. Progressively promote functionalmarkets before mission-critical potentialities.</Text><Text fontSize={200} color="text.body" mb={350}>Assertively incentivize 2.0 communities with quality technologies.Globally benchmark accurate sources for go forward systems.Energistically develop out-of-the-box ideas and quality services.</Text></Box><Box width={1 / 2}><ModalListExample /></Box></Modal.Content></Modal></Box>)}