Card
A versatile card component with header, content, footer, and image support
Brook
New
Defining a brook
A small, natural stream of fresh water flowing along a course towards a river, lake, or sea.
import {
Card,
CardHeader,
CardTitle,
CardAction,
CardDescription,
CardContent,
CardFooter,
CardIcon,
} from "@/components/ui/card/card";
import { Droplets } from "lucide-react";
import { Button } from "@/components/ui/button/button";
import { Badge } from "@/components/ui/badge/badge";
import styles from "./card-demo.module.css";
export default function CardDemo() {
return (
<Card className={styles.card}>
<CardHeader>
<div>
<CardIcon>
<Droplets />
</CardIcon>
<CardTitle>Brook</CardTitle>
</div>
<CardAction>
<Badge size="sm" variant="secondary">
New
</Badge>
</CardAction>
<CardDescription>Defining a brook</CardDescription>
</CardHeader>
<CardContent>
<p>A small, natural stream of fresh water flowing along a course towards a river, lake, or sea.</p>
</CardContent>
<CardFooter>
<Button size="sm">Click me</Button>
</CardFooter>
</Card>
);
}
Installation
npx shadcn@latest add https://roiui.com/r/card.json
Anatomy
anatomy
import { Card, CardHeader, CardTitle, CardAction, CardDescription, CardContent, CardFooter } from '../ui/card'
<Card>
<CardHeader>
<CardTitle />
<CardAction />
<CardDescription />
</CardHeader>
<CardContent />
<CardFooter />
</Card>
Examples
Image Card
Mountain Adventure
Experience the beauty of mountain landscapes with guided tours and hiking adventures.
import { Card, CardTitle, CardContent, CardImage, CardFooter } from "@/components/ui/card/card";
import { Button } from "@/components/ui/button/button";
import styles from "./card-image.module.css";
export default function CardImageDemo() {
return (
<Card variant="lift" className={styles.card}>
<CardImage
src="https://images.unsplash.com/photo-1506905925346-21bda4d32df4?w=560&h=315&fit=crop&crop=center"
alt="Mountain landscape"
/>
<CardContent>
<CardTitle className={styles.title}>Mountain Adventure</CardTitle>
<p className={styles.description}>
Experience the beauty of mountain landscapes with guided tours and hiking adventures.
</p>
</CardContent>
<CardFooter>
<Button showArrow size="sm">
Learn More
</Button>
</CardFooter>
</Card>
);
}
Login Card
Sign In
"use client";
import { Card, CardHeader, CardTitle, CardContent, CardFooter } from "@/components/ui/card/card";
import { Field, FieldLabel, FieldControl, FieldError } from "@/components/ui/field/field";
import { useState } from "react";
import { Button } from "@/components/ui/button/button";
import styles from "./card-login.module.css";
export default function CardLoginDemo() {
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const [errors, setErrors] = useState<{ email?: string; password?: string }>({});
const handleSubmit = (e: React.FormEvent) => {
e.preventDefault();
const newErrors: { email?: string; password?: string } = {};
if (!email) {
newErrors.email = "Email is required";
} else if (!/\S+@\S+\.\S+/.test(email)) {
newErrors.email = "Email is invalid";
}
if (!password) {
newErrors.password = "Password is required";
} else if (password.length < 6) {
newErrors.password = "Password must be at least 6 characters";
}
setErrors(newErrors);
if (Object.keys(newErrors).length === 0) {
console.log("Login successful!", { email, password });
}
};
return (
<Card className={styles.card}>
<CardHeader>
<CardTitle>Sign In</CardTitle>
</CardHeader>
<CardContent>
<form onSubmit={handleSubmit} className={styles.form}>
<Field>
<FieldLabel>Email</FieldLabel>
<FieldControl
type="email"
placeholder="Enter your email"
value={email}
onChange={(e) => setEmail(e.target.value)}
/>
{errors.email && <FieldError>{errors.email}</FieldError>}
</Field>
<Field>
<FieldLabel>Password</FieldLabel>
<FieldControl
type="password"
placeholder="Enter your password"
value={password}
onChange={(e) => setPassword(e.target.value)}
/>
{errors.password && <FieldError>{errors.password}</FieldError>}
</Field>
</form>
</CardContent>
<CardFooter className={styles.footer}>
<Button onClick={handleSubmit} className={styles.button}>
Sign In
</Button>
<Button variant="ghost" className={styles.button}>
Forgot Password?
</Button>
</CardFooter>
</Card>
);
}
Props
Card
Prop | Type | Default |
---|---|---|
variant | "default" | "lift" | "default" |
className | string | - |
children | React.ReactNode | - |
CardHeader
Prop | Type | Default |
---|---|---|
className | string | - |
children | React.ReactNode | - |
CardTitle
Prop | Type | Default |
---|---|---|
className | string | - |
children | React.ReactNode | - |
CardDescription
Prop | Type | Default |
---|---|---|
className | string | - |
children | React.ReactNode | - |
CardContent
Prop | Type | Default |
---|---|---|
className | string | - |
children | React.ReactNode | - |
CardFooter
Prop | Type | Default |
---|---|---|
className | string | - |
children | React.ReactNode | - |
CardImage
Prop | Type | Default |
---|---|---|
src | string | - |
alt | string | - |
className | string | - |
children | React.ReactNode | - |
CardIcon
Prop | Type | Default |
---|---|---|
className | string | - |
children | React.ReactNode | - |