Skip to content

Commit

Permalink
Merge pull request #26349 from storybookjs/feature/portable-stories-s…
Browse files Browse the repository at this point in the history
…velte-renderer

Svelte: Add experimental portable stories support
  • Loading branch information
yannbf authored Mar 18, 2024
2 parents f0dfc2a + 184e870 commit fb1a02e
Show file tree
Hide file tree
Showing 65 changed files with 13,996 additions and 29 deletions.
6 changes: 3 additions & 3 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -674,7 +674,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 @@ -732,7 +732,7 @@ workflows:
- build
matrix:
parameters:
directory: ["react", "vue3", "nextjs"]
directory: ["react", "vue3", "nextjs", "svelte"]
- bench:
parallelism: 5
requires:
Expand Down Expand Up @@ -795,7 +795,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.

17 changes: 14 additions & 3 deletions code/renderers/svelte/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,23 @@
"exports": {
".": {
"types": "./dist/index.d.ts",
"node": "./dist/index.js",
"import": "./dist/index.mjs",
"require": "./dist/index.js",
"import": "./dist/index.mjs"
"node": "./dist/index.js"
},
"./experimental-playwright": {
"types": "./dist/playwright.d.ts",
"import": "./dist/playwright.mjs",
"require": "./dist/playwright.js",
"node": "./dist/playwright.js"
},
"./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>
154 changes: 154 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,154 @@
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<StoryWithLocaleComponent> = (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: StoryObj<CustomRenderComponent> = {
args: {
buttonProps: CSF3Button.args,
},
render: (args) => ({
Component: CustomRenderComponent,
props: {
buttonProps: args.buttonProps,
},
}),
};

export const CSF3InputFieldFilled: StoryObj<InputFilledStoryComponent> = {
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<LoaderStoryComponent> = {
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,11 @@
<script lang="ts">
import Button from './Button.svelte';
import { ComponentProps } from 'svelte';
export let buttonProps: ComponentProps<Button>;
</script>

<div>
<p data-testid="custom-render">I am a custom render function</p>
<Button {...buttonProps} />
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<input data-testid="input" />
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<script>
export let mockFn;
export let loaded;
let data;
$: if (mockFn && loaded) {
data = mockFn('render');
}
</script>

<div>
<div data-testid="loaded-data">{loaded.value}</div>
<div data-testid="spy-data">{String(data)}</div>
</div>
Loading

0 comments on commit fb1a02e

Please sign in to comment.