BannerCallout is a banner displaying short messages with helpful information for a task on the page, or something that requires the user’s attention.

also known as Banner, Message, Notification, Notice, Note, Callout

Figma:

Responsive:

Adaptive:

Props

Component props
Name
Type
Default
message
Required
string | ReactElement
-

Main content of BannerCallout. Content should be localized.

See the message variant to learn more. Refer to the Best Practices for content guidelines.

type
Required
"default" | "error" | "info" | "recommendation" | "success" | "warning"
-

The category of BannerCallout. See Variants to learn more.

dismissButton
{
  accessibilityLabel?: string;
  onDismiss: () => void;
}
-

Adds a dismiss button to BannerCallout. See the Dismissible variant for more info.
The accessibilityLabel should follow the Accessibility guidelines.

iconAccessibilityLabel
string
-

Label to describe the icon’s purpose. See the Accessibility guidelines for details on proper usage.

primaryAction
{
    role: "link";
    accessibilityLabel: string;
    disabled?: boolean;
    href: string;
    label: string;
    onClick?: ComponentProps<typeof ButtonLink>["onClick"];
    rel?: "none" | "nofollow";
    target?: null | "self" | "blank";
  }
| {
    role?: "button";
    accessibilityLabel: string;
    disabled?: boolean;
    label: string;
    onClick?: ComponentProps<typeof Button>["onClick"];
  }
-

Main action for users to take on BannerCallout. If href is supplied, the action will serve as a link. See GlobalEventsHandlerProvider to learn more about link navigation.
If no href is supplied, the action will be a button.
The accessibilityLabel should follow the Accessibility guidelines.

secondaryAction
{
    role: "link";
    accessibilityLabel: string;
    disabled?: boolean;
    href: string;
    label: string;
    onClick?: ComponentProps<typeof ButtonLink>["onClick"];
    rel?: "none" | "nofollow";
    target?: null | "self" | "blank";
  }
| {
    role?: "button";
    accessibilityLabel: string;
    disabled?: boolean;
    label: string;
    onClick?: ComponentProps<typeof Button>["onClick"];
  }
-

Secondary action for users to take on BannerCallout. If role='link', the action will serve as a link. See GlobalEventsHandlerProvider to learn more about link navigation.
If role='button' (or undefined), the action will be a button.
The accessibilityLabel should follow the Accessibility guidelines.

title
string
-

Brief title summarizing BannerCallout. Content should be localized.

Usage guidelines

When to use
  • When displaying high priority, surface-level information to the user.
  • When providing persistent, non-blocking feedback.
  • When communicating updates to the state or status of the surface.
When not to use
  • When providing messaging/guidance for specific elements or areas within a surface. Let the team know if this is needed.
  • When displaying information that is intended for promotional/marketing purposes. Use BannerUpsell instead.
  • When interacting with the BannerCallout is required for the user to proceed with a task or flow. Use Modal instead.

Best practices

Do

Use BannerCallout for messages coming from the product or user interaction. Can be used in both Business and Pinner products.

Do

Place BannerCallout at the top of the page, under the primary navigation or page header when possible.

Don't

Use BannerCallouts for marketing new products or features. Use BannerUpsell instead.

Don't

Stack BannerCallouts. In the case that banners must be stacked, BannerCallouts should come before BannerUpsells.

Accessibility

Labels

iconAccessibilityLabel, dismissButton, primaryAction and secondaryAction each require a short, descriptive label for screen readers. These labels should communicate the intent of the icon, such as “Error”, “Info” or “Warning”. They should also be localized.

When using primaryAction or secondaryAction, alternative text should be provided through the accessibilityLabel prop to replace vague text like "Visit" or "Learn more" with more descriptive information, like "Learn more about work from home resources". Avoid using the words "button" or "link" in the label, as this becomes repetitive. If the action text is already descriptive, an empty string can be passed.

For the dismissButton, the label provided should indicate the intent, like “Dismiss this banner”.

import { BannerCallout, Box, Flex } from 'gestalt';

export default function Example() {
  return (
    <Flex
      alignItems="center"
      height="100%"
      justifyContent="center"
      width="100%"
    >
      <Box paddingX={8} paddingY={8}>
        <BannerCallout
          dismissButton={{
            accessibilityLabel: 'Dismiss this banner',
            onDismiss: () => {},
          }}
          iconAccessibilityLabel="Info"
          message="Apply to the Verified Merchant Program"
          primaryAction={{
            accessibilityLabel: 'Get started: Verified Merchant Program',
            href: 'https://pinterest.com',
            label: 'Get started',
            target: 'blank',
            role: 'link',
          }}
          secondaryAction={{
            accessibilityLabel: 'Learn more: Verified Merchant Program',
            href: 'https://pinterest.com',
            label: 'Learn more',
            target: 'blank',
            role: 'link',
          }}
          title="Your business account was created!"
          type="info"
        />
      </Box>
    </Flex>
  );
}

