Skip to content

feat(headless-docsite): embed code panel in canvas, magenta theme, refine sandbox & tabs#36073

Open
tudorpopams wants to merge 25 commits intomicrosoft:masterfrom
tudorpopams:feat/headless-docsite-theme
Open

feat(headless-docsite): embed code panel in canvas, magenta theme, refine sandbox & tabs#36073
tudorpopams wants to merge 25 commits intomicrosoft:masterfrom
tudorpopams:feat/headless-docsite-theme

Conversation

@tudorpopams
Copy link
Copy Markdown
Contributor

@tudorpopams tudorpopams commented Apr 28, 2026

Summary

Polishes the headless components docsite: embeds the "Show code" panel directly into the canvas card, swaps the accent to a magenta theme, and refines the Stackblitz sandbox + tab strip so users only see the files actually referenced by the displayed story.

Changes

Docsite (apps/public-docsite-v9-headless)

  • Custom docs page replaces autodocs: title / description / primary canvas / ArgTypes / remaining stories — matching the deployed Fluent docs layout. Lives under .storybook/HeadlessDocsPage.tsx (moved out of the stories package after PR review).
  • Tabbed source panel (HeadlessSourcePanel.tsx, also colocated with the docsite) is portaled into the same .sbdocs-preview canvas card and listens to Storybook's native "Show code" toggle so it sits next to "Open in Stackblitz". Styled via storybook/theming so it inherits the active SB theme.
  • Per-story tab strip is filtered to CSS modules actually referenced in the displayed TSX (the meta still lists the full set so the sandbox can bundle what's needed).
  • Sidebar / toolbar accent + tab indicator + selected nav now use magenta #9b1f5a (Figma --prmt-color-red ramp). Sidebar hover bg switched to neutral grey.
  • Segoe UI loaded from c.s-microsoft.com/static/fonts/segoe-ui/... so the docsite chrome and story canvases use Segoe on every OS, not just Windows.

Stories (react-headless-components-preview/stories)

  • withCssModuleSource bundles tokens.css + only the CSS modules referenced from src/example.tsx into the Stackblitz sandbox under src/styles/, and prepends an import of tokens.css to App.tsx.
  • Story TSX → docs page wiring is now handled by babel-preset-storybook-full-source (auto-injected parameters.docs.source.code/originalSource); the per-story withStorySource(storySource) boilerplate and ?raw story-source imports were removed from all 42 story files. The withStorySource helper is gone.
  • ?raw ambient module declaration moved out of the global typings/static-assets/ allowlist into a colocated src/_helpers/raw.d.ts.
  • Card stories converted from Tailwind classes to CSS Modules + design tokens (matches the rest of the headless components, fixes the broken render previously visible at /docs/headless-components-card--docs).

Babel preset (babel-preset-storybook-full-source)

  • fullSourcePlugin now also injects Story.parameters.docs.source.code / originalSource (cleaned raw source with paths rewritten to the Stackblitz ./styles/<basename> layout). Removes the need for per-story withStorySource(...) calls.
  • modifyImportsPlugin no longer special-cases known-safe relative imports — the warning allowlist was removed per review feedback. Strip behaviour and tests are unchanged (15/15 passing).

Shared CSS-Modules webpack rule

  • Source of truth lives at packages/.../stories/.storybook/css-modules-webpack.js. Both the per-package storybook (stories/.storybook/main.js) and the docsite (apps/.../.storybook/main.js) import it — eliminates the duplicated ~80 LoC.

SSR for headless stories

  • Re-enabled test-ssr for react-headless-components-preview-stories (removed from the nx.json exclude list). The test-ssr esbuild pipeline picked up two new plugins in scripts/test-ssr/src/utils/esbuild-plugin.ts so it can process ?raw queries and *.module.css imports during SSR rendering.

Theme source

  • Recovered design system source (tokens.css + 27 component CSS modules) that drives the docsite preview and Stackblitz sandboxes.

Verification

  • yarn nx run public-docsite-v9-headless:build-storybook — clean build, llms-extractor parsed all 29 stories.
  • yarn nx run babel-preset-storybook-full-source:test — 15/15 passing.
  • yarn nx run react-headless-components-preview-stories:test-ssr — passing.
  • Visual: Card / Selectable / Disabled stories now render correctly with design-token styling; "Show code" expands the tabbed panel inside the canvas card.

Follow-ups (deferred)

  • Spike storybook-css-modules addon as a replacement for the webpack-rule patching (hasn't been updated for SB 8 — likely won't replace the rule today).
  • Add stylelint for CSS / CSS Modules authoring.
  • Validation/lint rule for withCssModuleSource usage so missing modules surface at lint time rather than at sandbox open.
  • Move generic per-component styles (focus outline, etc.) into a shared layer.
  • Long-term, repackage HeadlessDocsPage + HeadlessSourcePanel + the babel preset as a Storybook addon so other Fluent storybooks can opt in.

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Apr 28, 2026

📊 Bundle size report

✅ No changes found

@tudorpopams tudorpopams changed the title feat(headless-docsite): embed code panel in canvas, magenta theme, refine sandbox & tabs [DON'T MERGE] feat(headless-docsite): embed code panel in canvas, magenta theme, refine sandbox & tabs Apr 28, 2026
@github-actions
Copy link
Copy Markdown

Pull request demo site: URL

@@ -1,5 +1,97 @@
const path = require('path');
Copy link
Copy Markdown

@github-actions github-actions Bot Apr 28, 2026

Choose a reason for hiding this comment

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

🕵🏾‍♀️ visual changes to review in the Visual Change Report

vr-tests-react-components/Charts-DonutChart 1 screenshots
Image Name Diff(in Pixels) Image Type
vr-tests-react-components/Charts-DonutChart.Dynamic.default.chromium.png 5581 Changed
vr-tests-react-components/Menu Converged - submenuIndicator slotted content 2 screenshots
Image Name Diff(in Pixels) Image Type
vr-tests-react-components/Menu Converged - submenuIndicator slotted content.default.submenus open.chromium.png 413 Changed
vr-tests-react-components/Menu Converged - submenuIndicator slotted content.default - RTL.submenus open.chromium.png 404 Changed
vr-tests-react-components/Positioning 2 screenshots
Image Name Diff(in Pixels) Image Type
vr-tests-react-components/Positioning.Positioning end.updated 2 times.chromium.png 732 Changed
vr-tests-react-components/Positioning.Positioning end.chromium.png 45 Changed
vr-tests-react-components/ProgressBar converged 2 screenshots
Image Name Diff(in Pixels) Image Type
vr-tests-react-components/ProgressBar converged.Indeterminate + thickness - High Contrast.default.chromium.png 69 Changed
vr-tests-react-components/ProgressBar converged.Indeterminate + thickness.default.chromium.png 54 Changed
vr-tests-react-components/TagPicker 1 screenshots
Image Name Diff(in Pixels) Image Type
vr-tests-react-components/TagPicker.disabled - High Contrast.disabled input hover.chromium.png 1319 Changed
vr-tests-web-components/Avatar 1 screenshots
Image Name Diff(in Pixels) Image Type
vr-tests-web-components/Avatar. - Dark Mode.normal.chromium.png 10380 Changed
vr-tests-web-components/MenuList 1 screenshots
Image Name Diff(in Pixels) Image Type
vr-tests-web-components/MenuList. - RTL.2nd selected.chromium.png 17 Changed
vr-tests-web-components/RadioGroup 1 screenshots
Image Name Diff(in Pixels) Image Type
vr-tests-web-components/RadioGroup. - Dark Mode.normal.chromium_1.png 89 Changed
vr-tests/Callout 12 screenshots
Image Name Diff(in Pixels) Image Type
vr-tests/Callout.Bottom left edge - RTL.default.chromium.png 2199 Changed
vr-tests/Callout.Left center.default.chromium.png 2584 Changed
vr-tests/Callout.Left bottom edge.default.chromium.png 3182 Changed
vr-tests/Callout.Bottom right edge.default.chromium.png 1130 Changed
vr-tests/Callout.Left top edge.default.chromium.png 2183 Changed
vr-tests/Callout.Right center.default.chromium.png 2117 Changed
vr-tests/Callout.Right bottom edge.default.chromium.png 3095 Changed
vr-tests/Callout.No beak.default.chromium.png 2192 Changed
vr-tests/Callout.Top center.default.chromium.png 2127 Changed
vr-tests/Callout.Top auto edge.default.chromium.png 2212 Changed
vr-tests/Callout.Top right edge.default.chromium.png 1146 Changed
vr-tests/Callout.Root.default.chromium.png 2195 Changed
vr-tests/Keytip 2 screenshots
Image Name Diff(in Pixels) Image Type
vr-tests/Keytip.Disabled.default.chromium.png 26 Changed
vr-tests/Keytip.Offset.default.chromium.png 86 Changed
vr-tests/react-charting-AreaChart 1 screenshots
Image Name Diff(in Pixels) Image Type
vr-tests/react-charting-AreaChart.Custom Accessibility.default.chromium.png 11 Changed
vr-tests/react-charting-LineChart 4 screenshots
Image Name Diff(in Pixels) Image Type
vr-tests/react-charting-LineChart.Multiple.default.chromium.png 192 Changed
vr-tests/react-charting-LineChart.Events - Dark Mode.default.chromium.png 16 Changed
vr-tests/react-charting-LineChart.Events - RTL.default.chromium.png 15 Changed
vr-tests/react-charting-LineChart.Events.default.chromium.png 17 Changed
vr-tests/react-charting-MultiStackBarChart 2 screenshots
Image Name Diff(in Pixels) Image Type
vr-tests/react-charting-MultiStackBarChart.Basic_Absolute - RTL.default.chromium.png 343 Changed
vr-tests/react-charting-MultiStackBarChart.Basic_Absolute.default.chromium.png 359 Changed
vr-tests/react-charting-SankeyChart 1 screenshots
Image Name Diff(in Pixels) Image Type
vr-tests/react-charting-SankeyChart.PlaceHolder - RTL.default.chromium.png 77 Changed
vr-tests/react-charting-VerticalBarChart 1 screenshots
Image Name Diff(in Pixels) Image Type
vr-tests/react-charting-VerticalBarChart.Basic - Secondary Y Axis.default.chromium.png 3 Changed

There were 4 duplicate changes discarded. Check the build logs for more information.

@tudorpopams tudorpopams changed the title [DON'T MERGE] feat(headless-docsite): embed code panel in canvas, magenta theme, refine sandbox & tabs feat(headless-docsite): embed code panel in canvas, magenta theme, refine sandbox & tabs Apr 29, 2026
@tudorpopams tudorpopams force-pushed the feat/headless-docsite-theme branch 2 times, most recently from 890b26d to 617450f Compare April 29, 2026 16:59
Copy link
Copy Markdown
Contributor

@dmytrokirpa dmytrokirpa left a comment

Choose a reason for hiding this comment

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

Overall, this looks great!

What we might want to improve in scope of the PR or as a followup:

There are a few points we should discuss before moving forward:

  • We currently don't have any tooling for authoring CSS or CSS Modules (such as stylelint).
  • SSR testing for headless stories still needs to be enabled, as that's the only way to test SSR compatiblity
  • Tooling for withCSSModuleSource/withStorySource appears to be missing. If I'm not mistaken, this has to be added manually, and without propper linting/validation, it could cause issues on the documentation site
  • We need to test llms-extractor if it's able to parse custom structure (or disable it)

Comment thread nx.json Outdated
"react-theme-stories",
"react-migration-v8-v9-stories",
"react-migration-v0-v9-stories",
"react-headless-components-preview-stories"
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.

why do we need to disable ssr-tests for headless?

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.

yeah revert please

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Re-enabled in 6ca535e — and taught test-ssr's esbuild pipeline to handle ?raw queries and *.module.css imports so the SSR build passes.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Reverted in 6ca535e.

// so its border tightly hugs the rendered story; when our panel is expanded
// inside the same card we need to release both so the code panel can flow.
const headlessDocsPageCss = `
.headless-docs-page .sbdocs-preview > *:not(.docs-story):not(.headless-source-portal) {
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.

could we move this to a static styles.css and import it from SB preview

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done in 7c949d1 — the inline <style> block is now apps/public-docsite-v9-headless/.storybook/headless-docs-page.css, loaded once from preview.js.

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.

Do we need this to be a part of headless components stories package? Maybe we should move it to headless docsite instead?

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.

yup, we dont need this for stories package sb boot, thus should live in app domain. in general this should follow our sb addon pattern later on if proved valid

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Moved in 7c949d1HeadlessDocsPage and HeadlessSourcePanel now live in apps/public-docsite-v9-headless/.storybook/. The stories package keeps only the runtime helper (withCssModuleSource).

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Moved into the docsite app in 7c949d1. The longer-term SB-addon repackaging is tracked in the PR description's Follow-ups list.

</div>
);

Default.parameters = withStorySource(storySource);
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.

can this be injected by babel-plugin, so devs shouldn't care about it

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done in cb67c6dbabel-preset-storybook-full-source now auto-injects parameters.docs.source.code/originalSource for every story export, and the withStorySource boilerplate was swept from all 42 story files. The helper itself is gone.

Copy link
Copy Markdown
Contributor

@Hotell Hotell left a comment

Choose a reason for hiding this comment

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

the UI/UX is great ! it would be great to make this pluggable and use via sb addon to provide consistent UI across all our sb docs.

From the implementation and maintenance POV things need most likely change/different architecture design (pluggable/following SB pattern/not blocking SB upgrades).

left additional comments. ty

*
* Returns the input array for chaining.
*/
function patchRules(rules) {
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.

this logic looks brittle, why cant we use official solution like https://storybook.js.org/addons/storybook-css-modules ?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Tracked as a follow-up in the PR description — storybook-css-modules hasn't been updated for SB 8/9, so it can't replace the rule today. The wiring is now de-duplicated and lives in one source-of-truth module (65ceacf), making it easy to swap out later.

Comment thread apps/public-docsite-v9-headless/.storybook/manager-head.html
*/
const cssIncludes = [tokensDir, headlessStoriesDir];

const cssModuleRule = {
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.

this is duplication of non trivial code. for temporary workaround the source of truth should stay within stores package and the app will only import from it as its base

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done in 65ceacf — source of truth now lives at packages/.../stories/.storybook/css-modules-webpack.js, and the docsite app require()s it. Eliminates ~80 LoC of duplication.

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.

yup, we dont need this for stories package sb boot, thus should live in app domain. in general this should follow our sb addon pattern later on if proved valid

const ACTIVE_TAB_FG = '#9b1f5a';
const TAB_FG = '#666666';

const containerStyle: React.CSSProperties = {
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.

this should most like use storybook styling framework

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done in 7c949d1HeadlessSourcePanel now uses styled from storybook/theming, so the panel inherits the active SB theme tokens (appBorderColor, background.content/app, color.mediumdark).

import { ChevronRightRegular } from '@fluentui/react-icons';

import styles from './accordion.module.css';
import storySource from './AccordionCollapsible.stories?raw';
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.

wondering what is this inception ? why cant this follow standard sb decorator pattern ?

it seems this api doesn't provide good enough ergonomics long term.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Removed entirely in cb67c6d — no more per-story withStorySource(...) calls. The babel preset auto-injects parameters.docs.source.code/originalSource; story files now just export the component, no docs-plumbing imports.

Comment thread nx.json Outdated
"react-theme-stories",
"react-migration-v8-v9-stories",
"react-migration-v0-v9-stories",
"react-headless-components-preview-stories"
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.

yeah revert please

Comment thread typings/static-assets/index.d.ts Outdated
* Webpack `?raw` query — imports a file's source as a string.
* Used by stories to display CSS module source in Storybook's "Show code" panel.
*/
declare module '*?raw' {
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.

the sole need of this should be a warning sign of the implemented abstraction. if it's really necessary we should scope this to those affected stories rather than global allowlist

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done in e694e06 — moved out of typings/static-assets/index.d.ts into a colocated stories/src/_helpers/raw.d.ts, scoped to this package only.

// (e.g. `parameters.exportToSandbox.transformFiles`). Skipping the
// warning for these well-known patterns keeps dev console output
// clean without changing extraction behavior.
const isKnownSafeRelative =
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.

this is tightly coupled logic to a generic babel loader, if this is really necessary the api should provide this opt out via configuration. in terms of functionality I'd suggest to either remove this and live with the warnings ( as the withStoryource does its own thing anyways ) or extend the loader to accomodate raw sources processing if that is the api we agree upon going forward

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done in 5a14626 — went with the "remove it and live with the warnings" path. withStorySource was removed entirely in cb67c6d so there's nothing to silence anyway.

tudorpopams added a commit to tudorpopams/fluentui that referenced this pull request Apr 30, 2026
- Stories README: §3 now describes the auto-injected docs source flow and
  the corrected `...withCssModuleSource(...)` spread (the previous example
  used a `transform:` shape the helper never matched). §8 paths point at
  the moved `?raw` typing, the shared webpack module, and the docs page
  components in the docsite app.
- Babel preset README: documents the new `parameters.docs.source.code` /
  `originalSource` injection alongside the existing `fullSource` feature.
- test-ssr README: documents the two custom esbuild plugins
  (`?raw` query loader, `*.module.css` Proxy shim) so future contributors
  know they exist before reaching for a testSSR exclusion.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
tudorpopams and others added 11 commits May 4, 2026 10:32
…me, refine sandbox & tabs

Bebop docsite (apps/public-docsite-v9-headless):
- Custom BebopDocsPage replaces autodocs: title/description/primary canvas/
  ArgTypes/remaining stories layout matching deployed Fluent docs.
- BebopSource portals a tabbed Story.tsx + .module.css source panel into the
  same .sbdocs-preview canvas card the user already sees, listening to
  Storybook's native 'Show code' toggle so it sits next to 'Open in Stackblitz'.
- Per-story tab strip is filtered to CSS modules actually referenced in the
  displayed TSX (the meta still lists the full set so the sandbox can bundle
  what's needed).
- Sidebar/toolbar accent + tab indicator + selected nav now use Bebop
  magenta #9b1f5a (Figma --prmt-color-red ramp); replaces the prior near-black
  #4a0a2c. Sidebar hover bg switched to neutral grey.
- Drop the rsms.me Inter import; everything inherits Segoe UI.

Stories (react-headless-components-preview/stories):
- New README.md replaces CLAUDE.md, merging the package metadata header with
  the full authoring guide (pattern, boilerplate, token tiers, gotchas,
  PR checklist, file map).
- withStorySource pins each story's own raw source as
  parameters.docs.source.code+originalSource and overrides fullSource via a
  non-writable getter so the babel preset's empty post-strip overwrite is
  swallowed; rewrites long ../../bebop/components/*.module.css paths to a
  colocated ./styles/*.module.css for paste-ready snippets.
- withCssModuleSource bundles tokens.css + only the CSS modules referenced
  from src/example.tsx into the Stackblitz sandbox under src/styles/, and
  prepends an import of tokens.css to App.tsx.
- Remove the broken Copy Page button.

Babel preset (babel-preset-storybook-full-source):
- modifyImportsPlugin no longer warns for known-safe relative patterns
  (*.module.css, ?raw queries, with{Story,CssModule}Source helpers,
  *.stories?raw). Strip behaviour and tests are unchanged.

Recovered bebop/ design system source (tokens.css + 27 component CSS modules)
that drives the docsite preview and Stackblitz sandboxes.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…imer

- Rename bebop/ folder to theme/ (tokens.css + 27 component CSS modules)
- Rename BebopDocsPage -> HeadlessDocsPage and BebopSource -> HeadlessSourcePanel
- Scrub all bebop identifiers, paths, classes, and comments across stories,
  helpers, .storybook config, and project.json files
- Add a disclaimer banner on the docs page explaining that headless components
  ship without default styles and that the demo CSS is illustrative only

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Move every `theme/components/*.module.css` into the corresponding story
folder under `stories/src/<Component>/`. Stories that compose multiple
components (Field, Dialog, Select, MessageBar, SpinButton) reference the
adjacent folder's module via a sibling import.

- Update `withStorySource` and `withCssModuleSource` regexes to match any
  relative `*.module.css` import (not just the old `theme/components/`
  path) and rewrite to `./styles/` for paste-ready snippets and Stackblitz
  sandbox layout.
- `theme/` now only contains `tokens.css` (still global).
- Update the stories README to document the colocated layout.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The global tokens.css now lives under apps/public-docsite-v9-headless/theme/
together with the docsite that consumes it. Update import paths in:
  - apps/public-docsite-v9-headless/.storybook/preview.js
  - stories/.storybook/preview.js
  - stories/src/_helpers/withCssModuleSource.ts (?raw inline)
  - project.json build inputs (workspaceRoot -> projectRoot for the docsite)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Owning tokens.css inside the stories package (where the headless story
authors edit theme variables) is cleaner than reaching from a sibling
package into the docsite app. The docsite now imports it from there.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Drop the design-system swap suggestion; just clarify that the CSS in the
stories is a demonstration of one possible look.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…review

The standalone stories storybook lives at stories/.storybook/preview.js,
so tokens.css (now at stories/theme/tokens.css) is one level up via
../theme/tokens.css — not ../../theme. The docsite build still passes
because it imports via its own preview.js which uses a different relative
path.

Also add a beachball change file for the babel-preset-storybook-full-source
warning skip (committed earlier).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…-check errors

- Exclude react-headless-components-preview-stories from auto-inferred test-ssr
  target via nx.json workspace plugin config (esbuild can't resolve ?raw query
  imports used by withStorySource).
- Narrow language type in HeadlessSourcePanel to satisfy SyntaxHighlighter's
  SupportedLanguage union (was string).
- Type RatingIcon helpers as React.FC instead of () => React.ReactNode so they
  match RatingDisplay's icon prop under React 17/18 stricter typing.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…ton underline

- Bump heads-up disclaimer font to 16px and beef up the styling so it stands
  out on every story page.
- Add a secondary preview note clarifying the controls are in preview and
  their APIs are subject to change.
- Force the 'Show code' and 'Open in Stackblitz' buttons' hover/focus
  underline to the magenta accent (Storybook's default and the sandbox
  addon's hard-coded blue both override here).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The .storybook/tsconfig.json runs with checkJs:true so the webpack config
in main.js needed JSDoc annotations: `patchRules` parameter is annotated
as `any[]` and the `localConfig` cast as `any` to access `module.rules`.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
tudorpopams and others added 14 commits May 4, 2026 10:32
Many *.module.css files in the headless stories had selectors written as
their bundler-generated names (e.g. .dialog-module__row--0+lMS) or with
trailing dashes/escaped pluses (.bar-, .card\+). These selectors never
matched at runtime, leaving Dialog, Divider, MessageBar, Rating,
SearchBox, Skeleton, Slider and others without their demo styles.

- Strip the '<file>-module__' prefix and '--<hash>' suffix
- Strip stray trailing '-' / escaped '+' from selectors
- Combine .surface with .alertSurface in the alert / non-modal Dialog
  stories so the surface is positioned and styled correctly

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The Skeleton demo had an extra 140px 'thumb' bar and a shimmer animation
that didn't match the deployed reference. Rewrite the CSS module to match
the deployed look: a clean card with avatar + two short lines, then three
horizontal bars with a softer pulse animation. Drop the unused .thumb.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…le.css

Removes the `react-headless-components-preview-stories` SSR-test exclusion
added when these tests started failing. test-ssr's esbuild pipeline now
bundles `?raw` queries (raw text loader with extension resolution) and
shims `*.module.css` imports as a Proxy that echoes the property name —
sufficient for SSR snapshots without the actual CSS-Modules transform.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The ambient `declare module '*?raw'` lived in the global
`typings/static-assets/` allowlist, which is too broad — it pulled the
shape into every consumer's compile. Move it to a colocated `raw.d.ts`
inside the stories package so the typing is opt-in rather than
workspace-wide.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Removes the special-case for `*.module.css`, `?raw` queries, and
withStorySource/withCssModuleSource imports that suppressed the
modifyImports warning. The warning is informational and the helpers do
their own thing — silencing them was tightly-coupled wallpaper. Strip
behaviour and the existing 15 tests are unchanged.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Source of truth for the CSS-Modules + ?raw webpack wiring lives at
`stories/.storybook/css-modules-webpack.js`. Both the per-package
storybook and the docsite app `require()` it — eliminates the duplicated
~80 LoC of `cssModuleRule` + `patchRules` between the two configs.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…e app

HeadlessDocsPage / HeadlessSourcePanel are docsite-app concerns, not
stories-package concerns — the per-package storybook should not need a
custom docs page. Move both into `apps/public-docsite-v9-headless/.storybook/`
and wire the docsite's preview.js to consume them locally.

Externalize the previously-inlined `<style>` block into a static
`headless-docs-page.css` loaded once from preview.js.

Switch HeadlessSourcePanel from inline CSSProperties objects to
emotion-via-`storybook/theming` `styled` components so the panel inherits
the active SB theme tokens (matches the rest of the docs chrome).

Surface the `CssModule` / `HeadlessSourceParameters` types from
`withCssModuleSource` (which produces them) instead of from the panel
that consumes them — cleaner one-way dependency.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Without an explicit webfont, the previous font stack fell through to
BlinkMacSystemFont/Roboto on machines without Segoe installed (i.e.
anyone not on Windows). Pull the four Segoe UI weights (light/normal/
semibold/bold) from Microsoft's static font CDN in both the manager
chrome and the story canvas iframe so the docsite renders Segoe on
every OS.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Extends fullSourcePlugin to also write Story.parameters.docs.source.code
and originalSource on every story export, using the cleaned raw file
contents (with `*.module.css` paths rewritten to the Stackblitz
`./styles/<basename>` layout). Removes the need for per-story
`withStorySource(...)` calls and `?raw` story-source imports.

Sweeps all 42 headless story files to drop the boilerplate, deletes the
`withStorySource` helper, and updates the four fixture outputs to match
the new injection.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Card was the only headless component story using inline Tailwind class
strings, which the docsite doesn't load — so /docs/headless-components-card
rendered unstyled. Add a `card.module.css` driven by the same token
ramp (--bg, --border, --space-*, --radius-*, --shadow-*, --accent…) the
rest of the components use, and switch CardDefault / CardSelectable /
CardDisabled to consume it. Wire `withCssModuleSource` in the meta so
the Stackblitz sandbox bundles the new stylesheet.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Stories README: §3 now describes the auto-injected docs source flow and
  the corrected `...withCssModuleSource(...)` spread (the previous example
  used a `transform:` shape the helper never matched). §8 paths point at
  the moved `?raw` typing, the shared webpack module, and the docs page
  components in the docsite app.
- Babel preset README: documents the new `parameters.docs.source.code` /
  `originalSource` injection alongside the existing `fullSource` feature.
- test-ssr README: documents the two custom esbuild plugins
  (`?raw` query loader, `*.module.css` Proxy shim) so future contributors
  know they exist before reaching for a testSSR exclusion.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Storybook ships a global \`.docs-story + div > div:last-child { background:
rgb(0,0,0) }\` rule meant for the legacy Source block. Our portaled
HeadlessSourcePanel renders into the matched DOM position; the previous
inline \`style=\` on its container beat the rule on specificity, but the
move to \`styled\` from \`storybook/theming\` (commit 7c949d1) emits class
names that don't.

Reset the inherited paint (background / box-shadow / border-radius /
right) on \`.headless-source-portal > div\` so the panel's own light
surface and theme-driven tokens show through. Background uses the
\`--bg-elev\` token from \`theme/tokens.css\`, already loaded in preview.js.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The .preview's negative margins push it to the card's border, but its
own square top corners were poking past the card's rounded boundary —
clearly visible on Selectable/Disabled where the magenta border made
the mismatch obvious. Added overflow: hidden to .card so children
clip to the rounded shape; the border and box-shadow render outside
the overflow box and stay intact.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Both packages were merged with Tailwind class strings inline, which the
docsite doesn't load — same problem we hit with Card. Following the
existing pattern:

- New drawer.module.css covers the OverlayDrawer (fixed-position dialog
  pinned to the right edge) and InlineDrawer (in-flow expanding panel)
  variants, plus shared DrawerHeader / Body / Footer / nav / button
  classes. Native `<dialog>` user-agent styles needed `left: auto` to
  stop centering and let `right: 0` win.
- New popover.module.css consolidates the trigger / surface / heading /
  body / actionButton / menuItem / arrow rules used across all 11
  popover stories. Multi-color trigger variants (root/nested/deep) are
  kept as triggerSecondary + triggerSmall modifiers driven by the
  monochrome accent ramp instead of arbitrary blue/indigo/purple.
- Both meta files now spread `withCssModuleSource(...)` so the docsite's
  "Show code" tab strip and the Stackblitz sandbox bundle the right
  styles.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown
Contributor

@Hotell Hotell left a comment

Choose a reason for hiding this comment

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

added more comments but there are various other things to address. to make our progress faster I implemented things I'd suggest to change in order to proceed.

here is PR against source tudorpopams#1

or brand new PR against upstream (closed for now) #36088

const { chromeVersion, cjsEntryPoint, cjsOutfile, esmEntryPoint, esmOutfile, distDirectory } = config;

const pluginInstance = tsConfigPathsPlugin({ cwd: distDirectory });
const plugins = [tsConfigPathsPlugin({ cwd: distDirectory }), rawQueryPlugin(), cssModulesShimPlugin()];
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.

we need to add tests to buildAssets.ts that this works as expected

*/
export function cleanStorySource(source: string): string {
return source
.replace(/^import\s+\w+\s+from\s+['"]\..*?\.stories\?raw['"];\s*\r?\n/m, '')
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.

we need to cover this is non trivial regex chain with tests. it doesn't address though the coupling I mentioned in previous review to the babel plugin logic

*
* Set as a separate statement (rather than inlined into the parameters
* literal) so it composes with whatever shape the story author already
* declared — `parameters.docs.description.story`, custom transforms, etc.
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.

are we sure this is the case ? atm this generate lot of extra "churn" that seems redundant for most cases besides headless SB plumbing.

now looks like fullSource is in 2 places as well

onResolve({ filter: /\?raw$/ }, async args => {
const cleanPath = args.path.replace(/\?raw$/, '');
const base = path.isAbsolute(cleanPath) ? cleanPath : path.resolve(args.resolveDir, cleanPath);
const resolved = await resolveExisting(base);
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.

this should be noop ( return empty string ) , why do we need to read whole source for no purpose ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants