The output would provide a complete, runnable solution structured as follows:
`` src/ ├── components/ │ └── Table/ │ ├── Table.tsx // Table.Root, TableContext provider │ ├── TableHeader.tsx // Table.Header │ ├── TableRow.tsx // Table.Row │ ├── TableCell.tsx // Table.Cell │ ├── TableColumnToggle.tsx // Table.ColumnToggle │ └── TablePagination.tsx // Table.Pagination ├── hooks/ │ └── useTable.ts // Core table logic, state, and actions ├── types/ │ └── table.ts // TypeScript interfaces for data, columns, state ├── utils/ │ └── sort.ts // Sorting utility functions └── App.tsx // Example usage ``
`src/components/Table/Table.tsx`: This file would define the Table.Root component, which establishes the TableContext. It accepts initial data and column configurations, then uses useTable to manage the table's state. The context provides access to sorted data, current page items, column visibility, and state modifiers to all child compound components.
`src/hooks/useTable.ts`: This hook encapsulates the core headless logic. It manages state for sorting (multi-column), pagination (current page, items per page), and column visibility. It exposes computed values like sortedData, paginatedData, and visibleColumns, along with functions to update state, such as setSort, goToPage, setItemsPerPage, and toggleColumnVisibility. All state and functions are strongly typed.
Compound Components (`TableHeader.tsx`, `TableRow.tsx`, `TableCell.tsx`, etc.): Each compound component consumes the TableContext to access relevant state and functions. For instance, Table.Header would render sort indicators based on useTable's sort state and trigger setSort on header clicks. Table.Pagination would use currentPage, totalPages, and goToPage to render controls. These components are primarily concerned with rendering UI based on the logic provided by useTable.
Accessibility Considerations: The solution incorporates WCAG guidelines. Table.Root would use role="table". Table.Header cells would have scope="col" and aria-sort attributes dynamically updated based on the sort state. Interactive elements like pagination buttons and column toggles would have appropriate aria-label attributes and keyboard navigation support.
Performance Optimizations: To handle large datasets, useMemo is applied to expensive computations within useTable, such as sorting and pagination, ensuring these operations only re-run when dependencies change. React.memo is used for individual table cells and rows to prevent unnecessary re-renders when their props haven't changed. For extremely large datasets, a virtualized list library would be noted as a potential future enhancement, but not implemented in the initial output to focus on core headless logic.
Testing Strategy: Unit tests for useTable.ts would cover sorting logic (single, multi-column, direction), pagination calculations (page changes, items per page), and column visibility toggling. Integration tests would verify that compound components correctly interact with the TableContext and trigger the expected state changes in useTable.