Fixture Modules
A fixture is a React Component or any React Node. A fixture module contains one or more fixtures.
Node Fixtures
Think of Node fixtures as the return value of a function component, or the
first argument to React.render
.
export default <Button disabled>Click me</Button>;
Component Fixtures
Component fixtures are just React function components with no props. They enable using Hooks inside fixtures, which is powerful for simulating state with stateless components.
export default () => {
const [count, setCount] = useState(0);
return <CounterButton count={count} increment={() => setCount(count + 1)} />;
};
Multi-Fixtures
A fixture module can also export multiple fixtures if the default export is an object. The object's property names will show up as fixture names in the Cosmos UI.
export default {
'Primary': <PrimaryButton>Click me</PrimaryButton>,
'Primary Disabled': <PrimaryButton disabled>Click me</PrimaryButton>,
'Secondary': <SecondaryButton>Click me</SecondaryButton>,
'Secondary Disabled': <SecondaryButton disabled>Click me</SecondaryButton>,
};
Component Multi-Fixtures
Multi-Fixtures can also contain components.
export default {
'Counter x1': () => {
const [count, setCount] = useState(0);
return (
<CounterButton count={count} increment={() => setCount(count + 1)} />
);
},
'Counter x2': () => {
const [count, setCount] = useState(0);
return (
<CounterButton count={count} increment={() => setCount(count + 2)} />
);
},
};
Using arrow functions in Multi-Fixtures will cause eslint-plugin-react-hooks (opens in a new tab) to complain about using hooks inside unnamed components. To avoid having to suppress these warnings in every fixture you can do one of the following:
- Use ESLint
overrides
to disable this rule inside Cosmos fixtures. Here is an example. (opens in a new tab) - Name your component functions, like this:
'my fixture': function MyFixture() {
. - Create regular component functions and attach them to the default fixture export (see below).
function CounterX1() {
const [count, setCount] = useState(0);
return <CounterButton count={count} increment={() => setCount(count + 1)} />;
}
function CounterX2() {
const [count, setCount] = useState(0);
return <CounterButton count={count} increment={() => setCount(count + 2)} />;
}
export default { CounterX1, CounterX2 };
Dynamic Multi-Fixtures
Multi-Fixtures can be created dynamically. This is useful for generating fixtures from data.
const fixtures = {};
for (let color of ['red', 'green', 'blue']) {
fixtures[color] = <Button color={color}>Click me</Button>;
}
export default fixtures;
MDX Fixtures
Creating MDX fixtures is as easy as configuring MDX for your bundler (opens in a new tab) and using the .mdx
(or .md
) file extension for your fixture files.
Both Vite and Webpack
examples (opens in a new tab)
feature MDX fixtures configured with @mdx-js/rollup
and @mdx-js/loader
respectively.