Localization

Be sure to localize all text strings. Note that localization can lengthen text by 20 to 30 percent.

Note that dismissButton.accessibilityLabel and iconAccessibilityLabel are optional as DefaultLabelProvider provides default strings. Use custom labels if they need to be more specific.

BannerCallout depends on DefaultLabelProvider for internal text strings. Localize the texts via DefaultLabelProvider. Learn more
import { BannerCallout, Box, DefaultLabelProvider, Flex } from 'gestalt';

export default function Example() {
  return (
    <DefaultLabelProvider
      labels={{
        BannerCallout: {
          accessibilityDismissButtonLabel: 'Banner entlassen.',
          iconAccessibilityLabelError: 'Fehler.',
          iconAccessibilityLabelInfo: 'Informationen.',
          iconAccessibilityLabelRecommendation: 'Empfehlung.',
          iconAccessibilityLabelWarning: 'Warnung.',
          iconAccessibilityLabelSuccess: 'Erfolg.',
        },
      }}
    >
      <Flex
        alignItems="center"
        height="100%"
        justifyContent="center"
        width="100%"
      >
        <Box paddingX={8} paddingY={8}>
          <BannerCallout
            dismissButton={{
              accessibilityLabel: 'Verwerfen Sie dieses Banner.',
              onDismiss: () => {},
            }}
            message="Bewerben Sie sich beim Verified Merchant Program"
            primaryAction={{
              accessibilityLabel: 'Loslegen: Verified Merchant Program',
              href: 'https://pinterest.com',
              label: 'Loslegen',
              target: 'blank',
              role: 'link',
            }}
            secondaryAction={{
              accessibilityLabel:
                'Erfahren Sie mehr: Verified Merchant Program',
              href: 'https://pinterest.com',
              label: 'Erfahren Sie mehr',
              target: 'blank',
              role: 'link',
            }}
            title="Ihr Geschäftskonto wurde erstellt!"
            type="info"
          />
        </Box>
      </Flex>
    </DefaultLabelProvider>
  );
}

Variants

Default

import { BannerCallout, Flex } from 'gestalt';

export default function Example() {
  return (
    <Flex
      alignItems="center"
      height="100%"
      justifyContent="center"
      width="100%"
    >
      <BannerCallout
        dismissButton={{
          onDismiss: () => {},
        }}
        message="Inspiration to build the life you love."
        primaryAction={{
          accessibilityLabel: 'Log in',
          href: 'https://pinterest.com',
          label: 'Sign up',
          target: 'blank',
          role: 'link',
        }}
        secondaryAction={{
          accessibilityLabel: 'Log in',
          href: 'https://pinterest.com',
          label: 'Log in',
          target: 'blank',
          role: 'link',
        }}
        title="Pinterest is the place for inspiration"
        type="default"
      />
    </Flex>
  );
}

Info

Info BannerCallouts communicate helpful messages to users about the product. In most cases, they should provide an action for users to take.

import { BannerCallout, Box, Flex } from 'gestalt';

export default function Example() {
  return (
    <Flex
      alignItems="center"
      height="100%"
      justifyContent="center"
      width="100%"
    >
      <Box paddingX={8} paddingY={8}>
        <BannerCallout
          dismissButton={{
            accessibilityLabel: 'Dismiss this banner',
            onDismiss: () => {},
          }}
          iconAccessibilityLabel="Info"
          message="Apply to the Verified Merchant Program"
          primaryAction={{
            accessibilityLabel: 'Get started: Verified Merchant Program',
            href: 'https://pinterest.com',
            label: 'Get started',
            target: 'blank',
            role: 'link',
          }}
          secondaryAction={{
            accessibilityLabel: 'Learn more: Verified Merchant Program',
            href: 'https://pinterest.com',
            label: 'Learn more',
            target: 'blank',
            role: 'link',
          }}
          title="Your business account was created!"
          type="info"
        />
      </Box>
    </Flex>
  );
}

Recommendation

Recommendation BannerCallouts inform people of quick things they can do to improve their experience.

import { BannerCallout, Box, Flex } from 'gestalt';

export default function Example() {
  return (
    <Flex
      alignItems="center"
      height="100%"
      justifyContent="center"
      width="100%"
    >
      <Box paddingX={8} paddingY={8}>
        <BannerCallout
          dismissButton={{
            accessibilityLabel: 'Dismiss this banner',
            onDismiss: () => {},
          }}
          iconAccessibilityLabel="Recommendation"
          message="When you run ads on Pinterest, you'll find recommendations to improve them here."
          primaryAction={{
            accessibilityLabel: 'Learn more: Ads on Pinterest',
            href: 'https://pinterest.com',
            label: 'Learn more',
            target: 'blank',
            role: 'link',
          }}
          title="Advertise with confidence!"
          type="recommendation"
        />
      </Box>
    </Flex>
  );
}

