Table View

An composable, editable data table.

page 1
desc1
page 2
desc2
import { TableView } from "@notion-kit/table-view";
import type { DatabaseProperty, RowDataType } from "@notion-kit/table-view";
 
const mockProps: DatabaseProperty[] = [
  {
    id: "prop-1",
    type: "title",
    name: "Name",
    width: "216px",
  },
  {
    id: "prop-2",
    type: "text",
    name: "Desc.",
    width: "100px",
  },
  {
    id: "prop-3",
    type: "checkbox",
    name: "Done",
    width: "90px",
  },
];
 
const mockData: RowDataType[] = [
  {
    id: "row-1",
    properties: {
      "prop-1": { id: "prop-1-1", type: "title", value: "page 1" },
      "prop-2": { id: "prop-1-2", type: "text", value: "desc1" },
      "prop-3": { id: "prop-1-3", type: "checkbox", checked: true },
    },
  },
  {
    id: "row-2",
    properties: {
      "prop-1": { id: "prop-2-1", type: "title", value: "page 2" },
      "prop-2": { id: "prop-2-2", type: "text", value: "desc2" },
      "prop-3": { id: "prop-2-3", type: "checkbox", checked: false },
    },
  },
];
 
export default function Demo() {
  return <TableView defaultState={{ properties: mockProps, data: mockData }} />;
}
 

Supported Features

  • Controlled/Uncontrolled state management

  • Column & row CRUD

  • Column & row DND

  • Column & row duplicating

  • Column wrapping

  • Column pinning

  • Column type changing

  • Cells types: title, text, checkbox

Installation

pnpm add @notion-kit/table-view

Note

Every table should have exactly one title property.

Examples


Uncontrolled Table

page 1
desc1
page 2
desc2
<TableView
  state={{ properties: mockProps, data: mockData }}
/>
 

Controlled Table

page 1
desc1
page 2
desc2
<TableView state={state} onStateChange={setState} />

API Reference

TableView

PropTypeDescription
defaultStateTableStateThe (uncontrolled) table state, consisting of column definitions and row data.
stateTableStateThe (controlled) table state, consisting of column definitions and row data.
onStateChange(newState: TableState, type: TableViewAction["type"]) => voidHandler that is called when the table data is updated.
dispatch(action: TableViewAction) => voidHandler that is called when the table data is updated. This is useful when you want to customize the table action.

type TableState

PropTypeDefaultDescription
propertiesDatabaseProperty[]-The column definitions of the table.
dataRowDataType[]-The rows of the table.
freezedIndexnumber-1The index of the last freezed column. It is -1 if no columns are freezed.

type TableViewAction

Possible actions of the <TableView />.

Action typePayloadDescription
add:col{ id: string, name: string, type: PropertyType }The action to create a new column.
update:col{ id: string, data: UpdateColumnPayload }The action to update the column definition.
update:col:type{ id: string, type: PropertyType }The action to change the column type.
update:col:visibility{ id: string, hidden: boolean }The action to toggle the visibility of all columns.
freeze:col{ id: string | null }The action to freeze or unfreeze up to a column.
duplicate:col{ id: string }The action to duplicate a column.
delete:col{ id: string }The action to delete a column.
reorder:colUpdater<string>The action to reorder the columns (by DND).
add:row{ id: string, at: "prev" | "next" } | undefinedThe action to add a new row at bottom or add below/above of a given row.
update:row:icon{ id: string, icon: IconData | null }The action to update the icon of the row title.
duplicate:row{ id: string }The action to duplicate a row.
delete:row{ id: string }The action to delete a row.
reorder:rowUpdater<string>The action to reorder the rows (by DND).
update:count:cap{ id: string, updater: Updater<boolean> }The action to set whether to cap the value when counting rows.
update:cell{ rowId: string, colId: string, data: CellDataType }The action to update the data of the cell.
reset-The action to reset the table.

On this page