feat: add BasicTable (Release 1 / MLP) - #4940
Draft
gethinwebster wants to merge 7 commits into
Draft
Conversation
BasicTable is a low-level, composable table primitive. This first release covers the minimum lovable product surface: - Compound API: BasicTable + Header/HeaderCell/Body/Row/Cell parts - Fixed + auto column layout, content density - Grid keyboard navigation (shared roving-tabindex model) + ARIA grid semantics - Row-scoped selected/striped props; variant='selection'; aria-sort passthrough - Empty / loading content slots - Consumer owns rows/state (sorting, selection, filtering, virtualization are composable) Deferred to later releases (not in this change): sticky header/columns, column resizing, row expansion, truncation/wrapText, bounded scroll height, grouped columns, chrome variants. Test utils: BasicTableWrapper. Dev pages under pages/basic-table/.
Move BasicTable and its parts from the versioned beta path
src/beta/basic-table-0.1/ to top-level GA components under src/:
BasicTable + BasicTable{Header,HeaderCell,Body,Row,Cell}, each exported
from the stable package (no longer at the /beta/basic-table-0.1 subpath).
- git mv the 6 component dirs + __tests__ to src/*; drop the beta barrel
- fix relative import depths (../../../ -> ../) and test-util/page/beta-lib paths
- revert the now-dead beta build-tools plumbing (listBetaItems, beta subpath,
getBetaComponentNames); keep the BasicTable pluralize entry
- tests import parts from the top-level barrel; pages use ~components/basic-table
…ocblocks
- Public BasicTableProps: columns, columnLayout?, role? (default 'table'), ariaLabel/ariaLabelledby/ariaDescribedby, totalRowCount?, children
- ColumnDefinition: { width?, minWidth? }; positional column binding only
- RowProps.index optional (virtualization only); no RowProps.id
- Remove contentDensity (inherited from ambient context), empty/loading (composable), i18nStrings, columnId
- StructuralPartProps forwards ref; docblocks rewritten to Cloudscape Table conventions
- Public interfaces import BaseComponentProps from ../types/base-component
- Dev pages and unit tests updated to the finalized surface
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} | ||
| > |
The pages tsconfig (webpack ts-loader) type-checks pages/, which the root tsconfig excludes; these id={item.id} usages on BasicTableRow broke buildPagesStatic on CI.
- Use a constant grid-navigation page size (10, matching Table) instead of deriving from totalRowCount, so PageUp/PageDown move by a constant amount. - Give the scrollable region an accessible name from ariaLabelledby as well as ariaLabel. - findRowByIndex indexes the class-filtered data rows so a composed loading/empty row does not offset it.
findRows()[index] only compiles for the dom wrapper (array); the generated selectors variant returns MultiElementWrapper (TS7052). Use the CSS nth-child selector, which compiles in both. The body contains only BasicTableRow elements, so nth-child is accurate.
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 BasicTable — a low-level, composable table primitive — as a GA component at
src/basic-table. Ships as a flat API:BasicTable(root) plusBasicTableHeader/BasicTableHeaderCell/BasicTableBody/BasicTableRow/BasicTableCell, each a top-level component with its own export path and documentation.This is the Release 1 / minimum lovable product (MLP) slice, per the tech design and API review.
What's in this release
selected/stripedprops;variant="selection";aria-sortpassthroughTest utils:
BasicTableWrapper. Dev pages underpages/basic-table/.Deferred to later releases
Sticky header/columns, column resizing, row expansion, truncation/
wrapText, bounded scroll height, grouped columns, chrome variants.Testing
tsc --noEmitclean across the project; carved unit suites pass locally (37 tests) and documenter / test-utils snapshots pass. Draft — parity dev-page review and Copilot/AutoSDE pass to follow; CI is the authoritative build/lint/unit/integ signal.Commits
feat(beta)— introduce BasicTable at the MLP surfacerefactor— promote from beta to GA (src/beta/basic-table-0.1→src/basic-table)