Skip to content

feat(storybook): per-component context.md + View as Markdown button (MVP)#6218

Open
blunteshwar wants to merge 2 commits into
mainfrom
MVP-contextMD
Open

feat(storybook): per-component context.md + View as Markdown button (MVP)#6218
blunteshwar wants to merge 2 commits into
mainfrom
MVP-contextMD

Conversation

@blunteshwar
Copy link
Copy Markdown
Contributor

@blunteshwar blunteshwar commented Apr 29, 2026

Description

Ships an MVP for the per-component context.md system proposed in [RFC] context.md for 2nd-gen SWC components.

Two pieces:

  1. 8 hand-authored context.md files — one per migrated 2nd-gen component (badge, divider, progress-circle, status-light, icon, asset, avatar, color-loupe). Each file is the LLM-only prose grounding layer: when-to-use, when-NOT-to-use, accessibility contract, composition rules, runtime invariants, common LLM mistakes, and gen-1 → gen-2 differences.
  2. A Storybook "View as Markdown" button on every migrated component's docs page that opens the component's context.md in a new tab — same pattern as React Spectrum's docs (https://react-spectrum.adobe.com/Tabs.md).

typography is intentionally excluded — it's a CSS-class utility, not a custom-element component, so the per-component file model does not fit.

Motivation and context

When external developers ask LLMs (Claude, Cursor, Copilot, Gemini) to build with SWC, the model frequently hallucinates: wrong variant names, missing aria-label, mixed gen-1/gen-2 imports, outline on a non-semantic variant. Existing docs surfaces (README, CEM, Storybook stories) are not LLM-grounding-shaped. context.md is purpose-built for LLM consumption — chrome-free, anti-pattern-rich, runtime-invariant-aware.

This PR ships the smallest viable slice from RFC §7 so we can evaluate whether the format reduces hallucination before scaling to all future migrations.

Related issue(s)

Note on branch base

This branch was cut from color-loupe-migration, not directly from main. The PR diff against main will therefore include color-loupe commits that haven't yet landed on main. The actual context.md / button work is in the single new commit 41f88ca216 — easiest to review by filtering the commits view to that commit.

Screenshots

The button renders top-right above the subtitle on every component's docs page. Click → new tab opens the raw markdown.

(Reviewer: please add a screenshot after running locally — see manual test steps below.)

Implementation notes

  • Source-of-truth is the context.md file in each component's directory (2nd-gen/packages/swc/components/{slug}/context.md). These ship with the package via npm.
  • Build step (.storybook/scripts/copy-context-md.mjs) copies the files into public/components/{slug}/context.md (gitignored) before Storybook starts. This is wired into both yarn storybook and yarn storybook:build.
  • Why a copy and not a staticDirs mapping of the components dir: mapping the entire components dir exposes .ts source files, which browsers receive with MIME type video/mp2t and refuse to execute as modules. Copying only context.md keeps the public surface tight.
  • Button hides itself when the file is missing (fetch HEAD returns 404), so unmigrated and excluded components (e.g. typography) just don't show it.

Author's checklist

  • I have read the CONTRIBUTING and PULL_REQUESTS documents.
  • I have reviewed the Accessibility Practices for this feature, see: Aria Practices
  • I have added automated tests to cover my changes.
  • I have included a well-written changeset if my change needs to be published.
  • I have included updated documentation if my change required it.

Note: tests + changeset intentionally deferred for the MVP per RFC §7. Will be added once the eval-suite milestone confirms the format earns its place. Flag if you'd rather block on tests for this PR.

Reviewer's checklist

  • Includes a Github Issue with appropriate flag or Jira ticket number without a link
  • Includes thoughtfully written changeset if changes suggested include patch, minor, or major features
  • Automated tests cover all use cases and follow best practices for writing
  • Validated on all supported browsers
  • All VRTs are approved before the author can update Golden Hash

Manual review test cases

  • Button renders on a migrated component's docs page

    1. cd 2nd-gen/packages/swc && yarn storybook
    2. Navigate to Components → Badge → README
    3. Expect a "View as Markdown" button rendered top-right above the subtitle
    4. Click the button
    5. Expect a new tab to open at /components/badge/context.md showing the raw markdown content
  • Button is hidden for components without a context.md

    1. In the running Storybook, navigate to Typography → README (or any non-migrated component)
    2. Expect no "View as Markdown" button to render
    3. No console errors
  • Production build serves the same files

    1. cd 2nd-gen/packages/swc && yarn storybook:build
    2. Serve storybook-static/ (e.g. npx http-server storybook-static)
    3. Repeat the badge test above against the static build

Device review

  • Did it pass in Desktop?
  • Did it pass in (emulated) Mobile?
  • Did it pass in (emulated) iPad?

Accessibility testing checklist

  • Keyboard (required — document steps below)

    1. In Storybook, navigate to Components → Badge → README
    2. Press Tab until focus reaches the "View as Markdown" link
    3. Expect a visible focus indicator on the link
    4. Press Enter
    5. Expect a new tab to open with context.md rendered as raw markdown
    6. No focus traps; Tab continues to the next interactive element after focus returns to the docs tab
  • Screen reader (required — document steps below)

    1. With VoiceOver / NVDA active, navigate to the "View as Markdown" link on a Badge docs page
    2. Expect announcement to include role "link" and the accessible name "View as Markdown"
    3. Expect the link to communicate that it opens in a new tab (via `target="_blank"` plus tooltip; consider adding aria-label text "opens in new tab" if reviewers feel announcement is unclear)
    4. Activate via screen-reader command — new tab opens

@blunteshwar blunteshwar requested a review from a team as a code owner April 29, 2026 08:26
@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented Apr 29, 2026

⚠️ No Changeset found

Latest commit: 9f83984

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 29, 2026

📚 Branch Preview Links

🔍 First Generation Visual Regression Test Results

When a visual regression test fails (or has previously failed while working on this branch), its results can be found in the following URLs:

Deployed to Azure Blob Storage: pr-6218

If the changes are expected, update the current_golden_images_cache hash in the circleci config to accept the new images. Instructions are included in that file.
If the changes are unexpected, you can investigate the cause of the differences and update the code accordingly.

blunteshwar and others added 2 commits April 29, 2026 14:46
Ships LLM-consumable `context.md` files for the 8 currently migrated
2nd-gen components (badge, divider, progress-circle, status-light, icon,
asset, avatar, color-loupe) and a Storybook button that opens the file
in a new tab from each component's docs page.

These files are the prose grounding layer for AI-assisted SWC
development — separate from the human-facing README.md and from the
machine-only Custom Elements Manifest. Each file covers when-to-use,
when-NOT-to-use, accessibility contract, composition rules, runtime
invariants, common LLM mistakes, and gen-1 → gen-2 differences.

Distribution:
- Source-of-truth: 2nd-gen/packages/swc/components/{slug}/context.md
- Build step (.storybook/scripts/copy-context-md.mjs) copies them into
  public/components/{slug}/context.md (gitignored) so Storybook serves
  them without exposing the component source directory to the static-
  asset layer (avoiding the video/mp2t MIME error from .ts files).
- ContextMarkdownButton block reads meta.component, strips the
  swc-/sp- prefix, HEAD-fetches the URL, and renders only when the
  file exists. Components without context.md (e.g. typography) hide
  the button automatically.

Typography is intentionally excluded — it's a CSS-class utility, not a
custom-element component, so the per-component file model does not fit.

See [RFC] context.md for 2nd-gen SWC components for the proposal:
https://wiki.corp.adobe.com/spaces/AdobeDesign/pages/3854270520

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The View as Markdown button used an absolute path (`/components/...`)
which resolves to the domain root. On the PR preview deploy under
`/pr-NNNN/docs/second-gen-storybook/`, that sends the request to the
wrong host root and returns 404, so the button hides itself
(correct fallback behaviour, but invisible button).

Resolve the URL via `document.baseURI` so it inherits the storybook
deploy prefix automatically. Works in both local dev (root path) and
CI preview deploys (sub-path).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@Rajdeepc
Copy link
Copy Markdown
Contributor

Rajdeepc commented May 4, 2026

@blunteshwar Adding this content here risks drifting from our single source of truth. We should instead convert the Storybook docs page into Markdown so it can be reliably consumed by AI. This conversion should be part of an automated pipeline to keep everything in sync.

* git-ignored.
*
* `context.md` is the LLM-consumable component documentation proposed in
* https://wiki.corp.adobe.com/spaces/AdobeDesign/pages/3854270520.
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 should not include internal links

* - the meta has no `component` tag
* - the resolved `context.md` returns 404 (not yet authored for that component)
*/
export const ContextMarkdownButton = ({ of }: { of?: any }) => {
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.

Recommending renaming this to ViewContextMaekdown as the original name sounds like it’s specific for the button component

@caseyisonit
Copy link
Copy Markdown
Contributor

I don’t think we should introduce another hand authored file as a source of truth. This will allow a lot of drift between the context and the storybook docs. Can you share more about the authoring experience change that would come with this new pattern? Does the replace another way of documenting?

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants