From 82ee228c6fb211d8f43197bbff87a27889ef4c10 Mon Sep 17 00:00:00 2001 From: devjiwonchoi Date: Thu, 12 Jun 2025 14:43:31 +0200 Subject: [PATCH 1/3] [devtools] apply tailwind to storybook --- packages/next/.storybook/main.ts | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/packages/next/.storybook/main.ts b/packages/next/.storybook/main.ts index 9dadabe0165e..860d8e56b087 100644 --- a/packages/next/.storybook/main.ts +++ b/packages/next/.storybook/main.ts @@ -34,5 +34,37 @@ const config: StorybookConfig = { }, }, }), + webpackFinal: async (config) => { + // Exclude tailwind.css from all existing CSS rules + config.module?.rules?.forEach((rule) => { + if ( + rule && + typeof rule === 'object' && + 'test' in rule && + rule.test?.toString().includes('css') + ) { + rule.exclude = rule.exclude + ? [rule.exclude, /tailwind\.css$/].flat() + : /tailwind\.css$/ + } + }) + + // Add our custom rule for tailwind.css + config.module?.rules?.push({ + test: /tailwind\.css$/, + use: [ + { + loader: 'style-loader', + options: { + injectType: 'lazyStyleTag', + insert: require.resolve('../next-devtools-inject-tailwind.js'), + }, + }, + 'css-loader', + 'postcss-loader', + ], + }) + return config + }, } export default config From 34ca4689c5e2c7722d6476ae1118da24e96ad8c3 Mon Sep 17 00:00:00 2001 From: devjiwonchoi Date: Fri, 13 Jun 2025 02:07:13 +0200 Subject: [PATCH 2/3] preserve the tailwind style tag on storybook --- .../dev-overlay/components/shadow-portal.tsx | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/packages/next/src/next-devtools/dev-overlay/components/shadow-portal.tsx b/packages/next/src/next-devtools/dev-overlay/components/shadow-portal.tsx index 5ff7ea3d7ea4..c93e4da3e6f0 100644 --- a/packages/next/src/next-devtools/dev-overlay/components/shadow-portal.tsx +++ b/packages/next/src/next-devtools/dev-overlay/components/shadow-portal.tsx @@ -37,6 +37,14 @@ export function ShadowPortal({ children }: { children: React.ReactNode }) { if (portalNode.current.shadowRoot === null) { shadowNode.current = portalNode.current.attachShadow({ mode: 'open' }) + // Storybook injects the Tailwind style tag from .storybook/main.ts on each load. + // When navigating to a different story, the injected style tag is removed within the iframe. + // To re-inject the style tag, we need to call `unuse()` since the `use()` function only runs + // once unless unused. + if (process.env.STORYBOOK) { + tailwindCss.unuse() + } + // Injecting Tailwind to the Shadow DOM with Webpack style-loader. // The target is passed to the next-devtools-inject-tailwind.js file which runs on the browser. // x-ref: https://webpack.js.org/loaders/style-loader/#lazystyletag From bf2ad56a73ec20f39b1df1c005dcf3e6008ffc37 Mon Sep 17 00:00:00 2001 From: devjiwonchoi Date: Fri, 13 Jun 2025 02:12:43 +0200 Subject: [PATCH 3/3] comment: full load --- .../src/next-devtools/dev-overlay/components/shadow-portal.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/next/src/next-devtools/dev-overlay/components/shadow-portal.tsx b/packages/next/src/next-devtools/dev-overlay/components/shadow-portal.tsx index c93e4da3e6f0..dc58f0b17e61 100644 --- a/packages/next/src/next-devtools/dev-overlay/components/shadow-portal.tsx +++ b/packages/next/src/next-devtools/dev-overlay/components/shadow-portal.tsx @@ -37,7 +37,7 @@ export function ShadowPortal({ children }: { children: React.ReactNode }) { if (portalNode.current.shadowRoot === null) { shadowNode.current = portalNode.current.attachShadow({ mode: 'open' }) - // Storybook injects the Tailwind style tag from .storybook/main.ts on each load. + // Storybook injects the Tailwind style tag from .storybook/main.ts on each full load. // When navigating to a different story, the injected style tag is removed within the iframe. // To re-inject the style tag, we need to call `unuse()` since the `use()` function only runs // once unless unused.