Skip to content

docs(useTableSortableState): add hook docs and a multi-sort orders example block - #9911

Merged
cixzhang merged 2 commits into
meta:mainfrom
MannXo:docs/9480-usetablesortablestate-example
Nov 5, 2026
Merged

cixzhang merged 2 commits into
meta:mainfrom
MannXo:docs/9480-usetablesortablestate-example

Conversation

@MannXo

@MannXo MannXo commented Nov 4, 2026

Copy link
Copy Markdown
Contributor

Reader impact

useTableSortableState has no HookDoc, so it has no docsite page and astryx hook useTableSortableState finds nothing. After this change it has a page with its config, its four return values and when to use useTableSortable instead, and an example. An orders Table has no sort code of its own: the hook owns the sort state, returns the sorted rows and hands useTableSortable its config. Clicking Customer and then Shift-clicking Total sorts by customer, then by total within each customer, and a line above the table reads the current sort state from the hook. It pairs with the useTableSortable page, which shows the controlled path. astryx template useTableSortableStateHookUsage <path> copies it.

Source of truth

  • packages/core/src/Table/plugins/sortable/useTableSortableState.tsx (config, default comparator, controlled and uncontrolled state, applySort) and useTableSortable.tsx for the header click behavior the passed-through options control.
  • architecture:knowledge-contracts INV28.

Correction

  • Adds packages/core/src/Table/plugins/sortable/useTableSortableState.doc.mjs next to the source, as the issue asks (a HookDoc, docs + docsDense, group: 'Table', importPath: '@astryxdesign/core/Table').
  • Adds blocks/components/Table/useTableSortableStateHookUsage (exampleFor: 'useTableSortableState'). It calls useTableSortableState<Order>({data: orders, isMultiSortEnabled: true}), passes sortConfig to useTableSortable, renders sortedData, and prints sort. Seven orders across three customers, so the Total tiebreaker changes the order within each customer.
  • Updates the recorded module resolution for useTableSortableState in packages/cli/api/component/__fixtures__/resolutions/modules.txt (it now opens its own doc instead of falling back to Table/Table.doc.mjs), as test: main is green again: Tokenizer's sheet-row test passes presentation, and the recorded module resolutions follow core #9851 did for useLightbox.

Evidence

  • Real Chromium (Playwright against the docsite dev server, /components/useTableSortableState, 1280x900).

    Action Sort state line Order column aria-sort
    (start) none 1042 1043 1044 1045 1046 1047 1048 not set
    Click Customer customer ascending 1043 1045 1048 1044 1047 1042 1046 Customer ascending
    Shift-click Total customer ascending, then total ascending 1045 1048 1043 1044 1047 1046 1042 Customer ascending (priority 1 of 2), Total ascending (priority 2 of 2)

    No page errors.

  • Test (packages/cli/api/template/use-table-sortable-state-hook-usage.test.tsx, 3 cases). It asserts the same three orders and sort lines. With the hook replaced by the unsorted data and a fixed empty sort, the two sorting cases fail.

  • packages/cli/api/build/tree.test.mjs pins the blocks astryx build picks for "analytics dashboard with a KPI row and a sortable table". A first description with "rows" and "Table" in it pushed TableStripedTable out of that list, so the block's description talks about orders instead. The pinned list is unchanged.

Scope

  • This PR changes documentation only, or names every necessary generated artifact. The generated artifacts are the block's route and the hook's route in internal/shadcn-registry/routes.lock.json, the block's sandbox route in apps/sandbox/scripts/next-export-routes.json, and the recorded resolution above.
  • Runtime, API, visual, and policy changes were removed or split.
  • Public text and artifacts contain no internal Meta context.

Testing

  • vitest run --project node packages/cli/foundation/discovery packages/cli/api/template packages/cli/assets/templates internal/shadcn-registry apps/sandbox/src/route-manifest.test.ts packages/cli/api/build packages/cli/test/experimental-isolation.test.mjs packages/cli/api/component packages/cli/api/docs packages/cli/api/hook: 1689 passed, 0 failed.
  • vitest run --project ui packages/core/src/docPropLiterals.test.ts packages/core/src/docPropReferences.test.ts packages/core/src/Table/plugins/sortable: 92 passed.
  • apps/docsite: pnpm generate, then vitest run src/__tests__/data-extraction.test.ts src/__tests__/example-coverage.test.ts: 136 passed, 0 failed. The route lock check is clean after UPDATE_SHADCN_ROUTE_LOCK=1 added the two routes.
  • pnpm lint:strict: clean (0 errors).
  • pnpm -F @astryxdesign/cli typecheck: clean.
  • node scripts/release/changeset-coverage.mjs pr --base upstream/main --head HEAD --released v0.7.7: passes. Changeset names @astryxdesign/core and @astryxdesign/cli, patch, [docs].
  • .github/scripts/check-public-text.mjs over this commit, title and description: no findings.
  • Not run: the full pnpm test suite.

Notes for reviewers

  1. The other Table hooks (useTableSortable, useTableSelectionState and so on) are documented as ComponentDocs with subComponentOf: 'Table' in packages/core/src/Table/. The issue asks for a HookDoc next to the source, with params and returns, so that is what this adds. If the Table family should stay on its own shape, the same content can move to Table/useTableSortableState.doc.mjs as a subComponentOf doc.
  2. The hook's allowUnsortedState comment says @default true, and the plugin does fall back to true (cfg.allowUnsortedState ?? true), so the new doc says true. useTableSortable.doc.mjs lists that option's default as false, which looks stale. I left it alone here.

Fixes #9480

@vercel

vercel Bot commented Nov 4, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
astryx Ready Ready Preview Nov 5, 2026 4:04pm UTC

Request Review

@meta-cla meta-cla Bot added the CLA Signed This label is managed by the Meta Open Source bot. label Nov 4, 2026
@astracat-bot

astracat-bot Bot commented Nov 4, 2026 •

Copy link
Copy Markdown
Contributor

AI review status for this pull request.

Review status Updated
🟢 Reviewed (for maintainers only) Nov 5, 2026, 4:10 PM UTC

@github-actions github-actions Bot added community Authored by a community contributor (not on the eng/design team) needs:code-review High-risk change (new package/component/API) — needs human code review before merge needs:design-review Affects visuals — Design should review labels Nov 4, 2026
@github-actions

github-actions Bot commented Nov 4, 2026 •

Copy link
Copy Markdown
Contributor

PR Analysis Report

🔎 Preview · bb970f5

Storybook · Sandbox · built from this PR's head

Modified components

Component Size LoC Visual · A11y · RTL
TableBody 3.4 kB (0) · 3.3 kB CSS (0) — ✓ · ✓ · ✗
TableFooter 3.4 kB (0) · 3.3 kB CSS (0) — ✓ · ✓ · ✗
TableHeader 3.4 kB (0) · 3.3 kB CSS (0) — ✓ · ✓ · ✗
5 more components
Component Size LoC Visual · A11y · RTL
TableRow 6.5 kB (0) · 4.0 kB CSS (0) — ✓ · ✓ · ✗
Table 83.5 kB (0) · 16.1 kB CSS (0) — ✓ · ✓ · —
TableCell 75.1 kB (0) · 15.9 kB CSS (0) — ✓ · ✓ · ✓
TableHeaderCell 74.7 kB (0) · 15.6 kB CSS (0) — ✓ · ✓ · ✓
TableSelectionToolbar 54.4 kB (0) · 11.8 kB CSS (0) — ✓ · ✓ · ✓

Package size:

  • @astryxdesign/cli 3.34 MB packed (+720 B); no new dependencies
  • @astryxdesign/core 6.31 MB packed (+1.3 kB); no new dependencies

