From 8548b6d07d5b6a49ac0ec494b4fd67694908df0b Mon Sep 17 00:00:00 2001 From: Ruben Carvalho Date: Wed, 1 Jul 2026 18:31:14 +0200 Subject: [PATCH 01/50] feat(swc): add dedicated VRT stories, scoped Chromatic to snap only them Chromatic was snapping every docs story automatically, and reviewing VRT-only coverage in local Storybook was hard since none of it had its own sidenav entry. This adds hand-authored `*.vrt.ts` story files (a new Storybook indexer/glob, discovered like `.stories.ts` files) that combine permutations into as few snapshots as possible, nested under `/VRT` in the sidenav. Chromatic's snapshotting now defaults to disabled globally and is re-enabled only on VRT files. A new `vrt` Storybook mode (env-gated, CI-only) builds just the `*.vrt.ts` files so the Chromatic-hosted catalog only lists what it actually snapshots; local dev keeps the full story set as before. Prototyped on Button; a shared `row()` helper and the existing `staticColorsDemo` decorator (already used by docs stories) are exported for reuse by future component VRT files. --- .github/workflows/chromatic-vrt.yml | 4 + .../packages/swc/.storybook/helpers/index.ts | 1 + .../packages/swc/.storybook/helpers/vrt.ts | 25 ++++ 2nd-gen/packages/swc/.storybook/main.ts | 82 +++++++---- 2nd-gen/packages/swc/.storybook/preview.ts | 3 + .../swc/components/button/test/button.vrt.ts | 131 ++++++++++++++++++ 6 files changed, 222 insertions(+), 24 deletions(-) create mode 100644 2nd-gen/packages/swc/.storybook/helpers/vrt.ts create mode 100644 2nd-gen/packages/swc/components/button/test/button.vrt.ts diff --git a/.github/workflows/chromatic-vrt.yml b/.github/workflows/chromatic-vrt.yml index 0addec01df1..35b5d87ad84 100644 --- a/.github/workflows/chromatic-vrt.yml +++ b/.github/workflows/chromatic-vrt.yml @@ -51,6 +51,10 @@ jobs: - name: Publish to Chromatic id: chromatic uses: chromaui/action@v15 + env: + # Build only *.vrt.ts stories, so Chromatic's catalog only lists + # what it actually snapshots. + SWC_STORYBOOK_MODE: vrt with: projectToken: ${{ secrets.CHROMATIC_TOKEN }} workingDir: 2nd-gen/packages/swc diff --git a/2nd-gen/packages/swc/.storybook/helpers/index.ts b/2nd-gen/packages/swc/.storybook/helpers/index.ts index 941ea4a4d45..0dd8ed9f518 100644 --- a/2nd-gen/packages/swc/.storybook/helpers/index.ts +++ b/2nd-gen/packages/swc/.storybook/helpers/index.ts @@ -12,3 +12,4 @@ export { formatTitle } from './format-title.js'; export { iconForSize } from './icon-for-size.js'; +export { row } from './vrt.js'; diff --git a/2nd-gen/packages/swc/.storybook/helpers/vrt.ts b/2nd-gen/packages/swc/.storybook/helpers/vrt.ts new file mode 100644 index 00000000000..6c99a091837 --- /dev/null +++ b/2nd-gen/packages/swc/.storybook/helpers/vrt.ts @@ -0,0 +1,25 @@ +/** + * Copyright 2026 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import { html } from 'lit'; + +/** + * Wraps a set of permutations in a single flex-wrap row. Stack multiple + * `row()` calls inside a VRT story to group permutations (e.g. one row per + * variant, one column per size) without needing every combination to be its + * own story/snapshot. + */ +export const row = (children: unknown) => html` +
+ ${children} +
+`; diff --git a/2nd-gen/packages/swc/.storybook/main.ts b/2nd-gen/packages/swc/.storybook/main.ts index 0731d2f519a..1f3cdfa254f 100644 --- a/2nd-gen/packages/swc/.storybook/main.ts +++ b/2nd-gen/packages/swc/.storybook/main.ts @@ -28,14 +28,18 @@ mkdirSync(resolve(__dirname, '../coverage'), { recursive: true }); // - dev: full local Storybook, including docs and test stories // - build: production Storybook build, excluding internal and test stories // - ci-a11y: minimal component-only Storybook used by CI accessibility checks -type StorybookMode = 'dev' | 'build' | 'ci-a11y'; +// - vrt: Chromatic-only build containing *just* .vrt.ts stories, so the +// Chromatic catalog never lists the non-VRT stories it skips snapshotting. +type StorybookMode = 'dev' | 'build' | 'ci-a11y' | 'vrt'; const storybookMode: StorybookMode = process.env.SWC_STORYBOOK_MODE === 'ci-a11y' ? 'ci-a11y' - : process.env.NODE_ENV === 'production' - ? 'build' - : 'dev'; + : process.env.SWC_STORYBOOK_MODE === 'vrt' + ? 'vrt' + : process.env.NODE_ENV === 'production' + ? 'build' + : 'dev'; // Custom indexer to allow .test.ts files to be treated as story files. const testStoryIndexer: Indexer = { @@ -46,6 +50,17 @@ const testStoryIndexer: Indexer = { }, }; +// Custom indexer to allow .vrt.ts files to be treated as story files. Unlike +// .test.ts fixtures, VRT stories must also index in `build` mode so Chromatic +// (which builds Storybook in production mode) can snapshot them. +const vrtStoryIndexer: Indexer = { + test: /\.vrt\.ts$/, + createIndex: async (fileName, options) => { + const csfFile = await readCsf(fileName, options); + return csfFile.parse().indexInputs; + }, +}; + const COMPONENT_STORY_ROOT = { directory: '../components', titlePrefix: 'Components', @@ -61,30 +76,46 @@ const CORE_STORY_ROOT = { titlePrefix: 'Core', } as const; -const stories: StorybookConfig['stories'] = [ - { - ...COMPONENT_STORY_ROOT, - // Production-style builds exclude internal-only stories; local/dev keeps the full set. - files: - storybookMode === 'build' - ? '**/!(*.internal).stories.ts' - : '**/*.stories.ts', - }, - { - ...PATTERN_STORY_ROOT, - files: '**/*.stories.ts', - }, - { - ...PATTERN_STORY_ROOT, - files: '**/*.mdx', - }, -]; +// vrt mode builds only .vrt.ts stories, so Chromatic's catalog never lists +// the non-VRT stories it's configured to skip snapshotting anyway. +const stories: StorybookConfig['stories'] = + storybookMode === 'vrt' + ? [ + { ...COMPONENT_STORY_ROOT, files: '**/*.vrt.ts' }, + { ...PATTERN_STORY_ROOT, files: '**/*.vrt.ts' }, + ] + : [ + { + ...COMPONENT_STORY_ROOT, + // Production-style builds exclude internal-only stories; local/dev keeps the full set. + files: + storybookMode === 'build' + ? '**/!(*.internal).stories.ts' + : '**/*.stories.ts', + }, + { + ...PATTERN_STORY_ROOT, + files: '**/*.stories.ts', + }, + { + ...PATTERN_STORY_ROOT, + files: '**/*.mdx', + }, + { + ...COMPONENT_STORY_ROOT, + files: '**/*.vrt.ts', + }, + { + ...PATTERN_STORY_ROOT, + files: '**/*.vrt.ts', + }, + ]; /** * The CI a11y mode trims docs/guides * that can pull in 1st-gen-linked dependencies the test build does not need. */ -if (storybookMode !== 'ci-a11y') { +if (storybookMode !== 'ci-a11y' && storybookMode !== 'vrt') { stories.push({ directory: '../components', // Production-style builds exclude internal-only docs; local/dev keeps the full set. @@ -197,7 +228,10 @@ const config: StorybookConfig = { }, staticDirs: ['../public', { from: '../coverage', to: '/coverage' }], addons, - experimental_indexers: storybookMode === 'dev' ? [testStoryIndexer] : [], + experimental_indexers: + storybookMode === 'dev' + ? [testStoryIndexer, vrtStoryIndexer] + : [vrtStoryIndexer], viteFinal: async (config) => { return mergeConfig(config, { css: { diff --git a/2nd-gen/packages/swc/.storybook/preview.ts b/2nd-gen/packages/swc/.storybook/preview.ts index 88d1fea217b..c3358334f34 100644 --- a/2nd-gen/packages/swc/.storybook/preview.ts +++ b/2nd-gen/packages/swc/.storybook/preview.ts @@ -143,6 +143,9 @@ const preview = { // same initial path, so without this it would snapshot the pre-play state. Enable // autoplay only under Chromatic to restore correct visual regression snapshots. autoplay: isChromatic(), + // Only dedicated *.vrt.ts stories snapshot in Chromatic; those files opt + // back in via `parameters.chromatic.disableSnapshot: false` on their meta. + chromatic: { disableSnapshot: true }, backgrounds: { disable: true }, // Use custom context switches controls: { expanded: true, diff --git a/2nd-gen/packages/swc/components/button/test/button.vrt.ts b/2nd-gen/packages/swc/components/button/test/button.vrt.ts new file mode 100644 index 00000000000..29c1841023f --- /dev/null +++ b/2nd-gen/packages/swc/components/button/test/button.vrt.ts @@ -0,0 +1,131 @@ +/** + * Copyright 2026 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import { html } from 'lit'; +import type { Meta, StoryObj as Story } from '@storybook/web-components'; +import { getStorybookHelpers } from '@wc-toolkit/storybook-helpers'; + +import { + BUTTON_VALID_SIZES, + BUTTON_VARIANTS, +} from '@spectrum-web-components/core/components/button'; + +import '@adobe/spectrum-wc/components/button/swc-button.js'; + +import { row } from '../../../.storybook/helpers/index.js'; + +// ──────────────── +// METADATA +// ──────────────── + +const { args, argTypes, template } = getStorybookHelpers('swc-button'); + +const meta: Meta = { + title: 'Button/VRT', + component: 'swc-button', + args, + argTypes, + parameters: { + chromatic: { disableSnapshot: false }, + }, + tags: ['dev'], +}; + +export default meta; + +// ──────────────────── +// HELPERS +// ──────────────────── + +// Row = one variant/fill-style pair, columns = every size. Outline only +// applies to primary/secondary (accent/negative don't ship an outline style). +const ROWS: ReadonlyArray<{ variant: string; fillStyle: string }> = [ + ...BUTTON_VARIANTS.map((variant) => ({ variant, fillStyle: 'fill' })), + { variant: 'primary', fillStyle: 'outline' }, + { variant: 'secondary', fillStyle: 'outline' }, +]; + +// ────────────────────────── +// VRT STORIES +// ────────────────────────── + +// Every variant × fill-style × size combination, plus disabled/pending states +// at every size, all rendered in a single story so it costs one snapshot. +export const Permutations: Story = { + render: (args) => html` + ${ROWS.map(({ variant, fillStyle }) => + row( + BUTTON_VALID_SIZES.map((size) => + template({ + ...args, + variant, + 'fill-style': fillStyle, + size, + 'default-slot': `${variant} ${fillStyle} ${size}`, + }) + ) + ) + )} + ${row( + BUTTON_VALID_SIZES.map((size) => + template({ + ...args, + size, + disabled: true, + 'default-slot': `Disabled ${size}`, + }) + ) + )} + ${row( + BUTTON_VALID_SIZES.map((size) => + template({ + ...args, + size, + pending: true, + 'default-slot': `Pending ${size}`, + }) + ) + )} + `, + parameters: { + styles: { display: 'flex', 'flex-direction': 'column', gap: '16px' }, + }, +}; + +// Static-color variants, both backgrounds, every fill-style, in one snapshot. +// Reuses the same `staticColorsDemo` decorator the docs stories use +// (see button.stories.ts StaticColors) for the background gradients. +export const StaticColors: Story = { + render: (args) => html` + ${row( + ['fill', 'outline'].map((fillStyle) => + template({ + ...args, + 'static-color': 'white', + 'fill-style': fillStyle, + 'default-slot': `White ${fillStyle}`, + }) + ) + )} + ${row( + ['fill', 'outline'].map((fillStyle) => + template({ + ...args, + 'static-color': 'black', + 'fill-style': fillStyle, + 'default-slot': `Black ${fillStyle}`, + }) + ) + )} + `, + parameters: { staticColorsDemo: true }, +}; From cde34f87dbb9997d8d1a065f806ad4136f909dfc Mon Sep 17 00:00:00 2001 From: Ruben Carvalho Date: Wed, 1 Jul 2026 20:07:11 +0200 Subject: [PATCH 02/50] feat(swc): flesh out Button VRT story with theme/RTL, icon anatomy, and text behaviors Combine light/ltr and dark/rtl coverage, icon-slot anatomy (label-only, icon+label, icon-only), and text wrapping/truncation into the single Permutations story so it still costs one Chromatic snapshot. Adds shared `theme()` and `staticColorBackground()` helpers to .storybook/helpers/vrt.ts for reuse across future component VRT files. Drops getStorybookHelpers' template()/args/argTypes in favor of plain lit `html` bindings: more legible for a Controls-free story, and it avoids a real bug in observe-slot-text.ts, where a Lit child-position marker comment left by template()'s icon-slot serialization gets misread as label text, permanently defeating Button's `iconOnly` detection. Uses the same static-markup workaround button.stories.ts's own Anatomy story already relies on. --- .../packages/swc/.storybook/helpers/index.ts | 2 +- .../packages/swc/.storybook/helpers/vrt.ts | 49 +++++ .../swc/components/button/test/button.vrt.ts | 198 +++++++++++------- 3 files changed, 177 insertions(+), 72 deletions(-) diff --git a/2nd-gen/packages/swc/.storybook/helpers/index.ts b/2nd-gen/packages/swc/.storybook/helpers/index.ts index 0dd8ed9f518..954d58243f4 100644 --- a/2nd-gen/packages/swc/.storybook/helpers/index.ts +++ b/2nd-gen/packages/swc/.storybook/helpers/index.ts @@ -12,4 +12,4 @@ export { formatTitle } from './format-title.js'; export { iconForSize } from './icon-for-size.js'; -export { row } from './vrt.js'; +export { row, staticColorBackground, theme } from './vrt.js'; diff --git a/2nd-gen/packages/swc/.storybook/helpers/vrt.ts b/2nd-gen/packages/swc/.storybook/helpers/vrt.ts index 6c99a091837..4da205545a1 100644 --- a/2nd-gen/packages/swc/.storybook/helpers/vrt.ts +++ b/2nd-gen/packages/swc/.storybook/helpers/vrt.ts @@ -23,3 +23,52 @@ export const row = (children: unknown) => html` ${children} `; + +/** + * Wraps content so it renders in a given theme/direction regardless of the + * Storybook toolbar's global theme/lang. `.swc-theme--{mode}` only sets + * `color-scheme`, which every token resolves via `light-dark()`; `dir` is a + * plain HTML attribute. Both are inherited properties, so this works even + * across the shadow boundary without needing the toolbar globals. Also + * stacks its children (e.g. multiple `row()` groups) vertically with a gap, + * since it already wraps everything a VRT story renders. + */ +export const theme = ( + children: unknown, + mode: 'light' | 'dark' | 'adaptive', + dir: 'ltr' | 'rtl' = 'ltr' +) => html` +
+ ${children} +
+`; + +// Matches the gradients in decorators/static-colors-demo.ts, so VRT static +// color groups look the same as the docs' staticColorsDemo decorator. +const STATIC_COLOR_GRADIENTS = { + white: 'linear-gradient(45deg, rgb(64 0 22), rgb(14 24 67))', + black: 'linear-gradient(45deg, rgb(255 241 246), rgb(238 245 255))', +} as const; + +/** + * Wraps a group of static-color="white"/"black" permutations in the matching + * contrast background, so they render correctly outside of the docs-only + * `staticColorsDemo` decorator (which only targets a story's top-level + * children, and can't compose with `theme()` wrapping the whole story too). + */ +export const staticColorBackground = ( + children: unknown, + staticColor: 'white' | 'black' +) => html` +
+ ${children} +
+`; diff --git a/2nd-gen/packages/swc/components/button/test/button.vrt.ts b/2nd-gen/packages/swc/components/button/test/button.vrt.ts index 29c1841023f..8c402c495fa 100644 --- a/2nd-gen/packages/swc/components/button/test/button.vrt.ts +++ b/2nd-gen/packages/swc/components/button/test/button.vrt.ts @@ -12,7 +12,6 @@ import { html } from 'lit'; import type { Meta, StoryObj as Story } from '@storybook/web-components'; -import { getStorybookHelpers } from '@wc-toolkit/storybook-helpers'; import { BUTTON_VALID_SIZES, @@ -20,20 +19,30 @@ import { } from '@spectrum-web-components/core/components/button'; import '@adobe/spectrum-wc/components/button/swc-button.js'; +import '@adobe/spectrum-wc/components/icon/swc-icon.js'; -import { row } from '../../../.storybook/helpers/index.js'; +import { + row, + staticColorBackground, + theme, +} from '../../../.storybook/helpers/index.js'; +import { Arrow100Icon } from '../../icon/elements/Arrow100Icon.js'; // ──────────────── // METADATA // ──────────────── -const { args, argTypes, template } = getStorybookHelpers('swc-button'); - +// No args/argTypes: this story isn't driven by Controls, and every +// permutation below sets its own attributes directly. Plain html bindings +// also avoid getStorybookHelpers' template(), which serializes icon-slot +// content through an extra DOM-parsing step that leaves a Lit child-position +// marker comment inside — observe-slot-text.ts's content filter +// doesn't special-case comment nodes, so it misreads that marker as label +// text and `iconOnly` never activates. See button.stories.ts's own Anatomy +// story, which sidesteps the same bug by writing icon-only markup directly. const meta: Meta = { title: 'Button/VRT', component: 'swc-button', - args, - argTypes, parameters: { chromatic: { disableSnapshot: false }, }, @@ -54,78 +63,125 @@ const ROWS: ReadonlyArray<{ variant: string; fillStyle: string }> = [ { variant: 'secondary', fillStyle: 'outline' }, ]; +const arrowIcon = () => html` + +`; + // ────────────────────────── // VRT STORIES // ────────────────────────── -// Every variant × fill-style × size combination, plus disabled/pending states -// at every size, all rendered in a single story so it costs one snapshot. -export const Permutations: Story = { - render: (args) => html` - ${ROWS.map(({ variant, fillStyle }) => - row( - BUTTON_VALID_SIZES.map((size) => - template({ - ...args, - variant, - 'fill-style': fillStyle, - size, - 'default-slot': `${variant} ${fillStyle} ${size}`, - }) - ) +// Every variant × fill-style × size combination, disabled/pending states, +// static-color variants on their contrast backgrounds, icon anatomy +// (label-only, icon+label, icon-only) for fill and outline, and text +// wrapping/truncation behavior. Rendered once in light/ltr and once in +// dark/rtl below (that combination covers both axes), all still in a single +// story so it costs one snapshot. +const permutationContent = () => html` + ${ROWS.map(({ variant, fillStyle }) => + row( + BUTTON_VALID_SIZES.map( + (size) => html` + + ${variant} ${fillStyle} ${size} + + ` ) - )} - ${row( - BUTTON_VALID_SIZES.map((size) => - template({ - ...args, - size, - disabled: true, - 'default-slot': `Disabled ${size}`, - }) - ) - )} - ${row( - BUTTON_VALID_SIZES.map((size) => - template({ - ...args, - size, - pending: true, - 'default-slot': `Pending ${size}`, - }) - ) - )} + ) + )} + ${row( + BUTTON_VALID_SIZES.map( + (size) => html` + Disabled ${size} + ` + ) + )} + ${row( + BUTTON_VALID_SIZES.map( + (size) => html` + Pending ${size} + ` + ) + )} + ${staticColorBackground( + ['fill', 'outline'].map( + (fillStyle) => html` + + White ${fillStyle} + + ` + ), + 'white' + )} + ${staticColorBackground( + ['fill', 'outline'].map( + (fillStyle) => html` + + Black ${fillStyle} + + ` + ), + 'black' + )} + ${['fill', 'outline'].map((fillStyle) => + row([ + html` + Next + `, + html` + ${arrowIcon()}Next + `, + // Written inline, not via the `arrowIcon()` helper: a helper call + // substituted directly as 's only child is itself a Lit + // child-position binding, which leaves the same marker comment problem + // described above. Icon-only is the one case where that actually + // breaks something (iconOnly detection), so must appear as + // literal markup here, with only the innermost Arrow100Icon() call as + // a nested expression. + html` + + + + `, + ]) + )} + ${row([ + html` + + Submit and notify all stakeholders + + `, + html` + + ${arrowIcon()}Submit and notify all stakeholders + + `, + ])} + ${row([ + html` + + Be a premium member + + `, + html` + + Be a premium member + + `, + html` + + ${arrowIcon()}Be a premium member + + `, + ])} +`; + +export const Permutations: Story = { + render: () => html` + ${theme(permutationContent(), 'light', 'ltr')} + ${theme(permutationContent(), 'dark', 'rtl')} `, parameters: { styles: { display: 'flex', 'flex-direction': 'column', gap: '16px' }, }, }; - -// Static-color variants, both backgrounds, every fill-style, in one snapshot. -// Reuses the same `staticColorsDemo` decorator the docs stories use -// (see button.stories.ts StaticColors) for the background gradients. -export const StaticColors: Story = { - render: (args) => html` - ${row( - ['fill', 'outline'].map((fillStyle) => - template({ - ...args, - 'static-color': 'white', - 'fill-style': fillStyle, - 'default-slot': `White ${fillStyle}`, - }) - ) - )} - ${row( - ['fill', 'outline'].map((fillStyle) => - template({ - ...args, - 'static-color': 'black', - 'fill-style': fillStyle, - 'default-slot': `Black ${fillStyle}`, - }) - ) - )} - `, - parameters: { staticColorsDemo: true }, -}; From 11678edaf2c76ef218fb92d8735347042bcc1eae Mon Sep 17 00:00:00 2001 From: Ruben Carvalho Date: Wed, 1 Jul 2026 20:49:20 +0200 Subject: [PATCH 03/50] feat(swc): deploy full dev-mode Storybook to PR preview deploys PR preview deploys were building the production-trimmed Storybook, which excludes internal stories, .test.ts fixtures, and (previously) VRT stories. Add an explicit SWC_STORYBOOK_MODE=dev override in main.ts, since `storybook build` forces NODE_ENV=production itself before the config runs, and wire it into preview-docs.yml. Also fixes an unescaped `|` inside a GFM table code span in the sidenav accessibility migration analysis doc, which broke MDX parsing once contributor-docs was included in a static build for the first time (previously only ever served live via `storybook dev`). --- .github/workflows/preview-docs.yml | 6 ++++++ 2nd-gen/packages/swc/.storybook/main.ts | 12 +++++++++--- .../sidenav/accessibility-migration-analysis.md | 4 ++-- 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/.github/workflows/preview-docs.yml b/.github/workflows/preview-docs.yml index a3f2278559b..cb4d1e60023 100644 --- a/.github/workflows/preview-docs.yml +++ b/.github/workflows/preview-docs.yml @@ -96,6 +96,12 @@ jobs: run: yarn workspace @spectrum-web-components/1st-gen storybook:build - name: Build second-gen Storybook + env: + # Deploy the full dev-mode story set (internal stories, .test.ts + # fixtures, .vrt.ts) to the PR preview, not the production-trimmed + # build. `storybook build` otherwise forces NODE_ENV=production + # itself, so this can't be achieved by leaving NODE_ENV unset. + SWC_STORYBOOK_MODE: dev run: yarn workspace @adobe/spectrum-wc storybook:build ## --- DEPLOY TO AZURE BLOB STORAGE --- ## diff --git a/2nd-gen/packages/swc/.storybook/main.ts b/2nd-gen/packages/swc/.storybook/main.ts index 1f3cdfa254f..c865f7e902b 100644 --- a/2nd-gen/packages/swc/.storybook/main.ts +++ b/2nd-gen/packages/swc/.storybook/main.ts @@ -37,9 +37,15 @@ const storybookMode: StorybookMode = ? 'ci-a11y' : process.env.SWC_STORYBOOK_MODE === 'vrt' ? 'vrt' - : process.env.NODE_ENV === 'production' - ? 'build' - : 'dev'; + : // Explicit override so a static `storybook build` (e.g. PR preview + // deploys) can still produce the full dev-mode story set. The `build` + // command otherwise forces NODE_ENV=production itself before this + // file runs, regardless of what's set in the shell beforehand. + process.env.SWC_STORYBOOK_MODE === 'dev' + ? 'dev' + : process.env.NODE_ENV === 'production' + ? 'build' + : 'dev'; // Custom indexer to allow .test.ts files to be treated as story files. const testStoryIndexer: Indexer = { diff --git a/CONTRIBUTOR-DOCS/03_project-planning/03_components/sidenav/accessibility-migration-analysis.md b/CONTRIBUTOR-DOCS/03_project-planning/03_components/sidenav/accessibility-migration-analysis.md index 70f0cadd425..53764d2f277 100644 --- a/CONTRIBUTOR-DOCS/03_project-planning/03_components/sidenav/accessibility-migration-analysis.md +++ b/CONTRIBUTOR-DOCS/03_project-planning/03_components/sidenav/accessibility-migration-analysis.md @@ -142,8 +142,8 @@ Category items map to the same concept as `swc-sidenav-heading` — they provide | **`` host** | Renders a `