Overlay
Notes
Creates a fixed position overlay to be used in conjunction with ModalProvider. Overlay does not create a mask or manage focus; to get an accessible modal overlay with a mask see ModalProvider documentation.
In mobile viewports, the overlay covers the entire viewport. In desktop, user can choose from a variety of presets for what portion of the viewport will cover. See prop options below.
The overlay comes with an optional close button which will automatically close the modal when used in conjunction with the ModalProvider component.
In your Overlay's content, please include a heading for accessibility; the heading level should be an h2 (as it is expected that you have an h1 on the page already).
Props
- alignment
oneOf('dialog', 'dialog-lg', 'fullscreen', 'rightCrate', 'leftCrate', 'rightThird', 'leftThird')
Indicates what portion of the UI is covered in desktop viewports.
- children
any
Nested component(s) which become the content of the overlay.
- childrenContainerClassName
string
Classname passed to the element that wraps the children
- closeCallback
func
Optional function to run when the overlay is closing.
- closeProps
object
Props passed to the CloseButton component within the Overlay.
- containerProps
object
Additional props to be spread on the container HTMLElement.
- contentProps
object
Additional props to be spread on the content HTMLElement.
- imageAlt
string
Prop to allow for giving alternate text to the image
- imageContainerProps
object
Props to pass into the container around the image
- imagePath
string
Optional prop to allow for image to be placed on top of the Overlay.
- permitImageToShrink
bool
Optional prop to allow for a top-image to be responsive. This is useful when you have tall content and a scalable image. Only applicable if imagePath is passed.
- imageObjectFit
oneOf('cover', 'contain', 'fill', 'scale-down')
Optional prop to control the object-fit of the top image. Only applicable if imagePath is passed and permitImageToShrink is true.
- renderCloseButton
bool
Whether to use the included default CloseButton component. If false, consumer is expected to provide a custom close button in the child component.
- style
object
Optional style object for custom styling such as z-index; applied to the outermost div.
- topShadow
bool
A CSS box shadow intended for situations in which another container is visually 'above' the overlay.
- useLegacyOverlay
[false]
Example: Standard overlay
const DefaultOverlay = () => (<ThemeContext.Provider value={themes.dark}><Overlayalignment="rightThird"closeProps={{ariaLabel: 'Close'}}><div className="sb-global-gutters"><Heading id="overlay1-heading" tagName="h2" size="md" className="text-semibold pb4">Sample overlay</Heading><div className="pb4"><img src="https://content-prod-live.cert.starbucks.com/binary/v2/asset/137-42656.jpg" alt="Sample image" /></div><p className="pb3">A standard overlay is a blank canvas that can be used to render arbitrary content in a modal window.</p><p className="pb3">The button below will open a native alert as a sample call to action.</p><Button onClick={() => alert("Do something here....")}>Sample call to action</Button></div></Overlay></ThemeContext.Provider>);const SampleApp = () => {const { openModal, closeModal } = React.useContext(ModalContext);const openDefaultOverlay = () => {openModal({component: DefaultOverlay,ariaLabelledBy: 'overlay1-heading',onEscape: () => {closeModal();alert("This message got triggered from the onEscape callback ");}});};return (<div className="p3"><Button className="mb3 mr3" onClick={openDefaultOverlay}>Open a standard overlay</Button></div>)}const ModalExample = () => (<ModalProvider appElementId="js-content" targetElementId="modal-target"><SampleApp /></ModalProvider>);render(<ModalExample />);
Example: Overlay using Dialog alignment
const DialogOverlay = ({ headingText }) => (<Overlayalignment="dialog-lg"closeProps={{ariaLabel: 'Close',highContrast: true,}}><div className="bg-houseGreen sb-global-gutters py4"><HeadingclassName="color-textWhite text-semibold"id="overlay2-heading"size="md"tagName="h2">{headingText}</Heading></div><div className="sb-global-gutters py4"><p>A dialog overlay is similar in appearance to a dialog. There are two standard width options ("dialog" and "dialog-lg"), though all appearance is editable via props. Unlike a true dialog, which expects 'confirm' and 'cancel' buttons, you construct any required interactivity as part of the content itself.</p></div></Overlay>);const SampleApp = () => {const { openModal } = React.useContext(ModalContext);const openDialogOverlay = () => {openModal({ariaLabel: 'Sample dialog-style overlay',component: DialogOverlay,// If your overlay's props can't be determined until runtime, you can pass them in// when opening the overlay.componentProps: {headingText: 'Sample Heading',},onClose: () => alert("This message got triggered from the onClose callback "),});};return (<div className="p3"><Button className="mb3" onClick={openDialogOverlay}>Open a dialog overlay</Button></div>)}const ModalExample = () => (<ModalProvider appElementId="js-content" targetElementId="modal-target"><SampleApp /></ModalProvider>);render(<ModalExample />);
Example: Overlay using Dialog alignment with an image
const DialogOverlay = ({ headingText, imagePath }) => (<OverlaycloseProps={{ariaLabel: 'Close'}}imagePath={imagePath}><div className="sb-global-gutters py5"><Heading id="overlay2-heading" tagName="h2" size="md" className="text-semibold pb4">{headingText}</Heading><p>A dialog overlay is similar in appearance to a dialog. It has an opinionated layout for the optional image at the top of the layout, and supports arbitrary content below the image. Unlike a dialog, which expects 'confirm' and 'cancel' buttons, you construct any needed interactivity as part of the content itself.</p></div></Overlay>);const SampleApp = () => {const { openModal } = React.useContext(ModalContext);const openDialogOverlay = () => {openModal({ariaLabel: 'Sample dialog-style overlay',component: DialogOverlay,// If your overlay's props can't be determined until runtime, you can pass them in// when opening the overlay.componentProps: {imagePath: 'https://content-prod-live.cert.starbucks.com/binary/v2/asset/137-42656.jpg',headingText: 'Sample Heading',},});};return (<div className="p3"><Button className="mb3" onClick={openDialogOverlay}>Open an image-based overlay</Button></div>)};const ModalExample = () => (<ModalProvider appElementId="js-content" targetElementId="modal-target"><SampleApp /></ModalProvider>);render(<ModalExample />);
Example: (Deprecated) Standard Overlay
class OverlayExample extends React.Component {constructor(props) {super(props);this.toggleOpen = this.toggleOpen.bind(this);this.state = { isOpen: false };}toggleOpen() {this.setState({ isOpen: !this.state.isOpen });}renderChildren() {return (<OverlaycloseCallback={ this.toggleOpen }closeProps={ {ariaLabel: 'Since it has no text, please provide a label for the close button'} }alignment='rightCrate'useLegacyOverlay><div className='p3 lg-px7'><div className='mx-auto' style={{ maxWidth: '500px' }}><Heading tagName='h2' size='md' className='pb3'>Overlay can contain anything</Heading><p className="pb5">Try changing the alignment prop in the example to see different layouts in desktop-sized viewports.</p><p className="pb5">You need to provide a handler for clicking the close button.</p><div><img src='http://placehold.it/1000x300' alt='' /></div></div></div></Overlay>);}render() {const { isOpen } = this.state;return (<div><p className='mb3'>Overlay handles layout of a mask and content, but needs to be renderedinto a component like Layer that can be fixed position over the whole application</p><Button onClick={ this.toggleOpen }>Open Overlay</Button><LayerisOpen={isOpen}>{this.renderChildren()}</Layer></div>);}}render(<OverlayExample />);
Example: (Deprecated) Overlay with optional image included
class OverlayExample extends React.Component {constructor(props) {super(props);this.toggleOpen = this.toggleOpen.bind(this);this.toggleShrinkable = this.toggleShrinkable.bind(this);this.state = { isOpen: false, isShrinkable: false };}toggleOpen() {this.setState({ isOpen: !this.state.isOpen });}toggleShrinkable() {this.setState({ isShrinkable: !this.state.isShrinkable });}renderChildren() {return (<OverlaycloseCallback={ this.toggleOpen }closeProps={ {ariaLabel: 'Since it has no text, please provide a label for the close button'} }imagePath="https://globalassets.starbucks.com/assets/bdea26b70ac94a02a97d2a24e3158ea5.jpg"permitImageToShrink={this.state.isShrinkable}useLegacyOverlay><div className='p3 lg-px7 mx-auto flex flex-column height-100' style={{ maxWidth: '500px' }}><Heading tagName='h2' size='md' className='pb3'>Overlay can contain anything</Heading><p className="pb5 flex-grow">It really can.</p>{this.state.isShrinkable && <p>This image is now shrinkable! Try making the window really short.</p>}<ButtonKit cancelText="Foo" confirmText="Toggle Shrinkable Image" onConfirm={this.toggleShrinkable} /></div></Overlay>);}render() {const { isOpen } = this.state;return (<div><p className='mb3'>You can pass a path to an image to the `imagePath` prop to get a different layout of the Overlaywhere the image from the path will be placed on top of the content and be rendered like a dialog atdesktop layouts. As a dialog, the image will be responsive for both height and width changes (try shrinking the window to be very short).</p><Button onClick={ this.toggleOpen }>Open Overlay</Button><LayerisOpen={isOpen}>{this.renderChildren()}</Layer></div>);}}render(<OverlayExample />);