API changes: none in this pull request

Committed API report behind this build: cli 8 rows, theme-butter 1 row, theme-chocolate 1 row, theme-gothic 1 row, theme-matcha 1 row, theme-neutral 1 row, theme-stone 1 row, theme-y2k 1 row; run pnpm api:report.

Touched components checked; add ci:run-visual, ci:run-a11y or ci:run-rtl to run the full suites.


Generated by PR Enrichment workflow | View full report

@astracat-bot astracat-bot Bot 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.

Thanks for this: the hook doc and the multi-sort orders block close #9480 well, and the block gets all of its sorting from the hook. One change is needed before approval:

  • The comparators description says null, undefined and NaN sort last (useTableSortableState.doc.mjs lines 58 and 142), but in a descending sort the hook puts them first, as its own test "sorts NaN to the start in descending order, like null" asserts, so please change both strings to "last in ascending order and first in descending".

While you are there (optional): with an empty sort state, sortedData is data itself, not a copy. CI has not run on this head yet. It waits for a maintainer to add the ci:run label.

[Automated review]

name: 'config.comparators',
type: 'Partial<Record<TSortKey, (a: T, b: T) => number>>',
description:
'Ascending comparators per sort key; the hook flips the result for descending. Keys without one compare numbers numerically, compare other values as strings with a numeric collator in the active InternationalizationProvider locale, and put null, undefined and NaN last.',

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.

In a descending sort the hook negates the default comparator's result too, so null, undefined and NaN come first, not last. useTableSortableState.test.tsx asserts this in "sorts NaN to the start in descending order, like null". Suggested ending: ...and put null, undefined and NaN last in ascending order and first in descending.

'config.sort': 'controlled sort state; pair with onSortChange.',
'config.onSortChange': 'called with next sort state; required with sort.',
'config.comparators':
'ascending comparators per key (flipped for descending). Else numbers numeric, others numeric-collator strings in provider locale; null/undefined/NaN last.',

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.

Same here: in a descending sort, missing values come first. Suggested ending: null/undefined/NaN last ascending, first descending.

@astracat-bot astracat-bot Bot 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.

Approved pending CI: CI has not run on this head yet, so a maintainer needs to add the ci:run label for it to run.

Thanks for the quick fix. The comparators row now says missing values sort last in ascending order and first in descending, which matches the hook, and the hook doc and multi-sort orders block meet the hook-example rule (INV28): the block gets all of its sorting from the hook.

  • Optional: with an empty sort state the hook returns data itself, so the config.data and sortedData rows could say "a sorted copy of data, or data itself while unsorted".

[Automated review]

name: 'sortedData',
type: 'T[]',
description:
'A sorted copy of data, memoized on data and the sort state. Ties keep their order in data.',

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.

Optional: with an empty sort state the hook returns data itself (useTableSortableState.tsx lines 212-213), not a copy. Consider "A sorted copy of data, or data itself while unsorted, …" here and in the config.data row and the two dense lines.

@cixzhang cixzhang added the ci:run A maintainer lets this outside contributor's pull request run CI (AST-030 FR17) label Nov 5, 2026
@cixzhang cixzhang closed this Nov 5, 2026
@cixzhang cixzhang reopened this Nov 5, 2026
@github-actions github-actions Bot removed the needs:code-review High-risk change (new package/component/API) — needs human code review before merge label Nov 5, 2026
@cixzhang
cixzhang merged commit 5f8a809 into meta:main Nov 5, 2026
115 of 119 checks passed

This branch was successfully deployed

1 active deployment
Preview — bb970f5e Deployed Nov 5, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci:run A maintainer lets this outside contributor's pull request run CI (AST-030 FR17) CLA Signed This label is managed by the Meta Open Source bot. community Authored by a community contributor (not on the eng/design team) needs:design-review Affects visuals — Design should review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

docs(useTableSortableState): add hook docs and a minimal live example

2 participants