The fully generalized table: per-column filtering on top of sorting and pagination (Data Table III). Each column gets a filter input, and the data flows through three stages in a fixed order — filter, then sort, then paginate. Get the order right and each stage is a one-liner; get it wrong and pages, sorts, and filters fight each other.
type Column = { key: string; header: string };
type Row = { id: number; [key: string]: string | number };
function DataTable(props: {
columns: Column[];
data: Row[];
pageSize: number;
}): JSX.Element;
filter Name = "a", sort by Age, page 1
→ keep rows whose name contains "a", order them by age, show the first 5
filters live in one object: { name: "a", occupation: "" }
a row survives only if EVERY column's filter matches (empty = matches all)
{ [key]: text }; a row passes when columns.every(...) of its filters match.Unlock the solution & editor
Runnable editor + tests
Solve in the browser with instant Jest feedback.
Detailed solutions
Walkthroughs, edge cases, and complexity notes.
Multi-framework variants
React, Vue, Vanilla, Angular — same question, different stacks.