Table
tableuiPlain HTML table primitives — `<Table>`, `<TableHeader>`, `<TableRow>`, `<TableCell>` — with the registry’s borders, padding, and tokens already applied. Use this when Data Table is too heavy.
Installation
$pnpm dlx shadcn-svelte@latest add https://uipkge.dev/r/svelte/table.json$npx shadcn-svelte@latest add https://uipkge.dev/r/svelte/table.json$yarn dlx shadcn-svelte@latest add https://uipkge.dev/r/svelte/table.json$bunx shadcn-svelte@latest add https://uipkge.dev/r/svelte/table.jsonManifest:
https://uipkge.dev/r/svelte/table.jsonInstalls to:src/lib/components/ui/table/Examples
Loading interactive previews…
Loading interactive previews…
Props
| Name | Type / Values | Default | Required |
|---|---|---|---|
containerClassExtra classes for the scroll container div (e.g. `min-h-0 flex-1` inside a flex column). A sticky TableHeader pins to THIS div -- an outer overflow wrapper around <Table> breaks stickiness, so size the scroller here. | string | — | optional |
density | 'compact' | 'cozy' | 'comfortable' | — | optional |
ref | HTMLTableElement | null | — | optional |
Used by
Files installed (11)
src/lib/components/ui/table/Table.svelte1.3 kB
<script lang="ts" module> import type { HTMLTableAttributes } from 'svelte/elements' export interface TableProps extends HTMLTableAttributes { /** * Extra classes for the scroll container div (e.g. `min-h-0 flex-1` inside a * flex column). A sticky TableHeader pins to THIS div -- an outer overflow * wrapper around <Table> breaks stickiness, so size the scroller here. */ containerClass?: string density?: 'compact' | 'cozy' | 'comfortable' ref?: HTMLTableElement | null } </script> <script lang="ts"> import { cn } from '$lib/utils' let { class: className, containerClass, density, children, ref = $bindable(null), ...restProps }: TableProps = $props() const densityClass = $derived.by(() => { if (density === 'compact') return '[&_td]:py-1.5 [&_td]:text-xs [&_th]:h-8 [&_th]:text-xs' if (density === 'comfortable') return '[&_td]:py-3 [&_th]:h-12' // cozy is the TableCell/TableHead baseline (py-2 / h-10) -- no override. return '' }) </script> <div data-uipkge="" data-slot="table-container" class={cn('relative w-full overflow-auto', containerClass)}> <table bind:this={ref} data-uipkge="" data-slot="table" class={cn('w-full caption-bottom text-sm', densityClass, className)} {...restProps}> {@render children?.()} </table> </div>src/lib/components/ui/table/TableBody.svelte0.5 kB
<script lang="ts" module> import type { HTMLAttributes } from 'svelte/elements' export interface TableBodyProps extends HTMLAttributes<HTMLElement> { ref?: HTMLTableSectionElement | null } </script> <script lang="ts"> import { cn } from '$lib/utils' let { class: className, children, ref = $bindable(null), ...restProps }: TableBodyProps = $props() </script> <tbody bind:this={ref} data-uipkge="" data-slot="table-body" class={cn('[&_tr:last-child]:border-0', className)} {...restProps}> {@render children?.()} </tbody>src/lib/components/ui/table/TableCaption.svelte0.5 kB
<script lang="ts" module> import type { HTMLAttributes } from 'svelte/elements' export interface TableCaptionProps extends HTMLAttributes<HTMLElement> { ref?: HTMLElement | null } </script> <script lang="ts"> import { cn } from '$lib/utils' let { class: className, children, ref = $bindable(null), ...restProps }: TableCaptionProps = $props() </script> <caption bind:this={ref} data-uipkge="" data-slot="table-caption" class={cn('text-muted-foreground mt-4 text-sm', className)} {...restProps}> {@render children?.()} </caption>src/lib/components/ui/table/TableCell.svelte0.6 kB
<script lang="ts" module> import type { HTMLTdAttributes } from 'svelte/elements' export interface TableCellProps extends HTMLTdAttributes { ref?: HTMLTableCellElement | null } </script> <script lang="ts"> import { cn } from '$lib/utils' let { class: className, children, ref = $bindable(null), ...restProps }: TableCellProps = $props() </script> <td bind:this={ref} data-uipkge="" data-slot="table-cell" class={cn( 'px-3 py-2 align-middle text-sm whitespace-nowrap [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]', className, )} {...restProps} > {@render children?.()} </td>src/lib/components/ui/table/TableEmpty.svelte0.7 kB
<script lang="ts" module> import type { HTMLTdAttributes } from 'svelte/elements' export interface TableEmptyProps extends HTMLTdAttributes { colspan?: number } </script> <script lang="ts"> import { cn } from '$lib/utils' import TableCell from './TableCell.svelte' import TableRow from './TableRow.svelte' let { class: className, colspan = 1, children, ...restProps }: TableEmptyProps = $props() </script> <TableRow> <TableCell class={cn('text-foreground p-4 align-middle text-sm whitespace-nowrap', className)} {colspan} {...restProps}> <div class="flex items-center justify-center py-10"> {@render children?.()} </div> </TableCell> </TableRow>src/lib/components/ui/table/TableFooter.svelte0.6 kB
<script lang="ts" module> import type { HTMLAttributes } from 'svelte/elements' export interface TableFooterProps extends HTMLAttributes<HTMLElement> { ref?: HTMLTableSectionElement | null } </script> <script lang="ts"> import { cn } from '$lib/utils' let { class: className, children, ref = $bindable(null), ...restProps }: TableFooterProps = $props() </script> <tfoot bind:this={ref} data-uipkge="" data-slot="table-footer" class={cn('bg-muted/50 border-t font-medium [&>tr]:last:border-b-0', className)} {...restProps} > {@render children?.()} </tfoot>src/lib/components/ui/table/TableHead.svelte0.7 kB
<script lang="ts" module> import type { HTMLTdAttributes } from 'svelte/elements' export interface TableHeadProps extends HTMLTdAttributes { ref?: HTMLTableCellElement | null } </script> <script lang="ts"> import { cn } from '$lib/utils' let { class: className, children, ref = $bindable(null), ...restProps }: TableHeadProps = $props() </script> <th bind:this={ref} data-uipkge="" data-slot="table-head" class={cn( 'text-foreground h-10 px-3 text-left align-middle text-sm font-medium whitespace-nowrap [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]', className, )} {...restProps} > {@render children?.()} </th>src/lib/components/ui/table/TableHeader.svelte0.5 kB
<script lang="ts" module> import type { HTMLAttributes } from 'svelte/elements' export interface TableHeaderProps extends HTMLAttributes<HTMLElement> { ref?: HTMLTableSectionElement | null } </script> <script lang="ts"> import { cn } from '$lib/utils' let { class: className, children, ref = $bindable(null), ...restProps }: TableHeaderProps = $props() </script> <thead bind:this={ref} data-uipkge="" data-slot="table-header" class={cn('bg-muted/50 [&_tr]:border-b', className)} {...restProps}> {@render children?.()} </thead>src/lib/components/ui/table/TableRow.svelte0.6 kB
<script lang="ts" module> import type { HTMLAttributes } from 'svelte/elements' export interface TableRowProps extends HTMLAttributes<HTMLTableRowElement> { ref?: HTMLTableRowElement | null } </script> <script lang="ts"> import { cn } from '$lib/utils' let { class: className, children, ref = $bindable(null), ...restProps }: TableRowProps = $props() </script> <tr bind:this={ref} data-uipkge="" data-slot="table-row" class={cn('hover:bg-muted/50 data-[state=selected]:bg-muted border-b transition-colors duration-150', className)} {...restProps} > {@render children?.()} </tr>src/lib/components/ui/table/index.ts0.7 kB
export { default as Table, type TableProps } from './Table.svelte' export { default as TableBody, type TableBodyProps } from './TableBody.svelte' export { default as TableCaption, type TableCaptionProps } from './TableCaption.svelte' export { default as TableCell, type TableCellProps } from './TableCell.svelte' export { default as TableEmpty, type TableEmptyProps } from './TableEmpty.svelte' export { default as TableFooter, type TableFooterProps } from './TableFooter.svelte' export { default as TableHead, type TableHeadProps } from './TableHead.svelte' export { default as TableHeader, type TableHeaderProps } from './TableHeader.svelte' export { default as TableRow, type TableRowProps } from './TableRow.svelte' export { valueUpdater } from './utils'src/lib/components/ui/table/utils.ts0.5 kB
/** * Applies a TanStack Table updater (value or `(old) => next` function) to a * `{ value }` box. The Vue twin imports `Updater`/`isFunction` from * `@tanstack/vue-table`; this port inlines the two-line check so plain-table * consumers pull zero table-state dependencies. Pair with * `@tanstack/svelte-table` when you need full data-table state. */ export function valueUpdater<T>(updaterOrValue: T | ((old: T) => T), ref: { value: T }) { ref.value = typeof updaterOrValue === 'function' ? (updaterOrValue as (old: T) => T)(ref.value) : updaterOrValue }
Raw manifest:https://uipkge.dev/r/svelte/table.json