react-inclusive-card
v0.1.4
Published
A simple, accessible, and flexible card component for React, inspired by the excellent book ["Inclusive Components"](https://inclusive-components.design/cards) by Heydon Pickering.
Maintainers
Readme
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
asprop (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-cardImport 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-cardYou will be prompted for a destination path.
Or pass the --path option to specify a custom path:
npx react-inclusive-card --path src/componentsThis 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 ifhreforcustomLinkComponentis 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
classNameprop 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.
