HomeStarbucks Pattern Library

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

  • alignmentoneOf('dialog', 'dialog-lg', 'fullscreen', 'rightCrate', 'leftCrate', 'rightThird', 'leftThird')

    Indicates what portion of the UI is covered in desktop viewports.

  • childrenany

    Nested component(s) which become the content of the overlay.

  • childrenContainerClassNamestring

    Classname passed to the element that wraps the children

  • closeCallbackfunc

    Optional function to run when the overlay is closing.

  • closePropsobject

    Props passed to the CloseButton component within the Overlay.

  • containerPropsobject

    Additional props to be spread on the container HTMLElement.

  • contentPropsobject

    Additional props to be spread on the content HTMLElement.

  • imageAltstring

    Prop to allow for giving alternate text to the image

  • imageContainerPropsobject

    Props to pass into the container around the image

  • imagePathstring

    Optional prop to allow for image to be placed on top of the Overlay.

  • permitImageToShrinkbool

    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.

  • imageObjectFitoneOf('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.

  • renderCloseButtonbool

    Whether to use the included default CloseButton component. If false, consumer is expected to provide a custom close button in the child component.

  • styleobject

    Optional style object for custom styling such as z-index; applied to the outermost div.

  • topShadowbool

    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}>
<Overlay
alignment="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 }) => (
<Overlay
alignment="dialog-lg"
closeProps={{
ariaLabel: 'Close',
highContrast: true,
}}
>
<div className="bg-houseGreen sb-global-gutters py4">
<Heading
className="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 }) => (
<Overlay
closeProps={{
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 (
<Overlay
closeCallback={ 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 rendered
into a component like Layer that can be fixed position over the whole application
</p>
<Button onClick={ this.toggleOpen }>Open Overlay</Button>
<Layer
isOpen={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 (
<Overlay
closeCallback={ 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 Overlay
where the image from the path will be placed on top of the content and be rendered like a dialog at
desktop 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>
<Layer
isOpen={isOpen}
>
{this.renderChildren()}
</Layer>
</div>
);
}
}
render(<OverlayExample />);