Skip to content

Commit b288d6e

Browse files
authored
Card: Add borderRadius prop (#7763)
Co-authored-by: liuliu-dev <6688812+liuliu-dev@users.noreply.github.com>
1 parent e974d9f commit b288d6e

9 files changed

Lines changed: 69 additions & 7 deletions

File tree

.changeset/swift-grapes-warn.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@primer/react': minor
3+
---
4+
5+
Add borderRadius prop to Card component.
318 Bytes
Loading
310 Bytes
Loading

packages/react/.storybook/primitives-v8.css

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
@import '@primer/primitives/dist/css/base/typography/typography.css';
55
@import '@primer/primitives/dist/css/functional/size/border.css';
66
@import '@primer/primitives/dist/css/functional/size/breakpoints.css';
7+
@import '@primer/primitives/dist/css/functional/size/radius.css';
78
@import '@primer/primitives/dist/css/functional/size/size-coarse.css';
89
@import '@primer/primitives/dist/css/functional/size/size-fine.css';
910
@import '@primer/primitives/dist/css/functional/size/size.css';

packages/react/src/Card/Card.docs.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,12 @@
2626
"type": "'none' | 'condensed' | 'normal'",
2727
"defaultValue": "'normal'",
2828
"description": "Controls the internal padding of the Card."
29+
},
30+
{
31+
"name": "borderRadius",
32+
"type": "'medium' | 'large'",
33+
"defaultValue": "'large'",
34+
"description": "Controls the border radius of the Card."
2935
}
3036
],
3137
"subcomponents": [

packages/react/src/Card/Card.module.css

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,21 @@
11
.Card {
22
display: grid;
33
position: relative;
4-
border-radius: var(--borderRadius-large);
54
overflow: hidden;
65
grid-auto-rows: max-content auto;
76
border: var(--borderWidth-thin) solid var(--borderColor-default);
87
box-shadow: var(--shadow-resting-small);
98
background-color: var(--bgColor-default);
109
gap: var(--stack-gap-normal);
1110

11+
&[data-border-radius='large'] {
12+
border-radius: var(--borderRadius-large);
13+
}
14+
15+
&[data-border-radius='medium'] {
16+
border-radius: var(--borderRadius-medium);
17+
}
18+
1219
&[data-padding='normal'] {
1320
/* stylelint-disable-next-line primer/spacing */
1421
padding: var(--stack-padding-spacious);

packages/react/src/Card/Card.stories.tsx

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,13 @@ export const Default = () => {
2525
type PlaygroundArgs = {
2626
showIcon: boolean
2727
showMetadata: boolean
28-
padding: 'normal' | 'none'
28+
padding: 'none' | 'condensed' | 'normal'
29+
borderRadius: 'medium' | 'large'
2930
}
3031

31-
export const Playground: StoryFn<PlaygroundArgs> = ({showIcon, showMetadata, padding}) => (
32+
export const Playground: StoryFn<PlaygroundArgs> = ({showIcon, showMetadata, padding, borderRadius}) => (
3233
<div style={{maxWidth: '400px'}}>
33-
<Card padding={padding}>
34+
<Card padding={padding} borderRadius={borderRadius}>
3435
{showIcon && <Card.Icon icon={RocketIcon} />}
3536
<Card.Heading>Playground Card</Card.Heading>
3637
<Card.Description>Experiment with the Card component and its subcomponents.</Card.Description>
@@ -43,6 +44,7 @@ Playground.args = {
4344
showIcon: true,
4445
showMetadata: true,
4546
padding: 'normal',
47+
borderRadius: 'large',
4648
}
4749

4850
Playground.argTypes = {
@@ -59,4 +61,9 @@ Playground.argTypes = {
5961
options: ['none', 'condensed', 'normal'],
6062
description: 'Controls the internal padding of the Card',
6163
},
64+
borderRadius: {
65+
control: {type: 'radio'},
66+
options: ['medium', 'large'],
67+
description: 'Controls the border radius of the Card',
68+
},
6269
}

packages/react/src/Card/Card.test.tsx

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,4 +153,22 @@ describe('Card', () => {
153153
)
154154
expect(container.firstChild).toHaveAttribute('data-padding', 'none')
155155
})
156+
157+
it('should set data-border-radius to large by default', () => {
158+
const {container} = render(
159+
<Card>
160+
<Card.Heading>Default Radius</Card.Heading>
161+
</Card>,
162+
)
163+
expect(container.firstChild).toHaveAttribute('data-border-radius', 'large')
164+
})
165+
166+
it('should set data-border-radius to medium when borderRadius="medium"', () => {
167+
const {container} = render(
168+
<Card borderRadius="medium">
169+
<Card.Heading>Medium Radius</Card.Heading>
170+
</Card>,
171+
)
172+
expect(container.firstChild).toHaveAttribute('data-border-radius', 'medium')
173+
})
156174
})

packages/react/src/Card/Card.tsx

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,12 @@ export type CardProps = React.ComponentPropsWithoutRef<'div'> & {
1414
* @default 'normal'
1515
*/
1616
padding?: 'none' | 'condensed' | 'normal'
17+
18+
/**
19+
* Controls the border radius of the Card.
20+
* @default 'large'
21+
*/
22+
borderRadius?: 'medium' | 'large'
1723
}
1824

1925
type HeadingLevel = 'h2' | 'h3' | 'h4' | 'h5' | 'h6'
@@ -62,7 +68,7 @@ type MetadataProps = React.ComponentPropsWithoutRef<'div'> & {
6268
}
6369

6470
const CardImpl = forwardRef<HTMLDivElement, CardProps>(function Card(
65-
{children, className, padding = 'normal', ...rest},
71+
{children, className, padding = 'normal', borderRadius = 'large', ...rest},
6672
ref,
6773
) {
6874
let icon: React.ReactNode = null
@@ -96,14 +102,26 @@ const CardImpl = forwardRef<HTMLDivElement, CardProps>(function Card(
96102

97103
if (!hasSlotChildren) {
98104
return (
99-
<div ref={ref} className={clsx(classes.Card, className)} data-padding={padding} {...rest}>
105+
<div
106+
ref={ref}
107+
className={clsx(classes.Card, className)}
108+
data-padding={padding}
109+
data-border-radius={borderRadius}
110+
{...rest}
111+
>
100112
{children}
101113
</div>
102114
)
103115
}
104116

105117
return (
106-
<div ref={ref} className={clsx(classes.Card, className)} data-padding={padding} {...rest}>
118+
<div
119+
ref={ref}
120+
className={clsx(classes.Card, className)}
121+
data-padding={padding}
122+
data-border-radius={borderRadius}
123+
{...rest}
124+
>
107125
{(image || icon) && (
108126
<div className={clsx(classes.CardHeader, image && classes.CardHeaderEdgeToEdge)}>{image || icon}</div>
109127
)}

0 commit comments

Comments
 (0)