From e5639091bee4965d19458169efccfe825275e94e Mon Sep 17 00:00:00 2001 From: Kasper Peulen Date: Mon, 22 May 2023 15:53:50 +0200 Subject: [PATCH 1/2] Patch back tests to main --- ...CustomRenderFunctionalComponent.stories.ts | 32 +++++++ ...CustomRenderOptionsArgsFromData.stories.ts | 45 ++++++++++ .../ReactiveDecorators.stories.ts | 88 +++++++++++++++++++ .../Reactivity.vue | 44 ++++++++++ 4 files changed, 209 insertions(+) create mode 100644 code/renderers/vue3/template/stories_vue3-vite-default-ts/CustomRenderFunctionalComponent.stories.ts create mode 100644 code/renderers/vue3/template/stories_vue3-vite-default-ts/CustomRenderOptionsArgsFromData.stories.ts create mode 100644 code/renderers/vue3/template/stories_vue3-vite-default-ts/ReactiveDecorators.stories.ts create mode 100644 code/renderers/vue3/template/stories_vue3-vite-default-ts/Reactivity.vue diff --git a/code/renderers/vue3/template/stories_vue3-vite-default-ts/CustomRenderFunctionalComponent.stories.ts b/code/renderers/vue3/template/stories_vue3-vite-default-ts/CustomRenderFunctionalComponent.stories.ts new file mode 100644 index 000000000000..bf70bc34f074 --- /dev/null +++ b/code/renderers/vue3/template/stories_vue3-vite-default-ts/CustomRenderFunctionalComponent.stories.ts @@ -0,0 +1,32 @@ +import type { Meta } from '@storybook/vue3'; +import { h } from 'vue'; +import Reactivity from './Reactivity.vue'; +import * as ReactiveDecorators from './ReactiveDecorators.stories'; + +const meta = { + ...ReactiveDecorators.default, + component: Reactivity, + // storybook render function is not a functional component. it returns a functional component or a component options + render: (args) => { + // create the slot contents as a functional components + const header = ({ title }: { title: string }) => h('h3', `${args.header} - Title: ${title}`); + const defaultSlot = () => h('p', `${args.default}`); + const footer = () => h('p', `${args.footer}`); + // vue render function is a functional components + return () => + h('div', [ + `Custom render uses a functional component, and passes slots to the component:`, + h(Reactivity, args, { header, default: defaultSlot, footer }), + ]); + }, +} satisfies Meta; + +export default meta; + +export { + NoDecorators, + DecoratorFunctionalComponent, + DecoratorFunctionalComponentArgsFromContext, + DecoratorComponentOptions, + DecoratorComponentOptionsArgsFromData, +} from './ReactiveDecorators.stories'; diff --git a/code/renderers/vue3/template/stories_vue3-vite-default-ts/CustomRenderOptionsArgsFromData.stories.ts b/code/renderers/vue3/template/stories_vue3-vite-default-ts/CustomRenderOptionsArgsFromData.stories.ts new file mode 100644 index 000000000000..9c904283d3bd --- /dev/null +++ b/code/renderers/vue3/template/stories_vue3-vite-default-ts/CustomRenderOptionsArgsFromData.stories.ts @@ -0,0 +1,45 @@ +import type { Meta } from '@storybook/vue3'; +import { defineComponent, shallowReactive } from 'vue'; +import Reactivity from './Reactivity.vue'; +import * as ReactiveDecorators from './ReactiveDecorators.stories'; + +// when you use custom render, you can use any vue api to create your story and garanti reactivity, otherwise i can ease kill the reactivity. +const state = shallowReactive<{ header: any; default: any; footer: any }>({ + header: '', + default: '', + footer: '', +}); // or reactive + +const meta = { + ...ReactiveDecorators.default, + component: Reactivity, + render: (args, { argTypes }) => { + state.header = args.header; + state.default = args.default; + state.footer = args.footer; + // return a component options + return defineComponent({ + data: () => ({ args, header: state.header, default: state.default, footer: state.footer }), + components: { + Reactivity, + }, + template: `
Custom render uses options api and binds args to data: + + + + + +
`, + }); + }, +} satisfies Meta; + +export default meta; + +export { + NoDecorators, + DecoratorFunctionalComponent, + DecoratorFunctionalComponentArgsFromContext, + DecoratorComponentOptions, + DecoratorComponentOptionsArgsFromData, +} from './ReactiveDecorators.stories'; diff --git a/code/renderers/vue3/template/stories_vue3-vite-default-ts/ReactiveDecorators.stories.ts b/code/renderers/vue3/template/stories_vue3-vite-default-ts/ReactiveDecorators.stories.ts new file mode 100644 index 000000000000..143cd1784559 --- /dev/null +++ b/code/renderers/vue3/template/stories_vue3-vite-default-ts/ReactiveDecorators.stories.ts @@ -0,0 +1,88 @@ +import { global as globalThis } from '@storybook/global'; +import { userEvent, within } from '@storybook/testing-library'; +import type { Meta, StoryObj } from '@storybook/vue3'; +import { h } from 'vue'; +import { RESET_STORY_ARGS, STORY_ARGS_UPDATED, UPDATE_STORY_ARGS } from '@storybook/core-events'; +import Reactivity from './Reactivity.vue'; + +const meta = { + component: Reactivity, + argTypes: { + header: { control: { type: 'text' } }, + footer: { control: { type: 'text' } }, + default: { control: { type: 'text' } }, + }, + args: { + label: 'If you see this then the label arg was not reactive.', + default: 'If you see this then the default slot was not reactive.', + header: 'If you see this, the header slot was not reactive.', // this can be useless if you have custom render function that overrides the slot + footer: 'If you see this, the footer slot was not reactive.', + }, + play: async ({ canvasElement, id, args }) => { + const channel = (globalThis as any).__STORYBOOK_ADDONS_CHANNEL__; + + const canvas = within(canvasElement); + + await channel.emit(RESET_STORY_ARGS, { storyId: id }); + await new Promise((resolve) => channel.once(STORY_ARGS_UPDATED, resolve)); + + const input = await canvas.findByLabelText('Some input:'); + await userEvent.type(input, 'value'); + + await channel.emit(UPDATE_STORY_ARGS, { + storyId: id, + updatedArgs: { + label: 'updated label', + header: 'updated header slot', // this can be useless if you have custom render function that overrides the slot which the case here + footer: 'updated footer slot', + default: 'updated default slot', + }, + }); + await new Promise((resolve) => channel.once(STORY_ARGS_UPDATED, resolve)); + }, +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const NoDecorators: Story = {}; + +export const DecoratorFunctionalComponent: Story = { + decorators: [ + (storyFn, context) => { + const story = storyFn(); + return () => h('div', [h('h2', ['Decorator not using args']), [h(story)]]); + }, + ], +}; + +export const DecoratorFunctionalComponentArgsFromContext: Story = { + decorators: [ + (storyFn, context) => { + const story = storyFn(); + return () => + h('div', [h('h2', ['Decorator using args.label: ', context.args.label]), [h(story)]]); + }, + ], +}; + +export const DecoratorComponentOptions: Story = { + decorators: [ + (storyFn, context) => { + return { + template: '

Decorator not using args

', + }; + }, + ], +}; + +export const DecoratorComponentOptionsArgsFromData: Story = { + decorators: [ + (storyFn, context) => { + return { + data: () => ({ args: context.args }), + template: '

Decorator using args.label: {{args.label}}

', + }; + }, + ], +}; diff --git a/code/renderers/vue3/template/stories_vue3-vite-default-ts/Reactivity.vue b/code/renderers/vue3/template/stories_vue3-vite-default-ts/Reactivity.vue new file mode 100644 index 000000000000..89880cb5b6cd --- /dev/null +++ b/code/renderers/vue3/template/stories_vue3-vite-default-ts/Reactivity.vue @@ -0,0 +1,44 @@ + + + + From 7100975a66547e10c38c496ec227ef2ed3a1ef17 Mon Sep 17 00:00:00 2001 From: Kasper Peulen Date: Mon, 22 May 2023 16:21:21 +0200 Subject: [PATCH 2/2] Cherry pick new template logic from next --- .../ImageFuture.stories.jsx | 0 .../Link.stories.jsx | 0 .../Font.jsx | 0 .../Font.stories.jsx | 0 .../Head.stories.jsx | 0 .../ImageLegacy.stories.jsx | 0 .../Link.stories.jsx | 0 .../Link.stories.module.css | 0 .../Navigation.stories.jsx | 0 .../Router.stories.jsx | 0 .../fonts/OFL.txt | 0 .../fonts/RubikStorm-Regular.ttf | Bin .../Link.stories.module.css | 0 .../Link.stories.tsx | 0 .../Navigation.stories.tsx | 0 scripts/tasks/sandbox-parts.ts | 35 +++++++++++++----- 16 files changed, 25 insertions(+), 10 deletions(-) rename code/frameworks/nextjs/template/{stories_12-js => stories_nextjs-12-js}/ImageFuture.stories.jsx (100%) rename code/frameworks/nextjs/template/{stories_12-js => stories_nextjs-12-js}/Link.stories.jsx (100%) rename code/frameworks/nextjs/template/{stories_default-js => stories_nextjs-default-js}/Font.jsx (100%) rename code/frameworks/nextjs/template/{stories_default-js => stories_nextjs-default-js}/Font.stories.jsx (100%) rename code/frameworks/nextjs/template/{stories_default-js => stories_nextjs-default-js}/Head.stories.jsx (100%) rename code/frameworks/nextjs/template/{stories_default-js => stories_nextjs-default-js}/ImageLegacy.stories.jsx (100%) rename code/frameworks/nextjs/template/{stories_default-js => stories_nextjs-default-js}/Link.stories.jsx (100%) rename code/frameworks/nextjs/template/{stories_default-js => stories_nextjs-default-js}/Link.stories.module.css (100%) rename code/frameworks/nextjs/template/{stories_default-js => stories_nextjs-default-js}/Navigation.stories.jsx (100%) rename code/frameworks/nextjs/template/{stories_default-js => stories_nextjs-default-js}/Router.stories.jsx (100%) rename code/frameworks/nextjs/template/{stories_default-js => stories_nextjs-default-js}/fonts/OFL.txt (100%) rename code/frameworks/nextjs/template/{stories_default-js => stories_nextjs-default-js}/fonts/RubikStorm-Regular.ttf (100%) rename code/frameworks/nextjs/template/{stories_default-ts => stories_nextjs-default-ts}/Link.stories.module.css (100%) rename code/frameworks/nextjs/template/{stories_default-ts => stories_nextjs-default-ts}/Link.stories.tsx (100%) rename code/frameworks/nextjs/template/{stories_default-ts => stories_nextjs-default-ts}/Navigation.stories.tsx (100%) diff --git a/code/frameworks/nextjs/template/stories_12-js/ImageFuture.stories.jsx b/code/frameworks/nextjs/template/stories_nextjs-12-js/ImageFuture.stories.jsx similarity index 100% rename from code/frameworks/nextjs/template/stories_12-js/ImageFuture.stories.jsx rename to code/frameworks/nextjs/template/stories_nextjs-12-js/ImageFuture.stories.jsx diff --git a/code/frameworks/nextjs/template/stories_12-js/Link.stories.jsx b/code/frameworks/nextjs/template/stories_nextjs-12-js/Link.stories.jsx similarity index 100% rename from code/frameworks/nextjs/template/stories_12-js/Link.stories.jsx rename to code/frameworks/nextjs/template/stories_nextjs-12-js/Link.stories.jsx diff --git a/code/frameworks/nextjs/template/stories_default-js/Font.jsx b/code/frameworks/nextjs/template/stories_nextjs-default-js/Font.jsx similarity index 100% rename from code/frameworks/nextjs/template/stories_default-js/Font.jsx rename to code/frameworks/nextjs/template/stories_nextjs-default-js/Font.jsx diff --git a/code/frameworks/nextjs/template/stories_default-js/Font.stories.jsx b/code/frameworks/nextjs/template/stories_nextjs-default-js/Font.stories.jsx similarity index 100% rename from code/frameworks/nextjs/template/stories_default-js/Font.stories.jsx rename to code/frameworks/nextjs/template/stories_nextjs-default-js/Font.stories.jsx diff --git a/code/frameworks/nextjs/template/stories_default-js/Head.stories.jsx b/code/frameworks/nextjs/template/stories_nextjs-default-js/Head.stories.jsx similarity index 100% rename from code/frameworks/nextjs/template/stories_default-js/Head.stories.jsx rename to code/frameworks/nextjs/template/stories_nextjs-default-js/Head.stories.jsx diff --git a/code/frameworks/nextjs/template/stories_default-js/ImageLegacy.stories.jsx b/code/frameworks/nextjs/template/stories_nextjs-default-js/ImageLegacy.stories.jsx similarity index 100% rename from code/frameworks/nextjs/template/stories_default-js/ImageLegacy.stories.jsx rename to code/frameworks/nextjs/template/stories_nextjs-default-js/ImageLegacy.stories.jsx diff --git a/code/frameworks/nextjs/template/stories_default-js/Link.stories.jsx b/code/frameworks/nextjs/template/stories_nextjs-default-js/Link.stories.jsx similarity index 100% rename from code/frameworks/nextjs/template/stories_default-js/Link.stories.jsx rename to code/frameworks/nextjs/template/stories_nextjs-default-js/Link.stories.jsx diff --git a/code/frameworks/nextjs/template/stories_default-js/Link.stories.module.css b/code/frameworks/nextjs/template/stories_nextjs-default-js/Link.stories.module.css similarity index 100% rename from code/frameworks/nextjs/template/stories_default-js/Link.stories.module.css rename to code/frameworks/nextjs/template/stories_nextjs-default-js/Link.stories.module.css diff --git a/code/frameworks/nextjs/template/stories_default-js/Navigation.stories.jsx b/code/frameworks/nextjs/template/stories_nextjs-default-js/Navigation.stories.jsx similarity index 100% rename from code/frameworks/nextjs/template/stories_default-js/Navigation.stories.jsx rename to code/frameworks/nextjs/template/stories_nextjs-default-js/Navigation.stories.jsx diff --git a/code/frameworks/nextjs/template/stories_default-js/Router.stories.jsx b/code/frameworks/nextjs/template/stories_nextjs-default-js/Router.stories.jsx similarity index 100% rename from code/frameworks/nextjs/template/stories_default-js/Router.stories.jsx rename to code/frameworks/nextjs/template/stories_nextjs-default-js/Router.stories.jsx diff --git a/code/frameworks/nextjs/template/stories_default-js/fonts/OFL.txt b/code/frameworks/nextjs/template/stories_nextjs-default-js/fonts/OFL.txt similarity index 100% rename from code/frameworks/nextjs/template/stories_default-js/fonts/OFL.txt rename to code/frameworks/nextjs/template/stories_nextjs-default-js/fonts/OFL.txt diff --git a/code/frameworks/nextjs/template/stories_default-js/fonts/RubikStorm-Regular.ttf b/code/frameworks/nextjs/template/stories_nextjs-default-js/fonts/RubikStorm-Regular.ttf similarity index 100% rename from code/frameworks/nextjs/template/stories_default-js/fonts/RubikStorm-Regular.ttf rename to code/frameworks/nextjs/template/stories_nextjs-default-js/fonts/RubikStorm-Regular.ttf diff --git a/code/frameworks/nextjs/template/stories_default-ts/Link.stories.module.css b/code/frameworks/nextjs/template/stories_nextjs-default-ts/Link.stories.module.css similarity index 100% rename from code/frameworks/nextjs/template/stories_default-ts/Link.stories.module.css rename to code/frameworks/nextjs/template/stories_nextjs-default-ts/Link.stories.module.css diff --git a/code/frameworks/nextjs/template/stories_default-ts/Link.stories.tsx b/code/frameworks/nextjs/template/stories_nextjs-default-ts/Link.stories.tsx similarity index 100% rename from code/frameworks/nextjs/template/stories_default-ts/Link.stories.tsx rename to code/frameworks/nextjs/template/stories_nextjs-default-ts/Link.stories.tsx diff --git a/code/frameworks/nextjs/template/stories_default-ts/Navigation.stories.tsx b/code/frameworks/nextjs/template/stories_nextjs-default-ts/Navigation.stories.tsx similarity index 100% rename from code/frameworks/nextjs/template/stories_default-ts/Navigation.stories.tsx rename to code/frameworks/nextjs/template/stories_nextjs-default-ts/Navigation.stories.tsx diff --git a/scripts/tasks/sandbox-parts.ts b/scripts/tasks/sandbox-parts.ts index ccce7b3f9169..ba4faf4faff5 100644 --- a/scripts/tasks/sandbox-parts.ts +++ b/scripts/tasks/sandbox-parts.ts @@ -280,7 +280,7 @@ function addStoriesEntry(mainConfig: ConfigFile, path: string) { mainConfig.setFieldValue(['stories'], [...stories, entry]); } -function addVariantToFolder(variant?: string, folder = 'stories') { +function getStoriesFolderWithVariant(variant?: string, folder = 'stories') { return variant ? `${folder}_${variant}` : folder; } @@ -288,9 +288,9 @@ function addVariantToFolder(variant?: string, folder = 'stories') { async function linkPackageStories( packageDir: string, { mainConfig, cwd, linkInDir }: { mainConfig: ConfigFile; cwd: string; linkInDir?: string }, - frameworkVariant?: string + variant?: string ) { - const storiesFolderName = frameworkVariant ? addVariantToFolder(frameworkVariant) : 'stories'; + const storiesFolderName = variant ? getStoriesFolderWithVariant(variant) : 'stories'; const source = join(CODE_DIRECTORY, packageDir, 'template', storiesFolderName); // By default we link `stories` directories // e.g '../../../code/lib/store/template/stories' to 'template-stories/lib/store' @@ -299,10 +299,7 @@ async function linkPackageStories( // The files must be linked in the cwd, in order to ensure that any dependencies they // reference are resolved in the cwd. In particular 'react' resolved by MDX files. const target = linkInDir - ? resolve( - linkInDir, - frameworkVariant ? addVariantToFolder(frameworkVariant, packageDir) : packageDir - ) + ? resolve(linkInDir, variant ? getStoriesFolderWithVariant(variant, packageDir) : packageDir) : resolve(cwd, 'template-stories', packageDir); await ensureSymlink(source, target); @@ -373,6 +370,9 @@ export const addStories: Task['run'] = async ( template.expected.renderer.startsWith('@storybook/') && template.expected.renderer !== '@storybook/server'; + const sandboxSpecificStoriesFolder = key.replaceAll('/', '-'); + const storiesVariantFolder = getStoriesFolderWithVariant(sandboxSpecificStoriesFolder); + if (isCoreRenderer) { // Link in the template/components/index.js from store, the renderer and the addons const rendererPath = await workspacePath('renderer', template.expected.renderer); @@ -388,6 +388,22 @@ export const addStories: Task['run'] = async ( cwd, linkInDir: resolve(cwd, storiesPath), }); + + if ( + await pathExists( + resolve(CODE_DIRECTORY, rendererPath, join('template', storiesVariantFolder)) + ) + ) { + await linkPackageStories( + rendererPath, + { + mainConfig, + cwd, + linkInDir: resolve(cwd, storiesPath), + }, + sandboxSpecificStoriesFolder + ); + } } const isCoreFramework = template.expected.framework.startsWith('@storybook/'); @@ -404,8 +420,7 @@ export const addStories: Task['run'] = async ( }); } - const frameworkVariant = key.split('/')[1]; - const storiesVariantFolder = addVariantToFolder(frameworkVariant); + console.log({ sandboxSpecificStoriesFolder, storiesVariantFolder }); if ( await pathExists( @@ -419,7 +434,7 @@ export const addStories: Task['run'] = async ( cwd, linkInDir: resolve(cwd, storiesPath), }, - frameworkVariant + sandboxSpecificStoriesFolder ); } }