Success

Success BannerCallouts communicate confirmation regarding an action within a larger flow.

import { BannerCallout, Box, Flex } from 'gestalt';

export default function Example() {
  return (
    <Flex
      alignItems="center"
      height="100%"
      justifyContent="center"
      width="100%"
    >
      <Box paddingX={8} paddingY={8}>
        <BannerCallout
          dismissButton={{
            accessibilityLabel: 'Dismiss this banner',
            onDismiss: () => {},
          }}
          iconAccessibilityLabel="Success"
          message="Keep it up by using recommendations to optimize your ad spend."
          primaryAction={{
            accessibilityLabel: 'Get started: Ad recommendations',
            href: 'https://pinterest.com',
            label: 'Get started',
            target: 'blank',
            role: 'link',
          }}
          title="Your ads are doing great!"
          type="success"
        />
      </Box>
    </Flex>
  );
}

Warning

Warning BannerCallouts communicate cautionary messages to users. Action shouldn't be required. The BannerCallout should provide clear guidance on how to correct an issue and/or learn more about it.

import { BannerCallout, Box, Flex } from 'gestalt';

export default function Example() {
  return (
    <Flex
      alignItems="center"
      height="100%"
      justifyContent="center"
      width="100%"
    >
      <Box paddingX={8} paddingY={8}>
        <BannerCallout
          dismissButton={{
            accessibilityLabel: 'Dismiss warning',
            onDismiss: () => {},
          }}
          iconAccessibilityLabel="Warning"
          message="We have noticed that you have audiences in your advertiser account that have been used in an ad campaign. Pinterest will be deleting any unused audiences on May 30, 2020."
          primaryAction={{
            accessibilityLabel: 'View unused audiences',
            href: 'https://pinterest.com',
            label: 'View audiences',
            target: 'blank',
            role: 'link',
          }}
          title="Unused audiences are going away"
          type="warning"
        />
      </Box>
    </Flex>
  );
}

Error

Error BannerCallouts inform users of problems that require immediate action to correct. Further actions on the page might be blocked if users don't correct the problems. The BannerCallout should also provide clear guidance on how to correct the issue and/or learn more about it.

import { BannerCallout, Box, Flex } from 'gestalt';

export default function Example() {
  return (
    <Flex
      alignItems="center"
      height="100%"
      justifyContent="center"
      width="100%"
    >
      <Box paddingX={8} paddingY={8}>
        <BannerCallout
          iconAccessibilityLabel="Error"
          message="Your tag has errors, so information may be outdated. Fix your tag for the most accurate metrics."
          primaryAction={{
            accessibilityLabel: 'Fix Pinterest tag',
            href: 'https://pinterest.com',
            label: 'Fix tag',
            target: 'blank',
            role: 'link',
          }}
          title="Pinterest tag needs attention"
          type="error"
        />
      </Box>
    </Flex>
  );
}

Actions

BannerCallouts can have either one primary action, or a primary action and a secondary action. These actions can be Links, by specifying the href property, or Buttons, when no href is supplied.

BannerCallout actions with link interaction can be paired with GlobalEventsHandlerProvider. See GlobalEventsHandlerProvider to learn more about link navigation.

For example, “Learn more” may link to a separate documentation site, while “Apply now” could be a Button that opens a Modal with an application flow. Be sure to localize the labels of the actions.

If needed, actions can become disabled after clicking by setting disabled: true in the action data.

import { useState } from 'react';
import {
  BannerCallout,
  Box,
  Button,
  ButtonGroup,
  Column,
  Flex,
  Label,
  Layer,
  Modal,
  Text,
  TextArea,
  TextField,
} from 'gestalt';

