-
-
Notifications
You must be signed in to change notification settings - Fork 9.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #22685 from storybookjs/main-vue-tests
Vue3: Bring back new tests to main
- Loading branch information
Showing
20 changed files
with
234 additions
and
10 deletions.
There are no files selected for viewing
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
32 changes: 32 additions & 0 deletions
32
...ers/vue3/template/stories_vue3-vite-default-ts/CustomRenderFunctionalComponent.stories.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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<typeof Reactivity>; | ||
|
||
export default meta; | ||
|
||
export { | ||
NoDecorators, | ||
DecoratorFunctionalComponent, | ||
DecoratorFunctionalComponentArgsFromContext, | ||
DecoratorComponentOptions, | ||
DecoratorComponentOptionsArgsFromData, | ||
} from './ReactiveDecorators.stories'; |
45 changes: 45 additions & 0 deletions
45
...ers/vue3/template/stories_vue3-vite-default-ts/CustomRenderOptionsArgsFromData.stories.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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: `<div>Custom render uses options api and binds args to data: | ||
<Reactivity v-bind="args"> | ||
<template #header="{title}"><h3>{{ args.header }} - Title: {{ title }}</h3></template> | ||
<template #default>{{ args.default }}</template> | ||
<template #footer>{{ args.footer }} </template> | ||
</Reactivity> | ||
</div>`, | ||
}); | ||
}, | ||
} satisfies Meta<typeof Reactivity>; | ||
|
||
export default meta; | ||
|
||
export { | ||
NoDecorators, | ||
DecoratorFunctionalComponent, | ||
DecoratorFunctionalComponentArgsFromContext, | ||
DecoratorComponentOptions, | ||
DecoratorComponentOptionsArgsFromData, | ||
} from './ReactiveDecorators.stories'; |
88 changes: 88 additions & 0 deletions
88
code/renderers/vue3/template/stories_vue3-vite-default-ts/ReactiveDecorators.stories.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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<HTMLInputElement>('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<typeof Reactivity>; | ||
|
||
export default meta; | ||
type Story = StoryObj<typeof meta>; | ||
|
||
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: '<div><h2>Decorator not using args</h2><story/></div>', | ||
}; | ||
}, | ||
], | ||
}; | ||
|
||
export const DecoratorComponentOptionsArgsFromData: Story = { | ||
decorators: [ | ||
(storyFn, context) => { | ||
return { | ||
data: () => ({ args: context.args }), | ||
template: '<div><h2>Decorator using args.label: {{args.label}}</h2><story/></div>', | ||
}; | ||
}, | ||
], | ||
}; |
44 changes: 44 additions & 0 deletions
44
code/renderers/vue3/template/stories_vue3-vite-default-ts/Reactivity.vue
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
<script setup lang="ts"> | ||
defineProps<{ label: string }>(); | ||
</script> | ||
<template> | ||
<div style="padding: 20px;background-color: pink;"> | ||
<header data-testid="header-slot"> | ||
<slot name="header" title="Header title from the slot"> | ||
If you see this, the header slot was not reactive. | ||
</slot> | ||
</header> | ||
<div id="content"> | ||
<label> | ||
Some input: | ||
<input style='width: 400px' placeholder='If you see this, an args update caused the input field to loose state' /> | ||
</label> | ||
<hr> | ||
<button class="storybook-button storybook-button--primary storybook-button--medium"> {{ label | ||
}}</button> | ||
</div> | ||
|
||
<main data-testid="default-slot"> | ||
<slot>Default slot placeholder</slot> | ||
</main> | ||
<footer data-testid="footer-slot"> | ||
<slot name="footer"> | ||
Footer slot placeholder | ||
</slot> | ||
</footer> | ||
</div> | ||
</template> | ||
|
||
<style> | ||
header, | ||
footer { | ||
background-color: #fff0ff; | ||
padding: 20px; | ||
} | ||
main, | ||
#content { | ||
background-color: #f0f0f0; | ||
padding: 20px; | ||
} | ||
</style> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters