# Use the Shadcn UI components in the Tanstack Start Supabase SaaS kit

> Learn how to use the Shadcn UI components in the Tanstack Start Supabase SaaS kit for building custom UIs

*Canonical: https://makerkit.dev/docs/tanstack-supabase/components/shadcn*

---

Makerkit uses [Shadcn UI](https://ui.shadcn.com) for its UI components. You can use the components in your Tanstack Start Supabase SaaS kit.

In this page, we showcase the components available in Makerkit and how to use them in your Tanstack Start Supabase SaaS kit. Most of these examples were taken from the Shadcn UI docs, however, we've updated the paths to reflect the path in the kit.

The components are located at `packages/ui/src/shadcn`. They are exported as named exports, so you can import them directly from the package `@kit/ui`.

## Accordion

The `Accordion` component is a collapsible container that allows users to expand and collapse content. It is a great way to organize and present information in a clear and concise manner.

{% component path="shadcn/accordion" /%}

```tsx
import { Accordion, AccordionItem } from '@kit/ui/accordion';

function MyAccordion() {
  return (
    <Accordion>
      <AccordionItem title="Section 1">
        <p>Content for Section 1</p>
      </AccordionItem>
      <AccordionItem title="Section 2">
        <p>Content for Section 2</p>
      </AccordionItem>
    </Accordion>
  );
}
```

## Alert

The `Alert` component is a visually distinctive and informative message that alerts users of important information or actions.

### Default Alert

The default alert component is a versatile and customizable way to display messages to users. It can be used for success, warning, error, or informational purposes.

{% component path="shadcn/alert/default-alert" /%}

```tsx
import { InfoIcon } from 'lucide-react';

import { Alert, AlertDescription, AlertTitle } from '@kit/ui/alert';

export default function DefaultAlertDemo() {
  return (
    <Alert>
      <InfoIcon className="h-5 w-5" />

      <AlertTitle>
        <span>This is a default alert</span>
      </AlertTitle>

      <AlertDescription>This is the description of the alert.</AlertDescription>
    </Alert>
  );
}
```

### Info / Success / Warning Alerts

Makerkit ships a companion token map for non-upstream tones. Apply via `className` so that `packages/ui/src/shadcn/alert.tsx` stays upstream-equivalent and CLI-replaceable. See [Customizing Shadcn Primitives](customizing-shadcn-primitives) for the full rationale.

{% component path="shadcn/alert/info-alert" /%}

```tsx
import { CheckCircleIcon, InfoIcon, TriangleAlertIcon } from 'lucide-react';

import { Alert, AlertDescription, AlertTitle } from '@kit/ui/alert';
import { alertExtras } from '@kit/ui/alert-extras';

export default function NonUpstreamAlertsDemo() {
  return (
    <div className="flex flex-col gap-4">
      <Alert className={alertExtras.info}>
        <InfoIcon className="h-5 w-5" />
        <AlertTitle>This is an info alert</AlertTitle>
        <AlertDescription>This is the description of the alert.</AlertDescription>
      </Alert>

      <Alert className={alertExtras.success}>
        <CheckCircleIcon className="h-5 w-5" />
        <AlertTitle>This is a success alert</AlertTitle>
        <AlertDescription>This is the description of the alert.</AlertDescription>
      </Alert>

      <Alert className={alertExtras.warning}>
        <TriangleAlertIcon className="h-5 w-5" />
        <AlertTitle>This is a warning alert</AlertTitle>
        <AlertDescription>This is the description of the alert.</AlertDescription>
      </Alert>
    </div>
  );
}
```

### Destructive Alert

For error alerts, use the `error` variant.

{% component path="shadcn/alert/destructive-alert" /%}

```tsx
import { XCircleIcon } from 'lucide-react';

import { Alert, AlertDescription, AlertTitle } from '@kit/ui/alert';

export default function ErrorAlertDemo() {
  return (
    <Alert variant={'destructive'}>
      <XCircleIcon className="h-5 w-5" />

      <AlertTitle>
        <span>This is an error alert</span>
      </AlertTitle>

      <AlertDescription>
        This is the description of the alert.
      </AlertDescription>
    </Alert>
  );
}
```

## AlertDialog

The `AlertDialog` component is a modal dialog that displays an alert message and provides an action to the user. It is a versatile and customizable way to display messages to users.

{% component path="shadcn/alert-dialog" /%}

```tsx
import {
  AlertDialog,
  AlertDialogAction,
  AlertDialogCancel,
  AlertDialogContent,
  AlertDialogDescription,
  AlertDialogFooter,
  AlertDialogHeader,
  AlertDialogTitle,
  AlertDialogTrigger,
} from '@kit/ui/alert-dialog';
import { Button } from '@kit/ui/button';

import WrapperComponent from '#/components/content/wrapper';

export default function AlertDialogDemo() {
  return (
    <WrapperComponent>
      <AlertDialog>
        <AlertDialogTrigger asChild>
          <Button variant="outline">Show Dialog</Button>
        </AlertDialogTrigger>
        <AlertDialogContent>
          <AlertDialogHeader>
            <AlertDialogTitle>Are you absolutely sure?</AlertDialogTitle>
            <AlertDialogDescription>
              This action cannot be undone. This will permanently delete your
              account and remove your data from our servers.
            </AlertDialogDescription>
          </AlertDialogHeader>
          <AlertDialogFooter>
            <AlertDialogCancel>Cancel</AlertDialogCancel>
            <AlertDialogAction>Continue</AlertDialogAction>
          </AlertDialogFooter>
        </AlertDialogContent>
      </AlertDialog>
    </WrapperComponent>
  );
}
```

For more information on the `AlertDialog` component, please refer to the [AlertDialog](https://ui.shadcn.com/docs/components/alert-dialog) documentation.

## Badge

The `Badge` component is a small label or tag that is displayed inline with other content. It is used to highlight important information or to indicate the status of an item.

{% component path="shadcn/badge" /%}

Use upstream `variant` values directly. For Makerkit's non-upstream tones (`info`, `success`, `warning`), apply the matching token from `@kit/ui/badge-extras` via `className`. See [Customizing Shadcn Primitives](customizing-shadcn-primitives) for the full rationale.

```tsx
import { Badge } from '@kit/ui/badge';
import { badgeExtras } from '@kit/ui/badge-extras';

function BadgeDemo() {
  return (
    <div className="flex flex-col gap-4">
      <div className="flex items-center gap-2">
        <Badge variant={'outline'}>Profile</Badge>
        <Badge variant={'outline'}>Settings</Badge>
        <Badge variant={'outline'}>Messages</Badge>
      </div>

      <div className="flex items-center gap-2">
        <Badge className={badgeExtras.info}>Info</Badge>
        <Badge className={badgeExtras.success}>Success</Badge>
        <Badge className={badgeExtras.warning}>Warning</Badge>
        <Badge variant={'destructive'}>Error</Badge>
      </div>
    </div>
  );
}
```

For more information on the `Badge` component, please refer to the [Badge](https://ui.shadcn.com/docs/components/badge) documentation.

## Breadcrumbs

The Breadcrumbs component is a navigational component that displays a list of links that represent the user's current location within a website or application. It is commonly used in multi-level navigation menus to provide a clear path for users to navigate back to previous pages.

{% component path="shadcn/breadcrumbs" /%}

```tsx
import {
  Breadcrumb,
  BreadcrumbEllipsis,
  BreadcrumbItem,
  BreadcrumbLink,
  BreadcrumbList,
  BreadcrumbPage,
  BreadcrumbSeparator,
} from '@kit/ui/breadcrumb';
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuTrigger,
} from '@kit/ui/dropdown-menu';

export default function BreadcrumbDemo() {
  return (
    <Breadcrumb>
      <BreadcrumbList>
        <BreadcrumbItem>
          <BreadcrumbLink href="/">Home</BreadcrumbLink>
        </BreadcrumbItem>
        <BreadcrumbSeparator />
        <BreadcrumbItem>
          <DropdownMenu>
            <DropdownMenuTrigger className="flex items-center gap-1">
              <BreadcrumbEllipsis className="h-4 w-4" />
              <span className="sr-only">Toggle menu</span>
            </DropdownMenuTrigger>
            <DropdownMenuContent align="start">
              <DropdownMenuItem>Documentation</DropdownMenuItem>
              <DropdownMenuItem>Themes</DropdownMenuItem>
              <DropdownMenuItem>GitHub</DropdownMenuItem>
            </DropdownMenuContent>
          </DropdownMenu>
        </BreadcrumbItem>
        <BreadcrumbSeparator />
        <BreadcrumbItem>
          <BreadcrumbLink href="/docs/components">Components</BreadcrumbLink>
        </BreadcrumbItem>
        <BreadcrumbSeparator />
        <BreadcrumbItem>
          <BreadcrumbPage>Breadcrumb</BreadcrumbPage>
        </BreadcrumbItem>
      </BreadcrumbList>
    </Breadcrumb>
  );
}
```

For more information on the `Breadcrumbs` component, please refer to the [Breadcrumbs](https://ui.shadcn.com/docs/components/breadcrumbs) documentation.

## Button

The `Button` component is a basic button component that can be used to trigger an action or event.

```tsx
import { Button } from '@kit/ui/button';

export default function ButtonDemo() {
  return (
    <Button>Button</Button>
  );
}
```

{% component path="shadcn/button" /%}

### Button Variants

The `Button` component comes with several variants that you can use to style your buttons. You can use the `variant` prop to change the appearance of the button.

{% component path="shadcn/button-variants" /%}

```tsx
import { Button } from '@kit/ui/button';

export default function ButtonDemo() {
  return (
    <Button variant="outline">Outline</Button>
    <Button variant="secondary">Secondary</Button>
    <Button variant="destructive">Destructive</Button>
  );
}
```

For more information on the `Button` component, please refer to the [Button](https://ui.shadcn.com/docs/components/button) documentation.

## Calendar

The `Calendar` component is a calendar component that allows users to select a date.

{% component path="shadcn/calendar" /%}


```tsx
import { Calendar } from '@kit/ui/calendar';

export default function CalendarDemo() {
  return (
    <Calendar />
  );
}
```

For more information on the `Calendar` component, please refer to the [Calendar](https://ui.shadcn.com/docs/components/calendar) documentation.

## Card

The `Card` component is a flexible and customizable card component that can be used to display content in a visually appealing way.

{% component path="shadcn/card" /%}

```tsx
import * as React from 'react';

import { Button } from '@kit/ui/button';
import {
  Card,
  CardContent,
  CardDescription,
  CardFooter,
  CardHeader,
  CardTitle,
} from '@kit/ui/card';
import { Input } from '@kit/ui/input';
import { Label } from '@kit/ui/label';
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from '@kit/ui/select';

export default function CardWithForm() {
  return (
    <Card className="w-[350px]">
      <CardHeader>
        <CardTitle>Create project</CardTitle>
        <CardDescription>Deploy your new project in one-click.</CardDescription>
      </CardHeader>

      <CardContent>
        <form>
          <div className="grid w-full items-center gap-4">
            <div className="flex flex-col space-y-1.5">
              <Label htmlFor="name">Name</Label>
              <Input id="name" placeholder="Name of your project" />
            </div>
            <div className="flex flex-col space-y-1.5">
              <Label htmlFor="framework">Framework</Label>
              <Select>
                <SelectTrigger id="framework">
                  <SelectValue placeholder="Select" />
                </SelectTrigger>
                <SelectContent position="popper">
                  <SelectItem value="next">Tanstack Start</SelectItem>
                  <SelectItem value="sveltekit">SvelteKit</SelectItem>
                  <SelectItem value="astro">Astro</SelectItem>
                  <SelectItem value="nuxt">Nuxt.js</SelectItem>
                </SelectContent>
              </Select>
            </div>
          </div>
        </form>
      </CardContent>

      <CardFooter className="flex justify-between">
        <Button variant="outline">Cancel</Button>
        <Button>Deploy</Button>
      </CardFooter>
    </Card>
  );
}
```

For more information on the `Card` component, please refer to the [Card](https://ui.shadcn.com/docs/components/card) documentation.

## Chart

Charts are built using Recharts, a powerful charting library that provides a wide range of customization options.

{% component path="shadcn/chart" /%}

For more information, please refer to the ShadcnUI documentation for the [Chart component](https://ui.shadcn.com/docs/components/chart).

## Checkbox

The `Checkbox` component is a simple and customizable checkbox component that allows users to select one or more options.

{% component path="shadcn/checkbox" /%}

```tsx
import { Checkbox } from '@kit/ui/checkbox';

export default function CheckboxDemo() {
  return (
    <div className="flex items-center space-x-2">
      <Checkbox id="terms" />

      <label
        htmlFor="terms"
        className="text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
      >
        Accept terms and conditions
      </label>
    </div>
  );
}
```

For more information on the `Checkbox` component, please refer to the [Checkbox](https://ui.shadcn.com/docs/components/checkbox) documentation.

## Command

The `Command` component is a powerful and customizable command palette component that allows users to access a wide range of commands and actions.

{% component path="shadcn/command" lazy="true" /%}

```tsx
import {
  Calculator,
  Calendar,
  CreditCard,
  Settings,
  Smile,
  User,
} from 'lucide-react';

import {
  Command,
  CommandEmpty,
  CommandGroup,
  CommandInput,
  CommandItem,
  CommandList,
  CommandSeparator,
  CommandShortcut,
} from '@kit/ui/command';

import WrapperComponent from '#/components/content/wrapper';

export default function CommandDemo() {
  return (
    <>
      <Command className="rounded-lg border shadow-md md:min-w-[450px]">
        <CommandInput placeholder="Type a command or search..." />
        <CommandList>
          <CommandEmpty>No results found.</CommandEmpty>
          <CommandGroup heading="Suggestions">
            <CommandItem>
              <Calendar />
              <span>Calendar</span>
            </CommandItem>
            <CommandItem>
              <Smile />
              <span>Search Emoji</span>
            </CommandItem>
            <CommandItem disabled>
              <Calculator />
              <span>Calculator</span>
            </CommandItem>
          </CommandGroup>
          <CommandSeparator />
          <CommandGroup heading="Settings">
            <CommandItem>
              <User />
              <span>Profile</span>
              <CommandShortcut>⌘P</CommandShortcut>
            </CommandItem>
            <CommandItem>
              <CreditCard />
              <span>Billing</span>
              <CommandShortcut>⌘B</CommandShortcut>
            </CommandItem>
            <CommandItem>
              <Settings />
              <span>Settings</span>
              <CommandShortcut>⌘S</CommandShortcut>
            </CommandItem>
          </CommandGroup>
        </CommandList>
      </Command>
    </>
  );
}
```

For more information on the `Command` component, please refer to the [Command](https://ui.shadcn.com/docs/components/command) documentation.

## Collapsible

The `Collapsible` component is a powerful and customizable collapsible component that allows users to expand and collapse content.

{% component path="shadcn/collapsible" /%}

```tsx
import * as React from 'react';

import { ChevronsUpDown } from 'lucide-react';

import { Button } from '@kit/ui/button';
import {
  Collapsible,
  CollapsibleContent,
  CollapsibleTrigger,
} from '@kit/ui/collapsible';

export default function CollapsibleDemo() {
  const [isOpen, setIsOpen] = React.useState(false);

  return (
    <>
      <Collapsible
        open={isOpen}
        onOpenChange={setIsOpen}
        className="w-[350px] space-y-2"
      >
        <div className="flex items-center justify-between space-x-4 px-4">
          <h4 className="text-sm font-semibold">
            @peduarte starred 3 repositories
          </h4>

          <CollapsibleTrigger asChild>
            <Button variant="ghost" size="sm">
              <ChevronsUpDown className="h-4 w-4" />
              <span className="sr-only">Toggle</span>
            </Button>
          </CollapsibleTrigger>
        </div>

        <div className="rounded-md border px-4 py-2 font-mono text-sm shadow-sm">
          @base-ui/primitives
        </div>

        <CollapsibleContent className="space-y-2">
          <div className="rounded-md border px-4 py-2 font-mono text-sm shadow-sm">
            @base-ui/colors
          </div>

          <div className="rounded-md border px-4 py-2 font-mono text-sm shadow-sm">
            @stitches/react
          </div>
        </CollapsibleContent>
      </Collapsible>
    </>
  );
}
```

For more information on how to use the Collapsible component, refer to the [Collapsible documentation](https://ui.shadcn.com/docs/components/collapsible).

## Data Table

The Data Table component uses TanStack React Table to display a table of data. It provides a flexible and customizable way to display data in a tabular format.

{% component path="shadcn/data-table" /%}

```tsx
import * as React from 'react';

import {
  ColumnDef,
  ColumnFiltersState,
  SortingState,
  VisibilityState,
  flexRender,
  getCoreRowModel,
  getFilteredRowModel,
  getPaginationRowModel,
  getSortedRowModel,
  useReactTable,
} from '@tanstack/react-table';
import { ArrowUpDown, ChevronDown, MoreHorizontal } from 'lucide-react';

import { Button } from '@kit/ui/button';
import { Checkbox } from '@kit/ui/checkbox';
import {
  DropdownMenu,
  DropdownMenuCheckboxItem,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuLabel,
  DropdownMenuSeparator,
  DropdownMenuTrigger,
} from '@kit/ui/dropdown-menu';
import { Input } from '@kit/ui/input';
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from '@kit/ui/table';

const data: Payment[] = [
  {
    id: 'm5gr84i9',
    amount: 316,
    status: 'success',
    email: 'ken99@yahoo.com',
  },
  {
    id: '3u1reuv4',
    amount: 242,
    status: 'success',
    email: 'Abe45@gmail.com',
  },
  {
    id: 'derv1ws0',
    amount: 837,
    status: 'processing',
    email: 'Monserrat44@gmail.com',
  },
  {
    id: '5kma53ae',
    amount: 874,
    status: 'success',
    email: 'Silas22@gmail.com',
  },
  {
    id: 'bhqecj4p',
    amount: 721,
    status: 'failed',
    email: 'carmella@hotmail.com',
  },
];

export type Payment = {
  id: string;
  amount: number;
  status: 'pending' | 'processing' | 'success' | 'failed';
  email: string;
};

export const columns: ColumnDef<Payment>[] = [
  {
    id: 'select',
    header: ({ table }) => (
      <Checkbox
        checked={
          table.getIsAllPageRowsSelected() ||
          (table.getIsSomePageRowsSelected() && 'indeterminate')
        }
        onCheckedChange={(value) => table.toggleAllPageRowsSelected(!!value)}
        aria-label="Select all"
      />
    ),
    cell: ({ row }) => (
      <Checkbox
        checked={row.getIsSelected()}
        onCheckedChange={(value) => row.toggleSelected(!!value)}
        aria-label="Select row"
      />
    ),
    enableSorting: false,
    enableHiding: false,
  },
  {
    accessorKey: 'status',
    header: 'Status',
    cell: ({ row }) => (
      <div className="capitalize">{row.getValue('status')}</div>
    ),
  },
  {
    accessorKey: 'email',
    header: ({ column }) => {
      return (
        <Button
          variant="ghost"
          onClick={() => column.toggleSorting(column.getIsSorted() === 'asc')}
        >
          Email
          <ArrowUpDown />
        </Button>
      );
    },
    cell: ({ row }) => <div className="lowercase">{row.getValue('email')}</div>,
  },
  {
    accessorKey: 'amount',
    header: () => <div className="text-right">Amount</div>,
    cell: ({ row }) => {
      const amount = parseFloat(row.getValue('amount'));

      // Format the amount as a dollar amount
      const formatted = new Intl.NumberFormat('en-US', {
        style: 'currency',
        currency: 'USD',
      }).format(amount);

      return <div className="text-right font-medium">{formatted}</div>;
    },
  },
  {
    id: 'actions',
    enableHiding: false,
    cell: ({ row }) => {
      const payment = row.original;

      return (
        <DropdownMenu>
          <DropdownMenuTrigger asChild>
            <Button variant="ghost" className="h-8 w-8 p-0">
              <span className="sr-only">Open menu</span>
              <MoreHorizontal />
            </Button>
          </DropdownMenuTrigger>
          <DropdownMenuContent align="end">
            <DropdownMenuLabel>Actions</DropdownMenuLabel>
            <DropdownMenuItem
              onClick={() => navigator.clipboard.writeText(payment.id)}
            >
              Copy payment ID
            </DropdownMenuItem>
            <DropdownMenuSeparator />
            <DropdownMenuItem>View customer</DropdownMenuItem>
            <DropdownMenuItem>View payment details</DropdownMenuItem>
          </DropdownMenuContent>
        </DropdownMenu>
      );
    },
  },
];

export default function DataTableDemo() {
  const [sorting, setSorting] = React.useState<SortingState>([]);
  const [columnFilters, setColumnFilters] = React.useState<ColumnFiltersState>(
    [],
  );
  const [columnVisibility, setColumnVisibility] =
    React.useState<VisibilityState>({});
  const [rowSelection, setRowSelection] = React.useState({});

  const table = useReactTable({
    data,
    columns,
    onSortingChange: setSorting,
    onColumnFiltersChange: setColumnFilters,
    getCoreRowModel: getCoreRowModel(),
    getPaginationRowModel: getPaginationRowModel(),
    getSortedRowModel: getSortedRowModel(),
    getFilteredRowModel: getFilteredRowModel(),
    onColumnVisibilityChange: setColumnVisibility,
    onRowSelectionChange: setRowSelection,
    state: {
      sorting,
      columnFilters,
      columnVisibility,
      rowSelection,
    },
  });

  return (
    <>
      <div className="w-full">
        <div className="flex items-center py-4">
          <Input
            placeholder="Filter emails..."
            value={(table.getColumn('email')?.getFilterValue() as string) ?? ''}
            onChange={(event) =>
              table.getColumn('email')?.setFilterValue(event.target.value)
            }
            className="max-w-sm"
          />
          <DropdownMenu>
            <DropdownMenuTrigger asChild>
              <Button variant="outline" className="ml-auto">
                Columns <ChevronDown />
              </Button>
            </DropdownMenuTrigger>
            <DropdownMenuContent align="end">
              {table
                .getAllColumns()
                .filter((column) => column.getCanHide())
                .map((column) => {
                  return (
                    <DropdownMenuCheckboxItem
                      key={column.id}
                      className="capitalize"
                      checked={column.getIsVisible()}
                      onCheckedChange={(value) =>
                        column.toggleVisibility(!!value)
                      }
                    >
                      {column.id}
                    </DropdownMenuCheckboxItem>
                  );
                })}
            </DropdownMenuContent>
          </DropdownMenu>
        </div>
        <div className="rounded-md border">
          <Table>
            <TableHeader>
              {table.getHeaderGroups().map((headerGroup) => (
                <TableRow key={headerGroup.id}>
                  {headerGroup.headers.map((header) => {
                    return (
                      <TableHead key={header.id}>
                        {header.isPlaceholder
                          ? null
                          : flexRender(
                              header.column.columnDef.header,
                              header.getContext(),
                            )}
                      </TableHead>
                    );
                  })}
                </TableRow>
              ))}
            </TableHeader>
            <TableBody>
              {table.getRowModel().rows?.length ? (
                table.getRowModel().rows.map((row) => (
                  <TableRow
                    key={row.id}
                    data-state={row.getIsSelected() && 'selected'}
                  >
                    {row.getVisibleCells().map((cell) => (
                      <TableCell key={cell.id}>
                        {flexRender(
                          cell.column.columnDef.cell,
                          cell.getContext(),
                        )}
                      </TableCell>
                    ))}
                  </TableRow>
                ))
              ) : (
                <TableRow>
                  <TableCell
                    colSpan={columns.length}
                    className="h-24 text-center"
                  >
                    No results.
                  </TableCell>
                </TableRow>
              )}
            </TableBody>
          </Table>
        </div>
        <div className="flex items-center justify-end space-x-2 py-4">
          <div className="flex-1 text-sm text-muted-foreground">
            {table.getFilteredSelectedRowModel().rows.length} of{' '}
            {table.getFilteredRowModel().rows.length} row(s) selected.
          </div>
          <div className="space-x-2">
            <Button
              variant="outline"
              size="sm"
              onClick={() => table.previousPage()}
              disabled={!table.getCanPreviousPage()}
            >
              Previous
            </Button>
            <Button
              variant="outline"
              size="sm"
              onClick={() => table.nextPage()}
              disabled={!table.getCanNextPage()}
            >
              Next
            </Button>
          </div>
        </div>
      </div>
    </>
  );
}
```

For more information on how to use the Data Table component, refer to the [Data Table documentation](/docs/tanstack-supabase/components/data-table).

For more information about Tanstack Table, refer to the [Tanstack Table documentation](https://tanstack.com/table/v8/docs/api/core/table).

## Dropdown Menu

The Dropdown Menu component is a customizable dropdown menu that can be used to display a list of options when a user interacts with a dropdown button. It is a versatile component that can be used in various contexts, such as navigation menus, dropdown menus, and more.

{% component path="shadcn/dropdown-menu" /%}

```tsx
import { Button } from '@kit/ui/button';
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuGroup,
  DropdownMenuItem,
  DropdownMenuLabel,
  DropdownMenuPortal,
  DropdownMenuSeparator,
  DropdownMenuShortcut,
  DropdownMenuSub,
  DropdownMenuSubContent,
  DropdownMenuSubTrigger,
  DropdownMenuTrigger,
} from '@kit/ui/dropdown-menu';

export default function DropdownMenuDemo() {
  return (
    <>
      <DropdownMenu>
        <DropdownMenuTrigger asChild>
          <Button variant="outline">Open</Button>
        </DropdownMenuTrigger>
        <DropdownMenuContent className="w-56">
          <DropdownMenuLabel>My Account</DropdownMenuLabel>
          <DropdownMenuSeparator />
          <DropdownMenuGroup>
            <DropdownMenuItem>
              Profile
              <DropdownMenuShortcut>⇧⌘P</DropdownMenuShortcut>
            </DropdownMenuItem>
            <DropdownMenuItem>
              Billing
              <DropdownMenuShortcut>⌘B</DropdownMenuShortcut>
            </DropdownMenuItem>
            <DropdownMenuItem>
              Settings
              <DropdownMenuShortcut>⌘S</DropdownMenuShortcut>
            </DropdownMenuItem>
            <DropdownMenuItem>
              Keyboard shortcuts
              <DropdownMenuShortcut>⌘K</DropdownMenuShortcut>
            </DropdownMenuItem>
          </DropdownMenuGroup>
          <DropdownMenuSeparator />
          <DropdownMenuGroup>
            <DropdownMenuItem>Team</DropdownMenuItem>
            <DropdownMenuSub>
              <DropdownMenuSubTrigger>Invite users</DropdownMenuSubTrigger>
              <DropdownMenuPortal>
                <DropdownMenuSubContent>
                  <DropdownMenuItem>Email</DropdownMenuItem>
                  <DropdownMenuItem>Message</DropdownMenuItem>
                  <DropdownMenuSeparator />
                  <DropdownMenuItem>More...</DropdownMenuItem>
                </DropdownMenuSubContent>
              </DropdownMenuPortal>
            </DropdownMenuSub>
            <DropdownMenuItem>
              New Team
              <DropdownMenuShortcut>⌘+T</DropdownMenuShortcut>
            </DropdownMenuItem>
          </DropdownMenuGroup>
          <DropdownMenuSeparator />
          <DropdownMenuItem>GitHub</DropdownMenuItem>
          <DropdownMenuItem>Support</DropdownMenuItem>
          <DropdownMenuItem disabled>API</DropdownMenuItem>
          <DropdownMenuSeparator />
          <DropdownMenuItem>
            Log out
            <DropdownMenuShortcut>⇧⌘Q</DropdownMenuShortcut>
          </DropdownMenuItem>
        </DropdownMenuContent>
      </DropdownMenu>
    </>
  );
}
```

For more information on how to use the Dropdown Menu component, refer to the [Dropdown Menu documentation](https://ui.shadcn.com/docs/components/dropdown-menu).

## Form

The `Form` component wraps `react-hook-form` and provides a simple and customizable form component.

{% component path="shadcn/form" /%}

```tsx
import { useForm } from 'react-hook-form';
import { Button } from '@kit/ui/button';

import {
  Form,
  FormControl,
  FormDescription,
  FormField,
  FormItem,
  FormLabel,
  FormMessage,
} from '@kit/ui/form';
import { Input } from '@kit/ui/input';
import { Textarea } from '@kit/ui/textarea';

export default function FormDemo() {
  const form = useForm({
    defaultValues: {
      name: 'John Doe',
      email: 'john@doe.com',
      message: 'Hello, world!',
    },
  });

  return (
    <>
      <Form {...form}>
        <form
          className="flex flex-col space-y-4"
          onSubmit={form.handleSubmit((data) => {
            console.log(data);
          })}
        >
          <FormField
            name="name"
            render={({ field }) => (
              <FormItem>
                <FormLabel>Name</FormLabel>
                <FormControl>
                  <Input {...field} type="text" placeholder="Enter your name" />
                </FormControl>
                <FormDescription>Please enter your name.</FormDescription>
                <FormMessage />
              </FormItem>
            )}
          />

          <FormField
            name="email"
            render={({ field }) => (
              <FormItem>
                <FormLabel>Email</FormLabel>
                <FormControl>
                  <Input
                    {...field}
                    type="email"
                    placeholder="Enter your email"
                  />
                </FormControl>
                <FormDescription>Please enter your email.</FormDescription>
                <FormMessage />
              </FormItem>
            )}
          />

          <FormField
            name="message"
            render={({ field }) => (
              <FormItem>
                <FormLabel>Message</FormLabel>
                <FormControl>
                  <Textarea {...field} placeholder="Enter your message" />
                </FormControl>
                <FormDescription>Please enter your message.</FormDescription>
                <FormMessage />
              </FormItem>
            )}
          />

          <div className="flex justify-end">
            <Button type="submit">Submit</Button>
          </div>
        </form>
      </Form>
    </>
  );
}
```

For more information on how to use the Form component, refer to the [Form documentation](https://ui.shadcn.com/docs/components/form).

## Heading

The `Heading` component is a reusable component for rendering headings with different levels.

{% component path="shadcn/heading" /%}

```tsx
import { Heading } from '@kit/ui/heading';

function HeadingDemo() {
  return (
    <>
      <Heading level={1}>Heading 1</Heading>
      <Heading level={2}>Heading 2</Heading>
      <Heading level={3}>Heading 3</Heading>
      <Heading level={4}>Heading 4</Heading>
      <Heading level={5}>Heading 5</Heading>
      <Heading level={6}>Heading 6</Heading>
    </>
  );
}
```

For more information on how to use the Heading component, refer to the [Heading documentation](https://ui.shadcn.com/docs/components/heading).

## Input

The `Input` component is a customizable input field component that allows users to enter text.

{% component path="shadcn/input" /%}

```tsx
import { Input } from '@kit/ui/input';

function InputDemo() {
  return (
    <div className="flex flex-col space-y-4">
      <Input placeholder="Enter your name" />
      <Input type="email" placeholder="Enter your email" />
      <Input type="password" placeholder="Enter your password" />
      <Input type="number" placeholder="Enter your age" />
      <Input type="tel" placeholder="Enter your phone number" />
      <Input type="url" placeholder="Enter your website URL" />
    </div>
  );
}
```

For more information on how to use the Input component, refer to the [Input documentation](https://ui.shadcn.com/docs/components/input).

## Input OTP

The `InputOTP` component is a customizable input field component that allows users to enter one-time passwords.

{% component path="shadcn/input-otp" /%}

```tsx
import {
  InputOTP,
  InputOTPGroup,
  InputOTPSeparator,
  InputOTPSlot,
} from '@kit/ui/input-otp';

export default function InputOTPDemo() {
  return (
    <div>
      <InputOTP maxLength={6}>
        <InputOTPGroup>
          <InputOTPSlot index={0} />
          <InputOTPSlot index={1} />
          <InputOTPSlot index={2} />
        </InputOTPGroup>
        <InputOTPSeparator />
        <InputOTPGroup>
          <InputOTPSlot index={3} />
          <InputOTPSlot index={4} />
          <InputOTPSlot index={5} />
        </InputOTPGroup>
      </InputOTP>
    </div>
  );
}
```

For more information on how to use the Input OTP component, refer to the [Input OTP documentation](https://ui.shadcn.com/docs/components/input-otp).

## Label

The `Label` component is a reusable component for rendering labels with different styles.

{% component path="shadcn/label" /%}

```tsx
import { Checkbox } from '@kit/ui/checkbox';
import { Label } from '@kit/ui/label';

import WrapperComponent from '#/components/content/wrapper';

export default function LabelDemo() {
  return (
    <div>
      <div className="flex items-center space-x-2">
        <Checkbox id="terms" />
        <Label htmlFor="terms">Accept terms and conditions</Label>
      </div>
    </WrapperComponent>
  );
}
```

For more information on how to use the Label component, refer to the [Label documentation](https://ui.shadcn.com/docs/components/label).

## Navigation Menu

The navigation menu component is a wrapper around the [Base UI Navigation Menu](https://base-ui.com/react/components/navigation-menu) component.

{% component path="shadcn/navigation-menu.tsx" /%}

```tsx
import {
  NavigationMenu,
  NavigationMenuContent,
  NavigationMenuItem,
  NavigationMenuLink,
  NavigationMenuList,
  NavigationMenuTrigger,
} from '@kit/ui/navigation-menu';

export default function NavigationMenuDemo() {
  return (
    <div>
      <NavigationMenu>
        <NavigationMenuList>
          <NavigationMenuItem>
            <NavigationMenuTrigger>Item One</NavigationMenuTrigger>

            <NavigationMenuContent>
              <NavigationMenuLink>Link</NavigationMenuLink>
            </NavigationMenuContent>
          </NavigationMenuItem>
        </NavigationMenuList>
      </NavigationMenu>
    </div>
  );
}
```

For more information on how to use the Navigation Menu component, refer to the [Navigation Menu documentation](https://ui.shadcn.com/docs/components/navigation-menu).

## Popover

THe Popover component helps you create a floating element that floats around a reference element.

{% component path="shadcn/popover.tsx" /%}

```tsx
import { Button } from '@kit/ui/button';
import { Input } from '@kit/ui/input';
import { Label } from '@kit/ui/label';
import { Popover, PopoverContent, PopoverTrigger } from '@kit/ui/popover';

export default function PopoverDemo() {
  return (
    <div>
      <div className="flex flex-col gap-4 items-center justify-center">
        <Popover>
          <PopoverTrigger asChild>
            <Button variant="outline">Open popover</Button>
          </PopoverTrigger>

          <PopoverContent className="w-80">
            <div className="grid gap-4">
              <div className="space-y-2">
                <h4 className="font-medium leading-none">Dimensions</h4>
                <p className="text-sm text-muted-foreground">
                  Set the dimensions for the layer.
                </p>
              </div>
              <div className="grid gap-2">
                <div className="grid grid-cols-3 items-center gap-4">
                  <Label htmlFor="width">Width</Label>
                  <Input
                    id="width"
                    defaultValue="100%"
                    className="col-span-2 h-8"
                  />
                </div>
                <div className="grid grid-cols-3 items-center gap-4">
                  <Label htmlFor="maxWidth">Max. width</Label>
                  <Input
                    id="maxWidth"
                    defaultValue="300px"
                    className="col-span-2 h-8"
                  />
                </div>
                <div className="grid grid-cols-3 items-center gap-4">
                  <Label htmlFor="height">Height</Label>
                  <Input
                    id="height"
                    defaultValue="25px"
                    className="col-span-2 h-8"
                  />
                </div>
                <div className="grid grid-cols-3 items-center gap-4">
                  <Label htmlFor="maxHeight">Max. height</Label>
                  <Input
                    id="maxHeight"
                    defaultValue="none"
                    className="col-span-2 h-8"
                  />
                </div>
              </div>
            </div>
          </PopoverContent>
        </Popover>
      </div>
    </div>
  );
}
```

For more information on how to use the Popover component, refer to the [Popover documentation](https://ui.shadcn.com/docs/components/popover).

## Radio Group

The Radio Group component is a wrapper around the `Radio` component. It provides a more convenient way to work with radio buttons.

{% component path="shadcn/radio-group" /%}

```tsx
import { Label } from '@kit/ui/label';
import { RadioGroup, RadioGroupItem } from '@kit/ui/radio-group';

export default function RadioGroupDemo() {
  return (
    <RadioGroup defaultValue="comfortable">
      <div className="flex items-center space-x-2">
        <RadioGroupItem value="default" id="r1" />
        <Label htmlFor="r1">Default</Label>
      </div>
      <div className="flex items-center space-x-2">
        <RadioGroupItem value="comfortable" id="r2" />
        <Label htmlFor="r2">Comfortable</Label>
      </div>
      <div className="flex items-center space-x-2">
        <RadioGroupItem value="compact" id="r3" />
        <Label htmlFor="r3">Compact</Label>
      </div>
    </RadioGroup>
  );
}
```

For more information on how to use the Radio Group component, refer to the [Radio Group documentation](https://ui.shadcn.com/docs/components/radio-group).

## Select

The `Select` component is a customizable select component that allows users to select an option from a list of options.

{% component path="shadcn/select" /%}

```tsx
import * as React from 'react';

import {
  Select,
  SelectContent,
  SelectGroup,
  SelectItem,
  SelectLabel,
  SelectTrigger,
  SelectValue,
} from '@kit/ui/select';

export default function SelectDemo() {
  return (
    <div>
      <Select>
        <SelectTrigger className="w-[180px]">
          <SelectValue placeholder="Select a fruit" />
        </SelectTrigger>
        <SelectContent>
          <SelectGroup>
            <SelectLabel>Fruits</SelectLabel>
            <SelectItem value="apple">Apple</SelectItem>
            <SelectItem value="banana">Banana</SelectItem>
            <SelectItem value="blueberry">Blueberry</SelectItem>
            <SelectItem value="grapes">Grapes</SelectItem>
            <SelectItem value="pineapple">Pineapple</SelectItem>
          </SelectGroup>
        </SelectContent>
      </Select>
    </div>
  );
}
```

For more information on the `Select` component, please refer to the [Select](https://ui.shadcn.com/docs/components/select) documentation.

## Skeleton

The `Skeleton` component is used to display a loading state while content is being fetched or rendered. It can be used to create a placeholder state for your components.

{% component path="shadcn/skeleton" /%}

```tsx
import { Skeleton } from '@kit/ui/skeleton';

export default function SkeletonDemo() {
  return (
    <div className="flex flex-col gap-4">
      <Skeleton className="h-6 w-full" />
  );
}
```

For more information on the `Skeleton` component, please refer to the [Skeleton](https://ui.shadcn.com/docs/components/skeleton) documentation.

## Switch

The `Switch` component is a customizable switch component that allows users to toggle between on and off states.

{% component path="shadcn/switch" /%}

```tsx
import { Label } from '@kit/ui/label';
import { Switch } from '@kit/ui/switch';

export default function SwitchDemo() {
  return (
    <div>
      <div className="flex items-center space-x-2">
        <Switch id="airplane-mode" />
        <Label htmlFor="airplane-mode">Airplane Mode</Label>
      </div>
    </div>
  );
}
```

For more information on the `Switch` component, please refer to the [Switch](https://ui.shadcn.com/docs/components/switch) documentation.

## Tabs

The `Tabs` component is a customizable tabs component that allows users to switch between different views or sections.

{% component path="shadcn/tabs" /%}

```tsx
import { Button } from '@kit/ui/button';
import {
  Card,
  CardContent,
  CardDescription,
  CardFooter,
  CardHeader,
  CardTitle,
} from '@kit/ui/card';
import { Input } from '@kit/ui/input';
import { Label } from '@kit/ui/label';
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@kit/ui/tabs';

export default function TabsDemo() {
  return (
    <Tabs defaultValue="account" className="w-[400px]">
      <TabsList className="grid w-full grid-cols-2">
        <TabsTrigger value="account">Account</TabsTrigger>
        <TabsTrigger value="password">Password</TabsTrigger>
      </TabsList>
      <TabsContent value="account">
        <Card>
          <CardHeader>
            <CardTitle>Account</CardTitle>
            <CardDescription>
              Make changes to your account here. Click save when you're done.
            </CardDescription>
          </CardHeader>
          <CardContent className="space-y-2">
            <div className="space-y-1">
              <Label htmlFor="name">Name</Label>
              <Input id="name" defaultValue="Pedro Duarte" />
            </div>
            <div className="space-y-1">
              <Label htmlFor="username">Username</Label>
              <Input id="username" defaultValue="@peduarte" />
            </div>
          </CardContent>
          <CardFooter>
            <Button>Save changes</Button>
          </CardFooter>
        </Card>
      </TabsContent>
      <TabsContent value="password">
        <Card>
          <CardHeader>
            <CardTitle>Password</CardTitle>
            <CardDescription>
              Change your password here. After saving, you'll be logged out.
            </CardDescription>
          </CardHeader>
          <CardContent className="space-y-2">
            <div className="space-y-1">
              <Label htmlFor="current">Current password</Label>
              <Input id="current" type="password" />
            </div>
            <div className="space-y-1">
              <Label htmlFor="new">New password</Label>
              <Input id="new" type="password" />
            </div>
          </CardContent>
          <CardFooter>
            <Button>Save password</Button>
          </CardFooter>
        </Card>
      </TabsContent>
    </Tabs>
  );
}

```

For more information on the `Tabs` component, please refer to the [Tabs](https://ui.shadcn.com/docs/components/tabs) documentation.

## Textarea

The `Textarea` component is a customizable textarea component that allows users to enter multiple lines of text.

{% component path="shadcn/textarea" /%}

```tsx
import { Textarea } from '@kit/ui/textarea';

function TextareaDemo() {
  return (
    <div className="flex flex-col space-y-4">
      <Textarea placeholder="Enter your message" />
    </div>
  );
}
```

For more information on the `Textarea` component, please refer to the [Textarea](https://ui.shadcn.com/docs/components/textarea) documentation.

## Tooltip

The `Tooltip` component is a customizable tooltip component that displays additional information when hovering over an element.

{% component path="shadcn/tooltip" /%}

```tsx
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@kit/ui/tooltip';
import { Button } from '@kit/ui/button';

export default function TooltipDemo() {
  return (
    <div>
      <TooltipProvider>
        <Tooltip>
          <TooltipTrigger asChild>
            <Button variant="outline">Hover over me</Button>
          </TooltipTrigger>

          <TooltipContent>
            This is a tooltip with some content.
          </TooltipContent>
        </Tooltip>
      </TooltipProvider>
    </div>
  );
}
```

For more information on the `Tooltip` component, please refer to the [Tooltip](https://ui.shadcn.com/docs/components/tooltip) documentation.
