UNPKG

@storybook/addon-actions

Version:

Get UI feedback when an action is performed on an interactive element

11 lines (7 loc) 4.03 kB
'use strict'; var previewApi = require('storybook/internal/preview-api'); var global = require('@storybook/global'); var previewErrors = require('storybook/internal/preview-errors'); var uuid = require('uuid'); var PARAM_KEY="actions",ADDON_ID="storybook/actions",EVENT_ID=`${ADDON_ID}/action-event`;var config={depth:10,clearOnStoryChange:!0,limit:50};var findProto=(obj,callback)=>{let proto=Object.getPrototypeOf(obj);return !proto||callback(proto)?proto:findProto(proto,callback)},isReactSyntheticEvent=e=>!!(typeof e=="object"&&e&&findProto(e,proto=>/^Synthetic(?:Base)?Event$/.test(proto.constructor.name))&&typeof e.persist=="function"),serializeArg=a=>{if(isReactSyntheticEvent(a)){let e=Object.create(a.constructor.prototype,Object.getOwnPropertyDescriptors(a));e.persist();let viewDescriptor=Object.getOwnPropertyDescriptor(e,"view"),view=viewDescriptor?.value;return typeof view=="object"&&view?.constructor.name==="Window"&&Object.defineProperty(e,"view",{...viewDescriptor,value:Object.create(view.constructor.prototype)}),e}return a},generateId=()=>typeof crypto=="object"&&typeof crypto.getRandomValues=="function"?uuid.v4():Date.now().toString(36)+Math.random().toString(36).substring(2);function action(name,options={}){let actionOptions={...config,...options},handler=function(...args){if(options.implicit){let storyRenderer=("__STORYBOOK_PREVIEW__"in global.global?global.global.__STORYBOOK_PREVIEW__:void 0)?.storyRenders.find(render=>render.phase==="playing"||render.phase==="rendering");if(storyRenderer){let deprecated=!window?.FEATURES?.disallowImplicitActionsInRenderV8,error=new previewErrors.ImplicitActionsDuringRendering({phase:storyRenderer.phase,name,deprecated});if(deprecated)console.warn(error);else throw error}}let channel=previewApi.addons.getChannel(),id=generateId(),minDepth=5,serializedArgs=args.map(serializeArg),normalizedArgs=args.length>1?serializedArgs:serializedArgs[0],actionDisplayToEmit={id,count:0,data:{name,args:normalizedArgs},options:{...actionOptions,maxDepth:minDepth+(actionOptions.depth||3),allowFunction:actionOptions.allowFunction||!1}};channel.emit(EVENT_ID,actionDisplayToEmit);};return handler.isAction=!0,handler.implicit=options.implicit,handler}var actions=(...args)=>{let options=config,names=args;names.length===1&&Array.isArray(names[0])&&([names]=names),names.length!==1&&typeof names[names.length-1]!="string"&&(options={...config,...names.pop()});let namesObject=names[0];(names.length!==1||typeof namesObject=="string")&&(namesObject={},names.forEach(name=>{namesObject[name]=name;}));let actionsObject={};return Object.keys(namesObject).forEach(name=>{actionsObject[name]=action(namesObject[name],options);}),actionsObject};var {document,Element}=global.global,delegateEventSplitter=/^(\S+)\s*(.*)$/,isIE=Element!=null&&!Element.prototype.matches,matchesMethod=isIE?"msMatchesSelector":"matches",hasMatchInAncestry=(element,selector)=>{if(element[matchesMethod](selector))return !0;let parent=element.parentElement;return parent?hasMatchInAncestry(parent,selector):!1},createHandlers=(actionsFn,...handles)=>{let actionsObject=actionsFn(...handles);return Object.entries(actionsObject).map(([key,action2])=>{let[_,eventName,selector]=key.match(delegateEventSplitter)||[];return {eventName,handler:e=>{(!selector||hasMatchInAncestry(e.target,selector))&&action2(e);}}})},applyEventHandlers=(actionsFn,...handles)=>{let root=document&&document.getElementById("storybook-root");previewApi.useEffect(()=>{if(root!=null){let handlers=createHandlers(actionsFn,...handles);return handlers.forEach(({eventName,handler})=>root.addEventListener(eventName,handler)),()=>handlers.forEach(({eventName,handler})=>root.removeEventListener(eventName,handler))}},[root,actionsFn,handles]);},withActions=previewApi.makeDecorator({name:"withActions",parameterName:PARAM_KEY,skipIfNoParametersOrOptions:!0,wrapper:(getStory,context,{parameters})=>(parameters?.handles&&applyEventHandlers(actions,...parameters.handles),getStory(context))}); exports.withActions = withActions;