DataTable

pro

DataTable pairs TanStack Table with the product Table primitives so sorting, selection, and paging arrive already wired.

Name
Email
Plan
Status
Aria Patelaria@acme.ioGrowthActive
Diego Ramosdiego@acme.ioScaleActive
Mei Linmei@acme.ioStarterTrial
Noah Beckernoah@acme.ioGrowthPast due
Priya Nairpriya@acme.ioScaleActive
Lucas Ferreiralucas@acme.ioStarterTrial
Hana Satohana@acme.ioGrowthActive
Owen Clarkeowen@acme.ioStarterActive
Freya Larsenfreya@acme.ioScalePast due
Malik Johnsonmalik@acme.ioGrowthActive

    Installation

    Add this component with the NateUI CLI.

    npx nateui@latest add DataTable

    Examples

    Deal
    Stage
    Value
    Close date
    Fenwick LabsNegotiation$48,0002026-07-18
    Bright Harbor CoProposal$22,5002026-07-25
    Northgate RetailDiscovery$9,8002026-08-02
    Alderwood GroupClosed Won$63,0002026-06-30
    Pinecrest StudioNegotiation$31,5002026-07-21
    Solace HealthProposal$17,2002026-08-09

      Row Selection

      Ticket
      Subject
      Priority
      Assignee
      TCK-201Checkout button unresponsiveHighAria Patel
      TCK-198Export CSV missing a columnMediumDiego Ramos
      TCK-195Typo in confirmation emailLowMei Lin
      TCK-190Slow load on reports pageMediumAria Patel
      TCK-187Dark mode toggle resets on reloadMediumOwen Clarke

        Column Resizing

        SKU
        Product
        Category
        Price
        Stock
        WM-1001Wireless MousePeripherals$29.00184
        MK-2044Mechanical KeyboardPeripherals$89.0062
        UM-3320USB-C Monitor ArmAccessories$54.0041
        DK-4108Standing Desk ConverterFurniture$210.0015
        HP-5061Noise-Cancelling HeadsetAudio$135.0073

          Pinned Columns

          Name
          Email
          Department
          Location
          Manager
          Start date
          Aria Patelaria@acme.ioEngineeringRemoteNoah Becker2023-04-11
          Diego Ramosdiego@acme.ioDesignAustin, TXMei Lin2022-09-02
          Priya Nairpriya@acme.ioSupportRemoteOwen Clarke2024-01-19
          Lucas Ferreiralucas@acme.ioSalesNew York, NYFreya Larsen2023-11-06
          Hana Satohana@acme.ioEngineeringRemoteNoah Becker2021-06-24

            Expandable Rows

            Name
            Type
            Size
            Modified
            Brand Kit
            Folder2 itemsJun 2, 2026
            Logo Variants
            Folder2 itemsMay 18, 2026
            Primary Logo.png
            Image860 KBMay 12, 2026
            Logo Guidelines.pdf
            Document1.4 MBMay 18, 2026
            Brand Voice.md
            Text9 KBJun 2, 2026
            Product Screenshots
            Folder2 itemsJun 20, 2026
            dashboard-dark.png
            Image2.1 MBJun 14, 2026
            dashboard-light.png
            Image2.3 MBJun 20, 2026
            changelog.txt
            Text6 KBJun 28, 2026

              Drag And Drop

              Feature request
              Votes
              Status
              Bulk CSV export
              128
              In progress
              Saved filter views
              96
              Planned
              Slack notifications
              74
              Planned
              Dark mode scheduling
              51
              Planned
              Audit log retention
              33
              Planned

                Empty State

                Name
                Email

                No customers found

                Try adjusting your search or filters.

                  API

                  DataTable wraps TanStack Table - columns, Row<T>, and the render prop's table instance all come directly from that library; see its own docs for the full column-def and table-instance API. Sorting and pagination stay manual: DataTable expects data to already be sorted and sliced to the current page, then calls back through onSort / onPaginationChange / onPageSizeChange so a parent can re-sort or re-fetch. Column resizing and sticky column pinning are built into the default renderer when columnResize or columnPinning is enabled. Pass children only when you need to replace the table structure entirely, as the Drag And Drop example does. With overflow enabled, the default renderer uses NateUI Scroll for horizontal table scrolling and applies overflowClass to its root; set overflow={false} to render without that viewport. Pagination stays outside the scroll region.

                  PropDescriptionTypeDefault
                  columnsColumn definitions for the table.ColumnDef<T>[][]
                  dataRows to render for the current page.T[][]
                  loadingShows skeleton rows while empty, or dims the table when rows are already present.booleanfalse
                  noDataRenders the built-in empty state instead of rows.booleanfalse
                  renderEmptyStateReplaces the default empty-state content.ReactNode-
                  selectableAdds a checkbox column for row and select-all selection.booleanfalse
                  onRowSelectCalled when a single row's checkbox changes.(checked: boolean, row: T) => void-
                  onAllRowSelectCalled when the header select-all checkbox changes.(checked: boolean, rows: Row<T>[]) => void-
                  checkboxCheckedOverrides a row's checked state instead of TanStack's internal selection.(row: T) => boolean-
                  indeterminateCheckboxCheckedOverrides the header checkbox's checked state.(rows: Row<T>[]) => boolean-
                  onSortCalled when the sorted column or direction changes.(sort: OnSortParam) => void-
                  columnPinningPins columns at the logical start or end by column id and renders them sticky in the default table.ColumnPinningState-
                  columnResizeAdds resize handles to header cells. Pass { mode: 'onChange' } for live resizing while dragging.boolean | ColumnResizeConfigfalse
                  pagingDataCurrent page, page size, and total row count.{ total: number; pageIndex: number; pageSize: number }{ total: 0, pageIndex: 1, pageSize: 10 }
                  onPaginationChangeCalled when the page changes.(page: number) => void-
                  pageSizesOptions shown in the page-size select.number[][10, 25, 50, 100]
                  onPageSizeChangeCalled when the page-size select changes.(size: number) => void-
                  skeletonAvatarColumnsColumn indexes that render an avatar-shaped skeleton while loading.number[]-
                  skeletonAvatarPropsProps for those skeleton avatars.SkeletonProps-
                  childrenRenders the table body yourself from the underlying TanStack instance, instead of DataTable's default rows.(props: { table: Table<T> }) => ReactNode-
                  refExposes resetSorting() and resetSelected().Ref<DataTableResetHandle>-
                  ...tablePropsForwarded to the underlying Table, for example bordered, compact, or overflow.TableProps-

                  Types

                  type OnSortParam = { sortOrder: 'asc' | 'desc' | ''; sortKey: string | number };
                  type ColumnPinningState = { start: string[]; end: string[] };
                  type ColumnResizeConfig = { mode?: ColumnResizeMode };
                  type ColumnResizeMode = 'onChange' | 'onEnd';
                  type DataTableResetHandle = { resetSorting: () => void; resetSelected: () => void };