CodePark/ questions / Component architecture & APIs
START PRACTICINGPRACTICE
Frontend question · Frontend system design › Component architecture & APIs

Design the API of a reusable DataTable used by many teams. How do you handle sorting, filtering, pagination and selection, and should those be controlled or uncontrolled?

Separate the table logic from the rendering. The core is a headless hook, in the style of TanStack Table. Headless means it handles logic and state but renders no markup.

The hook takes columns and data. It returns row models plus state. The design system ships a default rendered DataTable on top of the hook. Teams with unusual layouts can use the hook directly.

Each piece of state is uncontrolled by default, with an optional controlled pair. The pieces are:

  • sorting
  • filters
  • pagination
  • row selection
  • column visibility

For example, sorting has the controlled pair sorting and onSortingChange. This matters because teams differ. Some teams sort locally. Others need server-side sorting, so they must lift the state into the URL and the query key. A manualSorting or manualPagination flag tells the table not to process the data itself.

Columns are declared as config with:

  • accessor
  • header
  • cell render functions
  • enableSorting

For large datasets, I support virtualization, which renders only the visible rows. I also support a stable getRowId, so selection stays correct across pages.

For accessibility:

  • Use real table semantics.
  • Put aria-sort on the headers.
  • Make every control reachable by keyboard.
  • Headless logic is separated from rendering.
  • Each piece of state can optionally be controlled by the parent.
  • A manual mode supports server-side sorting and pagination.
  • Stable row ids keep selection correct, and virtualization handles large data.
  • Use real table semantics and aria-sort on headers.