# Card

<FrameworkCodeSwitcher>
  <div slot="astro">
```astro
---
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from "@/components/starwind/card";
import { Button } from "@/components/starwind/button";
import { Input } from "@/components/starwind/input";
import { Label } from "@/components/starwind/label";
import { Select, SelectTrigger, SelectValue, SelectContent, SelectItem, SelectGroup, SelectLabel, SelectSeparator, } from "@/components/starwind/select";
---

<Card class="w-[360px]" slot="preview">
  <CardHeader>
    <CardTitle>Create project</CardTitle>
    <CardDescription>Deploy your new project in one-click.</CardDescription>
  </CardHeader>
  <CardContent class="flex flex-col gap-4">
    <div class="flex w-full flex-col gap-2">
      <Label for="project-name">Name</Label>
      <Input type="text" id="project-name" placeholder="Name of your project" />
    </div>
    <div class="flex w-full flex-col gap-2">
      <Label for="project-framework">Framework</Label>
      <Select name="framework" required>
        <SelectTrigger id="project-framework" class="w-full">
          <SelectValue placeholder="Select" />
        </SelectTrigger>
        <SelectContent>
          <SelectGroup>
            <SelectLabel>Frameworks</SelectLabel>
            <SelectItem value="astro">Astro</SelectItem>
            <SelectItem value="next">Next.js</SelectItem>
            <SelectItem value="svelte">SvelteKit</SelectItem>
            <SelectItem value="solid">SolidStart</SelectItem>
          </SelectGroup>
        </SelectContent>
      </Select>
    </div>
  </CardContent>
  <CardFooter class="flex justify-between">
    <Button variant="outline">Cancel</Button>
    <Button type="submit">Deploy</Button>
  </CardFooter>
</Card>
```
  </div>
  <div slot="react">
```tsx
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from "@/components/starwind/card";
import { Button } from "@/components/starwind/button";
import { Input } from "@/components/starwind/input";
import { Label } from "@/components/starwind/label";
import { Select, SelectTrigger, SelectValue, SelectContent, SelectItem, SelectGroup, SelectLabel, SelectSeparator, } from "@/components/starwind/select";

export function Example() {
  return (
    <Card className="w-[360px]">
      <CardHeader>
        <CardTitle>Create project</CardTitle>
        <CardDescription>Deploy your new project in one-click.</CardDescription>
      </CardHeader>
      <CardContent className="flex flex-col gap-4">
        <div className="flex w-full flex-col gap-2">
          <Label htmlFor="project-name">Name</Label>
          <Input type="text" id="project-name" placeholder="Name of your project" />
        </div>
        <div className="flex w-full flex-col gap-2">
          <Label htmlFor="project-framework">Framework</Label>
          <Select name="framework" required>
            <SelectTrigger id="project-framework" className="w-full">
              <SelectValue placeholder="Select" />
            </SelectTrigger>
            <SelectContent>
              <SelectGroup>
                <SelectLabel>Frameworks</SelectLabel>
                <SelectItem value="astro">Astro</SelectItem>
                <SelectItem value="next">Next.js</SelectItem>
                <SelectItem value="svelte">SvelteKit</SelectItem>
                <SelectItem value="solid">SolidStart</SelectItem>
              </SelectGroup>
            </SelectContent>
          </Select>
        </div>
      </CardContent>
      <CardFooter className="flex justify-between">
        <Button variant="outline">Cancel</Button>
        <Button type="submit">Deploy</Button>
      </CardFooter>
    </Card>
  );
}
```
  </div>
</FrameworkCodeSwitcher>

> **Info:** `required`, `name`, and the selected value now belong to the Runtime-backed `Select` root. The
trigger keeps the `id` referenced by the label.

## Installation

```bash
npx starwind@latest add card
```

## Usage

### Form Submission

You can easily add a standard html form submission to your card. Here is a full example with the javascript submission code.

> **Tip:** Open up your browser's dev tools and view the console to see the form data.

