UI Library docs: page-per-component + source-generated tables (3/3) - #46
Open
librowski wants to merge 32 commits into
Open
UI Library docs: page-per-component + source-generated tables (3/3)#46librowski wants to merge 32 commits into
librowski wants to merge 32 commits into
Conversation
This was referenced Jun 24, 2026
librowski
marked this pull request as ready for review
June 24, 2026 12:31
librowski
requested review from
lukasz-jazwa,
piotrblaszczyk and
szymon-t-sc
as code owners
June 24, 2026 12:31
librowski
force-pushed
the
ui-consumers
branch
2 times, most recently
from
July 31, 2026 08:41
7970aa1 to
6192878
Compare
…tyle props/CSS tables Wrap every UI Library example in a shadow-DOM ComponentPreview so components are styled only by @workflowbuilder/ui (isolated from Starlight CSS), shown in a fixed 2:1 dotted preview box that matches the original Overflow UI docs. Collapse each example island to a single representative instance. Rework the generated Props and CSS-variable references from tables into card lists: props show a 'required' chip (required-first) instead of a line-wrapping '?' marker, with Type/Default/description rows; CSS variables group into Color/Size. Drop the now-unused example-frame styles.
Give the Edge, NodeIcon, NodeDescription and NodePanel pages the same shadow-DOM ComponentPreview the UI components use, rendering each as a standalone example (NodePanel compositions; EdgeLabel variants positioned relatively outside a canvas) for parity with the original Overflow UI docs. NodeAsPortWrapper stays props-only, matching the reference. Adds @phosphor-icons/react to the docs app for the example icons.
Status is an absolutely-positioned corner badge; rendered standalone it had no positioned ancestor and floated to the wrong place. Wrap it in a relative box that stands in for the node/field it marks, so it sits in the top-right corner as intended.
The UI Library overview told consumers to install @base-ui/react alongside the package. It is now a regular dependency that installs automatically; react and react-dom are the only peers.
@workflowbuilder/ui components and generate-ui-api.mjs's TypeDoc pass both need packages/ui/dist to exist; add a Build UI step ahead of Build docs, mirroring the existing Build SDK step.
- Fix the generator's lint errors (renamed vars for clarity, imported node:process, top-level await with process.exitCode instead of process.exit/main().catch, matching tools/preflight.mjs's pattern). - Strip internal engineering notes (matching /missing token/i) out of CSS variable comments instead of rendering them on the public docs pages. - Treat an unresolved props type as fatal (process.exitCode = 1) instead of a warning, so a renamed/typo'd type can't silently ship an empty page. - Add collectVariantProps() to merge Button's discriminated-union variant props (Label/Icon/IconLabel) into one deduped table with per-variant notes, and switch the TypeDoc entry point from index.ts (resolve) to src/components (expand) so those variant-only prop types get full reflections. - Add a check-ui-component-coverage.mjs guard, wired into generate:ui-api, asserting every packages/ui/vite.config.mts componentEntries item has a matching COMPONENTS entry, so a new published component can't ship without a docs page. - Run generate:ui-api before astro check in typecheck, so the coverage guard and generator failures surface there too. The unrelated PropRow/CssVar -> PropertyRow/CssVariable renames in props-table.astro / css-variables-table.astro are a lint-driven cleanup in the same generator/docs-api area.
- Add a Collapsible page: intro, live example, Usage, a hand-authored Parts table for Collapsible.Button/Collapsible.Content (no exported prop type to key a generated table on, same precedent as NodePanel), and generated Props/CSS variables tables. List it in the components index. - Add an Icon switch section to the Switch page documenting IconSwitch (live example, Usage, generated Props/CSS variables tables). - Rewrite the overview's Styles section: importing from the package root auto-injects the layer order/reset/tokens setup, so only tokens.css is needed; the styles.css + tokens.css pair only applies to the per-component subpath-import path. Matches packages/ui/README.md and packages/ui/css-layers.md. Depends on the collapsible/icon-switch COMPONENTS entries and the Button-variant TypeDoc entry point switch landed in the generator commit.
The runtime default (shape = 'default' in the forwardRef destructure) was documented as @default '' in the TSDoc comment, which the UI Library docs render verbatim.
Resolves vite-plugin-dts, vite-plugin-svgr, and i18next/react-i18next to a single typescript@5.9.3 peer resolution instead of a stale mixed 5.6.3/5.9.3 set, matching --frozen-lockfile.
Helper types like WithIcon live in src/shared, outside the components entry tree, so they got no reflection and their members (Accordion's and Modal's icon prop) silently vanished from the generated tables.
…views Modal, Menu, Select, Tooltip and DatePicker portal their popups to body, outside the shadow roots that carry the preview styles - the popups rendered unstyled. The library CSS is fully layered with no reset, so loading it globally is safe for the Starlight theme.
Every built stylesheet has carried the @layer order statement since the stamping fix, so 'import styles.css before any component' is no longer a correctness requirement; styles.css also ships no reset, only typography.
The docs generator reads the exported DatePickerProps, but the props the component actually accepts (value, defaultValue, placeholder, valueFormat, type, error) lived on an unexported local widening type - the generated table documented none of the props the page's own example uses. The widening moves into the exported type, TSDoc included.
… merge SegmentPicker's discriminated union was flattened first-wins: the table claimed value is always required and typed defaultValue as never, contradicting the page's own controlled/uncontrolled prose. NavButton was generated from its flat base type, so children - the prop its page is about - never appeared. Both now list their variant prop types, and a variant's 'foo?: never' exclusion counts as the prop being absent there instead of polluting the merged type.
Four holes of the same class - the tool swallowing a problem and shipping a plausible-looking page: - a moved/renamed component directory made extractCssVariables glob nothing and exit 0 (page claims 'no CSS variables') - an unknown slug in PropsTable/CssVariablesTable rendered the empty state instead of failing the build (typo = false page in production) - a first-party type hidden behind an unresolvable utility wrapper (Partial/Omit) dropped its props with no trace - the class that once got the library reshaped to suit the generator - findTypeByName picked the first of duplicate type names silently
Every docs gate (ui-api generator, component-coverage guard, astro page rendering) used to run for the first time at release-time deploy - a broken docs change merged green and surfaced weeks later as a red deploy. Path-filtered to docs/ui/tokens changes so unrelated PRs pay nothing.
The index pages sorted alphabetically inside their own groups (the 'UI Components' link sat 7th within UI Components). Order 0 plus an Overview label matches the plugins/nodes convention; link lists use exact component symbol names, and the section description gains sentence case.
The changeset announced them, but only NavBaseButtonProps left the package - the variant types lived in component files outside every barrel. Verified with a consumer-side tsc probe against dist.
The generator reads defaults from JSDoc only; Tooltip placement, IconSwitch variant and EdgeLabel size/state/type had runtime defaults with no tag, so their table cells rendered empty.
Absent variants were filtered out before the every() check, so SegmentPicker documented value (controlled) and defaultValue (uncontrolled) as simultaneously required - a call that cannot exist. Required now means required in every variant; the variant note says where a prop is required otherwise.
The coverage guard only cross-checked vite entries against generator entries; an entry with no page rendering its slug passed silently.
starlight-typedoc reads packages/sdk sources, and root manifests plus the workflow file itself shape the build - none of them triggered the gate, so an SDK change could break the docs build unnoticed until deploy.
The fixed 2/1 stage with overflow:hidden clipped wide examples (Snackbar) on narrow layouts. The ratio is now a preferred size: shadow-root children cap at the stage width and content restores the automatic minimum height. Also corrects the isolation comment - inherited typography crosses the shadow boundary by design.
Nine usage blocks called useState without importing it, so a copied example failed to compile. Snackbar now says it is purely presentational - no positioning, stacking, or auto-dismiss.
NodeAsPortWrapper stretches the existing target handle's hit area and adds no highlight of its own - the page claimed the whole node becomes a highlighted port with no preconditions. The missing-token note now describes the comments as historical markers (several referenced tokens exist in the export today). Overview drops the 1.4.x pin claim, and the custom-node guide gains the missing ui package install step.
librowski
force-pushed
the
ui-consumers
branch
from
August 11, 2026 10:48
19ee1f1 to
46e0305
Compare
piotrblaszczyk
approved these changes
Aug 12, 2026
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.
Part 3 of 3 of the
@workflowbuilder/uiseries (#44 packages → #45 consumers → this PR).Summary
Adds the UI Library section to the docs site: an overview + design-tokens guide, 19 component pages and 5 diagram-component pages, each with a live example rendered from the real
@workflowbuilder/uibuild and a props table generated from source (TypeDoc) plus a CSS-variables table scraped from the component stylesheets. Generated data (ui-api.json) is gitignored and rebuilt on every dev/build/typecheck run.How to review
apps/docs/scripts/generate-ui-api.mjs- the generator. Union/overload components (Button, NavButton, SegmentPicker) document through an explicit variant merge (collectVariantProps); a variant'sfoo?: neverexclusion counts as "absent in that variant". Every silent-empty path now fails the build: missing component directory, unknown table slug, first-party props hidden behind an unresolvable utility wrapper (Partial<X>), ambiguous type names.apps/docs/scripts/check-ui-component-coverage.mjs- parity guard: every ui vite entry must have a docs entry.apps/docs/src/components/ui-examples/**- live previews render inside shadow roots; portalled popups (Modal, Menu, Select, Tooltip, DatePicker) escape todocument.body, so the library stylesheet also loads at document level (astro.config.mjscustomCss) - it is fully layered with no reset, safe for the Starlight theme..github/workflows/pr-check-docs.yml- new path-filtered PR gate (apps/docs/**,packages/ui/**,packages/tokens/**): fullbuild:docs. Previously every docs gate first ran at release-time deploy.packages/uichanges riding here (by series convention: type exports needed by the generator): ~12export type XPropspromotions,DatePickerPropsnow covers the component's full runtime surface (value,defaultValue,placeholder,valueFormat,type,error), plus accurate@defaulttags. Covered by aminorchangeset for@workflowbuilder/ui.Review history
Three-reviewer adversarial pass (pipeline / content accuracy / coupling & hygiene). Fixed since: unstyled portalled previews (5 of 23 examples), a setup page teaching the pre-#44 import-order requirement that no longer exists, a DatePicker table that documented none of the props its own example used, SegmentPicker/NavButton tables contradicting their prose (first-wins union flattening), four silent-empty generator paths, the missing PR CI gate, sidebar ordering of section index pages.
2026-08-11 - OpenCode (GPT-5.6) adversarial round. 15 findings, all verified on code; fixed here:
NavIconButtonProps,NavLabelButtonProps,NavIconLabelButtonProps) were announced but reachable from no barrel - now re-exported viatypes.tsand proven importable with a consumer-side tsc probe against dist.valueanddefaultValueas simultaneously required - an impossible call); missing@defaulttags added for Tooltip/IconSwitch/EdgeLabel runtime defaults.useStateimport.Handle), the "missing token" note describes the markers as historical, overview drops the 1.4.x pin claim, Snackbar states it is purely presentational, and the custom-node guide gains the@workflowbuilder/uiinstall step.packages/sdk/**(starlight-typedoc reads it), root manifests, and the workflow file itself.missing tokencomment sweep.Verification
astro build: 208 pages, green - identical to the new CI job's gate.@themeimports, frontmatter fields, unsupported admonitions).Notes
pnpm-lock.yaml(regenerated).@workflowbuilder/ui@2.0.0tag no later than the docs deploy - the docs tell readers tonpm install @workflowbuilder/ui.