From 590848ef3758f364d637e7a4c41c16e994a819b9 Mon Sep 17 00:00:00 2001 From: jonniebigodes Date: Sun, 4 Jan 2026 19:10:06 +0000 Subject: [PATCH] Docs: Fix UI library examples --- .../decorator-parameterized-in-preview.md | 148 ++++++++- ...review-with-styled-components-decorator.md | 286 ++++++++++++++++++ docs/get-started/setup.mdx | 2 +- 3 files changed, 426 insertions(+), 10 deletions(-) diff --git a/docs/_snippets/decorator-parameterized-in-preview.md b/docs/_snippets/decorator-parameterized-in-preview.md index 599da719836b..e904a61d6428 100644 --- a/docs/_snippets/decorator-parameterized-in-preview.md +++ b/docs/_snippets/decorator-parameterized-in-preview.md @@ -10,7 +10,7 @@ const preview: Preview = { const { pageLayout } = parameters; switch (pageLayout) { case 'page': - // Your page layout is probably a little more complex than this ;) + // Your page layout is probably a little more complex than this return `
${story}
`; case 'page-mobile': return `
${story}
`; @@ -37,7 +37,7 @@ export default { switch (pageLayout) { case 'page': return ( - // Your page layout is probably a little more complex than this ;) + // Your page layout is probably a little more complex than this
@@ -60,7 +60,7 @@ export default { ```tsx filename=".storybook/preview.tsx" renderer="react" language="ts" tabTitle="CSF 3" import React from 'react'; -// Replace your-framework with the framework you are using, e.g. react-vite, nextjs, nextjs-vite, etc. +// Replace your-framework with the framework you are using (e.g., react-vite, nextjs, nextjs-vite) import type { Preview } from '@storybook/your-framework'; const preview: Preview = { @@ -72,7 +72,7 @@ const preview: Preview = { switch (pageLayout) { case 'page': return ( - // Your page layout is probably a little more complex than this ;) + // Your page layout is probably a little more complex than this
@@ -104,7 +104,7 @@ export default { switch (pageLayout) { case 'page': return ( - // Your page layout is probably a little more complex than this ;) + // Your page layout is probably a little more complex than this
@@ -136,7 +136,7 @@ const preview: Preview = { switch (pageLayout) { case 'page': return ( - // Your page layout is probably a little more complex than this ;) + // Your page layout is probably a little more complex than this
@@ -167,7 +167,7 @@ export default { const { pageLayout } = parameters; switch (pageLayout) { case 'page': - // Your page layout is probably a little more complex than this ;) + // Your page layout is probably a little more complex than this return { template: '
' }; case 'page-mobile': return { template: '
' }; @@ -206,6 +206,136 @@ const preview: Preview = { export default preview; ``` +```ts filename=".storybook/preview.ts" renderer="svelte" language="ts" tabTitle="Preview" +// Replace your-framework with svelte-vite or sveltekit +import type { Preview } from '@storybook/your-framework'; + +import PageLayout from './PageLayout.svelte'; + +const preview: Preview = { + decorators: [ + // πŸ‘‡ Defining the decorator in the preview file applies it to all stories + (story, { parameters }) => { + // πŸ‘‡ Make it configurable by reading from parameters + const { pageLayout } = parameters; + return { + Component: PageLayout, + props: { + layout: pageLayout || 'default', + children: story, + }, + }; + }, + ], +}; + +export default preview; +``` + +```svelte filename=".storybook/PageLayout.svelte" renderer="svelte" language="ts" tabTitle="Layout component" + + + +
+ {@render children?.()} +
+``` + +```js filename=".storybook/preview.js" renderer="svelte" language="js" tabTitle="Preview" +import PageLayout from './PageLayout.svelte'; + +const preview = { + decorators: [ + // πŸ‘‡ Defining the decorator in the preview file applies it to all stories + (story, { parameters }) => { + // πŸ‘‡ Make it configurable by reading from parameters + const { pageLayout } = parameters; + return { + Component: PageLayout, + props: { + layout: pageLayout || 'default', + children: story, + }, + }; + }, + ], +}; + +export default preview; +``` + +```svelte filename=".storybook/PageLayout.svelte" renderer="svelte" language="js" tabTitle="Layout component" + + + +
+ {@render children?.()} +
+``` + +```ts filename=".storybook/preview.ts" renderer="web-components" language="ts" +import type { Preview } from '@storybook/web-components-vite'; + +import { html } from 'lit'; + +const preview: Preview = { + decorators: [ + // πŸ‘‡ Defining the decorator in the preview file applies it to all stories + (story, { parameters }) => { + // πŸ‘‡ Make it configurable by reading from parameters + const { pageLayout } = parameters; + switch (pageLayout) { + case 'page': + // Your page layout is probably a little more complex than this + return html`
${story()}
`; + case 'page-mobile': + return html`
${story()}
`; + default: + // In the default case, don't apply a layout + return story(); + } + }, + ], +}; + +export default preview; +``` + +```js filename=".storybook/preview.js" renderer="web-components" language="js" tabTitle="Preview" +import { html } from 'lit'; + +const preview = { + decorators: [ + // πŸ‘‡ Defining the decorator in the preview file applies it to all stories + (story, { parameters }) => { + // πŸ‘‡ Make it configurable by reading from parameters + const { pageLayout } = parameters; + switch (pageLayout) { + case 'page': + // Your page layout is probably a little more complex than this + return html`
${story()}
`; + case 'page-mobile': + return html`
${story()}
`; + default: + // In the default case, don't apply a layout + return story(); + } + }, + ], +}; + +export default preview; +``` + ```tsx filename=".storybook/preview.tsx" renderer="react" language="ts" tabTitle="CSF Next πŸ§ͺ" import React from 'react'; @@ -221,7 +351,7 @@ export default definePreview({ switch (pageLayout) { case 'page': return ( - // Your page layout is probably a little more complex than this ;) + // Your page layout is probably a little more complex than this
@@ -258,7 +388,7 @@ export default definePreview({ switch (pageLayout) { case 'page': return ( - // Your page layout is probably a little more complex than this ;) + // Your page layout is probably a little more complex than this
diff --git a/docs/_snippets/storybook-preview-with-styled-components-decorator.md b/docs/_snippets/storybook-preview-with-styled-components-decorator.md index df975665fc46..278ba3e2cf15 100644 --- a/docs/_snippets/storybook-preview-with-styled-components-decorator.md +++ b/docs/_snippets/storybook-preview-with-styled-components-decorator.md @@ -27,6 +27,292 @@ const preview: Preview = { export default preview; ``` +```ts filename=".storybook/preview.ts" renderer="vue" language="ts" tabTitle="Preview" +import type { Preview } from '@storybook/vue3-vite'; +import { setup } from '@storybook/vue3-vite'; + +import 'vuetify/styles'; +import '@mdi/font/css/materialdesignicons.css'; +import vuetify from '../src/plugins/vuetify'; + +import StoryWrapper from './StoryWrapper.vue'; + +// Registers the Vuetify plugin in Storybook's Vue app instance +setup((app) => { + app.use(vuetify); +}); + +const preview: Preview = { + decorators: [ + (_, { globals }) => { + // The theme can be accessed via the story context's globals + const themeName = globals.theme || 'light'; + return { + components: { StoryWrapper }, + setup() { + return { themeName }; + }, + template: ` + + + + `, + }; + }, + ], +}; + +export default preview; +``` + +```html filename=".storybook/StoryWrapper.vue" renderer="vue" language="ts" tabTitle="Theme Provider" + + + +``` + +```js filename=".storybook/preview.js" renderer="vue" language="js" tabTitle="Preview" +import { setup } from '@storybook/vue3-vite'; + +import 'vuetify/styles'; +import '@mdi/font/css/materialdesignicons.css'; +import vuetify from '../src/plugins/vuetify'; + +import StoryWrapper from './StoryWrapper.vue'; + +// Registers the Vuetify plugin in Storybook's Vue app instance +setup((app) => { + app.use(vuetify); +}); + +const preview = { + decorators: [ + (_, { globals }) => { + // The theme can be accessed via the story context's globals + const themeName = globals.theme || 'light'; + return { + components: { StoryWrapper }, + setup() { + return { themeName }; + }, + template: ` + + + + `, + }; + }, + ], +}; + +export default preview; +``` + +```html filename=".storybook/StoryWrapper.vue" renderer="vue" language="js" tabTitle="Theme Provider" + + + +``` + +```ts filename=".storybook/preview.ts" renderer="svelte" language="ts" tabTitle="Preview" +// Replace your-framework with svelte-vite or sveltekit +import type { Preview } from '@storybook/your-framework'; + +import ThemeProvider from './ThemeProvider.svelte'; + +const preview: Preview = { + decorators: [ + // The theme can be accessed via the story context's globals + (story, { globals }) => { + return { + Component: ThemeProvider, + props: { + theme: globals.theme || 'light', + children: story, + }, + }; + }, + ], +}; + +export default preview; +``` + +```svelte filename=".storybook/ThemeProvider.svelte" renderer="svelte" language="ts" tabTitle="Theme Provider" + + + +
+ {@render children?.()} +
+
+``` + +```js filename=".storybook/preview.js" renderer="svelte" language="js" tabTitle="Preview" +import ThemeProvider from './ThemeProvider.svelte'; + +const preview = { + decorators: [ + // The theme can be accessed via the story context's globals + (story, { globals }) => { + return { + Component: ThemeProvider, + props: { + theme: globals.theme || 'light', + children: story, + }, + }; + }, + ], +}; + +export default preview; +``` + +```svelte filename=".storybook/ThemeProvider.svelte" renderer="svelte" language="js" tabTitle="Theme Provider" + + + +
+ {@render children?.()} +
+
+``` + +```ts filename=".storybook/preview.ts" renderer="web-components" language="ts" tabTitle="Preview" +import type { Preview } from '@storybook/web-components-vite'; + +import { html } from 'lit'; + +import './ThemeProvider'; + +const preview: Preview = { + decorators: [ + // The theme can be accessed via the story context's globals + (story, { globals }) => { + const theme = globals.theme || 'light'; + return html`${story()}`; + }, + ], +}; + +export default preview; +``` + +```ts filename=".storybook/ThemeProvider.ts" renderer="web-components" language="ts" tabTitle="Theme Provider" +import { LitElement, html } from 'lit'; +import { customElement, property } from 'lit/decorators.js'; + +export type Theme = 'light' | 'dark'; + +@customElement('theme-provider') +export class ThemeProvider extends LitElement { + @property({ type: String, reflect: true }) + theme: Theme = 'light'; + + public setTheme(theme: Theme): void { + this.theme = theme; + } + public getTheme(): Theme { + return this.theme; + } + + override render() { + return html` `; + } +} +``` + +```js filename=".storybook/preview.js" renderer="web-components" language="js" tabTitle="Preview" +import { html } from 'lit'; + +import './ThemeProvider'; + +const preview = { + decorators: [ + // The theme can be accessed via the story context's globals + (story, { globals }) => { + const theme = globals.theme || 'light'; + return html`${story()}`; + }, + ], +}; + +export default preview; +``` + +```js filename=".storybook/ThemeProvider.js" renderer="web-components" language="js" tabTitle="Theme Provider" +import { LitElement, html } from 'lit'; + +export class ThemeProvider extends LitElement { + static properties = { + theme: { type: String, reflect: true }, + }; + + constructor() { + super(); + this.theme = 'light'; + } + + setTheme(theme) { + this.theme = theme; + } + + getTheme() { + return this.theme; + } + + render() { + return html``; + } +} + +if (!customElements.get('theme-provider')) { + customElements.define('theme-provider', ThemeProvider); +} +``` + ```jsx filename=".storybook/preview.js" renderer="react" language="js" tabTitle="CSF 3" import React from 'react'; diff --git a/docs/get-started/setup.mdx b/docs/get-started/setup.mdx index e922ffc54db1..1c5fc6f93cc5 100644 --- a/docs/get-started/setup.mdx +++ b/docs/get-started/setup.mdx @@ -66,7 +66,7 @@ Your project may have additional requirements before components can be rendered A common frontend pattern is for components to assume that they render in a specific β€œcontext” with parent components higher up the rendering hierarchy (for instance, theme providers). - Use [decorators](../writing-stories/decorators.mdx) to β€œwrap” every story in the necessary context providers. The [`.storybook/preview.js|ts`](../configure/index.mdx#configure-story-rendering) file allows you to customize how components render in Canvas, the preview iframe. See how you can wrap every component rendered in Storybook with [Styled Components](https://styled-components.com/) `ThemeProvider`, [Vue's Fontawesome](https://github.com/FortAwesome/vue-fontawesome), or with an Angular theme provider component in the example below. + Use [decorators](../writing-stories/decorators.mdx) to β€œwrap” every story in the necessary context providers. The [`.storybook/preview.js|ts`](../configure/index.mdx#configure-story-rendering) file allows you to customize how components render in Canvas, the preview iframe. See how you can wrap every component rendered in Storybook with [Styled Components](https://styled-components.com/) `ThemeProvider`, [Vue's Vuetify](https://vuetifyjs.com/en/), Svelte's [Bits UI](https://bits-ui.com/) `BitsConfig`, or with an Angular theme provider component in the example below. {/* prettier-ignore-start */}