Skip to content

Add Card component#7723

Merged
liuliu-dev merged 20 commits intomainfrom
liuliu/add-card-component
Apr 9, 2026
Merged

Add Card component#7723
liuliu-dev merged 20 commits intomainfrom
liuliu/add-card-component

Conversation

@liuliu-dev
Copy link
Copy Markdown
Contributor

@liuliu-dev liuliu-dev commented Apr 1, 2026

Upstream the Card component from Pacer into @primer/react.

Issue: https://github.com/github/primer/issues/6467

Changelog

New

  • Card — A styled container component with border, box-shadow, and border-radius; also supports custom content without subcomponents (plain container mode)
  • Card.Icon — Renders a decorative icon in the card header (defaults to aria-hidden, supports aria-label for meaningful icons)
  • Card.Image — Renders an edge-to-edge image in the card header
  • Card.Heading — Renders a heading (defaults to h3, configurable via as prop)
  • Card.Description — Renders a description below the heading
  • Card.Menu — Slot for overlay menu (positioned absolute top-right)
  • Card.Metadata — Renders metadata content below the description

Changed

  • Playground Storybook story updated with boolean toggle controls for Card.Icon and Card.Metadata
  • CustomContent Storybook story added to demonstrate using Card as a plain styled container with arbitrary children (no subcomponents)

Rollout strategy

  • Patch release
  • Minor release
  • Major release; if selected, include a written rollout or migration plan
  • None; if selected, include a brief description as to why

Testing & Reviewing

Merge checklist

@changeset-bot
Copy link
Copy Markdown

changeset-bot bot commented Apr 1, 2026

🦋 Changeset detected

Latest commit: 06edb74

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@primer/react Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@liuliu-dev liuliu-dev changed the title card from pacer Add Card component Apr 1, 2026
@github-actions github-actions bot added the integration-tests: recommended This change needs to be tested for breaking changes. See https://arc.net/l/quote/tdmpakpm label Apr 1, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 1, 2026

⚠️ Action required

👋 Hi, this pull request contains changes to the source code that github/github-ui depends on. If you are GitHub staff, test these changes with github/github-ui using the integration workflow. Check the integration testing docs for step-by-step instructions. Or, apply the integration-tests: skipped manually label to skip these checks.

To publish a canary release for integration testing, apply the Canary Release label to this PR.

@liuliu-dev liuliu-dev added the update snapshots 🤖 Command that updates VRT snapshots on the pull request label Apr 1, 2026
@github-actions github-actions bot temporarily deployed to storybook-preview-7723 April 1, 2026 21:41 Inactive
@github-actions github-actions bot removed the update snapshots 🤖 Command that updates VRT snapshots on the pull request label Apr 1, 2026
@github-actions github-actions bot temporarily deployed to storybook-preview-7723 April 1, 2026 21:54 Inactive
@github-actions github-actions bot temporarily deployed to storybook-preview-7723 April 1, 2026 22:05 Inactive
@primer
Copy link
Copy Markdown
Contributor

primer bot commented Apr 2, 2026

🤖 Lint issues have been automatically fixed and committed to this PR.

@primer
Copy link
Copy Markdown
Contributor

primer bot commented Apr 2, 2026

🤖 Lint issues have been automatically fixed and committed to this PR.

@lukasoppermann
Copy link
Copy Markdown
Contributor

@liuliu-dev should we tie the padding to the content-top, instead of icon bottom?

CleanShot 2026-04-07 at 09 23 53@2x

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 7, 2026

Uh oh! @lukasoppermann, at least one image you shared is missing helpful alt text. Check #7723 (comment) to fix the following violations:

  • Images should have meaningful alternative text (alt text) at line 3

Alt text is an invisible description that helps screen readers describe images to blind or low-vision users. If you are using markdown to display images, add your alt text inside the brackets of the markdown image.

Learn more about alt text at Basic writing and formatting syntax: images on GitHub Docs.

🤖 Beep boop! This comment was added automatically by github/accessibility-alt-text-bot.

@lukasoppermann
Copy link
Copy Markdown
Contributor

This is also a use case: https://primer-1b76de82d9-13348165.drafts.github.io/storybook/?path=/story/components-card--custom-content

CleanShot 2026-04-07 at 09 25 01@2x

I am wondering if we should expect users to "bring their own padding" or if we should have a padding inside the card by default and a prop or a way to easily remove the default padding? CC: @siddharthkp ?

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 7, 2026

Uh oh! @lukasoppermann, at least one image you shared is missing helpful alt text. Check #7723 (comment) to fix the following violations:

  • Images should have meaningful alternative text (alt text) at line 3

