Skip to content

Addon-docs: Add transformCode option to apply transform to code prop#34519

Open
adam-sajko wants to merge 2 commits intostorybookjs:nextfrom
adam-sajko:feat/source-block-transform-code-option
Open

Addon-docs: Add transformCode option to apply transform to code prop#34519
adam-sajko wants to merge 2 commits intostorybookjs:nextfrom
adam-sajko:feat/source-block-transform-code-option

Conversation

@adam-sajko
Copy link
Copy Markdown

@adam-sajko adam-sajko commented Apr 10, 2026

transform is currently ignored when code is provided (via prop or parameter). This makes sense as a default, you don't want a global Prettier transform reformatting your hand-written snippets.

But sometimes you do want transform applied to code. This PR adds a transformCode boolean (defaults to false) to opt in.

Works as a prop, story parameter, or globally in preview.ts:

<Source code="const x = 1;" transform={fn} transformCode />
// .storybook/preview.ts
export const parameters = {
  docs: {
    source: {
      transformCode: true,
      transform: (code) => prettify(code),
    },
  },
};

What I did

  • Added transformCode?: boolean to SourceParameters
  • When true, transform runs on the code prop before rendering
  • Updated docs: new transformCode section, clarified transform/code interaction

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

  1. yarn task --task sandbox --start-from auto --template react-vite/default-ts
  2. <Source code="..." transform={fn} /> — should render raw code (unchanged behavior)
  3. <Source code="..." transform={fn} transformCode /> — should apply transform
  4. Set parameters.docs.source.transformCode: true in preview.ts — should apply globally

My Sandbox

import { Meta, Source } from '@storybook/addon-docs/blocks';
import * as ButtonStories from './Button.stories';

<Meta title="Tests/TransformCode" />

# TransformCode Test

## 1. code prop without transform — should render raw

<Source code={`const x = 1;\nconst y = 2;`} />

## 2. code + transform, no transformCode — transform should be IGNORED

<Source
  code={`const x = 1;\nconst y = 2;`}
  transform={(code) => code.toUpperCase()}
/>

## 3. code + transform + transformCode — transform should APPLY

<Source
  code={`const x = 1;\nconst y = 2;`}
  transform={(code) => code.toUpperCase()}
  transformCode
/>

## 4. Story source (no code prop) — should render normal source

<Source of={ButtonStories.Primary} />
image

Documentation

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

Summary by CodeRabbit

  • New Features

    • Added a new transformCode option to the Source block so consumers can opt to apply transformations to code provided directly.
    • When both code and a transform are supplied, the transform is applied only if transformCode is enabled; otherwise the code renders unchanged.
    • Formatting behavior now respects whether code was provided directly versus sourced, improving predictable output.
  • Documentation

    • Docs updated to describe the new transformCode option, precedence rules, and formatting implications.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 10, 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: 96d2f94e-ba4f-46d1-8487-7d15805da422

📥 Commits

Reviewing files that changed from the base of the PR and between 73e927f and 83abec2.

📒 Files selected for processing (1)
  • code/addons/docs/src/blocks/blocks/Source.tsx

📝 Walkthrough

Walkthrough

Added optional transformCode?: boolean to SourceParameters; explicit code is transformed only when transformCode is true. useCode no longer returns untransformed direct code early. useSourceProps computes directCode, shouldTransformCode, conditionally applies transform, and documentation was updated.

Changes

Cohort / File(s) Summary
Source Block Implementation
code/addons/docs/src/blocks/blocks/Source.tsx
Added transformCode?: boolean to SourceParameters. Removed early-return in useCode so transformed code is always returned when a transformer exists. useSourceProps now determines directCode = props.code ?? sourceParameters.code, shouldTransformCode = props.transformCode ?? sourceParameters.transformCode ?? false, creates codeTransformer only when shouldTransformCode is true, computes transformedDirectCode via useTransformCode, and returns { code: codeTransformer ? transformedDirectCode : directCode }. Adjusted format derivation to depend on presence of props.code.
Documentation
docs/api/doc-blocks/doc-block-source.mdx
Documented new transformCode boolean and clarified precedence: transform is applied to code only when transformCode is enabled (defaults to parameters.docs.source.transformCode or false).

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@code/addons/docs/src/blocks/blocks/Source.tsx`:
- Around line 154-160: The hook useTransformCode must be called unconditionally
to keep hook order stable: always invoke useTransformCode (passing props.code
and the transformer value derived from props.transform ??
sourceParameters.transform or undefined) and then conditionally use its returned
transformed code only when transformer and props.code are present; update the
code variable assignment (currently using transformer ? useTransformCode(...) :
props.code) so useTransformCode is called every render and its result is
selected conditionally, leaving transformCode, transformer, props.code,
props.transform, sourceParameters.transform, storyContext, argsForSource, and
code as the relevant symbols to locate and update.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 8076e744-a2b1-4060-8339-ea6ac38ba203

📥 Commits

Reviewing files that changed from the base of the PR and between aae6c95 and d79b66b.

📒 Files selected for processing (2)
  • code/addons/docs/src/blocks/blocks/Source.tsx
  • docs/api/doc-blocks/doc-block-source.mdx

@adam-sajko adam-sajko force-pushed the feat/source-block-transform-code-option branch from d79b66b to 14aa612 Compare April 10, 2026 10:53
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
code/addons/docs/src/blocks/blocks/Source.tsx (1)

139-165: ⚠️ Potential issue | 🟠 Major

parameters.docs.source.code still skips transformCode.

This only fixes the props.code branch. useCode() still returns sourceParameters.code unchanged on Line 93-Line 95, so parameters.docs.source.transformCode = true will not transform story/global parameters.docs.source.code. That leaves one of the advertised entry points for the feature non-functional.

🔧 Suggested direction
 const useCode = ({
   snippet,
   storyContext,
   typeFromProps,
   transformFromProps,
+  transformCodeFromProps,
 }: {
   snippet: string;
   storyContext: ReturnType<DocsContextProps['getStoryContext']>;
   typeFromProps: SourceType;
   transformFromProps?: SourceProps['transform'];
+  transformCodeFromProps?: SourceProps['transformCode'];
 }): string => {
   const parameters = storyContext.parameters ?? {};
   const { __isArgsStory: isArgsStory } = parameters;
   const sourceParameters = (parameters.docs?.source || {}) as SourceParameters;
@@
   const code = useSnippet ? snippet : sourceParameters.originalSource || '';
   const transformer = transformFromProps ?? sourceParameters.transform;
+  const providedCode = sourceParameters.code;
+  const shouldTransformProvidedCode =
+    transformCodeFromProps ?? sourceParameters.transformCode ?? false;
+  const providedCodeTransformer = shouldTransformProvidedCode
+    ? (transformFromProps ?? sourceParameters.transform)
+    : undefined;
 
   const transformedCode = transformer ? useTransformCode(code, transformer, storyContext) : code;
+  const transformedProvidedCode = useTransformCode(
+    providedCode ?? '',
+    providedCodeTransformer ?? ((c) => c),
+    storyContext
+  );
 
-  if (sourceParameters.code !== undefined) {
-    return sourceParameters.code;
+  if (providedCode !== undefined) {
+    return providedCodeTransformer ? transformedProvidedCode : providedCode;
   }
   const transformedCode = useCode({
     snippet: source ? source.code : '',
     storyContext: { ...storyContext, args: argsForSource },
     typeFromProps: props.type as SourceType,
     transformFromProps: props.transform,
+    transformCodeFromProps: props.transformCode,
   });
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@code/addons/docs/src/blocks/blocks/Source.tsx` around lines 139 - 165, The
parameters.docs.source.code path isn't being passed through the transformCode
logic; update the code that reads sourceParameters.code (e.g., inside useCode or
wherever sourceParameters.code is returned) to mirror the props.code branch:
detect shouldTransformCode (from props.transformCode ??
sourceParameters.transformCode), pick the transformer (props.transform ??
sourceParameters.transform), run useTransformCode on sourceParameters.code (or
apply the transformer) and return the transformed result (use
transformedCodeProp-like value) instead of returning sourceParameters.code
unchanged; ensure you reference sourceParameters, shouldTransformCode,
codeTransformer, useTransformCode, and transformedCodeProp so the
global/story-level parameters.docs.source.code honors transformCode.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@code/addons/docs/src/blocks/blocks/Source.tsx`:
- Around line 139-165: The parameters.docs.source.code path isn't being passed
through the transformCode logic; update the code that reads
sourceParameters.code (e.g., inside useCode or wherever sourceParameters.code is
returned) to mirror the props.code branch: detect shouldTransformCode (from
props.transformCode ?? sourceParameters.transformCode), pick the transformer
(props.transform ?? sourceParameters.transform), run useTransformCode on
sourceParameters.code (or apply the transformer) and return the transformed
result (use transformedCodeProp-like value) instead of returning
sourceParameters.code unchanged; ensure you reference sourceParameters,
shouldTransformCode, codeTransformer, useTransformCode, and transformedCodeProp
so the global/story-level parameters.docs.source.code honors transformCode.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 9cb00aab-82b4-4cf2-95b1-0169b41d9b57

📥 Commits

Reviewing files that changed from the base of the PR and between d79b66b and 14aa612.

📒 Files selected for processing (2)
  • code/addons/docs/src/blocks/blocks/Source.tsx
  • docs/api/doc-blocks/doc-block-source.mdx

@adam-sajko adam-sajko force-pushed the feat/source-block-transform-code-option branch from 14aa612 to 730ed19 Compare April 10, 2026 11:06
@adam-sajko adam-sajko force-pushed the feat/source-block-transform-code-option branch from 730ed19 to 73e927f Compare April 10, 2026 11:07
@adam-sajko
Copy link
Copy Markdown
Author

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 10, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
code/addons/docs/src/blocks/blocks/Source.tsx (1)

135-163: Add tests for the new transformCode branch matrix.

Lines 136-163 add multiple precedence paths (props.code vs parameter code, transformCode prop vs parameter, and transform origin). Please add focused unit coverage for these combinations to prevent regressions.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@code/addons/docs/src/blocks/blocks/Source.tsx` around lines 135 - 163, Add
unit tests for the Source component covering the transformCode precedence
matrix: create focused tests that exercise (1) directCode provided via props vs
code via sourceParameters, (2) transformCode true/false/undefined from props vs
sourceParameters, and (3) transform function coming from props vs
sourceParameters. For each combination assert whether useTransformCode
(transformedDirectCode) is used or the raw code is returned, and also verify
format selection logic when props.code is set vs when it falls back to format/
source?.format; reference the variables/source operators in the component
(sourceParameters, directCode, shouldTransformCode, codeTransformer,
transformedDirectCode, useTransformCode, props.code, props.transformCode) to
guide test setup and expected outcomes.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@code/addons/docs/src/blocks/blocks/Source.tsx`:
- Around line 138-145: The code may call user-provided transformers even when
directCode is empty; change the logic so the transformer is only selected when
shouldTransformCode is true AND directCode is non-empty. Concretely update the
computation of codeTransformer (used by useTransformCode for
transformedDirectCode) to require directCode (e.g., codeTransformer =
shouldTransformCode && directCode ? (props.transform ??
sourceParameters.transform) : undefined), and make the same guard for the other
transformer usage (the highlighted/other transformed code block) so
useTransformCode receives an identity/undefined transformer when there's no
direct code to avoid running user transforms unnecessarily.

---

Nitpick comments:
In `@code/addons/docs/src/blocks/blocks/Source.tsx`:
- Around line 135-163: Add unit tests for the Source component covering the
transformCode precedence matrix: create focused tests that exercise (1)
directCode provided via props vs code via sourceParameters, (2) transformCode
true/false/undefined from props vs sourceParameters, and (3) transform function
coming from props vs sourceParameters. For each combination assert whether
useTransformCode (transformedDirectCode) is used or the raw code is returned,
and also verify format selection logic when props.code is set vs when it falls
back to format/ source?.format; reference the variables/source operators in the
component (sourceParameters, directCode, shouldTransformCode, codeTransformer,
transformedDirectCode, useTransformCode, props.code, props.transformCode) to
guide test setup and expected outcomes.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 1d008f6d-1aaf-4c33-b4de-75fea958c75a

📥 Commits

Reviewing files that changed from the base of the PR and between 14aa612 and 73e927f.

📒 Files selected for processing (2)
  • code/addons/docs/src/blocks/blocks/Source.tsx
  • docs/api/doc-blocks/doc-block-source.mdx

@adam-sajko
Copy link
Copy Markdown
Author

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 10, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

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.

1 participant