Closed aaronadamsCA closed 1 year ago
I have the same question @aaronadamsCA
We have the same problem here. Upgraded to 7.x and @storybook/addon-styling and now we don't have any styling applied.
Funny thing is some styles are applied when adding import 'tailwindcss/tailwind.css';
to the preview but nothing is happening when importing our own styles (import '../styles/globals.css';
).
preview.js
// import 'tailwindcss/tailwind.css';
import '../styles/globals.css';
export const parameters = {
actions: { argTypesRegex: '^on[A-Z].*' },
controls: {
expanded: true,
hideNoControlsWarning: true,
matchers: {
color: /(background|color)$/i,
date: /Date$/,
},
},
};
main.js
module.exports = {
stories: [
'../stories/**/*.stories.@(js|jsx|ts|tsx|mdx)',
'../components/**/*.stories.@(js|jsx|ts|tsx|mdx)',
],
addons: [
'@storybook/addon-essentials',
{
name: '@storybook/addon-styling',
options: {
cssModules: true,
postCss: {
implementation: require('postcss'),
},
},
},
'@storybook/addon-mdx-gfm',
],
framework: {
name: '@storybook/nextjs',
options: {},
},
docs: {
autodocs: true,
},
};
postcss.config.js
module.exports = {
plugins: {
'postcss-import': {},
'tailwindcss/nesting': {},
tailwindcss: {},
autoprefixer: {},
cssnano: { preset: 'default' },
},
};
@dariusrosendahl Unless you want to use the theme switcher feature, you don't need to use @storybook/addon-styling
. The @storybook/nextjs
framework copies the configuration for your next app which works out of the box with postcss
and css modules.
Try removing @storybook/addon-styling
from your addons array and see if that solves your issue
Hey @aaronadamsCA 👋
Out of curiosity, do you have a sideEffects
array in your package.json?
Hey @Integrayshaun ,
I removed @storybook/addon-styling
but to no avail. Still no styling, it doesn't seem to pick up the stylesheet imported in preview.js
. Is there anything else I'm missing?
Hey @aaronadamsCA 👋
Out of curiosity, do you have a
sideEffects
array in your package.json?
@Integrayshaun, our package currently specifies "sideEffects": false
. I believe this is correct, since our exported components should not have any side effects; our UI component package is in a monorepo, it exports only TypeScript components that have not been transpiled, and our Storybook's preview.ts
isn't part of our package's API surface.
"sideEffects": false
, I still don't get any styles when importing "tailwindcss/tailwind.css"
."sideEffects": false
and instead import "../src/tailwind.css"
, I do start to get styles.
I will also provide our monorepo root Babel config, as it may now be relevant:
babel.config.json
{
"presets": [
"@babel/preset-env",
"@babel/preset-react",
"@babel/preset-typescript"
]
}
We use this primarily to configure the repository's ESLint Babel parser so we can lint modern syntax, however our Storybook uses it as well. I would expect our use of "@babel/preset-env"
to disable Webpack tree shaking, per their documentation.
@aaronadamsCA I've been trying to dig into this a bit more and it looks like when you set sideEffects
, Webpack will treeshake css imports out because it decides that the import isn't used.
To resolve this, we have two options. You can include your css files in sideEffects
like this:
{
sideEffects: [
'**/*.css',
],
}
or, I can try out setting the css webpack rule to consider all css files as side effects. However, I'll need some help from folks like you having the issue to help me test before I publish a change for that
I think it might be a better idea to first figure out why import "tailwindcss/tailwind.css"
doesn't work. I just tried it again to be sure, and the result is still no Storybook styles at all, regardless of the value (or absence) of sideEffects
.
@aaronadamsCA and @dariusrosendahl are you able to share a small reproduction with me to help nail this down?
@Integrayshaun Here you go!
https://github.com/aaronadamsCA/storybookjs-addon-styling-issue-28
This works fine when importing the local tailwind.css
, but not when importing "tailwindcss/tailwind.css"
.
Same problem with NextJS. Just installed a fresh install of Storybook 7 to create a component library, but it seems none of the tailwind classes are compiled and used.
Might be handy to know: When I change the extension of the style file to pcss instead of css, I get following error:
Module parse failed: Unexpected character '@' (1:0)
Which is the line where tailwind is importing @tailwind base;
To resolve this, we have two options. You can include your css files in
sideEffects
like this:{ sideEffects: [ '**/*.css', ], }
Thanks @Integrayshaun, this works for me as a workaround.
Thank you so much @Integrayshaun ,sideEffects
was the answer here too!:
"sideEffects": [
"./styles/globals.css"
]
Storybook 7.0.x + Tailwind 3.3.x working when this is enabled.
That's great news @dariusrosendahl and @felixmokross!!! I'll update the webpack rules to consider CSS files side effects so that you don't need to declare them like this.
@aaronadamsCA Thank you for putting that together :) I'll have a look at this today
Hey @aaronadamsCA 👋
It looks like it has something to do with how pnpm is optimizing your dependencies 🤔 when I switched over to using yarn it worked no problem.
I'll have to look into what we can do to make this work properly for pnpm as well
It looks like it has something to do with how pnpm is optimizing your dependencies 🤔 when I switched over to using yarn it worked no problem.
@Integrayshaun Very interesting, thank you. This led me to wonder if the problem might be in @storybook/react-webpack5
, but when I remove this plugin, external CSS imports work fine:
https://github.com/aaronadamsCA/storybookjs-addon-styling-issue-28/compare/main...no-styling-plugin
In the meantime at least there's a good workaround by just using a local CSS file. I'd try to help further but I'm in over my head as is.
It looks like it has something to do with how pnpm is optimizing your dependencies
hi @Integrayshaun
I have the same issue but with Lerna. After migrating from Storybook v6 to v7 and implementing all the stuff needed, only the styling is broken. A "tailwind" css file loaded from a different package in our mono repo is being ignored (sideEffects
did not help). When copypasted the file into the package where Storybook is, and loading it locally works fine (Except for "rebuilding" message in a terminal which goes crazy and never settles down - probably a infinite hot-reload? But not sure why. )
// preview.ts
// does not work - no styles at all
import '@our-monorepo/tailwind/style.css';
// works - I can see the styles
import '../local-copy-of-style.css';
// main.ts (other config files are similar to Aaron's mentioned in the initial post
import type { StorybookConfig } from '@storybook/react-webpack5';
const config: StorybookConfig = {
staticDirs: ['../src'],
stories: ['../src/**/*.stories.mdx', '../src/**/*.stories.@(js|jsx|ts|tsx)'],
addons: [
'@storybook/addon-links',
'@storybook/addon-essentials',
{
name: '@storybook/addon-styling',
options: {
postCss: true,
},
},
'@storybook/addon-mdx-gfm',
],
framework: {
name: '@storybook/react-webpack5',
options: {},
},
docs: {
autodocs: true,
},
};
export default config;
When copypasted the file into the package where Storybook is, and loading it locally works fine
Thanks, this worked for me in Turborepo and @storybook/nextjs
I still have this problem, no options mentioned here seems to work. I also tried the official set-up guides with all possible combinations and configurations. Does anyone have an idea?
Main.ts:
import type { StorybookConfig } from '@storybook/nextjs';
import path from 'path';
const TsconfigPathsPlugin = require('tsconfig-paths-webpack-plugin');
const config: StorybookConfig = {
stories: [
'../stories/**/*.mdx',
'../(stories|components)/**/*.stories.@(js|jsx|ts|tsx)'
],
addons: [
'@storybook/addon-links',
'@storybook/addon-essentials',
'@storybook/addon-interactions',
// '@storybook/addon-styling',
{
name: '@storybook/addon-styling',
options: {
postCss: {
implementation: require('postcss')
}
}
}
],
framework: {
name: '@storybook/nextjs',
options: {}
},
docs: {
autodocs: 'tag'
},
staticDirs: ['../public'],
webpackFinal: (config) => {
/**
* Add support for alias-imports
* @see https://github.com/storybookjs/storybook/issues/11989#issuecomment-715524391
*/
config.resolve!.alias = {
...config.resolve?.alias,
'@': [path.resolve(__dirname, '../src/'), path.resolve(__dirname, '../')]
};
/**
* Fixes font import with /
* @see https://github.com/storybookjs/storybook/issues/12844#issuecomment-867544160
*/
config.resolve!.roots = [
path.resolve(__dirname, '../public'),
'node_modules'
];
config.module!.rules!.push({
test: /\.scss$/,
use: ['style-loader', 'css-loader', 'postcss-loader', 'sass-loader']
});
config.module!.rules!.push({
test: /\.css$/,
use: [
{
loader: 'postcss-loader',
options: {
postcssOptions: {
plugins: [require('tailwindcss'), require('autoprefixer')]
}
}
}
],
include: path.resolve(__dirname, '../')
});
config.resolve!.plugins = [
...(config.resolve!.plugins || []),
new TsconfigPathsPlugin({
extensions: config.resolve!.extensions
})
];
return config;
}
};
export default config;
preview.tsx:
import React from 'react';
import type { Preview } from '@storybook/react';
import '../styles/main.css';
import { ThemeProvider } from '@mui/material';
import { lightTheme } from '../utils/theme';
import * as nextImage from 'next/image';
Object.defineProperty(nextImage, 'default', {
configurable: true,
value: (props) => <img {...props} />
});
const preview: Preview = {
decorators: [
(story: any) => <ThemeProvider theme={lightTheme}>{story()}</ThemeProvider>
],
parameters: {
actions: { argTypesRegex: '^on.*' },
controls: {
matchers: {
color: /(background|color)$/i,
date: /Date$/
}
}
}
};
export default preview;
tailwind.config.js:
const colors = require('tailwindcss/colors');
/** @type {import('tailwindcss').Config} */
module.exports = {
mode: 'all',
content: [
'./pages/**/*.{js,ts,jsx,tsx}',
'./components/**/*.{js,ts,jsx,tsx}',
'./views/**/*.{js,ts,jsx,tsx}',
'./hooks/**/*.{js,ts,jsx,tsx}'
],
important: '#__next',
theme: {
extend: {
colors: {
primary: {
lightest: '#82D4E9',
light: '#51C5E1',
DEFAULT: '#00b6da',
dark: '#009bbe'
},
secondary: {
lightest: colors.gray[100],
light: colors.gray[200],
DEFAULT: colors.gray[800],
dark: colors.gray[900]
},
success: {
lightest: colors.green[100],
light: colors.green[200],
DEFAULT: colors.green[800],
dark: colors.green[900]
},
warning: {
lightest: colors.yellow[100],
light: colors.yellow[200],
DEFAULT: colors.yellow[800],
dark: colors.yellow[900]
},
waiting: {
lightest: colors.purple[100],
light: colors.purple[200],
DEFAULT: colors.purple[800],
dark: colors.purple[900]
},
info: {
lightest: colors.blue[100],
light: colors.blue[200],
DEFAULT: colors.blue[800],
dark: colors.blue[900]
},
error: {
lightest: colors.red[100],
light: colors.red[200],
DEFAULT: colors.red[800],
dark: colors.red[900]
},
'routty-blue': {
lightest: '#82D4E9',
light: '#51C5E1',
DEFAULT: '#00b6da'
},
'routty-grey': {
light: '#f5f5f5',
dark: '#323537'
}
},
backgroundImage: {
routty: "url('/images/onboarding/onboarding-background.svg')"
},
backgroundSize: { 'size-70': '70%' },
ringColor: '#00b6da',
keyframes: {
slideUpAndFade: {
from: { opacity: 0, transform: 'translateY(2px)' },
to: { opacity: 1, transform: 'translateY(0)' }
},
slideRightAndFade: {
from: { opacity: 0, transform: 'translateX(-2px)' },
to: { opacity: 1, transform: 'translateX(0)' }
},
slideDownAndFade: {
from: { opacity: 0, transform: 'translateY(-2px)' },
to: { opacity: 1, transform: 'translateY(0)' }
},
slideLeftAndFade: {
from: { opacity: 0, transform: 'translateX(2px)' },
to: { opacity: 1, transform: 'translateX(0)' }
}
},
animation: {
slideUpAndFade: 'slideUpAndFade 400ms cubic-bezier(0.16, 1, 0.3, 1)',
slideRightAndFade:
'slideRightAndFade 400ms cubic-bezier(0.16, 1, 0.3, 1)',
slideDownAndFade:
'slideDownAndFade 400ms cubic-bezier(0.16, 1, 0.3, 1)',
slideLeftAndFade: 'slideLeftAndFade 400ms cubic-bezier(0.16, 1, 0.3, 1)'
}
}
},
plugins: [],
safelist: [
{
pattern:
/(bg|border|text)-(primary|secondary|success|warning|waiting|info|error)*/
}
]
};
Story:
import { Badge } from '@components/badge';
import type { Meta, StoryObj } from '@storybook/react';
const meta: Meta<typeof Badge> = {
title: 'Components/Badge',
component: Badge,
tags: ['autodocs'],
parameters: {
actions: false
},
argTypes: {
color: {
control: 'select',
options: [
'primary',
'secondary',
'error',
'warning',
'info',
'success',
'waiting'
]
}
}
};
export default meta;
type Story = StoryObj<typeof Badge>;
export const Primary: Story = {
args: {
text: 'Status'
}
};
package.json:
{
"name": "rex-fe",
"version": "0.1.0",
"private": true,
"sideEffects": ["**/*.css"],
...
}
Hey @oliviervanbulck 👋
@storybook/nextjs
configures postcss and scss for you so when you try to configure them with addon-styling you're doubling up and breaking it. You're also adding more rules to process css and scss files a third time in your webpackFinal function.
If you pull those out, you should be up and running.
import type { StorybookConfig } from '@storybook/nextjs';
import path from 'path';
const TsconfigPathsPlugin = require('tsconfig-paths-webpack-plugin');
const config: StorybookConfig = {
stories: [
'../stories/**/*.mdx',
'../(stories|components)/**/*.stories.@(js|jsx|ts|tsx)'
],
addons: [
'@storybook/addon-links',
'@storybook/addon-essentials',
'@storybook/addon-interactions',
'@storybook/addon-styling', // Leave this in for theme switching feature
],
framework: {
name: '@storybook/nextjs',
options: {}
},
docs: {
autodocs: 'tag'
},
staticDirs: ['../public'],
webpackFinal: (config) => {
/**
* Add support for alias-imports
* @see https://github.com/storybookjs/storybook/issues/11989#issuecomment-715524391
*/
config.resolve!.alias = {
...config.resolve?.alias,
'@': [path.resolve(__dirname, '../src/'), path.resolve(__dirname, '../')]
};
/**
* Fixes font import with /
* @see https://github.com/storybookjs/storybook/issues/12844#issuecomment-867544160
*/
config.resolve!.roots = [
path.resolve(__dirname, '../public'),
'node_modules'
];
config.resolve!.plugins = [
...(config.resolve!.plugins || []),
new TsconfigPathsPlugin({
extensions: config.resolve!.extensions
})
];
return config;
}
};
export default config;
Closing for inactivity. If this is still an issue, we can reopen the issue to triage again
Describe the bug
I am trying to implement Storybook 7 + PostCSS + Tailwind, but I am not getting any styles at all in our Storybook.
Steps to reproduce the behavior
postcss.config.cjs
tailwind.config.cjs
If I change the
content
field to point to the wrong location, I see a warning from this addon when I runstorybook dev
, so it seems the configs are being read normally.main.ts
A simple
postCss: true
doesn't work either.preview.ts
Importing my local
"../src/tailwind.css"
doesn't work either.Expected behavior
Styles!
Screenshots and/or logs
Environment