Skip to content

Commit

Permalink
Merge pull request #23149 from storybookjs/chaks/vue2-source-snippet-…
Browse files Browse the repository at this point in the history
…reactivity

Vue2: Source Decorator reactivity
  • Loading branch information
kasperpeulen committed Jul 24, 2023
2 parents 950df76 + f6b3735 commit ba646e8
Showing 1 changed file with 28 additions and 27 deletions.
55 changes: 28 additions & 27 deletions code/renderers/vue/src/docs/sourceDecorator.ts
Expand Up @@ -4,7 +4,7 @@
import { addons } from '@storybook/preview-api';
import { logger } from '@storybook/client-logger';
import { SourceType, SNIPPET_RENDERED } from '@storybook/docs-tools';
import type { ComponentOptions } from 'vue';
import { type ComponentOptions } from 'vue';
import type Vue from 'vue';
import type { StoryContext } from '../types';

Expand All @@ -24,46 +24,47 @@ export const skipSourceRender = (context: StoryContext) => {

export const sourceDecorator = (storyFn: any, context: StoryContext) => {
const story = storyFn();
const source = '';

// See ../react/jsxDecorator.tsx
if (skipSourceRender(context)) {
const skip = skipSourceRender(context);
if (skip) {
return story;
}

const channel = addons.getChannel();

const storyComponent = getStoryComponent(story.options.STORYBOOK_WRAPS);
const generateSource = (vueInstance: any) => {
try {
// console.log('updateSource():', vueInstance.$vnode);
const storyNode = lookupStoryInstance(vueInstance, storyComponent);
if (!storyNode) {
logger.warn(`Failed to find story component in the rendered tree: ${storyComponent}`);
return;
}
// eslint-disable-next-line no-param-reassign
vueInstance.source = vnodeToString(storyNode._vnode);
} catch (e) {
logger.warn(`Failed to generate dynamic story source: ${e}`);
}
};

return {
components: {
Story: story,
},
// We need to wait until the wrapper component to be mounted so Vue runtime
// struct VNode tree. We get `this._vnode == null` if switch to `created`
// lifecycle hook.
data() {
return { source };
},
updated() {
generateSource(this);
},
mounted() {
// Theoretically this does not happens but we need to check it.
// @ts-expect-error TS says it is called $vnode
if (!this._vnode) {
return;
}

try {
const storyNode = lookupStoryInstance(this, storyComponent);

// @ts-expect-error TS says it is called $vnode
const code = vnodeToString(storyNode._vnode);

const { id, unmappedArgs } = context;
channel.emit(SNIPPET_RENDERED, {
id,
args: unmappedArgs,
source: `<template>${code}</template>`,
format: 'vue',
});
} catch (e) {
logger.warn(`Failed to generate dynamic story source: ${e}`);
}
this.$watch('source', (val) =>
channel.emit(SNIPPET_RENDERED, context.id, `<template>${val}</template>`, 'vue')
);
generateSource(this);
},
template: '<story />',
} as ComponentOptions<Vue> & ThisType<Vue>;
Expand Down

0 comments on commit ba646e8

Please sign in to comment.