shadimage
fluent2-react-kit
uicardsource: ok · refreshed

Card

Fluent 2-styled card with shadcn APIs. Seven composable parts (Card, CardHeader, CardTitle, CardDescription, CardAction, CardContent, CardFooter), Fluent resting elevation (shadow-4) and rounded-lg border.

npx shadcn add "https://fluent2-react-kit.graund.io/r/card.json"
free

Where it goes

navbarfooter

Tags auto-generated by rules on 9/24/2026 — empty means no evidence, not lack of support.

Dependencies

Bundle weight · light

Registry dependencies

https://fluent2-react-kit.graund.io/r/utils.json

Files1 · source cached 10/8/2026, 3:01:43 AM

components/ui/card.tsx
import type { ComponentProps } from "react";

import { cn } from "@/lib/utils";

/**
 * Card — Fluent 2-styled, shadcn-API card family.
 *
 * Structure matches shadcn/ui's current Card exactly: seven composable parts
 * (`Card`, `CardHeader`, `CardTitle`, `CardDescription`, `CardAction`,
 * `CardContent`, `CardFooter`), each a plain `<div>` carrying its own
 * `data-slot`. `CardHeader` is a grid so an optional `CardAction` can sit in
 * its own column/row-span without extra markup (shadcn's `has-data-[slot=...]`
 * trick) — see https://ui.shadcn.com/docs/components/card.
 *
 * Fluent 2 aesthetics layered on top of that skeleton:
 * - `rounded-lg` + `border` + `shadow-4` (Fluent's resting elevation for a
 *   filled card — https://storybooks.fluentui.dev/react/?path=/docs/components-card--docs)
 *   instead of shadcn's default `rounded-xl` + `shadow-sm`.
 * - `bg-card text-card-foreground` (shadcn semantic tokens, re-pointed for
 *   dark mode by tokens.css).
 * - `CardTitle` is `font-semibold` (Fluent card titles are weight 600).
 * - Spacing: Fluent's own medium card padding is 12px (`p-3`), noticeably
 *   tighter than shadcn's 24px (`p-6`) default. We split the difference and
 *   land on 16px (`gap-4` / `p-4` / `px-4`) — visibly tighter than shadcn so
 *   the Fluent influence reads, while keeping enough breathing room that the
 *   header/content/footer rhythm still feels like the familiar shadcn
 *   composition (a straight 12px port felt cramped next to Button's 32px
 *   controls). Document this if you change it.
 *
 * No `variant`/`size` props: shadcn's Card ships none, so there is no `cva`
 * table here (unlike Button) — every part is a plain function component.
 *
 * `interactive` (kit extension): Fluent cards have hover/pressed states when
 * clickable; passing `interactive` raises the resting `shadow-4` to `shadow-8`
 * on hover (Fluent's interactive-card elevation step) with a pointer cursor
 * and `data-interactive` hook. Visual-only — semantics/focus come from what
 * you compose it with (wrap in an `<a>`/`<button>` or add role/tabIndex).
 *
 * Server-safe: no `"use client"`, no hooks — the React import is type-only.
 */

function Card({
  className,
  interactive = false,
  ...props
}: ComponentProps<"div"> & {
  /** Fluent interactive-card elevation states (hover raises to shadow-8). */
  interactive?: boolean;
}) {
  return (
    <div
      data-slot="card"
      data-interactive={interactive || undefined}
      className={cn(
        "flex flex-col gap-4 rounded-lg border bg-card py-4 text-card-foreground shadow-4",
        interactive &&
          "cursor-pointer transition-shadow duration-fast ease-ease hover:shadow-8 active:shadow-4",
        className
      )}
      {...props}
    />
  );
}

function CardHeader({ className, ...props }: ComponentProps<"div">) {
  return (
    <div
      data-slot="card-header"
      className={cn(
        "@container/card-header grid auto-rows-min grid-rows-[auto_auto] items-start gap-1.5 px-4 has-data-[slot=card-action]:grid-cols-[1fr_auto] [.border-b]:pb-4",
        className
      )}
      {...props}
    />
  );
}

function CardTitle({ className, ...props }: ComponentProps<"div">) {
  return (
    <div
      data-slot="card-title"
      className={cn("font-semibold leading-none", className)}
      {...props}
    />
  );
}

function CardDescription({ className, ...props }: ComponentProps<"div">) {
  return (
    <div
      data-slot="card-description"
      className={cn("text-sm text-muted-foreground", className)}
      {...props}
    />
  );
}

function CardAction({ className, ...props }: ComponentProps<"div">) {
  return (
    <div
      data-slot="card-action"
      className={cn(
        "col-start-2 row-span-2 row-start-1 self-start justify-self-end",
        className
      )}
      {...props}
    />
  );
}

function CardContent({ className, ...props }: ComponentProps<"div">) {
  return (
    <div
      data-slot="card-content"
      className={cn("px-4", className)}
      {...props}
    />
  );
}

function CardFooter({ className, ...props }: ComponentProps<"div">) {
  return (
    <div
      data-slot="card-footer"
      className={cn("flex items-center px-4 [.border-t]:pt-4", className)}
      {...props}
    />
  );
}

export {
  Card,
  CardHeader,
  CardFooter,
  CardTitle,
  CardAction,
  CardDescription,
  CardContent,
};

More from fluent2-react-kit

Browse all components in this library →