The setup for storybook is the same as their docs. Once you're repo is set up (Im using Typescript) and you have Stitches imported and set up (as per the stitches docs), the next step is to install Storybook.
I went with their npx setup: npx sb init
(note: since my project was already set up with React/TS this command detected everything it needed to know, so there was no interactive prompt for me)
When using a styled
stitches component everything will work as expected:
export const Button = styled('button', {
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
})
However, when you try to render a styled
component inside of a parent wrapper, you will run into a problem:
const DEFAULT_TAG = 'button'
const StyledButton = styled(DEFAULT_TAG, {
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
})
type ButtonCSSProp = { css?: CSS };
type ButtonVariants = StitchesVariants<typeof StyledButton>;
type ButtonOwnProps = ButtonCSSProp & ButtonVariants;
type ButtonComponent = Polymorphic.ForwardRefComponent<typeof DEFAULT_TAG, ButtonOwnProps>;
export const Button = forwardRef(function Button(props, forwardedRef) {
// This line will throw a TS error, something like 'prop css is incompatible...'
return <StyledButton role="button" {...props} ref={forwardedRef} />;
}) as ButtonComponent;
The reason we have a type error is that we are taking all props
from Button
and spreading them into StyledButton
. Normally this is fine, however Storybook uses Emotion v10+
as of this writing, and part of the setup for this version creates a global css prop typedef so that components can support Emotions css
prop (note: Emotion v11+
resolved this issue). Emotions global css
typedef clashes with the Stitches css
typedef, thus we get the error.
First we create an EMPTY .d.ts
file which will act as our Emotion typedef reset. The name/location of the file is irrelevant. I chose to put mine as follows:
/packages
/types
emotion.d.ts <----
tsconfig.json
Second, we point the @emotion/core
types to our empty file in tsconfig.json
. SB is setup to read from our tsconfig.json
if we have one, and when it does the empty .d.ts
map un-sets the typedefs for Emotion within the context of our app/lib. SB is not effected by this.
// tsconfig.json
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
// Emotion typedefs now point to an empty file, which unsets all declarations
"@emotion/core": ["./types/emotion.d.ts"],
},
}
}
Aaaand we're done. The TS error should go away.
- You might have to restart your IDE TS process, as well as your local SB server
- If/When SB upgrades to Emotion
v11+
thecss
prop clash will go away since Emotion 11 doesn't do global typedefs anymore. Aka, at some point in the future, this guide will be pointless 😁.