Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/swift-grapes-warn.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@primer/react': patch
Copy link

Copilot AI Apr 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This changeset marks the release as patch, but the versioning guide indicates that adding a prop is a minor bump ("Props → A prop is added → minor"). Please update the changeset to minor (or document why this is an exception).

Suggested change
'@primer/react': patch
'@primer/react': minor

Copilot uses AI. Check for mistakes.
---

Add borderRadius prop to Card component.
6 changes: 6 additions & 0 deletions packages/react/src/Card/Card.docs.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,12 @@
"type": "'none' | 'condensed' | 'normal'",
"defaultValue": "'normal'",
"description": "Controls the internal padding of the Card."
},
{
"name": "borderRadius",
"type": "'medium' | 'large'",
"defaultValue": "'large'",
"description": "Controls the border radius of the Card."
}
],
"subcomponents": [
Expand Down
9 changes: 8 additions & 1 deletion packages/react/src/Card/Card.module.css
Original file line number Diff line number Diff line change
@@ -1,14 +1,21 @@
.Card {
display: grid;
position: relative;
border-radius: var(--borderRadius-large);
overflow: hidden;
grid-auto-rows: max-content auto;
border: var(--borderWidth-thin) solid var(--borderColor-default);
box-shadow: var(--shadow-resting-small);
background-color: var(--bgColor-default);
gap: var(--stack-gap-normal);

&[data-border-radius='large'] {
border-radius: var(--borderRadius-large);
}

&[data-border-radius='medium'] {
border-radius: var(--borderRadius-medium);
}

&[data-padding='normal'] {
/* stylelint-disable-next-line primer/spacing */
padding: var(--stack-padding-spacious);
Expand Down
13 changes: 10 additions & 3 deletions packages/react/src/Card/Card.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,13 @@ export const Default = () => {
type PlaygroundArgs = {
showIcon: boolean
showMetadata: boolean
padding: 'normal' | 'none'
padding: 'none' | 'condensed' | 'normal'
borderRadius: 'medium' | 'large'
}

export const Playground: StoryFn<PlaygroundArgs> = ({showIcon, showMetadata, padding}) => (
export const Playground: StoryFn<PlaygroundArgs> = ({showIcon, showMetadata, padding, borderRadius}) => (
<div style={{maxWidth: '400px'}}>
<Card padding={padding}>
<Card padding={padding} borderRadius={borderRadius}>
{showIcon && <Card.Icon icon={RocketIcon} />}
<Card.Heading>Playground Card</Card.Heading>
<Card.Description>Experiment with the Card component and its subcomponents.</Card.Description>
Expand All @@ -43,6 +44,7 @@ Playground.args = {
showIcon: true,
showMetadata: true,
padding: 'normal',
borderRadius: 'large',
}

Playground.argTypes = {
Expand All @@ -59,4 +61,9 @@ Playground.argTypes = {
options: ['none', 'condensed', 'normal'],
description: 'Controls the internal padding of the Card',
},
borderRadius: {
control: {type: 'radio'},
options: ['medium', 'large'],
description: 'Controls the border radius of the Card',
},
}
24 changes: 21 additions & 3 deletions packages/react/src/Card/Card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,12 @@ export type CardProps = React.ComponentPropsWithoutRef<'div'> & {
* @default 'normal'
*/
padding?: 'none' | 'condensed' | 'normal'

/**
* Controls the border radius of the Card.
* @default 'large'
*/
borderRadius?: 'medium' | 'large'
}

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

const CardImpl = forwardRef<HTMLDivElement, CardProps>(function Card(
{children, className, padding = 'normal', ...rest},
{children, className, padding = 'normal', borderRadius = 'large', ...rest},
ref,
) {
let icon: React.ReactNode = null
Expand Down Expand Up @@ -96,14 +102,26 @@ const CardImpl = forwardRef<HTMLDivElement, CardProps>(function Card(

if (!hasSlotChildren) {
return (
<div ref={ref} className={clsx(classes.Card, className)} data-padding={padding} {...rest}>
<div
ref={ref}
className={clsx(classes.Card, className)}
data-padding={padding}
data-border-radius={borderRadius}
{...rest}
>
{children}
</div>
)
}

return (
<div ref={ref} className={clsx(classes.Card, className)} data-padding={padding} {...rest}>
<div
ref={ref}
className={clsx(classes.Card, className)}
data-padding={padding}
data-border-radius={borderRadius}
{...rest}
Comment on lines +118 to +123
Copy link

Copilot AI Apr 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

New borderRadius behavior is not covered by unit tests. Since this component already asserts data-padding defaults/overrides in Card.test.tsx, please add similar assertions for data-border-radius (default 'large' and when borderRadius="medium").

Copilot uses AI. Check for mistakes.
>
{(image || icon) && (
<div className={clsx(classes.CardHeader, image && classes.CardHeaderEdgeToEdge)}>{image || icon}</div>
)}
Expand Down
Loading