fbredius/storybook

View on GitHub
addons/interactions/src/preset/argsEnhancers.ts

Summary

Maintainability
A
0 mins
Test Coverage
import { addons } from '@storybook/addons';
import type { Args } from '@storybook/addons';
import { window as globalWindow } from 'global';
import { FORCE_REMOUNT, STORY_RENDER_PHASE_CHANGED } from '@storybook/core-events';
import { AnyFramework, ArgsEnhancer } from '@storybook/csf';
import { instrument } from '@storybook/instrumenter';
import { ModuleMocker } from 'jest-mock';

const JestMock = new ModuleMocker(globalWindow);
const fn = JestMock.fn.bind(JestMock);

// Aliasing `fn` to `action` here, so we get a more descriptive label in the UI.
const { action } = instrument({ action: fn }, { retain: true });
const channel = addons.getChannel();
const spies: any[] = [];

channel.on(FORCE_REMOUNT, () => spies.forEach((mock) => mock?.mockClear?.()));
channel.on(STORY_RENDER_PHASE_CHANGED, ({ newPhase }) => {
  if (newPhase === 'loading') spies.forEach((mock) => mock?.mockClear?.());
});

const addActionsFromArgTypes: ArgsEnhancer<AnyFramework> = ({ id, initialArgs }) => {
  return Object.entries(initialArgs).reduce((acc, [key, val]) => {
    if (typeof val === 'function' && val.name === 'actionHandler') {
      Object.defineProperty(val, 'name', { value: key, writable: false });
      Object.defineProperty(val, '__storyId__', { value: id, writable: false });
      acc[key] = action(val);
      spies.push(acc[key]);
      return acc;
    }
    acc[key] = val;
    return acc;
  }, {} as Args);
};

export const argsEnhancers = [addActionsFromArgTypes];