Skip to content

Instantly share code, notes, and snippets.

@sseagull
Last active May 17, 2023 11:40
Show Gist options
  • Save sseagull/e2e7fe58f7f236897d342e776bb549a2 to your computer and use it in GitHub Desktop.
Save sseagull/e2e7fe58f7f236897d342e776bb549a2 to your computer and use it in GitHub Desktop.
Stitches + Storybook `css` prop type definition clash fix

Using Stitches with Storybook

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.

Steps to fix

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.

Notes

  • You might have to restart your IDE TS process, as well as your local SB server
  • If/When SB upgrades to Emotion v11+ the css 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 😁.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment