Skip to content

Commit 774b91b

Browse files
authored
Improved background customization options for CTABanner (#810)
1 parent bbb14ce commit 774b91b

15 files changed

+492
-45
lines changed

.changeset/soft-frogs-build.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
---
2+
'@primer/react-brand': patch
3+
---
4+
5+
Added new background customization options to `CTABanner`
6+
7+
New props:
8+
9+
- `backgroundColor`
10+
- `backgroundImageSrc`
11+
- `backgroundImageSize`
12+
- `backgroundImagePosition`
13+
14+
Also added `variant` prop to `CTABanner.Description`, to achieve higher contrast when using background images.
15+
16+
:link: [See the documentation for more details and usage examples](https://primer.style/brand/components/CTABanner/react/).

apps/docs/content/components/CTABanner/react.mdx

Lines changed: 67 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,11 @@ description: Use the CTA banner component to highlight and create urgency around
77
---
88

99
import {Label} from '@primer/react'
10+
import {PropTableValues} from '../../../src/components'
1011
import {Link} from 'gatsby'
1112
import ComponentLayout from '../../../src/layouts/component-layout'
1213
export default ComponentLayout
14+
import {TextVariants} from '@primer/react-brand'
1315

1416
```js
1517
import {CTABanner, Button} from '@primer/react-brand'
@@ -57,6 +59,56 @@ The content alignment can be changed using the `align` prop on the root `CTABann
5759
</CTABanner>
5860
```
5961

62+
### Optional background image
63+
64+
```jsx live
65+
<ThemeProvider colorMode="dark">
66+
<CTABanner
67+
backgroundImageSrc={{
68+
narrow:
69+
'https://github.com/user-attachments/assets/a28110fd-d019-41a4-8f80-b49ae8895708',
70+
regular:
71+
'https://github.com/user-attachments/assets/a28110fd-d019-41a4-8f80-b49ae8895708',
72+
wide: 'https://github.com/user-attachments/assets/a28110fd-d019-41a4-8f80-b49ae8895708',
73+
}}
74+
align="center"
75+
hasShadow={false}
76+
>
77+
<CTABanner.Heading>
78+
Where the most ambitious teams build great things
79+
</CTABanner.Heading>
80+
<CTABanner.Description variant="default">
81+
Lorem ipsum dolor sit amet, consectetur adipiscing elit. In sapien sit
82+
ullamcorper id. Aliquam luctus sed turpis felis nam pulvinar risus
83+
elementum.
84+
</CTABanner.Description>
85+
<CTABanner.ButtonGroup>
86+
<Button>Primary Action</Button>
87+
</CTABanner.ButtonGroup>
88+
</CTABanner>
89+
</ThemeProvider>
90+
```
91+
92+
### Optional background colors
93+
94+
`CTABanner` supports `default`, `subtle` and arbitrary `background-color` values
95+
96+
```jsx live
97+
<CTABanner backgroundColor="subtle" hasShadow={false}>
98+
<CTABanner.Heading>
99+
Where the most ambitious teams build great things
100+
</CTABanner.Heading>
101+
<CTABanner.Description>
102+
Lorem ipsum dolor sit amet, consectetur adipiscing elit. In sapien sit
103+
ullamcorper id. Aliquam luctus sed turpis felis nam pulvinar risus
104+
elementum.
105+
</CTABanner.Description>
106+
<CTABanner.ButtonGroup>
107+
<Button>Primary Action</Button>
108+
</CTABanner.ButtonGroup>
109+
</CTABanner>
110+
```
111+
60112
### Optional border
61113

62114
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.
@@ -166,13 +218,17 @@ render(<App />)
166218

167219
### CTABanner <Label>Required</Label>
168220

169-
| name | type | default | required | description |
170-
| --------------- | -------------------------- | ----------- | -------- | ----------------------------------------------------------------- |
171-
| `children` | `ReactNode`, `ReactNode[]` | `undefined` | `true` | Content to include within the banner component |
172-
| `align` | `'start'`, `'center'` | `'start'` | `true` | The horizontal positioning of content within the banner component |
173-
| `hasBorder` | `boolean` | `false` | `false` | A flag used to provide a border to the banner component |
174-
| `hasShadow` | `boolean` | `true` | `false` | A flag used to provide a shadow to the banner component |
175-
| `hasBackground` | `boolean` | `true` | `false` | A flag used to add a background to the banner component |
221+
| name | type | default | required | description |
222+
| ------------------------- | ---------------------------------------------------------------------------------------------------------- | ----------- | -------- | ----------------------------------------------------------------- |
223+
| `children` | `ReactNode`, `ReactNode[]` | `undefined` | `true` | Content to include within the banner component |
224+
| `align` | `'start'`, `'center'` | `'start'` | `true` | The horizontal positioning of content within the banner component |
225+
| `backgroundColor` | <PropTableValues values={['default', 'subtle', 'string', `ResponsiveMap`]} addLineBreaks commaSeparated /> | `'default'` | `false` | Optional, custom background color |
226+
| `backgroundImageSrc` | <PropTableValues values={['string' , `ResponsiveMap`]} addLineBreaks commaSeparated /> | `undefined` | `false` | Optional, custom background image |
227+
| `backgroundImagePosition` | <PropTableValues values={['string' , `ResponsiveMap`]} addLineBreaks commaSeparated/> | `'center'` | `false` | Optional, custom background position |
228+
| `backgroundImageSize` | <PropTableValues values={['string' , `ResponsiveMap`]} addLineBreaks commaSeparated /> | `'cover'` | `false` | Optional, custom background position size |
229+
| `hasBorder` | `boolean` | `false` | `false` | A flag used to provide a border to the banner component |
230+
| `hasShadow` | `boolean` | `true` | `false` | A flag used to provide a shadow to the banner component |
231+
| `hasBackground` | `boolean` | `true` | `false` | A flag used to add a background to the banner component |
176232

177233
### CTABanner.Heading
178234

@@ -184,9 +240,10 @@ render(<App />)
184240

185241
### CTABanner.Description
186242

187-
| name | type | default | required | description |
188-
| ---------- | -------------------------- | ----------- | -------- | --------------------------------------------------- |
189-
| `children` | `ReactNode`, `ReactNode[]` | `undefined` | `true` | Content to be displayed inside the banner component |
243+
| name | type | default | required | description |
244+
| ---------- | ------------------------------------------------------- | ----------- | ----------------------------------- | --------------------------------------------------- |
245+
| `children` | `ReactNode`, `ReactNode[]` | `undefined` | `true` | Content to be displayed inside the banner component |
246+
| `variant` | <PropTableValues values={TextVariants} addLineBreaks /> | `'muted'` | Specify alternative text appearance |
190247

191248
### CTABanner.ButtonGroup <Label>Required</Label>
192249

apps/docs/scripts/components-with-animation.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@ export const supportedComponents = [
1111
'Pillar',
1212
'SectionIntro',
1313
'Stack',
14-
'Statistic',
1514
'Testimonial',
1615
'Text',
16+
'Statistic',
1717
'Timeline',
1818
'Animate',
1919
'River',

packages/react/src/CTABanner/CTABanner.features.stories.tsx

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,14 @@ import {ActionMenu} from '../ActionMenu'
44
import {Button} from '../Button'
55

66
import {CTABanner} from './CTABanner'
7+
import {Grid, Section, Stack, ThemeProvider} from '../'
8+
9+
import lightNarrowBg from '../fixtures/images/light-vertical-banner.png'
10+
import lightWideBg from '../fixtures/images/light-horizontal-banner.png'
11+
import darkNarrowBg from '../fixtures/images/dark-vertical-banner-alt.png'
12+
import darkWideBg from '../fixtures/images/dark-horizontal-banner-alt.png'
13+
import darkNarrowBg2 from '../fixtures/images/dark-vertical-banner-alt-2.png'
14+
import darkWideBg2 from '../fixtures/images/dark-horizontal-banner-alt-2.png'
715

816
export default {
917
title: 'Components/CTABanner/Features',
@@ -98,3 +106,118 @@ export const CustomShadow = () => (
98106
</CTABanner>
99107
</div>
100108
)
109+
110+
export const CustomBackgroundColors = () => (
111+
<Stack direction="vertical">
112+
<CTABanner hasShadow={false}>
113+
<CTABanner.Heading>Default</CTABanner.Heading>
114+
<CTABanner.Description>
115+
Lorem ipsum dolor sit amet, consectetur adipiscing elit. In sapien sit ullamcorper id. Aliquam luctus sed turpis
116+
felis nam pulvinar risus elementum.
117+
</CTABanner.Description>
118+
<CTABanner.ButtonGroup>
119+
<Button>Primary Action</Button>
120+
<Button>Secondary Action</Button>
121+
</CTABanner.ButtonGroup>
122+
</CTABanner>
123+
<CTABanner hasShadow={false} backgroundColor="subtle">
124+
<CTABanner.Heading>Subtle</CTABanner.Heading>
125+
<CTABanner.Description>
126+
Lorem ipsum dolor sit amet, consectetur adipiscing elit. In sapien sit ullamcorper id. Aliquam luctus sed turpis
127+
felis nam pulvinar risus elementum.
128+
</CTABanner.Description>
129+
<CTABanner.ButtonGroup>
130+
<Button>Primary Action</Button>
131+
<Button>Secondary Action</Button>
132+
</CTABanner.ButtonGroup>
133+
</CTABanner>
134+
<CTABanner hasShadow={false} backgroundColor="var(--base-color-scale-blue-0)">
135+
<CTABanner.Heading>Base scale blue 0</CTABanner.Heading>
136+
<CTABanner.Description>
137+
Lorem ipsum dolor sit amet, consectetur adipiscing elit. In sapien sit ullamcorper id. Aliquam luctus sed turpis
138+
felis nam pulvinar risus elementum.
139+
</CTABanner.Description>
140+
<CTABanner.ButtonGroup>
141+
<Button>Primary Action</Button>
142+
<Button>Secondary Action</Button>
143+
</CTABanner.ButtonGroup>
144+
</CTABanner>
145+
<CTABanner hasShadow={false} backgroundColor="cyan">
146+
<CTABanner.Heading>Cyan</CTABanner.Heading>
147+
<CTABanner.Description>
148+
Lorem ipsum dolor sit amet, consectetur adipiscing elit. In sapien sit ullamcorper id. Aliquam luctus sed turpis
149+
felis nam pulvinar risus elementum.
150+
</CTABanner.Description>
151+
<CTABanner.ButtonGroup>
152+
<Button>Primary Action</Button>
153+
<Button>Secondary Action</Button>
154+
</CTABanner.ButtonGroup>
155+
</CTABanner>
156+
<CTABanner hasShadow={false} backgroundColor={{narrow: 'yellow', regular: 'orange', wide: 'beige'}}>
157+
<CTABanner.Heading>Responsive</CTABanner.Heading>
158+
<CTABanner.Description>
159+
Lorem ipsum dolor sit amet, consectetur adipiscing elit. In sapien sit ullamcorper id. Aliquam luctus sed turpis
160+
felis nam pulvinar risus elementum.
161+
</CTABanner.Description>
162+
<CTABanner.ButtonGroup>
163+
<Button>Primary Action</Button>
164+
<Button>Secondary Action</Button>
165+
</CTABanner.ButtonGroup>
166+
</CTABanner>
167+
</Stack>
168+
)
169+
170+
export const ResponsiveBackgroundImage = args => (
171+
<CTABanner
172+
align="center"
173+
hasShadow={false}
174+
backgroundImageSrc={
175+
args.backgroundImageSrc || {
176+
narrow: lightNarrowBg,
177+
regular: lightWideBg,
178+
wide: lightWideBg,
179+
}
180+
}
181+
>
182+
<CTABanner.Heading>Where the most ambitious teams build great things</CTABanner.Heading>
183+
<CTABanner.Description variant="default">
184+
Lorem ipsum dolor sit amet, consectetur adipiscing elit. In sapien sit ullamcorper id. Aliquam luctus sed turpis
185+
felis nam pulvinar risus elementum.
186+
</CTABanner.Description>
187+
<CTABanner.ButtonGroup>
188+
<Button>Primary Action</Button>
189+
</CTABanner.ButtonGroup>
190+
</CTABanner>
191+
)
192+
193+
export const ResponsiveBackgroundImageDark = () => (
194+
<Stack padding="none" gap="spacious">
195+
<ResponsiveBackgroundImage
196+
backgroundImageSrc={{
197+
narrow: darkNarrowBg,
198+
regular: darkWideBg,
199+
wide: darkWideBg,
200+
}}
201+
/>{' '}
202+
<ResponsiveBackgroundImage
203+
backgroundImageSrc={{
204+
narrow: darkNarrowBg2,
205+
regular: darkWideBg2,
206+
wide: darkWideBg2,
207+
}}
208+
/>
209+
</Stack>
210+
)
211+
ResponsiveBackgroundImageDark.decorators = [
212+
Story => (
213+
<ThemeProvider colorMode="dark">
214+
<Section backgroundColor="default">
215+
<Grid>
216+
<Grid.Column>
217+
<Story />
218+
</Grid.Column>
219+
</Grid>
220+
</Section>
221+
</ThemeProvider>
222+
),
223+
]

packages/react/src/CTABanner/CTABanner.module.css

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,16 @@
3737
}
3838

3939
.CTABanner-container--background {
40-
background: var(--brand-CTABanner-bgColor);
40+
border-radius: var(--brand-borderRadius-xlarge);
41+
background-repeat: no-repeat;
42+
background-color: var(--brand-CTABanner-narrow-background-color, var(--brand-CTABanner-background-color));
43+
background-image: var(--brand-CTABanner-narrow-background-image-src, var(--brand-CTABanner-background-image-src));
44+
background-size: var(--brand-CTABanner-narrow-background-image-size, var(--brand-CTABanner-background-image-size));
45+
46+
background-position: var(
47+
--brand-CTABanner-narrow-background-image-position,
48+
var(--brand-CTABanner-background-image-position, center)
49+
);
4150
}
4251

4352
.CTABanner-container--border {
@@ -50,7 +59,6 @@
5059
}
5160

5261
.CTABanner-description {
53-
color: var(--brand-color-text-muted);
5462
margin-bottom: var(--base-size-16);
5563
}
5664

@@ -67,3 +75,30 @@
6775
padding: var(--base-size-128) var(--base-size-64);
6876
}
6977
}
78+
79+
/* Regular */
80+
@media screen and (min-width: 48rem) {
81+
.CTABanner-container--background {
82+
background-color: var(--brand-CTABanner-regular-background-color, var(--brand-CTABanner-background-color));
83+
background-image: var(--brand-CTABanner-regular-background-image-src, var(--brand-CTABanner-background-image-src));
84+
background-size: var(--brand-CTABanner-regular-background-image-size, var(--brand-CTABanner-background-image-size));
85+
background-position: var(
86+
--brand-CTABanner-regular-background-image-position,
87+
var(--brand-CTABanner-background-image-position)
88+
);
89+
}
90+
}
91+
92+
/* Wide */
93+
@media screen and (min-width: 80rem) {
94+
.CTABanner-container--background {
95+
background-color: var(--brand-CTABanner-wide-background-color, var(--brand-CTABanner-background-color));
96+
background-image: var(--brand-CTABanner-wide-background-image-src, var(--brand-CTABanner-background-image-src));
97+
background-size: var(--brand-CTABanner-wide-background-image-size, var(--brand-CTABanner-background-image-size));
98+
99+
background-position: var(
100+
--brand-CTABanner-wide-background-image-position,
101+
var(--brand-CTABanner-background-image-position)
102+
);
103+
}
104+
}

0 commit comments

Comments
 (0)