Card
Bordered surface with header, title, description, action, content and footer slots.
import * as React from "react"
import { cn } from "@/lib/utils"
/*
* Adapted from shadcn/ui (https://github.com/shadcn-ui/ui).
*
* MIT License
*
* Copyright (c) 2023 shadcn
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
function Card({ className, ...props }: React.ComponentProps<"div">) {
return (
<div
data-slot="card"
className={cn(
"flex flex-col gap-6 rounded-xl border border-border bg-card py-6 text-card-foreground shadow-none",
className
)}
{...props}
/>
)
}
function CardHeader({ className, ...props }: React.ComponentProps<"div">) {
return (
<div
data-slot="card-header"
className={cn(
"@container/card-header grid auto-rows-min grid-rows-[auto_auto] items-start gap-2 px-6 has-data-[slot=card-action]:grid-cols-[1fr_auto] [.border-b]:pb-6",
className
)}
{...props}
/>
)
}
function CardTitle({ className, ...props }: React.ComponentProps<"div">) {
return (
<div
data-slot="card-title"
className={cn("leading-none font-semibold", className)}
{...props}
/>
)
}
function CardDescription({ className, ...props }: React.ComponentProps<"div">) {
return (
<div
data-slot="card-description"
className={cn("text-sm text-muted-foreground", className)}
{...props}
/>
)
}
function CardAction({ className, ...props }: React.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 }: React.ComponentProps<"div">) {
return (
<div
data-slot="card-content"
className={cn("px-6", className)}
{...props}
/>
)
}
function CardFooter({ className, ...props }: React.ComponentProps<"div">) {
return (
<div
data-slot="card-footer"
className={cn("flex items-center px-6 [.border-t]:pt-6", className)}
{...props}
/>
)
}
export {
Card,
CardHeader,
CardFooter,
CardTitle,
CardAction,
CardDescription,
CardContent,
}Installation
pnpm dlx shadcn@latest add @ward/cardnpx shadcn@latest add @ward/cardyarn dlx shadcn@latest add @ward/cardbunx --bun shadcn@latest add @ward/cardAdd the Ward registry to components.json once:
"registries": {
"@ward": "https://ward.so/r/{name}.json"
}Or install from the URL with no configuration: npx shadcn@latest add https://ward.so/r/card.json
Copy each file from the Code tab into:
components/ui/card.tsx
Update the import paths to match your project.
Usage
import { Card, CardAction, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from "@/components/ui/card";
import { Button } from "@/components/ui/button";<Card className="w-80">
<CardHeader>
<CardTitle>Landing pages</CardTitle>
<CardDescription>24 sites saved by the team.</CardDescription>
<CardAction><Button variant="outline" size="sm">Edit</Button></CardAction>
</CardHeader>
<CardContent>Hero sections, pricing tables and footers worth a second look.</CardContent>
<CardFooter><Button size="sm">Open collection</Button></CardFooter>
</Card>Props
| Prop | Type | Default | Description |
|---|---|---|---|
className | string | - | Extra classes for the surface; every part of the card takes them too. |
CardHeader className | string | - | Add border-b to draw a divider under the header and pad below it. |
CardAction children | ReactNode | - | A control, such as a button, placed at the top right of the header beside the title and description. |
CardFooter className | string | - | Add border-t to draw a divider above the footer and pad below it. |
Ward · Version 1.0.0 · Registry manifest