Table
A component that displays data in a tabular format.
plain
outline
import { Table } from '~/components/ui/table'
export const Demo = (props: Table.RootProps) => {
  return (
    <Table.Root {...props}>
      <Table.Caption>Product Inventory</Table.Caption>
      <Table.Head>
        <Table.Row>
          <Table.Header>ID</Table.Header>
          <Table.Header>Name</Table.Header>
          <Table.Header>Stock</Table.Header>
          <Table.Header textAlign="right">Price</Table.Header>
        </Table.Row>
      </Table.Head>
      <Table.Body>
        {productData.map((product, index) => (
          <Table.Row key={index}>
            <Table.Cell fontWeight="medium">{product.id}</Table.Cell>
            <Table.Cell>{product.name}</Table.Cell>
            <Table.Cell>{product.stock}</Table.Cell>
            <Table.Cell textAlign="right">{product.price}</Table.Cell>
          </Table.Row>
        ))}
      </Table.Body>
      <Table.Foot>
        <Table.Row>
          <Table.Cell colSpan={2}>Totals</Table.Cell>
          <Table.Cell>87</Table.Cell>
          <Table.Cell textAlign="right">$34,163.00</Table.Cell>
        </Table.Row>
      </Table.Foot>
    </Table.Root>
  )
}
const productData = [
  { id: 'P001', name: 'MacBook Pro', stock: 12, price: '$1999.00' },
  { id: 'P002', name: 'AirPods Pro', stock: 25, price: '$249.00' },
  { id: 'P003', name: 'Leather Wallet', stock: 50, price: '$79.00' },
]
import { For } from 'solid-js'
import { Table } from '~/components/ui/table'
export const Demo = (props: Table.RootProps) => {
  return (
    <Table.Root {...props}>
      <Table.Caption>Product Inventory</Table.Caption>
      <Table.Head>
        <Table.Row>
          <Table.Header>ID</Table.Header>
          <Table.Header>Name</Table.Header>
          <Table.Header>Stock</Table.Header>
          <Table.Header textAlign="right">Price</Table.Header>
        </Table.Row>
      </Table.Head>
      <Table.Body>
        <For each={productData}>
          {(product) => (
            <Table.Row>
              <Table.Cell fontWeight="medium">{product.id}</Table.Cell>
              <Table.Cell>{product.name}</Table.Cell>
              <Table.Cell>{product.stock}</Table.Cell>
              <Table.Cell textAlign="right">{product.price}</Table.Cell>
            </Table.Row>
          )}
        </For>
      </Table.Body>
      <Table.Foot>
        <Table.Row>
          <Table.Cell colSpan={2}>Totals</Table.Cell>
          <Table.Cell>87</Table.Cell>
          <Table.Cell textAlign="right">$34,163.00</Table.Cell>
        </Table.Row>
      </Table.Foot>
    </Table.Root>
  )
}
const productData = [
  { id: 'P001', name: 'MacBook Pro', stock: 12, price: '$1999.00' },
  { id: 'P002', name: 'AirPods Pro', stock: 25, price: '$249.00' },
  { id: 'P003', name: 'Leather Wallet', stock: 50, price: '$79.00' },
]
Usage
import { Table } from '~/components/ui/table'Installation
npx @park-ui/cli components add table1
Add Styled Primitive
Copy the code snippet below into ~/components/ui/styled/table.tsx
'use client'
import type { Assign, PolymorphicProps } from '@ark-ui/react'
import { ark } from '@ark-ui/react/factory'
import { type TableVariantProps, table } from 'styled-system/recipes'
import type { HTMLStyledProps } from 'styled-system/types'
import { createStyleContext } from './utils/create-style-context'
const { withProvider, withContext } = createStyleContext(table)
export interface RootProps
  extends Assign<HTMLStyledProps<'table'>, PolymorphicProps>,
    TableVariantProps {}
export const Root = withProvider<HTMLTableElement, RootProps>(ark.table, 'root')
export const Body = withContext<
  HTMLTableSectionElement,
  Assign<HTMLStyledProps<'tbody'>, PolymorphicProps>
>(ark.tbody, 'body')
export const Caption = withContext<
  HTMLTableCaptionElement,
  Assign<HTMLStyledProps<'caption'>, PolymorphicProps>
>(ark.caption, 'caption')
export const Cell = withContext<
  HTMLTableCellElement,
  Assign<HTMLStyledProps<'td'>, PolymorphicProps>
