diff --git a/.circleci/config.yml b/.circleci/config.yml index dac362b5530b..d6ef4a750913 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -472,6 +472,98 @@ jobs: command: yarn upload-bench $(yarn get-template --cadence << pipeline.parameters.workflow >> --task bench) - report-workflow-on-failure: template: $(yarn get-template --cadence << pipeline.parameters.workflow >> --task bench) + test-empty-init: + executor: + class: medium + name: sb_node_16_browsers + parameters: + packageManager: + type: string + template: + type: string + steps: + - git-shallow-clone/checkout_advanced: + clone_options: '--depth 1 --verbose' + - attach_workspace: + at: . + - when: + condition: + equal: ["npm", << parameters.packageManager >>] + steps: + - run: + name: Storybook init from empty directory (NPM) + command: | + cd code + yarn local-registry --open & + cd ../../ + mkdir empty-<< parameters.template >> + cd empty-<< parameters.template >> + npm set registry http://localhost:6001 + npx storybook init --yes --package-manager npm + npm run storybook -- --smoke-test + environment: + IN_STORYBOOK_SANDBOX: true + STORYBOOK_INIT_EMPTY_TYPE: << parameters.template >> + STORYBOOK_DISABLE_TELEMETRY: true + - when: + condition: + equal: ["yarn1", << parameters.packageManager >>] + steps: + - run: + name: Storybook init from empty directory (Yarn 1) + command: | + cd code + yarn local-registry --open & + cd ../../ + mkdir empty-<< parameters.template >> + cd empty-<< parameters.template >> + npx storybook init --yes --package-manager yarn1 + yarn storybook --smoke-test + environment: + IN_STORYBOOK_SANDBOX: true + STORYBOOK_INIT_EMPTY_TYPE: << parameters.template >> + STORYBOOK_DISABLE_TELEMETRY: true + - when: + condition: + equal: ["yarn2", << parameters.packageManager >>] + steps: + - run: + name: Storybook init from empty directory (Yarn 2) + command: | + cd code + yarn local-registry --open & + cd ../../ + mkdir empty-<< parameters.template >> + cd empty-<< parameters.template >> + yarn set version berry + yarn config set registry http://localhost:6001 + yarn dlx storybook init --yes --package-manager yarn2 + yarn storybook --smoke-test + environment: + IN_STORYBOOK_SANDBOX: true + STORYBOOK_INIT_EMPTY_TYPE: << parameters.template >> + STORYBOOK_DISABLE_TELEMETRY: true + - when: + condition: + equal: ["pnpm", << parameters.packageManager >>] + steps: + - run: + name: Storybook init from empty directory (PNPM) + command: | + cd code + yarn local-registry --open & + cd ../../ + mkdir empty-<< parameters.template >> + cd empty-<< parameters.template >> + npm i -g pnpm + pnpm config set registry http://localhost:6001 + pnpm dlx storybook init --yes --package-manager pnpm + pnpm run storybook --smoke-test + environment: + IN_STORYBOOK_SANDBOX: true + STORYBOOK_INIT_EMPTY_TYPE: << parameters.template >> + STORYBOOK_DISABLE_TELEMETRY: true + - report-workflow-on-failure workflows: docs: @@ -504,19 +596,19 @@ workflows: requires: - unit-tests - create-sandboxes: - parallelism: 14 + parallelism: 13 requires: - build - build-sandboxes: - parallelism: 14 + parallelism: 13 requires: - create-sandboxes - chromatic-sandboxes: - parallelism: 11 + parallelism: 10 requires: - build-sandboxes - e2e-production: - parallelism: 9 + parallelism: 8 requires: - build-sandboxes - e2e-dev: @@ -524,7 +616,7 @@ workflows: requires: - create-sandboxes - test-runner-production: - parallelism: 9 + parallelism: 8 requires: - build-sandboxes - bench: @@ -560,19 +652,19 @@ workflows: requires: - unit-tests - create-sandboxes: - parallelism: 21 + parallelism: 20 requires: - build - build-sandboxes: - parallelism: 21 + parallelism: 20 requires: - create-sandboxes - chromatic-sandboxes: - parallelism: 18 + parallelism: 17 requires: - build-sandboxes - e2e-production: - parallelism: 16 + parallelism: 15 requires: - build-sandboxes - e2e-dev: @@ -580,7 +672,7 @@ workflows: requires: - create-sandboxes - test-runner-production: - parallelism: 16 + parallelism: 15 requires: - build-sandboxes - bench: @@ -614,22 +706,22 @@ workflows: requires: - build - create-sandboxes: - parallelism: 35 + parallelism: 33 requires: - build # - smoke-test-sandboxes: # disabled for now # requires: # - create-sandboxes - build-sandboxes: - parallelism: 35 + parallelism: 33 requires: - create-sandboxes - chromatic-sandboxes: - parallelism: 32 + parallelism: 30 requires: - build-sandboxes - e2e-production: - parallelism: 30 + parallelism: 28 requires: - build-sandboxes - e2e-dev: @@ -637,9 +729,29 @@ workflows: requires: - create-sandboxes - test-runner-production: - parallelism: 30 + parallelism: 28 requires: - build-sandboxes + + - test-empty-init: + requires: + - build + matrix: + parameters: + packageManager: + - "npm" + # TODO: reenable once we find out the source of failure + # - "yarn1" + # - "yarn2" + # - "pnpm" + template: + - "react-vite-ts" + - "nextjs-ts" + - "vue-vite-ts" + # --smoke-test is not supported for the angular builder right now + # - "angular-cli" + - "lit-vite-ts" + # TODO: reenable once we find out the source of flakyness # - test-runner-dev: # parallelism: 4 diff --git a/CHANGELOG.md b/CHANGELOG.md index ca7fcf921544..5ba60ca1636f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +## 7.6.4 + +- Angular: Fix CSF Plugin - [#25098](https://github.com/storybookjs/storybook/pull/25098), thanks [@valentinpalkovic](https://github.com/valentinpalkovic)! +- Viewport: Fix viewport dts files - [#25107](https://github.com/storybookjs/storybook/pull/25107), thanks [@kasperpeulen](https://github.com/kasperpeulen)! + ## 7.6.3 - Next.js: Fix next/font/local usage in babel mode - [#25045](https://github.com/storybookjs/storybook/pull/25045), thanks [@valentinpalkovic](https://github.com/valentinpalkovic)! diff --git a/CHANGELOG.prerelease.md b/CHANGELOG.prerelease.md index cae24fdc0f31..697526d7685d 100644 --- a/CHANGELOG.prerelease.md +++ b/CHANGELOG.prerelease.md @@ -1,3 +1,12 @@ +## 8.0.0-alpha.2 + +- Core: Maintenance changes for NextJS embedding - [#25086](https://github.com/storybookjs/storybook/pull/25086), thanks [@shilman](https://github.com/shilman)! +- Addon-docs: Fix story anchors using encodeURIComponent - [#25062](https://github.com/storybookjs/storybook/pull/25062), thanks [@xyy94813](https://github.com/xyy94813)! +- CLI: Generate a new project on init in empty directory - [#24997](https://github.com/storybookjs/storybook/pull/24997), thanks [@Integrayshaun](https://github.com/Integrayshaun)! +- Svelte: Support v5 prereleases - [#24889](https://github.com/storybookjs/storybook/pull/24889), thanks [@allozaur](https://github.com/allozaur)! +- Vue: Remove deprecated vue packages from next - [#25108](https://github.com/storybookjs/storybook/pull/25108), thanks [@kasperpeulen](https://github.com/kasperpeulen)! +- Vue: Remove unused preset-vue-webpack - [#25151](https://github.com/storybookjs/storybook/pull/25151), thanks [@shilman](https://github.com/shilman)! + ## 8.0.0-alpha.1 - Angular: Drop v14.x support - [#25101](https://github.com/storybookjs/storybook/pull/25101), thanks [@valentinpalkovic](https://github.com/valentinpalkovic)! diff --git a/Issue.md b/Issue.md deleted file mode 100644 index a56a5a902dc1..000000000000 --- a/Issue.md +++ /dev/null @@ -1,67 +0,0 @@ -*What:* -We want to step our TS game in the monorepo and enable strict typescript in all packages! - -*Why:* -Having TS track for you if a variable might be null or not, enables us to code with much more confidence, -and also gives us quick in editor feedback, when you make assumptions that are not actually true! - -*How:* -We would like to change as little as possible of the actual runtime behavior in this migration. -However, we also don't want to simply silence the compiler everywhere with `!`, `as` or `ts-ignore` to get this migration in. -As a rule of thumb, if the logic is easy enough, prefer improving the code (e.g. add a null check) over silencing the compiler. -If the change needed to do the right thing, is too risky, and not in your expertise, it is okay to silence the compiler. -It is not ideal, but we still gain the benefit that new code written will have extra typesafety. - -Feel free to contribute too any of packages in the list below! - -- [ ] @storybook/addon-backgrounds -- [ ] @storybook/addon-docs -- [ ] @storybook/addon-highlight -- [ ] @storybook/addon-interactions -- [ ] @storybook/addon-jest -- [ ] @storybook/addon-mdx-gfm -- [ ] @storybook/addon-measure -- [ ] @storybook/addon-outline -- [ ] @storybook/addon-storyshots -- [ ] @storybook/addon-storyshots-puppeteer -- [ ] @storybook/addon-storysource -- [ ] @storybook/addon-viewport -- [ ] @storybook/addons -- [ ] @storybook/angular -- [ ] @storybook/api -- [ ] @storybook/blocks -- [ ] @storybook/channel-postmessage -- [ ] @storybook/channel-websocket -- [ ] @storybook/channels -- [ ] @storybook/cli -- [ ] @storybook/client-api -- [ ] @storybook/codemod -- [ ] @storybook/components -- [ ] @storybook/core-client -- [ ] @storybook/core-events -- [ ] @storybook/core-server -- [ ] @storybook/csf-tools -- [ ] @storybook/docs-tools -- [ ] @storybook/external-docs -- [ ] @storybook/html-vite -- [ ] @storybook/instrumenter -- [ ] @storybook/manager -- [ ] @storybook/manager-api -- [ ] @storybook/postinstall -- [ ] @storybook/preact-vite -- [ ] @storybook/preset-create-react-app -- [ ] @storybook/preset-vue-webpack -- [ ] @storybook/preset-vue3-webpack -- [ ] @storybook/react-vite -- [ ] @storybook/router -- [ ] @storybook/scripts -- [ ] @storybook/server -- [ ] @storybook/source-loader -- [ ] @storybook/svelte-vite -- [ ] @storybook/sveltekit -- [ ] @storybook/theming -- [ ] @storybook/types -- [ ] @storybook/vue3-vite -- [ ] @storybook/vue3-webpack5 -- [ ] @storybook/web-components -- [ ] @storybook/web-components-vite diff --git a/README.md b/README.md index 820c663970f0..7c174bdcc250 100644 --- a/README.md +++ b/README.md @@ -131,7 +131,6 @@ For additional help, share your issue in [the repo's GitHub Discussions](https:/ | [measure](code/addons/measure/) | Visually inspect the layout and box model within the Storybook UI | | [outline](code/addons/outline/) | Visually debug the CSS layout and alignment within the Storybook UI | | [query params](https://github.com/storybookjs/addon-queryparams) | Mock query params | -| [storyshots](code/addons/storyshots-core/) | Snapshot testing for components in Storybook | | [storysource](code/addons/storysource/) | View the code of your stories within the Storybook UI | | [viewport](code/addons/viewport/) | Change display sizes and layouts for responsive components using Storybook | @@ -139,13 +138,14 @@ See [Addon / Framework Support Table](https://storybook.js.org/docs/react/api/fr ### Deprecated Addons -| Addons | | -| ---------------------------------------------------------------------------------- | ---------------------------------------------------------- | -| [contexts](https://storybook.js.org/addons/@storybook/addon-contexts/) | Addon for driving your components under dynamic contexts | -| [info](https://github.com/storybookjs/deprecated-addons/tree/master/addons/info) | Annotate stories with extra component usage information | -| [knobs](https://github.com/storybookjs/addon-knobs) | Interactively edit component prop data in the Storybook UI | -| [notes](https://github.com/storybookjs/deprecated-addons/tree/master/addons/notes) | Annotate Storybook stories with notes | -| [options](https://www.npmjs.com/package/@storybook/addon-options) | Customize the Storybook UI in code | +| Addons | | +| -------------------------------------------------------------------------------------------- | ---------------------------------------------------------- | +| [contexts](https://storybook.js.org/addons/@storybook/addon-contexts/) | Addon for driving your components under dynamic contexts | +| [info](https://github.com/storybookjs/deprecated-addons/tree/master/addons/info) | Annotate stories with extra component usage information | +| [knobs](https://github.com/storybookjs/addon-knobs) | Interactively edit component prop data in the Storybook UI | +| [notes](https://github.com/storybookjs/deprecated-addons/tree/master/addons/notes) | Annotate Storybook stories with notes | +| [options](https://www.npmjs.com/package/@storybook/addon-options) | Customize the Storybook UI in code | +| [storyshots](https://github.com/storybookjs/storybook/tree/main/code/addons/storyshots-core) | Snapshot testing for components in Storybook | To continue improving your experience, we have to eventually deprecate certain addons in favor of new and better tools. diff --git a/code/addons/essentials/package.json b/code/addons/essentials/package.json index 8f50f570f7dd..9664fc71e84a 100644 --- a/code/addons/essentials/package.json +++ b/code/addons/essentials/package.json @@ -76,7 +76,6 @@ "ts-dedent": "^2.0.0" }, "devDependencies": { - "@storybook/vue": "workspace:*", "typescript": "^5.3.2" }, "peerDependencies": { diff --git a/code/builders/builder-manager/src/utils/template.ts b/code/builders/builder-manager/src/utils/template.ts index 64fb626869b3..0d7b67a1dff3 100644 --- a/code/builders/builder-manager/src/utils/template.ts +++ b/code/builders/builder-manager/src/utils/template.ts @@ -34,7 +34,7 @@ export const renderHTML = async ( refs: Promise>, logLevel: Promise, docsOptions: Promise, - { versionCheck, previewUrl, configType }: Options + { versionCheck, previewUrl, configType, ignorePreview }: Options ) => { const titleRef = await title; const templateRef = await template; @@ -54,5 +54,6 @@ export const renderHTML = async ( PREVIEW_URL: JSON.stringify(previewUrl, null, 2), // global preview URL }, head: (await customHead) || '', + ignorePreview, }); }; diff --git a/code/builders/builder-manager/templates/template.ejs b/code/builders/builder-manager/templates/template.ejs index 7961f4ae4f7c..af42859a0791 100644 --- a/code/builders/builder-manager/templates/template.ejs +++ b/code/builders/builder-manager/templates/template.ejs @@ -66,6 +66,8 @@ import './sb-manager/runtime.js'; + <% if (!ignorePreview) { %> + <% } %> diff --git a/code/e2e-tests/addon-actions.spec.ts b/code/e2e-tests/addon-actions.spec.ts index 520c2b5dc41f..a9f32e61c022 100644 --- a/code/e2e-tests/addon-actions.spec.ts +++ b/code/e2e-tests/addon-actions.spec.ts @@ -3,9 +3,16 @@ import process from 'process'; import { SbPage } from './util'; const storybookUrl = process.env.STORYBOOK_URL || 'http://localhost:8001'; +const templateName = process.env.STORYBOOK_TEMPLATE_NAME || ''; test.describe('addon-actions', () => { test('should trigger an action', async ({ page }) => { + // eslint-disable-next-line jest/no-disabled-tests + test.skip( + // eslint-disable-next-line jest/valid-title + templateName.includes('svelte') && templateName.includes('prerelease'), + 'Svelte 5 prerelase does not support automatic actions with our current example components yet' + ); await page.goto(storybookUrl); const sbPage = new SbPage(page); sbPage.waitUntilLoaded(); diff --git a/code/e2e-tests/addon-docs.spec.ts b/code/e2e-tests/addon-docs.spec.ts index 30babefa2280..7edd143360ab 100644 --- a/code/e2e-tests/addon-docs.spec.ts +++ b/code/e2e-tests/addon-docs.spec.ts @@ -122,9 +122,6 @@ test.describe('addon-docs', () => { // - template: https://638db567ed97c3fb3e21cc22-ulhjwkqzzj.chromatic.com/?path=/docs/addons-docs-docspage-basic--docs // - real: https://638db567ed97c3fb3e21cc22-ulhjwkqzzj.chromatic.com/?path=/docs/example-button--docs 'lit-vite', - // Vue doesn't update when you change args, apparently fixed by this: - // https://github.com/storybookjs/storybook/pull/20995 - 'vue2-vite', ]; test.skip( new RegExp(`^${skipped.join('|')}`, 'i').test(`${templateName}`), diff --git a/code/frameworks/svelte-vite/package.json b/code/frameworks/svelte-vite/package.json index cb07dfdff473..b4975a090c78 100644 --- a/code/frameworks/svelte-vite/package.json +++ b/code/frameworks/svelte-vite/package.json @@ -52,18 +52,18 @@ "@storybook/svelte": "workspace:*", "@sveltejs/vite-plugin-svelte": "^2.4.2", "magic-string": "^0.30.0", - "svelte-preprocess": "^5.0.4", + "svelte-preprocess": "^5.1.1", "sveltedoc-parser": "^4.2.1", "ts-dedent": "^2.2.0" }, "devDependencies": { "@types/node": "^18.0.0", - "svelte": "^4.0.0", + "svelte": "^5.0.0-next.16", "typescript": "^5.3.2", "vite": "^4.0.0" }, "peerDependencies": { - "svelte": "^3.0.0 || ^4.0.0", + "svelte": "^4.0.0 || ^5.0.0-next.16", "vite": "^3.0.0 || ^4.0.0 || ^5.0.0" }, "engines": { diff --git a/code/frameworks/svelte-webpack5/package.json b/code/frameworks/svelte-webpack5/package.json index 2316a7377795..8953d61d85ce 100644 --- a/code/frameworks/svelte-webpack5/package.json +++ b/code/frameworks/svelte-webpack5/package.json @@ -59,7 +59,7 @@ }, "peerDependencies": { "@babel/core": "*", - "svelte": "^3.48.0 || ^4.0.0", + "svelte": "^4.0.0 || ^5.0.0-next.16", "svelte-loader": "*" }, "engines": { diff --git a/code/frameworks/sveltekit/README.md b/code/frameworks/sveltekit/README.md index 02f43b117710..2f2755dc91a2 100644 --- a/code/frameworks/sveltekit/README.md +++ b/code/frameworks/sveltekit/README.md @@ -185,16 +185,6 @@ export const MyStory = { You'll get this error when manually upgrading from 6.5 to 7.0. You need to remove the `svelteOptions` property in `.storybook/main.js`, as that is not supported by Storybook 7.0 + SvelteKit. The property is also not necessary anymore because the Vite and Svelte configurations are loaded automatically in Storybook 7.0. -### Error: `Cannot read properties of undefined (reading 'disable_scroll_handling')` in preview - -> Some stories don't load, instead they show the following error in the preview: -> -> ``` -> Cannot read properties of undefined (reading 'disable_scroll_handling') -> ``` - -You'll experience this if anything in your story is importing from `$app/forms` or `$app/navigation`, which is currently not supported. To get around this, separate your component into a shallow parent component that imports what's needed and passes it to a child component via props. This way you can write stories for your child component and mock any of the necessary modules by passing props in. - ## Acknowledgements Integrating with SvelteKit would not have been possible if it weren't for the fantastic efforts by the Svelte core team - especially [Ben McCann](https://twitter.com/benjaminmccann) - to make integrations with the wider ecosystem possible. diff --git a/code/frameworks/sveltekit/package.json b/code/frameworks/sveltekit/package.json index 5fc71b2414fc..305e6b709a37 100644 --- a/code/frameworks/sveltekit/package.json +++ b/code/frameworks/sveltekit/package.json @@ -64,7 +64,7 @@ "vite": "^4.0.0" }, "peerDependencies": { - "svelte": "^3.0.0 || ^4.0.0", + "svelte": "^4.0.0 || ^5.0.0-next.16", "vite": "^4.0.0" }, "engines": { diff --git a/code/frameworks/sveltekit/template/stories_svelte-kit-prerelease-ts/ButtonTypeScript.svelte b/code/frameworks/sveltekit/template/stories_svelte-kit-prerelease-ts/ButtonTypeScript.svelte new file mode 100644 index 000000000000..cd00f38a3d57 --- /dev/null +++ b/code/frameworks/sveltekit/template/stories_svelte-kit-prerelease-ts/ButtonTypeScript.svelte @@ -0,0 +1,38 @@ + + +

Button TypeScript

+ + + \ No newline at end of file diff --git a/code/frameworks/sveltekit/template/stories_svelte-kit-prerelease-ts/Hrefs.svelte b/code/frameworks/sveltekit/template/stories_svelte-kit-prerelease-ts/Hrefs.svelte new file mode 100644 index 000000000000..4e7d69e0e051 --- /dev/null +++ b/code/frameworks/sveltekit/template/stories_svelte-kit-prerelease-ts/Hrefs.svelte @@ -0,0 +1,8 @@ + diff --git a/code/frameworks/sveltekit/template/stories_svelte-kit-prerelease-ts/Navigation.svelte b/code/frameworks/sveltekit/template/stories_svelte-kit-prerelease-ts/Navigation.svelte new file mode 100644 index 000000000000..4bcb7d0e6fc9 --- /dev/null +++ b/code/frameworks/sveltekit/template/stories_svelte-kit-prerelease-ts/Navigation.svelte @@ -0,0 +1,25 @@ + + + + + + + diff --git a/code/frameworks/sveltekit/template/stories_svelte-kit-prerelease-ts/Stores.svelte b/code/frameworks/sveltekit/template/stories_svelte-kit-prerelease-ts/Stores.svelte new file mode 100644 index 000000000000..164b00f7fa8b --- /dev/null +++ b/code/frameworks/sveltekit/template/stories_svelte-kit-prerelease-ts/Stores.svelte @@ -0,0 +1,17 @@ + + +

Directly importing

+
{JSON.stringify($page, null, 2)}
+
{JSON.stringify($navigating, null, 2)}
+
{JSON.stringify($updated, null, 2)}
+ +

With getStores

+
{JSON.stringify($pageStore, null, 2)}
+
{JSON.stringify($navigatingStore, null, 2)}
+
{JSON.stringify($updatedStore, null, 2)}
diff --git a/code/frameworks/sveltekit/template/stories_svelte-kit-prerelease-ts/forms.stories.js b/code/frameworks/sveltekit/template/stories_svelte-kit-prerelease-ts/forms.stories.js new file mode 100644 index 000000000000..72b584baef76 --- /dev/null +++ b/code/frameworks/sveltekit/template/stories_svelte-kit-prerelease-ts/forms.stories.js @@ -0,0 +1,26 @@ +import { expect, fn, within } from '@storybook/test'; +import Forms from './Forms.svelte'; + +export default { + title: 'stories/sveltekit/modules/forms', + component: Forms, + tags: ['autodocs'], +}; + +const enhance = fn(); + +export const Enhance = { + async play({ canvasElement }) { + const canvas = within(canvasElement); + const button = canvas.getByText('enhance'); + button.click(); + expect(enhance).toHaveBeenCalled(); + }, + parameters: { + sveltekit_experimental: { + forms: { + enhance, + }, + }, + }, +}; diff --git a/code/frameworks/sveltekit/template/stories_svelte-kit-prerelease-ts/hrefs.stories.js b/code/frameworks/sveltekit/template/stories_svelte-kit-prerelease-ts/hrefs.stories.js new file mode 100644 index 000000000000..f1cbf4973534 --- /dev/null +++ b/code/frameworks/sveltekit/template/stories_svelte-kit-prerelease-ts/hrefs.stories.js @@ -0,0 +1,53 @@ +import { expect, fn, within } from '@storybook/test'; +import Hrefs from './Hrefs.svelte'; + +export default { + title: 'stories/sveltekit/modules/hrefs', + component: Hrefs, + tags: ['autodocs'], +}; + +export const DefaultActions = { + async play({ canvasElement }) { + const canvas = within(canvasElement); + // eslint-disable-next-line no-undef + const initialUrl = window.location.toString(); + + const basicHref = canvas.getByText('/basic-href'); + basicHref.click(); + + const complexHref = canvas.getByText( + '/deep/nested/link?with=true&multiple-params=200#and-an-id' + ); + complexHref.click(); + + // eslint-disable-next-line no-undef + const finalUrl = window.location.toString(); + expect(finalUrl).toBe(initialUrl); + }, +}; + +const basicStringMatch = fn(); +const noMatch = fn(); +const exactStringMatch = fn(); +const regexMatch = fn(); + +export const Callbacks = { + parameters: { + sveltekit_experimental: { + hrefs: { + '/basic-href': basicStringMatch, + '/basic': noMatch, + '/deep/nested/link?with=true&multiple-params=200#and-an-id': exactStringMatch, + 'nested/link\\?with': { callback: regexMatch, asRegex: true }, + }, + }, + }, + play: async (ctx) => { + await DefaultActions.play(ctx); + expect(basicStringMatch).toHaveBeenCalledTimes(1); + expect(noMatch).not.toHaveBeenCalled(); + expect(exactStringMatch).toHaveBeenCalledTimes(1); + expect(regexMatch).toHaveBeenCalledTimes(1); + }, +}; diff --git a/code/frameworks/sveltekit/template/stories_svelte-kit-prerelease-ts/navigation.stories.js b/code/frameworks/sveltekit/template/stories_svelte-kit-prerelease-ts/navigation.stories.js new file mode 100644 index 000000000000..ded12268e03c --- /dev/null +++ b/code/frameworks/sveltekit/template/stories_svelte-kit-prerelease-ts/navigation.stories.js @@ -0,0 +1,84 @@ +import { expect, fn, within } from '@storybook/test'; +import Navigation from './Navigation.svelte'; + +export default { + title: 'stories/sveltekit/modules/navigation', + component: Navigation, + tags: ['autodocs'], +}; + +const goto = fn(); + +export const Goto = { + async play({ canvasElement }) { + const canvas = within(canvasElement); + const button = canvas.getByText('goto'); + button.click(); + expect(goto).toHaveBeenCalledWith('/storybook-goto'); + }, + parameters: { + sveltekit_experimental: { + navigation: { + goto, + }, + }, + }, +}; + +export const DefaultActions = {}; + +const invalidate = fn(); + +export const Invalidate = { + async play({ canvasElement }) { + const canvas = within(canvasElement); + const button = canvas.getByText('invalidate', { exact: true }); + button.click(); + expect(invalidate).toHaveBeenCalledWith('/storybook-invalidate'); + }, + parameters: { + sveltekit_experimental: { + navigation: { + invalidate, + }, + }, + }, +}; + +const invalidateAll = fn(); + +export const InvalidateAll = { + async play({ canvasElement }) { + const canvas = within(canvasElement); + const button = canvas.getByText('invalidateAll'); + button.click(); + expect(invalidateAll).toHaveBeenCalledWith(); + }, + parameters: { + sveltekit_experimental: { + navigation: { + invalidateAll, + }, + }, + }, +}; + +const afterNavigateFn = fn(); + +export const AfterNavigate = { + async play() { + expect(afterNavigateFn).toHaveBeenCalledWith({ test: 'passed' }); + }, + args: { + afterNavigateFn, + }, + parameters: { + sveltekit_experimental: { + navigation: { + afterNavigate: { + test: 'passed', + }, + }, + }, + }, +}; diff --git a/code/frameworks/sveltekit/template/stories_svelte-kit-prerelease-ts/stores.stories.js b/code/frameworks/sveltekit/template/stories_svelte-kit-prerelease-ts/stores.stories.js new file mode 100644 index 000000000000..7f7401cf8bee --- /dev/null +++ b/code/frameworks/sveltekit/template/stories_svelte-kit-prerelease-ts/stores.stories.js @@ -0,0 +1,116 @@ +import Stores from './Stores.svelte'; + +export default { + title: 'stories/sveltekit/modules/stores', + component: Stores, + tags: ['autodocs'], +}; + +export const AllUndefined = {}; + +export const PageStore = { + parameters: { + sveltekit_experimental: { + stores: { + page: { + data: { + test: 'passed', + }, + }, + }, + }, + }, +}; + +export const NavigatingStore = { + parameters: { + sveltekit_experimental: { + stores: { + navigating: { + route: { + id: '/storybook', + }, + }, + }, + }, + }, +}; + +export const UpdatedStore = { + parameters: { + sveltekit_experimental: { + stores: { + updated: true, + }, + }, + }, +}; + +export const PageAndNavigatingStore = { + parameters: { + sveltekit_experimental: { + stores: { + page: { + data: { + test: 'passed', + }, + }, + navigating: { + route: { + id: '/storybook', + }, + }, + }, + }, + }, +}; + +export const PageAndUpdatedStore = { + parameters: { + sveltekit_experimental: { + stores: { + page: { + data: { + test: 'passed', + }, + }, + updated: true, + }, + }, + }, +}; + +export const NavigatingAndUpdatedStore = { + parameters: { + sveltekit_experimental: { + stores: { + navigating: { + route: { + id: '/storybook', + }, + }, + updated: true, + }, + }, + }, +}; + +export const AllThreeStores = { + parameters: { + sveltekit_experimental: { + stores: { + page: { + data: { + test: 'passed', + }, + }, + navigating: { + route: { + id: '/storybook', + }, + }, + updated: true, + }, + }, + }, +}; diff --git a/code/frameworks/sveltekit/template/stories_svelte-kit-prerelease-ts/ts-docs.stories.js b/code/frameworks/sveltekit/template/stories_svelte-kit-prerelease-ts/ts-docs.stories.js new file mode 100644 index 000000000000..f33428810ee9 --- /dev/null +++ b/code/frameworks/sveltekit/template/stories_svelte-kit-prerelease-ts/ts-docs.stories.js @@ -0,0 +1,12 @@ +import ButtonTypescript from './ButtonTypeScript.svelte'; + +export default { + title: 'stories/renderers/svelte/ts-docs', + component: ButtonTypescript, + args: { + primary: true, + }, + tags: ['autodocs'], +}; + +export const Primary = {}; diff --git a/code/frameworks/vue-vite/README.md b/code/frameworks/vue-vite/README.md deleted file mode 100644 index f19ebc711b42..000000000000 --- a/code/frameworks/vue-vite/README.md +++ /dev/null @@ -1,48 +0,0 @@ -# Storybook for Vue 2 and Vite - -Storybook for Vue 2 is a UI development environment for your Vue 2 components. -With it, you can visualize different states of your UI components and develop them interactively. - -![Storybook Screenshot](https://github.com/storybookjs/storybook/blob/main/media/storybook-intro.gif) - -Storybook runs outside of your app. -So you can develop UI components in isolation without worrying about app specific dependencies and requirements. - -## Getting Started - -```sh -cd my-vue-app -npx storybook@latest init -``` - -For more information visit: [storybook.js.org](https://storybook.js.org) - -## Starter Storybook-for-Vue Boilerplate project with [Vuetify](https://github.com/vuetifyjs/vuetify) Material Component Framework - - - ---- - -Storybook also comes with a lot of [addons](https://storybook.js.org/addons) and a great API to customize as you wish. -You can also build a [static version](https://storybook.js.org/docs/vue/sharing/publish-storybook) of your Storybook and deploy it anywhere you want. - -## Vue Notes - -- When using global custom components or extensions (e.g., `Vue.use`). You will need to declare those in the `./storybook/preview.js`. - -## Known Limitations - -In Storybook story and decorator components, you can not access the Vue instance -in factory functions for default prop values: - -```js -{ - props: { - foo: { - default() { - return this.bar; // does not work! - } - } - } -} -``` diff --git a/code/frameworks/vue-vite/jest.config.js b/code/frameworks/vue-vite/jest.config.js deleted file mode 100644 index 343e4c7a7f32..000000000000 --- a/code/frameworks/vue-vite/jest.config.js +++ /dev/null @@ -1,7 +0,0 @@ -const path = require('path'); -const baseConfig = require('../../jest.config.node'); - -module.exports = { - ...baseConfig, - displayName: __dirname.split(path.sep).slice(-2).join(path.posix.sep), -}; diff --git a/code/frameworks/vue-vite/package.json b/code/frameworks/vue-vite/package.json deleted file mode 100644 index 4c9f154e4fb9..000000000000 --- a/code/frameworks/vue-vite/package.json +++ /dev/null @@ -1,80 +0,0 @@ -{ - "name": "@storybook/vue-vite", - "version": "8.0.0-alpha.1", - "description": "Storybook for Vue2 and Vite: Develop Vue2 Components in isolation with Hot Reloading.", - "keywords": [ - "storybook" - ], - "homepage": "https://github.com/storybookjs/storybook/tree/next/code/frameworks/vue-vite", - "bugs": { - "url": "https://github.com/storybookjs/storybook/issues" - }, - "repository": { - "type": "git", - "url": "https://github.com/storybookjs/storybook.git", - "directory": "code/frameworks/vue-vite" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" - }, - "license": "MIT", - "exports": { - ".": { - "types": "./dist/index.d.ts", - "node": "./dist/index.js", - "require": "./dist/index.js", - "import": "./dist/index.mjs" - }, - "./preset": { - "types": "./dist/preset.d.ts", - "require": "./dist/preset.js" - }, - "./package.json": "./package.json" - }, - "main": "dist/index.js", - "module": "dist/index.mjs", - "types": "dist/index.d.ts", - "files": [ - "dist/**/*", - "README.md", - "*.js", - "*.d.ts", - "!src/**/*" - ], - "scripts": { - "check": "node --loader ../../../scripts/node_modules/esbuild-register/loader.js -r ../../../scripts/node_modules/esbuild-register/register.js ../../../scripts/prepare/check.ts", - "prep": "node --loader ../../../scripts/node_modules/esbuild-register/loader.js -r ../../../scripts/node_modules/esbuild-register/register.js ../../../scripts/prepare/bundle.ts" - }, - "dependencies": { - "@storybook/builder-vite": "workspace:*", - "@storybook/core-common": "workspace:*", - "@storybook/core-server": "workspace:*", - "@storybook/vue": "workspace:*", - "magic-string": "^0.30.0", - "vue-docgen-api": "^4.40.0" - }, - "devDependencies": { - "typescript": "^5.3.2", - "vite": "^4.0.0", - "vue": "^2.7.10" - }, - "peerDependencies": { - "vite": "^3.0.0 || ^4.0.0 || ^5.0.0", - "vue": "^2.7.0" - }, - "engines": { - "node": ">=16.0.0" - }, - "publishConfig": { - "access": "public" - }, - "bundler": { - "entries": [ - "./src/index.ts", - "./src/preset.ts" - ], - "platform": "node" - }, - "gitHead": "e6a7fd8a655c69780bc20b9749c2699e44beae17" -} diff --git a/code/frameworks/vue-vite/preset.js b/code/frameworks/vue-vite/preset.js deleted file mode 100644 index a83f95279e7f..000000000000 --- a/code/frameworks/vue-vite/preset.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require('./dist/preset'); diff --git a/code/frameworks/vue-vite/project.json b/code/frameworks/vue-vite/project.json deleted file mode 100644 index 605d4a032ab9..000000000000 --- a/code/frameworks/vue-vite/project.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "name": "@storybook/vue-vite", - "$schema": "../../node_modules/nx/schemas/project-schema.json", - "implicitDependencies": [], - "type": "library" -} diff --git a/code/frameworks/vue-vite/src/index.ts b/code/frameworks/vue-vite/src/index.ts deleted file mode 100644 index fcb073fefcd6..000000000000 --- a/code/frameworks/vue-vite/src/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './types'; diff --git a/code/frameworks/vue-vite/src/plugins/vue-docgen.ts b/code/frameworks/vue-vite/src/plugins/vue-docgen.ts deleted file mode 100644 index e80ca52d60c2..000000000000 --- a/code/frameworks/vue-vite/src/plugins/vue-docgen.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { parse } from 'vue-docgen-api'; -import type { PluginOption } from 'vite'; -import { createFilter } from 'vite'; -import MagicString from 'magic-string'; - -export function vueDocgen(): PluginOption { - const include = /\.(vue)$/; - const filter = createFilter(include); - - return { - name: 'storybook:vue2-docgen-plugin', - - async transform(src: string, id: string) { - if (!filter(id)) return undefined; - - const metaData = await parse(id); - const metaSource = JSON.stringify(metaData); - const s = new MagicString(src); - s.append(`;__component__.exports.__docgenInfo = ${metaSource}`); - - return { - code: s.toString(), - map: s.generateMap({ hires: true, source: id }), - }; - }, - }; -} diff --git a/code/frameworks/vue-vite/src/preset.ts b/code/frameworks/vue-vite/src/preset.ts deleted file mode 100644 index aec3778a7525..000000000000 --- a/code/frameworks/vue-vite/src/preset.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { dirname, join } from 'path'; -import type { PresetProperty } from '@storybook/types'; -import { mergeConfig } from 'vite'; -import type { StorybookConfig } from './types'; -import { vueDocgen } from './plugins/vue-docgen'; - -const getAbsolutePath = (input: I): I => - dirname(require.resolve(join(input, 'package.json'))) as any; - -export const core: PresetProperty<'core'> = async (config, options) => { - const framework = await options.presets.apply('framework'); - - return { - ...config, - builder: { - name: getAbsolutePath('@storybook/builder-vite'), - options: typeof framework === 'string' ? {} : framework?.options.builder || {}, - }, - renderer: getAbsolutePath('@storybook/vue'), - }; -}; - -export const viteFinal: StorybookConfig['viteFinal'] = async (config, { presets }) => { - return mergeConfig(config, { - plugins: [vueDocgen()], - resolve: { - alias: { - vue: 'vue/dist/vue.esm.js', - }, - }, - }); -}; diff --git a/code/frameworks/vue-vite/src/types.ts b/code/frameworks/vue-vite/src/types.ts deleted file mode 100644 index e5ba544f554c..000000000000 --- a/code/frameworks/vue-vite/src/types.ts +++ /dev/null @@ -1,36 +0,0 @@ -import type { StorybookConfig as StorybookConfigBase } from '@storybook/types'; -import type { StorybookConfigVite, BuilderOptions } from '@storybook/builder-vite'; - -type FrameworkName = '@storybook/vue-vite'; -type BuilderName = '@storybook/builder-vite'; - -export type FrameworkOptions = { - builder?: BuilderOptions; -}; - -type StorybookConfigFramework = { - framework: - | FrameworkName - | { - name: FrameworkName; - options: FrameworkOptions; - }; - core?: StorybookConfigBase['core'] & { - builder?: - | BuilderName - | { - name: BuilderName; - options: BuilderOptions; - }; - }; -}; - -/** - * The interface for Storybook configuration in `main.ts` files. - */ -export type StorybookConfig = Omit< - StorybookConfigBase, - keyof StorybookConfigVite | keyof StorybookConfigFramework -> & - StorybookConfigVite & - StorybookConfigFramework; diff --git a/code/frameworks/vue-vite/tsconfig.json b/code/frameworks/vue-vite/tsconfig.json deleted file mode 100644 index 1405a8fbb5a6..000000000000 --- a/code/frameworks/vue-vite/tsconfig.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "extends": "../../tsconfig.json", - "compilerOptions": { - "strict": true, - "skipLibCheck": true, - "resolveJsonModule": true - }, - "include": ["src/**/*"] -} diff --git a/code/frameworks/vue-webpack5/README.md b/code/frameworks/vue-webpack5/README.md deleted file mode 100644 index 9af5a6d0512f..000000000000 --- a/code/frameworks/vue-webpack5/README.md +++ /dev/null @@ -1,48 +0,0 @@ -# Storybook for Vue 3 and Webpack - -Storybook for Vue 3 is a UI development environment for your Vue 3 components. -With it, you can visualize different states of your UI components and develop them interactively. - -![Storybook Screenshot](https://github.com/storybookjs/storybook/blob/main/media/storybook-intro.gif) - -Storybook runs outside of your app. -So you can develop UI components in isolation without worrying about app specific dependencies and requirements. - -## Getting Started - -```sh -cd my-vue-app -npx storybook@latest init -``` - -For more information visit: [storybook.js.org](https://storybook.js.org) - -## Starter Storybook-for-Vue Boilerplate project with [Vuetify](https://github.com/vuetifyjs/vuetify) Material Component Framework - - - ---- - -Storybook also comes with a lot of [addons](https://storybook.js.org/addons) and a great API to customize as you wish. -You can also build a [static version](https://storybook.js.org/docs/vue/sharing/publish-storybook) of your Storybook and deploy it anywhere you want. - -## Vue Notes - -- When using global custom components or extensions (e.g., `Vue.use`). You will need to declare those in the `./storybook/preview.js`. - -## Known Limitations - -In Storybook story and decorator components, you can not access the Vue instance -in factory functions for default prop values: - -```js -{ - props: { - foo: { - default() { - return this.bar; // does not work! - } - } - } -} -``` diff --git a/code/frameworks/vue-webpack5/jest.config.js b/code/frameworks/vue-webpack5/jest.config.js deleted file mode 100644 index 343e4c7a7f32..000000000000 --- a/code/frameworks/vue-webpack5/jest.config.js +++ /dev/null @@ -1,7 +0,0 @@ -const path = require('path'); -const baseConfig = require('../../jest.config.node'); - -module.exports = { - ...baseConfig, - displayName: __dirname.split(path.sep).slice(-2).join(path.posix.sep), -}; diff --git a/code/frameworks/vue-webpack5/package.json b/code/frameworks/vue-webpack5/package.json deleted file mode 100644 index 6de5d46b642a..000000000000 --- a/code/frameworks/vue-webpack5/package.json +++ /dev/null @@ -1,84 +0,0 @@ -{ - "name": "@storybook/vue-webpack5", - "version": "8.0.0-alpha.1", - "description": "Storybook for Vue: Develop Vue Component in isolation with Hot Reloading.", - "keywords": [ - "storybook" - ], - "homepage": "https://github.com/storybookjs/storybook/tree/next/code/frameworks/vue-webpack5", - "bugs": { - "url": "https://github.com/storybookjs/storybook/issues" - }, - "repository": { - "type": "git", - "url": "https://github.com/storybookjs/storybook.git", - "directory": "code/frameworks/vue-webpack5" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" - }, - "license": "MIT", - "exports": { - ".": { - "types": "./dist/index.d.ts", - "node": "./dist/index.js", - "require": "./dist/index.js", - "import": "./dist/index.mjs" - }, - "./preset": { - "types": "./dist/preset.d.ts", - "require": "./dist/preset.js" - }, - "./package.json": "./package.json" - }, - "main": "dist/index.js", - "module": "dist/index.mjs", - "types": "dist/index.d.ts", - "files": [ - "dist/**/*", - "README.md", - "*.js", - "*.d.ts", - "!src/**/*" - ], - "scripts": { - "check": "node --loader ../../../scripts/node_modules/esbuild-register/loader.js -r ../../../scripts/node_modules/esbuild-register/register.js ../../../scripts/prepare/check.ts", - "prep": "node --loader ../../../scripts/node_modules/esbuild-register/loader.js -r ../../../scripts/node_modules/esbuild-register/register.js ../../../scripts/prepare/bundle.ts" - }, - "dependencies": { - "@storybook/builder-webpack5": "workspace:*", - "@storybook/core-common": "workspace:*", - "@storybook/preset-vue-webpack": "workspace:*", - "@storybook/vue": "workspace:*", - "@types/node": "^18.0.0" - }, - "devDependencies": { - "typescript": "^5.3.2", - "vue": "^2.6.12", - "vue-loader": "^15.7.0", - "vue-template-compiler": "^2.6.14" - }, - "peerDependencies": { - "@babel/core": "*", - "babel-loader": "^7.0.0 || ^8.0.0 || ^9.0.0", - "css-loader": "*", - "vue": "^2.6.8", - "vue-loader": "^15.7.0", - "vue-template-compiler": "^2.6.8" - }, - "engines": { - "node": ">=16.0.0" - }, - "publishConfig": { - "access": "public" - }, - "bundler": { - "entries": [ - "./src/index.ts", - "./src/preset.ts" - ], - "platform": "node" - }, - "gitHead": "e6a7fd8a655c69780bc20b9749c2699e44beae17" -} diff --git a/code/frameworks/vue-webpack5/preset.js b/code/frameworks/vue-webpack5/preset.js deleted file mode 100644 index a83f95279e7f..000000000000 --- a/code/frameworks/vue-webpack5/preset.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require('./dist/preset'); diff --git a/code/frameworks/vue-webpack5/project.json b/code/frameworks/vue-webpack5/project.json deleted file mode 100644 index 02735b354e6f..000000000000 --- a/code/frameworks/vue-webpack5/project.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "name": "@storybook/vue-webpack5", - "$schema": "../../node_modules/nx/schemas/project-schema.json", - "implicitDependencies": [], - "type": "library" -} diff --git a/code/frameworks/vue-webpack5/src/index.ts b/code/frameworks/vue-webpack5/src/index.ts deleted file mode 100644 index fcb073fefcd6..000000000000 --- a/code/frameworks/vue-webpack5/src/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './types'; diff --git a/code/frameworks/vue-webpack5/src/preset.ts b/code/frameworks/vue-webpack5/src/preset.ts deleted file mode 100644 index 690adc16b7c8..000000000000 --- a/code/frameworks/vue-webpack5/src/preset.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { dirname, join } from 'path'; -import type { PresetProperty } from '@storybook/types'; - -const getAbsolutePath = (input: I): I => - dirname(require.resolve(join(input, 'package.json'))) as any; - -export const addons: PresetProperty<'addons'> = [getAbsolutePath('@storybook/preset-vue-webpack')]; - -export const core: PresetProperty<'core'> = async (config, options) => { - const framework = await options.presets.apply('framework'); - - return { - ...config, - builder: { - name: getAbsolutePath('@storybook/builder-webpack5'), - options: typeof framework === 'string' ? {} : framework.options.builder || {}, - }, - renderer: getAbsolutePath('@storybook/vue'), - }; -}; - -export const typescript: PresetProperty<'typescript'> = async (config) => ({ - ...config, - skipBabel: true, - skipCompiler: true, -}); diff --git a/code/frameworks/vue-webpack5/src/types.ts b/code/frameworks/vue-webpack5/src/types.ts deleted file mode 100644 index 7a1c993d8791..000000000000 --- a/code/frameworks/vue-webpack5/src/types.ts +++ /dev/null @@ -1,45 +0,0 @@ -import type { - StorybookConfig as StorybookConfigBase, - TypescriptOptions as TypescriptOptionsReact, -} from '@storybook/preset-vue-webpack'; -import type { - StorybookConfigWebpack, - BuilderOptions, - TypescriptOptions as TypescriptOptionsBuilder, -} from '@storybook/builder-webpack5'; - -type FrameworkName = '@storybook/vue-webpack5'; -type BuilderName = '@storybook/builder-webpack5'; - -export type FrameworkOptions = { - builder?: BuilderOptions; -}; - -type StorybookConfigFramework = { - framework: - | FrameworkName - | { - name: FrameworkName; - options: FrameworkOptions; - }; - core?: StorybookConfigBase['core'] & { - builder?: - | BuilderName - | { - name: BuilderName; - options: BuilderOptions; - }; - }; - typescript?: Partial & - StorybookConfigBase['typescript']; -}; - -/** - * The interface for Storybook configuration in `main.ts` files. - */ -export type StorybookConfig = Omit< - StorybookConfigBase, - keyof StorybookConfigWebpack | keyof StorybookConfigFramework -> & - StorybookConfigWebpack & - StorybookConfigFramework; diff --git a/code/frameworks/vue-webpack5/src/typings.d.ts b/code/frameworks/vue-webpack5/src/typings.d.ts deleted file mode 100644 index 45d6411e8736..000000000000 --- a/code/frameworks/vue-webpack5/src/typings.d.ts +++ /dev/null @@ -1 +0,0 @@ -declare module 'vue-loader/lib/plugin'; diff --git a/code/frameworks/vue-webpack5/tsconfig.json b/code/frameworks/vue-webpack5/tsconfig.json deleted file mode 100644 index 1405a8fbb5a6..000000000000 --- a/code/frameworks/vue-webpack5/tsconfig.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "extends": "../../tsconfig.json", - "compilerOptions": { - "strict": true, - "skipLibCheck": true, - "resolveJsonModule": true - }, - "include": ["src/**/*"] -} diff --git a/code/lib/cli/package.json b/code/lib/cli/package.json index b7201c92e647..dd845db3b8c1 100644 --- a/code/lib/cli/package.json +++ b/code/lib/cli/package.json @@ -1,11 +1,13 @@ { "name": "@storybook/cli", "version": "8.0.0-alpha.1", - "description": "Storybook's CLI - easiest method of adding storybook to your projects", + "description": "Storybook's CLI - install, dev, build, upgrade, and more", "keywords": [ "cli", "generator", - "storybook" + "dev", + "build", + "upgrade" ], "homepage": "https://github.com/storybookjs/storybook/tree/next/code/lib/cli", "bugs": { diff --git a/code/lib/cli/src/automigrate/fixes/missing-babelrc.ts b/code/lib/cli/src/automigrate/fixes/missing-babelrc.ts index 14332f15b5f5..9d12ec658b1f 100644 --- a/code/lib/cli/src/automigrate/fixes/missing-babelrc.ts +++ b/code/lib/cli/src/automigrate/fixes/missing-babelrc.ts @@ -14,7 +14,6 @@ const logger = console; const frameworksThatNeedBabelConfig = [ '@storybook/react-webpack5', - '@storybook/vue-webpack5', '@storybook/vue3-webpack5', '@storybook/html-webpack5', '@storybook/web-components-webpack5', diff --git a/code/lib/cli/src/automigrate/fixes/new-frameworks.test.ts b/code/lib/cli/src/automigrate/fixes/new-frameworks.test.ts index 5e63d6d22fff..413ffb2f9363 100644 --- a/code/lib/cli/src/automigrate/fixes/new-frameworks.test.ts +++ b/code/lib/cli/src/automigrate/fixes/new-frameworks.test.ts @@ -258,7 +258,7 @@ describe('new-frameworks fix', () => { it('should update correctly when there is no builder', async () => { const packageManager = getPackageManager({ - '@storybook/vue': '7.0.0', + '@storybook/vue3': '7.0.0', '@storybook/builder-webpack5': '7.0.0', }); @@ -266,13 +266,13 @@ describe('new-frameworks fix', () => { checkNewFrameworks({ packageManager, main: { - framework: '@storybook/vue', + framework: '@storybook/vue3', }, }) ).resolves.toEqual( expect.objectContaining({ - frameworkPackage: '@storybook/vue-webpack5', - dependenciesToAdd: ['@storybook/vue-webpack5'], + frameworkPackage: '@storybook/vue3-webpack5', + dependenciesToAdd: ['@storybook/vue3-webpack5'], dependenciesToRemove: ['@storybook/builder-webpack5'], }) ); @@ -280,7 +280,7 @@ describe('new-frameworks fix', () => { it('should update when there is no framework field in main', async () => { const packageManager = getPackageManager({ - '@storybook/vue': '7.0.0', + '@storybook/vue3': '7.0.0', '@storybook/manager-webpack5': '7.0.0', }); @@ -291,8 +291,8 @@ describe('new-frameworks fix', () => { }) ).resolves.toEqual( expect.objectContaining({ - frameworkPackage: '@storybook/vue-webpack5', - dependenciesToAdd: ['@storybook/vue-webpack5'], + frameworkPackage: '@storybook/vue3-webpack5', + dependenciesToAdd: ['@storybook/vue3-webpack5'], dependenciesToRemove: ['@storybook/manager-webpack5'], hasFrameworkInMainConfig: false, }) @@ -301,7 +301,7 @@ describe('new-frameworks fix', () => { it('should update when the framework field has a legacy value', async () => { const packageManager = getPackageManager({ - '@storybook/vue': '7.0.0', + '@storybook/vue3': '7.0.0', '@storybook/manager-webpack5': '7.0.0', }); @@ -309,13 +309,13 @@ describe('new-frameworks fix', () => { checkNewFrameworks({ packageManager, main: { - framework: 'vue', + framework: 'vue3', }, }) ).resolves.toEqual( expect.objectContaining({ - frameworkPackage: '@storybook/vue-webpack5', - dependenciesToAdd: ['@storybook/vue-webpack5'], + frameworkPackage: '@storybook/vue3-webpack5', + dependenciesToAdd: ['@storybook/vue3-webpack5'], dependenciesToRemove: ['@storybook/manager-webpack5'], hasFrameworkInMainConfig: false, }) diff --git a/code/lib/cli/src/automigrate/helpers/mainConfigFile.test.ts b/code/lib/cli/src/automigrate/helpers/mainConfigFile.test.ts index 1d1d4c2095ac..5320d97e5dac 100644 --- a/code/lib/cli/src/automigrate/helpers/mainConfigFile.test.ts +++ b/code/lib/cli/src/automigrate/helpers/mainConfigFile.test.ts @@ -146,8 +146,8 @@ describe('getRendererPackageNameFromFramework', () => { }); it('should return the corresponding key of rendererPackages if the value is the same as the frameworkPackageName', () => { - const frameworkPackageName = 'vue'; - const expectedPackageName = '@storybook/vue'; + const frameworkPackageName = 'vue3'; + const expectedPackageName = '@storybook/vue3'; const packageName = getRendererPackageNameFromFramework(frameworkPackageName); expect(packageName).toBe(expectedPackageName); }); diff --git a/code/lib/cli/src/automigrate/helpers/new-frameworks-utils.ts b/code/lib/cli/src/automigrate/helpers/new-frameworks-utils.ts index e5fba48f2d71..7f62392c6839 100644 --- a/code/lib/cli/src/automigrate/helpers/new-frameworks-utils.ts +++ b/code/lib/cli/src/automigrate/helpers/new-frameworks-utils.ts @@ -24,10 +24,6 @@ export const packagesMap: Record = '@storybook/angular': { webpack5: '@storybook/angular', }, - '@storybook/vue': { - webpack5: '@storybook/vue-webpack5', - vite: '@storybook/vue-vite', - }, '@storybook/vue3': { webpack5: '@storybook/vue3-webpack5', vite: '@storybook/vue3-vite', diff --git a/code/lib/cli/src/detect.test.ts b/code/lib/cli/src/detect.test.ts index 7a78fa8fa536..1203d444e6d8 100644 --- a/code/lib/cli/src/detect.test.ts +++ b/code/lib/cli/src/detect.test.ts @@ -30,29 +30,6 @@ const MOCK_FRAMEWORK_FILES: { name: string; files: Record<'package.json', PackageJsonWithMaybeDeps> | Record; }[] = [ - { - name: ProjectType.SFC_VUE, - files: { - 'package.json': { - dependencies: { - vuetify: '1.0.0', - }, - devDependencies: { - 'vue-loader': '1.0.0', - }, - }, - }, - }, - { - name: ProjectType.VUE, - files: { - 'package.json': { - dependencies: { - vue: '1.0.0', - }, - }, - }, - }, { name: ProjectType.VUE3, files: { diff --git a/code/lib/cli/src/detect.ts b/code/lib/cli/src/detect.ts index dc02fbe4325b..733ed65e2974 100644 --- a/code/lib/cli/src/detect.ts +++ b/code/lib/cli/src/detect.ts @@ -127,8 +127,6 @@ export async function detectBuilder(packageManager: JsPackageManager, projectTyp // Fallback to Vite or Webpack based on project type switch (projectType) { - case ProjectType.SFC_VUE: - return CoreBuilder.Vite; case ProjectType.REACT_SCRIPTS: case ProjectType.ANGULAR: case ProjectType.REACT_NATIVE: // technically react native doesn't use webpack, we just want to set something diff --git a/code/lib/cli/src/generate.ts b/code/lib/cli/src/generate.ts index bc396ec428b7..2594863f0e90 100644 --- a/code/lib/cli/src/generate.ts +++ b/code/lib/cli/src/generate.ts @@ -223,6 +223,7 @@ command('dev') ) .option('--force-build-preview', 'Build the preview iframe even if you are using --preview-url') .option('--docs', 'Build a documentation-only site using addon-docs') + .option('--exact-port', 'Exit early if the desired port is not available') .option( '--initial-path [path]', 'URL path to be appended when visiting Storybook for the first time' diff --git a/code/lib/cli/src/generators/SFC_VUE/index.ts b/code/lib/cli/src/generators/SFC_VUE/index.ts deleted file mode 100644 index a3e2f15ea604..000000000000 --- a/code/lib/cli/src/generators/SFC_VUE/index.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { CoreBuilder } from '../../project_types'; -import { baseGenerator } from '../baseGenerator'; -import type { Generator } from '../types'; - -const generator: Generator = async (packageManager, npmOptions, options) => { - await baseGenerator(packageManager, npmOptions, options, 'vue', { - useSWC: ({ builder }) => builder === CoreBuilder.Webpack5, - }); -}; - -export default generator; diff --git a/code/lib/cli/src/generators/VUE/index.ts b/code/lib/cli/src/generators/VUE/index.ts deleted file mode 100644 index 6b771973a283..000000000000 --- a/code/lib/cli/src/generators/VUE/index.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { CoreBuilder } from '../../project_types'; -import { baseGenerator } from '../baseGenerator'; -import type { Generator } from '../types'; - -const generator: Generator = async (packageManager, npmOptions, options) => { - await baseGenerator(packageManager, npmOptions, options, 'vue', { - extraPackages: async ({ builder }) => { - return builder === CoreBuilder.Webpack5 ? ['vue-loader@^15.7.0'] : []; - }, - useSWC: ({ builder }) => builder === CoreBuilder.Webpack5, - }); -}; - -export default generator; diff --git a/code/lib/cli/src/generators/baseGenerator.ts b/code/lib/cli/src/generators/baseGenerator.ts index 813ba2d1dd59..43fbbe9c3a67 100644 --- a/code/lib/cli/src/generators/baseGenerator.ts +++ b/code/lib/cli/src/generators/baseGenerator.ts @@ -337,7 +337,6 @@ export async function baseGenerator( if (builder !== CoreBuilder.Vite && !skipBabel) { const frameworksThatNeedBabelConfig = [ '@storybook/react-webpack5', - '@storybook/vue-webpack5', '@storybook/vue3-webpack5', '@storybook/html-webpack5', '@storybook/web-components-webpack5', diff --git a/code/lib/cli/src/helpers.ts b/code/lib/cli/src/helpers.ts index 605fab2d1849..33c7b6c6ccd9 100644 --- a/code/lib/cli/src/helpers.ts +++ b/code/lib/cli/src/helpers.ts @@ -193,7 +193,10 @@ type CopyTemplateFilesOptions = { destination?: string; }; -const frameworkToRenderer: Record = { +const frameworkToRenderer: Record< + SupportedFrameworks | SupportedRenderers, + SupportedRenderers | 'vue' +> = { angular: 'angular', ember: 'ember', html: 'html', @@ -206,7 +209,6 @@ const frameworkToRenderer: Record( commandLog('Adding Storybook support to your "Next" app') ); - case ProjectType.SFC_VUE: - return sfcVueGenerator(packageManager, npmOptions, generatorOptions).then( - commandLog('Adding Storybook support to your "Single File Components Vue" app') - ); - - case ProjectType.VUE: - return vueGenerator(packageManager, npmOptions, generatorOptions).then( - commandLog('Adding Storybook support to your "Vue" app') - ); - case ProjectType.VUE3: return vue3Generator(packageManager, npmOptions, generatorOptions).then( commandLog('Adding Storybook support to your "Vue 3" app') @@ -234,45 +223,6 @@ const projectTypeInquirer = async ( process.exit(0); }; -const getEmptyDirMessage = (packageManagerType: PackageManagerName) => { - const generatorCommandsMap = { - vite: { - npm: 'npm create vite@latest', - yarn1: 'yarn create vite', - yarn2: 'yarn create vite', - pnpm: 'pnpm create vite', - }, - angular: { - npm: 'npx -p @angular/cli ng new my-project --package-manager=npm', - yarn1: 'npx -p @angular/cli ng new my-project --package-manager=yarn', - yarn2: 'npx -p @angular/cli ng new my-project --package-manager=yarn', - pnpm: 'npx -p @angular/cli ng new my-project --package-manager=pnpm', - }, - }; - - return dedent` - Storybook cannot be installed into an empty project. We recommend creating a new project with the following: - - πŸ“¦ Vite CLI for React/Vue/Web Components => ${chalk.green( - generatorCommandsMap.vite[packageManagerType] - )} - See ${chalk.yellowBright('https://vitejs.dev/guide/#scaffolding-your-first-vite-project')} - - πŸ“¦ Angular CLI => ${chalk.green(generatorCommandsMap.angular[packageManagerType])} - See ${chalk.yellowBright('https://angular.io/cli/new')} - - πŸ“¦ Any other tooling of your choice - - Once you've created a project, please re-run ${chalk.green( - 'npx storybook@latest init' - )} inside the project root. For more information, see ${chalk.yellowBright( - 'https://storybook.js.org/docs' - )} - - Good luck! πŸš€ - `; -}; - async function doInitiate( options: CommandOptions, pkg: PackageJson @@ -292,11 +242,10 @@ async function doInitiate( pkgMgr = 'npm'; } - const cwdFolderEntries = readdirSync(process.cwd()); - const isEmptyDir = - cwdFolderEntries.length === 0 || cwdFolderEntries.every((entry) => entry.startsWith('.')); + const packageManager = JsPackageManagerFactory.getPackageManager({ + force: pkgMgr, + }); - const packageManager = JsPackageManagerFactory.getPackageManager({ force: pkgMgr }); const welcomeMessage = 'storybook init - the simplest way to add a Storybook to your project.'; logger.log(chalk.inverse(`\n ${welcomeMessage} \n`)); @@ -307,15 +256,16 @@ async function doInitiate( updateCheckInterval: 1000 * 60 * 60, // every hour (we could increase this later on.) }); - if (options.force !== true && isEmptyDir) { - logger.log( - boxen(getEmptyDirMessage(packageManager.type), { - borderStyle: 'round', - padding: 1, - borderColor: '#F1618C', - }) - ); - throw new HandledError('Project was initialized in an empty directory.'); + // Check if the current directory is empty. + if (options.force !== true && currentDirectoryIsEmpty(packageManager.type)) { + // Prompt the user to create a new project from our list. + await scaffoldNewProject(packageManager.type, options); + + if (process.env.IN_STORYBOOK_SANDBOX === 'true' || process.env.CI === 'true') { + packageManager.addPackageResolutions({ + '@storybook/telemetry': versions['@storybook/telemetry'], + }); + } } let projectType: ProjectType; @@ -398,6 +348,7 @@ async function doInitiate( projectType === ProjectType.ANGULAR ? `ng run ${installResult.projectName}:storybook` : packageManager.getRunStorybookCommand(); + logger.log( boxen( dedent` diff --git a/code/lib/cli/src/js-package-manager/JsPackageManagerFactory.test.ts b/code/lib/cli/src/js-package-manager/JsPackageManagerFactory.test.ts index 4567987488ef..7e12ac20de6b 100644 --- a/code/lib/cli/src/js-package-manager/JsPackageManagerFactory.test.ts +++ b/code/lib/cli/src/js-package-manager/JsPackageManagerFactory.test.ts @@ -13,20 +13,26 @@ const spawnSyncMock = spawnSync as jest.Mock; jest.mock('find-up'); const findUpSyncMock = findUpSync as unknown as jest.Mock; -describe('JsPackageManagerFactory', () => { +describe('CLASS: JsPackageManagerFactory', () => { beforeEach(() => { findUpSyncMock.mockReturnValue(undefined); + delete process.env.npm_config_user_agent; }); - describe('getPackageManager', () => { - describe('return an NPM proxy', () => { - it('when `force` option is `npm`', () => { + describe('METHOD: getPackageManager', () => { + describe('NPM proxy', () => { + it('FORCE: it should return a NPM proxy when `force` option is `npm`', () => { expect(JsPackageManagerFactory.getPackageManager({ force: 'npm' })).toBeInstanceOf( NPMProxy ); }); - it('when all package managers are ok, but only a `package-lock.json` file', () => { + it('USER AGENT: it should infer npm from the user agent', () => { + process.env.npm_config_user_agent = 'npm/7.24.0'; + expect(JsPackageManagerFactory.getPackageManager()).toBeInstanceOf(NPMProxy); + }); + + it('ALL EXIST: when all package managers are ok, but only a `package-lock.json` file is found', () => { spawnSyncMock.mockImplementation((command) => { // Yarn is ok if (command === 'yarn') { @@ -62,14 +68,19 @@ describe('JsPackageManagerFactory', () => { }); }); - describe('return a PNPM proxy', () => { - it('when `force` option is `pnpm`', () => { + describe('PNPM proxy', () => { + it('FORCE: it should return a PNPM proxy when `force` option is `pnpm`', () => { expect(JsPackageManagerFactory.getPackageManager({ force: 'pnpm' })).toBeInstanceOf( PNPMProxy ); }); - it('when all package managers are ok, but only a `pnpm-lock.yaml` file', () => { + it('USER AGENT: it should infer pnpm from the user agent', () => { + process.env.npm_config_user_agent = 'pnpm/7.4.0'; + expect(JsPackageManagerFactory.getPackageManager()).toBeInstanceOf(PNPMProxy); + }); + + it('ALL EXIST: when all package managers are ok, but only a `pnpm-lock.yaml` file is found', () => { spawnSyncMock.mockImplementation((command) => { // Yarn is ok if (command === 'yarn') { @@ -104,7 +115,7 @@ describe('JsPackageManagerFactory', () => { expect(JsPackageManagerFactory.getPackageManager()).toBeInstanceOf(PNPMProxy); }); - it('when a pnpm-lock.yaml file is closer than a yarn.lock', () => { + it('PNPM LOCK IF CLOSER: when a pnpm-lock.yaml file is closer than a yarn.lock', () => { // Allow find-up to work as normal, we'll set the cwd to our fixture package findUpSyncMock.mockImplementation(jest.requireActual('find-up').sync); @@ -140,13 +151,18 @@ describe('JsPackageManagerFactory', () => { }); }); - describe('return a Yarn 1 proxy', () => { - it('when `force` option is `yarn1`', () => { + describe('Yarn 1 proxy', () => { + it('FORCE: it should return a Yarn1 proxy when `force` option is `yarn1`', () => { expect(JsPackageManagerFactory.getPackageManager({ force: 'yarn1' })).toBeInstanceOf( Yarn1Proxy ); }); + it('USER AGENT: it should infer yarn1 from the user agent', () => { + process.env.npm_config_user_agent = 'yarn/1.22.11'; + expect(JsPackageManagerFactory.getPackageManager()).toBeInstanceOf(Yarn1Proxy); + }); + it('when Yarn command is ok, Yarn version is <2, NPM is ko, PNPM is ko', () => { spawnSyncMock.mockImplementation((command) => { // Yarn is ok @@ -251,14 +267,19 @@ describe('JsPackageManagerFactory', () => { }); }); - describe('return a Yarn 2 proxy', () => { - it('when `force` option is `yarn2`', () => { + describe('Yarn 2 proxy', () => { + it('FORCE: it should return a Yarn2 proxy when `force` option is `yarn2`', () => { expect(JsPackageManagerFactory.getPackageManager({ force: 'yarn2' })).toBeInstanceOf( Yarn2Proxy ); }); - it('when Yarn command is ok, Yarn version is >=2, NPM is ko, PNPM is ko', () => { + it('USER AGENT: it should infer yarn2 from the user agent', () => { + process.env.npm_config_user_agent = 'yarn/2.2.10'; + expect(JsPackageManagerFactory.getPackageManager()).toBeInstanceOf(Yarn2Proxy); + }); + + it('ONLY YARN 2: when Yarn command is ok, Yarn version is >=2, NPM is ko, PNPM is ko', () => { spawnSyncMock.mockImplementation((command) => { // Yarn is ok if (command === 'yarn') { diff --git a/code/lib/cli/src/js-package-manager/JsPackageManagerFactory.ts b/code/lib/cli/src/js-package-manager/JsPackageManagerFactory.ts index 77986fd0c038..b6a6ea297956 100644 --- a/code/lib/cli/src/js-package-manager/JsPackageManagerFactory.ts +++ b/code/lib/cli/src/js-package-manager/JsPackageManagerFactory.ts @@ -14,24 +14,29 @@ const NPM_LOCKFILE = 'package-lock.json'; const PNPM_LOCKFILE = 'pnpm-lock.yaml'; const YARN_LOCKFILE = 'yarn.lock'; +type PackageManagerProxy = + | typeof NPMProxy + | typeof PNPMProxy + | typeof Yarn1Proxy + | typeof Yarn2Proxy; + export class JsPackageManagerFactory { public static getPackageManager( { force }: { force?: PackageManagerName } = {}, cwd?: string ): JsPackageManager { - if (force === 'npm') { - return new NPMProxy({ cwd }); - } - if (force === 'pnpm') { - return new PNPMProxy({ cwd }); - } - if (force === 'yarn1') { - return new Yarn1Proxy({ cwd }); + // Option 1: If the user has provided a forcing flag, we use it + if (force && force in this.PROXY_MAP) { + return new this.PROXY_MAP[force]({ cwd }); } - if (force === 'yarn2') { - return new Yarn2Proxy({ cwd }); + + // Option 2: If the user is running a command via npx/pnpx/yarn create/etc, we infer the package manager from the command + const inferredPackageManager = this.inferPackageManagerFromUserAgent(); + if (inferredPackageManager && inferredPackageManager in this.PROXY_MAP) { + return new this.PROXY_MAP[inferredPackageManager]({ cwd }); } + // Option 3: We try to infer the package manager from the closest lockfile const yarnVersion = getYarnVersion(cwd); const closestLockfilePath = findUpSync([YARN_LOCKFILE, PNPM_LOCKFILE, NPM_LOCKFILE], { @@ -56,6 +61,43 @@ export class JsPackageManagerFactory { throw new Error('Unable to find a usable package manager within NPM, PNPM, Yarn and Yarn 2'); } + + /** + * Look up map of package manager proxies by name + */ + private static PROXY_MAP: Record = { + npm: NPMProxy, + pnpm: PNPMProxy, + yarn1: Yarn1Proxy, + yarn2: Yarn2Proxy, + }; + + /** + * Infer the package manager based on the command the user is running. + * Each package manager sets the `npm_config_user_agent` environment variable with its name and version e.g. "npm/7.24.0" + * Which is really useful when invoking commands via npx/pnpx/yarn create/etc. + */ + private static inferPackageManagerFromUserAgent(): PackageManagerName | undefined { + const userAgent = process.env.npm_config_user_agent; + if (userAgent) { + const packageSpec = userAgent.split(' ')[0]; + const [pkgMgrName, pkgMgrVersion] = packageSpec.split('/'); + + if (pkgMgrName === 'pnpm') { + return 'pnpm'; + } + + if (pkgMgrName === 'npm') { + return 'npm'; + } + + if (pkgMgrName === 'yarn') { + return `yarn${pkgMgrVersion?.startsWith('1.') ? '1' : '2'}`; + } + } + + return undefined; + } } function hasNPM(cwd?: string) { diff --git a/code/lib/cli/src/project_types.ts b/code/lib/cli/src/project_types.ts index 8d2809f97379..8f1f07b3ae0f 100644 --- a/code/lib/cli/src/project_types.ts +++ b/code/lib/cli/src/project_types.ts @@ -1,13 +1,5 @@ import { minVersion, validRange } from 'semver'; -function ltMajor(versionRange: string, major: number) { - // Uses validRange to avoid a throw from minVersion if an invalid range gets passed - if (validRange(versionRange)) { - return (minVersion(versionRange)?.major ?? Infinity) < major; - } - return false; -} - function eqMajor(versionRange: string, major: number) { // Uses validRange to avoid a throw from minVersion if an invalid range gets passed if (validRange(versionRange)) { @@ -36,7 +28,6 @@ export type SupportedFrameworks = 'nextjs' | 'angular' | 'sveltekit' | 'qwik' | export type SupportedRenderers = | 'react' | 'react-native' - | 'vue' | 'vue3' | 'angular' | 'ember' @@ -51,7 +42,6 @@ export type SupportedRenderers = export const SUPPORTED_RENDERERS: SupportedRenderers[] = [ 'react', 'react-native', - 'vue', 'vue3', 'angular', 'ember', @@ -70,9 +60,7 @@ export enum ProjectType { REACT_PROJECT = 'REACT_PROJECT', WEBPACK_REACT = 'WEBPACK_REACT', NEXTJS = 'NEXTJS', - VUE = 'VUE', VUE3 = 'VUE3', - SFC_VUE = 'SFC_VUE', ANGULAR = 'ANGULAR', EMBER = 'EMBER', WEB_COMPONENTS = 'WEB_COMPONENTS', @@ -123,27 +111,6 @@ export type TemplateConfiguration = { * therefore WEBPACK_REACT has to come first, as it's more specific. */ export const supportedTemplates: TemplateConfiguration[] = [ - { - preset: ProjectType.SFC_VUE, - dependencies: { - 'vue-loader': (versionRange) => ltMajor(versionRange, 16), - vuetify: (versionRange) => ltMajor(versionRange, 3), - }, - matcherFunction: ({ dependencies }) => { - return dependencies?.some(Boolean) ?? false; - }, - }, - { - preset: ProjectType.VUE, - // This Vue template only works with Vue or Nuxt under v3 - dependencies: { - vue: (versionRange) => ltMajor(versionRange, 3), - nuxt: (versionRange) => ltMajor(versionRange, 3), - }, - matcherFunction: ({ dependencies }) => { - return dependencies?.some(Boolean) ?? false; - }, - }, { preset: ProjectType.VUE3, dependencies: { diff --git a/code/lib/cli/src/repro-generators/configs.ts b/code/lib/cli/src/repro-generators/configs.ts index b3cd46836fbf..b95e65a18a87 100644 --- a/code/lib/cli/src/repro-generators/configs.ts +++ b/code/lib/cli/src/repro-generators/configs.ts @@ -217,16 +217,6 @@ export const web_components_lit2: Parameters = { // #region vue -export const vue: Parameters = { - renderer: 'vue', - name: 'vue', - version: 'latest', - generator: [ - // vue2 with webpack5 - `npx -p @vue/cli vue create {{appName}} --default --packageManager=yarn --force --merge --preset="Default (Vue 2)"`, - ].join(' && '), -}; - export const vue3: Parameters = { renderer: 'vue3', name: 'vue3', @@ -263,14 +253,6 @@ export const preact_vite: Parameters = { generator: 'yarn create vite@{{version}} {{appName}} --template preact', }; -export const sfcVue: Parameters = { - renderer: 'vue', - name: 'sfcVue', - version: 'latest', - // - generator: fromDeps('vue@2.6', 'vue-loader@15.9', 'vue-template-compiler@2.6', 'webpack'), -}; - export const svelte: Parameters = { renderer: 'svelte', name: 'svelte', diff --git a/code/lib/cli/src/sandbox-templates.ts b/code/lib/cli/src/sandbox-templates.ts index 6aeed1d585a3..e2046abb8b6f 100644 --- a/code/lib/cli/src/sandbox-templates.ts +++ b/code/lib/cli/src/sandbox-templates.ts @@ -31,6 +31,10 @@ export type Template = { * This is used to generate projects which are pushed to https://github.com/storybookjs/sandboxes */ script: string; + /** + * Environment variables to set when running the script. + */ + env?: Record; /** * Used to assert various things about the generated template. * If the template is generated with a different expected framework, it will fail, detecting a possible regression. @@ -257,17 +261,6 @@ const baseTemplates = { }, skipTasks: ['e2e-tests-dev', 'bench'], }, - 'vue2-vite/2.7-js': { - name: 'Vue v2 (Vite | JavaScript)', - script: 'npx create-vue@2 {{beforeDir}} --default', - expected: { - framework: '@storybook/vue-vite', - renderer: '@storybook/vue', - builder: '@storybook/builder-vite', - }, - // Remove smoke-test from the list once https://github.com/storybookjs/storybook/issues/19351 is fixed. - skipTasks: ['smoke-test', 'e2e-tests-dev', 'bench'], - }, 'html-webpack/default': { name: 'HTML Latest (Webpack | JavaScript)', script: 'yarn create webpack5-html {{beforeDir}}', @@ -376,6 +369,17 @@ const baseTemplates = { }, skipTasks: ['e2e-tests-dev', 'bench'], }, + 'svelte-kit/prerelease-ts': { + name: 'SvelteKit Prerelease (Vite | TypeScript)', + script: + 'yarn create svelte-with-args --name=svelte-kit/prerelease-ts --directory={{beforeDir}} --template=skeleton --types=typescript --no-prettier --no-eslint --no-playwright --no-vitest --svelte5', + expected: { + framework: '@storybook/sveltekit', + renderer: '@storybook/svelte', + builder: '@storybook/builder-vite', + }, + skipTasks: ['e2e-tests-dev', 'bench'], + }, 'lit-vite/default-js': { name: 'Lit Latest (Vite | JavaScript)', script: @@ -412,18 +416,6 @@ const baseTemplates = { // Remove smoke-test from the list once https://github.com/storybookjs/storybook/issues/19351 is fixed. skipTasks: ['smoke-test', 'e2e-tests-dev', 'bench'], }, - 'vue-cli/vue2-default-js': { - name: 'Vue CLI v2 (Webpack | JavaScript)', - script: - 'npx -p @vue/cli vue create {{beforeDir}} --default --packageManager=yarn --force --merge --preset="Default (Vue 2)" && cd {{beforeDir}} && echo "module.exports = {}" > webpack.config.js', - expected: { - framework: '@storybook/vue-webpack5', - renderer: '@storybook/vue', - builder: '@storybook/builder-webpack5', - }, - // Remove smoke-test from the list once https://github.com/storybookjs/storybook/issues/19351 is fixed. - skipTasks: ['smoke-test', 'e2e-tests-dev', 'bench'], - }, 'preact-webpack5/default-js': { name: 'Preact CLI Latest (Webpack | JavaScript)', script: @@ -588,7 +580,6 @@ export const normal: TemplateKey[] = [ 'react-vite/default-ts', 'angular-cli/default-ts', 'vue3-vite/default-ts', - 'vue-cli/vue2-default-js', 'lit-vite/default-ts', 'svelte-vite/default-ts', 'svelte-kit/skeleton-ts', @@ -599,6 +590,7 @@ export const normal: TemplateKey[] = [ 'bench/react-vite-default-ts-test-build', 'bench/react-webpack-18-ts-test-build', ]; + export const merged: TemplateKey[] = [ ...normal, 'react-webpack/18-ts', @@ -609,13 +601,13 @@ export const merged: TemplateKey[] = [ 'html-webpack/default', 'html-vite/default-ts', ]; + export const daily: TemplateKey[] = [ ...merged, 'angular-cli/prerelease', 'cra/default-js', 'react-vite/default-js', 'vue3-vite/default-js', - 'vue2-vite/2.7-js', 'vue-cli/default-js', 'lit-vite/default-js', 'svelte-kit/skeleton-js', diff --git a/code/lib/cli/src/scaffold-new-project.ts b/code/lib/cli/src/scaffold-new-project.ts new file mode 100644 index 000000000000..d33d82a32d7a --- /dev/null +++ b/code/lib/cli/src/scaffold-new-project.ts @@ -0,0 +1,239 @@ +import boxen from 'boxen'; +import chalk from 'chalk'; +import execa from 'execa'; +import { readdirSync, remove } from 'fs-extra'; +import prompts from 'prompts'; +import dedent from 'ts-dedent'; + +import { telemetry } from '@storybook/telemetry'; + +import { GenerateNewProjectOnInitError } from '@storybook/core-events/server-errors'; +import { logger } from '@storybook/node-logger'; + +import type { PackageManagerName } from './js-package-manager'; +import type { CommandOptions } from './generators/types'; + +type CoercedPackageManagerName = 'npm' | 'yarn' | 'pnpm'; + +interface SupportedProject { + displayName: { + type: string; + builder?: string; + language: string; + }; + createScript: Record; +} + +/** + * The supported projects. + */ +const SUPPORTED_PROJECTS: Record = { + 'react-vite-ts': { + displayName: { + type: 'React', + builder: 'Vite', + language: 'TS', + }, + createScript: { + npm: 'npm create vite@latest . -- --template react-ts', + yarn: 'yarn create vite@latest . --template react-ts', + pnpm: 'pnpm create vite@latest . --template react-ts', + }, + }, + 'nextjs-ts': { + displayName: { + type: 'Next.js', + language: 'TS', + }, + createScript: { + npm: 'npm create next-app . -- --typescript --use-npm --eslint --tailwind --no-app --import-alias="@/*" --src-dir', + yarn: 'yarn create next-app . --typescript --use-yarn --eslint --tailwind --no-app --import-alias="@/*" --src-dir', + pnpm: 'pnpm create next-app . --typescript --use-pnpm --eslint --tailwind --no-app --import-alias="@/*" --src-dir', + }, + }, + 'vue-vite-ts': { + displayName: { + type: 'Vue 3', + builder: 'Vite', + language: 'TS', + }, + createScript: { + npm: 'npm create vite@latest . -- --template vue-ts', + yarn: 'yarn create vite@latest . --template vue-ts', + pnpm: 'pnpm create vite@latest . --template vue-ts', + }, + }, + 'angular-cli': { + displayName: { + type: 'Angular', + language: 'TS', + }, + createScript: { + npm: 'npx -p @angular/cli@latest ng new angular-latest --directory . --routing=true --minimal=true --style=scss --strict --skip-git --skip-install', + yarn: 'yarn dlx -p @angular/cli ng new angular-latest --directory . --routing=true --minimal=true --style=scss --strict --skip-git --package-manager=yarn --skip-install && touch yarn.lock && yarn set version berry && yarn config set nodeLinker node-modules', + pnpm: 'pnpm --package @angular/cli dlx ng new angular-latest --directory . --routing=true --minimal=true --style=scss --strict --skip-git --package-manager=pnpm --skip-install', + }, + }, + 'lit-vite-ts': { + displayName: { + type: 'Lit', + builder: 'Vite', + language: 'TS', + }, + createScript: { + npm: 'npm create vite@latest . -- --template lit-ts', + yarn: 'yarn create vite@latest . --template lit-ts && touch yarn.lock && yarn set version berry && yarn config set nodeLinker pnp', + pnpm: 'pnpm create vite@latest . --template lit-ts', + }, + }, +}; + +const packageManagerToCoercedName = ( + packageManager: PackageManagerName +): CoercedPackageManagerName => { + switch (packageManager) { + case 'npm': + return 'npm'; + case 'pnpm': + return 'pnpm'; + default: + return 'yarn'; + } +}; + +const buildProjectDisplayNameForPrint = ({ displayName }: SupportedProject) => { + const { type, builder, language } = displayName; + return `${chalk.bold.blue(type)} ${builder ? `+ ${builder} ` : ''}(${language})`; +}; + +/** + * Scaffold a new project. + * + * @param packageManager The package manager to use. + */ +export const scaffoldNewProject = async ( + packageManager: PackageManagerName, + { disableTelemetry }: CommandOptions +) => { + const packageManagerName = packageManagerToCoercedName(packageManager); + + logger.plain( + boxen( + dedent` + Would you like to generate a new project from the following list? + + ${chalk.bold('Note:')} + Storybook supports many more frameworks and bundlers than listed below. If you don't see your + preferred setup, you can still generate a project then rerun this command to add Storybook. + + ${chalk.bold('Press ^C at any time to quit.')} + `, + { + title: chalk.bold('πŸ”Ž Empty directory detected'), + padding: 1, + borderStyle: 'double', + borderColor: 'yellow', + } + ) + ); + logger.line(1); + + let projectStrategy; + + if (process.env.STORYBOOK_INIT_EMPTY_TYPE) { + projectStrategy = process.env.STORYBOOK_INIT_EMPTY_TYPE; + } + + if (!projectStrategy) { + const { project } = await prompts( + { + type: 'select', + name: 'project', + message: 'Choose a project template', + choices: Object.entries(SUPPORTED_PROJECTS).map(([key, value]) => ({ + title: buildProjectDisplayNameForPrint(value), + value: key, + })), + }, + { onCancel: () => process.exit(0) } + ); + + projectStrategy = project; + } + + const projectStrategyConfig = SUPPORTED_PROJECTS[projectStrategy]; + const projectDisplayName = buildProjectDisplayNameForPrint(projectStrategyConfig); + const createScript = projectStrategyConfig.createScript[packageManagerName]; + + logger.line(1); + logger.plain( + `Creating a new "${projectDisplayName}" project with ${chalk.bold(packageManagerName)}...` + ); + logger.line(1); + + const targetDir = process.cwd(); + + try { + // If target directory has a .cache folder, remove it + // so that it does not block the creation of the new project + await remove(`${targetDir}/.cache`); + + // Create new project in temp directory + await execa.command(createScript, { + stdio: 'pipe', + shell: true, + cwd: targetDir, + cleanup: true, + }); + } catch (e) { + throw new GenerateNewProjectOnInitError({ + error: e, + packageManager: packageManagerName, + projectType: projectStrategy, + }); + } + + if (!disableTelemetry) { + telemetry('scaffolded-empty', { + packageManager: packageManagerName, + projectType: projectStrategy, + }); + } + + logger.plain( + boxen( + dedent` + "${projectDisplayName}" project with ${chalk.bold(packageManagerName)} created successfully! + + Continuing with Storybook installation... + `, + { + title: chalk.bold('βœ… Success!'), + padding: 1, + borderStyle: 'double', + borderColor: 'green', + } + ) + ); + logger.line(1); +}; + +const BASE_IGNORED_FILES = ['.git', '.gitignore', '.DS_Store', '.cache']; + +const IGNORED_FILES_BY_PACKAGE_MANAGER: Record = { + npm: [...BASE_IGNORED_FILES], + yarn: [...BASE_IGNORED_FILES, '.yarnrc.yml', '.yarn'], + pnpm: [...BASE_IGNORED_FILES], +}; + +export const currentDirectoryIsEmpty = (packageManager: PackageManagerName) => { + const packageManagerName = packageManagerToCoercedName(packageManager); + const cwdFolderEntries = readdirSync(process.cwd()); + + const filesToIgnore = IGNORED_FILES_BY_PACKAGE_MANAGER[packageManagerName]; + + return ( + cwdFolderEntries.length === 0 || + cwdFolderEntries.every((entry) => filesToIgnore.includes(entry)) + ); +}; diff --git a/code/lib/cli/src/versions.ts b/code/lib/cli/src/versions.ts index 9b02a51bce66..50c4396ebf9a 100644 --- a/code/lib/cli/src/versions.ts +++ b/code/lib/cli/src/versions.ts @@ -53,7 +53,6 @@ export default { '@storybook/preset-react-webpack': '8.0.0-alpha.1', '@storybook/preset-server-webpack': '8.0.0-alpha.1', '@storybook/preset-svelte-webpack': '8.0.0-alpha.1', - '@storybook/preset-vue-webpack': '8.0.0-alpha.1', '@storybook/preset-vue3-webpack': '8.0.0-alpha.1', '@storybook/preset-web-components-webpack': '8.0.0-alpha.1', '@storybook/preview': '8.0.0-alpha.1', @@ -74,9 +73,6 @@ export default { '@storybook/test': '8.0.0-alpha.1', '@storybook/theming': '8.0.0-alpha.1', '@storybook/types': '8.0.0-alpha.1', - '@storybook/vue': '8.0.0-alpha.1', - '@storybook/vue-vite': '8.0.0-alpha.1', - '@storybook/vue-webpack5': '8.0.0-alpha.1', '@storybook/vue3': '8.0.0-alpha.1', '@storybook/vue3-vite': '8.0.0-alpha.1', '@storybook/vue3-webpack5': '8.0.0-alpha.1', diff --git a/code/lib/core-common/src/utils/get-storybook-info.ts b/code/lib/core-common/src/utils/get-storybook-info.ts index 8d97fed4d3ed..dd462a6b0370 100644 --- a/code/lib/core-common/src/utils/get-storybook-info.ts +++ b/code/lib/core-common/src/utils/get-storybook-info.ts @@ -5,7 +5,6 @@ import { getStorybookConfiguration } from './get-storybook-configuration'; export const rendererPackages: Record = { '@storybook/react': 'react', - '@storybook/vue': 'vue', '@storybook/vue3': 'vue3', '@storybook/angular': 'angular', '@storybook/html': 'html', @@ -36,8 +35,6 @@ export const frameworkPackages: Record = { '@storybook/sveltekit': 'sveltekit', '@storybook/vue3-vite': 'vue3-vite', '@storybook/vue3-webpack5': 'vue3-webpack5', - '@storybook/vue-vite': 'vue-vite', - '@storybook/vue-webpack5': 'vue-webpack5', '@storybook/web-components-vite': 'web-components-vite', '@storybook/web-components-webpack5': 'web-components-webpack5', // community (outside of monorepo) diff --git a/code/lib/core-events/src/errors/server-errors.ts b/code/lib/core-events/src/errors/server-errors.ts index f4ecab544773..bacdd7d6055e 100644 --- a/code/lib/core-events/src/errors/server-errors.ts +++ b/code/lib/core-events/src/errors/server-errors.ts @@ -410,3 +410,25 @@ export class NoMatchingExportError extends StorybookError { `; } } + +export class GenerateNewProjectOnInitError extends StorybookError { + readonly category = Category.CLI_INIT; + + readonly code = 3; + + constructor( + public data: { error: unknown | Error; packageManager: string; projectType: string } + ) { + super(); + } + + template(): string { + return dedent` + There was an error while using ${this.data.packageManager} to create a new ${ + this.data.projectType + } project. + + ${this.data.error instanceof Error ? this.data.error.message : ''} + `; + } +} diff --git a/code/lib/core-server/src/build-dev.ts b/code/lib/core-server/src/build-dev.ts index 186a1a6fc47b..5e8a0a955c2a 100644 --- a/code/lib/core-server/src/build-dev.ts +++ b/code/lib/core-server/src/build-dev.ts @@ -36,7 +36,7 @@ export async function buildDevStandalone( ); // updateInfo are cached, so this is typically pretty fast const [port, versionCheck] = await Promise.all([ - getServerPort(options.port), + getServerPort(options.port, { exactPort: options.exactPort }), versionUpdates ? updateCheck(packageJson.version) : Promise.resolve({ success: false, cached: false, data: {}, time: Date.now() }), diff --git a/code/lib/core-server/src/utils/server-address.ts b/code/lib/core-server/src/utils/server-address.ts index 5e4ae1b18b72..bfcb2ba969d9 100644 --- a/code/lib/core-server/src/utils/server-address.ts +++ b/code/lib/core-server/src/utils/server-address.ts @@ -26,11 +26,22 @@ export function getServerAddresses( }; } -export const getServerPort = (port?: number) => - detectFreePort(port).catch((error) => { - logger.error(error); - process.exit(-1); - }); +interface PortOptions { + exactPort?: boolean; +} + +export const getServerPort = (port?: number, { exactPort }: PortOptions = {}) => + detectFreePort(port) + .then((freePort) => { + if (freePort !== port && exactPort) { + process.exit(-1); + } + return freePort; + }) + .catch((error) => { + logger.error(error); + process.exit(-1); + }); export const getServerChannelUrl = (port: number, { https }: { https?: boolean }) => { return `${https ? 'wss' : 'ws'}://localhost:${port}/storybook-server-channel`; diff --git a/code/lib/preview-api/src/index.ts b/code/lib/preview-api/src/index.ts index db1f05d29870..d9b2be0b3bf5 100644 --- a/code/lib/preview-api/src/index.ts +++ b/code/lib/preview-api/src/index.ts @@ -85,5 +85,6 @@ export type { PropDescriptor } from './store'; */ export { ClientApi } from './client-api'; export { StoryStore } from './store'; -export { Preview, PreviewWeb } from './preview-web'; +export { Preview, PreviewWeb, PreviewWithSelection, UrlStore, WebView } from './preview-web'; +export type { SelectionStore, View } from './preview-web'; export { start } from './core-client'; diff --git a/code/lib/preview-api/src/modules/preview-web/index.ts b/code/lib/preview-api/src/modules/preview-web/index.ts index 0fb2f4da2a65..9ee4e4ce3d7a 100644 --- a/code/lib/preview-api/src/modules/preview-web/index.ts +++ b/code/lib/preview-api/src/modules/preview-web/index.ts @@ -6,6 +6,11 @@ export { Preview } from './Preview'; export { PreviewWeb } from './PreviewWeb'; export { PreviewWithSelection } from './PreviewWithSelection'; +export type { SelectionStore } from './SelectionStore'; +export { UrlStore } from './UrlStore'; +export type { View } from './View'; +export { WebView } from './WebView'; + export { simulatePageLoad, simulateDOMContentLoaded } from './simulate-pageload'; export { DocsContext } from './docs-context/DocsContext'; diff --git a/code/lib/preview-api/src/modules/store/csf/testing-utils/index.ts b/code/lib/preview-api/src/modules/store/csf/testing-utils/index.ts index c9a3731f4bd6..da92ad8784d7 100644 --- a/code/lib/preview-api/src/modules/store/csf/testing-utils/index.ts +++ b/code/lib/preview-api/src/modules/store/csf/testing-utils/index.ts @@ -11,6 +11,7 @@ import type { StoryContext, Parameters, ComposedStoryFn, + StrictArgTypes, } from '@storybook/types'; import { HooksContext } from '../../../addons'; @@ -89,6 +90,7 @@ export function composeStory, play: story.playFunction as ComposedStoryPlayFn>, parameters: story.parameters as Parameters, + argTypes: story.argTypes as StrictArgTypes, id: story.id, } ); diff --git a/code/lib/telemetry/src/types.ts b/code/lib/telemetry/src/types.ts index 35266814dff7..8f091703bcae 100644 --- a/code/lib/telemetry/src/types.ts +++ b/code/lib/telemetry/src/types.ts @@ -9,6 +9,7 @@ export type EventType = | 'build' | 'upgrade' | 'init' + | 'scaffolded-empty' | 'browser' | 'canceled' | 'error' diff --git a/code/lib/types/src/modules/composedStory.ts b/code/lib/types/src/modules/composedStory.ts index f02a30187a38..a8902426aba4 100644 --- a/code/lib/types/src/modules/composedStory.ts +++ b/code/lib/types/src/modules/composedStory.ts @@ -1,6 +1,6 @@ /* eslint-disable @typescript-eslint/naming-convention */ -import type { Renderer, StoryId } from '@storybook/csf'; +import type { Renderer, StoryId, StrictArgTypes } from '@storybook/csf'; import type { AnnotatedStoryFn, @@ -60,6 +60,7 @@ export type ComposedStoryFn< id: StoryId; storyName: string; parameters: Parameters; + argTypes: StrictArgTypes; }; /** * Based on a module of stories, it returns all stories within it, filtering non-stories diff --git a/code/lib/types/src/modules/core-common.ts b/code/lib/types/src/modules/core-common.ts index 4eb9119b74c4..53dcecdcc684 100644 --- a/code/lib/types/src/modules/core-common.ts +++ b/code/lib/types/src/modules/core-common.ts @@ -170,6 +170,7 @@ export interface CLIOptions { enableCrashReports?: boolean; host?: string; initialPath?: string; + exactPort?: boolean; /** * @deprecated Use 'staticDirs' Storybook Configuration option instead */ diff --git a/code/package.json b/code/package.json index 94d67d12bc6e..1ccd75eb6190 100644 --- a/code/package.json +++ b/code/package.json @@ -159,7 +159,6 @@ "@storybook/preset-react-webpack": "workspace:*", "@storybook/preset-server-webpack": "workspace:*", "@storybook/preset-svelte-webpack": "workspace:*", - "@storybook/preset-vue-webpack": "workspace:*", "@storybook/preset-vue3-webpack": "workspace:*", "@storybook/preset-web-components-webpack": "workspace:*", "@storybook/preview": "workspace:*", @@ -177,8 +176,6 @@ "@storybook/testing-library": "next", "@storybook/theming": "workspace:*", "@storybook/types": "workspace:*", - "@storybook/vue": "workspace:*", - "@storybook/vue-webpack5": "workspace:*", "@storybook/vue3": "workspace:*", "@storybook/vue3-vite": "workspace:*", "@storybook/vue3-webpack5": "workspace:*", @@ -320,5 +317,6 @@ "Dependency Upgrades" ] ] - } + }, + "deferredNextVersion": "8.0.0-alpha.2" } diff --git a/code/presets/svelte-webpack/package.json b/code/presets/svelte-webpack/package.json index 9ce7c683098d..07e21cd80f29 100644 --- a/code/presets/svelte-webpack/package.json +++ b/code/presets/svelte-webpack/package.json @@ -76,7 +76,7 @@ }, "peerDependencies": { "@babel/core": "*", - "svelte": "^3.1.0 || ^4.0.0", + "svelte": "^4.0.0 || ^5.0.0-next.16", "svelte-loader": "*" }, "engines": { diff --git a/code/presets/vue-webpack/README.md b/code/presets/vue-webpack/README.md deleted file mode 100644 index 1e301b010570..000000000000 --- a/code/presets/vue-webpack/README.md +++ /dev/null @@ -1,6 +0,0 @@ -# Storybook Webpack preset for Vue - -This package is a [preset](https://storybook.js.org/docs/vue/addons/writing-presets#presets-api) that configures Storybook's webpack settings for handling Vue. -It's an internal package that's not intended to be used directly by users. - -- More info on [Storybook for Vue](https://storybook.js.org/docs/vue/get-started) diff --git a/code/presets/vue-webpack/package.json b/code/presets/vue-webpack/package.json deleted file mode 100644 index 62a5847895fa..000000000000 --- a/code/presets/vue-webpack/package.json +++ /dev/null @@ -1,100 +0,0 @@ -{ - "name": "@storybook/preset-vue-webpack", - "version": "8.0.0-alpha.1", - "description": "Storybook for Vue: Develop Vue Component in isolation with Hot Reloading.", - "keywords": [ - "storybook" - ], - "homepage": "https://github.com/storybookjs/storybook/tree/next/code/presets/vue-webpack", - "bugs": { - "url": "https://github.com/storybookjs/storybook/issues" - }, - "repository": { - "type": "git", - "url": "https://github.com/storybookjs/storybook.git", - "directory": "code/presets/vue-webpack" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" - }, - "license": "MIT", - "exports": { - ".": { - "types": "./dist/index.d.ts", - "node": "./dist/index.js", - "require": "./dist/index.js", - "import": "./dist/index.mjs" - }, - "./preset": { - "types": "./dist/index.d.ts", - "node": "./dist/index.js", - "require": "./dist/index.js", - "import": "./dist/index.mjs" - }, - "./dist/framework-preset-vue-docs": { - "types": "./dist/framework-preset-vue-docs.d.ts", - "require": "./dist/framework-preset-vue-docs.js", - "import": "./dist/framework-preset-vue-docs.mjs" - }, - "./dist/framework-preset-vue": { - "types": "./dist/framework-preset-vue.d.ts", - "require": "./dist/framework-preset-vue.js", - "import": "./dist/framework-preset-vue.mjs" - }, - "./package.json": "./package.json" - }, - "main": "dist/index.js", - "module": "dist/index.mjs", - "types": "dist/index.d.ts", - "files": [ - "dist/**/*", - "README.md", - "*.js", - "*.d.ts", - "!src/**/*" - ], - "scripts": { - "check": "node --loader ../../../scripts/node_modules/esbuild-register/loader.js -r ../../../scripts/node_modules/esbuild-register/register.js ../../../scripts/prepare/check.ts", - "prep": "node --loader ../../../scripts/node_modules/esbuild-register/loader.js -r ../../../scripts/node_modules/esbuild-register/register.js ../../../scripts/prepare/bundle.ts" - }, - "dependencies": { - "@storybook/core-webpack": "workspace:*", - "@storybook/docs-tools": "workspace:*", - "@types/node": "^18.0.0", - "ts-loader": "^9.2.8", - "vue-docgen-api": "^4.44.23", - "vue-docgen-loader": "^1.5.1", - "webpack": "5" - }, - "devDependencies": { - "typescript": "^5.3.2", - "vue": "^2.6.12", - "vue-loader": "^15.7.0", - "vue-template-compiler": "^2.6.14", - "webpack": "5" - }, - "peerDependencies": { - "@babel/core": "*", - "babel-loader": "^7.0.0 || ^8.0.0 || ^9.0.0", - "css-loader": "*", - "vue": "^2.6.8", - "vue-loader": "^15.7.0", - "vue-template-compiler": "^2.6.14" - }, - "engines": { - "node": ">=16.0.0" - }, - "publishConfig": { - "access": "public" - }, - "bundler": { - "entries": [ - "./src/index.ts", - "./src/framework-preset-vue-docs.ts", - "./src/framework-preset-vue.ts" - ], - "platform": "node" - }, - "gitHead": "e6a7fd8a655c69780bc20b9749c2699e44beae17" -} diff --git a/code/presets/vue-webpack/preset.js b/code/presets/vue-webpack/preset.js deleted file mode 100644 index f4f0e998846b..000000000000 --- a/code/presets/vue-webpack/preset.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require('./dist/index'); diff --git a/code/presets/vue-webpack/project.json b/code/presets/vue-webpack/project.json deleted file mode 100644 index 79087a17eb73..000000000000 --- a/code/presets/vue-webpack/project.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "name": "@storybook/preset-vue-webpack", - "$schema": "../../node_modules/nx/schemas/project-schema.json", - "implicitDependencies": [], - "type": "library" -} diff --git a/code/presets/vue-webpack/src/framework-preset-vue-docs.ts b/code/presets/vue-webpack/src/framework-preset-vue-docs.ts deleted file mode 100644 index bd4dc600add5..000000000000 --- a/code/presets/vue-webpack/src/framework-preset-vue-docs.ts +++ /dev/null @@ -1,33 +0,0 @@ -import type { StorybookConfig } from '@storybook/core-webpack'; -import { hasDocsOrControls } from '@storybook/docs-tools'; - -export const webpackFinal: StorybookConfig['webpackFinal'] = (config, options) => { - if (!hasDocsOrControls(options)) return config; - - let vueDocgenOptions = {}; - - options.presetsList?.forEach((preset) => { - if (preset.name.includes('addon-docs') && preset.options.vueDocgenOptions) { - const appendableOptions = preset.options.vueDocgenOptions; - vueDocgenOptions = { - ...vueDocgenOptions, - ...appendableOptions, - }; - } - }); - - config.module?.rules?.push({ - test: /\.vue$/, - loader: require.resolve('vue-docgen-loader', { - paths: [require.resolve('@storybook/preset-vue-webpack')], - }), - enforce: 'post', - options: { - docgenOptions: { - alias: config.resolve?.alias, - ...vueDocgenOptions, - }, - }, - }); - return config; -}; diff --git a/code/presets/vue-webpack/src/framework-preset-vue.ts b/code/presets/vue-webpack/src/framework-preset-vue.ts deleted file mode 100644 index 6938d4ab5217..000000000000 --- a/code/presets/vue-webpack/src/framework-preset-vue.ts +++ /dev/null @@ -1,49 +0,0 @@ -/* eslint-disable no-param-reassign */ -import { VueLoaderPlugin } from 'vue-loader'; - -import type { StorybookConfig } from '@storybook/core-webpack'; - -export const webpack: StorybookConfig['webpack'] = async (config, { presets }) => { - const typescriptOptions = await presets.apply('typescript', {}); - - config.plugins?.push(new VueLoaderPlugin()); - config.module?.rules?.push({ - test: /\.vue$/, - loader: require.resolve('vue-loader'), - options: {}, - }); - config.module?.rules?.push({ - test: /\.ts$/, - use: [ - { - loader: require.resolve('ts-loader'), - options: { - transpileOnly: !typescriptOptions?.check, - appendTsSuffixTo: [/\.vue$/], - }, - }, - ], - }); - config.module?.rules?.push({ - test: /\.tsx$/, - use: [ - { - loader: require.resolve('ts-loader'), - options: { - transpileOnly: true, - appendTsxSuffixTo: [/\.vue$/], - }, - }, - ], - }); - - if (config.resolve) { - config.resolve.extensions?.push('.vue'); - config.resolve.alias = { - ...config.resolve.alias, - vue$: require.resolve('vue/dist/vue.esm.js'), - }; - } - - return config; -}; diff --git a/code/presets/vue-webpack/src/index.ts b/code/presets/vue-webpack/src/index.ts deleted file mode 100644 index 71b23495a8b2..000000000000 --- a/code/presets/vue-webpack/src/index.ts +++ /dev/null @@ -1,8 +0,0 @@ -import type { PresetProperty } from '@storybook/types'; - -export * from './types'; - -export const addons: PresetProperty<'addons'> = [ - require.resolve('@storybook/preset-vue-webpack/dist/framework-preset-vue'), - require.resolve('@storybook/preset-vue-webpack/dist/framework-preset-vue-docs'), -]; diff --git a/code/presets/vue-webpack/src/types.ts b/code/presets/vue-webpack/src/types.ts deleted file mode 100644 index 7b5a8352a9e1..000000000000 --- a/code/presets/vue-webpack/src/types.ts +++ /dev/null @@ -1 +0,0 @@ -export type { BuilderResult, TypescriptOptions, StorybookConfig } from '@storybook/core-webpack'; diff --git a/code/presets/vue-webpack/src/typings.d.ts b/code/presets/vue-webpack/src/typings.d.ts deleted file mode 100644 index 1cb13ccbdae2..000000000000 --- a/code/presets/vue-webpack/src/typings.d.ts +++ /dev/null @@ -1 +0,0 @@ -declare module 'vue-loader'; diff --git a/code/presets/vue-webpack/tsconfig.json b/code/presets/vue-webpack/tsconfig.json deleted file mode 100644 index 55e078e431f6..000000000000 --- a/code/presets/vue-webpack/tsconfig.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "extends": "../../tsconfig.json", - "compilerOptions": { - "skipLibCheck": true, - "resolveJsonModule": true, - "strict": true - }, - "include": ["src/**/*"] -} diff --git a/code/renderers/react/src/entry-preview.ts b/code/renderers/react/src/entry-preview.ts index fe96bc623da7..c5cabfb30420 100644 --- a/code/renderers/react/src/entry-preview.ts +++ b/code/renderers/react/src/entry-preview.ts @@ -1,2 +1,3 @@ export const parameters: {} = { renderer: 'react' }; -export { render, renderToCanvas } from './render'; +export { render } from './render'; +export { renderToCanvas } from './renderToCanvas'; diff --git a/code/renderers/react/src/render.tsx b/code/renderers/react/src/render.tsx index 275fa704ffca..06bf38aba8e3 100644 --- a/code/renderers/react/src/render.tsx +++ b/code/renderers/react/src/render.tsx @@ -1,13 +1,8 @@ -import { global } from '@storybook/global'; -import type { FC } from 'react'; -import React, { Component as ReactComponent, StrictMode, Fragment } from 'react'; -import { renderElement, unmountElement } from '@storybook/react-dom-shim'; +import React from 'react'; -import type { RenderContext, ArgsStoryFn } from '@storybook/types'; +import type { ArgsStoryFn } from '@storybook/types'; -import type { ReactRenderer, StoryContext } from './types'; - -const { FRAMEWORK_OPTIONS } = global; +import type { ReactRenderer } from './types'; export const render: ArgsStoryFn = (args, context) => { const { id, component: Component } = context; @@ -19,73 +14,3 @@ export const render: ArgsStoryFn = (args, context) => { return ; }; - -class ErrorBoundary extends ReactComponent<{ - showException: (err: Error) => void; - showMain: () => void; - children?: React.ReactNode; -}> { - state = { hasError: false }; - - static getDerivedStateFromError() { - return { hasError: true }; - } - - componentDidMount() { - const { hasError } = this.state; - const { showMain } = this.props; - if (!hasError) { - showMain(); - } - } - - componentDidCatch(err: Error) { - const { showException } = this.props; - // message partially duplicates stack, strip it - showException(err); - } - - render() { - const { hasError } = this.state; - const { children } = this.props; - - return hasError ? null : children; - } -} - -const Wrapper = FRAMEWORK_OPTIONS?.strictMode ? StrictMode : Fragment; - -export async function renderToCanvas( - { - storyContext, - unboundStoryFn, - showMain, - showException, - forceRemount, - }: RenderContext, - canvasElement: ReactRenderer['canvasElement'] -) { - const Story = unboundStoryFn as FC>; - - const content = ( - - - - ); - - // For React 15, StrictMode & Fragment doesn't exists. - const element = Wrapper ? {content} : content; - - // In most cases, we need to unmount the existing set of components in the DOM node. - // Otherwise, React may not recreate instances for every story run. - // This could leads to issues like below: - // https://github.com/storybookjs/react-storybook/issues/81 - // (This is not the case when we change args or globals to the story however) - if (forceRemount) { - unmountElement(canvasElement); - } - - await renderElement(element, canvasElement); - - return () => unmountElement(canvasElement); -} diff --git a/code/renderers/react/src/renderToCanvas.tsx b/code/renderers/react/src/renderToCanvas.tsx new file mode 100644 index 000000000000..d8821a3458e4 --- /dev/null +++ b/code/renderers/react/src/renderToCanvas.tsx @@ -0,0 +1,80 @@ +import { global } from '@storybook/global'; +import type { FC } from 'react'; +import React, { Component as ReactComponent, StrictMode, Fragment } from 'react'; +import { renderElement, unmountElement } from '@storybook/react-dom-shim'; + +import type { RenderContext } from '@storybook/types'; + +import type { ReactRenderer, StoryContext } from './types'; + +const { FRAMEWORK_OPTIONS } = global; + +class ErrorBoundary extends ReactComponent<{ + showException: (err: Error) => void; + showMain: () => void; + children?: React.ReactNode; +}> { + state = { hasError: false }; + + static getDerivedStateFromError() { + return { hasError: true }; + } + + componentDidMount() { + const { hasError } = this.state; + const { showMain } = this.props; + if (!hasError) { + showMain(); + } + } + + componentDidCatch(err: Error) { + const { showException } = this.props; + // message partially duplicates stack, strip it + showException(err); + } + + render() { + const { hasError } = this.state; + const { children } = this.props; + + return hasError ? null : children; + } +} + +const Wrapper = FRAMEWORK_OPTIONS?.strictMode ? StrictMode : Fragment; + +export async function renderToCanvas( + { + storyContext, + unboundStoryFn, + showMain, + showException, + forceRemount, + }: RenderContext, + canvasElement: ReactRenderer['canvasElement'] +) { + const Story = unboundStoryFn as FC>; + + const content = ( + + + + ); + + // For React 15, StrictMode & Fragment doesn't exists. + const element = Wrapper ? {content} : content; + + // In most cases, we need to unmount the existing set of components in the DOM node. + // Otherwise, React may not recreate instances for every story run. + // This could leads to issues like below: + // https://github.com/storybookjs/react-storybook/issues/81 + // (This is not the case when we change args or globals to the story however) + if (forceRemount) { + unmountElement(canvasElement); + } + + await renderElement(element, canvasElement); + + return () => unmountElement(canvasElement); +} diff --git a/code/renderers/svelte/package.json b/code/renderers/svelte/package.json index 2ddd62ac3ba3..ec38632a9f04 100644 --- a/code/renderers/svelte/package.json +++ b/code/renderers/svelte/package.json @@ -63,12 +63,12 @@ }, "devDependencies": { "expect-type": "^0.15.0", - "svelte": "^4.0.0", - "svelte-check": "3.4.6", + "svelte": "^5.0.0-next.15", + "svelte-check": "^3.6.1", "typescript": "^5.3.2" }, "peerDependencies": { - "svelte": "^3.1.0 || ^4.0.0" + "svelte": "^4.0.0 || ^5.0.0-next.16" }, "engines": { "node": ">=16.0.0" diff --git a/code/renderers/svelte/src/render.ts b/code/renderers/svelte/src/render.ts index cfde36047fa1..b1821b692358 100644 --- a/code/renderers/svelte/src/render.ts +++ b/code/renderers/svelte/src/render.ts @@ -1,6 +1,5 @@ /* eslint-disable no-param-reassign */ import type { RenderContext, ArgsStoryFn } from '@storybook/types'; -import type { SvelteComponentTyped } from 'svelte'; import { RESET_STORY_ARGS } from '@storybook/core-events'; // ! DO NOT change this PreviewRender import to a relative path, it will break it. // ! A relative import will be compiled at build time, and Svelte will be unable to @@ -10,10 +9,14 @@ import { RESET_STORY_ARGS } from '@storybook/core-events'; // eslint-disable-next-line import/no-extraneous-dependencies import PreviewRender from '@storybook/svelte/templates/PreviewRender.svelte'; import { addons } from '@storybook/preview-api'; +import * as svelte from 'svelte'; import type { SvelteRenderer } from './types'; -const componentsByDomElement = new Map(); +const componentsByDomElement = new Map< + SvelteRenderer['canvasElement'], + any // ReturnType depends on the version of Svelte v4 or v5 +>(); function teardown(canvasElement: SvelteRenderer['canvasElement']) { if (!componentsByDomElement.has(canvasElement)) { @@ -26,6 +29,25 @@ function teardown(canvasElement: SvelteRenderer['canvasElement']) { componentsByDomElement.delete(canvasElement); } +/** + * Mount the PreviewRender component to the provided canvasElement + * Either using the Svelte v4 or v5 API + */ +function createRoot(target: HTMLElement, props: any) { + if ((svelte as any).createRoot) { + // Svelte v5 + return svelte.createRoot(PreviewRender, { + target, + props, + }); + } + // Svelte v4 + return new (PreviewRender as any)({ + target, + props, + }); +} + /** * This is a workaround for the issue that when resetting args, * the story needs to be remounted completely to revert to the component's default props. @@ -66,16 +88,13 @@ export function renderToCanvas( } if (!existingComponent || remount) { - const createdComponent = new PreviewRender({ - target: canvasElement, - props: { - storyFn, - storyContext, - name, - kind, - showError, - }, - }) as SvelteComponentTyped; + const createdComponent = createRoot(canvasElement, { + storyFn, + storyContext, + name, + kind, + showError, + }); componentsByDomElement.set(canvasElement, createdComponent); } else { existingComponent.$set({ diff --git a/code/renderers/svelte/src/typings.d.ts b/code/renderers/svelte/src/typings.d.ts index 109dcd62da0e..2e00d983aa34 100644 --- a/code/renderers/svelte/src/typings.d.ts +++ b/code/renderers/svelte/src/typings.d.ts @@ -1,2 +1,9 @@ declare var STORYBOOK_ENV: 'svelte'; declare var LOGLEVEL: 'trace' | 'debug' | 'info' | 'warn' | 'error' | 'silent' | undefined; + +declare module '*.svelte' { + import type { ComponentType } from 'svelte'; + + const component: ComponentType; + export default component; +} diff --git a/code/renderers/svelte/templates/SlotDecorator.svelte b/code/renderers/svelte/templates/SlotDecorator.svelte index 5bd0fdfe3455..9de64db04c3d 100644 --- a/code/renderers/svelte/templates/SlotDecorator.svelte +++ b/code/renderers/svelte/templates/SlotDecorator.svelte @@ -5,19 +5,19 @@ export let Component; export let props = {}; export let on = undefined; - + let instance; let decoratorInstance; - - function getInstance() { - // instance can be undefined if a decorator doesn't have - return instance || decoratorInstance; - } - + if (on) { - // Attach svelte event listeners. - Object.keys(on).forEach((eventName) => { - onMount(() => getInstance().$on(eventName, on[eventName])); + // Attach Svelte event listeners in Svelte v4 + // In Svelte v5 this is not possible anymore as instances are no longer classes with $on() properties, so it will be a no-op + onMount(() => { + Object.entries(on).forEach(([eventName, eventCallback]) => { + // instance can be undefined if a decorator doesn't have + const inst = instance ?? decoratorInstance; + inst?.$on?.(eventName, eventCallback) + }); }); } diff --git a/code/renderers/vue/README.md b/code/renderers/vue/README.md deleted file mode 100644 index af07be8486f4..000000000000 --- a/code/renderers/vue/README.md +++ /dev/null @@ -1 +0,0 @@ -# Storybook Vue renderer diff --git a/code/renderers/vue/jest.config.js b/code/renderers/vue/jest.config.js deleted file mode 100644 index 4396fbc7010d..000000000000 --- a/code/renderers/vue/jest.config.js +++ /dev/null @@ -1,7 +0,0 @@ -const path = require('path'); -const baseConfig = require('../../jest.config.browser'); - -module.exports = { - ...baseConfig, - displayName: __dirname.split(path.sep).slice(-2).join(path.posix.sep), -}; diff --git a/code/renderers/vue/package.json b/code/renderers/vue/package.json deleted file mode 100644 index d2fef77f0b41..000000000000 --- a/code/renderers/vue/package.json +++ /dev/null @@ -1,91 +0,0 @@ -{ - "name": "@storybook/vue", - "version": "8.0.0-alpha.1", - "description": "Storybook Vue renderer", - "keywords": [ - "storybook" - ], - "homepage": "https://github.com/storybookjs/storybook/tree/next/code/renderers/vue", - "bugs": { - "url": "https://github.com/storybookjs/storybook/issues" - }, - "repository": { - "type": "git", - "url": "https://github.com/storybookjs/storybook.git", - "directory": "code/renderers/vue" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" - }, - "license": "MIT", - "exports": { - ".": { - "types": "./dist/index.d.ts", - "node": "./dist/index.js", - "require": "./dist/index.js", - "import": "./dist/index.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" - }, - "main": "dist/index.js", - "module": "dist/index.mjs", - "types": "dist/index.d.ts", - "files": [ - "dist/**/*", - "template/cli/**/*", - "README.md", - "*.js", - "*.d.ts", - "!src/**/*" - ], - "scripts": { - "check": "vue-tsc --noEmit", - "prep": "node --loader ../../../scripts/node_modules/esbuild-register/loader.js -r ../../../scripts/node_modules/esbuild-register/register.js ../../../scripts/prepare/bundle.ts" - }, - "dependencies": { - "@storybook/client-logger": "workspace:*", - "@storybook/docs-tools": "workspace:*", - "@storybook/global": "^5.0.0", - "@storybook/preview-api": "workspace:*", - "@storybook/types": "workspace:*", - "tiny-invariant": "^1.3.1", - "ts-dedent": "^2.0.0", - "type-fest": "~2.19" - }, - "devDependencies": { - "typescript": "^5.3.2", - "vue": "2.6.14", - "vue-tsc": "latest" - }, - "peerDependencies": { - "@babel/core": "*", - "babel-loader": "^7.0.0 || ^8.0.0 || ^9.0.0", - "css-loader": "*", - "vue": "^2.6.8" - }, - "peerDependenciesMeta": { - "babel-loader": { - "optional": true - } - }, - "engines": { - "node": ">=16.0.0" - }, - "publishConfig": { - "access": "public" - }, - "bundler": { - "entries": [ - "./src/index.ts", - "./src/preset.ts", - "./src/entry-preview.ts", - "./src/entry-preview-docs.ts" - ], - "platform": "browser" - }, - "gitHead": "e6a7fd8a655c69780bc20b9749c2699e44beae17" -} diff --git a/code/renderers/vue/preset.js b/code/renderers/vue/preset.js deleted file mode 100644 index a83f95279e7f..000000000000 --- a/code/renderers/vue/preset.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require('./dist/preset'); diff --git a/code/renderers/vue/project.json b/code/renderers/vue/project.json deleted file mode 100644 index 428631410866..000000000000 --- a/code/renderers/vue/project.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "name": "@storybook/vue", - "$schema": "../../node_modules/nx/schemas/project-schema.json", - "implicitDependencies": [], - "type": "library" -} diff --git a/code/renderers/vue/src/__tests__/Button.vue b/code/renderers/vue/src/__tests__/Button.vue deleted file mode 100644 index af26efec2577..000000000000 --- a/code/renderers/vue/src/__tests__/Button.vue +++ /dev/null @@ -1,28 +0,0 @@ - - - diff --git a/code/renderers/vue/src/decorateStory.ts b/code/renderers/vue/src/decorateStory.ts deleted file mode 100644 index eb69dfd63d7e..000000000000 --- a/code/renderers/vue/src/decorateStory.ts +++ /dev/null @@ -1,91 +0,0 @@ -import type { VueConstructor, ComponentOptions } from 'vue'; -import Vue from 'vue'; -import type { DecoratorFunction, StoryContext, LegacyStoryFn } from '@storybook/types'; -import { sanitizeStoryContextUpdate } from '@storybook/preview-api'; - -import type { StoryFnVueReturnType, VueRenderer } from './types'; -import { extractProps } from './util'; -import { VALUES } from './render'; - -export const WRAPS = 'STORYBOOK_WRAPS'; - -function prepare( - rawStory: StoryFnVueReturnType, - innerStory?: StoryFnVueReturnType, - context?: StoryContext -): VueConstructor | null { - let story: ComponentOptions | VueConstructor; - - if (typeof rawStory === 'string') { - story = { template: rawStory }; - } else if (rawStory != null) { - story = rawStory as ComponentOptions; - } else { - return null; - } - - // @ts-expect-error (Converted from ts-ignore) - // eslint-disable-next-line no-underscore-dangle - if (!story._isVue) { - if (innerStory) { - story.components = { ...(story.components || {}), story: innerStory }; - } - story = Vue.extend(story); - // @ts-expect-error // https://github.com/storybookjs/storybook/pull/7578#discussion_r307984824 - } else if (story.options[WRAPS]) { - return story as VueConstructor; - } - - return Vue.extend({ - // @ts-expect-error // https://github.com/storybookjs/storybook/pull/7578#discussion_r307985279 - [WRAPS]: story, - [VALUES]: { - // @ts-expect-error // https://github.com/storybookjs/storybook/pull/7578#discussion_r307984824 - ...(innerStory ? innerStory.options[VALUES] : {}), - // @ts-expect-error // https://github.com/storybookjs/storybook/pull/7578#discussion_r307984824 - ...extractProps(story), - ...(context?.args || {}), - }, - functional: true, - render(h, { data, parent, children }) { - return h( - story, - { - ...data, - // @ts-expect-error // https://github.com/storybookjs/storybook/pull/7578#discussion_r307986196 - props: { ...(data.props || {}), ...parent.$root[VALUES] }, - }, - children - ); - }, - }); -} - -export function decorateStory( - storyFn: LegacyStoryFn, - decorators: DecoratorFunction[] -) { - return decorators.reduce( - (decorated: LegacyStoryFn, decorator) => (context: StoryContext) => { - let story: VueRenderer['storyResult'] | undefined; - - const decoratedStory = decorator((update) => { - story = decorated({ ...context, ...sanitizeStoryContextUpdate(update) }); - return story; - }, context); - - if (!story) { - story = decorated(context); - } - - if (decoratedStory === story) { - return story; - } - - return prepare(decoratedStory, story) as VueRenderer['storyResult']; - }, - (context) => { - return prepare(storyFn(context), undefined, context) as VueRenderer['storyResult']; - } - ); -} diff --git a/code/renderers/vue/src/docs/extractArgTypes.ts b/code/renderers/vue/src/docs/extractArgTypes.ts deleted file mode 100644 index c73a2471aa08..000000000000 --- a/code/renderers/vue/src/docs/extractArgTypes.ts +++ /dev/null @@ -1,91 +0,0 @@ -import type { StrictArgTypes } from '@storybook/types'; -import type { ArgTypesExtractor, DocgenInfo, PropDef } from '@storybook/docs-tools'; -import { hasDocgen, extractComponentProps, convert } from '@storybook/docs-tools'; -import invariant from 'tiny-invariant'; - -const SECTIONS = ['props', 'events', 'slots', 'methods']; - -/** - * As @enum tag is not implemented in vuedocgen, infers propdef enum type - * from the presence of @values tag. - */ -function inferEnum(propDef: PropDef, docgenInfo: DocgenInfo): false | PropDef { - // cast as any, since "values" doesn't exist in DocgenInfo type - const { type, values } = docgenInfo as any; - const matched = Array.isArray(values) && values.length && type && type.name !== 'enum'; - - if (!matched) { - return false; - } - - invariant(propDef.type, 'PropDef should have a type defined'); - - const enumString = values.join(', '); - let { summary } = propDef.type; - summary = summary ? `${summary}: ${enumString}` : enumString; - - Object.assign(propDef.type, { - ...propDef.type, - name: 'enum', - value: values, - summary, - }); - return propDef; -} - -/** - * @returns {Array} result - * @returns {PropDef} result.def - propDef - * @returns {boolean} result.isChanged - flag whether propDef is mutated or not. - * this is needed to prevent sbType from performing convert(docgenInfo). - */ -function verifyPropDef(propDef: PropDef, docgenInfo: DocgenInfo): [PropDef, boolean] { - let def = propDef; - let isChanged = false; - - // another callback can be added here. - // callback is mutually exclusive from each other. - const callbacks = [inferEnum]; - for (let i = 0, len = callbacks.length; i < len; i += 1) { - const matched = callbacks[i](propDef, docgenInfo); - if (matched) { - def = matched; - isChanged = true; - } - } - - return [def, isChanged]; -} - -export const extractArgTypes: ArgTypesExtractor = (component) => { - if (!hasDocgen(component)) { - return null; - } - const results: StrictArgTypes = {}; - SECTIONS.forEach((section) => { - const props = extractComponentProps(component, section); - props.forEach(({ propDef, docgenInfo, jsDocTags }) => { - const [result, isPropDefChanged] = verifyPropDef(propDef, docgenInfo); - const { name, type, description, defaultValue: defaultSummary, required } = result; - - let sbType; - if (isPropDefChanged) { - sbType = type; - } else { - sbType = section === 'props' ? convert(docgenInfo) : { name: 'void' }; - } - results[name] = { - name, - description, - type: { required, ...sbType }, - table: { - type, - jsDocTags, - defaultValue: defaultSummary, - category: section, - }, - }; - }); - }); - return results; -}; diff --git a/code/renderers/vue/src/docs/sourceDecorator.test.ts b/code/renderers/vue/src/docs/sourceDecorator.test.ts deleted file mode 100644 index 136de32eb01c..000000000000 --- a/code/renderers/vue/src/docs/sourceDecorator.test.ts +++ /dev/null @@ -1,197 +0,0 @@ -/* eslint no-underscore-dangle: ["error", { "allow": ["_vnode"] }] */ - -import type { ComponentOptions, VueConstructor } from 'vue'; -import Vue from 'vue/dist/vue'; -import { vnodeToString } from './sourceDecorator'; - -expect.addSnapshotSerializer({ - print: (val: any) => val, - test: (val) => typeof val === 'string', -}); - -const getVNode = (Component: ComponentOptions) => { - const vm = new (Vue as unknown as VueConstructor)({ - render(h) { - return h(Component); - }, - }).$mount(); - - // @ts-expect-error TS says it is called $vnode - return vm.$children[0]._vnode; -}; - -describe('vnodeToString', () => { - it('basic', () => { - expect( - vnodeToString( - getVNode({ - template: ``, - }) - ) - ).toMatchInlineSnapshot(``); - }); - - it('static class', () => { - expect( - vnodeToString( - getVNode({ - template: ``, - }) - ) - ).toMatchInlineSnapshot(``); - }); - - it('string dynamic class', () => { - expect( - vnodeToString( - getVNode({ - template: ``, - }) - ) - ).toMatchInlineSnapshot(``); - }); - - it('non-string dynamic class', () => { - expect( - vnodeToString( - getVNode({ - template: ``, - }) - ) - ).toMatchInlineSnapshot(``); - }); - - it('array dynamic class', () => { - expect( - vnodeToString( - getVNode({ - template: ``, - }) - ) - ).toMatchInlineSnapshot(``); - }); - - it('object dynamic class', () => { - expect( - vnodeToString( - getVNode({ - template: ``, - }) - ) - ).toMatchInlineSnapshot(``); - }); - - it('merge dynamic and static classes', () => { - expect( - vnodeToString( - getVNode({ - template: ``, - }) - ) - ).toMatchInlineSnapshot(``); - }); - - it('attributes', () => { - const MyComponent: ComponentOptions = { - props: ['propA', 'propB', 'propC', 'propD', 'propE', 'propF', 'propG'], - template: '
', - }; - - expect( - vnodeToString( - getVNode({ - components: { MyComponent }, - data(): { props: Record } { - return { - props: { - propA: 'propA', - propB: 1, - propC: null, - propD: { - foo: 'bar', - }, - propE: true, - propF() { - const foo = 'bar'; - - return foo; - }, - propG: undefined, - }, - }; - }, - template: ``, - }) - ) - ).toMatchInlineSnapshot( - `` - ); - }); - - it('children', () => { - expect( - vnodeToString( - getVNode({ - template: ` -
-
- -
-
`, - }) - ) - ).toMatchInlineSnapshot(`
`); - }); - - it('empty tag', () => { - expect( - vnodeToString( - getVNode({ - template: ` -
-
`, - }) - ) - ).toMatchInlineSnapshot(`
`); - }); - - it('tag in text', () => { - expect( - vnodeToString( - getVNode({ - template: ` -
- <> -
`, - }) - ) - ).toMatchInlineSnapshot(` -
{{\` - <> - \`}}
- `); - }); - - it('component element with children', () => { - const MyComponent: ComponentOptions = { - props: ['propA'], - template: '
', - }; - - expect( - vnodeToString( - getVNode({ - components: { MyComponent }, - data(): { props: Record } { - return { - props: { - propA: 'propA', - }, - }; - }, - template: `
`, - }) - ) - ).toMatchInlineSnapshot(`
`); - }); -}); diff --git a/code/renderers/vue/src/docs/sourceDecorator.ts b/code/renderers/vue/src/docs/sourceDecorator.ts deleted file mode 100644 index becc96802860..000000000000 --- a/code/renderers/vue/src/docs/sourceDecorator.ts +++ /dev/null @@ -1,233 +0,0 @@ -/* eslint-disable no-underscore-dangle */ -/* eslint no-underscore-dangle: ["error", { "allow": ["_vnode"] }] */ - -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 Vue from 'vue'; -import type { StoryContext } from '../types'; - -export const skipSourceRender = (context: StoryContext) => { - const sourceParams = context?.parameters.docs?.source; - const isArgsStory = context?.parameters.__isArgsStory; - - // always render if the user forces it - if (sourceParams?.type === SourceType.DYNAMIC) { - return false; - } - - // never render if the user is forcing the block to render code, or - // if the user provides code, or if it's not an args story. - return !isArgsStory || sourceParams?.code || sourceParams?.type === SourceType.CODE; -}; - -export const sourceDecorator = (storyFn: any, context: StoryContext) => { - const story = storyFn(); - const source = ''; - - // See ../react/jsxDecorator.tsx - 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, - }, - data() { - return { source }; - }, - updated() { - generateSource(this); - }, - mounted() { - this.$watch('source', (val) => - channel.emit(SNIPPET_RENDERED, context.id, ``, 'vue') - ); - generateSource(this); - }, - template: '', - } as ComponentOptions & ThisType; -}; - -export function vnodeToString(vnode: Vue.VNode): string { - const attrString = [ - ...(vnode.data?.slot ? ([['slot', vnode.data.slot]] as [string, any][]) : []), - ['class', stringifyClassAttribute(vnode)], - ...(vnode.componentOptions?.propsData ? Object.entries(vnode.componentOptions.propsData) : []), - ...(vnode.data?.attrs ? Object.entries(vnode.data.attrs) : []), - ] - .filter(([name], index, list) => list.findIndex((item) => item[0] === name) === index) - .map(([name, value]) => stringifyAttr(name!, value)) - .filter(Boolean) - .join(' '); - - if (!vnode.componentOptions) { - // Non-component elements (div, span, etc...) - if (vnode.tag) { - if (!vnode.children) { - return `<${vnode.tag} ${attrString}/>`; - } - - return `<${vnode.tag} ${attrString}>${vnode.children.map(vnodeToString).join('')}`; - } - - // TextNode - if (vnode.text) { - if (/[<>"&]/.test(vnode.text)) { - return `{{\`${vnode.text.replace(/`/g, '\\`')}\`}}`; - } - - return vnode.text; - } - - // Unknown - return ''; - } - - // Probably users never see the "unknown-component". It seems that vnode.tag - // is always set. - const tag = vnode.componentOptions.tag || vnode.tag || 'unknown-component'; - - if (!vnode.componentOptions.children) { - return `<${tag} ${attrString}/>`; - } - - return `<${tag} ${attrString}>${vnode.componentOptions.children - .map(vnodeToString) - .join('')}`; -} - -function stringifyClassAttribute(vnode: Vue.VNode): string | undefined { - if (!vnode.data || (!vnode.data.staticClass && !vnode.data.class)) { - return undefined; - } - - return ( - [...(vnode.data.staticClass?.split(' ') ?? []), ...normalizeClassBinding(vnode.data.class)] - .filter(Boolean) - .join(' ') || undefined - ); -} - -// https://vuejs.org/v2/guide/class-and-style.html#Binding-HTML-Classes -function normalizeClassBinding(binding: unknown): readonly string[] { - if (!binding) { - return []; - } - - if (typeof binding === 'string') { - return [binding]; - } - - if (binding instanceof Array) { - // To handle an object-in-array binding smartly, we use recursion - return binding.map(normalizeClassBinding).reduce((a, b) => [...a, ...b], []); - } - - if (typeof binding === 'object') { - return Object.entries(binding) - .filter(([, active]) => !!active) - .map(([className]) => className); - } - - // Unknown class binding - return []; -} - -function stringifyAttr(attrName: string, value?: any): string | null { - if (typeof value === 'undefined' || typeof value === 'function') { - return null; - } - - if (value === true) { - return attrName; - } - - if (typeof value === 'string') { - return `${attrName}=${quote(value)}`; - } - - // TODO: Better serialization (unquoted object key, Symbol/Classes, etc...) - // Seems like Prettier don't format JSON-look object (= when keys are quoted) - return `:${attrName}=${quote(JSON.stringify(value))}`; -} - -function quote(value: string) { - return value.includes(`"`) && !value.includes(`'`) - ? `'${value}'` - : `"${value.replace(/"/g, '"')}"`; -} - -/** - * Skip decorators and grab a story component itself. - * https://github.com/pocka/storybook-addon-vue-info/pull/113 - */ -function getStoryComponent(w: any) { - let matched = w; - - while ( - matched && - matched.options && - matched.options.components && - matched.options.components.story && - matched.options.components.story.options && - matched.options.components.story.options.STORYBOOK_WRAPS - ) { - matched = matched.options.components.story.options.STORYBOOK_WRAPS; - } - return matched; -} - -interface VueInternal { - // We need to access this private property, in order to grab the vnode of the - // component instead of the "vnode of the parent of the component". - // Probably it's safe to rely on this because vm.$vnode is a reference for this. - // https://github.com/vuejs/vue/issues/6070#issuecomment-314389883 - _vnode: Vue.VNode; -} - -/** - * Find the story's instance from VNode tree. - */ -function lookupStoryInstance(instance: Vue, storyComponent: any): (Vue & VueInternal) | null { - if ( - instance.$vnode && - instance.$vnode.componentOptions && - instance.$vnode.componentOptions.Ctor === storyComponent - ) { - return instance as Vue & VueInternal; - } - - for (let i = 0, l = instance.$children.length; i < l; i += 1) { - const found = lookupStoryInstance(instance.$children[i], storyComponent); - - if (found) { - return found; - } - } - - return null; -} diff --git a/code/renderers/vue/src/entry-preview-docs.ts b/code/renderers/vue/src/entry-preview-docs.ts deleted file mode 100644 index bd5af4e3f916..000000000000 --- a/code/renderers/vue/src/entry-preview-docs.ts +++ /dev/null @@ -1,17 +0,0 @@ -import type { ArgTypesEnhancer, DecoratorFunction } from '@storybook/types'; -import { extractComponentDescription, enhanceArgTypes } from '@storybook/docs-tools'; -import { extractArgTypes } from './docs/extractArgTypes'; -import { sourceDecorator } from './docs/sourceDecorator'; -import type { VueRenderer } from './types'; - -export const parameters = { - docs: { - story: { inline: true, iframeHeight: '120px' }, - extractArgTypes, - extractComponentDescription, - }, -}; - -export const decorators: DecoratorFunction[] = [sourceDecorator]; - -export const argTypesEnhancers: ArgTypesEnhancer[] = [enhanceArgTypes]; diff --git a/code/renderers/vue/src/entry-preview.ts b/code/renderers/vue/src/entry-preview.ts deleted file mode 100644 index 2110e13bcf0c..000000000000 --- a/code/renderers/vue/src/entry-preview.ts +++ /dev/null @@ -1,3 +0,0 @@ -export const parameters: {} = { renderer: 'vue' }; -export { render, renderToCanvas } from './render'; -export { decorateStory as applyDecorators } from './decorateStory'; diff --git a/code/renderers/vue/src/globals.ts b/code/renderers/vue/src/globals.ts deleted file mode 100644 index f91a342510a2..000000000000 --- a/code/renderers/vue/src/globals.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { global } from '@storybook/global'; - -const { window: globalWindow } = global; - -globalWindow.STORYBOOK_ENV = 'vue'; diff --git a/code/renderers/vue/src/index.ts b/code/renderers/vue/src/index.ts deleted file mode 100644 index 145fbf2612ea..000000000000 --- a/code/renderers/vue/src/index.ts +++ /dev/null @@ -1,8 +0,0 @@ -/// - -import './globals'; - -export * from './public-types'; - -// optimization: stop HMR propagation in webpack -if (typeof module !== 'undefined') module?.hot?.decline(); diff --git a/code/renderers/vue/src/preset.ts b/code/renderers/vue/src/preset.ts deleted file mode 100644 index 03b11e7e6097..000000000000 --- a/code/renderers/vue/src/preset.ts +++ /dev/null @@ -1,15 +0,0 @@ -import type { PresetProperty } from '@storybook/types'; -import { join } from 'path'; - -export const previewAnnotations: PresetProperty<'previewAnnotations'> = async ( - input = [], - options -) => { - const docsEnabled = Object.keys(await options.presets.apply('docs', {}, options)).length > 0; - const result: string[] = []; - - return result - .concat(input) - .concat([join(__dirname, 'entry-preview.mjs')]) - .concat(docsEnabled ? [join(__dirname, 'entry-preview-docs.mjs')] : []); -}; diff --git a/code/renderers/vue/src/public-types.test.ts b/code/renderers/vue/src/public-types.test.ts deleted file mode 100644 index 0f3b90fbe04d..000000000000 --- a/code/renderers/vue/src/public-types.test.ts +++ /dev/null @@ -1,175 +0,0 @@ -import { satisfies } from '@storybook/core-common'; -import type { ComponentAnnotations, StoryAnnotations } from '@storybook/types'; -import { expectTypeOf } from 'expect-type'; -import type { SetOptional } from 'type-fest'; -import type { Component } from 'vue'; -import type { ExtendedVue } from 'vue/types/vue'; -import { Vue } from 'vue/types/vue'; -import type { Decorator, Meta, StoryObj } from './public-types'; -import Button from './__tests__/Button.vue'; -import type { VueRenderer } from './types'; - -describe('Meta', () => { - test('Generic parameter of Meta can be a component', () => { - const meta: Meta = { - component: Button, - args: { label: 'good', disabled: false }, - }; - - expectTypeOf(meta).toEqualTypeOf< - ComponentAnnotations< - VueRenderer, - { - disabled: boolean; - label: string; - } - > - >(); - }); - - test('Generic parameter of Meta can be the props of the component', () => { - const meta: Meta<{ disabled: boolean; label: string }> = { - component: Button, - args: { label: 'good', disabled: false }, - }; - - expectTypeOf(meta).toEqualTypeOf< - ComponentAnnotations - >(); - }); -}); - -describe('StoryObj', () => { - type ButtonProps = { - disabled: boolean; - label: string; - }; - - test('βœ… Required args may be provided partial in meta and the story', () => { - const meta = satisfies>()({ - component: Button, - args: { label: 'good' }, - }); - - type Actual = StoryObj; - type Expected = StoryAnnotations>; - expectTypeOf().toEqualTypeOf(); - }); - - test('❌ The combined shape of meta args and story args must match the required args.', () => { - { - const meta = satisfies>()({ component: Button }); - - type Expected = StoryAnnotations; - expectTypeOf>().toEqualTypeOf(); - } - { - const meta = satisfies>()({ - component: Button, - args: { label: 'good' }, - }); - // @ts-expect-error disabled not provided ❌ - const Basic: StoryObj = {}; - - type Expected = StoryAnnotations>; - expectTypeOf(Basic).toEqualTypeOf(); - } - { - const meta = satisfies>()({ component: Button }); - const Basic: StoryObj = { - // @ts-expect-error disabled not provided ❌ - args: { label: 'good' }, - }; - - type Expected = StoryAnnotations; - expectTypeOf(Basic).toEqualTypeOf(); - } - }); - - test('Component can be used as generic parameter for StoryObj', () => { - expectTypeOf>().toEqualTypeOf< - StoryAnnotations - >(); - }); -}); - -type ThemeData = 'light' | 'dark'; - -type ComponentProps = C extends ExtendedVue - ? P - : C extends Component - ? P - : unknown; - -describe('Story args can be inferred', () => { - test('Correct args are inferred when type is widened for render function', () => { - type Props = ComponentProps & { theme: ThemeData }; - - const meta = satisfies>()({ - component: Button, - args: { disabled: false }, - render: (args) => - Vue.extend({ - components: { Button }, - template: `
Using the theme: ${args.theme}
`, - props: Object.keys(args), - }), - }); - - const Basic: StoryObj = { args: { theme: 'light', label: 'good' } }; - - type Expected = StoryAnnotations>; - expectTypeOf(Basic).toEqualTypeOf(); - }); - - const withDecorator: Decorator<{ decoratorArg: string }> = ( - storyFn, - { args: { decoratorArg } } - ) => - Vue.extend({ - components: { Story: storyFn() }, - template: `
Decorator: ${decoratorArg}
`, - }); - - test('Correct args are inferred when type is widened for decorators', () => { - type Props = ComponentProps & { decoratorArg: string }; - - const meta = satisfies>()({ - component: Button, - args: { disabled: false }, - decorators: [withDecorator], - }); - - const Basic: StoryObj = { args: { decoratorArg: 'title', label: 'good' } }; - - type Expected = StoryAnnotations>; - expectTypeOf(Basic).toEqualTypeOf(); - }); - - test('Correct args are inferred when type is widened for multiple decorators', () => { - type Props = ComponentProps & { decoratorArg: string; decoratorArg2: string }; - - const secondDecorator: Decorator<{ decoratorArg2: string }> = ( - storyFn, - { args: { decoratorArg2 } } - ) => { - return Vue.extend({ - components: { Story: storyFn() }, - template: `
Decorator: ${decoratorArg2}
`, - }); - }; - - const meta = satisfies>()({ - component: Button, - args: { disabled: false }, - decorators: [withDecorator, secondDecorator], - }); - - const Basic: StoryObj = { - args: { decoratorArg: '', decoratorArg2: '', label: 'good' }, - }; - - type Expected = StoryAnnotations>; - expectTypeOf(Basic).toEqualTypeOf(); - }); -}); diff --git a/code/renderers/vue/src/public-types.ts b/code/renderers/vue/src/public-types.ts deleted file mode 100644 index eb6c68699a96..000000000000 --- a/code/renderers/vue/src/public-types.ts +++ /dev/null @@ -1,89 +0,0 @@ -import type { - AnnotatedStoryFn, - Args, - ArgsFromMeta, - ArgsStoryFn, - ComponentAnnotations, - DecoratorFunction, - LoaderFunction, - StoryAnnotations, - StoryContext as GenericStoryContext, - StrictArgs, - ProjectAnnotations, -} from '@storybook/types'; -import type { SetOptional, Simplify } from 'type-fest'; -import type { Component } from 'vue'; -import type { ExtendedVue } from 'vue/types/vue'; -import type { VueRenderer } from './types'; - -export type { Args, ArgTypes, Parameters, StrictArgs } from '@storybook/types'; -export type { VueRenderer }; - -/** - * Metadata to configure the stories for a component. - * - * @see [Default export](https://storybook.js.org/docs/formats/component-story-format/#default-export) - */ -export type Meta = ComponentAnnotations< - VueRenderer, - ComponentPropsOrProps ->; - -/** - * Story function that represents a CSFv2 component example. - * - * @see [Named Story exports](https://storybook.js.org/docs/formats/component-story-format/#named-story-exports) - */ -export type StoryFn = AnnotatedStoryFn< - VueRenderer, - ComponentPropsOrProps ->; - -/** - * Story function that represents a CSFv3 component example. - * - * @see [Named Story exports](https://storybook.js.org/docs/formats/component-story-format/#named-story-exports) - */ -export type StoryObj = TMetaOrCmpOrArgs extends { - render?: ArgsStoryFn; - component?: infer C; - args?: infer DefaultArgs; -} - ? TMetaOrCmpOrArgs extends Component // needed because StoryObj falls into this branch, see test - ? StoryAnnotations> - : Simplify & ArgsFromMeta> extends infer TArgs - ? StoryAnnotations< - VueRenderer, - TArgs, - SetOptional> - > - : never - : StoryAnnotations>; - -type ComponentProps = C extends ExtendedVue - ? P - : C extends Component - ? P - : unknown; - -type ComponentPropsOrProps = TCmpOrArgs extends Component - ? unknown extends ComponentProps - ? TCmpOrArgs - : ComponentProps - : TCmpOrArgs; - -/** - * @deprecated Use `StoryFn` instead. - * Use `StoryObj` if you want to migrate to CSF3, which uses objects instead of functions to represent stories. - * You can read more about the CSF3 format here: https://storybook.js.org/blog/component-story-format-3-0/ - * - * Story function that represents a CSFv2 component example. - * - * @see [Named Story exports](https://storybook.js.org/docs/formats/component-story-format/#named-story-exports) - */ -export type Story = StoryFn; - -export type Decorator = DecoratorFunction; -export type Loader = LoaderFunction; -export type StoryContext = GenericStoryContext; -export type Preview = ProjectAnnotations; diff --git a/code/renderers/vue/src/render.ts b/code/renderers/vue/src/render.ts deleted file mode 100644 index f7f75893336e..000000000000 --- a/code/renderers/vue/src/render.ts +++ /dev/null @@ -1,157 +0,0 @@ -/* eslint-disable no-underscore-dangle */ -import { dedent } from 'ts-dedent'; -import Vue from 'vue'; -import type { RenderContext, ArgsStoryFn } from '@storybook/types'; -import type { CombinedVueInstance } from 'vue/types/vue'; -import type { VueRenderer } from './types'; - -export const COMPONENT = 'STORYBOOK_COMPONENT'; -export const VALUES = 'STORYBOOK_VALUES'; - -const map = new Map(); -type Instance = CombinedVueInstance< - Vue, - { - STORYBOOK_COMPONENT: any; - STORYBOOK_VALUES: Record; - }, - object, - object, - Record ->; - -const getRoot = (canvasElement: VueRenderer['canvasElement']): Instance => { - const cachedInstance = map.get(canvasElement); - if (cachedInstance != null) return cachedInstance; - - // Create a dummy "target" underneath #storybook-root - // that Vue2 will replace on first render with #storybook-vue-root - const target = document.createElement('div'); - canvasElement.appendChild(target); - - const instance: Instance = new Vue({ - beforeDestroy() { - map.delete(canvasElement); - }, - data() { - return { - [COMPONENT]: undefined, - [VALUES]: {}, - }; - }, - // @ts-expect-error What's going on here? (TS says that we should not return an array here, but the `h` directly) - render(h) { - map.set(canvasElement, instance); - return this[COMPONENT] ? [h(this[COMPONENT])] : undefined; - }, - }); - - return instance; -}; - -export const render: ArgsStoryFn = (args, context) => { - const { id, component: Component, argTypes } = context; - const component = Component as VueRenderer['component'] & { - __docgenInfo?: { displayName: string }; - props: Record; - }; - - if (!component) { - throw new Error( - `Unable to render story ${id} as the component annotation is missing from the default export` - ); - } - - let componentName = 'component'; - - // if there is a name property, we either use it or preprend with sb- in case it's an invalid name - if (component.name) { - // @ts-expect-error isReservedTag is an internal function from Vue, might be changed in future releases - const isReservedTag = Vue.config.isReservedTag && Vue.config.isReservedTag(component.name); - - componentName = isReservedTag ? `sb-${component.name}` : component.name; - } else if (component.__docgenInfo?.displayName) { - // otherwise, we use the displayName from docgen, if present - componentName = component.__docgenInfo?.displayName; - } - - let eventsBinding = ''; - const eventProps = Object.values(argTypes) - .filter((argType) => argType?.table?.category === 'events') - .map((argType) => argType.name); - - const camelCase = (str: string) => str.replace(/-([a-z])/g, (g) => g[1].toUpperCase()); - - if (eventProps.length) { - eventsBinding = eventProps.map((name) => `@${name}="$props['${camelCase(name)}']"`).join(' '); - } - - return { - props: Object.keys(argTypes), - components: { [componentName]: component }, - template: `<${componentName} ${eventsBinding} v-bind="filterOutEventProps($props)" />`, - methods: { - filterOutEventProps(props: object) { - return Object.fromEntries( - Object.entries(props).filter(([key]) => !eventProps.includes(key)) - ); - }, - }, - }; -}; - -export function renderToCanvas( - { - title, - name, - storyFn, - showMain, - showError, - showException, - forceRemount, - }: RenderContext, - canvasElement: VueRenderer['canvasElement'] -) { - const root = getRoot(canvasElement); - Vue.config.errorHandler = showException; - const element = storyFn(); - - let mountTarget: Element | VueRenderer['canvasElement'] | null; - - // Vue2 mount always replaces the mount target with Vue-generated DOM. - // https://v2.vuejs.org/v2/api/#el:~:text=replaced%20with%20Vue%2Dgenerated%20DOM - // We cannot mount to the canvasElement directly, because it would be replaced. That would - // break the references to the canvasElement like canvasElement used in the play function. - // Instead, we mount to a child element of the canvasElement, creating one if necessary. - if (canvasElement.hasChildNodes()) { - mountTarget = canvasElement.firstElementChild; - } else { - mountTarget = document.createElement('div'); - canvasElement.appendChild(mountTarget); - } - - if (!element) { - showError({ - title: `Expecting a Vue component from the story: "${name}" of "${title}".`, - description: dedent` - Did you forget to return the Vue component from the story? - Use "() => ({ template: '' })" or "() => ({ components: MyComp, template: '' })" when defining the story. - `, - }); - return; - } - - // at component creation || refresh by HMR or switching stories - if (!root[COMPONENT] || forceRemount) { - root[COMPONENT] = element; - } - - // @ts-expect-error https://github.com/storybookjs/storrybook/pull/7578#discussion_r307986139 - root[VALUES] = { ...element.options[VALUES] }; - - if (!map.has(canvasElement)) { - root.$mount(mountTarget ?? undefined); - } - - showMain(); -} diff --git a/code/renderers/vue/src/types.ts b/code/renderers/vue/src/types.ts deleted file mode 100644 index 4ae4c9c4ab3c..000000000000 --- a/code/renderers/vue/src/types.ts +++ /dev/null @@ -1,24 +0,0 @@ -import type { StoryContext as StoryContextBase, WebRenderer } from '@storybook/types'; -import type { Component, AsyncComponent } from 'vue'; - -export type { RenderContext } from '@storybook/types'; - -export interface ShowErrorArgs { - title: string; - description: string; -} - -export type StoryFnVueReturnType = - | Component - | AsyncComponent; - -export type StoryContext = StoryContextBase; - -/** - * @deprecated Use `VueRenderer` instead. - */ -export type VueFramework = VueRenderer; -export interface VueRenderer extends WebRenderer { - component: Component | AsyncComponent; - storyResult: StoryFnVueReturnType; -} diff --git a/code/renderers/vue/src/typings.d.ts b/code/renderers/vue/src/typings.d.ts deleted file mode 100644 index daefb35a5f65..000000000000 --- a/code/renderers/vue/src/typings.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -declare var STORYBOOK_ENV: 'vue'; -declare var LOGLEVEL: 'trace' | 'debug' | 'info' | 'warn' | 'error' | 'silent' | undefined; diff --git a/code/renderers/vue/src/util.ts b/code/renderers/vue/src/util.ts deleted file mode 100644 index 303c750b28cc..000000000000 --- a/code/renderers/vue/src/util.ts +++ /dev/null @@ -1,24 +0,0 @@ -/* eslint-disable @typescript-eslint/ban-types */ -import type { VueConstructor } from 'vue'; - -function getType(fn: Function) { - const match = fn && fn.toString().match(/^\s*function (\w+)/); - return match ? match[1] : ''; -} - -// https://github.com/vuejs/vue/blob/dev/src/core/util/props.js#L92 -function resolveDefault({ type, default: def }: any) { - if (typeof def === 'function' && getType(type) !== 'Function') { - // known limitation: we don't have the component instance to pass - return def.call(); - } - - return def; -} - -export function extractProps(component: VueConstructor) { - // @ts-expect-error this options business seems not good according to the types - return Object.entries(component.options.props || {}) - .map(([name, prop]) => ({ [name]: resolveDefault(prop) })) - .reduce((wrap, prop) => ({ ...wrap, ...prop }), {}); -} diff --git a/code/renderers/vue/template/cli/Button.stories.js b/code/renderers/vue/template/cli/Button.stories.js deleted file mode 100644 index ac1fe487803b..000000000000 --- a/code/renderers/vue/template/cli/Button.stories.js +++ /dev/null @@ -1,48 +0,0 @@ -import MyButton from './Button.vue'; - -// More on how to set up stories at: https://storybook.js.org/docs/writing-stories -export default { - title: 'Example/Button', - component: MyButton, - tags: ['autodocs'], - render: (args, { argTypes }) => ({ - props: Object.keys(argTypes), - components: { MyButton }, - template: '', - }), - argTypes: { - backgroundColor: { control: 'color' }, - size: { - control: { type: 'select' }, - options: ['small', 'medium', 'large'], - }, - }, -}; - -// More on writing stories with args: https://storybook.js.org/docs/writing-stories/args -export const Primary = { - args: { - primary: true, - label: 'Button', - }, -}; - -export const Secondary = { - args: { - label: 'Button', - }, -}; - -export const Large = { - args: { - size: 'large', - label: 'Button', - }, -}; - -export const Small = { - args: { - size: 'small', - label: 'Button', - }, -}; diff --git a/code/renderers/vue/template/cli/Button.vue b/code/renderers/vue/template/cli/Button.vue deleted file mode 100644 index 864a2638ac5f..000000000000 --- a/code/renderers/vue/template/cli/Button.vue +++ /dev/null @@ -1,54 +0,0 @@ - - - diff --git a/code/renderers/vue/template/cli/Header.stories.js b/code/renderers/vue/template/cli/Header.stories.js deleted file mode 100644 index 553cd469b48b..000000000000 --- a/code/renderers/vue/template/cli/Header.stories.js +++ /dev/null @@ -1,30 +0,0 @@ -import MyHeader from './Header.vue'; - -export default { - title: 'Example/Header', - component: MyHeader, - // This component will have an automatically generated Autodocs entry: https://storybook.js.org/docs/writing-docs/autodocs - tags: ['autodocs'], - render: (args, { argTypes }) => ({ - props: Object.keys(argTypes), - components: { - MyHeader, - }, - template: - '', - }), - parameters: { - // More on how to position stories at: https://storybook.js.org/docs/configure/story-layout - layout: 'fullscreen', - }, -}; - -export const LoggedIn = { - args: { - user: { - name: 'Jane Doe', - }, - }, -}; - -export const LoggedOut = {}; diff --git a/code/renderers/vue/template/cli/Header.vue b/code/renderers/vue/template/cli/Header.vue deleted file mode 100644 index 4164c64bb144..000000000000 --- a/code/renderers/vue/template/cli/Header.vue +++ /dev/null @@ -1,63 +0,0 @@ - - - diff --git a/code/renderers/vue/template/cli/Page.stories.js b/code/renderers/vue/template/cli/Page.stories.js deleted file mode 100644 index e0b3309c2512..000000000000 --- a/code/renderers/vue/template/cli/Page.stories.js +++ /dev/null @@ -1,30 +0,0 @@ -import { within, userEvent, expect } from '@storybook/test'; -import MyPage from './Page.vue'; - -export default { - title: 'Example/Page', - component: MyPage, - render: () => ({ - components: { MyPage }, - template: '', - }), - parameters: { - // More on how to position stories at: https://storybook.js.org/docs/configure/story-layout - layout: 'fullscreen', - }, -}; -export const LoggedOut = {}; - -// More on interaction testing: https://storybook.js.org/docs/writing-tests/interaction-testing -export const LoggedIn = { - play: async ({ canvasElement }) => { - const canvas = within(canvasElement); - const loginButton = canvas.getByRole('button', { name: /Log in/i }); - await expect(loginButton).toBeInTheDocument(); - await userEvent.click(loginButton); - await expect(loginButton).not.toBeInTheDocument(); - - const logoutButton = canvas.getByRole('button', { name: /Log out/i }); - await expect(logoutButton).toBeInTheDocument(); - }, -}; diff --git a/code/renderers/vue/template/cli/Page.vue b/code/renderers/vue/template/cli/Page.vue deleted file mode 100644 index c57bfa7b10d5..000000000000 --- a/code/renderers/vue/template/cli/Page.vue +++ /dev/null @@ -1,88 +0,0 @@ - - - diff --git a/code/renderers/vue/template/components/Button.vue b/code/renderers/vue/template/components/Button.vue deleted file mode 100644 index 864a2638ac5f..000000000000 --- a/code/renderers/vue/template/components/Button.vue +++ /dev/null @@ -1,54 +0,0 @@ - - - diff --git a/code/renderers/vue/template/components/Form.vue b/code/renderers/vue/template/components/Form.vue deleted file mode 100644 index 2375a381eb7a..000000000000 --- a/code/renderers/vue/template/components/Form.vue +++ /dev/null @@ -1,47 +0,0 @@ - - - diff --git a/code/renderers/vue/template/components/Html.vue b/code/renderers/vue/template/components/Html.vue deleted file mode 100644 index 5b14a6b1a9ab..000000000000 --- a/code/renderers/vue/template/components/Html.vue +++ /dev/null @@ -1,16 +0,0 @@ - - - diff --git a/code/renderers/vue/template/components/Pre.vue b/code/renderers/vue/template/components/Pre.vue deleted file mode 100644 index eda0553dce3d..000000000000 --- a/code/renderers/vue/template/components/Pre.vue +++ /dev/null @@ -1,29 +0,0 @@ - - - diff --git a/code/renderers/vue/template/components/button.css b/code/renderers/vue/template/components/button.css deleted file mode 100644 index dc91dc76370b..000000000000 --- a/code/renderers/vue/template/components/button.css +++ /dev/null @@ -1,30 +0,0 @@ -.storybook-button { - font-family: 'Nunito Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif; - font-weight: 700; - border: 0; - border-radius: 3em; - cursor: pointer; - display: inline-block; - line-height: 1; -} -.storybook-button--primary { - color: white; - background-color: #1ea7fd; -} -.storybook-button--secondary { - color: #333; - background-color: transparent; - box-shadow: rgba(0, 0, 0, 0.15) 0px 0px 0px 1px inset; -} -.storybook-button--small { - font-size: 12px; - padding: 10px 16px; -} -.storybook-button--medium { - font-size: 14px; - padding: 11px 20px; -} -.storybook-button--large { - font-size: 16px; - padding: 12px 24px; -} diff --git a/code/renderers/vue/template/components/index.js b/code/renderers/vue/template/components/index.js deleted file mode 100644 index 342dc4a7a988..000000000000 --- a/code/renderers/vue/template/components/index.js +++ /dev/null @@ -1,13 +0,0 @@ -import { global as globalThis } from '@storybook/global'; -import Vue from 'vue'; - -import Button from './Button.vue'; -import Pre from './Pre.vue'; -import Form from './Form.vue'; -import Html from './Html.vue'; - -globalThis.Components = { Button, Pre, Form, Html }; -globalThis.storybookRenderer = 'vue'; - -// test globally-registered components -Vue.component('global-button', Button); diff --git a/code/renderers/vue/template/stories/core-template.stories.js b/code/renderers/vue/template/stories/core-template.stories.js deleted file mode 100644 index eedcf0486e6f..000000000000 --- a/code/renderers/vue/template/stories/core-template.stories.js +++ /dev/null @@ -1,6 +0,0 @@ -export default { - // we just need something here to make this valid CSF - component: {}, -}; - -export const StringOnly = () => ''; diff --git a/code/renderers/vue/template/stories/custom-decorators.stories.js b/code/renderers/vue/template/stories/custom-decorators.stories.js deleted file mode 100644 index 1415f6987614..000000000000 --- a/code/renderers/vue/template/stories/custom-decorators.stories.js +++ /dev/null @@ -1,43 +0,0 @@ -import { global as globalThis } from '@storybook/global'; - -const MyButton = globalThis.Components.Button; - -export default { - component: {}, - decorators: [ - (storyFn) => { - // Decorated with story-function - const WrapButton = storyFn({ customContext: 52, parameters: { customParameter: 42 } }); - return { - components: { WrapButton }, - template: '
', - data() { - return { borderStyle: 'medium solid red' }; - }, - }; - }, - () => ({ - // Decorated with `story` component - template: '
', - data() { - return { - borderStyle: 'medium solid blue', - }; - }, - }), - ], -}; - -export const Template = () => ({ - template: '', -}); - -export const WithData = (_args, { parameters: { fileName, ...parameters }, hooks, ...rest }) => ({ - template: `
${JSON.stringify({ ...rest, parameters }, null, 2)}
`, -}); - -export const Render = () => ({ - render(h) { - return h(MyButton, { props: { color: 'pink', label: 'renders component: MyButton' } }); - }, -}); diff --git a/code/renderers/vue/template/stories/custom-rendering.stories.js b/code/renderers/vue/template/stories/custom-rendering.stories.js deleted file mode 100644 index 39032b05f8f7..000000000000 --- a/code/renderers/vue/template/stories/custom-rendering.stories.js +++ /dev/null @@ -1,62 +0,0 @@ -import { global as globalThis } from '@storybook/global'; - -const MyButton = globalThis.Components.Button; - -export default { - component: {}, -}; - -export const Render = () => ({ - render: (h) => h('div', ['renders a div with some text in it..']), -}); - -export const RenderComponent = () => ({ - render(h) { - return h(MyButton, { props: { color: 'pink', label: 'renders component: MyButton' } }); - }, -}); - -export const Template = () => ({ - template: ` -
-

A template

-

rendered in vue in storybook

-
`, -}); - -export const TemplateComponent = () => ({ - components: { MyButton }, - template: '', -}); - -export const TemplateMethods = () => ({ - components: { MyButton }, - template: ` -

- Clicking the button will navigate to another story using the 'addon-links'
- -

`, - methods: { - action: () => {}, - }, -}); - -// FIXME: test JSX? -// export const JSX = () => ({ -// components: { MyButton }, -// render() { -// // eslint-disable-next-line react/react-in-jsx-scope, react/no-children-prop -// return ; -// }, -// }); - -export const PreRegisteredComponent = () => ({ - /* By pre-registering component in preview.js, - * the need to register all components with each story is removed. - * You'll only need the template */ - template: ` -

- This component was pre-registered in .storybook/preview.js
- -

`, -}); diff --git a/code/renderers/vue/template/stories/vue-mdx.stories.mdx b/code/renderers/vue/template/stories/vue-mdx.stories.mdx deleted file mode 100644 index 067d9af4eb6b..000000000000 --- a/code/renderers/vue/template/stories/vue-mdx.stories.mdx +++ /dev/null @@ -1,44 +0,0 @@ -import { global as globalThis } from '@storybook/global'; -import { Meta, Story, Canvas } from '@storybook/addon-docs'; - - - -# Vue-specific MDX Stories - -export const Button = globalThis.Components.Button; - -export const Template = (args, { argTypes }) => ({ - props: Object.keys(argTypes), - components: { MyButton: Button }, - template: '', -}); - -## Primary - - - - {{ - components: { MyButton: Button }, - template: '', - }} - - - -## Secondary - - - - {{ - components: { MyButton: Button }, - template: '', - }} - - - -## From template - - - - {Template.bind({})} - - diff --git a/code/renderers/vue/tsconfig.json b/code/renderers/vue/tsconfig.json deleted file mode 100644 index 4fbfb70f6d7b..000000000000 --- a/code/renderers/vue/tsconfig.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "extends": "../../tsconfig.json", - "compilerOptions": { - "strict": true, - "skipLibCheck": true, - "resolveJsonModule": true, - "allowJs": true - }, - "vueCompilerOptions": { - "target": 2 - }, - "include": ["src/**/*", "src/**/*.vue", "template/**/*", "template/**/*.vue"] -} diff --git a/code/ui/blocks/src/blocks/Subheading.tsx b/code/ui/blocks/src/blocks/Subheading.tsx index 02f35bf63fdf..57cf5223be51 100644 --- a/code/ui/blocks/src/blocks/Subheading.tsx +++ b/code/ui/blocks/src/blocks/Subheading.tsx @@ -8,7 +8,7 @@ export const Subheading: FC> = ({ children, disa if (disableAnchor || typeof children !== 'string') { return

{children}

; } - const tagID = children.toLowerCase().replace(/[^a-z0-9]/gi, '-'); + const tagID = globalThis.encodeURIComponent(children.toLowerCase()); return ( {children} diff --git a/code/yarn.lock b/code/yarn.lock index 551e676483a2..b20f98adbe2a 100644 --- a/code/yarn.lock +++ b/code/yarn.lock @@ -690,7 +690,7 @@ __metadata: languageName: node linkType: hard -"@babel/parser@npm:^7.1.0, @babel/parser@npm:^7.11.5, @babel/parser@npm:^7.13.16, @babel/parser@npm:^7.14.7, @babel/parser@npm:^7.18.4, @babel/parser@npm:^7.20.7, @babel/parser@npm:^7.21.4, @babel/parser@npm:^7.22.15, @babel/parser@npm:^7.23.0, @babel/parser@npm:^7.23.3, @babel/parser@npm:^7.23.5, @babel/parser@npm:^7.4.5, @babel/parser@npm:^7.6.0, @babel/parser@npm:^7.7.0, @babel/parser@npm:^7.9.6": +"@babel/parser@npm:^7.1.0, @babel/parser@npm:^7.11.5, @babel/parser@npm:^7.13.16, @babel/parser@npm:^7.14.7, @babel/parser@npm:^7.20.7, @babel/parser@npm:^7.21.4, @babel/parser@npm:^7.22.15, @babel/parser@npm:^7.23.0, @babel/parser@npm:^7.23.3, @babel/parser@npm:^7.23.5, @babel/parser@npm:^7.4.5, @babel/parser@npm:^7.6.0, @babel/parser@npm:^7.7.0, @babel/parser@npm:^7.9.6": version: 7.23.5 resolution: "@babel/parser@npm:7.23.5" bin: @@ -4857,7 +4857,6 @@ __metadata: "@storybook/manager-api": "workspace:*" "@storybook/node-logger": "workspace:*" "@storybook/preview-api": "workspace:*" - "@storybook/vue": "workspace:*" ts-dedent: "npm:^2.0.0" typescript: "npm:^5.3.2" peerDependencies: @@ -6201,36 +6200,11 @@ __metadata: typescript: "npm:^5.3.2" peerDependencies: "@babel/core": "*" - svelte: ^3.1.0 || ^4.0.0 + svelte: ^4.0.0 || ^5.0.0-next.16 svelte-loader: "*" languageName: unknown linkType: soft -"@storybook/preset-vue-webpack@workspace:*, @storybook/preset-vue-webpack@workspace:presets/vue-webpack": - version: 0.0.0-use.local - resolution: "@storybook/preset-vue-webpack@workspace:presets/vue-webpack" - dependencies: - "@storybook/core-webpack": "workspace:*" - "@storybook/docs-tools": "workspace:*" - "@types/node": "npm:^18.0.0" - ts-loader: "npm:^9.2.8" - typescript: "npm:^5.3.2" - vue: "npm:^2.6.12" - vue-docgen-api: "npm:^4.44.23" - vue-docgen-loader: "npm:^1.5.1" - vue-loader: "npm:^15.7.0" - vue-template-compiler: "npm:^2.6.14" - webpack: "npm:5" - peerDependencies: - "@babel/core": "*" - babel-loader: ^7.0.0 || ^8.0.0 || ^9.0.0 - css-loader: "*" - vue: ^2.6.8 - vue-loader: ^15.7.0 - vue-template-compiler: ^2.6.14 - languageName: unknown - linkType: soft - "@storybook/preset-vue3-webpack@workspace:*, @storybook/preset-vue3-webpack@workspace:presets/vue3-webpack": version: 0.0.0-use.local resolution: "@storybook/preset-vue3-webpack@workspace:presets/vue3-webpack" @@ -6497,7 +6471,6 @@ __metadata: "@storybook/preset-react-webpack": "workspace:*" "@storybook/preset-server-webpack": "workspace:*" "@storybook/preset-svelte-webpack": "workspace:*" - "@storybook/preset-vue-webpack": "workspace:*" "@storybook/preset-vue3-webpack": "workspace:*" "@storybook/preset-web-components-webpack": "workspace:*" "@storybook/preview": "workspace:*" @@ -6515,8 +6488,6 @@ __metadata: "@storybook/testing-library": "npm:next" "@storybook/theming": "workspace:*" "@storybook/types": "workspace:*" - "@storybook/vue": "workspace:*" - "@storybook/vue-webpack5": "workspace:*" "@storybook/vue3": "workspace:*" "@storybook/vue3-vite": "workspace:*" "@storybook/vue3-webpack5": "workspace:*" @@ -6679,14 +6650,14 @@ __metadata: "@sveltejs/vite-plugin-svelte": "npm:^2.4.2" "@types/node": "npm:^18.0.0" magic-string: "npm:^0.30.0" - svelte: "npm:^4.0.0" - svelte-preprocess: "npm:^5.0.4" + svelte: "npm:^5.0.0-next.16" + svelte-preprocess: "npm:^5.1.1" sveltedoc-parser: "npm:^4.2.1" ts-dedent: "npm:^2.2.0" typescript: "npm:^5.3.2" vite: "npm:^4.0.0" peerDependencies: - svelte: ^3.0.0 || ^4.0.0 + svelte: ^4.0.0 || ^5.0.0-next.16 vite: ^3.0.0 || ^4.0.0 || ^5.0.0 languageName: unknown linkType: soft @@ -6704,7 +6675,7 @@ __metadata: typescript: "npm:^5.3.2" peerDependencies: "@babel/core": "*" - svelte: ^3.48.0 || ^4.0.0 + svelte: ^4.0.0 || ^5.0.0-next.16 svelte-loader: "*" languageName: unknown linkType: soft @@ -6720,14 +6691,14 @@ __metadata: "@storybook/preview-api": "workspace:*" "@storybook/types": "workspace:*" expect-type: "npm:^0.15.0" - svelte: "npm:^4.0.0" - svelte-check: "npm:3.4.6" + svelte: "npm:^5.0.0-next.15" + svelte-check: "npm:^3.6.1" sveltedoc-parser: "npm:^4.2.1" ts-dedent: "npm:^2.0.0" type-fest: "npm:~2.19" typescript: "npm:^5.3.2" peerDependencies: - svelte: ^3.1.0 || ^4.0.0 + svelte: ^4.0.0 || ^5.0.0-next.16 languageName: unknown linkType: soft @@ -6743,7 +6714,7 @@ __metadata: typescript: "npm:^5.3.2" vite: "npm:^4.0.0" peerDependencies: - svelte: ^3.0.0 || ^4.0.0 + svelte: ^4.0.0 || ^5.0.0-next.16 vite: ^4.0.0 languageName: unknown linkType: soft @@ -6854,48 +6825,6 @@ __metadata: languageName: unknown linkType: soft -"@storybook/vue-vite@workspace:frameworks/vue-vite": - version: 0.0.0-use.local - resolution: "@storybook/vue-vite@workspace:frameworks/vue-vite" - dependencies: - "@storybook/builder-vite": "workspace:*" - "@storybook/core-common": "workspace:*" - "@storybook/core-server": "workspace:*" - "@storybook/vue": "workspace:*" - magic-string: "npm:^0.30.0" - typescript: "npm:^5.3.2" - vite: "npm:^4.0.0" - vue: "npm:^2.7.10" - vue-docgen-api: "npm:^4.40.0" - peerDependencies: - vite: ^3.0.0 || ^4.0.0 || ^5.0.0 - vue: ^2.7.0 - languageName: unknown - linkType: soft - -"@storybook/vue-webpack5@workspace:*, @storybook/vue-webpack5@workspace:frameworks/vue-webpack5": - version: 0.0.0-use.local - resolution: "@storybook/vue-webpack5@workspace:frameworks/vue-webpack5" - dependencies: - "@storybook/builder-webpack5": "workspace:*" - "@storybook/core-common": "workspace:*" - "@storybook/preset-vue-webpack": "workspace:*" - "@storybook/vue": "workspace:*" - "@types/node": "npm:^18.0.0" - typescript: "npm:^5.3.2" - vue: "npm:^2.6.12" - vue-loader: "npm:^15.7.0" - vue-template-compiler: "npm:^2.6.14" - peerDependencies: - "@babel/core": "*" - babel-loader: ^7.0.0 || ^8.0.0 || ^9.0.0 - css-loader: "*" - vue: ^2.6.8 - vue-loader: ^15.7.0 - vue-template-compiler: ^2.6.8 - languageName: unknown - linkType: soft - "@storybook/vue3-vite@workspace:*, @storybook/vue3-vite@workspace:frameworks/vue3-vite": version: 0.0.0-use.local resolution: "@storybook/vue3-vite@workspace:frameworks/vue3-vite" @@ -6960,32 +6889,6 @@ __metadata: languageName: unknown linkType: soft -"@storybook/vue@workspace:*, @storybook/vue@workspace:renderers/vue": - version: 0.0.0-use.local - resolution: "@storybook/vue@workspace:renderers/vue" - dependencies: - "@storybook/client-logger": "workspace:*" - "@storybook/docs-tools": "workspace:*" - "@storybook/global": "npm:^5.0.0" - "@storybook/preview-api": "workspace:*" - "@storybook/types": "workspace:*" - tiny-invariant: "npm:^1.3.1" - ts-dedent: "npm:^2.0.0" - type-fest: "npm:~2.19" - typescript: "npm:^5.3.2" - vue: "npm:2.6.14" - vue-tsc: "npm:latest" - peerDependencies: - "@babel/core": "*" - babel-loader: ^7.0.0 || ^8.0.0 || ^9.0.0 - css-loader: "*" - vue: ^2.6.8 - peerDependenciesMeta: - babel-loader: - optional: true - languageName: unknown - linkType: soft - "@storybook/web-components-vite@workspace:*, @storybook/web-components-vite@workspace:frameworks/web-components-vite": version: 0.0.0-use.local resolution: "@storybook/web-components-vite@workspace:frameworks/web-components-vite" @@ -8951,17 +8854,6 @@ __metadata: languageName: node linkType: hard -"@vue/compiler-sfc@npm:2.7.15": - version: 2.7.15 - resolution: "@vue/compiler-sfc@npm:2.7.15" - dependencies: - "@babel/parser": "npm:^7.18.4" - postcss: "npm:^8.4.14" - source-map: "npm:^0.6.1" - checksum: d5dc7667bea091702657cd9263371d407d708ab0a571da01ebff5870b7800ac709678285c7dc86ae23a0757ff8a5de13dceffc063687be6a7700f58519bd5f57 - languageName: node - linkType: hard - "@vue/compiler-sfc@npm:3.0.0": version: 3.0.0 resolution: "@vue/compiler-sfc@npm:3.0.0" @@ -9026,26 +8918,6 @@ __metadata: languageName: node linkType: hard -"@vue/component-compiler-utils@npm:^3.1.0": - version: 3.3.0 - resolution: "@vue/component-compiler-utils@npm:3.3.0" - dependencies: - consolidate: "npm:^0.15.1" - hash-sum: "npm:^1.0.2" - lru-cache: "npm:^4.1.2" - merge-source-map: "npm:^1.1.0" - postcss: "npm:^7.0.36" - postcss-selector-parser: "npm:^6.0.2" - prettier: "npm:^1.18.2 || ^2.0.0" - source-map: "npm:~0.6.1" - vue-template-es2015-compiler: "npm:^1.9.0" - dependenciesMeta: - prettier: - optional: true - checksum: ab471a561c29a307b92d019be9f0404157d7bec4ac5040bffea918db4fadc784765a52d9621bef9330a108eb123d1bcb4c276bf1c53fd6f4ac022739b3b80cbe - languageName: node - linkType: hard - "@vue/language-core@npm:1.8.24": version: 1.8.24 resolution: "@vue/language-core@npm:1.8.24" @@ -9482,6 +9354,15 @@ __metadata: languageName: node linkType: hard +"acorn-typescript@npm:^1.4.11": + version: 1.4.12 + resolution: "acorn-typescript@npm:1.4.12" + peerDependencies: + acorn: ">=8.9.0" + checksum: a3b33ed0dc321e3364da507a3decec96423736384068c88fea5ea57aeae864ea115a6c4a20b3ace71b75f4901b0657bec82d83aab30a8ad0dfc4bfc0d8337546 + languageName: node + linkType: hard + "acorn-walk@npm:^7.2.0": version: 7.2.0 resolution: "acorn-walk@npm:7.2.0" @@ -10256,6 +10137,15 @@ __metadata: languageName: node linkType: hard +"axobject-query@npm:^4.0.0": + version: 4.0.0 + resolution: "axobject-query@npm:4.0.0" + dependencies: + dequal: "npm:^2.0.3" + checksum: 4d756b5c2ff099f1c7f99e55a5de9b2066cb2a13a3170185ff34bfec2d7bcab81eb820a4e7340d35c251341b61ebee6e705b7ce64db78224df1df5a4d68448fe + languageName: node + linkType: hard + "b4a@npm:^1.6.4": version: 1.6.4 resolution: "b4a@npm:1.6.4" @@ -10681,7 +10571,7 @@ __metadata: languageName: node linkType: hard -"bluebird@npm:^3.1.1, bluebird@npm:^3.7.2": +"bluebird@npm:^3.7.2": version: 3.7.2 resolution: "bluebird@npm:3.7.2" checksum: 680de03adc54ff925eaa6c7bb9a47a0690e8b5de60f4792604aae8ed618c65e6b63a7893b57ca924beaf53eee69c5af4f8314148c08124c550fe1df1add897d2 @@ -12291,15 +12181,6 @@ __metadata: languageName: node linkType: hard -"consolidate@npm:^0.15.1": - version: 0.15.1 - resolution: "consolidate@npm:0.15.1" - dependencies: - bluebird: "npm:^3.1.1" - checksum: 02dfbab0a8d5452b74c42dee81526b26a42350ed333575c4f8f099957d02a2dbc92a1f89103b85e83b61371e08a16113ebcddbb38eded53402302e0748f608e1 - languageName: node - linkType: hard - "consolidate@npm:^0.16.0": version: 0.16.0 resolution: "consolidate@npm:0.16.0" @@ -12765,7 +12646,7 @@ __metadata: languageName: node linkType: hard -"csstype@npm:^3.0.2, csstype@npm:^3.1.0, csstype@npm:^3.1.2": +"csstype@npm:^3.0.2, csstype@npm:^3.1.2": version: 3.1.2 resolution: "csstype@npm:3.1.2" checksum: 32c038af259897c807ac738d9eab16b3d86747c72b09d5c740978e06f067f9b7b1737e1b75e407c7ab1fe1543dc95f20e202b4786aeb1b8d3bdf5d5ce655e6c6 @@ -14802,6 +14683,13 @@ __metadata: languageName: node linkType: hard +"esm-env@npm:^1.0.0": + version: 1.0.0 + resolution: "esm-env@npm:1.0.0" + checksum: 6ea0001410224ebc18de4a83ce97dbdca6abc83ea4bbe91625aa3aead70793bb98dfa089f38e2cc5c13b7b025668d0649d5e25f2f9e8cca0f4aa3ad3406870d0 + languageName: node + linkType: hard + "espree@npm:9.2.0": version: 9.2.0 resolution: "espree@npm:9.2.0" @@ -14843,6 +14731,16 @@ __metadata: languageName: node linkType: hard +"esrap@npm:^1.2.1": + version: 1.2.1 + resolution: "esrap@npm:1.2.1" + dependencies: + "@jridgewell/sourcemap-codec": "npm:^1.4.15" + "@types/estree": "npm:^1.0.1" + checksum: 28d6e36adcf4342a844a938a736132269c33e9db6bbefc98c6af5ed06c14899afcc85391e7ce4824ce5066877fa10b0ed5c5007592cbc58012be95f13c66467f + languageName: node + linkType: hard + "esrecurse@npm:^4.3.0": version: 4.3.0 resolution: "esrecurse@npm:4.3.0" @@ -16771,13 +16669,6 @@ __metadata: languageName: node linkType: hard -"hash-sum@npm:^1.0.2": - version: 1.0.2 - resolution: "hash-sum@npm:1.0.2" - checksum: 311b2d7ea317b128860a88c7fd3ae46aef010b7fd7418a44afd2787cd889f24d635fa1e22a51bd5a5d8e338597c1da917d81f572e0de2f375e52e96c9fb63a66 - languageName: node - linkType: hard - "hash-sum@npm:^2.0.0": version: 2.0.0 resolution: "hash-sum@npm:2.0.0" @@ -19740,7 +19631,7 @@ __metadata: languageName: node linkType: hard -"loader-utils@npm:^1.0.2, loader-utils@npm:^1.1.0, loader-utils@npm:^1.2.3": +"loader-utils@npm:^1.1.0, loader-utils@npm:^1.2.3": version: 1.4.2 resolution: "loader-utils@npm:1.4.2" dependencies: @@ -20060,16 +19951,6 @@ __metadata: languageName: node linkType: hard -"lru-cache@npm:^4.1.2": - version: 4.1.5 - resolution: "lru-cache@npm:4.1.5" - dependencies: - pseudomap: "npm:^1.0.2" - yallist: "npm:^2.1.2" - checksum: 1ca5306814e5add9ec63556d6fd9b24a4ecdeaef8e9cea52cbf30301e6b88c8d8ddc7cab45b59b56eb763e6c45af911585dc89925a074ab65e1502e3fe8103cf - languageName: node - linkType: hard - "lru-cache@npm:^5.1.1": version: 5.1.1 resolution: "lru-cache@npm:5.1.1" @@ -23495,7 +23376,7 @@ __metadata: languageName: node linkType: hard -"postcss@npm:8.4.31, postcss@npm:^8.2.14, postcss@npm:^8.4.14, postcss@npm:^8.4.21, postcss@npm:^8.4.23, postcss@npm:^8.4.27, postcss@npm:^8.4.31": +"postcss@npm:8.4.31, postcss@npm:^8.2.14, postcss@npm:^8.4.21, postcss@npm:^8.4.23, postcss@npm:^8.4.27, postcss@npm:^8.4.31": version: 8.4.31 resolution: "postcss@npm:8.4.31" dependencies: @@ -23506,7 +23387,7 @@ __metadata: languageName: node linkType: hard -"postcss@npm:^7.0.14, postcss@npm:^7.0.32, postcss@npm:^7.0.36, postcss@npm:^7.0.5, postcss@npm:^7.0.6": +"postcss@npm:^7.0.14, postcss@npm:^7.0.32, postcss@npm:^7.0.5, postcss@npm:^7.0.6": version: 7.0.39 resolution: "postcss@npm:7.0.39" dependencies: @@ -23570,7 +23451,7 @@ __metadata: languageName: node linkType: hard -"prettier@npm:^1.18.2 || ^2.0.0, prettier@npm:^2.8.0": +"prettier@npm:^2.8.0": version: 2.8.8 resolution: "prettier@npm:2.8.8" bin: @@ -23806,13 +23687,6 @@ __metadata: languageName: node linkType: hard -"pseudomap@npm:^1.0.2": - version: 1.0.2 - resolution: "pseudomap@npm:1.0.2" - checksum: 5a91ce114c64ed3a6a553aa7d2943868811377388bb31447f9d8028271bae9b05b340fe0b6961a64e45b9c72946aeb0a4ab635e8f7cb3715ffd0ff2beeb6a679 - languageName: node - linkType: hard - "psl@npm:^1.1.33": version: 1.9.0 resolution: "psl@npm:1.9.0" @@ -27215,9 +27089,9 @@ __metadata: languageName: node linkType: hard -"svelte-check@npm:3.4.6": - version: 3.4.6 - resolution: "svelte-check@npm:3.4.6" +"svelte-check@npm:^3.6.1": + version: 3.6.2 + resolution: "svelte-check@npm:3.6.2" dependencies: "@jridgewell/trace-mapping": "npm:^0.3.17" chokidar: "npm:^3.4.1" @@ -27225,13 +27099,13 @@ __metadata: import-fresh: "npm:^3.2.1" picocolors: "npm:^1.0.0" sade: "npm:^1.7.4" - svelte-preprocess: "npm:^5.0.4" + svelte-preprocess: "npm:^5.1.0" typescript: "npm:^5.0.3" peerDependencies: - svelte: ^3.55.0 || ^4.0.0-next.0 || ^4.0.0 + svelte: ^3.55.0 || ^4.0.0-next.0 || ^4.0.0 || ^5.0.0-next.0 bin: svelte-check: bin/svelte-check - checksum: 7f537831af8f2c47859ca72f4a929d24c58f2946f949f7c9721351be97ff9d0674c57db003e3ad3883fdd85761b7950c5c11513c2a917c91091f155e2d026350 + checksum: 3f389df29268d4df9b561d0b206566e827af84923c70150b2dadfd407bcbdaccbfd561bd8b93884597de62477d62826ff1a5108854641078b692130441a49a55 languageName: node linkType: hard @@ -27273,7 +27147,7 @@ __metadata: languageName: node linkType: hard -"svelte-preprocess@npm:^5.0.4": +"svelte-preprocess@npm:^5.1.0, svelte-preprocess@npm:^5.1.1": version: 5.1.1 resolution: "svelte-preprocess@npm:5.1.1" dependencies: @@ -27340,6 +27214,26 @@ __metadata: languageName: node linkType: hard +"svelte@npm:^5.0.0-next.15, svelte@npm:^5.0.0-next.16": + version: 5.0.0-next.19 + resolution: "svelte@npm:5.0.0-next.19" + dependencies: + "@ampproject/remapping": "npm:^2.2.1" + "@jridgewell/sourcemap-codec": "npm:^1.4.15" + acorn: "npm:^8.10.0" + acorn-typescript: "npm:^1.4.11" + aria-query: "npm:^5.3.0" + axobject-query: "npm:^4.0.0" + esm-env: "npm:^1.0.0" + esrap: "npm:^1.2.1" + is-reference: "npm:^3.0.1" + locate-character: "npm:^3.0.0" + magic-string: "npm:^0.30.4" + zimmerframe: "npm:^1.1.0" + checksum: 2efc415d3a51cd9094349aa0295e728ea74e10bad17dedd167b1fae64de8ee5d46cbd27b5cfb152e4af641e1326e233dfeb918d8fa0541f65cf149b85d00419a + languageName: node + linkType: hard + "sveltedoc-parser@npm:^4.2.1": version: 4.3.1 resolution: "sveltedoc-parser@npm:4.3.1" @@ -29114,7 +29008,7 @@ __metadata: languageName: node linkType: hard -"vue-docgen-api@npm:^4.40.0, vue-docgen-api@npm:^4.44.23, vue-docgen-api@npm:^4.46.0": +"vue-docgen-api@npm:^4.40.0, vue-docgen-api@npm:^4.46.0": version: 4.75.1 resolution: "vue-docgen-api@npm:4.75.1" dependencies: @@ -29150,13 +29044,6 @@ __metadata: languageName: node linkType: hard -"vue-hot-reload-api@npm:^2.3.0": - version: 2.3.4 - resolution: "vue-hot-reload-api@npm:2.3.4" - checksum: 6501a93582c2bba0f17564d1c61b4301e844e14fbac1cb7c3d726c40961375aefa89f2cc4ee8289c3663e12d108c28a5872ba35cfa7f091d1bcaa39feff9ac60 - languageName: node - linkType: hard - "vue-inbrowser-compiler-independent-utils@npm:^4.69.0": version: 4.71.1 resolution: "vue-inbrowser-compiler-independent-utils@npm:4.71.1" @@ -29166,29 +29053,6 @@ __metadata: languageName: node linkType: hard -"vue-loader@npm:^15.7.0": - version: 15.11.1 - resolution: "vue-loader@npm:15.11.1" - dependencies: - "@vue/component-compiler-utils": "npm:^3.1.0" - hash-sum: "npm:^1.0.2" - loader-utils: "npm:^1.1.0" - vue-hot-reload-api: "npm:^2.3.0" - vue-style-loader: "npm:^4.1.0" - peerDependencies: - css-loader: "*" - webpack: ^3.0.0 || ^4.1.0 || ^5.0.0-0 - peerDependenciesMeta: - cache-loader: - optional: true - prettier: - optional: true - vue-template-compiler: - optional: true - checksum: 22491414f3743d485cf8d966837314706abf35d330bf055e356d55f16df8d4ab21fb712c7168509f7492d62cdf799aedf8d31df36d89bd5a4479b9f90fa094c1 - languageName: node - linkType: hard - "vue-loader@npm:^16.0.0": version: 16.8.3 resolution: "vue-loader@npm:16.8.3" @@ -29202,17 +29066,7 @@ __metadata: languageName: node linkType: hard -"vue-style-loader@npm:^4.1.0": - version: 4.1.3 - resolution: "vue-style-loader@npm:4.1.3" - dependencies: - hash-sum: "npm:^1.0.2" - loader-utils: "npm:^1.0.2" - checksum: 871362711561c817c6b96650cf4bcf422c51d46808650da7e6ec39499d76445d08a1f9f1d1aa0f6cffb191cd128fbd77b6e233d9689a87c21d7e546689bed04c - languageName: node - linkType: hard - -"vue-template-compiler@npm:^2.6.14, vue-template-compiler@npm:^2.7.14": +"vue-template-compiler@npm:^2.7.14": version: 2.7.15 resolution: "vue-template-compiler@npm:2.7.15" dependencies: @@ -29222,13 +29076,6 @@ __metadata: languageName: node linkType: hard -"vue-template-es2015-compiler@npm:^1.9.0": - version: 1.9.1 - resolution: "vue-template-es2015-compiler@npm:1.9.1" - checksum: 21d27d1c6afe10a47f17793e18afb7f321888d3ca728bfdb2a79ff49789ed9b40e98abcb68b5499f3da1bbb76a0f188b94aeb5ab0e879f46d6399ac5d4ae38c8 - languageName: node - linkType: hard - "vue-tsc@npm:latest": version: 1.8.24 resolution: "vue-tsc@npm:1.8.24" @@ -29244,13 +29091,6 @@ __metadata: languageName: node linkType: hard -"vue@npm:2.6.14": - version: 2.6.14 - resolution: "vue@npm:2.6.14" - checksum: efbe26ccc7c1bd025b88e464ebc81217b92350a77b98049122a46ac2242e249719f930d3914e2efdeaaa521a51e6e6b1cb9ffbf95b4835ed94dc92efb481040f - languageName: node - linkType: hard - "vue@npm:3.0.0": version: 3.0.0 resolution: "vue@npm:3.0.0" @@ -29262,16 +29102,6 @@ __metadata: languageName: node linkType: hard -"vue@npm:^2.6.12, vue@npm:^2.7.10": - version: 2.7.15 - resolution: "vue@npm:2.7.15" - dependencies: - "@vue/compiler-sfc": "npm:2.7.15" - csstype: "npm:^3.1.0" - checksum: 92bc7bcef1a54fe6b98409a7094f7c8b1f4b8fcf52469380f130d0d671d581130b1ef8715f0e95020fc5dbffff7f519a0621206484b3fdee5e6319a76073fb0c - languageName: node - linkType: hard - "vue@npm:^3.2.33, vue@npm:^3.2.47": version: 3.3.9 resolution: "vue@npm:3.3.9" @@ -30031,13 +29861,6 @@ __metadata: languageName: node linkType: hard -"yallist@npm:^2.1.2": - version: 2.1.2 - resolution: "yallist@npm:2.1.2" - checksum: 0b9e25aa00adf19e01d2bcd4b208aee2b0db643d9927131797b7af5ff69480fc80f1c3db738cbf3946f0bddf39d8f2d0a5709c644fd42d4aa3a4e6e786c087b5 - languageName: node - linkType: hard - "yallist@npm:^3.0.2": version: 3.1.1 resolution: "yallist@npm:3.1.1" @@ -30221,6 +30044,13 @@ __metadata: languageName: node linkType: hard +"zimmerframe@npm:^1.1.0": + version: 1.1.0 + resolution: "zimmerframe@npm:1.1.0" + checksum: dffe3f555bb000176ed9c7577e0fb0c3eddeceb6df9bb3ff870995bac3a51b40fab5443bd3dc47ce91c1f8ecf07282742efb80771ae6a088edc0340bb217f93d + languageName: node + linkType: hard + "zod@npm:^3.22.2": version: 3.22.4 resolution: "zod@npm:3.22.4" diff --git a/docs/addons/addons-api.md b/docs/addons/addons-api.md index e73907d61c87..41daafbe8009 100644 --- a/docs/addons/addons-api.md +++ b/docs/addons/addons-api.md @@ -93,7 +93,7 @@ Use the `makeDecorator` API to create decorators in the style of the official ad - If the story's parameters include `{ exampleParameter: { disable: true } }` (where `exampleParameter` is the `parameterName` of your addon), your decorator will not be called. +If the story's parameters include `{ exampleParameter: { disable: true } }` (where `exampleParameter` is the `parameterName` of your addon), your decorator will not be called. @@ -124,6 +124,7 @@ The `selectStory` API method allows you to select a single story. It accepts the 'vue/button-story-with-addon-example.ts.mdx', 'angular/button-story-with-addon-example.ts.mdx', 'svelte/button-story-with-addon-example.js.mdx', + 'svelte/button-story-with-addon-example.ts.mdx', 'web-components/button-story-with-addon-example.js.mdx', 'web-components/button-story-with-addon-example.ts.mdx', ]} diff --git a/docs/api/csf.md b/docs/api/csf.md index 9e494e151a7a..d5ed3eb7ec40 100644 --- a/docs/api/csf.md +++ b/docs/api/csf.md @@ -51,6 +51,7 @@ With CSF, every named export in the file represents a story object by default. 'vue/my-component-story-basic-and-props.js.mdx', 'vue/my-component-story-basic-and-props.ts.mdx', 'svelte/my-component-story-basic-and-props.js.mdx', + 'svelte/my-component-story-basic-and-props.ts.mdx', 'angular/my-component-story-basic-and-props.ts.mdx', 'web-components/my-component-story-basic-and-props.js.mdx', 'web-components/my-component-story-basic-and-props.ts.mdx', @@ -112,6 +113,7 @@ Consider Storybook’s ["Button" example](../writing-stories/index.md#defining-s 'vue/button-story-click-handler.3.js.mdx', 'vue/button-story-click-handler.3.ts.mdx', 'svelte/button-story-click-handler.js.mdx', + 'svelte/button-story-click-handler.ts.mdx', 'angular/button-story-click-handler.ts.mdx', 'web-components/button-story-click-handler.js.mdx', 'web-components/button-story-click-handler.ts.mdx', @@ -138,6 +140,7 @@ Now consider the same example, re-written with args: 'vue/button-story-click-handler-args.3.ts.mdx', 'angular/button-story-click-handler-args.ts.mdx', 'svelte/button-story-click-handler-args.js.mdx', + 'svelte/button-story-click-handler-args.ts.mdx', 'web-components/button-story-click-handler-args.js.mdx', 'web-components/button-story-click-handler-args.ts.mdx', 'solid/button-story-click-handler-args.js.mdx', @@ -162,6 +165,8 @@ Or even more simply: 'vue/button-story-click-handler-simplificated.ts.mdx', 'web-components/button-story-click-handler-simplificated.js.mdx', 'web-components/button-story-click-handler-simplificated.ts.mdx', + 'svelte/button-story-click-handler-simplificated.js.mdx', + 'svelte/button-story-click-handler-simplificated.ts.mdx', 'solid/button-story-click-handler-simplificated.js.mdx', 'solid/button-story-click-handler-simplificated.ts.mdx', ]} @@ -193,6 +198,7 @@ A good use case for the `play` function is a form component. With previous Story 'web-components/login-form-with-play-function.js.mdx', 'web-components/login-form-with-play-function.ts.mdx', 'svelte/login-form-with-play-function.js.mdx', + 'svelte/login-form-with-play-function.ts.mdx', 'solid/login-form-with-play-function.js.mdx', 'solid/login-form-with-play-function.ts.mdx', ]} @@ -204,6 +210,8 @@ A good use case for the `play` function is a form component. With previous Story When the story renders in the UI, Storybook executes each step defined in the `play` function and runs the assertions without the need for user interaction. + + ## Custom render functions Starting in Storybook 6.4, you can write your stories as JavaScript objects, reducing the boilerplate code you need to generate to test your components, thus improving functionality and usability. `Render` functions are helpful methods to give you additional control over how the story renders. For example, if you were writing a story as an object and you wanted to specify how your component should render, you could write the following: @@ -230,6 +238,8 @@ Starting in Storybook 6.4, you can write your stories as JavaScript objects, red When Storybook loads this story, it will detect the existence of a `render` function and adjust the component rendering accordingly based on what's defined. + + ## Storybook export vs. name handling Storybook handles named exports and the `name` option slightly differently. When should you use one vs. the other? @@ -271,10 +281,11 @@ Consider the following story file: 'react/my-component-story-with-nonstory.ts.mdx', 'vue/my-component-story-with-nonstory.js.mdx', 'vue/my-component-story-with-nonstory.ts.mdx', - 'svelte/my-component-story-with-nonstory.js.mdx', 'angular/my-component-story-with-nonstory.ts.mdx', 'web-components/my-component-story-with-nonstory.js.mdx', 'web-components/my-component-story-with-nonstory.ts.mdx', + 'svelte/my-component-story-with-nonstory.js.mdx', + 'svelte/my-component-story-with-nonstory.ts.mdx', 'solid/my-component-story-with-nonstory.js.mdx', 'solid/my-component-story-with-nonstory.ts.mdx', ]} @@ -316,6 +327,8 @@ In CSF 2, the named exports are always functions that instantiate a component, a 'web-components/csf-2-example-starter.ts.mdx', 'solid/csf-2-example-starter.js.mdx', 'solid/csf-2-example-starter.ts.mdx', + 'svelte/csf-2-example-starter.js.mdx', + 'svelte/csf-2-example-starter.ts.mdx', ]} /> @@ -336,6 +349,7 @@ Here's the CSF 3 equivalent: 'web-components/csf-3-example-starter.js.mdx', 'web-components/csf-3-example-starter.ts.mdx', 'solid/csf-3-example-starter.ts.mdx', + 'svelte/csf-3-example-starter.ts.mdx', ]} /> @@ -399,6 +413,8 @@ Let's start with a simple CSF 2 story function: 'web-components/csf-2-example-story.ts.mdx', 'solid/csf-2-example-story.js.mdx', 'solid/csf-2-example-story.ts.mdx', + 'svelte/csf-2-example-story.js.mdx', + 'svelte/csf-2-example-story.ts.mdx', ]} /> @@ -421,11 +437,17 @@ Now, let's rewrite it as a story object in CSF 3 with an explicit `render` funct 'web-components/csf-3-example-render.ts.mdx', 'solid/csf-3-example-render.js.mdx', 'solid/csf-3-example-render.ts.mdx', + 'svelte/csf-3-example-render.js.mdx', + 'svelte/csf-3-example-render.ts.mdx', ]} /> + + Learn more about [render functions](#custom-render-functions). + + But in CSF 2, a lot of story functions are identical: take the component specified in the default export and spread args into it. What's interesting about these stories is not the function, but the args passed into the function. @@ -442,8 +464,12 @@ CSF 3 provides default render functions for each renderer. If all you're doing i + + For more information, see the section on [custom render functions](#custom-render-functions). + + ### Generate titles automatically Finally, CSF 3 can automatically generate titles. diff --git a/docs/configure/compilers.md b/docs/configure/compilers.md index fc18eac310aa..96d9cb75f64a 100644 --- a/docs/configure/compilers.md +++ b/docs/configure/compilers.md @@ -21,7 +21,7 @@ SWC is a fast, highly extensible tool for compiling and bundling modern JavaScri -Support for the SWC builder is currently experimental for Next.js projects, and it's not enabled by default. It requires you to opt in to use it. +Support for the SWC builder is currently experimental for Next.js projects, and it's not enabled by default. It requires you to opt in to use it. For more information on configuring SWC with the supported frameworks, see the [SWC API](../api/main-config-swc.md) documentation. diff --git a/docs/configure/images-and-assets.md b/docs/configure/images-and-assets.md index 8325aed14f6e..7b4a0c071ada 100644 --- a/docs/configure/images-and-assets.md +++ b/docs/configure/images-and-assets.md @@ -22,6 +22,7 @@ Afterward, you can use any asset in your stories: 'vue/component-story-static-asset-with-import.3.ts.mdx', 'angular/component-story-static-asset-with-import.ts.mdx', 'svelte/component-story-static-asset-with-import.js.mdx', + 'svelte/component-story-static-asset-with-import.ts.mdx', 'web-components/component-story-static-asset-with-import.js.mdx', 'web-components/component-story-static-asset-with-import.ts.mdx', 'solid/component-story-static-asset-with-import.js.mdx', @@ -62,6 +63,7 @@ Here `../public` is your static directory. Now use it in a component or story li 'vue/component-story-static-asset-without-import.ts.mdx', 'angular/component-story-static-asset-without-import.ts.mdx', 'svelte/component-story-static-asset-without-import.js.mdx', + 'svelte/component-story-static-asset-without-import.ts.mdx', 'web-components/component-story-static-asset-without-import.js.mdx', 'web-components/component-story-static-asset-without-import.ts.mdx', 'solid/component-story-static-asset-without-import.js.mdx', @@ -117,6 +119,7 @@ Upload your files to an online CDN and reference them. In this example, we’re 'vue/component-story-static-asset-cdn.ts.mdx', 'angular/component-story-static-asset-cdn.ts.mdx', 'svelte/component-story-static-asset-cdn.js.mdx', + 'svelte/component-story-static-asset-cdn.ts.mdx', 'web-components/component-story-static-asset-cdn.js.mdx', 'web-components/component-story-static-asset-cdn.ts.mdx', 'solid/component-story-static-asset-cdn.js.mdx', diff --git a/docs/essentials/controls.md b/docs/essentials/controls.md index 2fb67af32861..efff7222f5bd 100644 --- a/docs/essentials/controls.md +++ b/docs/essentials/controls.md @@ -121,6 +121,10 @@ If you haven't used the CLI to setup the configuration, or if you want to define + + + + ## Fully custom args Until now, we only used auto-generated controls based on the component we're writing stories for. If we are writing [complex stories](../writing-stories/stories-for-multiple-components.md), we may want to add controls for args that aren’t part of the component. For example, here's how you could use a `footer` arg to populate a child component: @@ -155,6 +159,8 @@ By default, Storybook will add controls for all args that: Using `argTypes`, you can change the display and behavior of each control. + + ### Dealing with complex values When dealing with non-primitive values, you'll notice that you'll run into some limitations. The most obvious issue is that not every value can be represented as part of the `args` param in the URL, losing the ability to share and deeplink to such a state. Beyond that, complex values such as JSX cannot be synchronized between the manager (e.g., Controls addon) and the preview (your story). @@ -171,6 +177,7 @@ One way to deal with this is to use primitive values (e.g., strings) as arg valu 'vue/component-story-custom-args-complex.ts.mdx', 'angular/component-story-custom-args-complex.ts.mdx', 'svelte/component-story-custom-args-complex.js.mdx', + 'svelte/component-story-custom-args-complex.ts.mdx', 'web-components/component-story-custom-args-complex.js.mdx', 'web-components/component-story-custom-args-complex.ts.mdx', 'solid/component-story-custom-args-complex.js.mdx', diff --git a/docs/essentials/toolbars-and-globals.md b/docs/essentials/toolbars-and-globals.md index ff169ff91aa8..7acb99956520 100644 --- a/docs/essentials/toolbars-and-globals.md +++ b/docs/essentials/toolbars-and-globals.md @@ -170,6 +170,7 @@ Using the example above, you can modify any story to retrieve the **Locale** `gl 'vue/my-component-story-use-globaltype.ts.mdx', 'angular/my-component-story-use-globaltype.ts.mdx', 'svelte/my-component-story-use-globaltype.js.mdx', + 'svelte/my-component-story-use-globaltype.ts.mdx', 'web-components/my-component-story-use-globaltype.js.mdx', 'web-components/my-component-story-use-globaltype.ts.mdx', 'solid/my-component-story-use-globaltype.js.mdx', @@ -193,6 +194,7 @@ In Storybook 6.0, if you set the global option `passArgsFirst: false` for backwa 'vue/my-component-story-use-globaltype-backwards-compat.js.mdx', 'angular/my-component-story-use-globaltype-backwards-compat.ts.mdx', 'svelte/my-component-story-use-globaltype-backwards-compat.js.mdx', + 'svelte/my-component-story-use-globaltype-backwards-compat.ts.mdx', 'web-components/my-component-story-use-globaltype-backwards-compat.js.mdx', 'web-components/my-component-story-use-globaltype-backwards-compat.ts.mdx', 'solid/my-component-story-use-globaltype-backwards-compat.js.mdx', diff --git a/docs/essentials/viewport.md b/docs/essentials/viewport.md index dd321d9f30ec..90bcae73da0c 100644 --- a/docs/essentials/viewport.md +++ b/docs/essentials/viewport.md @@ -132,6 +132,7 @@ Update your story through [parameters](../writing-stories/parameters.md) to incl 'web-components/my-component-story-configure-viewports.js.mdx', 'web-components/my-component-story-configure-viewports.ts.mdx', 'svelte/my-component-story-configure-viewports.js.mdx', + 'svelte/my-component-story-configure-viewports.ts.mdx', 'solid/my-component-story-configure-viewports.js.mdx', 'solid/my-component-story-configure-viewports.ts.mdx', ]} diff --git a/docs/get-started/install.md b/docs/get-started/install.md index 2d01dfd1a0f2..977a1e122c03 100644 --- a/docs/get-started/install.md +++ b/docs/get-started/install.md @@ -2,7 +2,7 @@ title: 'Install Storybook' --- -Use the Storybook CLI to install it in a single command. Run this inside your _existing project’s_ root directory: +Use the Storybook CLI to install it in a single command. Run this inside your project’s root directory: @@ -16,21 +16,6 @@ Use the Storybook CLI to install it in a single command. Run this inside your _e -
- -storybook init is not made for empty projects - -Storybook needs to be installed into a project that is already set up with a framework. It will not work on an empty project. There are many ways to bootstrap an app in a given framework, including: - -- πŸ“¦ [Create an Angular Workspace](https://angular.io/cli/new) -- πŸ“¦ [Create React App](https://reactjs.org/docs/create-a-new-react-app.html) -- πŸ“¦ [Create a Vue App](https://vuejs.org/guide/quick-start.html) -- πŸ“¦ [Ember CLI](https://guides.emberjs.com/release/getting-started/quick-start/) -- πŸ“¦ [Vite CLI](https://vitejs.dev/guide/#scaffolding-your-first-vite-project) -- Or any other tooling available. - -
- Storybook will look into your project's dependencies during its install process and provide you with the best configuration available. The command above will make the following changes to your local environment: diff --git a/docs/get-started/installation-problems/vue.mdx b/docs/get-started/installation-problems/vue.mdx index 84f464a5680e..1268f226a36b 100644 --- a/docs/get-started/installation-problems/vue.mdx +++ b/docs/get-started/installation-problems/vue.mdx @@ -15,7 +15,5 @@ ``` - For other installation issues, check the Vue README files for additional instructions: - - [Vue 2 with Webpack](https://github.com/storybookjs/storybook/tree/next/code/frameworks/vue-webpack5) - - [Vue 2 with Vite](https://github.com/storybookjs/storybook/tree/next/code/frameworks/vue-vite) - [Vue 3 with Webpack](https://github.com/storybookjs/storybook/tree/next/code/frameworks/vue3-webpack5) - [Vue 3 with Vite](https://github.com/storybookjs/storybook/tree/next/code/frameworks/vue3-vite) diff --git a/docs/sharing/design-integrations.md b/docs/sharing/design-integrations.md index d85530557e9c..ddd320a21ec1 100644 --- a/docs/sharing/design-integrations.md +++ b/docs/sharing/design-integrations.md @@ -110,6 +110,7 @@ In Storybook, add a new [parameter](../writing-stories/parameters.md) named `des 'vue/component-story-figma-integration.ts.mdx', 'angular/component-story-figma-integration.ts.mdx', 'svelte/component-story-figma-integration.js.mdx', + 'svelte/component-story-figma-integration.ts.mdx', 'web-components/component-story-figma-integration.js.mdx', 'web-components/component-story-figma-integration.ts.mdx', 'solid/component-story-figma-integration.js.mdx', diff --git a/docs/snippets/common/main-config-webpack-final.js.mdx b/docs/snippets/common/main-config-webpack-final.js.mdx index 65d346eb38db..4c583dca901f 100644 --- a/docs/snippets/common/main-config-webpack-final.js.mdx +++ b/docs/snippets/common/main-config-webpack-final.js.mdx @@ -5,7 +5,7 @@ export default { // Replace your-framework with the framework you are using (e.g., react-webpack5, vue3-vite) framework: '@storybook/your-framework', stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|mjs|ts|tsx)'], - async webpackFinal(config, { configType }) { + webpackFinal: async (config, { configType }) => { if (configType === 'DEVELOPMENT') { // Modify config for development } diff --git a/docs/snippets/common/main-config-webpack-final.ts.mdx b/docs/snippets/common/main-config-webpack-final.ts.mdx index c3d1e9aa2185..35d69858d07c 100644 --- a/docs/snippets/common/main-config-webpack-final.ts.mdx +++ b/docs/snippets/common/main-config-webpack-final.ts.mdx @@ -7,7 +7,7 @@ import type { StorybookConfig } from '@storybook/your-framework'; const config: StorybookConfig = { framework: '@storybook/your-framework', stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|mjs|ts|tsx)'], - async webpackFinal(config, { configType }) { + webpackFinal: async (config, { configType }) => { if (configType === 'DEVELOPMENT') { // Modify config for development } diff --git a/docs/snippets/common/your-theme.js.mdx b/docs/snippets/common/your-theme.js.mdx index 54ce8c5d37fd..1e596e518813 100644 --- a/docs/snippets/common/your-theme.js.mdx +++ b/docs/snippets/common/your-theme.js.mdx @@ -32,6 +32,7 @@ export default create({ // Toolbar default and active colors barTextColor: '#9E9E9E', barSelectedColor: '#585C6D', + barHoverColor: '#585C6D', barBg: '#ffffff', // Form colors diff --git a/docs/snippets/svelte/apollo-wrapper-component.with-mock-implementation.js.mdx b/docs/snippets/svelte/apollo-wrapper-component.with-mock-implementation.js.mdx index 2793daec07b6..d43181fd25da 100644 --- a/docs/snippets/svelte/apollo-wrapper-component.with-mock-implementation.js.mdx +++ b/docs/snippets/svelte/apollo-wrapper-component.with-mock-implementation.js.mdx @@ -23,7 +23,5 @@ setClient(mockedClient); -
- -
+ ``` diff --git a/docs/snippets/svelte/apollo-wrapper-component.with-mock-implementation.ts.mdx b/docs/snippets/svelte/apollo-wrapper-component.with-mock-implementation.ts.mdx new file mode 100644 index 000000000000..3e2c29cb660b --- /dev/null +++ b/docs/snippets/svelte/apollo-wrapper-component.with-mock-implementation.ts.mdx @@ -0,0 +1,27 @@ +```html + + + + + +``` diff --git a/docs/snippets/svelte/badge-story.mdx.mdx b/docs/snippets/svelte/badge-story.mdx.mdx deleted file mode 100644 index f30d432b4d38..000000000000 --- a/docs/snippets/svelte/badge-story.mdx.mdx +++ /dev/null @@ -1,76 +0,0 @@ -```md - - -import { Canvas, Meta, Story } from '@storybook/addon-docs'; - -import Badge from './Badge.svelte'; - - - -# Badge - -Let's define a story for our `Badge` component: - - ({ - Component: Badge, - props: args, - })} /> - -We can drop it in a `Canvas` to get a code snippet: - - - ({ - Component: Badge, - props: args, - })} /> - - -We can even preview multiple Stories in a block. This -gets rendered as a group but defines individual stories -with unique URLs, which is great for review and testing. - - - ({ - Component: Badge, - props: args, - })} /> - ({ - Component: Badge, - props: args, - })} /> - ({ - Component: Badge, - props: args, - })} /> - -``` diff --git a/docs/snippets/svelte/button-group-story.js.mdx b/docs/snippets/svelte/button-group-story.js.mdx index b40b40322ee9..9304e1bfda12 100644 --- a/docs/snippets/svelte/button-group-story.js.mdx +++ b/docs/snippets/svelte/button-group-story.js.mdx @@ -10,16 +10,7 @@ export default { component: ButtonGroup, }; -/* - *πŸ‘‡ Render functions are a framework specific feature to allow you control on how the component renders. - * See https://storybook.js.org/docs/api/csf - * to learn how to use render functions. - */ export const Pair = { - render: (args) => ({ - Component: ButtonGroup, - props: args, - }), args: { buttons: [{ ...ButtonStories.Primary.args }, { ...ButtonStories.Secondary.args }], orientation: 'horizontal', diff --git a/docs/snippets/svelte/button-group-story.ts-4-9.mdx b/docs/snippets/svelte/button-group-story.ts-4-9.mdx new file mode 100644 index 000000000000..aab891afac53 --- /dev/null +++ b/docs/snippets/svelte/button-group-story.ts-4-9.mdx @@ -0,0 +1,24 @@ +```ts +// ButtonGroup.stories.ts + +import type { Meta, StoryObj } from '@storybook/svelte'; + +import ButtonGroup from './ButtonGroup.svelte'; + +//πŸ‘‡ Imports the Button stories +import * as ButtonStories from './Button.stories'; + +const meta = { + component: ButtonGroup, +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const Pair: Story = { + args: { + buttons: [{ ...ButtonStories.Primary.args }, { ...ButtonStories.Secondary.args }], + orientation: 'horizontal', + }, +}; +``` diff --git a/docs/snippets/svelte/button-group-story.ts.mdx b/docs/snippets/svelte/button-group-story.ts.mdx new file mode 100644 index 000000000000..d0d9a8989620 --- /dev/null +++ b/docs/snippets/svelte/button-group-story.ts.mdx @@ -0,0 +1,24 @@ +```ts +// ButtonGroup.stories.ts + +import type { Meta, StoryObj } from '@storybook/svelte'; + +import ButtonGroup from './ButtonGroup.svelte'; + +//πŸ‘‡ Imports the Button stories +import * as ButtonStories from './Button.stories'; + +const meta: Meta = { + component: ButtonGroup, +}; + +export default meta; +type Story = StoryObj; + +export const Pair: Story = { + args: { + buttons: [{ ...ButtonStories.Primary.args }, { ...ButtonStories.Secondary.args }], + orientation: 'horizontal', + }, +}; +``` diff --git a/docs/snippets/svelte/button-story-auto-docs.js.mdx b/docs/snippets/svelte/button-story-auto-docs.js.mdx index 013999d572dd..b4bed93087ce 100644 --- a/docs/snippets/svelte/button-story-auto-docs.js.mdx +++ b/docs/snippets/svelte/button-story-auto-docs.js.mdx @@ -13,10 +13,6 @@ export default { }; export const Primary = { - render: (args) => ({ - Component: Button, - props: args, - }), args: { primary: true, label: 'Button', @@ -24,10 +20,6 @@ export const Primary = { }; export const Secondary = { - render: (args) => ({ - Component: Button, - props: args, - }), args: { ...Primary.args, primary: false, diff --git a/docs/snippets/svelte/button-story-auto-docs.ts-4-9.mdx b/docs/snippets/svelte/button-story-auto-docs.ts-4-9.mdx new file mode 100644 index 000000000000..a15d00516058 --- /dev/null +++ b/docs/snippets/svelte/button-story-auto-docs.ts-4-9.mdx @@ -0,0 +1,33 @@ +```ts +// Button.stories.ts + +import type { Meta, StoryObj } from '@storybook/svelte'; + +import Button from './Button.svelte'; + +const meta = { + component: Button, + //πŸ‘‡ Enables auto-generated documentation for the component story + tags: ['autodocs'], + argTypes: { + backgroundColor: { control: 'color' }, + }, +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const Primary: Story = { + args: { + primary: true, + label: 'Button', + }, +}; + +export const Secondary: Story = { + args: { + ...Primary.args, + primary: false, + }, +}; +``` diff --git a/docs/snippets/svelte/button-story-auto-docs.ts.mdx b/docs/snippets/svelte/button-story-auto-docs.ts.mdx new file mode 100644 index 000000000000..26248d745aff --- /dev/null +++ b/docs/snippets/svelte/button-story-auto-docs.ts.mdx @@ -0,0 +1,33 @@ +```ts +// Button.stories.ts + +import type { Meta, StoryObj } from '@storybook/svelte'; + +import Button from './Button.svelte'; + +const meta: Meta = { + component: Button, + //πŸ‘‡ Enables auto-generated documentation for the component story + tags: ['autodocs'], + argTypes: { + backgroundColor: { control: 'color' }, + }, +}; + +export default meta; +type Story = StoryObj; + +export const Primary: Story = { + args: { + primary: true, + label: 'Button', + }, +}; + +export const Secondary: Story = { + args: { + ...Primary.args, + primary: false, + }, +}; +``` diff --git a/docs/snippets/svelte/button-story-click-handler-args.ts-4-9.mdx b/docs/snippets/svelte/button-story-click-handler-args.ts-4-9.mdx new file mode 100644 index 000000000000..ff23875fed16 --- /dev/null +++ b/docs/snippets/svelte/button-story-click-handler-args.ts-4-9.mdx @@ -0,0 +1,31 @@ +```ts +// Button.stories.ts + +import type { Meta, StoryObj } from '@storybook/svelte'; +import { action } from '@storybook/addon-actions'; + +import Button from './Button.svelte'; + +const meta = { + component: Button, +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const Primary: Story = { + render: ({ label, click }) => ({ + Component: Button, + props: { + label, + }, + on: { + click, + }, + }), + args: { + label: 'Hello', + click: action('clicked'), + }, +}; +``` diff --git a/docs/snippets/svelte/button-story-click-handler-args.ts.mdx b/docs/snippets/svelte/button-story-click-handler-args.ts.mdx new file mode 100644 index 000000000000..0601a77f56e7 --- /dev/null +++ b/docs/snippets/svelte/button-story-click-handler-args.ts.mdx @@ -0,0 +1,31 @@ +```ts +// Button.stories.ts + +import type { Meta, StoryObj } from '@storybook/svelte'; +import { action } from '@storybook/addon-actions'; + +import Button from './Button.svelte'; + +const meta: Meta = { + component: Button, +}; + +export default meta; +type Story = StoryObj; + +export const Text: Story = { + render: ({ label, click }) => ({ + Component: Button, + props: { + label, + }, + on: { + click, + }, + }), + args: { + label: 'Hello', + click: action('clicked'), + }, +}; +``` diff --git a/docs/snippets/svelte/button-story-click-handler-simplificated.js.mdx b/docs/snippets/svelte/button-story-click-handler-simplificated.js.mdx new file mode 100644 index 000000000000..8f6a170584d3 --- /dev/null +++ b/docs/snippets/svelte/button-story-click-handler-simplificated.js.mdx @@ -0,0 +1,13 @@ +```js +// Button.stories.js + +import Button from './Button.svelte'; + +export default { + component: Button, +}; + +export const Text = { + args: {...}, +}; +``` diff --git a/docs/snippets/svelte/button-story-click-handler-simplificated.ts-4-9.mdx b/docs/snippets/svelte/button-story-click-handler-simplificated.ts-4-9.mdx new file mode 100644 index 000000000000..13eeb3c3b7c6 --- /dev/null +++ b/docs/snippets/svelte/button-story-click-handler-simplificated.ts-4-9.mdx @@ -0,0 +1,18 @@ +```ts +// Button.stories.ts + +import type { Meta, StoryObj } from '@storybook/svelte'; + +import Button from './Button.svelte'; + +const meta = { + component: Button, +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const Text: Story = { + args: {...}, +}; +``` diff --git a/docs/snippets/svelte/button-story-click-handler-simplificated.ts.mdx b/docs/snippets/svelte/button-story-click-handler-simplificated.ts.mdx new file mode 100644 index 000000000000..860f8e586456 --- /dev/null +++ b/docs/snippets/svelte/button-story-click-handler-simplificated.ts.mdx @@ -0,0 +1,18 @@ +```ts +// Button.stories.ts + +import type { Meta, StoryObj } from '@storybook/svelte'; + +import Button from './Button.svelte'; + +const meta: Meta = { + component: Button, +}; + +export default meta; +type Story = StoryObj; + +export const Text: Story = { + args: {...}, +}; +``` diff --git a/docs/snippets/svelte/button-story-click-handler.js.mdx b/docs/snippets/svelte/button-story-click-handler.js.mdx index ff58c6e44a2c..06f272af6ca6 100644 --- a/docs/snippets/svelte/button-story-click-handler.js.mdx +++ b/docs/snippets/svelte/button-story-click-handler.js.mdx @@ -1,10 +1,10 @@ ```js // Button.stories.js -import Button from './Button.svelte'; - import { action } from '@storybook/addon-actions'; +import Button from './Button.svelte'; + export default { component: Button, }; diff --git a/docs/snippets/svelte/button-story-click-handler.ts-4-9.mdx b/docs/snippets/svelte/button-story-click-handler.ts-4-9.mdx new file mode 100644 index 000000000000..16db58d0a779 --- /dev/null +++ b/docs/snippets/svelte/button-story-click-handler.ts-4-9.mdx @@ -0,0 +1,26 @@ +```ts +// Button.stories.ts + +import type { Meta, StoryObj } from '@storybook/svelte'; +import { action } from '@storybook/addon-actions'; + +import Button from './Button.svelte'; + +const meta = { + component: Button, +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const Primary: Story = { + render: (args) => ({ + Component: Button, + props: args, + }), + args: { + primary: true, + label: 'Button', + }, +}; +``` diff --git a/docs/snippets/svelte/button-story-click-handler.ts.mdx b/docs/snippets/svelte/button-story-click-handler.ts.mdx new file mode 100644 index 000000000000..f5e8c397eba5 --- /dev/null +++ b/docs/snippets/svelte/button-story-click-handler.ts.mdx @@ -0,0 +1,27 @@ +```ts +// Button.stories.ts + +import type { Meta, StoryObj } from '@storybook/svelte'; +import { action } from '@storybook/addon-actions'; + +import Button from './Button.svelte'; + +const meta: Meta = { + component: Button, +}; + +export default meta; +type Story = StoryObj; + +export const Text: Story = { + render: () => ({ + Component: Button, + props: { + label: 'Hello', + }, + on: { + click: action('clicked'), + }, + }), +}; +``` diff --git a/docs/snippets/svelte/button-story-component-args-primary.mdx.mdx b/docs/snippets/svelte/button-story-component-args-primary.mdx.mdx deleted file mode 100644 index 8dcda41aff7a..000000000000 --- a/docs/snippets/svelte/button-story-component-args-primary.mdx.mdx +++ /dev/null @@ -1,22 +0,0 @@ -```md - - -import { Meta, Story } from '@storybook/addon-docs'; - -import Button from './Button.svelte'; - - - - - - -``` \ No newline at end of file diff --git a/docs/snippets/svelte/button-story-component-args-primary.ts-4-9.mdx b/docs/snippets/svelte/button-story-component-args-primary.ts-4-9.mdx new file mode 100644 index 000000000000..7c83e880ac7f --- /dev/null +++ b/docs/snippets/svelte/button-story-component-args-primary.ts-4-9.mdx @@ -0,0 +1,21 @@ +```ts +// Button.stories.ts + +import type { Meta } from '@storybook/svelte'; + +import Button from './Button.svelte'; + +const meta = { + component: Button, + //πŸ‘‡ Creates specific argTypes + argTypes: { + backgroundColor: { control: 'color' }, + }, + args: { + //πŸ‘‡ Now all Button stories will be primary. + primary: true, + }, +} satisfies Meta; + +export default meta; +``` diff --git a/docs/snippets/svelte/button-story-component-args-primary.ts.mdx b/docs/snippets/svelte/button-story-component-args-primary.ts.mdx new file mode 100644 index 000000000000..2b5e54a6ea2d --- /dev/null +++ b/docs/snippets/svelte/button-story-component-args-primary.ts.mdx @@ -0,0 +1,21 @@ +```ts +// Button.stories.ts + +import type { Meta } from '@storybook/svelte'; + +import Button from './Button.svelte'; + +const meta: Meta = { + component: Button, + //πŸ‘‡ Creates specific argTypes + argTypes: { + backgroundColor: { control: 'color' }, + }, + args: { + //πŸ‘‡ Now all Button stories will be primary. + primary: true, + }, +}; + +export default meta; +``` diff --git a/docs/snippets/svelte/button-story-component-decorator.js.mdx b/docs/snippets/svelte/button-story-component-decorator.js.mdx index 75984c49a1ea..d777e387143f 100644 --- a/docs/snippets/svelte/button-story-component-decorator.js.mdx +++ b/docs/snippets/svelte/button-story-component-decorator.js.mdx @@ -8,22 +8,4 @@ export default { component: Button, decorators: [() => MarginDecorator], }; - -// Your stories here. - -// Don't forget to use the component you're testing and not the MarginDecorator component -``` - -```html - - -
- -
- - ``` diff --git a/docs/snippets/svelte/button-story-component-decorator.mdx.mdx b/docs/snippets/svelte/button-story-component-decorator.mdx.mdx deleted file mode 100644 index 843ae3a43f4c..000000000000 --- a/docs/snippets/svelte/button-story-component-decorator.mdx.mdx +++ /dev/null @@ -1,12 +0,0 @@ -```md - - -import { Story, Meta } from '@storybook/addon-docs'; - -import Button from './Button.svelte'; -import MarginDecorator from './MarginDecorator.svelte'; - - MarginDecorator]}/> - - -``` \ No newline at end of file diff --git a/docs/snippets/svelte/button-story-component-decorator.ts-4-9.mdx b/docs/snippets/svelte/button-story-component-decorator.ts-4-9.mdx new file mode 100644 index 000000000000..badb749d2732 --- /dev/null +++ b/docs/snippets/svelte/button-story-component-decorator.ts-4-9.mdx @@ -0,0 +1,15 @@ +```ts +// Button.stories.ts + +import type { Meta } from '@storybook/svelte'; + +import Button from './Button.svelte'; +import MarginDecorator from './MarginDecorator.svelte'; + +const meta = { + component: Button, + decorators: [() => MarginDecorator], +}; + +export default meta; +``` diff --git a/docs/snippets/svelte/button-story-component-decorator.ts.mdx b/docs/snippets/svelte/button-story-component-decorator.ts.mdx new file mode 100644 index 000000000000..67c72b7cc899 --- /dev/null +++ b/docs/snippets/svelte/button-story-component-decorator.ts.mdx @@ -0,0 +1,15 @@ +```ts +// Button.stories.ts + +import type { Meta } from '@storybook/svelte'; + +import Button from './Button.svelte'; +import MarginDecorator from './MarginDecorator.svelte'; + +const meta: Meta = { + component: Button, + decorators: [() => MarginDecorator], +}; + +export default meta; +``` diff --git a/docs/snippets/svelte/button-story-decorator.js.mdx b/docs/snippets/svelte/button-story-decorator.js.mdx index 30413fa807b4..94378724bb4d 100644 --- a/docs/snippets/svelte/button-story-decorator.js.mdx +++ b/docs/snippets/svelte/button-story-decorator.js.mdx @@ -8,15 +8,7 @@ export default { component: Button, }; -/* - *πŸ‘‡ Render functions are a framework specific feature to allow you control on how the component renders. - * See https://storybook.js.org/docs/api/csf - * to learn how to use render functions. - */ export const Primary = { - render: () => ({ - component: Button, - }), decorators: [() => MarginDecorator], }; ``` diff --git a/docs/snippets/svelte/button-story-decorator.mdx.mdx b/docs/snippets/svelte/button-story-decorator.mdx.mdx deleted file mode 100644 index 5abb2d2bf697..000000000000 --- a/docs/snippets/svelte/button-story-decorator.mdx.mdx +++ /dev/null @@ -1,25 +0,0 @@ -```md - - -import { Meta, Story } from '@storybook/addon-docs'; - -import Button from './Button.svelte'; -import MarginDecorator from './MarginDecorator.svelte'; - - - - - - MarginDecorator]} - render={(args) => ({ - Component: Badge, - props: args, - })} /> -``` \ No newline at end of file diff --git a/docs/snippets/svelte/button-story-decorator.ts-4-9.mdx b/docs/snippets/svelte/button-story-decorator.ts-4-9.mdx new file mode 100644 index 000000000000..94567b8b9ec1 --- /dev/null +++ b/docs/snippets/svelte/button-story-decorator.ts-4-9.mdx @@ -0,0 +1,19 @@ +```ts +// Button.stories.ts + +import { Meta, StoryObj } from '@storybook/svelte'; + +import Button from './Button.svelte'; +import MarginDecorator from './MarginDecorator.svelte'; + +const meta = { + component: Button, +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const Primary: Story = { + decorators: [() => MarginDecorator], +}; +``` diff --git a/docs/snippets/svelte/button-story-decorator.ts.mdx b/docs/snippets/svelte/button-story-decorator.ts.mdx new file mode 100644 index 000000000000..22ba3a40c092 --- /dev/null +++ b/docs/snippets/svelte/button-story-decorator.ts.mdx @@ -0,0 +1,19 @@ +```ts +// Button.stories.ts + +import { Meta, StoryObj } from '@storybook/svelte'; + +import Button from './Button.svelte'; +import MarginDecorator from './MarginDecorator.svelte'; + +const meta: Meta = { + component: Button, +}; + +export default meta; +type Story = StoryObj; + +export const Primary: Story = { + decorators: [() => MarginDecorator], +}; +``` diff --git a/docs/snippets/svelte/button-story-default-docs-code.mdx.mdx b/docs/snippets/svelte/button-story-default-docs-code.mdx.mdx deleted file mode 100644 index 410d3fc6b0c1..000000000000 --- a/docs/snippets/svelte/button-story-default-docs-code.mdx.mdx +++ /dev/null @@ -1,45 +0,0 @@ -```md - - -import { Meta, Story } from '@storybook/addon-docs'; - -import Button from './Button.svelte'; - - - - - -export const someFunction = (someValue) => { - return `i am a ${someValue}`; -}; - - - - - {(args) => { - const { label } = args; - const functionResult = someFunction(label); - return { - Component: Button, - props: { - ...args, - label: functionResult, - }, - }; - }} - -``` \ No newline at end of file diff --git a/docs/snippets/svelte/button-story-default-export-with-component.ts-4-9.mdx b/docs/snippets/svelte/button-story-default-export-with-component.ts-4-9.mdx new file mode 100644 index 000000000000..62d8e08df1b7 --- /dev/null +++ b/docs/snippets/svelte/button-story-default-export-with-component.ts-4-9.mdx @@ -0,0 +1,13 @@ +```ts +// Button.stories.ts + +import type { Meta } from '@storybook/svelte'; + +import Button from './Button.svelte'; + +const meta = { + component: Button, +} satisfies Meta; + +export default meta; +``` diff --git a/docs/snippets/svelte/button-story-default-export-with-component.ts.mdx b/docs/snippets/svelte/button-story-default-export-with-component.ts.mdx new file mode 100644 index 000000000000..d0bf35d7af69 --- /dev/null +++ b/docs/snippets/svelte/button-story-default-export-with-component.ts.mdx @@ -0,0 +1,13 @@ +```ts +// Button.stories.ts + +import type { Meta } from '@storybook/svelte'; + +import Button from './Button.svelte'; + +const meta: Meta = { + component: Button, +}; + +export default meta; +``` diff --git a/docs/snippets/svelte/button-story-rename-story.ts-4-9.mdx b/docs/snippets/svelte/button-story-rename-story.ts-4-9.mdx new file mode 100644 index 000000000000..2bb5d69c5565 --- /dev/null +++ b/docs/snippets/svelte/button-story-rename-story.ts-4-9.mdx @@ -0,0 +1,30 @@ +```ts +// Button.stories.ts + +import type { Meta, StoryObj } from '@storybook/svelte'; + +import Button from './Button.svelte'; + +const meta = { + component: Button, +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +/* + *πŸ‘‡ Render functions are a framework specific feature to allow you control on how the component renders. + * See https://storybook.js.org/docs/svelte/api/csf + * to learn how to use render functions. + */ +export const Primary: Story = ({ + name: 'I am the primary', + render: () => ({ + Component: Button, + props: { + primary: true, + label: 'Button', + }, + }), +}; +``` diff --git a/docs/snippets/svelte/button-story-rename-story.ts.mdx b/docs/snippets/svelte/button-story-rename-story.ts.mdx new file mode 100644 index 000000000000..ad254c10b73d --- /dev/null +++ b/docs/snippets/svelte/button-story-rename-story.ts.mdx @@ -0,0 +1,30 @@ +```ts +// Button.stories.ts + +import type { Meta, StoryObj } from '@storybook/svelte'; + +import Button from './Button.svelte'; + +const meta: Meta = { + component: Button, +}; + +export default meta; +type Story = StoryObj; + +/* + *πŸ‘‡ Render functions are a framework specific feature to allow you control on how the component renders. + * See https://storybook.js.org/docs/svelte/api/csf + * to learn how to use render functions. + */ +export const Primary: Story = ({ + name: 'I am the primary', + render: () => ({ + Component: Button, + props: { + primary: true, + label: 'Button', + }, + }), +}; +``` diff --git a/docs/snippets/svelte/button-story-using-args.js.mdx b/docs/snippets/svelte/button-story-using-args.js.mdx index 64dd4cd5f58b..8be69a92c46f 100644 --- a/docs/snippets/svelte/button-story-using-args.js.mdx +++ b/docs/snippets/svelte/button-story-using-args.js.mdx @@ -7,16 +7,7 @@ export default { component: Button, }; -/* - *πŸ‘‡ Render functions are a framework specific feature to allow you control on how the component renders. - * See https://storybook.js.org/docs/api/csf - * to learn how to use render functions. - */ export const Primary = { - render: (args) => ({ - Component: Button, - props: args, - }), args: { backgroundColor: '#ff0', label: 'Button', @@ -24,10 +15,6 @@ export const Primary = { }; export const Secondary = { - render: (args) => ({ - Component: Button, - props: args, - }), args: { ...Primary.args, label: 'πŸ˜„πŸ‘πŸ˜πŸ’―', @@ -35,10 +22,6 @@ export const Secondary = { }; export const Tertiary = { - render: (args) => ({ - Component: Button, - props: args, - }), args: { ...Primary.args, label: 'πŸ“šπŸ“•πŸ“ˆπŸ€“', diff --git a/docs/snippets/svelte/button-story-using-args.ts-4-9.mdx b/docs/snippets/svelte/button-story-using-args.ts-4-9.mdx new file mode 100644 index 000000000000..e5d5dc11f72d --- /dev/null +++ b/docs/snippets/svelte/button-story-using-args.ts-4-9.mdx @@ -0,0 +1,36 @@ +```ts +// Button.stories.ts + +import type { Meta, StoryObj } from '@storybook/svelte'; + +import Button from './Button.svelte'; + +//πŸ‘‡This default export determines where your story goes in the story list +const meta = { + component: Button, +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const Primary: Story = { + args: { + backgroundColor: '#ff0', + label: 'Button', + }, +}; + +export const Secondary: Story = { + args: { + ...Primary.args, + label: 'πŸ˜„πŸ‘πŸ˜πŸ’―', + }, +}; + +export const Tertiary: Story = { + args: { + ...Primary.args, + label: 'πŸ“šπŸ“•πŸ“ˆπŸ€“', + }, +}; +``` diff --git a/docs/snippets/svelte/button-story-using-args.ts.mdx b/docs/snippets/svelte/button-story-using-args.ts.mdx new file mode 100644 index 000000000000..edcd9995e364 --- /dev/null +++ b/docs/snippets/svelte/button-story-using-args.ts.mdx @@ -0,0 +1,36 @@ +```ts +// Button.stories.ts + +import type { Meta, StoryObj } from '@storybook/svelte'; + +import Button from './Button.svelte'; + +//πŸ‘‡This default export determines where your story goes in the story list +const meta: Meta = { + component: Button, +}; + +export default meta; +type Story = StoryObj; + +export const Primary: Story = { + args: { + backgroundColor: '#ff0', + label: 'Button', + }, +}; + +export const Secondary: Story = { + args: { + ...Primary.args, + label: 'πŸ˜„πŸ‘πŸ˜πŸ’―', + }, +}; + +export const Tertiary: Story = { + args: { + ...Primary.args, + label: 'πŸ“šπŸ“•πŸ“ˆπŸ€“', + }, +}; +``` diff --git a/docs/snippets/svelte/button-story-with-addon-example.js.mdx b/docs/snippets/svelte/button-story-with-addon-example.js.mdx index d96a3c9c2cba..e1fcca24d96d 100644 --- a/docs/snippets/svelte/button-story-with-addon-example.js.mdx +++ b/docs/snippets/svelte/button-story-with-addon-example.js.mdx @@ -9,6 +9,7 @@ export default { * to learn how to generate automatic titles */ title: 'Button', + component: Button, //πŸ‘‡ Creates specific parameters for the story parameters: { myAddon: { @@ -17,15 +18,5 @@ export default { }, }; -/* - *πŸ‘‡ Render functions are a framework specific feature to allow you control on how the component renders. - * See https://storybook.js.org/docs/api/csf - * to learn how to use render functions. - */ -export const Basic = { - render: (args) => ({ - Component: Button, - props: args, - }), -}; +export const Basic = {}; ``` diff --git a/docs/snippets/svelte/button-story-with-addon-example.ts-4-9.mdx b/docs/snippets/svelte/button-story-with-addon-example.ts-4-9.mdx new file mode 100644 index 000000000000..697c27744174 --- /dev/null +++ b/docs/snippets/svelte/button-story-with-addon-example.ts-4-9.mdx @@ -0,0 +1,27 @@ +```ts +// Button.stories.ts + +import type { Meta, StoryObj } from '@storybook/svelte'; + +import Button from './Button.svelte'; + +const meta = { + /* πŸ‘‡ The title prop is optional. + * See https://storybook.js.org/docs/configure/#configure-story-loading + * to learn how to generate automatic titles + */ + title: 'Button', + component: Button, + //πŸ‘‡ Creates specific parameters for the story + parameters: { + myAddon: { + data: 'this data is passed to the addon', + }, + }, +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const Basic: Story = {}; +``` diff --git a/docs/snippets/svelte/button-story-with-addon-example.ts.mdx b/docs/snippets/svelte/button-story-with-addon-example.ts.mdx new file mode 100644 index 000000000000..53aa9fe085fd --- /dev/null +++ b/docs/snippets/svelte/button-story-with-addon-example.ts.mdx @@ -0,0 +1,27 @@ +```ts +// Button.stories.ts + +import type { Meta, StoryObj } from '@storybook/svelte'; + +import Button from './Button.svelte'; + +const meta: Meta = { + /* πŸ‘‡ The title prop is optional. + * See https://storybook.js.org/docs/configure/#configure-story-loading + * to learn how to generate automatic titles + */ + title: 'Button', + component: Button, + //πŸ‘‡ Creates specific parameters for the story + parameters: { + myAddon: { + data: 'this data is passed to the addon', + }, + }, +}; + +export default meta; +type Story = StoryObj; + +export const Basic: Story = {}; +``` diff --git a/docs/snippets/svelte/button-story-with-args.js.mdx b/docs/snippets/svelte/button-story-with-args.js.mdx index 652c4b59d0d0..58cf0732e6be 100644 --- a/docs/snippets/svelte/button-story-with-args.js.mdx +++ b/docs/snippets/svelte/button-story-with-args.js.mdx @@ -7,16 +7,7 @@ export default { component: Button, }; -/* - *πŸ‘‡ Render functions are a framework specific feature to allow you control on how the component renders. - * See https://storybook.js.org/docs/api/csf - * to learn how to use render functions. - */ export const Primary = { - render: (args) => ({ - Component: Button, - props: args, - }), args: { primary: true, label: 'Button', diff --git a/docs/snippets/svelte/button-story-with-args.mdx.mdx b/docs/snippets/svelte/button-story-with-args.mdx.mdx deleted file mode 100644 index 365def163b33..000000000000 --- a/docs/snippets/svelte/button-story-with-args.mdx.mdx +++ /dev/null @@ -1,26 +0,0 @@ -```md - - -import { Meta, Story } from '@storybook/addon-docs'; - -import Button from './Button.svelte'; - - - - - - ({ - Component: Button, - props: args, - })} /> -``` \ No newline at end of file diff --git a/docs/snippets/svelte/button-story-with-args.ts-4-9.mdx b/docs/snippets/svelte/button-story-with-args.ts-4-9.mdx index 045361662c3e..059ecc250092 100644 --- a/docs/snippets/svelte/button-story-with-args.ts-4-9.mdx +++ b/docs/snippets/svelte/button-story-with-args.ts-4-9.mdx @@ -12,16 +12,7 @@ const meta = { export default meta; type Story = StoryObj; -/* - *πŸ‘‡ Render functions are a framework specific feature to allow you control on how the component renders. - * See https://storybook.js.org/docs/api/csf - * to learn how to use render functions. - */ export const Primary: Story = { - render: (args) => ({ - Component: Button, - props: args, - }), args: { primary: true, label: 'Button', diff --git a/docs/snippets/svelte/button-story-with-args.ts.mdx b/docs/snippets/svelte/button-story-with-args.ts.mdx index ee49e33b2069..0c481911787c 100644 --- a/docs/snippets/svelte/button-story-with-args.ts.mdx +++ b/docs/snippets/svelte/button-story-with-args.ts.mdx @@ -12,16 +12,7 @@ const meta: Meta = { export default meta; type Story = StoryObj; -/* - *πŸ‘‡ Render functions are a framework specific feature to allow you control on how the component renders. - * See https://storybook.js.org/docs/api/csf - * to learn how to use render functions. - */ export const Primary: Story = { - render: (args) => ({ - Component: Button, - props: args, - }), args: { primary: true, label: 'Button', diff --git a/docs/snippets/svelte/button-story-with-blue-args.mdx.mdx b/docs/snippets/svelte/button-story-with-blue-args.mdx.mdx deleted file mode 100644 index c6d410ddc632..000000000000 --- a/docs/snippets/svelte/button-story-with-blue-args.mdx.mdx +++ /dev/null @@ -1,24 +0,0 @@ -```md - - -import { Meta } from '@storybook/addon-docs'; - -import Button from './Button.svelte'; - - - - - -``` \ No newline at end of file diff --git a/docs/snippets/svelte/button-story-with-blue-args.ts-4-9.mdx b/docs/snippets/svelte/button-story-with-blue-args.ts-4-9.mdx new file mode 100644 index 000000000000..c45a9dcd99ab --- /dev/null +++ b/docs/snippets/svelte/button-story-with-blue-args.ts-4-9.mdx @@ -0,0 +1,23 @@ +```ts +// Button.stories.ts + +import type { Meta } from '@storybook/svelte'; + +import Button from './Button.svelte'; + +const meta = { + component: Button, + //πŸ‘‡ Creates specific parameters for the story + parameters: { + backgrounds: { + values: [ + { name: 'red', value: '#f00' }, + { name: 'green', value: '#0f0' }, + { name: 'blue', value: '#00f' }, + ], + }, + }, +} satisfies Meta; + +export default meta; +``` diff --git a/docs/snippets/svelte/button-story-with-blue-args.ts.mdx b/docs/snippets/svelte/button-story-with-blue-args.ts.mdx new file mode 100644 index 000000000000..4e2960f81120 --- /dev/null +++ b/docs/snippets/svelte/button-story-with-blue-args.ts.mdx @@ -0,0 +1,23 @@ +```ts +// Button.stories.ts + +import type { Meta } from '@storybook/svelte'; + +import Button from './Button.svelte'; + +const meta: Meta = { + component: Button, + //πŸ‘‡ Creates specific parameters for the story + parameters: { + backgrounds: { + values: [ + { name: 'red', value: '#f00' }, + { name: 'green', value: '#0f0' }, + { name: 'blue', value: '#00f' }, + ], + }, + }, +}; + +export default meta; +``` diff --git a/docs/snippets/svelte/button-story-with-emojis.mdx.mdx b/docs/snippets/svelte/button-story-with-emojis.mdx.mdx deleted file mode 100644 index 00fa74f2c06f..000000000000 --- a/docs/snippets/svelte/button-story-with-emojis.mdx.mdx +++ /dev/null @@ -1,43 +0,0 @@ -```md - - -import { Meta, Story } from '@storybook/addon-docs'; - -import Button from './Button.svelte'; - - - - - - ({ - Component: Button, - props: { - backgroundColor: '#ff0', - label: 'Button', - } - })} /> - ({ - Component: Button, - props: { - background: '#ff0', - label: 'πŸ˜„πŸ‘πŸ˜πŸ’―', - }, - })} /> - ({ - Component: Button, - props: { - background: '#ff0', - label: 'πŸ“šπŸ“•πŸ“ˆπŸ€“', - }, - })} /> -``` \ No newline at end of file diff --git a/docs/snippets/svelte/button-story-with-emojis.ts-4-9.mdx b/docs/snippets/svelte/button-story-with-emojis.ts-4-9.mdx new file mode 100644 index 000000000000..61c72830fa8f --- /dev/null +++ b/docs/snippets/svelte/button-story-with-emojis.ts-4-9.mdx @@ -0,0 +1,49 @@ +```ts +// Button.stories.ts + +import type { Meta, StoryObj } from '@storybook/svelte'; + +import Button from './Button.svelte'; + +const meta = { + component: Button, +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +/* + *πŸ‘‡ Render functions are a framework specific feature to allow you control on how the component renders. + * See https://storybook.js.org/docs/svelte/api/csf + * to learn how to use render functions. + */ +export const Primary: Story = { + render: () => ({ + Component: Button, + props: { + backgroundColor: '#ff0', + label: 'Button', + }, + }), +}; + +export const Secondary: Story = { + render: () => ({ + Component: Button, + props: { + backgroundColor: '#ff0', + label: 'πŸ˜„πŸ‘πŸ˜πŸ’―', + }, + }), +}; + +export const Tertiary: Story = { + render: () => ({ + Component: Button, + props: { + backgroundColor: '#ff0', + label: 'πŸ“šπŸ“•πŸ“ˆπŸ€“', + }, + }), +}; +``` diff --git a/docs/snippets/svelte/button-story-with-emojis.ts.mdx b/docs/snippets/svelte/button-story-with-emojis.ts.mdx new file mode 100644 index 000000000000..8bcc1bd7c66a --- /dev/null +++ b/docs/snippets/svelte/button-story-with-emojis.ts.mdx @@ -0,0 +1,49 @@ +```ts +// Button.stories.ts + +import type { Meta, StoryObj } from '@storybook/svelte'; + +import Button from './Button.svelte'; + +const meta: Meta = { + component: Button, +}; + +export default meta; +type Story = StoryObj; + +/* + *πŸ‘‡ Render functions are a framework specific feature to allow you control on how the component renders. + * See https://storybook.js.org/docs/svelte/api/csf + * to learn how to use render functions. + */ +export const Primary: Story = { + render: () => ({ + Component: Button, + props: { + backgroundColor: '#ff0', + label: 'Button', + }, + }), +}; + +export const Secondary: Story = { + render: () => ({ + Component: Button, + props: { + backgroundColor: '#ff0', + label: 'πŸ˜„πŸ‘πŸ˜πŸ’―', + }, + }), +}; + +export const Tertiary: Story = { + render: () => ({ + Component: Button, + props: { + backgroundColor: '#ff0', + label: 'πŸ“šπŸ“•πŸ“ˆπŸ€“', + }, + }), +}; +``` diff --git a/docs/snippets/svelte/button-story.mdx.mdx b/docs/snippets/svelte/button-story.mdx.mdx deleted file mode 100644 index 863161bf7248..000000000000 --- a/docs/snippets/svelte/button-story.mdx.mdx +++ /dev/null @@ -1,27 +0,0 @@ -```md - - -import { Meta, Story } from '@storybook/addon-docs'; - -import Button from './Button.svelte'; - - - -# Button - - - - ({ - Component:Button, - props: { - primary: true, - label: 'Button', - }, - })} /> -``` \ No newline at end of file diff --git a/docs/snippets/svelte/checkbox-story.mdx.mdx b/docs/snippets/svelte/checkbox-story.mdx.mdx deleted file mode 100644 index 7359621ab606..000000000000 --- a/docs/snippets/svelte/checkbox-story.mdx.mdx +++ /dev/null @@ -1,55 +0,0 @@ -```md - - -import { Canvas, Meta, Story } from '@storybook/addon-docs'; - -import Checkbox from './Checkbox.svelte'; - - - - - -# Checkbox - -With `MDX`, we can define a story for `Checkbox` right in the middle of our -Markdown documentation. - - - ({ - Component: Checkbox, - props: args - })} /> - - ({ - Component: Checkbox, - props: args - })} /> - - ({ - Component: Checkbox, - props: args - })} /> - -``` \ No newline at end of file diff --git a/docs/snippets/svelte/component-story-custom-args-complex.ts-4-9.mdx b/docs/snippets/svelte/component-story-custom-args-complex.ts-4-9.mdx new file mode 100644 index 000000000000..e32f516fb01b --- /dev/null +++ b/docs/snippets/svelte/component-story-custom-args-complex.ts-4-9.mdx @@ -0,0 +1,46 @@ +```ts +// YourComponent.stories.ts + +import type { Meta, StoryObj } from '@storybook/svelte'; + +import YourComponent from './YourComponent.svelte'; + +const meta = { + component: YourComponent, + //πŸ‘‡ Creates specific argTypes + argTypes: { + propertyA: { + options: ['Item One', 'Item Two', 'Item Three'], + control: { type: 'select' }, // Automatically inferred when 'options' is defined + }, + propertyB: { + options: ['Another Item One', 'Another Item Two', 'Another Item Three'], + }, + }, +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +const someFunction = (valuePropertyA, valuePropertyB) => { + // Do some logic here +}; + +export const ExampleStory: Story = { + render: ({ propertyA, propertyB }) => { + //πŸ‘‡ Assigns the function result to a variable + const someFunctionResult = someFunction(propertyA, propertyB); + return { + Component: YourComponent, + props: { + ...args, + someProperty: someFunctionResult, + }, + }; + }, + args: { + propertyA: 'Item One', + propertyB: 'Another Item One', + }, +}; +``` diff --git a/docs/snippets/svelte/component-story-custom-args-complex.ts.mdx b/docs/snippets/svelte/component-story-custom-args-complex.ts.mdx new file mode 100644 index 000000000000..eb0a45d9a1db --- /dev/null +++ b/docs/snippets/svelte/component-story-custom-args-complex.ts.mdx @@ -0,0 +1,46 @@ +```ts +// YourComponent.stories.ts + +import type { Meta, StoryObj } from '@storybook/svelte'; + +import YourComponent from './YourComponent.svelte'; + +const meta: Meta = { + component: YourComponent, + //πŸ‘‡ Creates specific argTypes + argTypes: { + propertyA: { + options: ['Item One', 'Item Two', 'Item Three'], + control: { type: 'select' }, // Automatically inferred when 'options' is defined + }, + propertyB: { + options: ['Another Item One', 'Another Item Two', 'Another Item Three'], + }, + }, +}; + +export default meta; +type Story = StoryObj; + +const someFunction = (valuePropertyA, valuePropertyB) => { + // Do some logic here +}; + +export const ExampleStory: Story = { + render: ({ propertyA, propertyB }) => { + //πŸ‘‡ Assigns the function result to a variable + const someFunctionResult = someFunction(propertyA, propertyB); + return { + Component: YourComponent, + props: { + ...args, + someProperty: someFunctionResult, + }, + }; + }, + args: { + propertyA: 'Item One', + propertyB: 'Another Item One', + }, +}; +``` diff --git a/docs/snippets/svelte/component-story-figma-integration.js.mdx b/docs/snippets/svelte/component-story-figma-integration.js.mdx index f77576417513..f6781fe6fe61 100644 --- a/docs/snippets/svelte/component-story-figma-integration.js.mdx +++ b/docs/snippets/svelte/component-story-figma-integration.js.mdx @@ -5,14 +5,10 @@ import MyComponent from './MyComponent.svelte'; // More on default export: https://storybook.js.org/docs/writing-stories/#default-export export default { - component: { MyComponent }, + component: MyComponent, }; export const Example = { - render: () => ({ - Component: MyComponent, - props: {}, - }), parameters: { design: { type: 'figma', diff --git a/docs/snippets/svelte/component-story-figma-integration.mdx.mdx b/docs/snippets/svelte/component-story-figma-integration.mdx.mdx deleted file mode 100644 index f28ee0608e39..000000000000 --- a/docs/snippets/svelte/component-story-figma-integration.mdx.mdx +++ /dev/null @@ -1,33 +0,0 @@ -```md - - -import { Canvas, Meta, Story } from '@storybook/addon-docs'; - -import MyComponent from './MyComponent.svelte'; - - - - - - - ({ - Component: MyComponent, - props: {} - })} /> - -``` \ No newline at end of file diff --git a/docs/snippets/svelte/component-story-figma-integration.ts-4-9.mdx b/docs/snippets/svelte/component-story-figma-integration.ts-4-9.mdx new file mode 100644 index 000000000000..bf5c42c553f4 --- /dev/null +++ b/docs/snippets/svelte/component-story-figma-integration.ts-4-9.mdx @@ -0,0 +1,24 @@ +```ts +// MyComponent.stories.ts + +import type { Meta, StoryObj } from '@storybook/svelte'; + +import MyComponent from './MyComponent.svelte'; + +// More on default export: https://storybook.js.org/docs/svelte/writing-stories/introduction#default-export +const meta = { + component: MyComponent, +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const Example: Story = { + parameters: { + design: { + type: 'figma', + url: 'https://www.figma.com/file/Sample-File', + }, + }, +}; +``` diff --git a/docs/snippets/svelte/component-story-figma-integration.ts.mdx b/docs/snippets/svelte/component-story-figma-integration.ts.mdx new file mode 100644 index 000000000000..799438a116eb --- /dev/null +++ b/docs/snippets/svelte/component-story-figma-integration.ts.mdx @@ -0,0 +1,24 @@ +```ts +// MyComponent.stories.ts + +import type { Meta, StoryObj } from '@storybook/svelte'; + +import MyComponent from './MyComponent.svelte'; + +// More on default export: https://storybook.js.org/docs/svelte/writing-stories/introduction#default-export +const meta: Meta = { + component: MyComponent, +}; + +export default meta; +type Story = StoryObj; + +export const Example: Story = { + parameters: { + design: { + type: 'figma', + url: 'https://www.figma.com/file/Sample-File', + }, + }, +}; +``` diff --git a/docs/snippets/svelte/component-story-mdx-story-by-name.mdx.mdx b/docs/snippets/svelte/component-story-mdx-story-by-name.mdx.mdx deleted file mode 100644 index 449383141f75..000000000000 --- a/docs/snippets/svelte/component-story-mdx-story-by-name.mdx.mdx +++ /dev/null @@ -1,23 +0,0 @@ -```md - - -import { Meta, Story } from '@storybook/addon-docs'; - -import Button from './Button.svelte'; - - - - - - ({ - Component: Button, - props: args, - })} /> -``` \ No newline at end of file diff --git a/docs/snippets/svelte/component-story-static-asset-cdn.mdx.mdx b/docs/snippets/svelte/component-story-static-asset-cdn.mdx.mdx deleted file mode 100644 index c2704b49bbd4..000000000000 --- a/docs/snippets/svelte/component-story-static-asset-cdn.mdx.mdx +++ /dev/null @@ -1,25 +0,0 @@ -```md - - -import { Meta, Story } from '@storybook/addon-docs'; - -import MyComponent from './MyComponent.svelte'; - - - - - - ({ - Component: MyComponent, - props: { - src: 'https://storybook.js.org/images/placeholders/350x150.png', - alt: 'my image', - }, - })} /> -``` \ No newline at end of file diff --git a/docs/snippets/svelte/component-story-static-asset-cdn.ts-4-9.mdx b/docs/snippets/svelte/component-story-static-asset-cdn.ts-4-9.mdx new file mode 100644 index 000000000000..542c6ccefb33 --- /dev/null +++ b/docs/snippets/svelte/component-story-static-asset-cdn.ts-4-9.mdx @@ -0,0 +1,24 @@ +```ts +// MyComponent.stories.ts + +import type { Meta, StoryObj } from '@storybook/svelte'; + +import MyComponent from './MyComponent.svelte'; + +const meta = { + component: MyComponent, +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const WithAnImage: Story = { + render: () => ({ + Component: MyComponent, + props: { + src: 'https://storybook.js.org/images/placeholders/350x150.png', + alt: 'My CDN placeholder', + }, + }), +}; +``` diff --git a/docs/snippets/svelte/component-story-static-asset-cdn.ts.mdx b/docs/snippets/svelte/component-story-static-asset-cdn.ts.mdx new file mode 100644 index 000000000000..3b21d2eed894 --- /dev/null +++ b/docs/snippets/svelte/component-story-static-asset-cdn.ts.mdx @@ -0,0 +1,24 @@ +```ts +// MyComponent.stories.ts + +import type { Meta, StoryObj } from '@storybook/svelte'; + +import MyComponent from './MyComponent.svelte'; + +const meta: Meta = { + component: MyComponent, +}; + +export default meta; +type Story = StoryObj; + +export const WithAnImage: Story = { + render: () => ({ + Component: MyComponent, + props: { + src: 'https://storybook.js.org/images/placeholders/350x150.png', + alt: 'My CDN placeholder', + }, + }), +}; +``` diff --git a/docs/snippets/svelte/component-story-static-asset-with-import.mdx.mdx b/docs/snippets/svelte/component-story-static-asset-with-import.mdx.mdx deleted file mode 100644 index 0b688fa554de..000000000000 --- a/docs/snippets/svelte/component-story-static-asset-with-import.mdx.mdx +++ /dev/null @@ -1,29 +0,0 @@ -```md - - -import { Meta, Story } from '@storybook/addon-docs'; - -import MyComponent from './MyComponent.svelte'; - -import imageFile from './static/image.png'; - - - - - -export const image = { - src: imageFile, - alt: 'my image', -}; - - ({ - Component: MyComponent, - props: image - })} /> -``` \ No newline at end of file diff --git a/docs/snippets/svelte/component-story-static-asset-with-import.ts-4-9.mdx b/docs/snippets/svelte/component-story-static-asset-with-import.ts-4-9.mdx new file mode 100644 index 000000000000..bc8eb9d4688c --- /dev/null +++ b/docs/snippets/svelte/component-story-static-asset-with-import.ts-4-9.mdx @@ -0,0 +1,28 @@ +```ts +// MyComponent.stories.ts + +import type { Meta, StoryObj } from '@storybook/svelte'; + +import MyComponent from './MyComponent.svelte'; + +import imageFile from './static/image.png'; + +const meta = { + component: MyComponent, +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +const image = { + src: imageFile, + alt: 'my image', +}; + +export const WithAnImage: Story = { + render: () => ({ + Component: MyComponent, + props: image, + }), +}; +``` diff --git a/docs/snippets/svelte/component-story-static-asset-with-import.ts.mdx b/docs/snippets/svelte/component-story-static-asset-with-import.ts.mdx new file mode 100644 index 000000000000..9014220f808c --- /dev/null +++ b/docs/snippets/svelte/component-story-static-asset-with-import.ts.mdx @@ -0,0 +1,28 @@ +```ts +// MyComponent.stories.ts + +import type { Meta, StoryObj } from '@storybook/svelte'; + +import MyComponent from './MyComponent.svelte'; + +import imageFile from './static/image.png'; + +const meta: Meta = { + component: MyComponent, +}; + +export default meta; +type Story = StoryObj; + +const image = { + src: imageFile, + alt: 'my image', +}; + +export const WithAnImage: Story = { + render: () => ({ + Component: MyComponent, + props: image, + }), +}; +``` diff --git a/docs/snippets/svelte/component-story-static-asset-without-import.mdx.mdx b/docs/snippets/svelte/component-story-static-asset-without-import.mdx.mdx deleted file mode 100644 index 5d7141fd087e..000000000000 --- a/docs/snippets/svelte/component-story-static-asset-without-import.mdx.mdx +++ /dev/null @@ -1,21 +0,0 @@ -```md - - -import { Meta, Story } from '@storybook/addon-docs'; - -import MyComponent from './MyComponent.svelte0; - - - - - - ({ - Component: MyComponent, - props: { - src: '/image.png', - alt: 'my image', - }, - })} /> -``` \ No newline at end of file diff --git a/docs/snippets/svelte/component-story-static-asset-without-import.ts-4-9.mdx b/docs/snippets/svelte/component-story-static-asset-without-import.ts-4-9.mdx new file mode 100644 index 000000000000..894af1a2f567 --- /dev/null +++ b/docs/snippets/svelte/component-story-static-asset-without-import.ts-4-9.mdx @@ -0,0 +1,25 @@ +```ts +// MyComponent.stories.ts + +import type { Meta, StoryObj } from '@storybook/svelte'; + +import MyComponent from './MyComponent.svelte'; + +const meta = { + component: MyComponent, +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +// Assume image.png is located in the "public" directory. +export const WithAnImage: Story = { + render: () => ({ + Component: MyComponent, + props: { + src: '/image.png', + alt: 'my image', + }, + }), +}; +``` diff --git a/docs/snippets/svelte/component-story-static-asset-without-import.ts.mdx b/docs/snippets/svelte/component-story-static-asset-without-import.ts.mdx new file mode 100644 index 000000000000..cfc54fb20623 --- /dev/null +++ b/docs/snippets/svelte/component-story-static-asset-without-import.ts.mdx @@ -0,0 +1,25 @@ +```ts +// MyComponent.stories.ts + +import type { Meta, StoryObj } from '@storybook/svelte'; + +import MyComponent from './MyComponent.svelte'; + +const meta: Meta = { + component: MyComponent, +}; + +export default meta; +type Story = StoryObj; + +// Assume image.png is located in the "public" directory. +export const WithAnImage: Story = { + render: () => ({ + Component: MyComponent, + props: { + src: '/image.png', + alt: 'my image', + }, + }), +}; +``` diff --git a/docs/snippets/svelte/component-story-with-accessibility.mdx.mdx b/docs/snippets/svelte/component-story-with-accessibility.mdx.mdx deleted file mode 100644 index 173dc60e1691..000000000000 --- a/docs/snippets/svelte/component-story-with-accessibility.mdx.mdx +++ /dev/null @@ -1,51 +0,0 @@ -```md - - -import { Meta, Story } from '@storybook/addon-docs'; - -import Button from './Button.svelte'; - - - - - -## This is an accessible story - - ({ - Component: Button, - props: args, - })} /> - -## This is not - - ({ - Component: Button, - props: args, - })} /> -``` \ No newline at end of file diff --git a/docs/snippets/svelte/component-story-with-accessibility.ts-4-9.mdx b/docs/snippets/svelte/component-story-with-accessibility.ts-4-9.mdx new file mode 100644 index 000000000000..fd54dd1393c1 --- /dev/null +++ b/docs/snippets/svelte/component-story-with-accessibility.ts-4-9.mdx @@ -0,0 +1,33 @@ +```ts +// Button.stories.ts + +import type { Meta, StoryObj } from '@storybook/svelte'; + +import Button from './Button.svelte'; + +const meta = { + component: Button, + argTypes: { + backgroundColor: { control: 'color' }, + }, +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +// This is an accessible story +export const Accessible: Story = { + args: { + primary: false, + label: 'Button', + }, +}; + +// This is not +export const Inaccessible: Story = { + args: { + ...Accessible.args, + backgroundColor: 'red', + }, +}; +``` diff --git a/docs/snippets/svelte/component-story-with-accessibility.ts.mdx b/docs/snippets/svelte/component-story-with-accessibility.ts.mdx new file mode 100644 index 000000000000..c66dc1afb6e3 --- /dev/null +++ b/docs/snippets/svelte/component-story-with-accessibility.ts.mdx @@ -0,0 +1,33 @@ +```ts +// Button.stories.ts + +import type { Meta, StoryObj } from '@storybook/svelte'; + +import Button from './Button.svelte'; + +const meta: Meta = { + component: Button, + argTypes: { + backgroundColor: { control: 'color' }, + }, +}; + +export default meta; +type Story = StoryObj; + +// This is an accessible story +export const Accessible: Story = { + args: { + primary: false, + label: 'Button', + }, +}; + +// This is not +export const Inaccessible: Story = { + args: { + ...Accessible.args, + backgroundColor: 'red', + }, +}; +``` diff --git a/docs/snippets/svelte/component-test-with-testing-library.js.mdx b/docs/snippets/svelte/component-test-with-testing-library.js.mdx index f7e1702c3451..cd3da15a6bfc 100644 --- a/docs/snippets/svelte/component-test-with-testing-library.js.mdx +++ b/docs/snippets/svelte/component-test-with-testing-library.js.mdx @@ -1,5 +1,5 @@ ```js -// Form.test.js +// Form.test.js|ts import { render, fireEvent } from '@testing-library/svelte'; diff --git a/docs/snippets/svelte/csf-2-example-starter.js.mdx b/docs/snippets/svelte/csf-2-example-starter.js.mdx new file mode 100644 index 000000000000..025761271718 --- /dev/null +++ b/docs/snippets/svelte/csf-2-example-starter.js.mdx @@ -0,0 +1,16 @@ +```js +// Button.stories.js + +import Button from './Button.svelte'; + +export default { + title: 'Button', + component: Button, +}; + +export const Primary = (args) => ({ + Component: Button, + props: args, +}); +Primary.args = { primary: true }; +``` diff --git a/docs/snippets/svelte/csf-2-example-starter.ts.mdx b/docs/snippets/svelte/csf-2-example-starter.ts.mdx new file mode 100644 index 000000000000..67f72c6419ce --- /dev/null +++ b/docs/snippets/svelte/csf-2-example-starter.ts.mdx @@ -0,0 +1,18 @@ +```ts +// Button.stories.ts + +import type { Meta, StoryFn } from '@storybook/svelte'; + +import Button from './Button.svelte'; + +export default { + title: 'Button', + component: Button, +} as Meta; + +export const Primary: StoryFn = (args) => ({ + Component: Button, + props: args, +}); +Primary.args = { primary: true }; +``` diff --git a/docs/snippets/svelte/csf-2-example-story.js.mdx b/docs/snippets/svelte/csf-2-example-story.js.mdx new file mode 100644 index 000000000000..31654612ae2b --- /dev/null +++ b/docs/snippets/svelte/csf-2-example-story.js.mdx @@ -0,0 +1,9 @@ +```js +// CSF 2 + +// Other imports and story implementation +export const Default = (args) => ({ + Component: Button, + props: args, +}); +``` diff --git a/docs/snippets/svelte/csf-2-example-story.ts.mdx b/docs/snippets/svelte/csf-2-example-story.ts.mdx new file mode 100644 index 000000000000..3d479ca132fc --- /dev/null +++ b/docs/snippets/svelte/csf-2-example-story.ts.mdx @@ -0,0 +1,9 @@ +```ts +// CSF 2 + +// Other imports and story implementation +export const Primary: StoryFn = (args) => ({ + Component: Button, + props: args, +}); +``` diff --git a/docs/snippets/svelte/csf-3-example-render.js.mdx b/docs/snippets/svelte/csf-3-example-render.js.mdx new file mode 100644 index 000000000000..bf3cd564a422 --- /dev/null +++ b/docs/snippets/svelte/csf-3-example-render.js.mdx @@ -0,0 +1,11 @@ +```js +// CSF 3 - explicit render function + +// Other imports and story implementation +export const Default = { + render: (args) => ({ + Component: Button, + props: args, + }); +}; +``` diff --git a/docs/snippets/svelte/csf-3-example-render.ts.mdx b/docs/snippets/svelte/csf-3-example-render.ts.mdx new file mode 100644 index 000000000000..ea8603bdcf9a --- /dev/null +++ b/docs/snippets/svelte/csf-3-example-render.ts.mdx @@ -0,0 +1,11 @@ +```ts +// CSF 3 - explicit render function + +// Other imports and story implementation +export const Default: Story = { + render: (args) => ({ + Component: Button, + props: args, + }), +}; +``` diff --git a/docs/snippets/svelte/csf-3-example-starter.ts.mdx b/docs/snippets/svelte/csf-3-example-starter.ts.mdx new file mode 100644 index 000000000000..70a4585e5192 --- /dev/null +++ b/docs/snippets/svelte/csf-3-example-starter.ts.mdx @@ -0,0 +1,14 @@ +```ts +// Button.stories.ts + +import type { Meta, StoryObj } from '@storybook/svelte'; + +import Button from './Button.svelte'; + +const meta: Meta = { component: Button }; +export default meta; + +type Story = StoryObj; + +export const Primary: Story = { args: { primary: true } }; +``` diff --git a/docs/snippets/svelte/document-screen-fetch.js.mdx b/docs/snippets/svelte/document-screen-fetch.js.mdx index b50d0bc021bd..e36bec8be30b 100644 --- a/docs/snippets/svelte/document-screen-fetch.js.mdx +++ b/docs/snippets/svelte/document-screen-fetch.js.mdx @@ -7,6 +7,7 @@ import PageLayout from './PageLayout.svelte'; import DocumentHeader from './DocumentHeader.svelte'; import DocumentList from './DocumentList.svelte'; + export let user = {}; export let document = {}; export let subdocuments = []; @@ -35,7 +36,7 @@ {#if status === "error"}

There was an error fetching the data!

-{/if} {#if status === "loading"} +{:else if status === "loading"}

Loading...

{:else} diff --git a/docs/snippets/svelte/document-screen-fetch.ts.mdx b/docs/snippets/svelte/document-screen-fetch.ts.mdx new file mode 100644 index 000000000000..a64fa476ccad --- /dev/null +++ b/docs/snippets/svelte/document-screen-fetch.ts.mdx @@ -0,0 +1,47 @@ +```html + + + + +{#if status === "error"} +

There was an error fetching the data!

+{:else if status === "loading"} +

Loading...

+{:else} + + + + +{/if} +``` diff --git a/docs/snippets/svelte/document-screen-with-grapqhl.ts.mdx b/docs/snippets/svelte/document-screen-with-grapqhl.ts.mdx new file mode 100644 index 000000000000..df975e9da4b3 --- /dev/null +++ b/docs/snippets/svelte/document-screen-with-grapqhl.ts.mdx @@ -0,0 +1,46 @@ +```html + + + + +{#if $infoResult.loading} +

Loading...

+{:else if $infoResult.error} +

There was an error fetching the data!

+{:else} + + + + +{/if} +``` diff --git a/docs/snippets/svelte/documentscreen-story-msw-graphql-query.js.mdx b/docs/snippets/svelte/documentscreen-story-msw-graphql-query.js.mdx index 7f44a194d27d..2ef38ef65b84 100644 --- a/docs/snippets/svelte/documentscreen-story-msw-graphql-query.js.mdx +++ b/docs/snippets/svelte/documentscreen-story-msw-graphql-query.js.mdx @@ -8,7 +8,7 @@ import MockApolloWrapperClient from './MockApolloWrapperClient.svelte'; export default { component: DocumentScreen, - decorators: [() => MockGraphqlProvider], + decorators: [() => MockApolloWrapperClient], }; //πŸ‘‡The mocked data that will be used in the story diff --git a/docs/snippets/svelte/documentscreen-story-msw-graphql-query.ts-4-9.mdx b/docs/snippets/svelte/documentscreen-story-msw-graphql-query.ts-4-9.mdx new file mode 100644 index 000000000000..ab72000499cd --- /dev/null +++ b/docs/snippets/svelte/documentscreen-story-msw-graphql-query.ts-4-9.mdx @@ -0,0 +1,70 @@ +```ts +// YourPage.stories.ts + +import type { Meta, StoryObj } from '@storybook/svelte'; + +import { graphql } from 'msw'; + +import DocumentScreen from './YourPage.svelte'; +import MockApolloWrapperClient from './MockApolloWrapperClient.svelte'; + +const meta = { + component: DocumentScreen, + decorators: [() => MockApolloWrapperClient], +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +//πŸ‘‡The mocked data that will be used in the story +const TestData = { + user: { + userID: 1, + name: 'Someone', + }, + document: { + id: 1, + userID: 1, + title: 'Something', + brief: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.', + status: 'approved', + }, + subdocuments: [ + { + id: 1, + userID: 1, + title: 'Something', + content: + 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.', + status: 'approved', + }, + ], +}; + +export const MockedSuccess: Story = { + parameters: { + msw: [ + graphql.query('AllInfoQuery', (req, res, ctx) => { + return res(ctx.data(TestData)); + }), + ], + }, +}; + +export const MockedError: Story = { + parameters: { + msw: [ + graphql.query('AllInfoQuery', (req, res, ctx) => { + return res( + ctx.delay(800), + ctx.errors([ + { + message: 'Access denied', + }, + ]) + ); + }), + ], + }, +}; +``` diff --git a/docs/snippets/svelte/documentscreen-story-msw-graphql-query.ts.mdx b/docs/snippets/svelte/documentscreen-story-msw-graphql-query.ts.mdx new file mode 100644 index 000000000000..c61204cfd1ab --- /dev/null +++ b/docs/snippets/svelte/documentscreen-story-msw-graphql-query.ts.mdx @@ -0,0 +1,70 @@ +```ts +// YourPage.stories.ts + +import type { Meta, StoryObj } from '@storybook/svelte'; + +import { graphql } from 'msw'; + +import DocumentScreen from './YourPage.svelte'; +import MockApolloWrapperClient from './MockApolloWrapperClient.svelte'; + +const meta: Meta = { + component: DocumentScreen, + decorators: [() => MockApolloWrapperClient], +}; + +export default meta; +type Story = StoryObj; + +//πŸ‘‡The mocked data that will be used in the story +const TestData = { + user: { + userID: 1, + name: 'Someone', + }, + document: { + id: 1, + userID: 1, + title: 'Something', + brief: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.', + status: 'approved', + }, + subdocuments: [ + { + id: 1, + userID: 1, + title: 'Something', + content: + 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.', + status: 'approved', + }, + ], +}; + +export const MockedSuccess: Story = { + parameters: { + msw: [ + graphql.query('AllInfoQuery', (req, res, ctx) => { + return res(ctx.data(TestData)); + }), + ], + }, +}; + +export const MockedError: Story = { + parameters: { + msw: [ + graphql.query('AllInfoQuery', (req, res, ctx) => { + return res( + ctx.delay(800), + ctx.errors([ + { + message: 'Access denied', + }, + ]) + ); + }), + ], + }, +}; +``` diff --git a/docs/snippets/svelte/histogram-story.mdx.mdx b/docs/snippets/svelte/histogram-story.mdx.mdx deleted file mode 100644 index c17806227f8d..000000000000 --- a/docs/snippets/svelte/histogram-story.mdx.mdx +++ /dev/null @@ -1,30 +0,0 @@ -```md - - -import { Canvas, Meta, Story } from '@storybook/addon-docs'; - -import Histogram from './Histogram.svelte'; - - - - - - - ({ - Component: Histogram, - props: args, - })} /> - -``` \ No newline at end of file diff --git a/docs/snippets/svelte/loader-story.mdx.mdx b/docs/snippets/svelte/loader-story.mdx.mdx deleted file mode 100644 index d6cc1e15fb76..000000000000 --- a/docs/snippets/svelte/loader-story.mdx.mdx +++ /dev/null @@ -1,34 +0,0 @@ -```md - - -import { Meta, Story } from '@storybook/addon-docs'; - -import TodoItem from './TodoItem.svelte'; - -import fetch from 'node-fetch'; - - - - - - ({ - todo: await ( - await fetch('https://jsonplaceholder.typicode.com/todos/1') - ).json(), - }), - ]} - render={(args, { loaded: { todo } }) => ({ - Component: TodoItem, - props: { - ...args, - todo, - }, - })} /> -``` \ No newline at end of file diff --git a/docs/snippets/svelte/loader-story.ts-4-9.mdx b/docs/snippets/svelte/loader-story.ts-4-9.mdx new file mode 100644 index 000000000000..3a0c52903ec4 --- /dev/null +++ b/docs/snippets/svelte/loader-story.ts-4-9.mdx @@ -0,0 +1,36 @@ +```ts +// TodoItem.stories.ts + +import type { Meta, StoryObj } from '@storybook/svelte'; + +import fetch from 'node-fetch'; + +import TodoItem from './TodoItem.svelte'; + +/* + *πŸ‘‡ Render functions are a framework specific feature to allow you control on how the component renders. + * See https://storybook.js.org/docs/svelte/api/csf + * to learn how to use render functions. + */ +const meta = { + component: TodoItem, + render: (args, { loaded: { todo } }) => ({ + Component: TodoItem, + props: { + ...args, + ...todo, + }, + }), +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const Primary: Story = { + loaders: [ + async () => ({ + todo: await (await fetch('https://jsonplaceholder.typicode.com/todos/1')).json(), + }), + ], +}; +``` diff --git a/docs/snippets/svelte/loader-story.ts.mdx b/docs/snippets/svelte/loader-story.ts.mdx new file mode 100644 index 000000000000..5bea2892ef0c --- /dev/null +++ b/docs/snippets/svelte/loader-story.ts.mdx @@ -0,0 +1,36 @@ +```ts +// TodoItem.stories.ts + +import type { Meta, StoryObj } from '@storybook/svelte'; + +import fetch from 'node-fetch'; + +import TodoItem from './TodoItem.svelte'; + +/* + *πŸ‘‡ Render functions are a framework specific feature to allow you control on how the component renders. + * See https://storybook.js.org/docs/svelte/api/csf + * to learn how to use render functions. + */ +const meta: Meta = { + component: TodoItem, + render: (args, { loaded: { todo } }) => ({ + Component: TodoItem, + props: { + ...args, + ...todo, + }, + }), +}; + +export default meta; +type Story = StoryObj; + +export const Primary: Story = { + loaders: [ + async () => ({ + todo: await (await fetch('https://jsonplaceholder.typicode.com/todos/1')).json(), + }), + ], +}; +``` diff --git a/docs/snippets/svelte/login-form-with-play-function.js.mdx b/docs/snippets/svelte/login-form-with-play-function.js.mdx index c0fbce4a48fc..a73d16222c61 100644 --- a/docs/snippets/svelte/login-form-with-play-function.js.mdx +++ b/docs/snippets/svelte/login-form-with-play-function.js.mdx @@ -1,7 +1,8 @@ ```js // LoginForm.stories.js -import { userEvent, within, expect } from '@storybook/test'; +import { userEvent, within } from '@storybook/testing-library'; +import { expect } from '@storybook/jest'; import LoginForm from './LoginForm.svelte'; @@ -9,27 +10,13 @@ export default { component: LoginForm, }; -/* - *πŸ‘‡ Render functions are a framework specific feature to allow you control on how the component renders. - * See https://storybook.js.org/docs/api/csf - * to learn how to use render functions. - */ -export const EmptyForm = { - render: (args) => ({ - Component: LoginForm, - props: args, - }), -}; +export const EmptyForm = {}; /* * See https://storybook.js.org/docs/writing-stories/play-function#working-with-the-canvas * to learn more about using the canvasElement to query the DOM */ export const FilledForm = { - render: (args) => ({ - Component: LoginForm, - props: args, - }), play: async ({ canvasElement }) => { const canvas = within(canvasElement); diff --git a/docs/snippets/svelte/login-form-with-play-function.mdx.mdx b/docs/snippets/svelte/login-form-with-play-function.mdx.mdx deleted file mode 100644 index bc4fca63ad11..000000000000 --- a/docs/snippets/svelte/login-form-with-play-function.mdx.mdx +++ /dev/null @@ -1,53 +0,0 @@ -```md - - -import { Canvas, Meta, Story } from '@storybook/addon-docs'; - -import { within, userEvent } from '@storybook/testing-library'; - -import { expect } from '@storybook/jest'; - -import LoginForm from './LoginForm.svelte'; - - - - - - - ({ - Component: LoginForm, - props: args, - })} /> - ({ - Component: LoginForm, - props: args, - })} - play={ async ({ canvasElement }) => { - // Starts querying the component from its root element - const canvas = within(canvasElement); - - // πŸ‘‡ Simulate interactions - await userEvent.type(canvas.getByTestId('email'), 'email@provider.com'); - - await userEvent.type(canvas.getByTestId('password'), 'a-random-password'); - - // See https://storybook.js.org/docs/essentials/actions#automatically-matching-args to learn how to setup logging in the Actions panel - await userEvent.click(canvas.getByRole('button')); - - // πŸ‘‡ Assert DOM structure - await expect( - canvas.getByText( - 'Everything is perfect. Your account is ready and we should probably get you started!' - ) - ).toBeInTheDocument(); - }} /> - -``` \ No newline at end of file diff --git a/docs/snippets/svelte/login-form-with-play-function.ts-4-9.mdx b/docs/snippets/svelte/login-form-with-play-function.ts-4-9.mdx new file mode 100644 index 000000000000..6b4da3545731 --- /dev/null +++ b/docs/snippets/svelte/login-form-with-play-function.ts-4-9.mdx @@ -0,0 +1,43 @@ +```ts +// LoginForm.stories.ts + +import type { Meta, StoryObj } from '@storybook/svelte'; +import { userEvent, within } from '@storybook/testing-library'; +import { expect } from '@storybook/jest'; + +import LoginForm from './LoginForm.svelte'; + +const meta = { + component: LoginForm, +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const EmptyForm: Story = {}; + +/* + * See https://storybook.js.org/docs/writing-stories/play-function#working-with-the-canvas + * to learn more about using the canvasElement to query the DOM + */ +export const FilledForm: Story = { + play: async ({ canvasElement }) => { + const canvas = within(canvasElement); + + // πŸ‘‡ Simulate interactions with the component + await userEvent.type(canvas.getByTestId('email'), 'email@provider.com'); + + await userEvent.type(canvas.getByTestId('password'), 'a-random-password'); + + // See https://storybook.js.org/docs/essentials/actions#automatically-matching-args to learn how to setup logging in the Actions panel + await userEvent.click(canvas.getByRole('button')); + + // πŸ‘‡ Assert DOM structure + await expect( + canvas.getByText( + 'Everything is perfect. Your account is ready and we should probably get you started!' + ) + ).toBeInTheDocument(); + }, +}; +``` diff --git a/docs/snippets/svelte/login-form-with-play-function.ts.mdx b/docs/snippets/svelte/login-form-with-play-function.ts.mdx new file mode 100644 index 000000000000..c89d3591d6d8 --- /dev/null +++ b/docs/snippets/svelte/login-form-with-play-function.ts.mdx @@ -0,0 +1,43 @@ +```ts +// LoginForm.stories.ts + +import type { Meta, StoryObj } from '@storybook/svelte'; +import { userEvent, within } from '@storybook/testing-library'; +import { expect } from '@storybook/jest'; + +import LoginForm from './LoginForm.svelte'; + +const meta: Meta = { + component: LoginForm, +}; + +export default meta; +type Story = StoryObj; + +export const EmptyForm: Story = {}; + +/* + * See https://storybook.js.org/docs/writing-stories/play-function#working-with-the-canvas + * to learn more about using the canvasElement to query the DOM + */ +export const FilledForm: Story = { + play: async ({ canvasElement }) => { + const canvas = within(canvasElement); + + // πŸ‘‡ Simulate interactions with the component + await userEvent.type(canvas.getByTestId('email'), 'email@provider.com'); + + await userEvent.type(canvas.getByTestId('password'), 'a-random-password'); + + // See https://storybook.js.org/docs/essentials/actions#automatically-matching-args to learn how to setup logging in the Actions panel + await userEvent.click(canvas.getByRole('button')); + + // πŸ‘‡ Assert DOM structure + await expect( + canvas.getByText( + 'Everything is perfect. Your account is ready and we should probably get you started!' + ) + ).toBeInTheDocument(); + }, +}; +``` diff --git a/docs/snippets/svelte/margindecorator.with-margin-component.js.mdx b/docs/snippets/svelte/margindecorator.with-margin-component.js.mdx new file mode 100644 index 000000000000..c7a129062935 --- /dev/null +++ b/docs/snippets/svelte/margindecorator.with-margin-component.js.mdx @@ -0,0 +1,13 @@ +```html + + +
+ +
+ + +``` diff --git a/docs/snippets/svelte/margindecorator.with-margin-component.ts.mdx b/docs/snippets/svelte/margindecorator.with-margin-component.ts.mdx new file mode 100644 index 000000000000..c7a129062935 --- /dev/null +++ b/docs/snippets/svelte/margindecorator.with-margin-component.ts.mdx @@ -0,0 +1,13 @@ +```html + + +
+ +
+ + +``` diff --git a/docs/snippets/svelte/mdx-canvas-multiple-stories.mdx.mdx b/docs/snippets/svelte/mdx-canvas-multiple-stories.mdx.mdx deleted file mode 100644 index 09c2626f435f..000000000000 --- a/docs/snippets/svelte/mdx-canvas-multiple-stories.mdx.mdx +++ /dev/null @@ -1,48 +0,0 @@ -```md - - -import { Canvas, Meta, Story } from '@storybook/addon-docs'; - -import Badge from './Badge.svelte'; - - - - - - - ({ - Component: Badge, - props: args, - })} /> - ({ - Component: Badge, - props: args, - })} /> - ({ - Component: Badge, - props: args, - })} /> - -``` diff --git a/docs/snippets/svelte/my-component-story-basic-and-props.js.mdx b/docs/snippets/svelte/my-component-story-basic-and-props.js.mdx index baaf11c2767c..42e11888b759 100644 --- a/docs/snippets/svelte/my-component-story-basic-and-props.js.mdx +++ b/docs/snippets/svelte/my-component-story-basic-and-props.js.mdx @@ -7,12 +7,13 @@ export default { component: MyComponent, }; -export const Basic = { - render: () => ({ - Component: MyComponent, - }), -}; +export const Basic = {}; +/* + *πŸ‘‡ Render functions are a framework specific feature to allow you control on how the component renders. + * See https://storybook.js.org/docs/api/csf + * to learn how to use render functions. + */ export const WithProp = { render: () => ({ Component: MyComponent, diff --git a/docs/snippets/svelte/my-component-story-basic-and-props.ts-4-9.mdx b/docs/snippets/svelte/my-component-story-basic-and-props.ts-4-9.mdx new file mode 100644 index 000000000000..486fd96d1ceb --- /dev/null +++ b/docs/snippets/svelte/my-component-story-basic-and-props.ts-4-9.mdx @@ -0,0 +1,30 @@ +```ts +// MyComponent.stories.ts + +import type { Meta, StoryObj } from '@storybook/svelte'; + +import MyComponent from './MyComponent.svelte'; + +const meta = { + component: MyComponent, +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const Basic: Story = {}; + +/* + *πŸ‘‡ Render functions are a framework specific feature to allow you control on how the component renders. + * See https://storybook.js.org/docs/api/csf + * to learn how to use render functions. + */ +export const WithProp: Story = { + render: () => ({ + Component: MyComponent, + props: { + prop: 'value', + }, + }), +}; +``` diff --git a/docs/snippets/svelte/my-component-story-basic-and-props.ts.mdx b/docs/snippets/svelte/my-component-story-basic-and-props.ts.mdx new file mode 100644 index 000000000000..ad985f99262e --- /dev/null +++ b/docs/snippets/svelte/my-component-story-basic-and-props.ts.mdx @@ -0,0 +1,30 @@ +```ts +// MyComponent.stories.ts + +import type { Meta, StoryObj } from '@storybook/svelte'; + +import MyComponent from './MyComponent.svelte'; + +const meta: Meta = { + component: MyComponent, +}; + +export default meta; +type Story = StoryObj; + +export const Basic: Story = {}; + +/* + *πŸ‘‡ Render functions are a framework specific feature to allow you control on how the component renders. + * See https://storybook.js.org/docs/api/csf + * to learn how to use render functions. + */ +export const WithProp: Story = { + render: () => ({ + Component: MyComponent, + props: { + prop: 'value', + }, + }), +}; +``` diff --git a/docs/snippets/svelte/my-component-story-configure-viewports.js.mdx b/docs/snippets/svelte/my-component-story-configure-viewports.js.mdx index 075779bbb1bb..856aed93e83b 100644 --- a/docs/snippets/svelte/my-component-story-configure-viewports.js.mdx +++ b/docs/snippets/svelte/my-component-story-configure-viewports.js.mdx @@ -19,9 +19,6 @@ export default { }; export const MyStory = { - render: () => ({ - Component: MyComponent, - }), parameters: { viewport: { defaultViewport: 'iphonex', diff --git a/docs/snippets/svelte/my-component-story-configure-viewports.mdx.mdx b/docs/snippets/svelte/my-component-story-configure-viewports.mdx.mdx deleted file mode 100644 index b3b0ee79076e..000000000000 --- a/docs/snippets/svelte/my-component-story-configure-viewports.mdx.mdx +++ /dev/null @@ -1,37 +0,0 @@ -```md - - -import { Meta, Story } from '@storybook/addon-docs'; - -import { INITIAL_VIEWPORTS } from '@storybook/addon-viewport'; - -import MyComponent from './MyComponent.svelte'; - - - - - - ({ - Component: MyComponent, - props: {}, - })} /> -``` \ No newline at end of file diff --git a/docs/snippets/svelte/my-component-story-configure-viewports.ts-4-9.mdx b/docs/snippets/svelte/my-component-story-configure-viewports.ts-4-9.mdx new file mode 100644 index 000000000000..2395d688fb55 --- /dev/null +++ b/docs/snippets/svelte/my-component-story-configure-viewports.ts-4-9.mdx @@ -0,0 +1,32 @@ +```ts +// MyComponent.stories.ts + +import type { Meta, StoryObj } from '@storybook/svelte'; +import { INITIAL_VIEWPORTS } from '@storybook/addon-viewport'; + +import MyComponent from './MyComponent.svelte'; + +const meta = { + component: MyComponent, + parameters: { + //πŸ‘‡ The viewports object from the Essentials addon + viewport: { + //πŸ‘‡ The viewports you want to use + viewports: INITIAL_VIEWPORTS, + //πŸ‘‡ Your own default viewport + defaultViewport: 'iphone6', + }, + }, +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const MyStory: Story = { + parameters: { + viewport: { + defaultViewport: 'iphonex', + }, + }, +}; +``` diff --git a/docs/snippets/svelte/my-component-story-configure-viewports.ts.mdx b/docs/snippets/svelte/my-component-story-configure-viewports.ts.mdx new file mode 100644 index 000000000000..93ab5bcf7ae0 --- /dev/null +++ b/docs/snippets/svelte/my-component-story-configure-viewports.ts.mdx @@ -0,0 +1,32 @@ +```ts +// MyComponent.stories.ts + +import type { Meta, StoryObj } from '@storybook/svelte'; +import { INITIAL_VIEWPORTS } from '@storybook/addon-viewport'; + +import MyComponent from './MyComponent.svelte'; + +const meta: Meta = { + component: MyComponent, + parameters: { + //πŸ‘‡ The viewports object from the Essentials addon + viewport: { + //πŸ‘‡ The viewports you want to use + viewports: INITIAL_VIEWPORTS, + //πŸ‘‡ Your own default viewport + defaultViewport: 'iphone6', + }, + }, +}; + +export default meta; +type Story = StoryObj; + +export const MyStory: Story = { + parameters: { + viewport: { + defaultViewport: 'iphonex', + }, + }, +}; +``` diff --git a/docs/snippets/svelte/my-component-story-use-globaltype-backwards-compat.js.mdx b/docs/snippets/svelte/my-component-story-use-globaltype-backwards-compat.js.mdx index 8ee73b34422d..c25aa876eb7d 100644 --- a/docs/snippets/svelte/my-component-story-use-globaltype-backwards-compat.js.mdx +++ b/docs/snippets/svelte/my-component-story-use-globaltype-backwards-compat.js.mdx @@ -4,7 +4,7 @@ export const StoryWithLocale = ({ globals: { locale } }) => { const caption = getCaptionForLocale(locale); return { - component: MyComponent, + Component: MyComponent, props: { locale: caption, }, diff --git a/docs/snippets/svelte/my-component-story-use-globaltype-backwards-compat.ts-4-9.mdx b/docs/snippets/svelte/my-component-story-use-globaltype-backwards-compat.ts-4-9.mdx new file mode 100644 index 000000000000..f48fa95463e0 --- /dev/null +++ b/docs/snippets/svelte/my-component-story-use-globaltype-backwards-compat.ts-4-9.mdx @@ -0,0 +1,13 @@ +```ts +// MyComponent.stories.ts + +export const StoryWithLocale: Story = ({ globals: { locale } }) => { + const caption = getCaptionForLocale(locale); + return { + Component: MyComponent, + props: { + locale: caption, + }, + }; +}; +``` diff --git a/docs/snippets/svelte/my-component-story-use-globaltype-backwards-compat.ts.mdx b/docs/snippets/svelte/my-component-story-use-globaltype-backwards-compat.ts.mdx new file mode 100644 index 000000000000..f48fa95463e0 --- /dev/null +++ b/docs/snippets/svelte/my-component-story-use-globaltype-backwards-compat.ts.mdx @@ -0,0 +1,13 @@ +```ts +// MyComponent.stories.ts + +export const StoryWithLocale: Story = ({ globals: { locale } }) => { + const caption = getCaptionForLocale(locale); + return { + Component: MyComponent, + props: { + locale: caption, + }, + }; +}; +``` diff --git a/docs/snippets/svelte/my-component-story-use-globaltype.js.mdx b/docs/snippets/svelte/my-component-story-use-globaltype.js.mdx index 176e9cae2381..8542b37240a7 100644 --- a/docs/snippets/svelte/my-component-story-use-globaltype.js.mdx +++ b/docs/snippets/svelte/my-component-story-use-globaltype.js.mdx @@ -26,7 +26,7 @@ export const StoryWithLocale = { render: (args, { globals: { locale } }) => { const caption = getCaptionForLocale(locale); return { - component: MyComponent, + Component: MyComponent, props: { locale: caption, }, diff --git a/docs/snippets/svelte/my-component-story-use-globaltype.mdx.mdx b/docs/snippets/svelte/my-component-story-use-globaltype.mdx.mdx deleted file mode 100644 index 56de0d43fdc5..000000000000 --- a/docs/snippets/svelte/my-component-story-use-globaltype.mdx.mdx +++ /dev/null @@ -1,38 +0,0 @@ -```md - - -import { Meta, Story } from '@storybook/addon-docs'; - -import MyComponent from './MyComponent.svelte'; - - - -export const getCaptionForLocale = (locale) => { - switch(locale) { - case 'es': return 'Hola!'; - case 'fr': return 'Bonjour!'; - case 'kr': return 'μ•ˆλ…•ν•˜μ„Έμš”!'; - case 'zh': return 'δ½ ε₯½!'; - default: - return 'Hello!'; - } -}; - - - - { - const caption = getCaptionForLocale(locale); - return { - component: MyComponent, - props: { - locale: caption, - }, - }; - }} /> -``` \ No newline at end of file diff --git a/docs/snippets/svelte/my-component-story-use-globaltype.ts-4-9.mdx b/docs/snippets/svelte/my-component-story-use-globaltype.ts-4-9.mdx new file mode 100644 index 000000000000..59e0feecc847 --- /dev/null +++ b/docs/snippets/svelte/my-component-story-use-globaltype.ts-4-9.mdx @@ -0,0 +1,41 @@ +```ts +// MyComponent.stories.ts + +import type { Meta, StoryObj } from '@storybook/svelte'; + +import MyComponent from './YourComponent.svelte'; + +const meta = { + component: MyComponent, +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +const getCaptionForLocale = (locale) => { + switch (locale) { + case 'es': + return 'Hola!'; + case 'fr': + return 'Bonjour!'; + case 'kr': + return 'μ•ˆλ…•ν•˜μ„Έμš”!'; + case 'zh': + return 'δ½ ε₯½!'; + default: + return 'Hello!'; + } +}; + +export const StoryWithLocale: Story = { + render: (args, { globals: { locale } }) => { + const caption = getCaptionForLocale(locale); + return { + Component: MyComponent, + props: { + locale: caption, + }, + }; + }, +}; +``` diff --git a/docs/snippets/svelte/my-component-story-use-globaltype.ts.mdx b/docs/snippets/svelte/my-component-story-use-globaltype.ts.mdx new file mode 100644 index 000000000000..88847d3d9011 --- /dev/null +++ b/docs/snippets/svelte/my-component-story-use-globaltype.ts.mdx @@ -0,0 +1,41 @@ +```ts +// MyComponent.stories.ts + +import type { Meta, StoryObj } from '@storybook/svelte'; + +import MyComponent from './YourComponent.svelte'; + +const meta: Meta = { + component: MyComponent, +}; + +export default meta; +type Story = StoryObj; + +const getCaptionForLocale = (locale) => { + switch (locale) { + case 'es': + return 'Hola!'; + case 'fr': + return 'Bonjour!'; + case 'kr': + return 'μ•ˆλ…•ν•˜μ„Έμš”!'; + case 'zh': + return 'δ½ ε₯½!'; + default: + return 'Hello!'; + } +}; + +export const StoryWithLocale: Story = { + render: (args, { globals: { locale } }) => { + const caption = getCaptionForLocale(locale); + return { + Component: MyComponent, + props: { + locale: caption, + }, + }; + }, +}; +``` diff --git a/docs/snippets/svelte/my-component-story-with-nonstory.js.mdx b/docs/snippets/svelte/my-component-story-with-nonstory.js.mdx index a1d49428d9fa..0ca9319f8737 100644 --- a/docs/snippets/svelte/my-component-story-with-nonstory.js.mdx +++ b/docs/snippets/svelte/my-component-story-with-nonstory.js.mdx @@ -15,20 +15,12 @@ export const simpleData = { foo: 1, bar: 'baz' }; export const complexData = { foo: 1, foobar: { bar: 'baz', baz: someData } }; export const SimpleStory = { - render: (args) => ({ - Component: MyComponent, - props: args, - }), args: { data: simpleData, }, }; export const ComplexStory = { - render: (args) => ({ - Component: MyComponent, - props: args, - }), args: { data: complexData, }, diff --git a/docs/snippets/svelte/my-component-story-with-nonstory.ts-4-9.mdx b/docs/snippets/svelte/my-component-story-with-nonstory.ts-4-9.mdx new file mode 100644 index 000000000000..9bf8759217e1 --- /dev/null +++ b/docs/snippets/svelte/my-component-story-with-nonstory.ts-4-9.mdx @@ -0,0 +1,33 @@ +```ts +// MyComponent.stories.ts + +import type { Meta, StoryObj } from '@storybook/svelte'; + +import MyComponent from './MyComponent.svelte'; + +import someData from './data.json'; + +const meta = { + component: MyComponent, + includeStories: ['SimpleStory', 'ComplexStory'], // πŸ‘ˆ Storybook loads these stories + excludeStories: /.*Data$/, // πŸ‘ˆ Storybook ignores anything that contains Data +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const simpleData = { foo: 1, bar: 'baz' }; +export const complexData = { foo: 1, foobar: { bar: 'baz', baz: someData } }; + +export const SimpleStory: Story = { + args: { + data: simpleData, + }, +}; + +export const ComplexStory: Story = { + args: { + data: complexData, + }, +}; +``` diff --git a/docs/snippets/svelte/my-component-story-with-nonstory.ts.mdx b/docs/snippets/svelte/my-component-story-with-nonstory.ts.mdx new file mode 100644 index 000000000000..97c183896eb9 --- /dev/null +++ b/docs/snippets/svelte/my-component-story-with-nonstory.ts.mdx @@ -0,0 +1,33 @@ +```ts +// MyComponent.stories.ts + +import type { Meta, StoryObj } from '@storybook/svelte'; + +import MyComponent from './MyComponent.svelte'; + +import someData from './data.json'; + +const meta: Meta = { + component: MyComponent, + includeStories: ['SimpleStory', 'ComplexStory'], // πŸ‘ˆ Storybook loads these stories + excludeStories: /.*Data$/, // πŸ‘ˆ Storybook ignores anything that contains Data +}; + +export default meta; +type Story = StoryObj; + +export const simpleData = { foo: 1, bar: 'baz' }; +export const complexData = { foo: 1, foobar: { bar: 'baz', baz: someData } }; + +export const SimpleStory: Story = { + args: { + data: simpleData, + }, +}; + +export const ComplexStory: Story = { + args: { + data: complexData, + }, +}; +``` diff --git a/docs/snippets/svelte/my-component-with-env-variables.mdx.mdx b/docs/snippets/svelte/my-component-with-env-variables.mdx.mdx deleted file mode 100644 index 75d7cbe6b30a..000000000000 --- a/docs/snippets/svelte/my-component-with-env-variables.mdx.mdx +++ /dev/null @@ -1,27 +0,0 @@ -```md - - -import { Canvas, Meta, Story } from '@storybook/addon-docs'; - -import MyComponent from './MyComponent.svelte'; - - - - - - - ({ - Component: MyComponent, - props: args, - })} /> - -``` \ No newline at end of file diff --git a/docs/snippets/svelte/page-story.js.mdx b/docs/snippets/svelte/page-story.js.mdx index 287abf710838..ec72dc32448c 100644 --- a/docs/snippets/svelte/page-story.js.mdx +++ b/docs/snippets/svelte/page-story.js.mdx @@ -10,16 +10,7 @@ export default { component: Page, }; -/* - *πŸ‘‡ Render functions are a framework specific feature to allow you control on how the component renders. - * See https://storybook.js.org/docs/api/csf - * to learn how to use render functions. - */ export const LoggedIn = { - render: (args) => ({ - Component: Page, - props: args, - }), args: { ...HeaderStories.LoggedIn.args, }, diff --git a/docs/snippets/svelte/page-story.ts-4-9.mdx b/docs/snippets/svelte/page-story.ts-4-9.mdx new file mode 100644 index 000000000000..7184cc7ce31f --- /dev/null +++ b/docs/snippets/svelte/page-story.ts-4-9.mdx @@ -0,0 +1,23 @@ +```ts +// Page.stories.ts + +import type { Meta, StoryObj } from '@storybook/svelte'; + +import Page from './Page.svelte'; + +//πŸ‘‡ Imports all Header stories +import * as HeaderStories from './Header.stories'; + +const meta = { + component: Page, +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const LoggedIn: Story = { + args: { + ...HeaderStories.LoggedIn.args, + }, +}; +``` diff --git a/docs/snippets/svelte/page-story.ts.mdx b/docs/snippets/svelte/page-story.ts.mdx new file mode 100644 index 000000000000..897a7f6db039 --- /dev/null +++ b/docs/snippets/svelte/page-story.ts.mdx @@ -0,0 +1,23 @@ +```ts +// Page.stories.ts + +import type { Meta, StoryObj } from '@storybook/svelte'; + +import Page from './Page.svelte'; + +//πŸ‘‡ Imports all Header stories +import * as HeaderStories from './Header.stories'; + +const meta: Meta = { + component: Page, +}; + +export default meta; +type Story = StoryObj; + +export const LoggedIn: Story = { + args: { + ...HeaderStories.LoggedIn.args, + }, +}; +``` diff --git a/docs/snippets/svelte/simple-page-implementation.ts.mdx b/docs/snippets/svelte/simple-page-implementation.ts.mdx new file mode 100644 index 000000000000..95fb6c5b988a --- /dev/null +++ b/docs/snippets/svelte/simple-page-implementation.ts.mdx @@ -0,0 +1,20 @@ +```html + + + + +
+ + + + +
+``` diff --git a/docs/snippets/svelte/storybook-addon-a11y-disable.js.mdx b/docs/snippets/svelte/storybook-addon-a11y-disable.js.mdx index 448436303a53..7ddea5b9cef4 100644 --- a/docs/snippets/svelte/storybook-addon-a11y-disable.js.mdx +++ b/docs/snippets/svelte/storybook-addon-a11y-disable.js.mdx @@ -8,10 +8,6 @@ export default { }; export const NonA11yStory = { - render: (args) => ({ - Component: MyComponent, - props: args, - }), parameters: { a11y: { // This option disables all a11y checks on this story diff --git a/docs/snippets/svelte/storybook-addon-a11y-disable.mdx.mdx b/docs/snippets/svelte/storybook-addon-a11y-disable.mdx.mdx deleted file mode 100644 index c2e5d4ff3ee5..000000000000 --- a/docs/snippets/svelte/storybook-addon-a11y-disable.mdx.mdx +++ /dev/null @@ -1,30 +0,0 @@ -```md - - -import { Meta, Story } from '@storybook/addon-docs'; - -import MyComponent from './MyComponent.svelte'; - - - - - - ({ - Component: MyComponent, - props: {}, - })} /> -``` \ No newline at end of file diff --git a/docs/snippets/svelte/storybook-addon-a11y-disable.ts-4-9.mdx b/docs/snippets/svelte/storybook-addon-a11y-disable.ts-4-9.mdx new file mode 100644 index 000000000000..a88af48d41e6 --- /dev/null +++ b/docs/snippets/svelte/storybook-addon-a11y-disable.ts-4-9.mdx @@ -0,0 +1,23 @@ +```ts +// MyComponent.stories.ts + +import type { Meta, StoryObj } from '@storybook/svelte'; + +import MyComponent from './MyComponent.svelte'; + +const meta = { + component: MyComponent, +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const NonA11yStory: Story = { + parameters: { + a11y: { + // This option disables all a11y checks on this story + disable: true, + }, + }, +}; +``` diff --git a/docs/snippets/svelte/storybook-addon-a11y-disable.ts.mdx b/docs/snippets/svelte/storybook-addon-a11y-disable.ts.mdx new file mode 100644 index 000000000000..d9b1abb6a04e --- /dev/null +++ b/docs/snippets/svelte/storybook-addon-a11y-disable.ts.mdx @@ -0,0 +1,23 @@ +```ts +// MyComponent.stories.ts + +import type { Meta, StoryObj } from '@storybook/svelte'; + +import MyComponent from './MyComponent.svelte'; + +const meta: Meta = { + component: MyComponent, +}; + +export default meta; +type Story = StoryObj; + +export const NonA11yStory: Story = { + parameters: { + a11y: { + // This option disables all a11y checks on this story + disable: true, + }, + }, +}; +``` diff --git a/docs/snippets/svelte/storybook-addon-a11y-story-config.js.mdx b/docs/snippets/svelte/storybook-addon-a11y-story-config.js.mdx index 65635998e178..d26c9049ae24 100644 --- a/docs/snippets/svelte/storybook-addon-a11y-story-config.js.mdx +++ b/docs/snippets/svelte/storybook-addon-a11y-story-config.js.mdx @@ -8,10 +8,6 @@ export default { }; export const ExampleStory = { - render: (args) => ({ - Component: MyComponent, - props: args, - }), parameters: { a11y: { element: '#storybook-root', diff --git a/docs/snippets/svelte/storybook-addon-a11y-story-config.mdx.mdx b/docs/snippets/svelte/storybook-addon-a11y-story-config.ts-4-9.mdx similarity index 55% rename from docs/snippets/svelte/storybook-addon-a11y-story-config.mdx.mdx rename to docs/snippets/svelte/storybook-addon-a11y-story-config.ts-4-9.mdx index 503c7230d71f..405228dd4df8 100644 --- a/docs/snippets/svelte/storybook-addon-a11y-story-config.mdx.mdx +++ b/docs/snippets/svelte/storybook-addon-a11y-story-config.ts-4-9.mdx @@ -1,23 +1,19 @@ -```md - +```ts +// MyComponent.stories.ts -import { Meta, Story } from '@storybook/addon-docs'; +import type { Meta, StoryObj } from '@storybook/svelte'; import MyComponent from './MyComponent.svelte'; - +const meta = { + component: MyComponent, +} satisfies Meta; - +export default meta; +type Story = StoryObj; - ({ - Component: MyComponent, - props: {}, - })} /> -``` \ No newline at end of file + }, +}; +``` diff --git a/docs/snippets/svelte/storybook-addon-a11y-story-config.ts.mdx b/docs/snippets/svelte/storybook-addon-a11y-story-config.ts.mdx new file mode 100644 index 000000000000..a2516ffa6464 --- /dev/null +++ b/docs/snippets/svelte/storybook-addon-a11y-story-config.ts.mdx @@ -0,0 +1,38 @@ +```ts +// MyComponent.stories.ts + +import type { Meta, StoryObj } from '@storybook/svelte'; + +import MyComponent from './MyComponent.svelte'; + +const meta: Meta = { + component: MyComponent, +}; + +export default meta; +type Story = StoryObj; + +export const ExampleStory: Story = { + parameters: { + a11y: { + element: '#storybook-root', + config: { + rules: [ + { + // The autocomplete rule will not run based on the CSS selector provided + id: 'autocomplete-valid', + selector: '*:not([autocomplete="nope"])', + }, + { + // Setting the enabled option to false will disable checks for this particular rule on all stories. + id: 'image-alt', + enabled: false, + }, + ], + }, + options: {}, + manual: true, + }, + }, +}; +``` diff --git a/docs/snippets/svelte/storybook-preview-global-decorator.ts.mdx b/docs/snippets/svelte/storybook-preview-global-decorator.ts.mdx new file mode 100644 index 000000000000..9e6cf557f9c3 --- /dev/null +++ b/docs/snippets/svelte/storybook-preview-global-decorator.ts.mdx @@ -0,0 +1,13 @@ +```ts +// .storybook/preview.ts + +import type { Preview } from '@storybook/svelte'; + +import MarginDecorator from './MarginDecorator.svelte'; + +const preview: Preview = { + decorators: [() => MarginDecorator], +}; + +export default preview; +``` diff --git a/docs/snippets/svelte/your-component-with-decorator.js.mdx b/docs/snippets/svelte/your-component-with-decorator.js.mdx index a5dfce20e711..c9d943052349 100644 --- a/docs/snippets/svelte/your-component-with-decorator.js.mdx +++ b/docs/snippets/svelte/your-component-with-decorator.js.mdx @@ -9,21 +9,4 @@ export default { component: YourComponent, decorators: [() => MarginDecorator], }; - -// Your templates and stories here. -// Don't forget to use the component you're testing and not the MarginDecorator component -``` - -```html - - -
- -
- - ``` diff --git a/docs/snippets/svelte/your-component-with-decorator.mdx.mdx b/docs/snippets/svelte/your-component-with-decorator.mdx.mdx deleted file mode 100644 index 8cc0313e5d30..000000000000 --- a/docs/snippets/svelte/your-component-with-decorator.mdx.mdx +++ /dev/null @@ -1,13 +0,0 @@ -```md - - -import { Meta } from '@storybook/addon-docs'; - -import YourComponent from './YourComponent.svelte'; -import MarginDecorator from './MarginDecorator.svelte'; - - MarginDecorator]}/> -``` \ No newline at end of file diff --git a/docs/snippets/svelte/your-component-with-decorator.ts-4-9.mdx b/docs/snippets/svelte/your-component-with-decorator.ts-4-9.mdx new file mode 100644 index 000000000000..b840eb852abe --- /dev/null +++ b/docs/snippets/svelte/your-component-with-decorator.ts-4-9.mdx @@ -0,0 +1,15 @@ +```ts +// YourComponent.stories.ts + +import type { Meta } from '@storybook/svelte'; + +import YourComponent from './YourComponent.svelte'; +import MarginDecorator from './MarginDecorator.svelte'; + +const meta = { + component: Button, + decorators: [() => MarginDecorator], +} satisfies Meta; + +export default meta; +``` diff --git a/docs/snippets/svelte/your-component-with-decorator.ts.mdx b/docs/snippets/svelte/your-component-with-decorator.ts.mdx new file mode 100644 index 000000000000..d7698d42c35d --- /dev/null +++ b/docs/snippets/svelte/your-component-with-decorator.ts.mdx @@ -0,0 +1,15 @@ +```ts +// YourComponent.stories.ts + +import type { Meta } from '@storybook/svelte'; + +import YourComponent from './YourComponent.svelte'; +import MarginDecorator from './MarginDecorator.svelte'; + +const meta: Meta = { + component: YourComponent, + decorators: [() => MarginDecorator], +}; + +export default meta; +``` diff --git a/docs/snippets/svelte/your-component.mdx.mdx b/docs/snippets/svelte/your-component.mdx.mdx deleted file mode 100644 index 8f63ceffc626..000000000000 --- a/docs/snippets/svelte/your-component.mdx.mdx +++ /dev/null @@ -1,20 +0,0 @@ -```md - - -import { Meta, Story } from '@storybook/addon-docs'; - -import YourComponent from './YourComponent.svelte'; - - - - - - - ({ - component: YourComponent, - props: args, - })} /> -``` \ No newline at end of file diff --git a/docs/versions/next.json b/docs/versions/next.json index fae3915b5229..fa9aa8ce29c5 100644 --- a/docs/versions/next.json +++ b/docs/versions/next.json @@ -1 +1 @@ -{"version":"8.0.0-alpha.1","info":{"plain":"- Angular: Drop v14.x support - [#25101](https://github.com/storybookjs/storybook/pull/25101), thanks [@valentinpalkovic](https://github.com/valentinpalkovic)!\n- Angular: Fix CSF Plugin - [#25098](https://github.com/storybookjs/storybook/pull/25098), thanks [@valentinpalkovic](https://github.com/valentinpalkovic)!\n- Build: Fix Angular sandbox - [#23896](https://github.com/storybookjs/storybook/pull/23896), thanks [@Marklb](https://github.com/Marklb)!\n- CLI: Improve dependency metadata detection in storybook doctor - [#25037](https://github.com/storybookjs/storybook/pull/25037), thanks [@yannbf](https://github.com/yannbf)!\n- CLI: Point the update-notice to the changelog in the suggested version - [#19911](https://github.com/storybookjs/storybook/pull/19911), thanks [@cprecioso](https://github.com/cprecioso)!\n- CLI: Typescript strict mode - [#22254](https://github.com/storybookjs/storybook/pull/22254), thanks [@0916dhkim](https://github.com/0916dhkim)!\n- CSF: Autotitle fix multiple dots and handle stories.js - [#21840](https://github.com/storybookjs/storybook/pull/21840), thanks [@agriffis](https://github.com/agriffis)!\n- Next.js: Add next/font/local declarations support - [#24983](https://github.com/storybookjs/storybook/pull/24983), thanks [@MauricioRobayo](https://github.com/MauricioRobayo)!\n- Next.js: Drop Next.js < v13.5 support - [#25104](https://github.com/storybookjs/storybook/pull/25104), thanks [@valentinpalkovic](https://github.com/valentinpalkovic)!\n- Next.js: Fix AppRouterProvider usage - [#25032](https://github.com/storybookjs/storybook/pull/25032), thanks [@valentinpalkovic](https://github.com/valentinpalkovic)!\n- Next.js: Fix next/font/local usage in babel mode - [#25045](https://github.com/storybookjs/storybook/pull/25045), thanks [@valentinpalkovic](https://github.com/valentinpalkovic)!\n- Next.js: Update validateData function for next/font compatibility - [#25061](https://github.com/storybookjs/storybook/pull/25061), thanks [@kkirby](https://github.com/kkirby)!\n- NextJS: Add experimental RSC support - [#25091](https://github.com/storybookjs/storybook/pull/25091), thanks [@shilman](https://github.com/shilman)!\n- React-Docgen: Make error-handling more gentle - [#25055](https://github.com/storybookjs/storybook/pull/25055), thanks [@valentinpalkovic](https://github.com/valentinpalkovic)!\n- React: Change `StoryFnReactReturnType` to `JSX.Element` - [#23204](https://github.com/storybookjs/storybook/pull/23204), thanks [@chakAs3](https://github.com/chakAs3)!\n- React: Set `react-docgen` to default TS docgen - [#24165](https://github.com/storybookjs/storybook/pull/24165), thanks [@shilman](https://github.com/shilman)!\n- SvelteKit: Fix HMR not working - [#25031](https://github.com/storybookjs/storybook/pull/25031), thanks [@JReinhold](https://github.com/JReinhold)!\n- TypeScript: Migrate `@storybook/docs-tools` to strict TS - [#22567](https://github.com/storybookjs/storybook/pull/22567), thanks [@efrenaragon96](https://github.com/efrenaragon96)!\n- UI: Add stricter types to the language property of the SyntaxHighlighter - [#22790](https://github.com/storybookjs/storybook/pull/22790), thanks [@valentinpalkovic](https://github.com/valentinpalkovic)!\n- Viewport: Fix viewport dts files - [#25107](https://github.com/storybookjs/storybook/pull/25107), thanks [@kasperpeulen](https://github.com/kasperpeulen)!\n- Webpack: Fix exclude regex in react-docgen-loader - [#25030](https://github.com/storybookjs/storybook/pull/25030), thanks [@valentinpalkovic](https://github.com/valentinpalkovic)!"}} +{"version":"8.0.0-alpha.2","info":{"plain":"- Core: Maintenance changes for NextJS embedding - [#25086](https://github.com/storybookjs/storybook/pull/25086), thanks [@shilman](https://github.com/shilman)!\n- Docs: Use encodeURIComponent to encode story name - [#25062](https://github.com/storybookjs/storybook/pull/25062), thanks [@xyy94813](https://github.com/xyy94813)!\n- Init: Allow users to generate a new project in empty directory - [#24997](https://github.com/storybookjs/storybook/pull/24997), thanks [@Integrayshaun](https://github.com/Integrayshaun)!\n- Svelte: Support v5 prereleases - [#24889](https://github.com/storybookjs/storybook/pull/24889), thanks [@allozaur](https://github.com/allozaur)!\n- Vue: Remove deprecated vue packages from next - [#25108](https://github.com/storybookjs/storybook/pull/25108), thanks [@kasperpeulen](https://github.com/kasperpeulen)!\n- Vue: Remove unused preset-vue-webpack - [#25151](https://github.com/storybookjs/storybook/pull/25151), thanks [@shilman](https://github.com/shilman)!"}} diff --git a/docs/writing-docs/autodocs.md b/docs/writing-docs/autodocs.md index 61026e2d981b..96c42c8ba831 100644 --- a/docs/writing-docs/autodocs.md +++ b/docs/writing-docs/autodocs.md @@ -20,6 +20,7 @@ To enable auto-generated documentation for your stories, you'll need to add the 'vue/button-story-auto-docs.ts.mdx', 'angular/button-story-auto-docs.ts.mdx', 'svelte/button-story-auto-docs.js.mdx', + 'svelte/button-story-auto-docs.ts.mdx', 'web-components/button-story-auto-docs.js.mdx', 'web-components/button-story-auto-docs.ts.mdx', ]} diff --git a/docs/writing-stories/args.md b/docs/writing-stories/args.md index c4595f31c783..5a3d7cbd14a6 100644 --- a/docs/writing-stories/args.md +++ b/docs/writing-stories/args.md @@ -32,6 +32,7 @@ To define the args of a single story, use the `args` CSF story key: 'web-components/button-story-with-args.js.mdx', 'web-components/button-story-with-args.ts.mdx', 'svelte/button-story-with-args.js.mdx', + 'svelte/button-story-with-args.ts.mdx', 'html/button-story-with-args.ts.mdx', 'html/button-story-with-args.js.mdx', 'solid/button-story-with-args.js.mdx', @@ -80,6 +81,7 @@ You can also define args at the component level; they will apply to all the comp 'web-components/button-story-component-args-primary.js.mdx', 'web-components/button-story-component-args-primary.ts.mdx', 'svelte/button-story-component-args-primary.js.mdx', + 'svelte/button-story-component-args-primary.ts.mdx', 'solid/button-story-component-args-primary.js.mdx', 'solid/button-story-component-args-primary.ts.mdx', ]} @@ -152,6 +154,7 @@ Args are useful when writing stories for composite components that are assembled 'web-components/page-story.js.mdx', 'web-components/page-story.ts.mdx', 'svelte/page-story.js.mdx', + 'svelte/page-story.ts.mdx', 'solid/page-story.js.mdx', 'solid/page-story.ts.mdx', ]} @@ -161,6 +164,10 @@ Args are useful when writing stories for composite components that are assembled + + + + ## Args can modify any aspect of your component You can use args in your stories to configure the component's appearance, similar to what you would do in an application. For example, here's how you could use a `footer` arg to populate a child component: @@ -187,6 +194,8 @@ You can use args in your stories to configure the component's appearance, simila + + ## Setting args through the URL You can also override the set of initial args for the active story by adding an `args` query parameter to the URL. Typically you would use the [Controls addon](../essentials/controls.md) to handle this. For example, here's how you could set a `size` and `style` arg in the Storybook's URL: diff --git a/docs/writing-stories/build-pages-with-storybook.md b/docs/writing-stories/build-pages-with-storybook.md index d8c1b8f5b3b7..fecddea8921a 100644 --- a/docs/writing-stories/build-pages-with-storybook.md +++ b/docs/writing-stories/build-pages-with-storybook.md @@ -44,6 +44,7 @@ When you are building screens in this way, it is typical that the inputs of a co 'web-components/simple-page-implementation.js.mdx', 'web-components/simple-page-implementation.ts.mdx', 'svelte/simple-page-implementation.js.mdx', + 'svelte/simple-page-implementation.ts.mdx', 'solid/simple-page-implementation.js.mdx', 'solid/simple-page-implementation.ts.mdx', ]} @@ -146,6 +147,7 @@ If you're working with pure presentational screens, adding stories through [args 'vue/document-screen-fetch.3.ts.mdx', 'angular/document-screen-fetch.ts.mdx', 'svelte/document-screen-fetch.js.mdx', + 'svelte/document-screen-fetch.ts.mdx', 'web-components/document-screen-fetch.js.mdx', 'solid/document-screen-fetch.js.mdx', ]} @@ -193,6 +195,7 @@ In addition to mocking RESTful requests, the other noteworthy feature of the [MS 'vue/document-screen-with-graphql.3.ts.mdx', 'angular/document-screen-with-graphql.ts.mdx', 'svelte/document-screen-with-grapqhl.js.mdx', + 'svelte/document-screen-with-grapqhl.ts.mdx', ]} /> @@ -212,7 +215,9 @@ To test your screen with the GraphQL mocked data, you could write the following 'angular/apollo-module.mock-apollo-module.ts.mdx', 'angular/documentscreen-story-msw-graphql-query.ts.mdx', 'svelte/documentscreen-story-msw-graphql-query.js.mdx', + 'svelte/documentscreen-story-msw-graphql-query.ts.mdx', 'svelte/apollo-wrapper-component.with-mock-implementation.js.mdx', + 'svelte/apollo-wrapper-component.with-mock-implementation.ts.mdx', ]} usesCsf3 csf2Path="writing-stories/build-pages-with-storybook#snippet-documentscreen-story-msw-graphql-query" diff --git a/docs/writing-stories/decorators.md b/docs/writing-stories/decorators.md index f6c5305877cd..3f213ca28058 100644 --- a/docs/writing-stories/decorators.md +++ b/docs/writing-stories/decorators.md @@ -26,6 +26,9 @@ Some components require a β€œharness” to render in a useful way. For instance, 'web-components/your-component-with-decorator.js.mdx', 'web-components/your-component-with-decorator.ts.mdx', 'svelte/your-component-with-decorator.js.mdx', + 'svelte/your-component-with-decorator.ts.mdx', + 'svelte/margindecorator.with-margin-component.js.mdx', + 'svelte/margindecorator.with-margin-component.ts.mdx', 'solid/your-component-with-decorator.js.mdx', 'solid/your-component-with-decorator.ts.mdx' ]} @@ -103,6 +106,9 @@ To define a decorator for a single story, use the `decorators` key on a named ex 'web-components/button-story-decorator.js.mdx', 'web-components/button-story-decorator.ts.mdx', 'svelte/button-story-decorator.js.mdx', + 'svelte/button-story-decorator.ts.mdx', + 'svelte/margindecorator.with-margin-component.js.mdx', + 'svelte/margindecorator.with-margin-component.ts.mdx', 'solid/button-story-decorator.js.mdx', 'solid/button-story-decorator.ts.mdx', ]} @@ -131,6 +137,9 @@ To define a decorator for all stories of a component, use the `decorators` key o 'web-components/button-story-component-decorator.js.mdx', 'web-components/button-story-component-decorator.ts.mdx', 'svelte/button-story-component-decorator.js.mdx', + 'svelte/button-story-component-decorator.ts.mdx', + 'svelte/margindecorator.with-margin-component.js.mdx', + 'svelte/margindecorator.with-margin-component.ts.mdx', 'solid/button-story-component-decorator.js.mdx', 'solid/button-story-component-decorator.ts.mdx', ]} @@ -153,6 +162,9 @@ We can also set a decorator for **all stories** via the `decorators` export of y 'angular/storybook-preview-global-decorator.ts.mdx', 'web-components/storybook-preview-global-decorator.js.mdx', 'svelte/storybook-preview-global-decorator.js.mdx', + 'svelte/storybook-preview-global-decorator.ts.mdx', + 'svelte/margindecorator.with-margin-component.js.mdx', + 'svelte/margindecorator.with-margin-component.ts.mdx', 'solid/storybook-preview-global-decorator.js.mdx', 'solid/storybook-preview-global-decorator.ts.mdx', ]} diff --git a/docs/writing-stories/index.md b/docs/writing-stories/index.md index e7dab69ec876..c938a3f60929 100644 --- a/docs/writing-stories/index.md +++ b/docs/writing-stories/index.md @@ -37,6 +37,7 @@ The _default_ export metadata controls how Storybook lists your stories and prov 'vue/button-story-default-export-with-component.ts.mdx', 'angular/button-story-default-export-with-component.ts.mdx', 'svelte/button-story-default-export-with-component.js.mdx', + 'svelte/button-story-default-export-with-component.ts.mdx', 'web-components/button-story-default-export-with-component.js.mdx', 'html/button-story-default-export.js.mdx', 'html/button-story-default-export.ts.mdx', @@ -69,6 +70,7 @@ Use the _named_ exports of a CSF file to define your component’s stories. We r 'web-components/button-story.js.mdx', 'web-components/button-story.ts.mdx', 'svelte/button-story.js.mdx', + 'svelte/button-story.ts.mdx', 'html/button-story.js.mdx', 'html/button-story.ts.mdx', 'solid/button-story.js.mdx', @@ -150,6 +152,7 @@ You can rename any particular story you need. For instance, to give it a more ac 'web-components/button-story-rename-story.js.mdx', 'web-components/button-story-rename-story.ts.mdx', 'svelte/button-story-rename-story.js.mdx', + 'svelte/button-story-rename-story.ts.mdx', 'html/button-story-rename-story.js.mdx', 'html/button-story-rename-story.ts.mdx', 'solid/button-story-rename-story.js.mdx', @@ -179,6 +182,7 @@ A story is a function that describes how to render a component. You can have mul 'web-components/button-story-with-emojis.js.mdx', 'web-components/button-story-with-emojis.ts.mdx', 'svelte/button-story-with-emojis.js.mdx', + 'svelte/button-story-with-emojis.ts.mdx', 'html/button-story-with-emojis.js.mdx', 'html/button-story-with-emojis.ts.mdx', 'solid/button-story-with-emojis.js.mdx', @@ -210,6 +214,7 @@ Refine this pattern by introducing `args` for your component's stories. It reduc 'web-components/button-story-using-args.js.mdx', 'web-components/button-story-using-args.ts.mdx', 'svelte/button-story-using-args.js.mdx', + 'svelte/button-story-using-args.ts.mdx', 'html/button-story-using-args.js.mdx', 'html/button-story-using-args.ts.mdx', 'solid/button-story-using-args.js.mdx', @@ -239,6 +244,7 @@ What’s more, you can import `args` to reuse when writing stories for other com 'web-components/button-group-story.js.mdx', 'web-components/button-group-story.ts.mdx', 'svelte/button-group-story.js.mdx', + 'svelte/button-group-story.ts.mdx', 'solid/button-group-story.js.mdx', 'solid/button-group-story.ts.mdx', ]} @@ -285,6 +291,7 @@ Storybook's `play` function and the [`@storybook/addon-interactions`](https://st 'web-components/login-form-with-play-function.js.mdx', 'web-components/login-form-with-play-function.ts.mdx', 'svelte/login-form-with-play-function.js.mdx', + 'svelte/login-form-with-play-function.ts.mdx', 'solid/login-form-with-play-function.js.mdx', 'solid/login-form-with-play-function.ts.mdx', ]} @@ -312,6 +319,7 @@ For instance, suppose you wanted to test your Button component against a differe 'web-components/button-story-with-blue-args.js.mdx', 'web-components/button-story-with-blue-args.ts.mdx', 'svelte/button-story-with-blue-args.js.mdx', + 'svelte/button-story-with-blue-args.ts.mdx', 'html/button-story-with-blue-args.js.mdx', 'html/button-story-with-blue-args.ts.mdx', 'solid/button-story-with-blue-args.js.mdx', @@ -343,6 +351,9 @@ A simple example is adding padding to a component’s stories. Accomplish this u 'web-components/button-story-component-decorator.js.mdx', 'web-components/button-story-component-decorator.ts.mdx', 'svelte/button-story-component-decorator.js.mdx', + 'svelte/button-story-component-decorator.ts.mdx', + 'svelte/margindecorator.with-margin-component.js.mdx', + 'svelte/margindecorator.with-margin-component.ts.mdx', 'html/button-story-component-decorator.js.mdx', 'html/button-story-component-decorator.ts.mdx', 'solid/button-story-component-decorator.js.mdx', diff --git a/docs/writing-stories/loaders.md b/docs/writing-stories/loaders.md index b0b5c11fd123..663670d6e1e9 100644 --- a/docs/writing-stories/loaders.md +++ b/docs/writing-stories/loaders.md @@ -26,6 +26,7 @@ Loaders are helpful when you need to load story data externally (e.g., from a re 'web-components/loader-story.js.mdx', 'web-components/loader-story.ts.mdx', 'svelte/loader-story.js.mdx', + 'svelte/loader-story.ts.mdx', 'solid/loader-story.js.mdx', 'solid/loader-story.ts.mdx', ]} diff --git a/docs/writing-stories/parameters.md b/docs/writing-stories/parameters.md index b697330ec848..9ec6b5c73225 100644 --- a/docs/writing-stories/parameters.md +++ b/docs/writing-stories/parameters.md @@ -44,6 +44,7 @@ We can set the parameters for all stories of a component using the `parameters` 'web-components/button-story-with-blue-args.js.mdx', 'web-components/button-story-with-blue-args.ts.mdx', 'svelte/button-story-with-blue-args.js.mdx', + 'svelte/button-story-with-blue-args.ts.mdx', 'solid/button-story-with-blue-args.js.mdx', 'solid/button-story-with-blue-args.ts.mdx', ]} diff --git a/docs/writing-tests/accessibility-testing.md b/docs/writing-tests/accessibility-testing.md index 4285fa95eaa8..14506ae979e2 100644 --- a/docs/writing-tests/accessibility-testing.md +++ b/docs/writing-tests/accessibility-testing.md @@ -70,6 +70,7 @@ Storybook's a11y addon runs [Axe](https://github.com/dequelabs/axe-core) on the 'vue/component-story-with-accessibility.3.js.mdx', 'vue/component-story-with-accessibility.3.ts.mdx', 'svelte/component-story-with-accessibility.js.mdx', + 'svelte/component-story-with-accessibility.ts.mdx', 'web-components/component-story-with-accessibility.js.mdx', 'web-components/component-story-with-accessibility.ts.mdx', ]} @@ -134,6 +135,7 @@ Customize the a11y ruleset at the story level by updating your story to include 'vue/storybook-addon-a11y-story-config.js.mdx', 'vue/storybook-addon-a11y-story-config.ts.mdx', 'svelte/storybook-addon-a11y-story-config.js.mdx', + 'svelte/storybook-addon-a11y-story-config.ts.mdx', 'web-components/storybook-addon-a11y-story-config.js.mdx', 'web-components/storybook-addon-a11y-story-config.ts.mdx', ]} @@ -157,6 +159,7 @@ Disable accessibility testing for stories or components by adding the following 'vue/storybook-addon-a11y-disable.js.mdx', 'vue/storybook-addon-a11y-disable.ts.mdx', 'svelte/storybook-addon-a11y-disable.js.mdx', + 'svelte/storybook-addon-a11y-disable.ts.mdx', 'web-components/storybook-addon-a11y-disable.js.mdx', 'web-components/storybook-addon-a11y-disable.ts.mdx', ]} diff --git a/docs/writing-tests/interaction-testing.md b/docs/writing-tests/interaction-testing.md index 90c7e2fc8a06..4cc94872b15f 100644 --- a/docs/writing-tests/interaction-testing.md +++ b/docs/writing-tests/interaction-testing.md @@ -71,6 +71,7 @@ The test itself is defined inside a `play` function connected to a story. Here's 'web-components/login-form-with-play-function.js.mdx', 'web-components/login-form-with-play-function.ts.mdx', 'svelte/login-form-with-play-function.js.mdx', + 'svelte/login-form-with-play-function.ts.mdx', 'solid/login-form-with-play-function.js.mdx', 'solid/login-form-with-play-function.ts.mdx', ]} diff --git a/docs/writing-tests/stories-in-end-to-end-tests.md b/docs/writing-tests/stories-in-end-to-end-tests.md index 50fa58ae0688..6699ea352cbe 100644 --- a/docs/writing-tests/stories-in-end-to-end-tests.md +++ b/docs/writing-tests/stories-in-end-to-end-tests.md @@ -22,6 +22,7 @@ An example of an end-to-end test with Cypress and Storybook is testing a login c 'web-components/login-form-with-play-function.js.mdx', 'web-components/login-form-with-play-function.ts.mdx', 'svelte/login-form-with-play-function.js.mdx', + 'svelte/login-form-with-play-function.ts.mdx', ]} usesCsf3 csf2Path="writing-tests/importing-stories-in-tests#snippet-login-form-with-play-function" @@ -69,6 +70,7 @@ A real-life scenario of user flow testing with Playwright would be how to test a 'web-components/login-form-with-play-function.js.mdx', 'web-components/login-form-with-play-function.ts.mdx', 'svelte/login-form-with-play-function.js.mdx', + 'svelte/login-form-with-play-function.ts.mdx', ]} usesCsf3 csf2Path="writing-tests/importing-stories-in-tests#snippet-login-form-with-play-function" diff --git a/scripts/sandbox/generate.ts b/scripts/sandbox/generate.ts index e14b8bac5f04..0ad2860b536f 100755 --- a/scripts/sandbox/generate.ts +++ b/scripts/sandbox/generate.ts @@ -28,10 +28,15 @@ import { LOCAL_REGISTRY_URL, } from '../utils/constants'; -const sbInit = async (cwd: string, flags?: string[], debug?: boolean) => { +const sbInit = async ( + cwd: string, + envVars: Record = {}, + flags?: string[], + debug?: boolean +) => { const sbCliBinaryPath = join(__dirname, `../../code/lib/cli/bin/index.js`); console.log(`🎁 Installing storybook`); - const env = { STORYBOOK_DISABLE_TELEMETRY: 'true' }; + const env = { STORYBOOK_DISABLE_TELEMETRY: 'true', ...envVars }; const fullFlags = ['--yes', ...(flags || [])]; await runCommand(`${sbCliBinaryPath} init ${fullFlags.join(' ')}`, { cwd, env }, debug); }; @@ -61,11 +66,13 @@ const addStorybook = async ({ localRegistry, flags, debug, + env = {}, }: { baseDir: string; localRegistry: boolean; flags?: string[]; debug?: boolean; + env?: Record; }) => { const beforeDir = join(baseDir, BEFORE_DIR_NAME); const afterDir = join(baseDir, AFTER_DIR_NAME); @@ -84,10 +91,10 @@ const addStorybook = async ({ jackspeak: '2.1.1', }); - await sbInit(tmpDir, flags, debug); + await sbInit(tmpDir, env, flags, debug); }); } else { - await sbInit(tmpDir, flags, debug); + await sbInit(tmpDir, env, flags, debug); } } catch (e) { await remove(tmpDir); @@ -142,7 +149,7 @@ const runGenerators = async ( const limit = pLimit(1); await Promise.all( - generators.map(({ dirName, name, script, expected }) => + generators.map(({ dirName, name, script, expected, env }) => limit(async () => { let flags: string[] = []; if (expected.renderer === '@storybook/html') flags = ['--type html']; @@ -189,7 +196,7 @@ const runGenerators = async ( // Make sure there are no git projects in the folder await remove(join(beforeDir, '.git')); - await addStorybook({ baseDir, localRegistry, flags, debug }); + await addStorybook({ baseDir, localRegistry, flags, debug, env }); await addDocumentation(baseDir, { name, dirName }); diff --git a/scripts/sandbox/utils/types.ts b/scripts/sandbox/utils/types.ts index a9e61af5715d..39d4594aa6e5 100644 --- a/scripts/sandbox/utils/types.ts +++ b/scripts/sandbox/utils/types.ts @@ -6,4 +6,5 @@ export type GeneratorConfig = { renderer: string; builder: string; }; + env?: Record; }; diff --git a/scripts/task.ts b/scripts/task.ts index 20dad32716c3..1247cc89351a 100644 --- a/scripts/task.ts +++ b/scripts/task.ts @@ -496,7 +496,7 @@ async function run() { controller.abort(); }); - return 1; + throw err; } statuses.set(task, task.service ? 'serving' : 'complete'); diff --git a/scripts/tasks/generate.ts b/scripts/tasks/generate.ts index cbce6c66a1c5..f453fc3222e8 100644 --- a/scripts/tasks/generate.ts +++ b/scripts/tasks/generate.ts @@ -1,3 +1,4 @@ +/* eslint-disable import/extensions */ import { pathExists, remove } from 'fs-extra'; import { join } from 'path'; import { REPROS_DIRECTORY } from '../utils/constants'; @@ -27,7 +28,8 @@ export const generate: Task = { } // This uses an async import as it depends on `lib/cli` which requires `code` to be installed. - const { generate: generateRepro } = await import('../sandbox/generate'); + // @ts-expect-error Default import required for dynamic import processed by esbuild + const { generate: generateRepro } = (await import('../sandbox/generate.ts')).default; await generateRepro({ templates: [details.key], diff --git a/scripts/tasks/sandbox-parts.ts b/scripts/tasks/sandbox-parts.ts index d2f5748ce104..d35edced9abc 100644 --- a/scripts/tasks/sandbox-parts.ts +++ b/scripts/tasks/sandbox-parts.ts @@ -39,6 +39,7 @@ import { JsPackageManagerFactory } from '../../code/lib/cli/src/js-package-manag import { workspacePath } from '../utils/workspace'; import { babelParse } from '../../code/lib/csf-tools/src/babelParse'; import { CODE_DIRECTORY, REPROS_DIRECTORY } from '../utils/constants'; +import type { TemplateKey } from '../../code/lib/cli/src/sandbox-templates'; const logger = console; @@ -75,7 +76,7 @@ export const create: Task['run'] = async ({ key, template, sandboxDir }, { dryRu } }; -export const install: Task['run'] = async ({ sandboxDir }, { link, dryRun, debug }) => { +export const install: Task['run'] = async ({ sandboxDir, key }, { link, dryRun, debug }) => { const cwd = sandboxDir; await installYarn2({ cwd, dryRun, debug }); @@ -93,24 +94,22 @@ export const install: Task['run'] = async ({ sandboxDir }, { link, dryRun, debug // of any storybook packages as verdaccio is not able to both proxy to npm and publish over // the top. In theory this could mask issues where different versions cause problems. await addPackageResolutions({ cwd, dryRun, debug }); - await configureYarn2ForVerdaccio({ cwd, dryRun, debug }); + await configureYarn2ForVerdaccio({ cwd, dryRun, debug, key }); // Add vite plugin workarounds for frameworks that need it // (to support vite 5 without peer dep errors) - if ( - [ - 'bench-react-vite-default-ts', - 'bench-react-vite-default-ts-nodocs', - 'bench-react-vite-default-ts-test-build', - 'internal-ssv6-vite', - 'react-vite-default-js', - 'react-vite-default-ts', - 'svelte-vite-default-js', - 'svelte-vite-default-ts', - 'vue3-vite-default-js', - 'vue3-vite-default-ts', - ].includes(sandboxDir.split(sep).at(-1)) - ) { + const sandboxesNeedingWorkarounds: TemplateKey[] = [ + 'bench/react-vite-default-ts', + 'bench/react-vite-default-ts-nodocs', + 'bench/react-vite-default-ts-test-build', + 'react-vite/default-js', + 'react-vite/default-ts', + 'svelte-vite/default-js', + 'svelte-vite/default-ts', + 'vue3-vite/default-js', + 'vue3-vite/default-ts', + ]; + if (sandboxesNeedingWorkarounds.includes(key)) { await addWorkaroundResolutions({ cwd, dryRun, debug }); } diff --git a/scripts/utils/yarn.ts b/scripts/utils/yarn.ts index 19f87d1c0182..2f1fdc8b838e 100644 --- a/scripts/utils/yarn.ts +++ b/scripts/utils/yarn.ts @@ -1,6 +1,7 @@ import { pathExists, readJSON, writeJSON } from 'fs-extra'; import path from 'path'; +import type { TemplateKey } from 'get-template'; import { exec } from './exec'; // TODO -- should we generate this file a second time outside of CLI? import storybookVersions from '../../code/lib/cli/src/versions'; @@ -75,7 +76,12 @@ export const addWorkaroundResolutions = async ({ cwd, dryRun }: YarnOptions) => await writeJSON(packageJsonPath, packageJson, { spaces: 2 }); }; -export const configureYarn2ForVerdaccio = async ({ cwd, dryRun, debug }: YarnOptions) => { +export const configureYarn2ForVerdaccio = async ({ + cwd, + dryRun, + debug, + key, +}: YarnOptions & { key: TemplateKey }) => { const command = [ // We don't want to use the cache or we might get older copies of our built packages // (with identical versions), as yarn (correctly I guess) assumes the same version hasn't changed @@ -89,10 +95,20 @@ export const configureYarn2ForVerdaccio = async ({ cwd, dryRun, debug }: YarnOpt `yarn config set pnpFallbackMode none`, // We need to be able to update lockfile when bootstrapping the examples `yarn config set enableImmutableInstalls false`, + ]; + + if (key === 'svelte-kit/prerelease-ts') { + // Don't error with INCOMPATIBLE_PEER_DEPENDENCY for SvelteKit prerelease, it is expected + command.push( + `yarn config set logFilters --json '[ { "code": "YN0013", "level": "discard" } ]'` + ); + } else { // Discard all YN0013 - FETCH_NOT_CACHED messages // Error on YN0060 - INCOMPATIBLE_PEER_DEPENDENCY - `yarn config set logFilters --json '[ { "code": "YN0013", "level": "discard" }, { "code": "YN0060", "level": "error" } ]'`, - ]; + command.push( + `yarn config set logFilters --json '[ { "code": "YN0013", "level": "discard" }, { "code": "YN0060", "level": "error" } ]'` + ); + } await exec( command, diff --git a/test-storybooks/ember-cli/package.json b/test-storybooks/ember-cli/package.json index 030ade6a58e2..e2f454ef9587 100644 --- a/test-storybooks/ember-cli/package.json +++ b/test-storybooks/ember-cli/package.json @@ -57,7 +57,6 @@ "@storybook/preset-react-webpack": "portal:../../code/presets/react-webpack", "@storybook/preset-server-webpack": "portal:../../code/presets/server-webpack", "@storybook/preset-svelte-webpack": "portal:../../code/presets/svelte-webpack", - "@storybook/preset-vue-webpack": "portal:../../code/presets/vue-webpack", "@storybook/preset-vue3-webpack": "portal:../../code/presets/vue3-webpack", "@storybook/preset-web-components-webpack": "portal:../../code/presets/web-components-webpack", "@storybook/react": "portal:../../code/renderers/react", @@ -74,7 +73,6 @@ "@storybook/theming": "portal:../../code/lib/theming", "@storybook/vue": "portal:../../code/renderers/vue", "@storybook/vue-vite": "portal:../../code/frameworks/vue-vite", - "@storybook/vue-webpack5": "portal:../../code/frameworks/vue-webpack5", "@storybook/vue3": "portal:../../code/renderers/vue3", "@storybook/vue3-vite": "portal:../../code/frameworks/vue3-vite", "@storybook/vue3-webpack5": "portal:../../code/frameworks/vue3-webpack5", diff --git a/test-storybooks/external-docs/package.json b/test-storybooks/external-docs/package.json index 359c78de0b19..368f160a40cd 100644 --- a/test-storybooks/external-docs/package.json +++ b/test-storybooks/external-docs/package.json @@ -58,7 +58,6 @@ "@storybook/preset-react-webpack": "portal:../../code/presets/react-webpack", "@storybook/preset-server-webpack": "portal:../../code/presets/server-webpack", "@storybook/preset-svelte-webpack": "portal:../../code/presets/svelte-webpack", - "@storybook/preset-vue-webpack": "portal:../../code/presets/vue-webpack", "@storybook/preset-vue3-webpack": "portal:../../code/presets/vue3-webpack", "@storybook/preset-web-components-webpack": "portal:../../code/presets/web-components-webpack", "@storybook/preview-api": "portal:../../code/lib/preview-api", @@ -76,7 +75,6 @@ "@storybook/theming": "portal:../../code/lib/theming", "@storybook/vue": "portal:../../code/renderers/vue", "@storybook/vue-vite": "portal:../../code/frameworks/vue-vite", - "@storybook/vue-webpack5": "portal:../../code/frameworks/vue-webpack5", "@storybook/vue3": "portal:../../code/renderers/vue3", "@storybook/vue3-vite": "portal:../../code/frameworks/vue3-vite", "@storybook/vue3-webpack5": "portal:../../code/frameworks/vue3-webpack5", @@ -116,4 +114,4 @@ "typescript": "~5.2.2", "webpack": "5" } -} +} \ No newline at end of file diff --git a/test-storybooks/server-kitchen-sink/package.json b/test-storybooks/server-kitchen-sink/package.json index beffa87a6fda..b663db093309 100644 --- a/test-storybooks/server-kitchen-sink/package.json +++ b/test-storybooks/server-kitchen-sink/package.json @@ -60,7 +60,6 @@ "@storybook/preset-react-webpack": "portal:../../code/presets/react-webpack", "@storybook/preset-server-webpack": "portal:../../code/presets/server-webpack", "@storybook/preset-svelte-webpack": "portal:../../code/presets/svelte-webpack", - "@storybook/preset-vue-webpack": "portal:../../code/presets/vue-webpack", "@storybook/preset-vue3-webpack": "portal:../../code/presets/vue3-webpack", "@storybook/preset-web-components-webpack": "portal:../../code/presets/web-components-webpack", "@storybook/react": "portal:../../code/renderers/react", @@ -77,7 +76,6 @@ "@storybook/theming": "portal:../../code/lib/theming", "@storybook/vue": "portal:../../code/renderers/vue", "@storybook/vue-vite": "portal:../../code/frameworks/vue-vite", - "@storybook/vue-webpack5": "portal:../../code/frameworks/vue-webpack5", "@storybook/vue3": "portal:../../code/renderers/vue3", "@storybook/vue3-vite": "portal:../../code/frameworks/vue3-vite", "@storybook/vue3-webpack5": "portal:../../code/frameworks/vue3-webpack5", diff --git a/test-storybooks/standalone-preview/package.json b/test-storybooks/standalone-preview/package.json index 46363a02b6f1..41a52bd14f4c 100644 --- a/test-storybooks/standalone-preview/package.json +++ b/test-storybooks/standalone-preview/package.json @@ -53,7 +53,6 @@ "@storybook/preset-react-webpack": "portal:../../code/presets/react-webpack", "@storybook/preset-server-webpack": "portal:../../code/presets/server-webpack", "@storybook/preset-svelte-webpack": "portal:../../code/presets/svelte-webpack", - "@storybook/preset-vue-webpack": "portal:../../code/presets/vue-webpack", "@storybook/preset-vue3-webpack": "portal:../../code/presets/vue3-webpack", "@storybook/preset-web-components-webpack": "portal:../../code/presets/web-components-webpack", "@storybook/react": "portal:../../code/renderers/react", @@ -70,7 +69,6 @@ "@storybook/theming": "portal:../../code/lib/theming", "@storybook/vue": "portal:../../code/renderers/vue", "@storybook/vue-vite": "portal:../../code/frameworks/vue-vite", - "@storybook/vue-webpack5": "portal:../../code/frameworks/vue-webpack5", "@storybook/vue3": "portal:../../code/renderers/vue3", "@storybook/vue3-vite": "portal:../../code/frameworks/vue3-vite", "@storybook/vue3-webpack5": "portal:../../code/frameworks/vue3-webpack5",