BannerOverlays displays short educational messages when users have performed actions that indicate some intent, such as a related pin tap or idea pin swipe. It is scrim-less, meaning users can scroll content underneath without having a wash layer on top of the content.
BannerOverlay is a sticky component triggered by scroll, on tap or long-press, placed at the bottom of the screen.
also known as UpsellOverlay
Props
Usage guidelines
- To provide short educational messages allowing content to scroll underneath
- To help users learn more about a specific idea or interest
- To support users when they have performed actions that indicate medium or high intent (related pin tap, idea pin swipe)
- If there is a need to block the content underneath use Modal instead
- To replace Toast
- For lengthy messages, forms, or blocks of information. Consider OverlayPanel or new page instead
Best Practices
Use BannerOverlay to educate and provide additional information to users when they have performed actions that indicate some intent, such as a related pin tap or idea pin swipe.
Use BannerOverlay for critical information, such as errors or warnings. Use BannerCallout instead.
Be concise when writing the content. The BannerOverlay is intended to display short messages. Ideally max of 3 lines.
Please consider localization.
Display long messages inside the BannerOverlay as it isn't the intent of this component, and it could lead to readability issues considering the component size and space.
Place BannerOverlay out of the way so a user can still navigate and complete tasks.
Please note: On desktop devices, the BannerOverlay should appear at the top of the screen. The BannerOverlay shouldn't block navigation; therefore, it shuld be positioned below the navigation bar.
On mobile devices, the BannerOverlay should appear at the bottom of the screen. The 'offset' prop can be used to adjust the position of the BannerOverlay.
If both top an bottom offset are set, only the bottom offset will be used when mobile device is detected and the only top offset will be used on desktop devices.
In case we need to break this design positioning rule, and place BannerOverlay at the top in mobile devices and at the bottom in desktop devices, you can set the prop 'reverseOffset' to true and invert the logic. If you want to only apply the revert on mobile, you can only prop 'reverseOffset' to true when mobile devices are detected. With this, BannerOverlay will always be positioned at the top.
Stack multiple BannerOverlays; only one BannerOverlay should appear on the screen per time.
Accessibility
Labels
dismissButton
and primaryAction
, require a short, descriptive label for screen readers, which should also be localized.
Icons and thumbnails on BannerOverlay are purely decorative, and can therefore have an empty string as the accessibilityLabel
. The thumbnail (Image) or Icon should supply an alt or accessibilityLabel, respectively, if the Image or Icon supplies extra context or information.
Variants
Thumbnail
BannerOverlay supports images, icons and avatars as thumbnails.
- Image: With an image for Pin or Board actions, or the Pinterest logo.
- Avatar: With an Avatar for Profile or Pinner-related messaging.
- Icon: For when an icon is needed to represent content that isn’t a pin or a profile.
import { useState } from 'react'; import { BannerOverlay, Button, FixedZIndex, Image, Link, Text } from 'gestalt'; export default function Example() { const [showComponent, setShowComponent] = useState(true); return !showComponent ? ( <Button onClick={() => { setShowComponent(true); }} text="Show BannerOverlay" /> ) : ( <BannerOverlay message={ <Text inline> Discover trending{' '} <Link display="inlineBlock" href="#" target="self"> fashion </Link>{' '} ideas in the app! </Text> } offset={{ top: 130, bottom: 24 }} onDismiss={() => { setShowComponent(false); }} primaryAction={{ role: 'button', onClick: () => { setShowComponent(false); }, label: 'Get the app', accessibilityLabel: 'Get the app', }} thumbnail={{ image: ( <Image alt="Pinterest Logo" naturalHeight={1} naturalWidth={1} src="https://i.ibb.co/LQc8ynn/image.png" /> ), }} title="More to Explore" zIndex={new FixedZIndex(100)} /> ); }
import { useState } from 'react'; import { Avatar, BannerOverlay, Button, FixedZIndex, Link, Text, } from 'gestalt'; export default function Example() { const [showComponent, setShowComponent] = useState(true); return !showComponent ? ( <Button onClick={() => { setShowComponent(true); }} text="Show BannerOverlay" /> ) : ( <BannerOverlay message={ <Text inline> Discover trending{' '} <Link display="inlineBlock" href="#" target="self"> fashion </Link>{' '} ideas in the app! </Text> } offset={{ top: 130, bottom: 24 }} onDismiss={() => { setShowComponent(false); }} primaryAction={{ role: 'button', onClick: () => { setShowComponent(false); }, label: 'Get the app', accessibilityLabel: 'Get the app', }} thumbnail={{ avatar: ( <Avatar name="Keerthi" src="https://i.ibb.co/ZfCZrY8/keerthi.jpg" /> ), }} title="More to Explore" zIndex={new FixedZIndex(100)} /> ); }
import { useState } from 'react'; import { BannerOverlay, Button, FixedZIndex, Icon, Link, Text } from 'gestalt'; export default function Example() { const [showComponent, setShowComponent] = useState(true); return !showComponent ? ( <Button onClick={() => { setShowComponent(true); }} text="Show BannerOverlay" /> ) : ( <BannerOverlay message={ <Text inline> Discover trending{' '} <Link display="inlineBlock" href="#" target="self"> fashion </Link>{' '} ideas in the app! </Text> } offset={{ top: 130, bottom: 24 }} onDismiss={() => { setShowComponent(false); }} primaryAction={{ role: 'button', onClick: () => { setShowComponent(false); }, label: 'Get the app', accessibilityLabel: 'Get the app', }} thumbnail={{ icon: ( <Icon accessibilityLabel="Sparkle" color="recommendation" icon="sparkle" /> ), }} title="More to Explore" zIndex={new FixedZIndex(100)} /> ); }
Actions
You can have zero, one or two actions using the props primaryAction
and `secondaryAction'.
Remember to localize text and any string within primaryAction
or dismissButton
, as well as title and message.
Please note: Start aligned text is the primary alignment for our Business products. It will be left-aligned in left-to-right languages and right-aligned in right-to-left languages
import { useState } from 'react'; import { BannerOverlay, Button, FixedZIndex, Icon } from 'gestalt'; export default function Example() { const [showComponent, setShowComponent] = useState(true); return !showComponent ? ( <Button onClick={() => { setShowComponent(true); }} text="Show BannerOverlay" /> ) : ( <BannerOverlay message="You can have up to two buttons in the BannerOverlay!" offset={{ top: 130, bottom: 24 }} onDismiss={() => { setShowComponent(false); }} primaryAction={{ role: 'button', onClick: () => { setShowComponent(false); }, label: 'Primary action', accessibilityLabel: 'Primary action', }} secondaryAction={{ role: 'button', onClick: () => {}, label: 'Secondary Action', accessibilityLabel: 'Secondary Action', }} thumbnail={{ icon: ( <Icon accessibilityLabel="Sparkle" color="info" icon="info-circle" /> ), }} title="Call to Action" zIndex={new FixedZIndex(100)} /> ); }
Dismissable
BannerOverlay provides a dismiss button affordance. You can optionally have the Call to Action dismiss the BannerOverlay by not setting the dismissButton prop.
import { useState } from 'react'; import { BannerOverlay, Button, FixedZIndex, Icon } from 'gestalt'; export default function Example() { const [showComponent, setShowComponent] = useState(true); return !showComponent ? ( <Button onClick={() => { setShowComponent(true); }} text="Show BannerOverlay" /> ) : ( <BannerOverlay message="You can dismiss this banner with the dismiss button!" offset={{ top: 130, bottom: 24 }} onDismiss={() => { setShowComponent(false); }} thumbnail={{ icon: ( <Icon accessibilityLabel="Sparkle" color="info" icon="info-circle" /> ), }} title="Dismissable Banner" zIndex={new FixedZIndex(100)} /> ); }
import { useState } from 'react'; import { BannerOverlay, Button, FixedZIndex, Icon } from 'gestalt'; export default function Example() { const [showComponent, setShowComponent] = useState(true); return !showComponent ? ( <Button onClick={() => { setShowComponent(true); }} text="Show BannerOverlay" /> ) : ( <BannerOverlay message="You can dismiss this banner with the primary action!" offset={{ top: 130, bottom: 24 }} primaryAction={{ role: 'button', onClick: () => { setShowComponent(false); }, label: 'Got it!', accessibilityLabel: 'Got it!', }} thumbnail={{ icon: ( <Icon accessibilityLabel="Sparkle" color="info" icon="info-circle" /> ), }} title="Dismissable Banner" zIndex={new FixedZIndex(100)} /> ); }
Message
The message
prop accepts either a string or
Text. Use a string for simple messages without any visual style. BannerOverlay will handle the message style and adherence to design guidelines. If a message with more complex style is required, such as bold text or inline links, use Text to wrap your message with any additional Text or Link usages contained within.
import { useState } from 'react'; import { BannerOverlay, Button, FixedZIndex, Image, Link, Text } from 'gestalt'; export default function Example() { const [showComponent, setShowComponent] = useState(true); return !showComponent ? ( <Button onClick={() => { setShowComponent(true); }} text="Show BannerOverlay" /> ) : ( <BannerOverlay message={ <Text inline> Discover{' '} <Link display="inlineBlock" href="#" target="self"> trending fashion ideas </Link>{' '} in the app! </Text> } offset={{ top: 130, bottom: 24 }} onDismiss={() => { setShowComponent(false); }} primaryAction={{ role: 'button', onClick: () => { setShowComponent(false); }, label: 'Get the app', accessibilityLabel: 'Get the app', }} secondaryAction={{ role: 'button', onClick: () => {}, label: 'Not now', accessibilityLabel: 'Not now', }} thumbnail={{ image: ( <Image alt="Pinterest Logo" naturalHeight={1} naturalWidth={1} src="https://i.ibb.co/LQc8ynn/image.png" /> ), }} title="More to Explore" zIndex={new FixedZIndex(100)} /> ); }
Responsive
BannerOverlay is responsive to different devices. Therefore, BannerOverlay dweb is set to a max width of 900 px to preserve a great usability experience and consistency with other components.
On desktop devices, the BannerOverlay should appear at the top of the screen (below navigation). The BannerOverlay shouldn't block navigation.
On mobile devices, the BannerOverlay should appear at the bottom of the screen. The 'offset' prop can be used to adjust the position of the BannerOverlay.
Writing
- Use succinct and scannable language that clearly conveys support to the user
- Consider internationalization and how other languages may be constrained
- Write up to 2 lines of text.
- Write messages that are wordy and take up a lot of space, as the BannerOverlay is intended to short messages
- Write content that takes more than 2 lines of text
- Truncate content. If the message needs more words, consider a different component
Related
BannerUpsell
BannerUpsell banners are used for paid upgrades, free trials, or marketing promotions.
Modal
A generic, customizable container for modals that aren’t used as alerts or acknowledgements and need more functionality like form fields.
Toast
Toasts educate users on the content of the screen, provide confirmation when people complete an action, or simply communicate a short message.