kosori

Card

A content container for grouping related information.

Card composes Base UI's useRender and mergeProps into a header, panel, footer and action layout, with CardFrame variants for framed groups. Every part marks itself with data-slot, and CardContent is exported as an alias of CardPanel.

Installation

npx shadcn@latest add @kosori/card

Example

card-example.tsx
Create project
Deploy your new project in one-click.

This will take a few seconds to complete.

card-example
'use client';

import { IconAlertCircle } from '@tabler/icons-react';
import type React from 'react';

import { Button } from '@/components/ui/button';
import {
  Card,
  CardDescription,
  CardFooter,
  CardHeader,
  CardPanel,
  CardTitle,
} from '@/components/ui/card';
import { Field, FieldLabel } from '@/components/ui/field';
import { Form } from '@/components/ui/form';
import { Input } from '@/components/ui/input';
import {
  Select,
  SelectItem,
  SelectPopup,
  SelectTrigger,
  SelectValue,
} from '@/components/ui/select';

const frameworkOptions = [
  { label: 'Next.js', value: 'next' },
  { label: 'Vite', value: 'vite' },
  { label: 'Remix', value: 'remix' },
  { label: 'Astro', value: 'astro' },
];

/** Stop the demo form from navigating so the preview stays on the page. */
const preventSubmit: React.FormEventHandler<HTMLFormElement> = (event) => {
  event.preventDefault();
};

const CardExample = () => (
  <Card className='w-full max-w-xs'>
    <CardHeader>
      <CardTitle>Create project</CardTitle>
      <CardDescription>Deploy your new project in one-click.</CardDescription>
    </CardHeader>
    <CardPanel>
      <Form className='flex w-full flex-col gap-4' onSubmit={preventSubmit}>
        <Field>
          <FieldLabel>Name</FieldLabel>
          <Input placeholder='Name of your project' type='text' />
        </Field>
        <Field>
          <FieldLabel>Framework</FieldLabel>
          <Select defaultValue='next' items={frameworkOptions}>
            <SelectTrigger>
              <SelectValue />
            </SelectTrigger>
            <SelectPopup>
              {frameworkOptions.map(({ label, value }) => (
                <SelectItem key={value} value={value}>
                  {label}
                </SelectItem>
              ))}
            </SelectPopup>
          </Select>
        </Field>
        <Button className='w-full' type='submit'>
          Deploy
        </Button>
      </Form>
    </CardPanel>
    <CardFooter>
      <div className='flex gap-1 text-muted-foreground text-xs'>
        <IconAlertCircle className='size-3 h-lh shrink-0' />
        <p>This will take a few seconds to complete.</p>
      </div>
    </CardFooter>
  </Card>
);

export default CardExample;

Usage

import {
  Card,
  CardDescription,
  CardHeader,
  CardPanel,
  CardTitle,
} from '@/components/ui/card';

const CardDemo = () => (
  <Card className='w-full max-w-xs'>
    <CardHeader>
      <CardTitle>Create project</CardTitle>
      <CardDescription>Deploy your project in one click.</CardDescription>
    </CardHeader>
    <CardPanel>Card content</CardPanel>
  </Card>
);

On this page