Search for a command to run...
Displays a card with header, content, and footer.
npx shadcn@latest add @zaidan/cardpnpx shadcn add @zaidan/cardyarn dlx shadcn@latest add @zaidan/cardbunx shadcn@latest add @zaidan/cardCopy and paste the following code into your project.
1import { type ComponentProps, mergeProps, splitProps } from "solid-js";2import { cn } from "~/lib/utils";3
4type CardProps = ComponentProps<"div"> & { size?: "default" | "sm" };5
6const Card = (props: CardProps) => {7 const mergedProps = mergeProps({ size: "default" } as const, props);8 const [local, others] = splitProps(mergedProps, ["class", "size"]);9 return (10 <div11 data-slot="card"12 data-size={local.size}13 class={cn("group/card z-card flex flex-col", local.class)}14 {...others}15 />16 );17};18
19type CardHeaderProps = ComponentProps<"div">;20
21const CardHeader = (props: CardHeaderProps) => {22 const [local, others] = splitProps(props, ["class"]);23 return (24 <div25 data-slot="card-header"26 class={cn(27 "group/card-header @container/card-header z-card-header grid auto-rows-min items-start has-data-[slot=card-action]:grid-cols-[1fr_auto] has-data-[slot=card-description]:grid-rows-[auto_auto]",28 local.class,29 )}30 {...others}31 />32 );33};34
35type CardTitleProps = ComponentProps<"div">;36
37const CardTitle = (props: CardTitleProps) => {38 const [local, others] = splitProps(props, ["class"]);39 return (40 <div41 data-slot="card-title"42 class={cn("z-card-title z-font-heading", local.class)}43 {...others}44 />45 );46};47
48type CardDescriptionProps = ComponentProps<"div">;49
50const CardDescription = (props: CardDescriptionProps) => {51 const [local, others] = splitProps(props, ["class"]);52 return (53 <div data-slot="card-description" class={cn("z-card-description", local.class)} {...others} />54 );55};56
57type CardActionProps = ComponentProps<"div">;58
59const CardAction = (props: CardActionProps) => {60 const [local, others] = splitProps(props, ["class"]);61 return (62 <div63 data-slot="card-action"64 class={cn(65 "z-card-action col-start-2 row-span-2 row-start-1 self-start justify-self-end",66 local.class,67 )}68 {...others}69 />70 );71};72
73type CardContentProps = ComponentProps<"div">;74
75const CardContent = (props: CardContentProps) => {76 const [local, others] = splitProps(props, ["class"]);77 return <div data-slot="card-content" class={cn("z-card-content", local.class)} {...others} />;78};79
80type CardFooterProps = ComponentProps<"div">;81
82const CardFooter = (props: CardFooterProps) => {83 const [local, others] = splitProps(props, ["class"]);84 return (85 <div86 data-slot="card-footer"87 class={cn("z-card-footer flex items-center", local.class)}88 {...others}89 />90 );91};92
93export { Card, CardAction, CardContent, CardDescription, CardFooter, CardHeader, CardTitle };Here are the source code of all the examples from the preview page:
import { Button } from "~/components/ui/button";import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle,} from "~/components/ui/card";function CardDefault() { return ( <Example title="Default Size"> <Card size="default" class="mx-auto w-full max-w-sm"> <CardHeader> <CardTitle>Default Card</CardTitle> <CardDescription>This card uses the default size variant.</CardDescription> </CardHeader> <CardContent> <p> The card component supports a size prop that defaults to "default" for standard spacing and sizing. </p> </CardContent> <CardFooter> <Button variant="outline" class="w-full"> Action </Button> </CardFooter> </Card> </Example> );}import { Button } from "~/components/ui/button";import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle,} from "~/components/ui/card";function CardSmall() { return ( <Example title="Small Size"> <Card size="sm" class="mx-auto w-full max-w-sm"> <CardHeader> <CardTitle>Small Card</CardTitle> <CardDescription>This card uses the small size variant.</CardDescription> </CardHeader> <CardContent> <p> The card component supports a size prop that can be set to "sm" for a more compact appearance. </p> </CardContent> <CardFooter> <Button variant="outline" size="sm" class="w-full"> Action </Button> </CardFooter> </Card> </Example> );}import { Card, CardContent, CardDescription, CardHeader, CardTitle,} from "~/components/ui/card";function CardHeaderWithBorder() { return ( <Example title="Header with Border"> <Card class="mx-auto w-full max-w-sm"> <CardHeader class="border-b"> <CardTitle>Header with Border</CardTitle> <CardDescription>This is a card with a header that has a bottom border.</CardDescription> </CardHeader> <CardContent> <p> The header has a border-b class applied, creating a visual separation between the header and content sections. </p> </CardContent> </Card> </Example> );}import { Button } from "~/components/ui/button";import { Card, CardContent, CardFooter,} from "~/components/ui/card";function CardFooterWithBorder() { return ( <Example title="Footer with Border"> <Card class="mx-auto w-full max-w-sm"> <CardContent> <p> The footer has a border-t class applied, creating a visual separation between the content and footer sections. </p> </CardContent> <CardFooter class="border-t"> <Button variant="outline" class="w-full"> Footer with Border </Button> </CardFooter> </Card> </Example> );}import { Card, CardContent, CardDescription, CardHeader, CardTitle,} from "~/components/ui/card";function CardHeaderWithBorderSmall() { return ( <Example title="Header with Border (Small)"> <Card size="sm" class="mx-auto w-full max-w-sm"> <CardHeader class="border-b"> <CardTitle>Header with Border</CardTitle> <CardDescription> This is a small card with a header that has a bottom border. </CardDescription> </CardHeader> <CardContent> <p> The header has a border-b class applied, creating a visual separation between the header and content sections. </p> </CardContent> </Card> </Example> );}import { Button } from "~/components/ui/button";import { Card, CardContent, CardFooter,} from "~/components/ui/card";function CardFooterWithBorderSmall() { return ( <Example title="Footer with Border (Small)"> <Card size="sm" class="mx-auto w-full max-w-sm"> <CardContent> <p> The footer has a border-t class applied, creating a visual separation between the content and footer sections. </p> </CardContent> <CardFooter class="border-t"> <Button variant="outline" size="sm" class="w-full"> Footer with Border </Button> </CardFooter> </Card> </Example> );}import Plus from "lucide-solid/icons/plus";import { Button } from "~/components/ui/button";import { Card, CardDescription, CardFooter, CardHeader, CardTitle,} from "~/components/ui/card";function CardWithImage() { return ( <Example title="With Image"> <Card size="default" class="relative mx-auto w-full max-w-sm pt-0"> <div class="absolute inset-0 z-30 aspect-video bg-primary opacity-50 mix-blend-color" /> <img src="https://images.unsplash.com/photo-1604076850742-4c7221f3101b?q=80&w=1887&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D" alt="Landscape by mymind on Unsplash" title="Landscape by mymind on Unsplash" class="relative z-20 aspect-video w-full object-cover brightness-60 grayscale" /> <CardHeader> <CardTitle>Beautiful Landscape</CardTitle> <CardDescription> A stunning view that captures the essence of natural beauty. </CardDescription> </CardHeader> <CardFooter> <Button class="w-full"> <Plus data-icon="inline-start" /> Button </Button> </CardFooter> </Card> </Example> );}import Plus from "lucide-solid/icons/plus";import { Button } from "~/components/ui/button";import { Card, CardDescription, CardFooter, CardHeader, CardTitle,} from "~/components/ui/card";function CardWithImageSmall() { return ( <Example title="With Image (Small)"> <Card size="sm" class="relative mx-auto w-full max-w-sm pt-0"> <div class="absolute inset-0 z-30 aspect-video bg-primary opacity-50 mix-blend-color" /> <img src="https://images.unsplash.com/photo-1604076850742-4c7221f3101b?q=80&w=1887&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D" alt="Landscape by mymind on Unsplash" title="Landscape by mymind on Unsplash" class="relative z-20 aspect-video w-full object-cover brightness-60 grayscale" /> <CardHeader> <CardTitle>Beautiful Landscape</CardTitle> <CardDescription> A stunning view that captures the essence of natural beauty. </CardDescription> </CardHeader> <CardFooter> <Button size="sm" class="w-full"> <Plus data-icon="inline-start" /> Button </Button> </CardFooter> </Card> </Example> );}import { Button } from "~/components/ui/button";import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle,} from "~/components/ui/card";import { Field, FieldGroup, FieldLabel } from "~/components/ui/field";import { Input } from "~/components/ui/input";function CardLogin() { return ( <Example title="Login"> <Card class="mx-auto w-full max-w-sm"> <CardHeader> <CardTitle>Login to your account</CardTitle> <CardDescription>Enter your email below to login to your account</CardDescription> </CardHeader> <CardContent> <form> <FieldGroup> <Field> <FieldLabel for="email">Email</FieldLabel> <Input id="email" type="email" placeholder="m@example.com" required /> </Field> <Field> <div class="flex items-center"> <FieldLabel for="password">Password</FieldLabel> <a href="#" class="ml-auto inline-block underline-offset-4 hover:underline"> Forgot your password? </a> </div> <Input id="password" type="password" required /> </Field> </FieldGroup> </form> </CardContent> <CardFooter class="flex-col gap-2"> <Button type="submit" class="w-full"> Login </Button> <Button variant="outline" class="w-full"> Login with Google </Button> <div class="mt-4 text-center"> Don't have an account?{" "} <a href="#" class="underline underline-offset-4"> Sign up </a> </div> </CardFooter> </Card> </Example> );}import Captions from "lucide-solid/icons/captions";import { Avatar, AvatarFallback, AvatarGroup, AvatarGroupCount, AvatarImage,} from "~/components/ui/avatar";import { Button } from "~/components/ui/button";import { Card, CardAction, CardContent, CardDescription, CardFooter, CardHeader, CardTitle,} from "~/components/ui/card";function CardMeetingNotes() { return ( <Example title="Meeting Notes"> <Card class="mx-auto w-full max-w-sm"> <CardHeader> <CardTitle>Meeting Notes</CardTitle> <CardDescription>Transcript from the meeting with the client.</CardDescription> <CardAction> <Button variant="outline" size="sm"> <Captions data-icon="inline-start" /> Transcribe </Button> </CardAction> </CardHeader> <CardContent> <p>Client requested dashboard redesign with focus on mobile responsiveness.</p> <ol class="mt-4 flex list-decimal flex-col gap-2 pl-6"> <li>New analytics widgets for daily/weekly metrics</li> <li>Simplified navigation menu</li> <li>Dark mode support</li> <li>Timeline: 6 weeks</li> <li>Follow-up meeting scheduled for next Tuesday</li> </ol> </CardContent> <CardFooter> <AvatarGroup> <Avatar> <AvatarImage src="https://github.com/shadcn.png" alt="@shadcn" /> <AvatarFallback>CN</AvatarFallback> </Avatar> <Avatar> <AvatarImage src="https://github.com/maxleiter.png" alt="@maxleiter" /> <AvatarFallback>LR</AvatarFallback> </Avatar> <Avatar> <AvatarImage src="https://github.com/evilrabbit.png" alt="@evilrabbit" /> <AvatarFallback>ER</AvatarFallback> </Avatar> <AvatarGroupCount>+8</AvatarGroupCount> </AvatarGroup> </CardFooter> </Card> </Example> );}