Alt text is an invisible description that helps screen readers describe images to blind or low-vision users. If you are using markdown to display images, add your alt text inside the brackets of the markdown image.

Learn more about alt text at Basic writing and formatting syntax: images on GitHub Docs.

🤖 Beep boop! This comment was added automatically by github/accessibility-alt-text-bot.

@ericwbailey
Copy link
Copy Markdown
Contributor

Thanks for the review @ericwbailey! Addressed:

Amazing! Thank you so much!

@liuliu-dev
Copy link
Copy Markdown
Contributor Author

Thanks @lukasoppermann! Here's what I've updated based on your feedback:

  • Updated typography and spacing to use the recommended tokens
  • Padding: moved padding to the Card root and added a padding prop (normal | none), defaults to normal. Header/body no longer have their own padding, spacing between them is controlled by gap instead.
  • Moved the custom content one into features stories.

@lukasoppermann
Copy link
Copy Markdown
Contributor

@liuliu-dev perfect, thank you.

@siddharthkp
Copy link
Copy Markdown
Member

I am wondering if we should expect users to "bring their own padding" or if we should have a padding inside the card by default and a prop or a way to easily remove the default padding? CC: @siddharthkp ?

I think bring your padding is a pattern we don't follow anywhere right now because it can lead to variation that is visibly inconsistent. Something we can take from PageLayout is the idea of padding: 'none' | 'condensed' | 'spacious' and of course, you can always fine-tune it with css.

@lukasoppermann
Copy link
Copy Markdown
Contributor

lukasoppermann commented Apr 8, 2026

I think bring your padding is a pattern we don't follow anywhere right now because it can lead to variation that is visibly inconsistent. Something we can take from PageLayout is the idea of padding: 'none' | 'condensed' | 'spacious' and of course, you can always fine-tune it with css.

The prop is now implemented, this makes sense to me.

@siddharthkp the Pagelayout does not make total sense to me, because there seems to be no default or normal one. Does the current implementation for card make sense to you?

you can always fine-tune it with css.

This is important! 👍

@siddharthkp
Copy link
Copy Markdown
Member

@siddharthkp the Pagelayout does not make total sense to me, because there seems to be no default or normal one.

My bad, the values in the docs are none | condensed | normal

normal as a value is a bit weird to me. default is totally fine.

Does the current implementation for card make sense to you?

I've come into this blind, so I don't actually know what's going on or what we are trying to do 😅

I would say however, we should put this in experimental and not root index right away

CardDescriptionProps,
CardMenuProps,
CardMetadataProps,
} from './Card'
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Should we export this from src/experimental/index until we build some confidence in the API with some usage?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Whatever you folks feel is best. Do we have a clear path for how we move this out of experimental? It feels like stuff stays in experimental for way to long some times.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Makes sense to keep it in experimental for now. It’s mostly upstreamed from Pacer so it’s not totally new, but the padding prop is new, if it looks good in usage we can move it out pretty quickly.

Copy link
Copy Markdown
Member

@siddharthkp siddharthkp Apr 9, 2026

Choose a reason for hiding this comment

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

Yep, but I would count pacer as super experimental too (and maybe deprecated).

It did not go through primer's patterns or accessibility process, so I'd like for us to be able to change our mind on the details

Copy link
Copy Markdown
Member

@siddharthkp siddharthkp Apr 9, 2026

Choose a reason for hiding this comment

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

^ which makes me wonder, @lukasoppermann are there any Card components as shared-components in github-ui that we should also consider as inventory?

Feels a bit strange to promote the experimental pacer component without looking at the other stable components that exist in github-ui

(Doesn't have to be blocking if we are putting this component in experimental, we can iterate over it before pushing for adoption)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Moved Card to @primer/react/experimental, merging now, happy to iterate in the future!

@lukasoppermann
Copy link
Copy Markdown
Contributor

Figma component: https://github.com/github/primer/issues/6537

@primer-integration
Copy link
Copy Markdown

👋 Hi from github/github-ui! Your integration PR is ready: https://github.com/github/github-ui/pull/18126

@primer-integration
Copy link
Copy Markdown

Integration test results from github/github-ui:

Passed  CI   Passed
Passed  VRT   Passed
Passed  Projects   Passed

All checks passed!

@liuliu-dev liuliu-dev added this pull request to the merge queue Apr 9, 2026
Merged via the queue into main with commit ec6c88f Apr 9, 2026
53 checks passed
@liuliu-dev liuliu-dev deleted the liuliu/add-card-component branch April 9, 2026 16:17
@primer primer bot mentioned this pull request Apr 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Canary Release Apply this label when you want CI to create a canary release of the current PR integration-tests: recommended This change needs to be tested for breaking changes. See https://arc.net/l/quote/tdmpakpm

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants