Skip to content

Conversation

@mrginglymus
Copy link
Contributor

@mrginglymus mrginglymus commented Nov 25, 2025

Closes #33161

What I did

Ensure code panel hooks are called within a react component rather than the addon render function, to ensure compliance with storybook's own docs:

/**
* The actual contents of your addon.
*
* This is called as a function, so if you want to use hooks, your function needs to return a
* JSX.Element within which components are rendered
*/
render: (props: Partial<Addon_RenderOptions>) => ReturnType<FC<Partial<Addon_RenderOptions>>>;

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

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

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 PR does not have a canary release associated. You can request a canary release of this pull request by mentioning the @storybookjs/core team here.

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

Summary by CodeRabbit

  • Refactor
    • Internal code reorganization with no visible changes to user experience.

✏️ Tip: You can customize this high-level summary in your review settings.

currentStoryId,
}: {
active: boolean | undefined;
lastEvent: any | undefined;
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I did try to type this, then I noticed that where it is emitted, format is not actually set....

addons.getChannel().emit(SNIPPET_RENDERED, {
id,
source: result,
args: unmappedArgs,
});

@nx-cloud
Copy link

nx-cloud bot commented Nov 25, 2025

View your CI Pipeline Execution ↗ for commit 4102998

Command Status Duration Result
nx run-many -t compile --parallel=3 ✅ Succeeded 45s View ↗

☁️ Nx Cloud last updated this comment at 2025-12-01 15:52:43 UTC

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 26, 2025

📝 Walkthrough

Walkthrough

The code panel rendering logic in the manager component is refactored into a new CodePanel component, extracting state management, parameter retrieval, channel subscriptions, and theming logic from inline code into an isolated component structure.

Changes

Cohort / File(s) Summary
Component extraction
code/addons/docs/src/manager.tsx
Refactors code panel rendering by extracting state (codeSnippet), channel listeners (SNIPPET_RENDERED), parameter retrieval, and dark mode determination into a new CodePanel component. Preserves existing behavior with encapsulated logic.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

  • Focus on verifying state initialization and channel subscription logic is correctly preserved in the new component
  • Confirm the component lifecycle (reinitializes on currentStoryId changes) matches the previous inline behavior
  • Check that theming logic accurately reflects dark mode determination from the previous implementation
✨ Finishing touches
  • 📝 Generate docstrings

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

Copy link
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: 0

🧹 Nitpick comments (2)
code/addons/docs/src/manager.tsx (2)

17-25: Consider defining a type for lastEvent instead of any.

The lastEvent prop is typed as any, which reduces type safety. Even if the format field is unreliable (as noted in your comment), defining a minimal interface would improve code clarity.

+interface SnippetRenderedEvent {
+  source?: string;
+  format?: SyntaxHighlighterFormatTypes;
+}
+
 const CodePanel = ({
   active,
   lastEvent,
   currentStoryId,
 }: {
   active: boolean | undefined;
-  lastEvent: any | undefined;
+  lastEvent: SnippetRenderedEvent | undefined;
   currentStoryId: string | undefined;
 }) => {

26-32: Fix naming inconsistency between state variable and setter.

The state is named codeSnippet but the setter is setSourceCode. For consistency, rename the setter to match the state variable name.

-  const [codeSnippet, setSourceCode] = useState<{
+  const [codeSnippet, setCodeSnippet] = useState<{

Then update the setter calls on lines 40 and 48:

-    setSourceCode({
+    setCodeSnippet({
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 809c130 and 6c11393.

📒 Files selected for processing (1)
  • code/addons/docs/src/manager.tsx (2 hunks)
🧰 Additional context used
📓 Path-based instructions (4)
**/*.{ts,tsx,js,jsx,mjs}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Use camelCase for variable and function names

Files:

  • code/addons/docs/src/manager.tsx
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.{ts,tsx}: Enable TypeScript strict mode
Export functions from modules for testing purposes

Files:

  • code/addons/docs/src/manager.tsx
**/*.{ts,tsx,js,jsx,json,html,mjs}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.{ts,tsx,js,jsx,json,html,mjs}: Use ESLint and Prettier for code style enforcement
Run 'yarn prettier --write ' to format code after making changes
Run 'yarn lint:js:cmd ' to check for ESLint issues after making changes

Files:

  • code/addons/docs/src/manager.tsx
code/**/!(*.test).{ts,tsx,js,mjs}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

code/**/!(*.test).{ts,tsx,js,mjs}: Use 'logger' from 'storybook/internal/node-logger' for server-side (Node.js) logging, not console.log/console.warn/console.error
Use 'logger' from 'storybook/internal/client-logger' for client-side (browser) logging, not console.log/console.warn/console.error
Do not use console.log, console.warn, or console.error directly unless in isolated files where importing loggers would significantly increase bundle size

Files:

  • code/addons/docs/src/manager.tsx
🧠 Learnings (1)
📓 Common learnings
Learnt from: Sidnioulz
Repo: storybookjs/storybook PR: 32458
File: code/core/src/components/components/Tabs/Tabs.stories.tsx:222-227
Timestamp: 2025-11-05T09:36:55.944Z
Learning: Repo: storybookjs/storybook PR: 32458 — In code/core/src/components/components/Button/Button.tsx (React/TypeScript), ButtonProps includes ariaLabel?: string | false and the component maps it to the DOM aria-label. Convention: ariaLabel is mandatory on all Button usages — provide a descriptive string for icon-only buttons; set ariaLabel=false when the button’s children already serve as the accessible name. Do not suggest using a raw aria-label prop on Button call sites.
Learnt from: Sidnioulz
Repo: storybookjs/storybook PR: 32458
File: code/core/src/components/components/Select/Select.tsx:200-204
Timestamp: 2025-11-05T09:38:47.712Z
Learning: Repo: storybookjs/storybook — Guidance: Until Storybook 11 is released, do not suggest using React.useId anywhere (e.g., in code/core/src/components/components/Select/Select.tsx) to maintain compatibility with React 17 runtimes. Prefer advising: accept a caller-provided props.id and, if needed, generate a client-only fallback id to minimize SSR hydration issues — but avoid useId. Resume prompting for useId after Storybook 11.
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: normal
  • GitHub Check: get-parameters
🔇 Additional comments (6)
code/addons/docs/src/manager.tsx (6)

34-37: LGTM!

The parameter retrieval with sensible defaults is correct.


39-44: LGTM!

The effect correctly resets the code snippet when navigating to a different story, preventing stale code from displaying.


46-50: LGTM!

The channel subscription correctly updates the code snippet state when new source code is rendered.


52-53: LGTM!

The theme detection logic is correct for determining dark mode.


55-67: LGTM!

The rendering logic correctly prioritizes the code sources and applies the appropriate theme.


89-96: LGTM! This change fixes the React hooks error.

By extracting hook calls into the CodePanel component and returning it from the render function, you've correctly resolved the issue where hooks were being called outside of a React component. This now complies with Storybook's addon API requirements.

@valentinpalkovic valentinpalkovic changed the title Ensure CodePanel hooks are called within component Docs: Ensure CodePanel hooks are called within component Dec 9, 2025
@valentinpalkovic valentinpalkovic merged commit 41f1653 into storybookjs:next Dec 9, 2025
58 of 60 checks passed
@github-actions github-actions bot mentioned this pull request Dec 9, 2025
13 tasks
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.

[Bug]: @storybook/addon-docs code panel calls react hooks outside of react component

2 participants