Skip to content

feat: add BasicTable (Release 1 / MLP) - #4940

Draft
gethinwebster wants to merge 7 commits into
mainfrom
dev-v3-gethinw-basic-table-mlp
Draft

feat: add BasicTable (Release 1 / MLP)#4940
gethinwebster wants to merge 7 commits into
mainfrom
dev-v3-gethinw-basic-table-mlp

Conversation

@gethinwebster

@gethinwebster gethinwebster commented Aug 27, 2026

Copy link
Copy Markdown
Member

Summary

Adds BasicTable — a low-level, composable table primitive — as a GA component at src/basic-table. Ships as a flat API: BasicTable (root) plus BasicTableHeader / 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

  • Fixed and 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 and state — sorting, selection, filtering, and virtualization are composable

Test utils: BasicTableWrapper. Dev pages under pages/basic-table/.

Deferred to later releases

Sticky header/columns, column resizing, row expansion, truncation/wrapText, bounded scroll height, grouped columns, chrome variants.

Testing

tsc --noEmit clean 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

  1. feat(beta) — introduce BasicTable at the MLP surface
  2. refactor — promote from beta to GA (src/beta/basic-table-0.1src/basic-table)

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

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 useBasicTable hook 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.

Comment thread src/basic-table/internal.tsx Outdated
});

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}
>
Comment thread src/test-utils/dom/basic-table/index.ts
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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants