diff --git a/MIGRATION.md b/MIGRATION.md index 2e2e735fb21f..07aecbbe3973 100644 --- a/MIGRATION.md +++ b/MIGRATION.md @@ -1,5 +1,7 @@

Migration

+- [From version 8.4.x to 8.5.x](#from-version-84x-to-85x) + - [Added source code pnael to docs](#added-source-code-pnael-to-docs) - [From version 8.2.x to 8.3.x](#from-version-82x-to-83x) - [Removed `experimental_SIDEBAR_BOTTOM` and deprecated `experimental_SIDEBAR_TOP` addon types](#removed-experimental_sidebar_bottom-and-deprecated-experimental_sidebar_top-addon-types) - [New parameters format for addon backgrounds](#new-parameters-format-for-addon-backgrounds) @@ -167,7 +169,7 @@ - [Angular: Drop support for calling Storybook directly](#angular-drop-support-for-calling-storybook-directly) - [Angular: Application providers and ModuleWithProviders](#angular-application-providers-and-modulewithproviders) - [Angular: Removed legacy renderer](#angular-removed-legacy-renderer) - - [Angular: initializer functions](#angular-initializer-functions) + - [Angular: Initializer functions](#angular-initializer-functions) - [Next.js: use the `@storybook/nextjs` framework](#nextjs-use-the-storybooknextjs-framework) - [SvelteKit: needs the `@storybook/sveltekit` framework](#sveltekit-needs-the-storybooksveltekit-framework) - [Vue3: replaced app export with setup](#vue3-replaced-app-export-with-setup) @@ -419,6 +421,22 @@ - [Packages renaming](#packages-renaming) - [Deprecated embedded addons](#deprecated-embedded-addons) +## From version 8.4.x to 8.5.x + +### Added source code pnael to docs + +Starting in 8.5, Storybook Docs (`@storybook/addon-docs`) automatically adds a new addon panel to stories that displays a source snippet beneath each story. This works similarly to the existing [source snippet doc block](https://storybook.js.org/docs/writing-docs/doc-blocks#source), but in the story view. It is intended to replace the [Storysource addon](https://storybook.js.org/addons/@storybook/addon-storysource). + +If you wish to disable this panel globally, add the following line to your `.storybook/preview.js` project configuration. You can also selectively disable/enable at the story level. + +```js +export default { + parameters: { + docsSourcePanel: { disable: true }, + }, +}; +``` + ## From version 8.2.x to 8.3.x ### Removed `experimental_SIDEBAR_BOTTOM` and deprecated `experimental_SIDEBAR_TOP` addon types diff --git a/code/addons/docs/src/manager.tsx b/code/addons/docs/src/manager.tsx index 09c371be238b..fdbe0375d369 100644 --- a/code/addons/docs/src/manager.tsx +++ b/code/addons/docs/src/manager.tsx @@ -1,31 +1,17 @@ import React from 'react'; import { AddonPanel, type SyntaxHighlighterFormatTypes } from 'storybook/internal/components'; -import { FORCE_RE_RENDER, PRELOAD_ENTRIES } from 'storybook/internal/core-events'; -import { ADDON_ID, PANEL_ID, PARAM_KEY, SNIPPET_RENDERED } from 'storybook/internal/docs-tools'; +import { ADDON_ID, PANEL_ID, SNIPPET_RENDERED } from 'storybook/internal/docs-tools'; import { addons, types, useAddonState, useChannel } from 'storybook/internal/manager-api'; import { Source } from '@storybook/blocks'; -addons.register(ADDON_ID, async (api) => { - // at this point, the parameters are not yet defined so we can not check whether the addon panel should - // be added or not. The "PRELOAD_ENTRIES" event seems to be the earliest point in time where the parameters - // are available - const isDisabled = await new Promise((resolve) => { - api.once(PRELOAD_ENTRIES, () => { - const parameter = api.getCurrentParameter(PARAM_KEY); - resolve(shouldDisableAddonPanel(parameter)); - }); - }); - - if (isDisabled) { - return; - } - +addons.register(ADDON_ID, (api) => { addons.add(PANEL_ID, { title: 'Code', type: types.PANEL, - paramKey: PARAM_KEY, + // disable this with `docsSourcePanel: { disable: true }` + paramKey: 'docsSourcePanel', match: ({ viewMode }) => viewMode === 'story', render: ({ active }) => { const [codeSnippet, setSourceCode] = useAddonState<{ @@ -49,24 +35,4 @@ addons.register(ADDON_ID, async (api) => { ); }, }); - - api.emit(FORCE_RE_RENDER); }); - -const isObject = (value: unknown): value is object => { - return value != null && typeof value === 'object'; -}; - -/** - * Checks whether the addon panel should be disabled by checking the parameter.source.addonPanel - * property. - */ -const shouldDisableAddonPanel = (parameter: unknown) => { - return ( - isObject(parameter) && - 'source' in parameter && - isObject(parameter.source) && - 'addonPanel' in parameter.source && - parameter.source.addonPanel === false - ); -}; diff --git a/code/addons/docs/template/stories/sourcePanel/index.stories.tsx b/code/addons/docs/template/stories/sourcePanel/index.stories.tsx new file mode 100644 index 000000000000..dd4d2208fe6e --- /dev/null +++ b/code/addons/docs/template/stories/sourcePanel/index.stories.tsx @@ -0,0 +1,15 @@ +export default { + component: globalThis.Components.Button, + tags: ['autodocs'], + parameters: { + chromatic: { disable: true }, + docsSourcePanel: { disable: true }, + }, +}; + +export const One = { args: { label: 'One' } }; +export const Two = { args: { label: 'Two' } }; +export const WithSource = { + args: { label: 'Three' }, + parameters: { docsSourcePanel: { disable: false } }, +};