export default function Example() {
  const [showModal, setShowModal] = useState(false);
  const toggleModal = () => {
    setShowModal((currState) => !currState);
  };

  return (
    <Flex
      alignItems="center"
      height="100%"
      justifyContent="center"
      width="100%"
    >
      <Box paddingX={8} paddingY={8}>
        <BannerCallout
          dismissButton={{
            accessibilityLabel: 'Dismiss banner',
            onDismiss: () => {},
          }}
          iconAccessibilityLabel="Info"
          message="Apply to the Verified Merchant Program"
          primaryAction={{
            accessibilityLabel: 'Apply now: verified merchant program',
            label: 'Apply now',
            onClick: toggleModal,
            role: 'button',
          }}
          secondaryAction={{
            accessibilityLabel: 'Learn more: Verified Merchant Program',
            href: 'https://help.pinterest.com/en/business/article/verified-merchant-program',
            label: 'Learn more',
            target: 'blank',
            role: 'link',
          }}
          title="Your business account was created!"
          type="info"
        />

        {showModal && (
          <Layer>
            <Modal
              accessibilityModalLabel="Apply for the Verified Merchant Program"
              footer={
                <Flex flex="grow" justifyContent="end">
                  <ButtonGroup>
                    <Button onClick={toggleModal} size="lg" text="Cancel" />
                    <Button
                      color="red"
                      onClick={toggleModal}
                      size="lg"
                      text="Save"
                    />
                  </ButtonGroup>
                </Flex>
              }
              heading="Verified Merchant Program Application"
              onDismiss={toggleModal}
              size="md"
            >
              <Flex>
                <Column span={12}>
                  <Box display="flex" paddingX={8} paddingY={2}>
                    <Column span={4}>
                      <Label htmlFor="name">
                        <Text align="start" weight="bold">
                          Name
                        </Text>
                      </Label>
                    </Column>
                    <Column span={8}>
                      <TextField id="name" onChange={() => {}} />
                    </Column>
                  </Box>

                  <Box display="flex" paddingX={8} paddingY={2}>
                    <Column span={4}>
                      <Label htmlFor="desc">
                        <Text align="start" weight="bold">
                          Business Description
                        </Text>
                      </Label>
                    </Column>
                    <Column span={8}>
                      <TextArea id="desc" onChange={() => {}} />
                    </Column>
                  </Box>
                </Column>
              </Flex>
            </Modal>
          </Layer>
        )}
      </Box>
    </Flex>
  );
}

Dismissible

dismissButton can be used when BannerCallout doesn't indicate a persistent state. This will most commonly be used in type="info" BannerCallouts.

Don't use dismiss buttons in the following cases:

  • There is a persistent account or page status that the user must address.
  • The user must access BannerCallout's information again in order to perform a task.
import { BannerCallout, Box, Flex } from 'gestalt';

export default function Example() {
  return (
    <Flex
      alignItems="center"
      height="100%"
      justifyContent="center"
      width="100%"
    >
      <Box paddingX={8} paddingY={8}>
        <BannerCallout
          dismissButton={{
            accessibilityLabel: 'Dismiss this banner',
            onDismiss: () => {},
          }}
          iconAccessibilityLabel="Info"
          message="Apply to the Verified Merchant Program"
          primaryAction={{
            accessibilityLabel: 'Get started: Verified Merchant Program',
            href: 'https://pinterest.com',
            label: 'Get started',
            target: 'blank',
            role: 'link',
          }}
          secondaryAction={{
            accessibilityLabel: 'Learn more: Verified Merchant Program',
            href: 'https://pinterest.com',
            label: 'Learn more',
            target: 'blank',
            role: 'link',
          }}
          title="Your business account was created!"
          type="info"
        />
      </Box>
    </Flex>
  );
}

Message

The message prop accepts either a string or Text. Use a string for simple messages without any visual style. BannerCallout 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 React from 'react';
import { BannerCallout, Box, Flex, Text } from 'gestalt';

export default function ResponsiveExample() {
  return (
    <Flex
      alignItems="center"
      height="100%"
      justifyContent="center"
      width="100%"
    >
      <Box paddingX={8} paddingY={8}>
        <BannerCallout
          dismissButton={{
            accessibilityLabel: 'Dismiss this banner',
            onDismiss: () => {},
          }}
          iconAccessibilityLabel="Info"
          message={
            <Text inline>
              You have invited{' '}
              <Text inline weight="bold">
                Leaf Media Agency
              </Text>{' '}
              to your business hierarchy. Once they accept, you will be able to
              manage their business account.
            </Text>
          }
          primaryAction={{
            accessibilityLabel: 'Resend invite',
            label: 'Resend invite',
            role: 'button',
          }}
          secondaryAction={{
            accessibilityLabel: 'Cancel invite',
            label: 'Cancel invite',
            role: 'button',
          }}
          title="You've sent an invite"
          type="info"
        />
      </Box>
    </Flex>
  );
}

Component quality checklist

Component quality checklist
Quality item
Status
Status description
Figma Library
Ready
Component is available in Figma for web and mobile web.
Responsive Web
Ready
Component responds to changing viewport sizes in web and mobile web.

BannerUpsell
If marketing new products or features, or encouraging upgrades, use BannerUpsell instead.

Toast
Toast provides feedback on a user interaction, like a confirmation that appears when a Pin has been saved. Unlike BannerUpsell and BannerCallout, Toasts don’t contain actions. They’re also less persistent, and disappear after a certain duration.

ActivationCard
ActivationCards are used in groups to communicate a user’s stage in a series of steps toward an overall action.