Documentation
Fixture Modules

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.

Button.fixture.jsx
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.

CounterButton.fixture.jsx
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.

Button.fixture.jsx
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.

CounterButton.fixture.jsx
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:

  1. Use ESLint overrides to disable this rule inside Cosmos fixtures. Here is an example. (opens in a new tab)
  2. Name your component functions, like this: 'my fixture': function MyFixture() {.
  3. Create regular component functions and attach them to the default fixture export (see below).
CounterButton.fixture.jsx
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.

Button.fixture.jsx
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.