Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Svelte: Add experimental portable stories support #26349

Merged
Show file tree
Hide file tree
Changes from 23 commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
c97fa73
add composeStories api for svelte
yannbf Feb 5, 2024
a9b74e5
add testing library for svelte
yannbf Mar 5, 2024
f721c8e
patch @testing-library/svelte to support Svelte 5 based on https://gi…
JReinhold Feb 5, 2024
17b0367
make basic composeStories test work in Svelte
yannbf Mar 5, 2024
e9a144e
cleanup basic svelte composeStories tests
JReinhold Feb 5, 2024
e7e8cc8
fix testing library patch
yannbf Mar 5, 2024
1d47ca3
add decorators support, write more tests
yannbf Mar 6, 2024
395addd
fix decorator path
yannbf Mar 7, 2024
b4326eb
add portable stories exports
yannbf Mar 7, 2024
6016142
add playwright experimental ct api for svelte
yannbf Mar 7, 2024
7c613aa
add svelte to CI tests
yannbf Mar 7, 2024
b71db43
add cypress ct
yannbf Mar 7, 2024
9d9bffd
remove wrapper id decorator
yannbf Mar 12, 2024
e952402
Merge branch 'feature/portable-stories-improvements' into feature/por…
yannbf Mar 12, 2024
586a135
more improvements
yannbf Mar 12, 2024
bbc3c07
change tests
yannbf Mar 12, 2024
96287f1
add svelte tests to kitchen sink
JReinhold Mar 12, 2024
eb023e5
add svelte 4 support
yannbf Mar 12, 2024
721a5a4
add portable stories + svelte + vitest docs
yannbf Mar 12, 2024
f782b89
update lockfile
yannbf Mar 12, 2024
9960880
update package json
yannbf Mar 12, 2024
70dcbfa
Merge branch 'feature/portable-stories-improvements' into feature/por…
yannbf Mar 12, 2024
4a95c9b
update docs
kylegach Mar 12, 2024
4f199c1
put "import" condition at the top of Svelte renderer exports
JReinhold Mar 13, 2024
61647d0
fix playwright setup
yannbf Mar 13, 2024
1ae542f
Merge branch 'feature/portable-stories-improvements' into feature/por…
yannbf Mar 13, 2024
97b4701
Merge branch 'feature/portable-stories-improvements' into feature/por…
yannbf Mar 13, 2024
0466f7a
Update docs/snippets/svelte/portable-stories-vitest-compose-story.ts.mdx
yannbf Mar 13, 2024
f225bea
fix prettier docs issue
yannbf Mar 14, 2024
d9e22dd
dedupe a few deps
yannbf Mar 14, 2024
9f1b772
add EOL to scripts package.json
yannbf Mar 14, 2024
893f3c3
cleanup
yannbf Mar 14, 2024
95ed6da
Merge branch 'feature/portable-stories-improvements' into feature/por…
yannbf Mar 14, 2024
c8c7e7b
Merge branch 'feature/portable-stories-improvements' into feature/por…
yannbf Mar 15, 2024
8ddbffc
Fix svelte types
kasperpeulen Mar 15, 2024
afee7be
Merge branch 'feature/portable-stories-improvements' into feature/por…
yannbf Mar 18, 2024
184e870
fix types for composeStories
yannbf Mar 18, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -670,7 +670,7 @@ workflows:
- build
matrix:
parameters:
directory: ["react", "vue3", "nextjs"]
directory: ["react", "vue3", "nextjs", "svelte"]
# TODO: reenable once we find out the source of flakyness
# - test-runner-dev:
# requires:
Expand Down Expand Up @@ -728,7 +728,7 @@ workflows:
- build
matrix:
parameters:
directory: ["react", "vue3", "nextjs"]
directory: ["react", "vue3", "nextjs", "svelte"]
- bench:
parallelism: 5
requires:
Expand Down Expand Up @@ -791,7 +791,7 @@ workflows:
- build
matrix:
parameters:
directory: ["react", "vue3", "nextjs"]
directory: ["react", "vue3", "nextjs", "svelte"]
- test-empty-init:
requires:
- build
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ export function createPlaywrightTest<TFixture extends { extend: any }>(
): TFixture {
return baseTest.extend({
mount: async ({ mount, page }: any, use: any) => {
await use(async (storyRef: WrappedStoryRef) => {
await use(async (storyRef: WrappedStoryRef, ...restArgs: any) => {
// load the story in the browser
await page.evaluate(async (wrappedStoryRef: WrappedStoryRef) => {
const unwrappedStoryRef = await globalThis.__pwUnwrapObject?.(wrappedStoryRef);
Expand All @@ -179,7 +179,7 @@ export function createPlaywrightTest<TFixture extends { extend: any }>(
}, storyRef);

// mount the story
const mountResult = await mount(storyRef);
const mountResult = await mount(storyRef, ...restArgs);

// play the story in the browser
await page.evaluate(async (wrappedStoryRef: WrappedStoryRef) => {
Expand Down
13 changes: 12 additions & 1 deletion code/renderers/svelte/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,19 @@
"require": "./dist/index.js",
"import": "./dist/index.mjs"
},
"./experimental-playwright": {
"types": "./dist/playwright.d.ts",
"node": "./dist/playwright.js",
"require": "./dist/playwright.js",
"import": "./dist/playwright.mjs"
},
"./preset": "./preset.js",
"./dist/entry-preview.mjs": "./dist/entry-preview.mjs",
"./dist/entry-preview-docs.mjs": "./dist/entry-preview-docs.mjs",
"./package.json": "./package.json",
"./internal/PreviewRender.svelte": "./dist/components/PreviewRender.svelte",
"./internal/SlotDecorator.svelte": "./dist/components/SlotDecorator.svelte",
"./internal/AddStorybookIdDecorator.svelte": "./dist/components/AddStorybookIdDecorator.svelte",
"./internal/createSvelte5Props": "./dist/createSvelte5Props.svelte.js"
},
"main": "dist/index.js",
Expand Down Expand Up @@ -62,8 +69,11 @@
},
"devDependencies": {
"@sveltejs/vite-plugin-svelte": "^3.0.2",
"@testing-library/jest-dom": "^6.4.1",
"@testing-library/svelte": "patch:@testing-library/svelte@npm%3A4.1.0#~/.yarn/patches/@testing-library-svelte-npm-4.1.0-34b7037bc0.patch",
"expect-type": "^0.15.0",
"fs-extra": "^11.1.0",
"jsdom": "^24.0.0",
"svelte": "^5.0.0-next.65",
"svelte-check": "^3.6.4",
"typescript": "^5.3.2"
Expand All @@ -83,7 +93,8 @@
"./src/index.ts",
"./src/preset.ts",
"./src/entry-preview.ts",
"./src/entry-preview-docs.ts"
"./src/entry-preview-docs.ts",
"./src/playwright.ts"
],
"platform": "browser"
},
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<div style="margin: 3em;" data-testid="local-decorator">
<slot/>
</div>
152 changes: 152 additions & 0 deletions code/renderers/svelte/src/__test__/composeStories/Button.stories.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
import { expect, fn, userEvent, within } from '@storybook/test';
import type { Meta, StoryFn as CSF2Story, StoryObj } from '../..';

import LoaderStoryComponent from './LoaderStoryComponent.svelte';
import InputFilledStoryComponent from './InputFilledStoryComponent.svelte';
import StoryWithLocaleComponent from './StoryWithLocaleComponent.svelte';
import AddWrapperDecorator from './AddWrapperDecorator.svelte';
import CustomRenderComponent from './CustomRenderComponent.svelte';

import Button from './Button.svelte';

const meta = {
title: 'Example/Button',
component: Button,
argTypes: {
backgroundColor: { control: 'color' },
size: {
control: { type: 'select' },
options: ['small', 'medium', 'large'],
},
},
excludeStories: /.*ImNotAStory$/,
} satisfies Meta<Button>;

export default meta;
type CSF3Story = StoryObj<typeof meta>;

// For testing purposes. Should be ignored in ComposeStories
export const ImNotAStory = 123;

const Template: CSF2Story = (args) => ({
Component: Button,
props: args,
});

export const CSF2Secondary = Template.bind({});
CSF2Secondary.args = {
label: 'label coming from story args!',
primary: false,
};

const getCaptionForLocale = (locale: string) => {
switch (locale) {
case 'es':
return 'Hola!';
case 'fr':
return 'Bonjour!';
case 'kr':
return '안녕하세요!';
case 'pt':
return 'Olá!';
default:
return 'Hello!';
}
};

export const CSF2StoryWithLocale: CSF2Story = (args, { globals }) => ({
Component: StoryWithLocaleComponent,
props: {
...args,
locale: globals.locale,
label: getCaptionForLocale(globals.locale),
},
});
CSF2StoryWithLocale.storyName = 'WithLocale';

export const CSF2StoryWithParamsAndDecorator = Template.bind({});
CSF2StoryWithParamsAndDecorator.args = {
label: 'foo',
};
CSF2StoryWithParamsAndDecorator.parameters = {
layout: 'centered',
};
CSF2StoryWithParamsAndDecorator.decorators = [
() => ({
Component: AddWrapperDecorator,
}),
];

export const NewStory: CSF3Story = {
args: {
label: 'foo',
size: 'large',
primary: true,
},
decorators: [
() => ({
Component: AddWrapperDecorator,
}),
],
};

export const CSF3Primary: CSF3Story = {
args: {
label: 'foo',
size: 'large',
primary: true,
},
};

export const CSF3Button: CSF3Story = {
args: { label: 'foo' },
};

export const CSF3ButtonWithRender: CSF3Story = {
...CSF3Button,
render: (args) => ({
Component: CustomRenderComponent,
props: {
args,
},
}),
};

export const CSF3InputFieldFilled: CSF3Story = {
render: () => ({
Component: InputFilledStoryComponent,
}),
play: async ({ canvasElement, step }) => {
const canvas = within(canvasElement);
await step('Step label', async () => {
const inputEl = canvas.getByTestId('input');
await userEvent.type(inputEl, 'Hello world!');
await expect(inputEl).toHaveValue('Hello world!');
});
},
};

const mockFn = fn();
export const LoaderStory: StoryObj<{ mockFn: (val: string) => string }> = {
args: {
mockFn,
},
loaders: [
async () => {
mockFn.mockReturnValueOnce('mockFn return value');
return {
value: 'loaded data',
};
},
],
render: (args, { loaded }) => ({
Component: LoaderStoryComponent,
props: {
...args,
loaded,
},
}),
play: async () => {
expect(mockFn).toHaveBeenCalledWith('render');
},
};
33 changes: 33 additions & 0 deletions code/renderers/svelte/src/__test__/composeStories/Button.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<script lang="ts">
/**
* Is this the principal call to action on the page?
*/
export let primary = false;

/**
* What background color to use
*/
export let backgroundColor: string | undefined = undefined;
/**
* How large should the button be?
*/
export let size: 'small' | 'medium' | 'large' = 'medium';
/**
* Button contents
*/
export let label: string = '';

$: mode = primary ? 'storybook-button--primary' : 'storybook-button--secondary';

$: style = backgroundColor ? `background-color: ${backgroundColor}` : '';
</script>

<button
type="button"
class={['storybook-button', `storybook-button--${size}`, mode].join(' ')}
{style}
on:click
>
{label}
<slot/>
</button>
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<script>
import Button from './Button.svelte';

export let args;
</script>

<div>
<p data-testid="custom-render">I am a custom render function</p>
<Button {...args} />
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<input data-testid="input" />
Loading
Loading