```astro
---
import { Button } from "@/components/starwind/button";
import {
  Card,
  CardContent,
  CardDescription,
  CardFooter,
  CardHeader,
  CardTitle,
} from "@/components/starwind/card";
import { Input } from "@/components/starwind/input";
import { Label } from "@/components/starwind/label";
import {
  Select,
  SelectContent,
  SelectGroup,
  SelectItem,
  SelectLabel,
  SelectTrigger,
  SelectValue,
} from "@/components/starwind/select";
---

<Card class="w-[360px]">
  <CardHeader>
    <CardTitle>Create project</CardTitle>
    <CardDescription>Deploy your new project in one-click.</CardDescription>
  </CardHeader>
  <form id="create-project-form">
    <CardContent class="flex flex-col gap-4">
      <div class="flex w-full flex-col gap-2">
        <Label for="create-project-name">Name</Label>
        <Input
          type="text"
          id="create-project-name"
          name="name"
          placeholder="Name of your project"
          required
        />
      </div>
      <div class="flex w-full flex-col gap-2">
        <Label for="create-project-framework">Framework</Label>
        <Select name="framework" required>
          <SelectTrigger id="create-project-framework" class="w-full">
            <SelectValue placeholder="Select" />
          </SelectTrigger>
          <SelectContent>
            <SelectGroup>
              <SelectLabel>Frameworks</SelectLabel>
              <SelectItem value="astro">Astro</SelectItem>
              <SelectItem value="next">Next.js</SelectItem>
              <SelectItem value="svelte">SvelteKit</SelectItem>
              <SelectItem value="solid">SolidStart</SelectItem>
            </SelectGroup>
          </SelectContent>
        </Select>
      </div>
    </CardContent>
    <CardFooter class="mt-6 flex justify-between">
      <Button type="button" variant="outline">Cancel</Button>
      <Button type="submit">Deploy</Button>
    </CardFooter>
  </form>
</Card>

<script>
  const setupForm = () => {
    const form = document.getElementById("create-project-form") as HTMLFormElement;
    if (!form) return;

    form.addEventListener("submit", (e) => {
      e.preventDefault();

      console.log(
        "Form submission data:",
        Object.fromEntries(new FormData(form).entries()),
      );
    });
  };

  setupForm();

  document.addEventListener("astro:after-swap", setupForm);
</script>
```

> **Info:** The Runtime-backed Select participates in native form submission through its `name` prop. Reading
`FormData` now captures both the text input and Select value without querying Select's internal
markup.

### Size

Use the `size="sm"` prop to set the size of the card to small. The small size variant uses smaller spacing.

```astro
---
import { Button } from "@/components/starwind/button";
import {
  Card,
  CardContent,
  CardDescription,
  CardFooter,
  CardHeader,
  CardTitle,
} from "@/components/starwind/card";
---

<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>
```

### Image

Add an image before the card header to create a card with an image. Use the `CardAction` component to position a badge or other action in the header.

```astro
---
import { Button } from "@/components/starwind/button";
import { Badge } from "@/components/starwind/badge";
import {
  Card,
  CardAction,
  CardDescription,
  CardFooter,
  CardHeader,
  CardTitle,
} from "@/components/starwind/card";
---

<Card class="relative mx-auto w-full max-w-sm">
  <img
    src="https://images.unsplash.com/photo-1540575467063-178a50c2df87?w=600&h=400&fit=crop"
    alt="Event cover"
    class="aspect-video w-full object-cover"
  />
  <CardHeader>
    <CardAction>
      <Badge size="sm" variant="primary">Featured</Badge>
    </CardAction>
    <CardTitle>Design systems meetup</CardTitle>
    <CardDescription>
      A practical talk on component APIs, accessibility, and shipping faster.
    </CardDescription>
  </CardHeader>
  <CardFooter>
    <Button class="w-full">View Event</Button>
  </CardFooter>
</Card>
```

## Framework Availability
Card is available for Astro and React.
Astro available; React available
| Framework | Status | Notes |
| --- | --- | --- |
| Astro | available | - |
| React | available | - |
## API Reference
### Card
| Prop | Type | Required | Default | Kind | Description |
| --- | --- | --- | --- | --- | --- |
| `size` | `"default" \| "sm"` | No | `"default"` | Styled variant | Selects the component's visual size. |
- Inherits div attributes.

### CardHeader
- Inherits div attributes.

### CardTitle
- Inherits div attributes.

### CardDescription
- Inherits div attributes.

### CardContent
- Inherits div attributes.

### CardFooter
- Inherits div attributes.

### CardAction
- Inherits div attributes.

## Changelog

### v2.1.0

- Added contract-generated Astro and React implementations while preserving the component's existing public API and styling.

### v2.0.2 

- Refactor tailwind variants functions into separate `variants.ts` file

### v2.0.0

- Added `size` prop to Card component (`"default"` | `"sm"`)
- Added `CardAction` component for positioning actions in card headers
- Added support for images within cards with automatic rounded corners
- Update styling to more closely match the shadcn/ui card component

### v1.3.0 

- style updates

### v1.2.0

- Add a `data-slot` attribute to all components to enable global styling updates

### v1.1.0

- `tailwind-variants` now implemented. This uses `tailwind-merge` under the hood to merge Tailwind classes without style conflicts, allowing you to override any existing classes using the "class" prop.