I have a very simple and plain ComponentX that renders some styled HTML, no data fetching or even routing needed. It has a single, simple story. ComponentX is meant to be used in a dark-themed website, so it assumes that it will inherit color: white;
and other such styles. This is crucial to rendering ComponentX correctly. I won't bore you with the code for ComponentX.
Those contextual styles, such as background-color: black;
and color: white;
, are applied to the <body>
by the GlobalStyles
component. GlobalStyles
uses the css-in-js library Emotion
to apply styles to the document.
import { Global } from '@emotion/react';
export const GlobalStyles = () => (
<>
<Global styles={{ body: { backgroundColor: 'black' } }} />
<Outlet />
</>
);
As you can see, this component does not accept children, but rather is meant to be used as a layout route, so it renders an <Outlet />
. I expect the application to render a Route tree like the below, using a layout route indicated by the (1)
<Router>
<Routes>
<Route element={<GlobalStyles/>} > <== (1)
<Route path="login">
<Route index element={<Login />} />
<Route path="multifactor" element={<Mfa />} />
</Route>
Not pictured: the <Login>
and <Mfa>
pages call ComponentX.
And this works!
The problem is with the Stories. If I render a plain story with ComponentX, it will be hard to see because it expects all of those styles on <body>
to be present. The obvious solution is to create a decorator that wraps each story with this <Route element={<GlobalStyles/>} >
. How can this be accomplished? Here's my working-but-not-as-intended component-x.stories.tsx:
import React from 'react';
import ComponentX from './ComponentX';
export default {
component: ComponentX,
title: 'Component X',
};
const Template = args => <ComponentX {...args} />;
export const Default = Template.bind({});
Default.args = {};
Default.decorators = [
(story) => <div style={{ padding: '3rem' }}>{story()}</div>
];
(I realize that I can make <GlobalStyles>
a simple wrapper component around the entire <Router>
, but I want to use this pattern to create stories for other components that assume other, intermediate layout routes.)