Table
Vue data-displayPlain 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.
Also available for React ->Installation
$ pnpm dlx shadcn-vue@latest add https://uipkge.dev/r/vue/table.json$ npx shadcn-vue@latest add https://uipkge.dev/r/vue/table.json$ yarn dlx shadcn-vue@latest add https://uipkge.dev/r/vue/table.json$ bunx shadcn-vue@latest add https://uipkge.dev/r/vue/table.json
Or with the named registry:
npx shadcn-vue@latest add @uipkge/table
Examples
Props
| Name | Type / Values | Default | Required |
|---|---|---|---|
class | HTMLAttributes['class'] | — | optional |
density | 'compact''cozy''comfortable' | — | optional |
Dependencies
Used by
Files (11)
-
app/components/ui/table/Table.vue 1.1 kB
<script setup lang="ts"> import type { HTMLAttributes } from 'vue' import { computed } from 'vue' import { cn } from '@/lib/utils' // Match DataTable's density enum so consumers can opt into the same // runtime feel without wiring DataTable. `cozy` is the canonical default // for bare tables (cells: py-2, head: h-10); the other two are escape // hatches for high-density admin lists and roomy patient-facing views. const props = defineProps<{ class?: HTMLAttributes['class'] density?: 'compact' | 'cozy' | 'comfortable' }>() const densityClass = computed(() => { if (props.density === 'compact') return '[&_td]:py-1.5 [&_td]:text-xs [&_th]:h-8 [&_th]:text-xs' if (props.density === 'comfortable') return '[&_td]:py-3 [&_th]:h-12' // cozy is the new TableCell/TableHead baseline (py-2 / h-10) -- no override. return '' }) </script> <template> <div data-uipkge data-slot="table-container" class="relative w-full overflow-auto" > <table data-uipkge data-slot="table" :class="cn('w-full caption-bottom text-sm', densityClass, props.class)" > <slot /> </table> </div> </template> -
app/components/ui/table/TableBody.vue 0.3 kB
<script setup lang="ts"> import type { HTMLAttributes } from 'vue' import { cn } from '@/lib/utils' const props = defineProps<{ class?: HTMLAttributes['class'] }>() </script> <template> <tbody data-uipkge data-slot="table-body" :class="cn('[&_tr:last-child]:border-0', props.class)"> <slot /> </tbody> </template> -
app/components/ui/table/TableCaption.vue 0.3 kB
<script setup lang="ts"> import type { HTMLAttributes } from 'vue' import { cn } from '@/lib/utils' const props = defineProps<{ class?: HTMLAttributes['class'] }>() </script> <template> <caption data-uipkge data-slot="table-caption" :class="cn('text-muted-foreground mt-4 text-sm', props.class)"> <slot /> </caption> </template> -
app/components/ui/table/TableCell.vue 0.5 kB
<script setup lang="ts"> import type { HTMLAttributes } from 'vue' import { cn } from '@/lib/utils' const props = defineProps<{ class?: HTMLAttributes['class'] }>() </script> <template> <td 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]', props.class, ) " > <slot /> </td> </template> -
app/components/ui/table/TableEmpty.vue 0.7 kB
<script setup lang="ts"> import type { HTMLAttributes } from 'vue' import { reactiveOmit } from '@vueuse/core' import { cn } from '@/lib/utils' import TableCell from './TableCell.vue' import TableRow from './TableRow.vue' const props = withDefaults( defineProps<{ class?: HTMLAttributes['class'] colspan?: number }>(), { colspan: 1, }, ) const delegatedProps = reactiveOmit(props, 'class') </script> <template> <TableRow> <TableCell :class="cn('text-foreground p-4 align-middle text-sm whitespace-nowrap', props.class)" v-bind="delegatedProps" > <div class="flex items-center justify-center py-10"> <slot /> </div> </TableCell> </TableRow> </template> -
app/components/ui/table/TableFooter.vue 0.4 kB
<script setup lang="ts"> import type { HTMLAttributes } from 'vue' import { cn } from '@/lib/utils' const props = defineProps<{ class?: HTMLAttributes['class'] }>() </script> <template> <tfoot data-uipkge data-slot="table-footer" :class="cn('bg-muted/50 border-t font-medium [&>tr]:last:border-b-0', props.class)" > <slot /> </tfoot> </template> -
app/components/ui/table/TableHead.vue 0.5 kB
<script setup lang="ts"> import type { HTMLAttributes } from 'vue' import { cn } from '@/lib/utils' const props = defineProps<{ class?: HTMLAttributes['class'] }>() </script> <template> <th 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]', props.class, ) " > <slot /> </th> </template> -
app/components/ui/table/TableHeader.vue 0.3 kB
<script setup lang="ts"> import type { HTMLAttributes } from 'vue' import { cn } from '@/lib/utils' const props = defineProps<{ class?: HTMLAttributes['class'] }>() </script> <template> <thead data-uipkge data-slot="table-header" :class="cn('bg-muted/50 [&_tr]:border-b', props.class)"> <slot /> </thead> </template> -
app/components/ui/table/TableRow.vue 0.4 kB
<script setup lang="ts"> import type { HTMLAttributes } from 'vue' import { cn } from '@/lib/utils' const props = defineProps<{ class?: HTMLAttributes['class'] }>() </script> <template> <tr data-uipkge data-slot="table-row" :class="cn('hover:bg-muted/50 data-[state=selected]:bg-muted border-b transition-colors duration-150', props.class)" > <slot /> </tr> </template> -
app/components/ui/table/index.ts 0.5 kB
export { default as Table } from './Table.vue' export { default as TableBody } from './TableBody.vue' export { default as TableCaption } from './TableCaption.vue' export { default as TableCell } from './TableCell.vue' export { default as TableEmpty } from './TableEmpty.vue' export { default as TableFooter } from './TableFooter.vue' export { default as TableHead } from './TableHead.vue' export { default as TableHeader } from './TableHeader.vue' export { default as TableRow } from './TableRow.vue' -
app/components/ui/table/utils.ts 0.3 kB
import type { Updater } from '@tanstack/vue-table' import type { Ref } from 'vue' import { isFunction } from '@tanstack/vue-table' export function valueUpdater<T>(updaterOrValue: Updater<T>, ref: Ref<T>) { ref.value = isFunction(updaterOrValue) ? updaterOrValue(ref.value) : updaterOrValue }
Raw manifest: https://uipkge.dev/r/vue/table.json