UNPKG

4.03 kBJavaScriptView Raw
1import { dedent } from 'ts-dedent';
2import Vue from 'vue';
3import { sanitizeStoryContextUpdate } from '@storybook/preview-api';
4
5var COMPONENT="STORYBOOK_COMPONENT",VALUES="STORYBOOK_VALUES",map=new Map,getRoot=canvasElement=>{let cachedInstance=map.get(canvasElement);if(cachedInstance!=null)return cachedInstance;let target=document.createElement("div");canvasElement.appendChild(target);let instance=new Vue({beforeDestroy(){map.delete(canvasElement);},data(){return {[COMPONENT]:void 0,[VALUES]:{}}},render(h){return map.set(canvasElement,instance),this[COMPONENT]?[h(this[COMPONENT])]:void 0}});return instance},render=(args,context)=>{let{id,component:Component,argTypes}=context,component=Component;if(!component)throw new Error(`Unable to render story ${id} as the component annotation is missing from the default export`);let componentName="component";component.name?componentName=Vue.config.isReservedTag&&Vue.config.isReservedTag(component.name)?`sb-${component.name}`:component.name:component.__docgenInfo?.displayName&&(componentName=component.__docgenInfo?.displayName);let eventsBinding="",eventProps=Object.values(argTypes).filter(argType=>argType?.table?.category==="events").map(argType=>argType.name),camelCase=str=>str.replace(/-([a-z])/g,g=>g[1].toUpperCase());return eventProps.length&&(eventsBinding=eventProps.map(name=>`@${name}="$props['${camelCase(name)}']"`).join(" ")),{props:Object.keys(argTypes),components:{[componentName]:component},template:`<${componentName} ${eventsBinding} v-bind="filterOutEventProps($props)" />`,methods:{filterOutEventProps(props){return Object.fromEntries(Object.entries(props).filter(([key])=>!eventProps.includes(key)))}}}};function renderToCanvas({title,name,storyFn,showMain,showError,showException,forceRemount},canvasElement){let root=getRoot(canvasElement);Vue.config.errorHandler=showException;let element=storyFn(),mountTarget;if(canvasElement.hasChildNodes()?mountTarget=canvasElement.firstElementChild:(mountTarget=document.createElement("div"),canvasElement.appendChild(mountTarget)),!element){showError({title:`Expecting a Vue component from the story: "${name}" of "${title}".`,description:dedent`
6 Did you forget to return the Vue component from the story?
7 Use "() => ({ template: '<my-comp></my-comp>' })" or "() => ({ components: MyComp, template: '<my-comp></my-comp>' })" when defining the story.
8 `});return}(!root[COMPONENT]||forceRemount)&&(root[COMPONENT]=element),root[VALUES]={...element.options[VALUES]},map.has(canvasElement)||root.$mount(mountTarget??void 0),showMain();}function getType(fn){let match=fn&&fn.toString().match(/^\s*function (\w+)/);return match?match[1]:""}function resolveDefault({type,default:def}){return typeof def=="function"&&getType(type)!=="Function"?def.call():def}function extractProps(component){return Object.entries(component.options.props||{}).map(([name,prop])=>({[name]:resolveDefault(prop)})).reduce((wrap,prop)=>({...wrap,...prop}),{})}var WRAPS="STORYBOOK_WRAPS";function prepare(rawStory,innerStory,context){let story;if(typeof rawStory=="string")story={template:rawStory};else if(rawStory!=null)story=rawStory;else return null;if(!story._isVue)innerStory&&(story.components={...story.components||{},story:innerStory}),story=Vue.extend(story);else if(story.options[WRAPS])return story;return Vue.extend({[WRAPS]:story,[VALUES]:{...innerStory?innerStory.options[VALUES]:{},...extractProps(story),...context?.args||{}},functional:!0,render(h,{data,parent,children}){return h(story,{...data,props:{...data.props||{},...parent.$root[VALUES]}},children)}})}function decorateStory(storyFn,decorators){return decorators.reduce((decorated,decorator)=>context=>{let story,decoratedStory=decorator(update=>(story=decorated({...context,...sanitizeStoryContextUpdate(update)}),story),context);return story||(story=decorated(context)),decoratedStory===story?story:prepare(decoratedStory,story)},context=>prepare(storyFn(context),void 0,context))}
9
10export { decorateStory, render, renderToCanvas };