Skip to content

React: Add subcomponents to component manifests#34428

Merged
JReinhold merged 12 commits intonextfrom
kasper/add-mcp-subcomponents-manifest
Apr 14, 2026
Merged

React: Add subcomponents to component manifests#34428
JReinhold merged 12 commits intonextfrom
kasper/add-mcp-subcomponents-manifest

Conversation

@kasperpeulen
Copy link
Copy Markdown
Member

@kasperpeulen kasperpeulen commented Apr 1, 2026

Closes #

What I did

Added explicit subcomponents support to the React component manifest used by MCP. The manifest generator now reads meta.subcomponents, reuses the existing component resolution/docgen pipeline for child components, resolves declared subcomponents even when they are not rendered in JSX, and attaches their docs under a new subcomponents section on the parent manifest. I also updated the manifest debugger and AI manifests docs so the new data is visible and documented.

Checklist for Contributors

Testing

The changes in this PR are covered in the following automated tests:

  • stories
  • unit tests
  • integration tests
  • end-to-end tests

Manual testing

Caution

This section is mandatory for all contributions. If you believe no manual test is necessary, please state so explicitly. Thanks!

No manual testing performed. Validation was done with targeted manifest tests and yarn nx run-many -t compile.

Documentation

  • Add or update documentation reflecting your changes
  • If you are deprecating/removing a feature, make sure to update
    MIGRATION.MD

Checklist for Maintainers

  • When this PR is ready for testing, make sure to add ci:normal, ci:merged or ci:daily GH label to it to run a specific set of sandboxes. The particular set of sandboxes can be found in code/lib/cli-storybook/src/sandbox-templates.ts

  • Make sure this PR contains one of the labels below:

    Available labels
    • bug: Internal changes that fixes incorrect behavior.
    • maintenance: User-facing maintenance tasks.
    • dependencies: Upgrading (sometimes downgrading) dependencies.
    • build: Internal-facing build tooling & test updates. Will not show up in release changelog.
    • cleanup: Minor cleanup style change. Will not show up in release changelog.
    • documentation: Documentation only changes. Will not show up in release changelog.
    • feature request: Introducing a new feature.
    • BREAKING CHANGE: Changes that break compatibility in some way with current major version.
    • other: Changes that don't fit in the above categories.

🦋 Canary release

This pull request has been released as version 0.0.0-pr-34428-sha-d7a905aa. Try it out in a new sandbox by running npx storybook@0.0.0-pr-34428-sha-d7a905aa sandbox or in an existing project with npx storybook@0.0.0-pr-34428-sha-d7a905aa upgrade.

More information
Published version 0.0.0-pr-34428-sha-d7a905aa
Triggered by @kasperpeulen
Repository storybookjs/storybook
Branch kasper/add-mcp-subcomponents-manifest
Commit d7a905aa
Datetime Wed Apr 1 14:14:33 UTC 2026 (1775052873)
Workflow run 23853145688

To request a new release of this pull request, mention the @storybookjs/core team.

core team members can create a new canary release here or locally with gh workflow run --repo storybookjs/storybook publish.yml --field pr=34428

Summary by CodeRabbit

  • New Features

    • Component manifests now include declared subcomponents and an interactive toggle/panel to view subcomponent details, docs, and status.
  • Documentation

    • Manifest docs updated to describe subcomponents support.
  • Tests

    • New unit/integration tests for subcomponent extraction, manifest generation, rendering, and stability against circular references.
  • Chores

    • Test harness and e2e test cleanup and editor settings adjustments to support subcomponent scenarios.

@nx-cloud
Copy link
Copy Markdown

nx-cloud Bot commented Apr 1, 2026

View your CI Pipeline Execution ↗ for commit 0dce105

Command Status Duration Result
nx run-many -t compile,check,knip,test,lint,fmt... ✅ Succeeded 9m 47s View ↗

☁️ Nx Cloud last updated this comment at 2026-04-14 08:06:56 UTC

@kasperpeulen kasperpeulen marked this pull request as ready for review April 1, 2026 12:18
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 1, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 8b180344-bc33-4827-a8df-2eb5a30af945

📥 Commits

Reviewing files that changed from the base of the PR and between d7a905a and 0dce105.

📒 Files selected for processing (1)
  • .vscode/settings.json

📝 Walkthrough

Walkthrough

Adds declared subcomponents end-to-end: new core types, React extraction of declared subcomponents from CSF, threading resolved subcomponents and their docgen into generated manifests, rendering a subcomponents panel in the manifest HTML, and tests/docs/memfs updates.

Changes

