react ~5 KB 0 deps v0.1.0 ↗ GitHub ↗

@mshafiqyajid/react-card

Headless card hook and styled component. Four variants, six tones, clickable with keyboard support, header/body/footer sub-components.

Playground #

Elevated

Surface card with subtle shadow and border.

Filled Primary

Filled variant with primary tone background tint.

Outlined Success

Clickable card — try hovering or pressing.

Card title

This is the card body. It can hold any content — text, images, actions, or other components.

Props
TSX
import { CardStyled } from "@mshafiqyajid/react-card/styled";
import "@mshafiqyajid/react-card/styles.css";

<CardStyled />

Install #

npm install @mshafiqyajid/react-card

Quick start #

import { CardStyled } from "@mshafiqyajid/react-card/styled";
import "@mshafiqyajid/react-card/styles.css";

// Simple card with shorthand slots
<CardStyled header="Title" footer="Footer">
  Card body content.
</CardStyled>

// Clickable card with tone
<CardStyled
  variant="outlined"
  tone="primary"
  clickable
  onClick={() => console.log("clicked")}
>
  Interactive card
</CardStyled>

// Selectable card (controlled)
<CardStyled
  clickable
  selected={isSelected}
  onSelect={setIsSelected}
>
  Toggle me
</CardStyled>

Sub-components #

import { Card } from "@mshafiqyajid/react-card/styled";
import "@mshafiqyajid/react-card/styles.css";

// Use Card.Header / Card.Body / Card.Footer for full control
<Card variant="elevated" size="lg">
  <Card.Header>
    <div style={{ display: "flex", justifyContent: "space-between" }}>
      <strong>Project Alpha</strong>
      <span>Active</span>
    </div>
  </Card.Header>
  <Card.Body>
    <p>Project description with custom layout inside the body.</p>
  </Card.Body>
  <Card.Footer>
    <button>View details</button>
  </Card.Footer>
</Card>
// Renders as <a> automatically when href is provided
<CardStyled href="/projects/alpha" tone="info" variant="outlined">
  Link card — full keyboard accessible
</CardStyled>

Headless #

import { useCard } from "@mshafiqyajid/react-card";

function MyCard() {
  const { cardProps, isSelected, isFocused } = useCard({
    clickable: true,
    defaultSelected: false,
    onSelect: (selected) => console.log("selected:", selected),
  });

  return (
    <div
      {...cardProps}
      className={`my-card ${isSelected ? "my-card--selected" : ""}`}
    >
      Custom card
    </div>
  );
}

API — CardStyled / Card #

PropTypeDefaultDescription
variant"elevated" | "outlined" | "filled" | "ghost""elevated"Visual style
size"sm" | "md" | "lg""md"Controls padding of header, body, and footer
tone"neutral" | "primary" | "success" | "warning" | "danger" | "info""neutral"Color accent applied to border and (filled) background
shadow"none" | "sm" | "md" | "lg"autoBox shadow. Defaults to sm for elevated, none otherwise
radius"none" | "sm" | "md" | "lg""md"Border radius
clickablebooleanfalseAdds button role, keyboard handling, and hover/active styles
selectedbooleanControlled selected state (shows indigo border)
defaultSelectedbooleanfalseUncontrolled initial selected state
disabledbooleanfalseDisables all interactions, reduces opacity
onClick(e: MouseEvent) => voidClick handler
onSelect(selected: boolean) => voidCalled with new selected state on each toggle
hrefstringRenders root as <a>
asElementType"div"Polymorphic element override
headerReactNodeShorthand for Card.Header content
footerReactNodeShorthand for Card.Footer content
loadingbooleanfalseReplaces children with a skeleton shimmer placeholder
hoverablebooleanfalseAdds hover lift effect without full clickable button semantics
borderedbooleanfalseForces a visible border on filled and ghost variants
compactbooleanfalseReduces padding to ~60% of the size-based default
classNamestringExtra class on the root element
styleCSSPropertiesInline style override

API — Sub-components #

ComponentPropTypeDescription
Card.HeaderchildrenReactNodeHeader content; gets a bottom border and bold weight
Card.BodychildrenReactNodeMain content area; receives padding from size prop
Card.FooterchildrenReactNodeFooter content; gets a top border
AllclassName, stylestring / CSSPropertiesClass and style overrides

API — useCard hook #

OptionTypeDescription
clickablebooleanEnable button semantics and keyboard handling
selectedbooleanControlled selected state
defaultSelectedbooleanUncontrolled initial selected state
disabledbooleanSuppress all events
onClick(e: MouseEvent) => voidClick callback
onSelect(selected: boolean) => voidSelection change callback

Returns cardProps (spread onto your element), isSelected, and isFocused.

Edit this page on GitHub