Inclusive Card
A simple, accessible, and flexible card component for React, inspired by the excellent book "Inclusive Components" by Heydon Pickering.
Table of Contents
Features
- Polymorphic: Render as any HTML element using the
as
prop (e.g.article
,li
,a
, etc.). - Accessible: Follows best practices for headings, links, and focus management.
- Customizable: Easily adjust styles with CSS custom properties or class names to fit your design needs.
- Composable: Includes subcomponents for title, controls, image, and call-to-action.
- CLI: Copy the component into your project with a single command.
Installation
You have two options to use this component:
1. Install via npm:
npm install react-inclusive-card
Import the component in your React project:
import { Card } from "react-inclusive-card";
2. Copy the code:
You can copy the component to your project using CLI script
npx react-inclusive-card
You will be prompted for a destination path.
\
Or pass the --path
option to specify a custom path:
npx react-inclusive-card --path src/components
This will copy the InclusiveCard.tsx
component and its styles to the specified directory.
Usage
import { Card } from "inclusive-card";
<Card
as={"li"}
className="card-container"
imageClassName="card-image"
contentClassName="card-content"
imageProps={{
src: "https://upload.wikimedia.org/wikipedia/commons/5/5e/TomateSanMarzano.jpg",
alt: "A proud tomato plant in a garden",
}}
>
<Card.Title as={`h3`} href={"#"} className="card-title">
The Tomato Whisperer
</Card.Title>
<p>
Accidentally watered your shoes instead of the plants? Planted carrots
upside down? Welcome to the club! Here, we believe every weed is just a
misunderstood flower.
</p>
<Card.Controls asChild>
<button
className="btn btn-primary"
onClick={() =>
alert(
"You planted a mystery seed. Is it a pumpkin or a triffid? Only time will tell."
)
}
>
Plant Mystery Seed
</button>
</Card.Controls>
<Card.CallToAction
className="btn btn-secondary"
style={
{
"--inclusive-card-cta-focus-shadow": "0 0 0 2px hsl(0 0% 0% / 0.5)",
} as React.CSSProperties
}
>
read more
</Card.CallToAction>
</Card>;

API
<Card>
Prop | Type | Default | Description |
---|---|---|---|
as |
React.ElementType |
"article" |
The element type to render as (e.g. "li" , "a" , "section" ). |
className |
string |
"" |
Additional class names to apply to the card container. |
imageClassName |
string |
"" |
Additional class names to apply to the image wrapper. |
contentClassName |
string |
"" |
Additional class names to apply to the content wrapper. |
imageProps |
{ src: string; alt: string; } or { customImageComponent: React.ReactElement } |
— | Image source and alt text, or a custom image component to render inside the card. |
<Card.Title>
Prop | Type | Default | Description | |||||
---|---|---|---|---|---|---|---|---|
as |
"h1" \ |
"h2" \ |
"h3" \ |
"h4" \ |
"h5" \ |
"h6" |
"h2" |
The element type to render as (e.g. "h1" , "h3" , etc.). |
href |
string |
— | If provided, renders an <a> element with this URL. |
|||||
customLinkComponent |
React.ReactElement |
— | A custom link component to use instead of the default <a> . |
|||||
linkProps |
React.AnchorHTMLAttributes<HTMLAnchorElement> |
— | Additional props to pass to the link element if href is used. |
|||||
aria-describedby |
string |
— | ID of an element providing additional context for screen readers. | |||||
className |
string |
"" |
Additional class names to apply to the title element. | |||||
children |
React.ReactNode |
— | The content of the title, typically text or a link. |
- Use for the main heading of the card.
- Renders as a heading element (
h1
-h6
) with an anchor link that makes the whole card clickable ifhref
orcustomLinkComponent
is provided.
<Card.Controls>
Prop | Type | Default | Description |
---|---|---|---|
as |
React.ElementType |
"div" |
The element type to render as (e.g. "button" , "div" ). |
asChild |
boolean |
false |
If true , applies styles to the child element directly (no wrapper). |
className |
string |
"" |
Additional class names to apply to the controls wrapper. |
children |
React.ReactNode |
— | The content of the controls, typically buttons or links. |
- Use for interactive elements like buttons or links.
<Card.CallToAction>
Prop | Type | Default | Description |
---|---|---|---|
as |
React.ElementType |
"div" |
The element type to render as (e.g. "button" , "div" ). |
className |
string |
"" |
Additional class names to apply to the call-to-action wrapper. |
children |
React.ReactNode |
— | The content of the call-to-action, typically text or a link. |
- Use for decorative call-to-action elements (e.g., "read more" links).
- Hidden from screen readers by default (
aria-hidden="true"
). - Gets focus styles when the card title is focused.
Styling
- Use the
className
prop to add your own styles. Customize with CSS custom properties in your own stylesheet:
--inclusive-card-default-shadow
--inclusive-card-hover-shadow
--inclusive-card-focus-shadow
--inclusive-card-cta-focus-decoration
--inclusive-card-cta-focus-shadow
Or override classes like
.inclusive-card
,.inclusive-card__title
,.inclusive-card__controls
, etc.
Credits
Inspired by "Inclusive Components" by Heydon Pickering.