UNPKG

@storybook/addon-actions

Version:
50 lines (44 loc) 1.6 kB
/* eslint-disable no-underscore-dangle */ import addons from '@storybook/addons'; import stringify from 'json-stringify-safe'; import uuid from 'uuid/v1'; import { EVENT_ID } from './'; function _format(arg) { if (arg && typeof arg.preventDefault !== 'undefined') { return stringify('[SyntheticEvent]'); } return stringify(arg); } export function action(name) { // eslint-disable-next-line no-unused-vars, func-names const handler = function(..._args) { const args = Array.from(_args).map(_format); const channel = addons.getChannel(); const id = uuid(); channel.emit(EVENT_ID, { id, data: { name, args }, }); }; // some day when {[name]: function() {}} syntax is not transpiled by babel // we can get rid of this eval as by ES2015 spec the above function gets the // name `name`, but babel transpiles to Object.defineProperty which doesn't do // the same. // // Ref: https://bocoup.com/weblog/whats-in-a-function-name const fnName = name && typeof name === 'string' ? name.replace(/\W+/g, '_') : 'action'; // eslint-disable-next-line no-eval const named = eval(`(function ${fnName}() { return handler.apply(this, arguments) })`); return named; } export function decorateAction(decorators) { // eslint-disable-next-line no-unused-vars, func-names return function(name) { const callAction = action(name); // eslint-disable-next-line no-unused-vars, func-names return function(..._args) { const decorated = decorators.reduce((args, fn) => fn(args), _args); callAction(...decorated); }; }; }