>(ark.td, 'cell')
export const Foot = withContext<
  HTMLTableSectionElement,
  Assign<HTMLStyledProps<'tfoot'>, PolymorphicProps>
>(ark.tfoot, 'footer')
export const Head = withContext<
  HTMLTableSectionElement,
  Assign<HTMLStyledProps<'head'>, PolymorphicProps>
>(ark.thead, 'head')
export const Header = withContext<
  HTMLTableCellElement,
  Assign<HTMLStyledProps<'th'>, PolymorphicProps>
>(ark.th, 'header')
export const Row = withContext<
  HTMLTableRowElement,
  Assign<HTMLStyledProps<'tr'>, PolymorphicProps>
>(ark.tr, 'row')
import { type Assign, type PolymorphicProps, ark } from '@ark-ui/solid'
import type { ComponentProps } from 'solid-js'
import { table } from 'styled-system/recipes'
import type { HTMLStyledProps } from 'styled-system/types'
import { createStyleContext } from './utils/create-style-context'
const { withProvider, withContext } = createStyleContext(table)
export type RootProps = ComponentProps<typeof Root>
export const Root = withProvider<Assign<HTMLStyledProps<'table'>, PolymorphicProps<'table'>>>(
  ark.table,
  'root',
)
export const Body = withContext<Assign<HTMLStyledProps<'tbody'>, PolymorphicProps<'tbody'>>>(
  ark.tbody,
  'body',
)
export const Caption = withContext<Assign<HTMLStyledProps<'caption'>, PolymorphicProps<'caption'>>>(
  ark.caption,
  'caption',
)
export const Cell = withContext<Assign<HTMLStyledProps<'td'>, PolymorphicProps<'td'>>>(
  ark.td,
  'cell',
)
export const Foot = withContext<Assign<HTMLStyledProps<'tfoot'>, PolymorphicProps<'tfoot'>>>(
  ark.tfoot,
  'footer',
)
export const Head = withContext<Assign<HTMLStyledProps<'head'>, PolymorphicProps<'head'>>>(
  ark.thead,
  'head',
)
export const Header = withContext<Assign<HTMLStyledProps<'th'>, PolymorphicProps<'th'>>>(
  ark.th,
  'header',
)
export const Row = withContext<Assign<HTMLStyledProps<'tr'>, PolymorphicProps<'tr'>>>(ark.tr, 'row')
No snippet found2
Add Re-Export
To improve the developer experience, re-export the styled primitives in~/components/ui/table.tsx.
export * as Table from './styled/table'
export * as Table from './styled/table'
3
Integrate Recipe
If you're not using @park-ui/preset, add the following recipe to yourpanda.config.ts:
import { defineSlotRecipe } from '@pandacss/dev'
export const table = defineSlotRecipe({
  className: 'table',
  slots: ['root', 'body', 'cell', 'footer', 'head', 'header', 'row', 'caption'],
  base: {
    root: {
      captionSide: 'bottom',
      width: 'full',
    },
    body: {
      '& tr:last-child': {
        borderBottomWidth: '0',
      },
    },
    caption: {
      color: 'fg.subtle',
    },
    cell: {
      verticalAlign: 'middle',
    },
    footer: {
      fontWeight: 'medium',
      borderTopWidth: '1px',
      '& tr:last-child': {
        borderBottomWidth: '0',
      },
    },
    header: {
      color: 'fg.muted',
      fontWeight: 'medium',
      textAlign: 'left',
      verticalAlign: 'middle',
    },
    row: {
      borderBottomWidth: '1px',
      transitionDuration: 'normal',
      transitionProperty: 'background, color',
      transitionTimingFunction: 'default',
    },
  },
  defaultVariants: {
    size: 'md',
    variant: 'plain',
  },
  variants: {
    variant: {
      outline: {
        root: {
          borderWidth: '1px',
        },
        head: {
          bg: 'bg.subtle',
        },
      },
      plain: {
        row: {
          _hover: {
            bg: 'bg.subtle',
          },
          _selected: {
            bg: 'bg.muted',
          },
        },
      },
    },
    size: {
      sm: {
        root: {
          textStyle: 'sm',
        },
        caption: {
          mt: '4',
        },
        cell: {
          height: '11',
          px: '3',
        },
        header: {
          height: '11',
          px: '3',
        },
      },
      md: {
        root: {
          textStyle: 'sm',
        },
        caption: {
          mt: '4',
        },
        cell: {
          height: '14',
          px: '4',
        },
        header: {
          height: '11',
          px: '4',
        },
      },
    },
  },
})