fix(docsite): render the component anatomy table - #4847
Conversation
Anatomy.tsx has existed since the doc site landed (f45f465) but nothing ever imported it -- `git log -S Anatomy` on ComponentDetailClient.tsx is empty, so it was never wired rather than deliberately unwired. Meanwhile 55 component entries carry `usage.anatomy` (236 elements, 97 of them required): generate-data.mjs passes the whole `usage` block through, and the emitted registry type declares the field. The data reached the page and had nowhere to go, so the docsite silently showed nothing while the CLI rendered the same data at clients/cli/lib/component-format.mjs:207. Wire Anatomy into the Overview tab, placed before Best practices to match the CLI's section order, and align its heading with its peer section (level 2 / display-3, gap 4) instead of a bare level-3. Add a wiring test that fails if any module under component-detail/ becomes unreachable from an import, resolving specifiers the way the bundler does so a package path like `@astryxdesign/core/Section` cannot be mistaken for a local file. That directory holds only internal building blocks -- no route entry points, no script-consumed modules -- so an orphan there is always a bug. A second test guards the generator against dropping `anatomy` from the `usage` block it forwards. No issue filed; found while triaging an unrelated documentation RFC.
|
@AKnassa is attempting to deploy a commit to the Meta Open Source Team on Vercel. A member of the Team first needs to authorize it. |
kentonquatman
left a comment
There was a problem hiding this comment.
Please wrap the table in a card so that it matches the styling of all other tables on this page. The "required" badge also seems oddly positioned in the screenshot. Please update so that it's an inline bold text element as part of the description (eg. "Required: Avatar elements that from...").
Review feedback on facebook#4847. The anatomy table rendered bare while the tables around it sit in cards. BestPracticesBlock -- directly below it in the same Usage block -- wraps its Table in `<Card variant="default">`, and the /docs TableBlock does the same. Match them. The required flag lived in its own 80px column under an empty header, so the badge floated in a gap between Element and Description. Fold it into the description as a bold `**Required:**` lead-in instead, which also retires an empty table header. This mirrors how the CLI marks its guidance rows (`**Do:**` / `**Don't:**` in component-format.mjs), so a required part reads the same way in both surfaces. The shaping lives in anatomyHelpers.ts, following the themingHelpers.ts split, so the lead-in logic is unit-testable without rendering React.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
cixzhang
left a comment
There was a problem hiding this comment.
Thanks — both of Kenton's asks are in; approve. Description still shows the badge column. Red Vercel looks like the DerivedVar error you flagged, since fixed on main — try a merge.
[Reviewed by Robohands]
| // Guard against a vacuous pass if the directory is ever moved or renamed. | ||
| expect(detailModules.length).toBeGreaterThan(5); | ||
|
|
||
| const imported = collectImportedFiles(walk(SRC_DIR)); |
There was a problem hiding this comment.
A unit test on an orphan silences this. Might need the .test. filter from :83.
| { | ||
| key: 'name', | ||
| header: 'Element', | ||
| width: pixel(140), |
There was a problem hiding this comment.
140 hard-breaks Optional/Requ ired indicator on the Field page. Might need a little more width.
Both asks are in at f055409 — the table is wrapped in Card variant="default" matching BestPracticesBlock, and required is now a bold **Required:** lead-in inside the description rather than a badge column. Dismissing so this can land; reopen if the rendering is not what you meant.
|
Merged — I merged [Reviewed by Robohands] |
…id-word Two defects the #4847 review surfaced, both ours. The component-detail wiring guard collected importers by walking all of src/, so a renderer imported only by its own unit test counted as wired. Unwire Anatomy and add a test that imports it and the guard goes green while the section ships dark — exactly what it exists to prevent. Walk the import graph out from app/ instead: reachability from the router, not "somebody imports it". That also closes the case the .test. filter would have left open — a module reached only by other modules the page never reaches. The Anatomy table lays out fixed at pixel(140), leaving ~108px of content box. "Optional/Required" (Field) and "Collapse/expand" (SideNav) are wider than that and a solidus is not a break opportunity in CSS the way a hyphen is, so Chromium breaks them inside a word instead: "Optional/Requ / ired indicator". Offer the break the text implies with a <wbr /> after each solidus. Nothing moves: the column stays 140px on every component page.
…id-word (#5391) Two defects the #4847 review surfaced, both ours. The component-detail wiring guard collected importers by walking all of src/, so a renderer imported only by its own unit test counted as wired. Unwire Anatomy and add a test that imports it and the guard goes green while the section ships dark — exactly what it exists to prevent. Walk the import graph out from app/ instead: reachability from the router, not "somebody imports it". That also closes the case the .test. filter would have left open — a module reached only by other modules the page never reaches. The Anatomy table lays out fixed at pixel(140), leaving ~108px of content box. "Optional/Required" (Field) and "Collapse/expand" (SideNav) are wider than that and a solidus is not a break opportunity in CSS the way a hyphen is, so Chromium breaks them inside a word instead: "Optional/Requ / ired indicator". Offer the break the text implies with a <wbr /> after each solidus. Nothing moves: the column stays 140px on every component page.
What this does
Component pages on the doc site now show an Anatomy table — the named parts a
component is made of, and what each one is for. Avatar, for example, now lists Photo,
Initials, Default icon, and Status dot.
Why
That information was already written down and already reaching the page — 55 components
describe their anatomy, 236 parts in total. The table that displays it had been built too.
It just was never connected to anything, so the doc site quietly showed none of it while
the CLI (
astryx component <Name>) showed it all.So this isn't new content or a new feature. It's switching on writing that authors have
been doing all along.
What changed
its parts, and shows nothing when it doesn't.
practices). It had been set smaller.
again, which is the exact way this was missed.
No changes to any published package, and no change to what authors write.
For reviewers: how it was never noticed
Anatomy.tsxarrived with the doc site in f45f465 and was never imported —git log -S "Anatomy"onComponentDetailClient.tsxreturns nothing, so it was neverwired rather than deliberately unwired. The data path was always intact:
generate-data.mjsforwards the wholeusageblock, and the emitted registry typedeclares
anatomy.The new test resolves import specifiers the way the bundler does, so a package path like
@astryxdesign/core/Sectioncan't be mistaken for a local file. It's scoped tocomponent-detail/on purpose — that folder holds only internal building blocks, with noroute entry points and no script-consumed modules, so an unimported file there is always
a bug.
Two notes on scope.
ThemeShowcaseTile.tsxis a second orphan from the same commit; it'sleft alone because where it belongs on
/themesis a design question, not a wiring bug.And the docsite typecheck reports one pre-existing error in the generated registry
(
DerivedVar."replaces") — verified identical with these changes reverted.How to see it
requiredbadge on a rowTests:
pnpm -F @astryxdesign/docsite test— 21 files, 326 tests.