feat: add atomic table components (Release 1 / MLP) - #4940
Draft
gethinwebster wants to merge 6 commits into
Draft
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
Adds a new GA BasicTable component family (root + structural subcomponents) as a low-level, composable table primitive with shared column layout, optional grid keyboard navigation, and supporting dev pages/test utilities.
Changes:
- Introduces the headless
useBasicTablehook plus compound components (BasicTable*) built on it. - Adds BasicTable styling (Cloudscape-tokenized), DOM test-utils wrapper, and comprehensive unit/a11y tests.
- Adds dev/demo pages showcasing composition patterns (selection, striping, sorting, loading/empty, keyboard scroll) and updates build/test snapshots and pluralization utilities.
Reviewed changes
Copilot reviewed 33 out of 33 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| src/test-utils/dom/basic-table/index.ts | Adds BasicTableWrapper DOM test util helpers. |
| src/basic-table/use-basic-table.ts | Implements headless useBasicTable prop-getters (ARIA + grid template). |
| src/basic-table/styles.scss | Adds tokenized SCSS styling for BasicTable (grid layout, selection, striping, states). |
| src/basic-table/internal.tsx | Implements compound components + auto column sizing + scroll wrapper behavior. |
| src/basic-table/interfaces.ts | Defines public props and internal hook config/types. |
| src/basic-table/index.tsx | Exports the root BasicTable component and props type. |
| src/basic-table/context.ts | Adds context wiring for table, row state, and positional column indices. |
| src/basic-table/tests/use-basic-table.test.tsx | Unit tests for useBasicTable getters + raw-DOM contract proof. |
| src/basic-table/tests/setup.ts | Registers shared a11y matcher for BasicTable tests. |
| src/basic-table/tests/basic-table.test.tsx | Tests compound component rendering + wrapper discoverability. |
| src/basic-table/tests/basic-table-styling-props.test.tsx | Tests styling hooks (selected/striped/selection variant) + auto layout branch. |
| src/basic-table/tests/basic-table-i18n.test.tsx | Tests accessible naming via ariaLabel. |
| src/basic-table/tests/basic-table-a11y.test.tsx | Axe + keyboard navigation + ARIA coherence tests for role=grid. |
| src/basic-table/tests/stubs/styles-stub.js | Adds a styles module stub for tests running from source. |
| src/basic-table-row/index.tsx | Adds top-level BasicTableRow export wrapper. |
| src/basic-table-header/index.tsx | Adds top-level BasicTableHeader export wrapper. |
| src/basic-table-header-cell/index.tsx | Adds top-level BasicTableHeaderCell export wrapper. |
| src/basic-table-cell/index.tsx | Adds top-level BasicTableCell export wrapper. |
| src/basic-table-body/index.tsx | Adds top-level BasicTableBody export wrapper. |
| src/tests/snapshot-tests/snapshots/test-utils-wrappers.test.tsx.snap | Updates generated wrapper snapshots to include BasicTable wrapper APIs. |
| src/tests/snapshot-tests/snapshots/test-utils-selectors.test.tsx.snap | Updates generated selectors snapshot output. |
| src/tests/snapshot-tests/snapshots/documenter.test.ts.snap | Updates documenter snapshot to include BasicTableWrapper method docs. |
| pages/basic-table/striped-rows.page.tsx | Adds dev page demonstrating row striping + selected override. |
| pages/basic-table/simple.page.tsx | Adds basic non-sticky BasicTable dev page. |
| pages/basic-table/shift-selection.page.tsx | Adds dev page demonstrating composed shift-range selection. |
| pages/basic-table/selection.page.tsx | Adds dev page demonstrating composed selection patterns and disabled rows. |
| pages/basic-table/permutations.page.tsx | Adds dev page matrix for role/striped/selected permutations. |
| pages/basic-table/multi-column-sort.page.tsx | Adds dev page demonstrating composed multi-column sort with aria-sort. |
| pages/basic-table/loading-and-empty.page.tsx | Adds dev page showing composed loading/empty rows. |
| pages/basic-table/keyboard-scroll.page.tsx | Adds dev page demonstrating horizontal keyboard scroll region behavior. |
| pages/basic-table/compact-mode.page.tsx | Adds dev page demonstrating inherited compact density styling. |
| pages/basic-table/common.tsx | Adds shared dev-page helpers (columns + header/body renderers). |
| build-tools/utils/pluralize.js | Adds pluralization mapping for BasicTable. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| }); | ||
|
|
||
| const columnCount = table.columnCount; | ||
| const pageSize = Math.max(1, Math.min(totalRowCount || 1, 100)); |
Comment on lines
+292
to
+295
| role={isScrollable ? 'region' : undefined} | ||
| tabIndex={isScrollable ? 0 : undefined} | ||
| aria-label={isScrollable ? ariaLabel : undefined} | ||
| > |
gethinwebster
force-pushed
the
dev-v3-gethinw-basic-table-mlp
branch
from
September 3, 2026 09:25
ab45dac to
81124ca
Compare
Flat compound parts: TableRoot, TableHead, TableHeaderRow, TableHeaderCell,
TableBody, TableRow, TableCell. Table composes the atomic Row/Cell for its body
hot path (plain-data, selection-control, sticky, wrap, resizable), sharing the
selection/stripe/divider geometry via _selection-mixins so there is a single
source of truth.
- columnLayout: { type: 'auto' } (default) | { type: 'grid', columns }
- TableRow variant: 'default' | 'selected' | 'shaded' (visual only)
- curated flat aria props; disablePaddings on TableCell/TableHeaderCell
- fixed-height bring-your-own virtualization via style props on Body/Row
TableBody/TableRow no longer walk or clone their children to flag the last row. The last-row divider suppression and selected-last-row height compensation move to a positional :last-child rule in table-body styles, scoped under .body so the Table-reuse path (plain <tbody>) is unaffected. Shared cell padding constants are extracted to table-cell/constants so both modules stay in lock-step. This is composition-safe and drops the cloneElement machinery.
Mirror the status-indicator internal-component idiom across all 7 parts: - named exported InternalTable<X>Props interface (extends the public props + InternalBaseComponentProps); internal-only flags live inside it - uniform InternalTable<X> naming (was InternalRoot + bare Head/Body/Row/Cell) - default-export function with destructured params + getBaseProps(rest) - value-style props re-export in index.tsx, default-importing the internal - table-cell's separate internal props interface merged into the single InternalTableCellProps (dual-consumer substrate note kept) Also drops fluff comments and regenerates the two stale generated-artifact snapshots (documenter Style.height Property.Height collapse; the dedup-dropped classic body-cell test-utils selector). Behavior-neutral: no public API, DOM, or CSS change.
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #4940 +/- ##
==========================================
- Coverage 97.67% 97.66% -0.01%
==========================================
Files 960 983 +23
Lines 31376 31572 +196
Branches 11597 11681 +84
==========================================
+ Hits 30645 30834 +189
- Misses 724 731 +7
Partials 7 7 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds the atomic table components (Release 1 / MLP): flat compound parts that give consumers control over individual row and cell rendering, instead of the configuration-driven auto-rendering of
Table. Ships GA incloudscape-design/components.Parts:
TableRoot,TableHead,TableHeaderRow,TableHeaderCell,TableBody,TableRow,TableCell.API per the API proposal.
API
columnLayout?: { type: 'auto' } | { type: 'grid'; columns }—auto(content-sized, default) orgrid(explicit/proportional widths; the basis for virtualization). Column widths live only on the grid variant, so the correlation is type-enforced.TableRowvariant: 'default' | 'selected' | 'shaded'— visual only; the consumer setsariaSelectedexplicitly.aria*props (Root / Row / HeaderCell) — no blanketaria-*passthrough.disablePaddingsonTableCell/TableHeaderCellfor exact control columns (e.g. a centered selection control).styleonTableBody/TableRow.Reuse with
TableTablecomposes the atomicTableRow/TableCellas its body<tr>/<td>for the common path (plain-data, selection-control, sticky, wrap-lines, resizable columns). The selection / stripe / divider / padding geometry lives once in_selection-mixins.scss, shared by bothTable's body-cell and the atomic cell — one source of truth for the box model. Editable/expandable/treegrid rows, row-header<th>, and header cells stay native.Deferred (each its own later review)
Grid keyboard navigation (
role='grid'), sticky header, bounded internal scroll viewport, column resizing, row expansion, truncation vs wrapping, skeleton loading, grouped columns, auto-measured dynamic row-height virtualization, and id-based column binding.Testing
Table-reuse selection/stripe paths.Table(selection reflow, control alignment, first/last row, sticky columns): selected rows are constant-height (no row reflow on select).