Cohort / File(s) Summary
Core Types
code/core/src/types/modules/core-common.ts
Add ComponentSubcomponentManifest and optional subcomponents?: Record<string, ComponentSubcomponentManifest> on ComponentManifest.
React manifest: generator + imports
code/renderers/react/src/componentManifest/generator.ts, code/renderers/react/src/componentManifest/getComponentImports.ts
Extract declared subcomponents from CSF, prefer exact-name matches when resolving, include resolved subcomponents' docgen/meta in manifests; getComponents accepts additionalComponentNames.
Subcomponent utilities & tests
code/renderers/react/src/componentManifest/subcomponents.ts, code/renderers/react/src/componentManifest/subcomponents.test.ts
New extractDeclaredSubcomponents and findExactComponentMatch; handles identifier unwrapping, member expressions, and circular refs; tests ensure stable termination and mappings.
Manifest HTML rendering
code/core/src/core-server/utils/manifests/render-components-manifest.ts
Add UI toggle/badge and .panel-subcomponents, compute subcomponentEntries, render subcomponent notes via renderSubcomponentNote(...), and generalize docgen input types.
Renderer tests
code/renderers/react/src/componentManifest/generator.test.ts
Add tests for: subcomponents present in JSX, declared-only subcomponents, aliased member-expression subcomponents, and unresolved-subcomponent error handling.
Core manifest tests
code/core/src/core-server/utils/manifests/manifests.test.ts
Add unit test asserting writeManifests output includes rendered subcomponent markup (e.g., ButtonIcon, subcomponent).
Memfs test setup
code/renderers/react/src/componentManifest/memfs-test-setup.ts
Mock cachedResolveImport now accepts options.basedir and resolves relative imports against memfs with common file extensions.
Docs & e2e utilities
docs/ai/manifests.mdx, test-storybooks/portable-stories-kitchen-sink/react/e2e-tests/component-testing.spec.ts
Document declared subcomponents behavior; add closeTestingModuleOverlays helper and adjust Playwright interactions/typing.
Workspace config
.vscode/settings.json
Reorganized formatter settings and per-language default formatters (editor preferences only).

Sequence Diagram(s)

sequenceDiagram
  participant CSF as Story CSF
  participant Extractor as extractDeclaredSubcomponents
  participant Resolver as getComponents / findExactComponentMatch
  participant Docgen as react-docgen / manager.batchExtract
  participant Generator as generator.ts
  participant CoreRender as render-components-manifest
  participant FS as writeManifests (memfs)

  CSF->>Extractor: parse subcomponents field
  Extractor->>Resolver: provide component names
  Resolver->>Docgen: request component/import resolution & docgen
  Docgen-->>Resolver: docgen/meta (or error)
  Resolver->>Generator: resolved ComponentRef + docgen data
  Generator->>CoreRender: emit manifest with subcomponents
  CoreRender->>FS: write HTML manifest with subcomponents panel
  FS-->>CoreRender: confirm write
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs


Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions github-actions Bot added the Stale label Apr 12, 2026
@shilman shilman added manifest Component manifest generation and removed Stale labels Apr 12, 2026
Comment thread code/core/src/types/modules/core-common.ts Outdated
@JReinhold JReinhold added the patch:yes Bugfix & documentation PR that need to be picked to main branch label Apr 13, 2026
@Powerplex
Copy link
Copy Markdown

Powerplex commented Apr 13, 2026

I tried the canary version today, thank you very much it is a must for us.

I noticed the description (jsdoc comment) attached to a subComponent is inherited from the root element of the compound. Not sure if it can be fixed to allow subcomponents to have their own description somehow ? (on the screenshot, both Accordion and Accordion.Item have the same description)

Capture d’écran 2026-04-13 à 11 22 51

It could be tricky because there are many ways to declare a compound component, mine is using Object.assign:
Capture d’écran 2026-04-13 à 11 24 17

I had to adjust my imports to avoid using the compound in subcomponent and use direct imports instead. It is a bit more tedious but it works.

Maybe there could be an alternative syntax for meta.subcomponents in the future to pass a description to each directly ?

const meta: Meta<typeof Accordion> = {
  title: 'Components/Accordion',
  component: Accordion,
  subcomponents: {
    'Accordion.Item': {component: Accordion.Item, description: 'A single item inside the accordion, combines a header and its associated content'}, 
   ...
  },

@storybook-app-bot
Copy link
Copy Markdown

storybook-app-bot Bot commented Apr 13, 2026

Package Benchmarks

Commit: 0dce105, ran on 14 April 2026 at 08:08:06 UTC

No significant changes detected, all good. 👏

@JReinhold
Copy link
Copy Markdown
Contributor

Thanks for the feedback @Powerplex! It sounds more like something we should handle better, automatically, than something we need an explicit API for. Sounds like a bug to me.

If you could provide us with some minimal code snippets that demonstrates this behavior, that would make it a lot easier for us to fix. 🙏

@JReinhold JReinhold merged commit c6bb9f5 into next Apr 14, 2026
125 checks passed
@JReinhold JReinhold deleted the kasper/add-mcp-subcomponents-manifest branch April 14, 2026 08:44
@JReinhold JReinhold removed the patch:yes Bugfix & documentation PR that need to be picked to main branch label Apr 14, 2026
@Powerplex
Copy link
Copy Markdown

Thanks for the feedback @Powerplex! It sounds more like something we should handle better, automatically, than something we need an explicit API for. Sounds like a bug to me.

If you could provide us with some minimal code snippets that demonstrates this behavior, that would make it a lot easier for us to fix. 🙏

I have this branch using your canary version: https://github.com/leboncoin/spark-web/pull/3018/changes#diff-d36927dce8b753153bad94b9be26eaf06084082dc614e8c6c411c03bbe24843eR25-R34

Basically I had to do

subcomponents: {
    'Carousel.Controls': Controls,

Instead of

subcomponents: {
    'Carousel.Controls': Carousel.Controls,

To resolve the correct jsdoc description.

You can see how the compound itself is assembled here: https://github.com/leboncoin/spark-web/blob/13179d09b7ca6a4d9018cfa0741c4a2f885e551b/packages/components/src/carousel/index.ts

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

Labels

ci:normal feature request manifest Component manifest generation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants