Skip to content

chore: Move shared table-role and async-store primitives from components - #242

Open
gethinwebster wants to merge 6 commits into
mainfrom
dev-v3-gethinw-shared-table-role-async-store
Open

chore: Move shared table-role and async-store primitives from components#242
gethinwebster wants to merge 6 commits into
mainfrom
dev-v3-gethinw-shared-table-role-async-store

Conversation

@gethinwebster

@gethinwebster gethinwebster commented Jul 29, 2026

Copy link
Copy Markdown
Member

Description

Moves table-role (grid navigation + ARIA role helpers) and async-store out of @cloudscape-design/components into component-toolkit so the existing Table and the upcoming BasicTable/VirtualTable can share them.

Byte-identical move (no behaviour change); adds two entrypoints: ./internal/table-role and ./internal/async-store.

Changes beyond the verbatim move (addressing Copilot review):

  • table-role/index.ts: re-export TableRole as a type-only export (export type { TableRole }) — unambiguous under the ESM build (the value form relied on tsc type-elision).
  • grid-navigation.md: fix a copy/paste typo in the Page Up bullet ("when moving down" → "when moving up"). Pre-existing in components main.

Related links, issue #, if available: n/a

How has this been tested?

  • New/moved unit tests for table-role (grid-navigation, grid-navigation-processor, table-role-helper, utils) and async-store pass in the toolkit build.
  • Verified downstream: @cloudscape-design/components was repointed locally to consume these via the new entrypoints; Table suites pass against the shared modules.

(Code will be removed from components repo once this package is merged & published, WIP: https://github.com/cloudscape-design/components/pull/4846/changes)

Review checklist

The following items are to be evaluated by the author(s) and the reviewer(s).

Correctness

  • Changes include appropriate documentation updates.
  • Changes are backward-compatible if not indicated, see CONTRIBUTING.md.
  • Changes do not include unsupported browser features, see CONTRIBUTING.md.
  • Changes were manually tested for accessibility, see accessibility guidelines.

Security

Testing

  • Changes are covered with new/existing unit tests?
  • Changes are covered with new/existing integration tests?

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

@gethinwebster
gethinwebster requested a review from a team as a code owner July 29, 2026 13:35
@gethinwebster
gethinwebster requested review from cansuaa and removed request for a team July 29, 2026 13:35
@codecov

codecov Bot commented Jul 29, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 98.98734% with 4 lines in your changes missing coverage. Please review.
✅ Project coverage is 98.07%. Comparing base (a7d0d07) to head (b98e5a2).

Files with missing lines Patch % Lines
src/internal/table-role/grid-navigation.tsx 98.31% 3 Missing ⚠️
src/internal/table-role/utils.ts 99.01% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #242      +/-   ##
==========================================
- Coverage   99.01%   98.07%   -0.94%     
==========================================
  Files          44       52       +8     
  Lines        1314     1764     +450     
  Branches      341      514     +173     
==========================================
+ Hits         1301     1730     +429     
- Misses         13       33      +20     
- Partials        0        1       +1     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@gethinwebster
gethinwebster marked this pull request as draft July 29, 2026 13:43
@gethinwebster gethinwebster changed the title Add shared table-role and async-store primitives feat: add shared table-role and async-store primitives Jul 29, 2026
…nents@main

Pure relocation of src/table/table-role/* and src/area-chart/async-store/* (+ use-previous
dep and render-hook test helper), original content and import paths (does not yet satisfy
component-toolkit lint by design).
@gethinwebster
gethinwebster force-pushed the dev-v3-gethinw-shared-table-role-async-store branch from 2ce878c to 72a67f9 Compare July 29, 2026 14:15
@gethinwebster gethinwebster changed the title feat: add shared table-role and async-store primitives chore: Move shared table-role and async-store primitives from components Jul 29, 2026
@gethinwebster
gethinwebster requested a review from Copilot July 30, 2026 08:34

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

This PR moves the shared table-role (ARIA role helpers + grid keyboard navigation) and async-store primitives into component-toolkit so multiple table implementations (current Table and upcoming BasicTable/VirtualTable) can reuse them via new internal entrypoints.

Changes:

  • Adds the src/internal/table-role module (helpers, grid navigation processor/provider, and docs) plus unit tests.
  • Adds the src/internal/async-store module (store + hooks) plus unit tests.
  • Exposes new package entrypoints ./internal/table-role and ./internal/async-store, and updates unit-test TS libs.

Reviewed changes

Copilot reviewed 17 out of 17 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
tsconfig.unit.json Extends unit-test TS libs to include dom.iterable.
package.json Adds exports entries for ./internal/table-role and ./internal/async-store.
src/internal/table-role/utils.ts Table/grid navigation DOM helpers (cells/rows, focus movement, span handling).
src/internal/table-role/table-role-helper.ts Helpers for applying ARIA/table role props across table structures.
src/internal/table-role/interfaces.ts Shared types for table role + grid navigation props/state.
src/internal/table-role/index.ts Public internal entrypoint re-exporting table-role utilities/provider.
src/internal/table-role/grid-navigation.tsx Grid navigation provider + processor implementing keyboard navigation behavior.
src/internal/table-role/grid-navigation.md Documentation of the grid navigation behavior and patterns.
src/internal/table-role/tests/utils.test.ts Unit tests for navigation utilities (colspan/rowspan + targeting).
src/internal/table-role/tests/table-role-helper.test.ts Unit tests for role prop helpers.
src/internal/table-role/tests/stubs.tsx Test table/controls used by grid navigation tests.
src/internal/table-role/tests/grid-navigation.test.tsx Integration-style tests for keyboard navigation behavior and suppression.
src/internal/table-role/tests/grid-navigation-processor.test.tsx Safety test for processor methods when uninitialized.
src/internal/async-store/use-previous.ts usePrevious hook used by selector logic.
src/internal/async-store/index.ts AsyncStore implementation + useReaction/useSelector hooks.
src/internal/async-store/tests/render-hook.tsx Minimal renderHook test utility for async-store tests.
src/internal/async-store/tests/async-store.test.ts Unit tests validating store subscription + hooks behavior.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/internal/table-role/grid-navigation.md Outdated
Comment thread src/internal/table-role/index.ts Outdated

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 17 out of 17 changed files in this pull request and generated 2 comments.

Comments suppressed due to low confidence (1)

src/internal/async-store/index.ts:88

  • usePrevious returns undefined on the first render, so this condition is true on initial mount and useSelector returns a freshly computed selector result instead of the memoized state. If the selector returns non-primitive values, this can cause a reference change without any store change. Check against undefined (or initialize usePrevious to null).
  if (prevStore !== null && prevStore !== store) {
    return selector(store.get());

// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

import { TableRole } from './interfaces.js';
Comment on lines +3 to +4

export type TableRole = 'table' | 'grid' | 'treegrid' | 'grid-default';

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 17 out of 17 changed files in this pull request and generated no new comments.

Comments suppressed due to low confidence (3)

src/internal/table-role/grid-navigation.tsx:5

  • React hooks are imported from react in two separate statements here. Consolidating into a single import keeps the file consistent and avoids duplicate module imports.
import React, { useRef } from 'react';
import { useEffect, useMemo } from 'react';

src/internal/async-store/tests/async-store.test.ts:7

  • The test suite name references AreaChart, but these tests exercise the generic AsyncStore utilities. Renaming the suite makes failures easier to interpret and avoids stale copy/paste context.
describe('AreaChart AsyncStore', () => {

src/internal/async-store/index.ts:88

  • usePrevious(store) returns undefined on the first render, so the prevStore !== null guard is always true and this branch will run whenever prevStore is still undefined. If the intent is to synchronously recompute only when the store instance changes, the guard should check for undefined (or a truthy previous value) instead of null.
  // When store changes we need the state to be updated synchronously to avoid inconsistencies.
  const prevStore = usePrevious(store);
  if (prevStore !== null && prevStore !== store) {
    return selector(store.get());
  }

@gethinwebster
gethinwebster marked this pull request as ready for review July 30, 2026 12:02
@gethinwebster
gethinwebster enabled auto-merge July 30, 2026 12:02
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