@primer/react-brand
Version:
Primer Brand is a GitHub's design system for creating React-based marketing websites and digital experiences.
344 lines (285 loc) • 17.4 kB
Markdown
---
title: CTA banner
description: Use the CTA banner component to highlight and create urgency around user actions.
keywords: ['call to action', 'banner', 'conversion', 'highlight', 'urgent']
ready: true
figma: https://www.figma.com/file/BJ95AjraesmRCWsKA013GS/Primer-Brand?node-id=539%3A14285&t=RJEWZhVUtrRQ0pKh-0
source: https://github.com/primer/brand/blob/main/packages/react/src/CTABanner/CTABanner.tsx
storybook: '/brand/storybook/?path=/story/components-ctabanner--playground'
---
```js
import {CTABanner, Button} from '@primer/react-brand'
```
## Examples
### Default
```jsx
<CTABanner>
<CTABanner.Heading>Where the most ambitious teams build great things</CTABanner.Heading>
<CTABanner.Description>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. In sapien sit ullamcorper id. Aliquam luctus sed turpis
felis nam pulvinar risus elementum.
</CTABanner.Description>
<CTABanner.ButtonGroup>
<Button>Primary Action</Button>
<Button>Secondary Action</Button>
</CTABanner.ButtonGroup>
</CTABanner>
```
### Variants
#### Balanced
> A `CTABanner.Image` child is required in this variant.
```jsx
<CTABanner variant="balanced">
<CTABanner.Heading>Where the most ambitious teams build great things</CTABanner.Heading>
<CTABanner.Description>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. In sapien sit ullamcorper id. Aliquam luctus sed turpis
felis nam pulvinar risus elementum.
</CTABanner.Description>
<CTABanner.ButtonGroup>
<Button>Primary Action</Button>
<Button>Secondary Action</Button>
</CTABanner.ButtonGroup>
<CTABanner.Image src="/images/placeholder.png" alt="placeholder" />
</CTABanner>
```
#### Minimal
> `CTABanner.Image` is not supported in this variant and will not be rendered.
```jsx
<CTABanner variant="minimal">
<CTABanner.Heading>Where the most ambitious teams build great things</CTABanner.Heading>
<CTABanner.Description>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. In sapien sit ullamcorper id.
</CTABanner.Description>
<CTABanner.ButtonGroup>
<Button>Primary Action</Button>
<Button>Secondary Action</Button>
</CTABanner.ButtonGroup>
</CTABanner>
```
### With logo
Use `CTABanner.Logo` to display a brand mark above the heading.
```jsx
<CTABanner>
<CTABanner.Logo>
<svg role="img" focusable="false" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 45 16" width="45" height="16">
<title>GitHub</title>
<path d="M8.81 7.35v5.74c0 .04-.01.11-.06.13 0 0-1.25.89-3.31.89-2.49 0-5.44-.78-5.44-5.92S2.58 1.99 5.1 2c2.18 0 3.06.49 3.2.58.04.05.06.09.06.14L7.94 4.5c0 .09-.09.2-.2.17-.36-.11-.9-.33-2.17-.33-1.47 0-3.05.42-3.05 3.73s1.5 3.7 2.58 3.7c.92 0 1.25-.11 1.25-.11v-2.3H4.88c-.11 0-.19-.08-.19-.17V7.35c0-.09.08-.17.19-.17h3.74c.11 0 .19.08.19.17Zm35.85 2.33c0 3.43-1.11 4.41-3.05 4.41-1.64 0-2.52-.83-2.52-.83s-.04.46-.09.52c-.03.06-.08.08-.14.08h-1.48c-.1 0-.19-.08-.19-.17l.02-11.11c0-.09.08-.17.17-.17h2.13c.09 0 .17.08.17.17v3.77s.82-.53 2.02-.53l-.01-.02c1.2 0 2.97.45 2.97 3.88ZM27.68 2.43c.09 0 .17.08.17.17v11.11c0 .09-.08.17-.17.17h-2.13c-.09 0-.17-.08-.17-.17l.02-4.75h-3.31v4.75c0 .09-.08.17-.17.17h-2.13c-.08 0-.17-.08-.17-.17V2.6c0-.09.08-.17.17-.17h2.13c.09 0 .17.08.17.17v4.09h3.31V2.6c0-.09.08-.17.17-.17Zm8.26 3.64c.11 0 .19.08.19.17l-.02 7.47c0 .09-.06.17-.17.17H34.6c-.07 0-.14-.04-.16-.09-.03-.06-.08-.45-.08-.45s-1.13.77-2.52.77c-1.69 0-2.92-.55-2.92-2.75V6.25c0-.09.08-.17.17-.17h2.14c.09 0 .17.08.17.17V11c0 .75.22 1.09.97 1.09s1.3-.39 1.3-.39V6.26c0-.11.06-.19.17-.19Zm-17.406 5.971h.005a.177.177 0 0 1 .141.179v1.5c0 .07-.03.14-.09.16-.1.05-.74.22-1.27.22-1.16 0-2.86-.25-2.86-2.69V8.13h-1.11c-.09 0-.17-.08-.17-.19V6.58c0-.08.05-.15.13-.17.07-.01 1.16-.28 1.16-.28V3.96c0-.08.05-.13.14-.13h2.16c.09 0 .14.05.14.13v2.11h1.59c.08 0 .16.08.16.17v1.7c0 .11-.07.19-.16.19h-1.59v3.131c0 .47.27.83 1.05.83.247 0 .481-.049.574-.05ZM12.24 6.06c.09 0 .17.08.17.17v7.37c0 .18-.05.27-.25.27h-1.92c-.17 0-.3-.07-.3-.27V6.26c0-.11.08-.2.17-.2Zm29.99 3.78c0-1.81-.73-2.05-1.5-1.97-.6.04-1.08.34-1.08.34v3.52s.49.34 1.22.36c1.03.03 1.36-.34 1.36-2.25ZM11.19 2.68c.75 0 1.36.61 1.36 1.38 0 .77-.61 1.38-1.36 1.38-.77 0-1.38-.61-1.38-1.38 0-.77.61-1.38 1.38-1.38Zm7.34 9.35v.001l.01.01h-.001l-.005-.001v.001c-.009-.001-.015-.011-.024-.011Z"></path>
</svg>
</CTABanner.Logo>
<CTABanner.Heading>Where the most ambitious teams build great things</CTABanner.Heading>
<CTABanner.Description>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. In sapien sit ullamcorper id.
</CTABanner.Description>
<CTABanner.ButtonGroup>
<Button>Primary Action</Button>
<Button>Secondary Action</Button>
</CTABanner.ButtonGroup>
</CTABanner>
```
### With link
Use `CTABanner.Link` to provide a secondary call-to-action as a text link instead of a button.
```jsx
<CTABanner>
<CTABanner.Heading>Where the most ambitious teams build great things</CTABanner.Heading>
<CTABanner.Description>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. In sapien sit ullamcorper id.
</CTABanner.Description>
<CTABanner.Link href="#">Read the customer story</CTABanner.Link>
</CTABanner>
```
### Duotone heading text
Wrap part of a heading in a `<b>` tag to apply the duotone emphasis color.
```jsx
<CTABanner>
<CTABanner.Heading>
Where the most ambitious teams <b>build great things</b>
</CTABanner.Heading>
<CTABanner.Description>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. In sapien sit ullamcorper id.
</CTABanner.Description>
<CTABanner.ButtonGroup>
<Button>Primary Action</Button>
<Button>Secondary Action</Button>
</CTABanner.ButtonGroup>
</CTABanner>
```
### Alignment
The content alignment can be changed using the `align` prop on the root `CTABanner`. This can be configured to either `start` or `center`.
```jsx
<CTABanner align="center">
<CTABanner.Heading>Where the most ambitious teams build great things</CTABanner.Heading>
<CTABanner.Description>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. In sapien sit ullamcorper id. Aliquam luctus sed turpis
felis nam pulvinar risus elementum.
</CTABanner.Description>
<CTABanner.ButtonGroup>
<Button>Primary Action</Button>
<Button>Secondary Action</Button>
</CTABanner.ButtonGroup>
</CTABanner>
```
### Optional background image
```jsx
<ThemeProvider colorMode="dark">
<CTABanner
backgroundImageSrc={{
narrow: 'https://github.com/user-attachments/assets/a28110fd-d019-41a4-8f80-b49ae8895708',
regular: 'https://github.com/user-attachments/assets/a28110fd-d019-41a4-8f80-b49ae8895708',
wide: 'https://github.com/user-attachments/assets/a28110fd-d019-41a4-8f80-b49ae8895708',
}}
align="center"
hasShadow={false}
>
<CTABanner.Heading>Where the most ambitious teams build great things</CTABanner.Heading>
<CTABanner.Description variant="default">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. In sapien sit ullamcorper id. Aliquam luctus sed turpis
felis nam pulvinar risus elementum.
</CTABanner.Description>
<CTABanner.ButtonGroup>
<Button>Primary Action</Button>
</CTABanner.ButtonGroup>
</CTABanner>
</ThemeProvider>
```
### Optional background colors
`CTABanner` supports `default`, `subtle` and arbitrary `background-color` values
```jsx
<CTABanner backgroundColor="subtle" hasShadow={false}>
<CTABanner.Heading>Where the most ambitious teams build great things</CTABanner.Heading>
<CTABanner.Description>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. In sapien sit ullamcorper id. Aliquam luctus sed turpis
felis nam pulvinar risus elementum.
</CTABanner.Description>
<CTABanner.ButtonGroup>
<Button>Primary Action</Button>
</CTABanner.ButtonGroup>
</CTABanner>
```
### Optional border
A border can be provided using the `hasBorder` prop on the root `CTABanner`. This will render a border around the `CTABanner` component giving further separation between the foreground and background. Especially when there is no shadow present on the background.
```jsx
<CTABanner hasBorder>
<CTABanner.Heading>Where the most ambitious teams build great things</CTABanner.Heading>
<CTABanner.Description>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. In sapien sit ullamcorper id. Aliquam luctus sed turpis
felis nam pulvinar risus elementum.
</CTABanner.Description>
<CTABanner.ButtonGroup>
<Button>Primary Action</Button>
<Button>Secondary Action</Button>
</CTABanner.ButtonGroup>
</CTABanner>
```
### Optional background
A background can be removed using the `hasBackground` prop on the root `CTABanner`. This will render the `CTABanner` component without a background allowing it to blend in with its parent.
```jsx
<CTABanner hasBackground={false} hasShadow={false}>
<CTABanner.Heading>Where the most ambitious teams build great things</CTABanner.Heading>
<CTABanner.Description>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. In sapien sit ullamcorper id. Aliquam luctus sed turpis
felis nam pulvinar risus elementum.
</CTABanner.Description>
<CTABanner.ButtonGroup>
<Button>Primary Action</Button>
<Button>Secondary Action</Button>
</CTABanner.ButtonGroup>
</CTABanner>
```
### Remove shadow
The shadow can be removed using the `hasShadow` prop. This will render the component without the background shadow.
```jsx
<CTABanner hasShadow={false}>
<CTABanner.Heading>Where the most ambitious teams build great things</CTABanner.Heading>
<CTABanner.Description>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. In sapien sit ullamcorper id. Aliquam luctus sed turpis
felis nam pulvinar risus elementum.
</CTABanner.Description>
<CTABanner.ButtonGroup>
<Button>Primary Action</Button>
<Button>Secondary Action</Button>
</CTABanner.ButtonGroup>
</CTABanner>
```
### Shadow color customization
The default shadow colors can be customized through their respective CSS variables.
```jsx filename="noinline"
const App = () => {
const designTokenOverrides = `
.custom-colors[data-color-mode='dark'] {
/*
* Modify the value of these tokens.
* Remember to apply light mode equivalents if you're enabling theme switching.
*/
--brand-CTABanner-shadow-color-start: var(--base-color-scale-purple-5);
--brand-CTABanner-shadow-color-end: var(--base-color-scale-red-5);
}
`
return (
<ThemeProvider colorMode="dark" className="custom-colors">
<style>{designTokenOverrides}</style>
<CTABanner>
<CTABanner.Heading>Where the most ambitious teams build great things</CTABanner.Heading>
<CTABanner.Description>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. In sapien sit ullamcorper id. Aliquam luctus sed
turpis felis nam pulvinar risus elementum.
</CTABanner.Description>
<CTABanner.ButtonGroup>
<Button>Primary Action</Button>
<Button>Secondary Action</Button>
</CTABanner.ButtonGroup>
</CTABanner>
</ThemeProvider>
)
}
render(<App />)
```
## Component props
### CTABanner `Required`
| name | type | default | required | description |
| ------------------------- | ------------------------------------------------------ | ----------- | -------- | ----------------------------------------------------------------- |
| `children` | `ReactNode`, `ReactNode[]` | `undefined` | `true` | Content to include within the banner component |
| `variant` | `'default' \| 'balanced' \| 'minimal'` | `'default'` | `false` | Alternative layout presentations |
| `align` | `'start' \| 'center'` | `'center'` | `false` | The horizontal positioning of content within the banner component |
| `backgroundColor` | `'default' \| 'subtle' \| 'string' \| 'ResponsiveMap'` | `'default'` | `false` | Optional, custom background color |
| `backgroundImageSrc` | `'string' \| 'ResponsiveMap'` | `undefined` | `false` | Optional, custom background image |
| `backgroundImagePosition` | `'string' \| 'ResponsiveMap'` | `'center'` | `false` | Optional, custom background position |
| `backgroundImageSize` | `'string' \| 'ResponsiveMap'` | `'cover'` | `false` | Optional, custom background position size |
| `hasBorder` | `boolean` | `false` | `false` | A flag used to provide a border to the banner component |
| `hasGridLines` | `boolean` | `false` | `false` | Enables optional gridlines appearance |
| `hasShadow` | `boolean` | `false` | `false` | A flag used to provide a shadow to the banner component |
| `hasBackground` | `boolean` | `true` | `false` | A flag used to add a background to the banner component |
### CTABanner.Heading
| name | type | default | required | description |
| ---------- | ---------------------------------------------- | ----------- | -------- | ---------------------------------------------------------------------------------------------------------------------------- |
| `children` | `ReactNode`, `ReactNode[]` | `undefined` | `true` | Content to be displayed inside the `CTABanner.Heading` component. Wrap text in `<b>` to apply duotone emphasis. |
| `as` | `'h1' \| 'h2' \| 'h3' \| 'h4' \| 'h5' \| 'h6'` | `'h3'` | `false` | Heading level |
| `size` | `'1' \| '2' \| '3' \| '4' \| '5' \| '6'` | `'3'` | `false` | Visual heading size, irrespective of level. Note: the `minimal` variant defaults the visual size to `'6'` when not provided. |
### CTABanner.Description
| name | type | default | required | description |
| ---------- | ---------------------------------- | ----------- | -------- | --------------------------------------------------- |
| `children` | `ReactNode`, `ReactNode[]` | `undefined` | `true` | Content to be displayed inside the banner component |
| `variant` | `'default' \| 'muted' \| 'subtle'` | `'muted'` | `false` | Specify alternative text appearance |
### CTABanner.ButtonGroup `Required`
| name | type | default | required | description |
| ------------ | ------------------------ | ----------- | -------- | -------------------------------------------- |
| `children` | `<Button>`, `<Button>[]` | `undefined` | `true` | The buttons to be displayed within the group |
| `buttonSize` | `'medium'`, `'large'` | `large` | `false` | The size of the buttons in the group |
| `buttonsAs` | `'a'`, `'button'` | `'button'` | `false` | Sets underlying HTML element for each button |
`id`, `className` and `ref` are forwarded by default to all children.
### CTABanner.Image
| name | type | default | required | description |
| ----- | -------- | ----------- | -------- | ----------------------------------------- |
| `src` | `string` | `undefined` | `true` | The image source URL |
| `alt` | `string` | `undefined` | `true` | Accessible alternative text for the image |
### CTABanner.Logo
| name | type | default | required | description |
| ---------- | ----------- | ----------- | -------- | ------------------------------------------------------------------------------------- |
| `children` | `ReactNode` | `undefined` | `true` | The logo to display, typically an inline SVG so it can be styled and stay accessible. |
### CTABanner.Link
| name | type | default | required | description |
| ---------- | ----------------------- | ----------- | -------- | ----------------------------------------------------- |
| `children` | `ReactNode` | `undefined` | `true` | The link text |
| `href` | `string` | `undefined` | `true` | The link target URL |
| `variant` | `'default'`, `'accent'` | `'accent'` | `false` | Visual variant. Defaults to `accent` inside CTABanner |
## Related components
- [BreakoutBanner](../BreakoutBanner/index.md)