Home / Function/ DataTableDemo() — supabase Function Reference

DataTableDemo() — supabase Function Reference

Architecture documentation for the DataTableDemo() function in data-table-demo.tsx from the supabase codebase.

Entity Profile

Relationship Graph

Source Code

apps/design-system/registry/default/example/data-table-demo.tsx lines 161–348

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({})

  // Convert TanStack Table's SortingState to the string format expected by TableHeadSort
  const getSortString = React.useMemo(() => {
    if (sorting.length === 0) return ''
    const sort = sorting[0]
    return `${sort.id}:${sort.desc ? 'desc' : 'asc'}`
  }, [sorting])

  // Handle sort changes from TableHeadSort and convert to TanStack Table's SortingState
  const handleSortChange = React.useCallback(
    (column: string) => {
      const currentSort = sorting.find((s) => s.id === column)
      if (currentSort) {
        if (currentSort.desc) {
          // Cycle: desc -> remove sort
          setSorting([])
        } else {
          // Cycle: asc -> desc
          setSorting([{ id: column, desc: true }])
        }
      } else {
        // New column, start with asc
        setSorting([{ id: column, desc: false }])
      }
    },
    [sorting]
  )

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

  return (
    <div className="w-full flex flex-col gap-4">
      {/* Filters and column visibility controls */}
      <div className="flex items-center">
        <Input
          size="tiny"
          placeholder="Filter by email"
          value={(table.getColumn('email')?.getFilterValue() as string) ?? ''}
          onChange={(event) => table.getColumn('email')?.setFilterValue(event.target.value)}
          className="max-w-sm"
        />
        <DropdownMenu>
          <DropdownMenuTrigger asChild>
            <Button type="default" className="ml-auto" size="tiny" iconRight={<ChevronDown />}>
              Columns
            </Button>
          </DropdownMenuTrigger>
          <DropdownMenuContent align="end" className="max-w-48">
            {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>
      {/* Table */}
      <Card className="w-full">
        <Table>
          <TableHeader>
            {table.getHeaderGroups().map((headerGroup) => (
              <TableRow key={headerGroup.id}>
                {headerGroup.headers.map((header) => {
                  const columnId = header.column.id
                  const canSort = header.column.getCanSort()

                  return (
                    <TableHead
                      key={header.id}
                      className={
                        columnId === 'amount'
                          ? 'text-right'
                          : columnId === 'actions'
                            ? 'w-1'
                            : undefined
                      }
                    >
                      {header.isPlaceholder ? null : canSort ? (
                        <TableHeadSort
                          column={columnId}
                          currentSort={getSortString}
                          onSortChange={handleSortChange}
                          className={columnId === 'amount' ? 'justify-end' : undefined}
                        >
                          {flexRender(header.column.columnDef.header, header.getContext())}
                        </TableHeadSort>
                      ) : (
                        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}
                      className={
                        cell.column.id === 'email'
                          ? 'text-foreground-lighter'
                          : cell.column.id === 'actions'
                            ? 'w-1'
                            : undefined
                      }
                    >
                      {flexRender(cell.column.columnDef.cell, cell.getContext())}
                    </TableCell>
                  ))}
                </TableRow>
              ))
            ) : (
              <TableRow>
                <TableCell colSpan={columns.length}>
                  <p className="text-sm text-foreground">No results found</p>
                  <p className="text-sm text-foreground-lighter">
                    Your search did not return any results
                  </p>
                </TableCell>
              </TableRow>
            )}
          </TableBody>
        </Table>
      </Card>
      {/* Count and pagination controls */}
      <div className="flex items-center justify-end space-x-2">
        <div className="text-foreground-muted flex-1 text-xs">
          {table.getFilteredSelectedRowModel().rows.length} of{' '}
          {table.getFilteredRowModel().rows.length} row(s) selected
        </div>
        <div className="space-x-2">
          <Button
            type="default"
            size="tiny"
            onClick={() => table.previousPage()}
            disabled={!table.getCanPreviousPage()}
          >
            Previous
          </Button>
          <Button
            type="default"
            size="tiny"
            onClick={() => table.nextPage()}
            disabled={!table.getCanNextPage()}
          >
            Next
          </Button>
        </div>
      </div>
    </div>
  )
}

Domain

Subdomains

Analyze Your Own Codebase

Get architecture documentation, dependency graphs, and domain analysis for your codebase in minutes.

Try Supermodel Free