From 11a848414e651bf44bce6abbf3c15d793cf6179b Mon Sep 17 00:00:00 2001 From: Jeppe Reinhold Date: Fri, 9 Feb 2024 23:06:36 +0100 Subject: [PATCH 001/132] consolidate generate-sandboxes workflows into a single workflow and composite action --- .../generate-sandboxes-composite-action.yml | 58 ++++++++++++++++++ .github/workflows/generate-sandboxes-main.yml | 60 ------------------- .github/workflows/generate-sandboxes.yml | 34 +++++++++++ 3 files changed, 92 insertions(+), 60 deletions(-) create mode 100644 .github/actions/generate-sandboxes-composite-action.yml delete mode 100644 .github/workflows/generate-sandboxes-main.yml create mode 100644 .github/workflows/generate-sandboxes.yml diff --git a/.github/actions/generate-sandboxes-composite-action.yml b/.github/actions/generate-sandboxes-composite-action.yml new file mode 100644 index 000000000000..d47166c73ec4 --- /dev/null +++ b/.github/actions/generate-sandboxes-composite-action.yml @@ -0,0 +1,58 @@ +name: Generate and push sandboxes action +description: This is a composite action that generates sandboxes and pushes them to the storybookjs/sandboxes repository + +inputs: + destination-branch: + description: The destination branch to generate sandboxes to in the storybookjs/sandboxes repository + required: true + +defaults: + run: + shell: bash + working-directory: ./code + +runs: + using: "composite" + steps: + - uses: actions/setup-node@v3 + with: + node-version-file: ".nvmrc" + + - name: Setup git user + run: | + git config --global user.name "storybook-bot" + git config --global user.email "32066757+storybook-bot@users.noreply.github.com" + + - name: Install dependencies + working-directory: ./scripts + env: + YARN_ENABLE_IMMUTABLE_INSTALLS: false + run: node --experimental-modules ./check-dependencies.js + + - name: Compile Storybook libraries + run: yarn task --task compile --start-from=auto --no-link + + - name: Publish to local registry + run: yarn local-registry --publish + + - name: Run local registry + run: yarn local-registry --open & + + - name: Wait for registry + run: yarn wait-on tcp:127.0.0.1:6001 + + - name: Generate + env: + CLEANUP_SANDBOX_NODE_MODULES: true + run: yarn generate-sandboxes --local-registry + + - name: Publish + run: yarn publish-sandboxes --remote=https://storybook-bot:${{ secrets.PAT_STORYBOOK_BOT}}@github.com/storybookjs/sandboxes.git --push --branch=${{ inputs.destination-branch }} + + - name: The job has failed + if: ${{ failure() || cancelled() }} + env: + DISCORD_WEBHOOK: ${{ secrets.DISCORD_MONITORING_URL }} + uses: Ilshidur/action-discord@master + with: + args: "The generation of sandboxes in the **${{ inputs.destination-branch }}** branch has failed. [View Run](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }})" diff --git a/.github/workflows/generate-sandboxes-main.yml b/.github/workflows/generate-sandboxes-main.yml deleted file mode 100644 index cc17376c57de..000000000000 --- a/.github/workflows/generate-sandboxes-main.yml +++ /dev/null @@ -1,60 +0,0 @@ -name: Generate and push sandboxes (main) - -on: - schedule: - - cron: '2 2 */1 * *' - workflow_dispatch: - # To test fixes on push rather than wait for the scheduling, do the following: - # 1. Uncomment the lines below and add your branch. - # push: - # branches: - # - - # 2. change the "ref" value to in the actions/checkout step below. - # 3. ๐Ÿ‘‰ DON'T FORGET TO UNDO THE VALUES BACK TO `main` BEFORE YOU MERGE YOUR CHANGES! - -jobs: - generate: - runs-on: ubuntu-latest - env: - YARN_ENABLE_IMMUTABLE_INSTALLS: false - CLEANUP_SANDBOX_NODE_MODULES: true - steps: - - uses: actions/checkout@v3 - with: - ref: main - - uses: actions/setup-node@v3 - with: - node-version-file: '.nvmrc' - - name: Setup git user - run: | - git config --global user.name "Storybook Bot" - git config --global user.email "bot@storybook.js.org" - - name: Install dependencies - run: | - cd ./scripts - node --experimental-modules ./check-dependencies.js - cd .. - - name: Compile Storybook libraries - run: yarn task --task compile --start-from=auto --no-link - - name: Publishing to local registry - run: yarn local-registry --publish - working-directory: ./code - - name: Running local registry - run: yarn local-registry --open & - working-directory: ./code - - name: Wait for registry - run: yarn wait-on tcp:127.0.0.1:6001 - working-directory: ./code - - name: Generate - run: yarn generate-sandboxes --local-registry - working-directory: ./code - - name: Publish - run: yarn publish-sandboxes --remote=https://storybook-bot:${{ secrets.PAT_STORYBOOK_BOT}}@github.com/storybookjs/sandboxes.git --push --branch=main - working-directory: ./code - - name: The job has failed - if: ${{ failure() || cancelled() }} - env: - DISCORD_WEBHOOK: ${{ secrets.DISCORD_MONITORING_URL }} - uses: Ilshidur/action-discord@master - with: - args: 'The generation of sandboxes in the **main** branch has failed. [View Run](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }})' diff --git a/.github/workflows/generate-sandboxes.yml b/.github/workflows/generate-sandboxes.yml new file mode 100644 index 000000000000..dd80cefcb790 --- /dev/null +++ b/.github/workflows/generate-sandboxes.yml @@ -0,0 +1,34 @@ +name: Generate and push sandboxes + +on: + schedule: + - cron: "2 2 */1 * *" + workflow_dispatch: + # To test fixes on push rather than wait for the scheduling, do the following: + # 1. Uncomment the lines below and add your branch. + # push: + # branches: + # - + # 2. Change the "ref" value to in the actions/checkout step below. + # 3. Comment out the whole "generate-main" job starting at line 26 + # 3. ๐Ÿ‘‰ DON'T FORGET TO UNDO STEP 2 AND 3 BEFORE YOU MERGE YOUR CHANGES! + +jobs: + generate-next: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + ref: next + - uses: .github/actions/generate-sandboxes-composite-action.yml + with: + destination-branch: next + generate-main: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + ref: main + - uses: .github/actions/generate-sandboxes-composite-action.yml + with: + destination-branch: main From 81abd2ac5f5f5c0f6b2a1d65b1972650cf86949e Mon Sep 17 00:00:00 2001 From: Jeppe Reinhold Date: Fri, 9 Feb 2024 23:08:06 +0100 Subject: [PATCH 002/132] temporarily test this branch as for sandbox generation --- .github/workflows/generate-sandboxes.yml | 26 ++++++++++++------------ 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/.github/workflows/generate-sandboxes.yml b/.github/workflows/generate-sandboxes.yml index dd80cefcb790..af353f6b19aa 100644 --- a/.github/workflows/generate-sandboxes.yml +++ b/.github/workflows/generate-sandboxes.yml @@ -6,9 +6,9 @@ on: workflow_dispatch: # To test fixes on push rather than wait for the scheduling, do the following: # 1. Uncomment the lines below and add your branch. - # push: - # branches: - # - + push: + branches: + - jeppe/25922-ci-generation-of-sandboxes-fail-sometimes-on-prereleases # 2. Change the "ref" value to in the actions/checkout step below. # 3. Comment out the whole "generate-main" job starting at line 26 # 3. ๐Ÿ‘‰ DON'T FORGET TO UNDO STEP 2 AND 3 BEFORE YOU MERGE YOUR CHANGES! @@ -19,16 +19,16 @@ jobs: steps: - uses: actions/checkout@v4 with: - ref: next + ref: jeppe/25922-ci-generation-of-sandboxes-fail-sometimes-on-prereleases - uses: .github/actions/generate-sandboxes-composite-action.yml with: destination-branch: next - generate-main: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - with: - ref: main - - uses: .github/actions/generate-sandboxes-composite-action.yml - with: - destination-branch: main + # generate-main: + # runs-on: ubuntu-latest + # steps: + # - uses: actions/checkout@v4 + # with: + # ref: main + # - uses: .github/actions/generate-sandboxes-composite-action.yml + # with: + # destination-branch: main From 658f715228ae08b5f7187e13ed94e40392c6447c Mon Sep 17 00:00:00 2001 From: Jeppe Reinhold Date: Fri, 9 Feb 2024 23:09:11 +0100 Subject: [PATCH 003/132] correct syntax for local composite actions --- .github/workflows/generate-sandboxes.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/generate-sandboxes.yml b/.github/workflows/generate-sandboxes.yml index af353f6b19aa..a138a7ebe4ef 100644 --- a/.github/workflows/generate-sandboxes.yml +++ b/.github/workflows/generate-sandboxes.yml @@ -20,7 +20,7 @@ jobs: - uses: actions/checkout@v4 with: ref: jeppe/25922-ci-generation-of-sandboxes-fail-sometimes-on-prereleases - - uses: .github/actions/generate-sandboxes-composite-action.yml + - uses: ./.github/actions/generate-sandboxes-composite-action.yml with: destination-branch: next # generate-main: @@ -29,6 +29,6 @@ jobs: # - uses: actions/checkout@v4 # with: # ref: main - # - uses: .github/actions/generate-sandboxes-composite-action.yml + # - uses: ./.github/actions/generate-sandboxes-composite-action.yml # with: # destination-branch: main From a38557413a09dcdc0dafee7c1cf6c6f61a07c68b Mon Sep 17 00:00:00 2001 From: Jeppe Reinhold Date: Fri, 9 Feb 2024 23:12:07 +0100 Subject: [PATCH 004/132] correcterer composite action syntax --- .github/workflows/generate-sandboxes.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/generate-sandboxes.yml b/.github/workflows/generate-sandboxes.yml index a138a7ebe4ef..0f6b5e992e7d 100644 --- a/.github/workflows/generate-sandboxes.yml +++ b/.github/workflows/generate-sandboxes.yml @@ -20,7 +20,7 @@ jobs: - uses: actions/checkout@v4 with: ref: jeppe/25922-ci-generation-of-sandboxes-fail-sometimes-on-prereleases - - uses: ./.github/actions/generate-sandboxes-composite-action.yml + - uses: ./.github/actions/generate-sandboxes-composite-action with: destination-branch: next # generate-main: @@ -29,6 +29,6 @@ jobs: # - uses: actions/checkout@v4 # with: # ref: main - # - uses: ./.github/actions/generate-sandboxes-composite-action.yml + # - uses: ./.github/actions/generate-sandboxes-composite-action # with: # destination-branch: main From 871e1b17f78721e05d67bde518c3e63879d48e09 Mon Sep 17 00:00:00 2001 From: Jeppe Reinhold Date: Fri, 9 Feb 2024 23:16:08 +0100 Subject: [PATCH 005/132] correctest composite action syntax --- .../action.yml} | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) rename .github/actions/{generate-sandboxes-composite-action.yml => generate-sandboxes-composite-action/action.yml} (88%) diff --git a/.github/actions/generate-sandboxes-composite-action.yml b/.github/actions/generate-sandboxes-composite-action/action.yml similarity index 88% rename from .github/actions/generate-sandboxes-composite-action.yml rename to .github/actions/generate-sandboxes-composite-action/action.yml index d47166c73ec4..e2d84a2c283d 100644 --- a/.github/actions/generate-sandboxes-composite-action.yml +++ b/.github/actions/generate-sandboxes-composite-action/action.yml @@ -6,11 +6,6 @@ inputs: description: The destination branch to generate sandboxes to in the storybookjs/sandboxes repository required: true -defaults: - run: - shell: bash - working-directory: ./code - runs: using: "composite" steps: @@ -19,34 +14,42 @@ runs: node-version-file: ".nvmrc" - name: Setup git user + shell: bash run: | git config --global user.name "storybook-bot" git config --global user.email "32066757+storybook-bot@users.noreply.github.com" - name: Install dependencies + shell: bash working-directory: ./scripts env: - YARN_ENABLE_IMMUTABLE_INSTALLS: false + YARN_ENABLE_IMMUTABLE_INSTALLS: "false" run: node --experimental-modules ./check-dependencies.js - name: Compile Storybook libraries + shell: bash run: yarn task --task compile --start-from=auto --no-link - name: Publish to local registry + shell: bash run: yarn local-registry --publish - name: Run local registry + shell: bash run: yarn local-registry --open & - name: Wait for registry + shell: bash run: yarn wait-on tcp:127.0.0.1:6001 - name: Generate + shell: bash env: - CLEANUP_SANDBOX_NODE_MODULES: true + CLEANUP_SANDBOX_NODE_MODULES: "true" run: yarn generate-sandboxes --local-registry - name: Publish + shell: bash run: yarn publish-sandboxes --remote=https://storybook-bot:${{ secrets.PAT_STORYBOOK_BOT}}@github.com/storybookjs/sandboxes.git --push --branch=${{ inputs.destination-branch }} - name: The job has failed From bb0d0d0f7ea919118d275c0c10833ced6297db96 Mon Sep 17 00:00:00 2001 From: Jeppe Reinhold Date: Fri, 9 Feb 2024 23:20:38 +0100 Subject: [PATCH 006/132] move secrets to workflow --- .../generate-sandboxes-composite-action/action.yml | 10 ++++++++-- .github/workflows/generate-sandboxes.yml | 7 +++++++ 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/.github/actions/generate-sandboxes-composite-action/action.yml b/.github/actions/generate-sandboxes-composite-action/action.yml index e2d84a2c283d..a4f0112731e7 100644 --- a/.github/actions/generate-sandboxes-composite-action/action.yml +++ b/.github/actions/generate-sandboxes-composite-action/action.yml @@ -5,6 +5,12 @@ inputs: destination-branch: description: The destination branch to generate sandboxes to in the storybookjs/sandboxes repository required: true + token: + description: The personal access token to use when authenticating with the destination repository + required: true + discord-url: + description: The Discord URL to use when reporting failures + required: true runs: using: "composite" @@ -50,12 +56,12 @@ runs: - name: Publish shell: bash - run: yarn publish-sandboxes --remote=https://storybook-bot:${{ secrets.PAT_STORYBOOK_BOT}}@github.com/storybookjs/sandboxes.git --push --branch=${{ inputs.destination-branch }} + run: yarn publish-sandboxes --remote=https://storybook-bot:${{ inputs.token }}@github.com/storybookjs/sandboxes.git --push --branch=${{ inputs.destination-branch }} - name: The job has failed if: ${{ failure() || cancelled() }} env: - DISCORD_WEBHOOK: ${{ secrets.DISCORD_MONITORING_URL }} + DISCORD_WEBHOOK: ${{ inputs.discord-url }} uses: Ilshidur/action-discord@master with: args: "The generation of sandboxes in the **${{ inputs.destination-branch }}** branch has failed. [View Run](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }})" diff --git a/.github/workflows/generate-sandboxes.yml b/.github/workflows/generate-sandboxes.yml index 0f6b5e992e7d..942ad7527d42 100644 --- a/.github/workflows/generate-sandboxes.yml +++ b/.github/workflows/generate-sandboxes.yml @@ -15,6 +15,7 @@ on: jobs: generate-next: + name: Generate to next runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 @@ -23,7 +24,11 @@ jobs: - uses: ./.github/actions/generate-sandboxes-composite-action with: destination-branch: next + token: ${{ secrets.PAT_STORYBOOK_BOT }} + discord-url: ${{ secrets.DISCORD_MONITORING_URL }} + # generate-main: + # name: Generate to main # runs-on: ubuntu-latest # steps: # - uses: actions/checkout@v4 @@ -32,3 +37,5 @@ jobs: # - uses: ./.github/actions/generate-sandboxes-composite-action # with: # destination-branch: main + # token: ${{ secrets.PAT_STORYBOOK_BOT }} + # discord-url: ${{ secrets.DISCORD_MONITORING_URL }} From 02f624193347e4920a01fc9a2da5135efa979131 Mon Sep 17 00:00:00 2001 From: Jeppe Reinhold Date: Fri, 9 Feb 2024 23:27:25 +0100 Subject: [PATCH 007/132] use regular workflow instead of composite action --- .../action.yml | 67 ------------------- .github/workflows/generate-sandboxes-next.yml | 60 ----------------- .github/workflows/generate-sandboxes.yml | 63 ++++++++++++----- 3 files changed, 46 insertions(+), 144 deletions(-) delete mode 100644 .github/actions/generate-sandboxes-composite-action/action.yml delete mode 100644 .github/workflows/generate-sandboxes-next.yml diff --git a/.github/actions/generate-sandboxes-composite-action/action.yml b/.github/actions/generate-sandboxes-composite-action/action.yml deleted file mode 100644 index a4f0112731e7..000000000000 --- a/.github/actions/generate-sandboxes-composite-action/action.yml +++ /dev/null @@ -1,67 +0,0 @@ -name: Generate and push sandboxes action -description: This is a composite action that generates sandboxes and pushes them to the storybookjs/sandboxes repository - -inputs: - destination-branch: - description: The destination branch to generate sandboxes to in the storybookjs/sandboxes repository - required: true - token: - description: The personal access token to use when authenticating with the destination repository - required: true - discord-url: - description: The Discord URL to use when reporting failures - required: true - -runs: - using: "composite" - steps: - - uses: actions/setup-node@v3 - with: - node-version-file: ".nvmrc" - - - name: Setup git user - shell: bash - run: | - git config --global user.name "storybook-bot" - git config --global user.email "32066757+storybook-bot@users.noreply.github.com" - - - name: Install dependencies - shell: bash - working-directory: ./scripts - env: - YARN_ENABLE_IMMUTABLE_INSTALLS: "false" - run: node --experimental-modules ./check-dependencies.js - - - name: Compile Storybook libraries - shell: bash - run: yarn task --task compile --start-from=auto --no-link - - - name: Publish to local registry - shell: bash - run: yarn local-registry --publish - - - name: Run local registry - shell: bash - run: yarn local-registry --open & - - - name: Wait for registry - shell: bash - run: yarn wait-on tcp:127.0.0.1:6001 - - - name: Generate - shell: bash - env: - CLEANUP_SANDBOX_NODE_MODULES: "true" - run: yarn generate-sandboxes --local-registry - - - name: Publish - shell: bash - run: yarn publish-sandboxes --remote=https://storybook-bot:${{ inputs.token }}@github.com/storybookjs/sandboxes.git --push --branch=${{ inputs.destination-branch }} - - - name: The job has failed - if: ${{ failure() || cancelled() }} - env: - DISCORD_WEBHOOK: ${{ inputs.discord-url }} - uses: Ilshidur/action-discord@master - with: - args: "The generation of sandboxes in the **${{ inputs.destination-branch }}** branch has failed. [View Run](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }})" diff --git a/.github/workflows/generate-sandboxes-next.yml b/.github/workflows/generate-sandboxes-next.yml deleted file mode 100644 index 2c0b592d024f..000000000000 --- a/.github/workflows/generate-sandboxes-next.yml +++ /dev/null @@ -1,60 +0,0 @@ -name: Generate and push sandboxes (next) - -on: - schedule: - - cron: '2 2 */1 * *' - workflow_dispatch: - # To test fixes on push rather than wait for the scheduling, do the following: - # 1. Uncomment the lines below and add your branch. - # push: - # branches: - # - - # 2. change the "ref" value to in the actions/checkout step below. - # 3. ๐Ÿ‘‰ DON'T FORGET TO UNDO THE VALUES BACK TO `next` BEFORE YOU MERGE YOUR CHANGES! - -jobs: - generate: - runs-on: ubuntu-latest - env: - YARN_ENABLE_IMMUTABLE_INSTALLS: false - CLEANUP_SANDBOX_NODE_MODULES: true - steps: - - uses: actions/checkout@v3 - with: - ref: next - - uses: actions/setup-node@v3 - with: - node-version-file: '.nvmrc' - - name: Setup git user - run: | - git config --global user.name "Storybook Bot" - git config --global user.email "bot@storybook.js.org" - - name: Install dependencies - run: | - cd ./scripts - node --experimental-modules ./check-dependencies.js - cd .. - - name: Compile Storybook libraries - run: yarn task --task compile --start-from=auto --no-link - - name: Publishing to local registry - run: yarn local-registry --publish - working-directory: ./code - - name: Running local registry - run: yarn local-registry --open & - working-directory: ./code - - name: Wait for registry - run: yarn wait-on tcp:127.0.0.1:6001 - working-directory: ./code - - name: Generate - run: yarn generate-sandboxes --local-registry --debug - working-directory: ./code - - name: Publish - run: yarn publish-sandboxes --remote=https://storybook-bot:${{ secrets.PAT_STORYBOOK_BOT}}@github.com/storybookjs/sandboxes.git --push --branch=next - working-directory: ./code - - name: The job has failed - if: ${{ failure() || cancelled() }} - env: - DISCORD_WEBHOOK: ${{ secrets.DISCORD_MONITORING_URL }} - uses: Ilshidur/action-discord@master - with: - args: 'The generation of sandboxes in the **next** branch has failed. [View Run](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }})' diff --git a/.github/workflows/generate-sandboxes.yml b/.github/workflows/generate-sandboxes.yml index 942ad7527d42..8c1af15b40ad 100644 --- a/.github/workflows/generate-sandboxes.yml +++ b/.github/workflows/generate-sandboxes.yml @@ -13,6 +13,14 @@ on: # 3. Comment out the whole "generate-main" job starting at line 26 # 3. ๐Ÿ‘‰ DON'T FORGET TO UNDO STEP 2 AND 3 BEFORE YOU MERGE YOUR CHANGES! +env: + YARN_ENABLE_IMMUTABLE_INSTALLS: "false" + CLEANUP_SANDBOX_NODE_MODULES: "true" + +defaults: + run: + working-directory: ./code + jobs: generate-next: name: Generate to next @@ -21,21 +29,42 @@ jobs: - uses: actions/checkout@v4 with: ref: jeppe/25922-ci-generation-of-sandboxes-fail-sometimes-on-prereleases - - uses: ./.github/actions/generate-sandboxes-composite-action + + - uses: actions/setup-node@v4 + with: + node-version-file: ".nvmrc" + + - name: Setup git user + run: | + git config --global user.name "storybook-bot" + git config --global user.email "32066757+storybook-bot@users.noreply.github.com" + + - name: Install dependencies + working-directory: ./scripts + run: node --experimental-modules ./check-dependencies.js + + - name: Compile Storybook libraries + run: yarn task --task compile --start-from=auto --no-link + + - name: Publish to local registry + run: yarn local-registry --publish + + - name: Run local registry + run: yarn local-registry --open & + + - name: Wait for registry + run: yarn wait-on tcp:127.0.0.1:6001 + + - name: Generate + run: yarn generate-sandboxes --local-registry + + - name: Publish + run: yarn publish-sandboxes --remote=https://storybook-bot:${{ secrets.PAT_STORYBOOK_BOT }}@github.com/storybookjs/sandboxes.git --push --branch=next + + - name: The job has failed + if: ${{ failure() || cancelled() }} + env: + DISCORD_WEBHOOK: ${{ secrets.DISCORD_MONITORING_URL }} + uses: Ilshidur/action-discord@master with: - destination-branch: next - token: ${{ secrets.PAT_STORYBOOK_BOT }} - discord-url: ${{ secrets.DISCORD_MONITORING_URL }} - - # generate-main: - # name: Generate to main - # runs-on: ubuntu-latest - # steps: - # - uses: actions/checkout@v4 - # with: - # ref: main - # - uses: ./.github/actions/generate-sandboxes-composite-action - # with: - # destination-branch: main - # token: ${{ secrets.PAT_STORYBOOK_BOT }} - # discord-url: ${{ secrets.DISCORD_MONITORING_URL }} + args: "The generation of sandboxes on the **next** branch has failed. [View Run](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }})" From f1846015d018d27302942cc94a988db56c8f8ba1 Mon Sep 17 00:00:00 2001 From: Jeppe Reinhold Date: Sat, 10 Feb 2024 00:09:13 +0100 Subject: [PATCH 008/132] Continue with publishing even if some sandboxes fail --- .github/workflows/generate-sandboxes.yml | 17 +++++-- scripts/sandbox/generate.ts | 57 +++++++++++++++++------- 2 files changed, 55 insertions(+), 19 deletions(-) diff --git a/.github/workflows/generate-sandboxes.yml b/.github/workflows/generate-sandboxes.yml index 8c1af15b40ad..643361e63143 100644 --- a/.github/workflows/generate-sandboxes.yml +++ b/.github/workflows/generate-sandboxes.yml @@ -1,4 +1,4 @@ -name: Generate and push sandboxes +name: Generate and publish sandboxes on: schedule: @@ -56,15 +56,24 @@ jobs: run: yarn wait-on tcp:127.0.0.1:6001 - name: Generate + id: generate run: yarn generate-sandboxes --local-registry - name: Publish + # publish sandboxes even if the generation fails, as some sandboxes might have been generated successfully + if: !cancelled() run: yarn publish-sandboxes --remote=https://storybook-bot:${{ secrets.PAT_STORYBOOK_BOT }}@github.com/storybookjs/sandboxes.git --push --branch=next - - name: The job has failed - if: ${{ failure() || cancelled() }} + - name: Report failure to Discord + if: failure() env: DISCORD_WEBHOOK: ${{ secrets.DISCORD_MONITORING_URL }} uses: Ilshidur/action-discord@master with: - args: "The generation of sandboxes on the **next** branch has failed. [View Run](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }})" + args: | + The generation of some or all sandboxes on the **next** branch has failed. + [View Job](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}/job/${{ github.job }}) + + ${{ steps.generate.outputs.failed-before-script-templates && format('The following templates failed to execute the before script:\n- {0}', steps.generate.outputs.failed-before-script-templates) || '' }} + + ${{ steps.generate.outputs.failed-before-script-templates && format('The following templates failed to initialize Storybook:\n- {0}', steps.generate.outputs.failed-init-templates) || '' }} diff --git a/scripts/sandbox/generate.ts b/scripts/sandbox/generate.ts index 27f17f8c7ad0..969247d6ba1d 100755 --- a/scripts/sandbox/generate.ts +++ b/scripts/sandbox/generate.ts @@ -27,6 +27,7 @@ import { REPROS_DIRECTORY, LOCAL_REGISTRY_URL, } from '../utils/constants'; +import { setOutput } from '@actions/core'; const sbInit = async ( cwd: string, @@ -148,7 +149,10 @@ const runGenerators = async ( const limit = pLimit(1); - await Promise.all( + const failedBeforeScriptTemplates: string[] = []; + const failedInitTemplates: string[] = []; + + await Promise.allSettled( generators.map(({ dirName, name, script, expected, env }) => limit(async () => { let flags: string[] = []; @@ -173,19 +177,26 @@ const runGenerators = async ( // Some tools refuse to run inside an existing directory and replace the contents, // where as others are very picky about what directories can be called. So we need to // handle different modes of operation. - if (script.includes('{{beforeDir}}')) { - const scriptWithBeforeDir = script.replaceAll('{{beforeDir}}', BEFORE_DIR_NAME); - await runCommand( - scriptWithBeforeDir, - { - cwd: createBaseDir, - timeout: SCRIPT_TIMEOUT, - }, - debug - ); - } else { - await ensureDir(createBeforeDir); - await runCommand(script, { cwd: createBeforeDir, timeout: SCRIPT_TIMEOUT }, debug); + try { + if (script.includes('{{beforeDir}}')) { + const scriptWithBeforeDir = script.replaceAll('{{beforeDir}}', BEFORE_DIR_NAME); + await runCommand( + scriptWithBeforeDir, + { + cwd: createBaseDir, + timeout: SCRIPT_TIMEOUT, + }, + debug + ); + } else { + await ensureDir(createBeforeDir); + await runCommand(script, { cwd: createBeforeDir, timeout: SCRIPT_TIMEOUT }, debug); + } + } catch (error) { + console.error(`โŒ Failed to execute before-script for template: ${name}`); + console.error(error); + failedBeforeScriptTemplates.push(name); + return; } await localizeYarnConfigFiles(createBaseDir, createBeforeDir); @@ -196,7 +207,14 @@ const runGenerators = async ( // Make sure there are no git projects in the folder await remove(join(beforeDir, '.git')); - await addStorybook({ baseDir, localRegistry, flags, debug, env }); + try { + await addStorybook({ baseDir, localRegistry, flags, debug, env }); + } catch (error) { + console.error(`โŒ Failed to add Storybook to template: ${name}`); + console.error(error); + failedInitTemplates.push(name); + return; + } await addDocumentation(baseDir, { name, dirName }); @@ -218,6 +236,15 @@ const runGenerators = async ( }) ) ); + + if (process.env.GITHUB_ACTIONS === 'true') { + if (failedBeforeScriptTemplates.length > 0) { + setOutput('failed-before-script-templates', failedBeforeScriptTemplates.join('\n- ')); + } + if (failedInitTemplates.length > 0) { + setOutput('failed-init-templates', failedInitTemplates.join('\n- ')); + } + } }; export const options = createOptions({ From 86c58958146617d044748cdd97f0a4dcb190da7c Mon Sep 17 00:00:00 2001 From: Jeppe Reinhold Date: Sat, 10 Feb 2024 00:20:35 +0100 Subject: [PATCH 009/132] =?UTF-8?q?Yet=20Another=20Maddening=20Language?= =?UTF-8?q?=E2=84=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/generate-sandboxes.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/generate-sandboxes.yml b/.github/workflows/generate-sandboxes.yml index 643361e63143..339e6eb9d0c8 100644 --- a/.github/workflows/generate-sandboxes.yml +++ b/.github/workflows/generate-sandboxes.yml @@ -61,7 +61,7 @@ jobs: - name: Publish # publish sandboxes even if the generation fails, as some sandboxes might have been generated successfully - if: !cancelled() + if: ${{ !cancelled() }} run: yarn publish-sandboxes --remote=https://storybook-bot:${{ secrets.PAT_STORYBOOK_BOT }}@github.com/storybookjs/sandboxes.git --push --branch=next - name: Report failure to Discord From 11222151b69819c9d7e1cdd049b61f24cfccb3f3 Mon Sep 17 00:00:00 2001 From: Jeppe Reinhold Date: Sat, 10 Feb 2024 00:23:02 +0100 Subject: [PATCH 010/132] randomly cause generation failures --- scripts/sandbox/generate.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/scripts/sandbox/generate.ts b/scripts/sandbox/generate.ts index 969247d6ba1d..ee0b952175a6 100755 --- a/scripts/sandbox/generate.ts +++ b/scripts/sandbox/generate.ts @@ -81,6 +81,9 @@ const addStorybook = async ({ const tmpDir = directory(); try { + if (Math.random() < 0.2) { + throw new Error('Blip Bloop random error in addStorybook'); + } await copy(beforeDir, tmpDir); const packageManager = JsPackageManagerFactory.getPackageManager({ force: 'yarn1' }, tmpDir); @@ -178,6 +181,9 @@ const runGenerators = async ( // where as others are very picky about what directories can be called. So we need to // handle different modes of operation. try { + if (Math.random() < 0.2) { + throw new Error('Blip Bloop random error when executing before-script'); + } if (script.includes('{{beforeDir}}')) { const scriptWithBeforeDir = script.replaceAll('{{beforeDir}}', BEFORE_DIR_NAME); await runCommand( From 78f122caed653f9e3a38b732a779d1eefba1696c Mon Sep 17 00:00:00 2001 From: Jeppe Reinhold Date: Mon, 12 Feb 2024 12:22:01 +0100 Subject: [PATCH 011/132] simplify error handling, rethrow errors --- .github/workflows/generate-sandboxes.yml | 6 +- scripts/sandbox/generate.ts | 218 ++++++++++++++--------- 2 files changed, 136 insertions(+), 88 deletions(-) diff --git a/.github/workflows/generate-sandboxes.yml b/.github/workflows/generate-sandboxes.yml index 339e6eb9d0c8..a7d1ded22573 100644 --- a/.github/workflows/generate-sandboxes.yml +++ b/.github/workflows/generate-sandboxes.yml @@ -72,8 +72,4 @@ jobs: with: args: | The generation of some or all sandboxes on the **next** branch has failed. - [View Job](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}/job/${{ github.job }}) - - ${{ steps.generate.outputs.failed-before-script-templates && format('The following templates failed to execute the before script:\n- {0}', steps.generate.outputs.failed-before-script-templates) || '' }} - - ${{ steps.generate.outputs.failed-before-script-templates && format('The following templates failed to initialize Storybook:\n- {0}', steps.generate.outputs.failed-init-templates) || '' }} + [See the job summary for details](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}/job/${{ github.job }}) diff --git a/scripts/sandbox/generate.ts b/scripts/sandbox/generate.ts index ee0b952175a6..510b34b9a2b6 100755 --- a/scripts/sandbox/generate.ts +++ b/scripts/sandbox/generate.ts @@ -27,7 +27,14 @@ import { REPROS_DIRECTORY, LOCAL_REGISTRY_URL, } from '../utils/constants'; -import { setOutput } from '@actions/core'; +import * as ghActions from '@actions/core'; + +const isCI = process.env.GITHUB_ACTIONS === 'true'; + +const logError = isCI ? ghActions.error : console.error; + +class BeforeScriptExecutionError extends Error {} +class StorybookInitError extends Error {} const sbInit = async ( cwd: string, @@ -152,105 +159,150 @@ const runGenerators = async ( const limit = pLimit(1); - const failedBeforeScriptTemplates: string[] = []; - const failedInitTemplates: string[] = []; - - await Promise.allSettled( + const generationResults = await Promise.allSettled( generators.map(({ dirName, name, script, expected, env }) => limit(async () => { - let flags: string[] = []; - if (expected.renderer === '@storybook/html') flags = ['--type html']; - else if (expected.renderer === '@storybook/server') flags = ['--type server']; - - const time = process.hrtime(); - console.log(`๐Ÿงฌ Generating ${name}`); + try { + if (isCI) { + ghActions.startGroup(`Generating sandbox for ${name}`); + } - const baseDir = join(REPROS_DIRECTORY, dirName); - const beforeDir = join(baseDir, BEFORE_DIR_NAME); - await emptyDir(baseDir); + let flags: string[] = []; + if (expected.renderer === '@storybook/html') flags = ['--type html']; + else if (expected.renderer === '@storybook/server') flags = ['--type server']; - // We do the creation inside a temp dir to avoid yarn container problems - const createBaseDir = directory(); - if (!script.includes('pnp')) { - await setupYarn({ cwd: createBaseDir }); - } + const time = process.hrtime(); + console.log(`๐Ÿงฌ Generating ${name}`); - const createBeforeDir = join(createBaseDir, BEFORE_DIR_NAME); + const baseDir = join(REPROS_DIRECTORY, dirName); + const beforeDir = join(baseDir, BEFORE_DIR_NAME); + await emptyDir(baseDir); - // Some tools refuse to run inside an existing directory and replace the contents, - // where as others are very picky about what directories can be called. So we need to - // handle different modes of operation. - try { - if (Math.random() < 0.2) { - throw new Error('Blip Bloop random error when executing before-script'); + // We do the creation inside a temp dir to avoid yarn container problems + const createBaseDir = directory(); + if (!script.includes('pnp')) { + await setupYarn({ cwd: createBaseDir }); } - if (script.includes('{{beforeDir}}')) { - const scriptWithBeforeDir = script.replaceAll('{{beforeDir}}', BEFORE_DIR_NAME); - await runCommand( - scriptWithBeforeDir, - { - cwd: createBaseDir, - timeout: SCRIPT_TIMEOUT, - }, - debug - ); - } else { - await ensureDir(createBeforeDir); - await runCommand(script, { cwd: createBeforeDir, timeout: SCRIPT_TIMEOUT }, debug); - } - } catch (error) { - console.error(`โŒ Failed to execute before-script for template: ${name}`); - console.error(error); - failedBeforeScriptTemplates.push(name); - return; - } - await localizeYarnConfigFiles(createBaseDir, createBeforeDir); - - // Now move the created before dir into it's final location and add storybook - await move(createBeforeDir, beforeDir); + const createBeforeDir = join(createBaseDir, BEFORE_DIR_NAME); + + // Some tools refuse to run inside an existing directory and replace the contents, + // where as others are very picky about what directories can be called. So we need to + // handle different modes of operation. + try { + if (Math.random() < 0.4) { + throw new Error('Blip Bloop random error when executing before-script'); + } + if (script.includes('{{beforeDir}}')) { + const scriptWithBeforeDir = script.replaceAll('{{beforeDir}}', BEFORE_DIR_NAME); + await runCommand( + scriptWithBeforeDir, + { + cwd: createBaseDir, + timeout: SCRIPT_TIMEOUT, + }, + debug + ); + } else { + await ensureDir(createBeforeDir); + await runCommand(script, { cwd: createBeforeDir, timeout: SCRIPT_TIMEOUT }, debug); + } + } catch (error) { + const message = `โŒ Failed to execute before-script for template: ${name}`; + logError(message); + logError(error); + logError((error as any).stack); + throw new BeforeScriptExecutionError(message, { cause: error }); + } - // Make sure there are no git projects in the folder - await remove(join(beforeDir, '.git')); + await localizeYarnConfigFiles(createBaseDir, createBeforeDir); + + // Now move the created before dir into it's final location and add storybook + await move(createBeforeDir, beforeDir); + + // Make sure there are no git projects in the folder + await remove(join(beforeDir, '.git')); + + try { + if (Math.random() < 0.4) { + throw new Error('Blip Bloop random error when init storybook'); + } + await addStorybook({ baseDir, localRegistry, flags, debug, env }); + } catch (error) { + const message = `โŒ Failed to initialize Storybook in template: ${name}`; + logError(message); + logError(error); + logError((error as any).stack); + throw new StorybookInitError(message, { + cause: error, + }); + } + if (Math.random() < 0.4) { + throw new Error('Blip Bloop random error anywhere'); + } + await addDocumentation(baseDir, { name, dirName }); + + // Remove node_modules to save space and avoid GH actions failing + // They're not uploaded to the git sandboxes repo anyway + if (process.env.CLEANUP_SANDBOX_NODE_MODULES) { + console.log(`๐Ÿ—‘๏ธ Removing ${join(beforeDir, 'node_modules')}`); + await remove(join(beforeDir, 'node_modules')); + console.log(`๐Ÿ—‘๏ธ Removing ${join(baseDir, AFTER_DIR_NAME, 'node_modules')}`); + await remove(join(baseDir, AFTER_DIR_NAME, 'node_modules')); + } - try { - await addStorybook({ baseDir, localRegistry, flags, debug, env }); + console.log( + `โœ… Created ${dirName} in ./${relative( + process.cwd(), + baseDir + )} successfully in ${prettyTime(process.hrtime(time))}` + ); } catch (error) { - console.error(`โŒ Failed to add Storybook to template: ${name}`); - console.error(error); - failedInitTemplates.push(name); - return; - } - - await addDocumentation(baseDir, { name, dirName }); - - // Remove node_modules to save space and avoid GH actions failing - // They're not uploaded to the git sandboxes repo anyway - if (process.env.CLEANUP_SANDBOX_NODE_MODULES) { - console.log(`๐Ÿ—‘๏ธ Removing ${join(beforeDir, 'node_modules')}`); - await remove(join(beforeDir, 'node_modules')); - console.log(`๐Ÿ—‘๏ธ Removing ${join(baseDir, AFTER_DIR_NAME, 'node_modules')}`); - await remove(join(baseDir, AFTER_DIR_NAME, 'node_modules')); + throw error; + } finally { + if (isCI) { + ghActions.endGroup(); + } } - - console.log( - `โœ… Created ${dirName} in ./${relative( - process.cwd(), - baseDir - )} successfully in ${prettyTime(process.hrtime(time))}` - ); }) ) ); - if (process.env.GITHUB_ACTIONS === 'true') { - if (failedBeforeScriptTemplates.length > 0) { - setOutput('failed-before-script-templates', failedBeforeScriptTemplates.join('\n- ')); - } - if (failedInitTemplates.length > 0) { - setOutput('failed-init-templates', failedInitTemplates.join('\n- ')); - } + ghActions.summary.addHeading('Sandbox generation summary'); + + if (!generationResults.some((result) => result.status === 'rejected')) { + await ghActions.summary.addRaw('โœ… Success!').write(); + return; + } + + if (isCI) { + await ghActions.summary + .addRaw('Some sandboxes failed, see the action log for details') + .addTable([ + [ + { data: 'Template', header: true }, + { data: 'Result', header: true }, + ], + ...generationResults.map((result, index) => { + const template = generators[index].name; + if (result.status === 'fulfilled') { + return [template, '๐ŸŸข Pass']; + } + const generationError = (result as PromiseRejectedResult).reason as Error; + const errorCause = generationError.cause; + if (errorCause instanceof BeforeScriptExecutionError) { + return [template, '๐Ÿ”ด Failed to execute before script']; + } else if (errorCause instanceof StorybookInitError) { + return [template, '๐Ÿ”ด Failed to initialize Storybook']; + } else { + return [template, '๐Ÿ”ด Failed with unknown error']; + } + }), + ]) + .write(); } + + throw new Error(`Some sandboxes failed to generate`); }; export const options = createOptions({ From b7eb43338b28f7f24fd7190d92c70de41c04ce3b Mon Sep 17 00:00:00 2001 From: Jeppe Reinhold Date: Mon, 12 Feb 2024 13:02:17 +0100 Subject: [PATCH 012/132] fix error logging and summary generation --- .github/workflows/generate-sandboxes.yml | 2 +- scripts/sandbox/generate.ts | 45 +++++++++++++----------- 2 files changed, 25 insertions(+), 22 deletions(-) diff --git a/.github/workflows/generate-sandboxes.yml b/.github/workflows/generate-sandboxes.yml index a7d1ded22573..b3a875bcfb00 100644 --- a/.github/workflows/generate-sandboxes.yml +++ b/.github/workflows/generate-sandboxes.yml @@ -72,4 +72,4 @@ jobs: with: args: | The generation of some or all sandboxes on the **next** branch has failed. - [See the job summary for details](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}/job/${{ github.job }}) + [See the job summary for details](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}) diff --git a/scripts/sandbox/generate.ts b/scripts/sandbox/generate.ts index 510b34b9a2b6..85a296f71f30 100755 --- a/scripts/sandbox/generate.ts +++ b/scripts/sandbox/generate.ts @@ -28,11 +28,10 @@ import { LOCAL_REGISTRY_URL, } from '../utils/constants'; import * as ghActions from '@actions/core'; +import dedent from 'ts-dedent'; const isCI = process.env.GITHUB_ACTIONS === 'true'; -const logError = isCI ? ghActions.error : console.error; - class BeforeScriptExecutionError extends Error {} class StorybookInitError extends Error {} @@ -164,7 +163,7 @@ const runGenerators = async ( limit(async () => { try { if (isCI) { - ghActions.startGroup(`Generating sandbox for ${name}`); + ghActions.startGroup(`${name} (${dirName})`); } let flags: string[] = []; @@ -208,10 +207,12 @@ const runGenerators = async ( await runCommand(script, { cwd: createBeforeDir, timeout: SCRIPT_TIMEOUT }, debug); } } catch (error) { - const message = `โŒ Failed to execute before-script for template: ${name}`; - logError(message); - logError(error); - logError((error as any).stack); + const message = `โŒ Failed to execute before-script for template: ${name} (${dirName})`; + if (isCI) { + ghActions.error(dedent`${message} + ${(error as any).stack}`); + } + console.error(error); throw new BeforeScriptExecutionError(message, { cause: error }); } @@ -229,10 +230,12 @@ const runGenerators = async ( } await addStorybook({ baseDir, localRegistry, flags, debug, env }); } catch (error) { - const message = `โŒ Failed to initialize Storybook in template: ${name}`; - logError(message); - logError(error); - logError((error as any).stack); + const message = `โŒ Failed to initialize Storybook in template: ${name} (${dirName})`; + if (isCI) { + ghActions.error(dedent`${message} + ${(error as any).stack}`); + } + console.error(error); throw new StorybookInitError(message, { cause: error, }); @@ -277,25 +280,25 @@ const runGenerators = async ( if (isCI) { await ghActions.summary - .addRaw('Some sandboxes failed, see the action log for details') + .addRaw('Some sandboxes failed, see the job log for detailed errors') .addTable([ [ - { data: 'Template', header: true }, + { data: 'Name', header: true }, + { data: 'Key', header: true }, { data: 'Result', header: true }, ], ...generationResults.map((result, index) => { - const template = generators[index].name; + const { name, dirName } = generators[index]; if (result.status === 'fulfilled') { - return [template, '๐ŸŸข Pass']; + return [name, dirName, '๐ŸŸข Pass']; } const generationError = (result as PromiseRejectedResult).reason as Error; - const errorCause = generationError.cause; - if (errorCause instanceof BeforeScriptExecutionError) { - return [template, '๐Ÿ”ด Failed to execute before script']; - } else if (errorCause instanceof StorybookInitError) { - return [template, '๐Ÿ”ด Failed to initialize Storybook']; + if (generationError instanceof BeforeScriptExecutionError) { + return [name, dirName, '๐Ÿ”ด Failed to execute before script']; + } else if (generationError instanceof StorybookInitError) { + return [name, dirName, '๐Ÿ”ด Failed to initialize Storybook']; } else { - return [template, '๐Ÿ”ด Failed with unknown error']; + return [name, dirName, '๐Ÿ”ด Failed with unknown error']; } }), ]) From c9e9d6242536edb2b7359671455dcc1af46e94f7 Mon Sep 17 00:00:00 2001 From: Jeppe Reinhold Date: Mon, 12 Feb 2024 13:23:09 +0100 Subject: [PATCH 013/132] fix double error logging --- scripts/sandbox/generate.ts | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/scripts/sandbox/generate.ts b/scripts/sandbox/generate.ts index 85a296f71f30..a3c88eb4eb5c 100755 --- a/scripts/sandbox/generate.ts +++ b/scripts/sandbox/generate.ts @@ -189,7 +189,7 @@ const runGenerators = async ( // where as others are very picky about what directories can be called. So we need to // handle different modes of operation. try { - if (Math.random() < 0.4) { + if (Math.random() < 0.2) { throw new Error('Blip Bloop random error when executing before-script'); } if (script.includes('{{beforeDir}}')) { @@ -211,8 +211,10 @@ const runGenerators = async ( if (isCI) { ghActions.error(dedent`${message} ${(error as any).stack}`); + } else { + console.error(message); + console.error(error); } - console.error(error); throw new BeforeScriptExecutionError(message, { cause: error }); } @@ -225,7 +227,7 @@ const runGenerators = async ( await remove(join(beforeDir, '.git')); try { - if (Math.random() < 0.4) { + if (Math.random() < 0.2) { throw new Error('Blip Bloop random error when init storybook'); } await addStorybook({ baseDir, localRegistry, flags, debug, env }); @@ -234,8 +236,10 @@ const runGenerators = async ( if (isCI) { ghActions.error(dedent`${message} ${(error as any).stack}`); + } else { + console.error(message); + console.error(error); } - console.error(error); throw new StorybookInitError(message, { cause: error, }); @@ -366,7 +370,7 @@ if (esMain(import.meta.url)) { .action((optionValues) => { generate(optionValues) .catch((e) => { - console.trace(e); + console.error(e); process.exit(1); }) .then(() => { From 57cbc5ece4f192a09e0a20591cbfc268db0b11b8 Mon Sep 17 00:00:00 2001 From: Jeppe Reinhold Date: Mon, 12 Feb 2024 14:25:01 +0100 Subject: [PATCH 014/132] support partial publishing to sandboxes repo --- .github/workflows/generate-sandboxes.yml | 2 +- scripts/sandbox/generate.ts | 6 +++--- scripts/sandbox/publish.ts | 27 +++++++++++++++--------- 3 files changed, 21 insertions(+), 14 deletions(-) diff --git a/.github/workflows/generate-sandboxes.yml b/.github/workflows/generate-sandboxes.yml index b3a875bcfb00..774cd297c571 100644 --- a/.github/workflows/generate-sandboxes.yml +++ b/.github/workflows/generate-sandboxes.yml @@ -62,7 +62,7 @@ jobs: - name: Publish # publish sandboxes even if the generation fails, as some sandboxes might have been generated successfully if: ${{ !cancelled() }} - run: yarn publish-sandboxes --remote=https://storybook-bot:${{ secrets.PAT_STORYBOOK_BOT }}@github.com/storybookjs/sandboxes.git --push --branch=next + run: yarn publish-sandboxes --remote=https://storybook-bot:${{ secrets.PAT_STORYBOOK_BOT }}@github.com/storybookjs/sandboxes.git --push --branch=jeppe/experiment-partial-generation - name: Report failure to Discord if: failure() diff --git a/scripts/sandbox/generate.ts b/scripts/sandbox/generate.ts index a3c88eb4eb5c..dd77b4ee8574 100755 --- a/scripts/sandbox/generate.ts +++ b/scripts/sandbox/generate.ts @@ -189,7 +189,7 @@ const runGenerators = async ( // where as others are very picky about what directories can be called. So we need to // handle different modes of operation. try { - if (Math.random() < 0.2) { + if (Math.random() < 0.6) { throw new Error('Blip Bloop random error when executing before-script'); } if (script.includes('{{beforeDir}}')) { @@ -227,7 +227,7 @@ const runGenerators = async ( await remove(join(beforeDir, '.git')); try { - if (Math.random() < 0.2) { + if (Math.random() < 0.6) { throw new Error('Blip Bloop random error when init storybook'); } await addStorybook({ baseDir, localRegistry, flags, debug, env }); @@ -244,7 +244,7 @@ const runGenerators = async ( cause: error, }); } - if (Math.random() < 0.4) { + if (Math.random() < 0.6) { throw new Error('Blip Bloop random error anywhere'); } await addDocumentation(baseDir, { name, dirName }); diff --git a/scripts/sandbox/publish.ts b/scripts/sandbox/publish.ts index e4307690efdd..99323c3a2420 100755 --- a/scripts/sandbox/publish.ts +++ b/scripts/sandbox/publish.ts @@ -1,14 +1,15 @@ import program from 'commander'; -import { join } from 'path'; +import { join, relative } from 'path'; import { existsSync } from 'fs'; import * as tempy from 'tempy'; -import { copy, emptyDir, readdir, remove, stat, writeFile } from 'fs-extra'; +import { copy, emptyDir, remove, writeFile } from 'fs-extra'; import { execaCommand } from 'execa'; import { getTemplatesData, renderTemplate } from './utils/template'; // eslint-disable-next-line import/no-cycle import { commitAllToGit } from './utils/git'; import { REPROS_DIRECTORY } from '../utils/constants'; +import { glob } from 'glob'; export const logger = console; @@ -31,15 +32,21 @@ const publish = async (options: PublishOptions & { tmpFolder: string }) => { // otherwise old files will stick around and result inconsistent states logger.log(`๐Ÿ—‘ Delete existing template dirs from clone`); - const files = await Promise.all( - ( - await readdir(REPROS_DIRECTORY) - ).map(async (f) => ({ path: f, stats: await stat(join(REPROS_DIRECTORY, f)) })) - ); + + // empty all existing directories for sandboxes that have a successful after-storybook directory await Promise.all( - files - .filter(({ stats, path }) => stats.isDirectory && !path.startsWith('.')) - .map(async ({ path }) => emptyDir(join(tmpFolder, path))) + // find all successfully generated after-storybook directories + // eg. /home/repros/react-vite/default-ts/after-storybook + (await glob(join(REPROS_DIRECTORY, '**', 'after-storybook'))).map((dir) => { + // get their path relative to the source 'repros' directory + // eg. ./react-vite/default-ts/after-storybook + const pathRelativeToSource = relative(REPROS_DIRECTORY, dir); + // get the actual path to the corresponding sandbox directory in the clone + // eg. /home/sandboxes-clone/react-vite/default-ts + const sandboxDirectoryToEmpty = join(tmpFolder, pathRelativeToSource, '..'); + console.log({ pathRelativeToSource, sandboxDirectoryToEmpty }); + return emptyDir(sandboxDirectoryToEmpty); + }) ); logger.log(`๐Ÿšš Moving template files into the repository`); From 1e8eaa4583a1727599e8c7bb5153c309ac101937 Mon Sep 17 00:00:00 2001 From: Jeppe Reinhold Date: Tue, 13 Feb 2024 09:49:09 +0100 Subject: [PATCH 015/132] publish based on the presence of a README.md --- scripts/sandbox/publish.ts | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/scripts/sandbox/publish.ts b/scripts/sandbox/publish.ts index 99323c3a2420..fc5d6b6db5a6 100755 --- a/scripts/sandbox/publish.ts +++ b/scripts/sandbox/publish.ts @@ -1,5 +1,5 @@ import program from 'commander'; -import { join, relative } from 'path'; +import { dirname, join, relative } from 'path'; import { existsSync } from 'fs'; import * as tempy from 'tempy'; import { copy, emptyDir, remove, writeFile } from 'fs-extra'; @@ -35,16 +35,16 @@ const publish = async (options: PublishOptions & { tmpFolder: string }) => { // empty all existing directories for sandboxes that have a successful after-storybook directory await Promise.all( - // find all successfully generated after-storybook directories - // eg. /home/repros/react-vite/default-ts/after-storybook - (await glob(join(REPROS_DIRECTORY, '**', 'after-storybook'))).map((dir) => { - // get their path relative to the source 'repros' directory + // find all successfully generated after-storybook/README.md files + // eg. /home/repros/react-vite/default-ts/after-storybook/README.md + // README.md being the last fil generated, thus representing a successful generation + (await glob(join(REPROS_DIRECTORY, '**', 'after-storybook/README.md'))).map((readmePath) => { + // get the after-storybook path relative to the source 'repros' directory // eg. ./react-vite/default-ts/after-storybook - const pathRelativeToSource = relative(REPROS_DIRECTORY, dir); + const pathRelativeToSource = relative(REPROS_DIRECTORY, dirname(readmePath)); // get the actual path to the corresponding sandbox directory in the clone // eg. /home/sandboxes-clone/react-vite/default-ts const sandboxDirectoryToEmpty = join(tmpFolder, pathRelativeToSource, '..'); - console.log({ pathRelativeToSource, sandboxDirectoryToEmpty }); return emptyDir(sandboxDirectoryToEmpty); }) ); From fce6818d61b1e21d9235625e19def339c2ae04fa Mon Sep 17 00:00:00 2001 From: Jeppe Reinhold Date: Tue, 13 Feb 2024 09:49:36 +0100 Subject: [PATCH 016/132] lower fake error threshold --- scripts/sandbox/generate.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/sandbox/generate.ts b/scripts/sandbox/generate.ts index dd77b4ee8574..91a4fd2fccd5 100755 --- a/scripts/sandbox/generate.ts +++ b/scripts/sandbox/generate.ts @@ -189,7 +189,7 @@ const runGenerators = async ( // where as others are very picky about what directories can be called. So we need to // handle different modes of operation. try { - if (Math.random() < 0.6) { + if (Math.random() < 0.2) { throw new Error('Blip Bloop random error when executing before-script'); } if (script.includes('{{beforeDir}}')) { @@ -227,7 +227,7 @@ const runGenerators = async ( await remove(join(beforeDir, '.git')); try { - if (Math.random() < 0.6) { + if (Math.random() < 0.2) { throw new Error('Blip Bloop random error when init storybook'); } await addStorybook({ baseDir, localRegistry, flags, debug, env }); @@ -244,7 +244,7 @@ const runGenerators = async ( cause: error, }); } - if (Math.random() < 0.6) { + if (Math.random() < 0.2) { throw new Error('Blip Bloop random error anywhere'); } await addDocumentation(baseDir, { name, dirName }); From 6b1be49c6b807939b6a940c0cf00b6ab7b7d6461 Mon Sep 17 00:00:00 2001 From: Jeppe Reinhold Date: Tue, 13 Feb 2024 09:50:19 +0100 Subject: [PATCH 017/132] remove fake errors --- scripts/sandbox/generate.ts | 9 --------- 1 file changed, 9 deletions(-) diff --git a/scripts/sandbox/generate.ts b/scripts/sandbox/generate.ts index 91a4fd2fccd5..a28bbd6963f2 100755 --- a/scripts/sandbox/generate.ts +++ b/scripts/sandbox/generate.ts @@ -189,9 +189,6 @@ const runGenerators = async ( // where as others are very picky about what directories can be called. So we need to // handle different modes of operation. try { - if (Math.random() < 0.2) { - throw new Error('Blip Bloop random error when executing before-script'); - } if (script.includes('{{beforeDir}}')) { const scriptWithBeforeDir = script.replaceAll('{{beforeDir}}', BEFORE_DIR_NAME); await runCommand( @@ -227,9 +224,6 @@ const runGenerators = async ( await remove(join(beforeDir, '.git')); try { - if (Math.random() < 0.2) { - throw new Error('Blip Bloop random error when init storybook'); - } await addStorybook({ baseDir, localRegistry, flags, debug, env }); } catch (error) { const message = `โŒ Failed to initialize Storybook in template: ${name} (${dirName})`; @@ -244,9 +238,6 @@ const runGenerators = async ( cause: error, }); } - if (Math.random() < 0.2) { - throw new Error('Blip Bloop random error anywhere'); - } await addDocumentation(baseDir, { name, dirName }); // Remove node_modules to save space and avoid GH actions failing From cea38444efa47fe291fe9cfddb1b255790951f05 Mon Sep 17 00:00:00 2001 From: Jeppe Reinhold Date: Tue, 13 Feb 2024 12:31:57 +0100 Subject: [PATCH 018/132] =?UTF-8?q?actually=20remove=20fake=20errors=20?= =?UTF-8?q?=F0=9F=A4=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/sandbox/generate.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/scripts/sandbox/generate.ts b/scripts/sandbox/generate.ts index a28bbd6963f2..c313117987b5 100755 --- a/scripts/sandbox/generate.ts +++ b/scripts/sandbox/generate.ts @@ -87,9 +87,6 @@ const addStorybook = async ({ const tmpDir = directory(); try { - if (Math.random() < 0.2) { - throw new Error('Blip Bloop random error in addStorybook'); - } await copy(beforeDir, tmpDir); const packageManager = JsPackageManagerFactory.getPackageManager({ force: 'yarn1' }, tmpDir); From 1c3713eb6c54a5f66a0b55b1220b2edbfec57b5d Mon Sep 17 00:00:00 2001 From: Jeppe Reinhold Date: Tue, 13 Feb 2024 21:28:14 +0100 Subject: [PATCH 019/132] always cleanup node_modules, don't collapse sandbox logs --- scripts/sandbox/generate.ts | 42 ++++++++++++++++--------------------- 1 file changed, 18 insertions(+), 24 deletions(-) diff --git a/scripts/sandbox/generate.ts b/scripts/sandbox/generate.ts index c313117987b5..4e8f4bae1f4f 100755 --- a/scripts/sandbox/generate.ts +++ b/scripts/sandbox/generate.ts @@ -158,20 +158,15 @@ const runGenerators = async ( const generationResults = await Promise.allSettled( generators.map(({ dirName, name, script, expected, env }) => limit(async () => { + const baseDir = join(REPROS_DIRECTORY, dirName); + const beforeDir = join(baseDir, BEFORE_DIR_NAME); try { - if (isCI) { - ghActions.startGroup(`${name} (${dirName})`); - } - let flags: string[] = []; if (expected.renderer === '@storybook/html') flags = ['--type html']; else if (expected.renderer === '@storybook/server') flags = ['--type server']; const time = process.hrtime(); - console.log(`๐Ÿงฌ Generating ${name}`); - - const baseDir = join(REPROS_DIRECTORY, dirName); - const beforeDir = join(baseDir, BEFORE_DIR_NAME); + console.log(`๐Ÿงฌ Generating ${name} (${{ dirName }})`); await emptyDir(baseDir); // We do the creation inside a temp dir to avoid yarn container problems @@ -237,17 +232,8 @@ const runGenerators = async ( } await addDocumentation(baseDir, { name, dirName }); - // Remove node_modules to save space and avoid GH actions failing - // They're not uploaded to the git sandboxes repo anyway - if (process.env.CLEANUP_SANDBOX_NODE_MODULES) { - console.log(`๐Ÿ—‘๏ธ Removing ${join(beforeDir, 'node_modules')}`); - await remove(join(beforeDir, 'node_modules')); - console.log(`๐Ÿ—‘๏ธ Removing ${join(baseDir, AFTER_DIR_NAME, 'node_modules')}`); - await remove(join(baseDir, AFTER_DIR_NAME, 'node_modules')); - } - console.log( - `โœ… Created ${dirName} in ./${relative( + `โœ… Generated ${name} (${dirName}) in ./${relative( process.cwd(), baseDir )} successfully in ${prettyTime(process.hrtime(time))}` @@ -255,8 +241,13 @@ const runGenerators = async ( } catch (error) { throw error; } finally { - if (isCI) { - ghActions.endGroup(); + // Remove node_modules to save space and avoid GH actions failing + // They're not uploaded to the git sandboxes repo anyway + if (process.env.CLEANUP_SANDBOX_NODE_MODULES) { + console.log(`๐Ÿ—‘๏ธ Removing ${join(beforeDir, 'node_modules')}`); + await remove(join(beforeDir, 'node_modules')); + console.log(`๐Ÿ—‘๏ธ Removing ${join(baseDir, AFTER_DIR_NAME, 'node_modules')}`); + await remove(join(baseDir, AFTER_DIR_NAME, 'node_modules')); } } }) @@ -281,17 +272,20 @@ const runGenerators = async ( ], ...generationResults.map((result, index) => { const { name, dirName } = generators[index]; + const row = [name, `\`${dirName}\``]; if (result.status === 'fulfilled') { - return [name, dirName, '๐ŸŸข Pass']; + row.push('๐ŸŸข Pass'); + return row; } const generationError = (result as PromiseRejectedResult).reason as Error; if (generationError instanceof BeforeScriptExecutionError) { - return [name, dirName, '๐Ÿ”ด Failed to execute before script']; + row.push('๐Ÿ”ด Failed to execute before script'); } else if (generationError instanceof StorybookInitError) { - return [name, dirName, '๐Ÿ”ด Failed to initialize Storybook']; + row.push('๐Ÿ”ด Failed to initialize Storybook'); } else { - return [name, dirName, '๐Ÿ”ด Failed with unknown error']; + row.push('๐Ÿ”ด Failed with unknown error'); } + return row; }), ]) .write(); From 01962f352935bba1cd3fc7ce52873a7edc6caa6f Mon Sep 17 00:00:00 2001 From: Jeppe Reinhold Date: Tue, 13 Feb 2024 21:28:39 +0100 Subject: [PATCH 020/132] remove test variables from generate workflow, add job for main --- .github/workflows/generate-sandboxes.yml | 66 +++++++++++++++++++++--- 1 file changed, 59 insertions(+), 7 deletions(-) diff --git a/.github/workflows/generate-sandboxes.yml b/.github/workflows/generate-sandboxes.yml index 774cd297c571..88dc9e21bb41 100644 --- a/.github/workflows/generate-sandboxes.yml +++ b/.github/workflows/generate-sandboxes.yml @@ -6,12 +6,12 @@ on: workflow_dispatch: # To test fixes on push rather than wait for the scheduling, do the following: # 1. Uncomment the lines below and add your branch. - push: - branches: - - jeppe/25922-ci-generation-of-sandboxes-fail-sometimes-on-prereleases + # push: + # branches: + # - # 2. Change the "ref" value to in the actions/checkout step below. - # 3. Comment out the whole "generate-main" job starting at line 26 - # 3. ๐Ÿ‘‰ DON'T FORGET TO UNDO STEP 2 AND 3 BEFORE YOU MERGE YOUR CHANGES! + # 3. Comment out the whole "generate-main" job starting at line 77 + # 4. ๐Ÿ‘‰ DON'T FORGET TO UNDO THE STEPS BEFORE YOU MERGE YOUR CHANGES! env: YARN_ENABLE_IMMUTABLE_INSTALLS: "false" @@ -28,7 +28,7 @@ jobs: steps: - uses: actions/checkout@v4 with: - ref: jeppe/25922-ci-generation-of-sandboxes-fail-sometimes-on-prereleases + ref: next - uses: actions/setup-node@v4 with: @@ -62,7 +62,7 @@ jobs: - name: Publish # publish sandboxes even if the generation fails, as some sandboxes might have been generated successfully if: ${{ !cancelled() }} - run: yarn publish-sandboxes --remote=https://storybook-bot:${{ secrets.PAT_STORYBOOK_BOT }}@github.com/storybookjs/sandboxes.git --push --branch=jeppe/experiment-partial-generation + run: yarn publish-sandboxes --remote=https://storybook-bot:${{ secrets.PAT_STORYBOOK_BOT }}@github.com/storybookjs/sandboxes.git --push --branch=next - name: Report failure to Discord if: failure() @@ -73,3 +73,55 @@ jobs: args: | The generation of some or all sandboxes on the **next** branch has failed. [See the job summary for details](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}) + + generate-main: + name: Generate to main + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + ref: main + + - uses: actions/setup-node@v4 + with: + node-version-file: ".nvmrc" + + - name: Setup git user + run: | + git config --global user.name "storybook-bot" + git config --global user.email "32066757+storybook-bot@users.noreply.github.com" + + - name: Install dependencies + working-directory: ./scripts + run: node --experimental-modules ./check-dependencies.js + + - name: Compile Storybook libraries + run: yarn task --task compile --start-from=auto --no-link + + - name: Publish to local registry + run: yarn local-registry --publish + + - name: Run local registry + run: yarn local-registry --open & + + - name: Wait for registry + run: yarn wait-on tcp:127.0.0.1:6001 + + - name: Generate + id: generate + run: yarn generate-sandboxes --local-registry + + - name: Publish + # publish sandboxes even if the generation fails, as some sandboxes might have been generated successfully + if: ${{ !cancelled() }} + run: yarn publish-sandboxes --remote=https://storybook-bot:${{ secrets.PAT_STORYBOOK_BOT }}@github.com/storybookjs/sandboxes.git --push --branch=main + + - name: Report failure to Discord + if: failure() + env: + DISCORD_WEBHOOK: ${{ secrets.DISCORD_MONITORING_URL }} + uses: Ilshidur/action-discord@master + with: + args: | + The generation of some or all sandboxes on the **main** branch has failed. + [See the job summary for details](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}) From 43deb5f2ab9c3553daf6fccd0a4bc5ffdc76b6b5 Mon Sep 17 00:00:00 2001 From: Jeppe Reinhold Date: Tue, 13 Feb 2024 21:37:01 +0100 Subject: [PATCH 021/132] only write summary in CI --- scripts/sandbox/generate.ts | 65 ++++++++++++++++++++----------------- 1 file changed, 36 insertions(+), 29 deletions(-) diff --git a/scripts/sandbox/generate.ts b/scripts/sandbox/generate.ts index 4e8f4bae1f4f..410d49373d93 100755 --- a/scripts/sandbox/generate.ts +++ b/scripts/sandbox/generate.ts @@ -254,42 +254,49 @@ const runGenerators = async ( ) ); + const hasGenerationErrors = generationResults.some((result) => result.status === 'rejected'); + + if (!isCI) { + if (hasGenerationErrors) { + throw new Error(`Some sandboxes failed to generate`); + } + return; + } + ghActions.summary.addHeading('Sandbox generation summary'); - if (!generationResults.some((result) => result.status === 'rejected')) { + if (!hasGenerationErrors) { await ghActions.summary.addRaw('โœ… Success!').write(); return; } - if (isCI) { - await ghActions.summary - .addRaw('Some sandboxes failed, see the job log for detailed errors') - .addTable([ - [ - { data: 'Name', header: true }, - { data: 'Key', header: true }, - { data: 'Result', header: true }, - ], - ...generationResults.map((result, index) => { - const { name, dirName } = generators[index]; - const row = [name, `\`${dirName}\``]; - if (result.status === 'fulfilled') { - row.push('๐ŸŸข Pass'); - return row; - } - const generationError = (result as PromiseRejectedResult).reason as Error; - if (generationError instanceof BeforeScriptExecutionError) { - row.push('๐Ÿ”ด Failed to execute before script'); - } else if (generationError instanceof StorybookInitError) { - row.push('๐Ÿ”ด Failed to initialize Storybook'); - } else { - row.push('๐Ÿ”ด Failed with unknown error'); - } + await ghActions.summary + .addRaw('Some sandboxes failed, see the job log for detailed errors') + .addTable([ + [ + { data: 'Name', header: true }, + { data: 'Key', header: true }, + { data: 'Result', header: true }, + ], + ...generationResults.map((result, index) => { + const { name, dirName } = generators[index]; + const row = [name, `\`${dirName}\``]; + if (result.status === 'fulfilled') { + row.push('๐ŸŸข Pass'); return row; - }), - ]) - .write(); - } + } + const generationError = (result as PromiseRejectedResult).reason as Error; + if (generationError instanceof BeforeScriptExecutionError) { + row.push('๐Ÿ”ด Failed to execute before script'); + } else if (generationError instanceof StorybookInitError) { + row.push('๐Ÿ”ด Failed to initialize Storybook'); + } else { + row.push('๐Ÿ”ด Failed with unknown error'); + } + return row; + }), + ]) + .write(); throw new Error(`Some sandboxes failed to generate`); }; From d8e40ace46938dc5f22813c15d4d7266d78d6261 Mon Sep 17 00:00:00 2001 From: Jeppe Reinhold Date: Tue, 13 Feb 2024 21:45:08 +0100 Subject: [PATCH 022/132] typo --- scripts/sandbox/publish.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/sandbox/publish.ts b/scripts/sandbox/publish.ts index fc5d6b6db5a6..334e8a9177eb 100755 --- a/scripts/sandbox/publish.ts +++ b/scripts/sandbox/publish.ts @@ -37,7 +37,7 @@ const publish = async (options: PublishOptions & { tmpFolder: string }) => { await Promise.all( // find all successfully generated after-storybook/README.md files // eg. /home/repros/react-vite/default-ts/after-storybook/README.md - // README.md being the last fil generated, thus representing a successful generation + // README.md being the last file generated, thus representing a successful generation (await glob(join(REPROS_DIRECTORY, '**', 'after-storybook/README.md'))).map((readmePath) => { // get the after-storybook path relative to the source 'repros' directory // eg. ./react-vite/default-ts/after-storybook From e29d22b08707a10682234b3f950034eed4f7178f Mon Sep 17 00:00:00 2001 From: James Garbutt <43081j@users.noreply.github.com> Date: Thu, 29 Feb 2024 13:17:36 +0000 Subject: [PATCH 023/132] chore: upgrade esbuild to 0.20.1 --- code/builders/builder-manager/package.json | 2 +- code/lib/core-common/package.json | 2 +- code/package.json | 2 +- code/yarn.lock | 200 +++++++++++---------- scripts/package.json | 2 +- scripts/yarn.lock | 196 ++++++++++---------- 6 files changed, 212 insertions(+), 192 deletions(-) diff --git a/code/builders/builder-manager/package.json b/code/builders/builder-manager/package.json index 03f53e5dd368..2733705ef1cd 100644 --- a/code/builders/builder-manager/package.json +++ b/code/builders/builder-manager/package.json @@ -52,7 +52,7 @@ "@yarnpkg/esbuild-plugin-pnp": "^3.0.0-rc.10", "browser-assert": "^1.2.1", "ejs": "^3.1.8", - "esbuild": "^0.18.0", + "esbuild": "^0.20.1", "esbuild-plugin-alias": "^0.2.1", "express": "^4.17.3", "fs-extra": "^11.1.0", diff --git a/code/lib/core-common/package.json b/code/lib/core-common/package.json index c40b6c3569d8..9f74856a0af9 100644 --- a/code/lib/core-common/package.json +++ b/code/lib/core-common/package.json @@ -52,7 +52,7 @@ "@yarnpkg/libzip": "2.3.0", "chalk": "^4.1.0", "cross-spawn": "^7.0.3", - "esbuild": "^0.18.0", + "esbuild": "^0.20.1", "esbuild-register": "^3.5.0", "execa": "^5.0.0", "file-system-cache": "2.3.0", diff --git a/code/package.json b/code/package.json index 071cf4a60003..a9cb89380c79 100644 --- a/code/package.json +++ b/code/package.json @@ -80,7 +80,7 @@ "@storybook/theming": "workspace:*", "@types/node": "^18.0.0", "@vitest/expect@1.1.3": "patch:@vitest/expect@npm%3A1.1.3#~/.yarn/patches/@vitest-expect-npm-1.1.3-2062bf533f.patch", - "esbuild": "^0.18.0", + "esbuild": "^0.20.1", "playwright": "1.36.0", "playwright-core": "1.36.0", "serialize-javascript": "^3.1.0", diff --git a/code/yarn.lock b/code/yarn.lock index c0338dabe0c4..01c18ce7fef5 100644 --- a/code/yarn.lock +++ b/code/yarn.lock @@ -2583,156 +2583,163 @@ __metadata: languageName: node linkType: hard -"@esbuild/android-arm64@npm:0.18.20": - version: 0.18.20 - resolution: "@esbuild/android-arm64@npm:0.18.20" +"@esbuild/aix-ppc64@npm:0.20.1": + version: 0.20.1 + resolution: "@esbuild/aix-ppc64@npm:0.20.1" + conditions: os=aix & cpu=ppc64 + languageName: node + linkType: hard + +"@esbuild/android-arm64@npm:0.20.1": + version: 0.20.1 + resolution: "@esbuild/android-arm64@npm:0.20.1" conditions: os=android & cpu=arm64 languageName: node linkType: hard -"@esbuild/android-arm@npm:0.18.20": - version: 0.18.20 - resolution: "@esbuild/android-arm@npm:0.18.20" +"@esbuild/android-arm@npm:0.20.1": + version: 0.20.1 + resolution: "@esbuild/android-arm@npm:0.20.1" conditions: os=android & cpu=arm languageName: node linkType: hard -"@esbuild/android-x64@npm:0.18.20": - version: 0.18.20 - resolution: "@esbuild/android-x64@npm:0.18.20" +"@esbuild/android-x64@npm:0.20.1": + version: 0.20.1 + resolution: "@esbuild/android-x64@npm:0.20.1" conditions: os=android & cpu=x64 languageName: node linkType: hard -"@esbuild/darwin-arm64@npm:0.18.20": - version: 0.18.20 - resolution: "@esbuild/darwin-arm64@npm:0.18.20" +"@esbuild/darwin-arm64@npm:0.20.1": + version: 0.20.1 + resolution: "@esbuild/darwin-arm64@npm:0.20.1" conditions: os=darwin & cpu=arm64 languageName: node linkType: hard -"@esbuild/darwin-x64@npm:0.18.20": - version: 0.18.20 - resolution: "@esbuild/darwin-x64@npm:0.18.20" +"@esbuild/darwin-x64@npm:0.20.1": + version: 0.20.1 + resolution: "@esbuild/darwin-x64@npm:0.20.1" conditions: os=darwin & cpu=x64 languageName: node linkType: hard -"@esbuild/freebsd-arm64@npm:0.18.20": - version: 0.18.20 - resolution: "@esbuild/freebsd-arm64@npm:0.18.20" +"@esbuild/freebsd-arm64@npm:0.20.1": + version: 0.20.1 + resolution: "@esbuild/freebsd-arm64@npm:0.20.1" conditions: os=freebsd & cpu=arm64 languageName: node linkType: hard -"@esbuild/freebsd-x64@npm:0.18.20": - version: 0.18.20 - resolution: "@esbuild/freebsd-x64@npm:0.18.20" +"@esbuild/freebsd-x64@npm:0.20.1": + version: 0.20.1 + resolution: "@esbuild/freebsd-x64@npm:0.20.1" conditions: os=freebsd & cpu=x64 languageName: node linkType: hard -"@esbuild/linux-arm64@npm:0.18.20": - version: 0.18.20 - resolution: "@esbuild/linux-arm64@npm:0.18.20" +"@esbuild/linux-arm64@npm:0.20.1": + version: 0.20.1 + resolution: "@esbuild/linux-arm64@npm:0.20.1" conditions: os=linux & cpu=arm64 languageName: node linkType: hard -"@esbuild/linux-arm@npm:0.18.20": - version: 0.18.20 - resolution: "@esbuild/linux-arm@npm:0.18.20" +"@esbuild/linux-arm@npm:0.20.1": + version: 0.20.1 + resolution: "@esbuild/linux-arm@npm:0.20.1" conditions: os=linux & cpu=arm languageName: node linkType: hard -"@esbuild/linux-ia32@npm:0.18.20": - version: 0.18.20 - resolution: "@esbuild/linux-ia32@npm:0.18.20" +"@esbuild/linux-ia32@npm:0.20.1": + version: 0.20.1 + resolution: "@esbuild/linux-ia32@npm:0.20.1" conditions: os=linux & cpu=ia32 languageName: node linkType: hard -"@esbuild/linux-loong64@npm:0.18.20": - version: 0.18.20 - resolution: "@esbuild/linux-loong64@npm:0.18.20" +"@esbuild/linux-loong64@npm:0.20.1": + version: 0.20.1 + resolution: "@esbuild/linux-loong64@npm:0.20.1" conditions: os=linux & cpu=loong64 languageName: node linkType: hard -"@esbuild/linux-mips64el@npm:0.18.20": - version: 0.18.20 - resolution: "@esbuild/linux-mips64el@npm:0.18.20" +"@esbuild/linux-mips64el@npm:0.20.1": + version: 0.20.1 + resolution: "@esbuild/linux-mips64el@npm:0.20.1" conditions: os=linux & cpu=mips64el languageName: node linkType: hard -"@esbuild/linux-ppc64@npm:0.18.20": - version: 0.18.20 - resolution: "@esbuild/linux-ppc64@npm:0.18.20" +"@esbuild/linux-ppc64@npm:0.20.1": + version: 0.20.1 + resolution: "@esbuild/linux-ppc64@npm:0.20.1" conditions: os=linux & cpu=ppc64 languageName: node linkType: hard -"@esbuild/linux-riscv64@npm:0.18.20": - version: 0.18.20 - resolution: "@esbuild/linux-riscv64@npm:0.18.20" +"@esbuild/linux-riscv64@npm:0.20.1": + version: 0.20.1 + resolution: "@esbuild/linux-riscv64@npm:0.20.1" conditions: os=linux & cpu=riscv64 languageName: node linkType: hard -"@esbuild/linux-s390x@npm:0.18.20": - version: 0.18.20 - resolution: "@esbuild/linux-s390x@npm:0.18.20" +"@esbuild/linux-s390x@npm:0.20.1": + version: 0.20.1 + resolution: "@esbuild/linux-s390x@npm:0.20.1" conditions: os=linux & cpu=s390x languageName: node linkType: hard -"@esbuild/linux-x64@npm:0.18.20": - version: 0.18.20 - resolution: "@esbuild/linux-x64@npm:0.18.20" +"@esbuild/linux-x64@npm:0.20.1": + version: 0.20.1 + resolution: "@esbuild/linux-x64@npm:0.20.1" conditions: os=linux & cpu=x64 languageName: node linkType: hard -"@esbuild/netbsd-x64@npm:0.18.20": - version: 0.18.20 - resolution: "@esbuild/netbsd-x64@npm:0.18.20" +"@esbuild/netbsd-x64@npm:0.20.1": + version: 0.20.1 + resolution: "@esbuild/netbsd-x64@npm:0.20.1" conditions: os=netbsd & cpu=x64 languageName: node linkType: hard -"@esbuild/openbsd-x64@npm:0.18.20": - version: 0.18.20 - resolution: "@esbuild/openbsd-x64@npm:0.18.20" +"@esbuild/openbsd-x64@npm:0.20.1": + version: 0.20.1 + resolution: "@esbuild/openbsd-x64@npm:0.20.1" conditions: os=openbsd & cpu=x64 languageName: node linkType: hard -"@esbuild/sunos-x64@npm:0.18.20": - version: 0.18.20 - resolution: "@esbuild/sunos-x64@npm:0.18.20" +"@esbuild/sunos-x64@npm:0.20.1": + version: 0.20.1 + resolution: "@esbuild/sunos-x64@npm:0.20.1" conditions: os=sunos & cpu=x64 languageName: node linkType: hard -"@esbuild/win32-arm64@npm:0.18.20": - version: 0.18.20 - resolution: "@esbuild/win32-arm64@npm:0.18.20" +"@esbuild/win32-arm64@npm:0.20.1": + version: 0.20.1 + resolution: "@esbuild/win32-arm64@npm:0.20.1" conditions: os=win32 & cpu=arm64 languageName: node linkType: hard -"@esbuild/win32-ia32@npm:0.18.20": - version: 0.18.20 - resolution: "@esbuild/win32-ia32@npm:0.18.20" +"@esbuild/win32-ia32@npm:0.20.1": + version: 0.20.1 + resolution: "@esbuild/win32-ia32@npm:0.20.1" conditions: os=win32 & cpu=ia32 languageName: node linkType: hard -"@esbuild/win32-x64@npm:0.18.20": - version: 0.18.20 - resolution: "@esbuild/win32-x64@npm:0.18.20" +"@esbuild/win32-x64@npm:0.20.1": + version: 0.20.1 + resolution: "@esbuild/win32-x64@npm:0.20.1" conditions: os=win32 & cpu=x64 languageName: node linkType: hard @@ -5470,7 +5477,7 @@ __metadata: "@yarnpkg/esbuild-plugin-pnp": "npm:^3.0.0-rc.10" browser-assert: "npm:^1.2.1" ejs: "npm:^3.1.8" - esbuild: "npm:^0.18.0" + esbuild: "npm:^0.20.1" esbuild-plugin-alias: "npm:^0.2.1" express: "npm:^4.17.3" fs-extra: "npm:^11.1.0" @@ -5737,7 +5744,7 @@ __metadata: "@yarnpkg/libzip": "npm:2.3.0" chalk: "npm:^4.1.0" cross-spawn: "npm:^7.0.3" - esbuild: "npm:^0.18.0" + esbuild: "npm:^0.20.1" esbuild-register: "npm:^3.5.0" execa: "npm:^5.0.0" file-system-cache: "npm:2.3.0" @@ -14211,33 +14218,36 @@ __metadata: languageName: node linkType: hard -"esbuild@npm:^0.18.0": - version: 0.18.20 - resolution: "esbuild@npm:0.18.20" - dependencies: - "@esbuild/android-arm": "npm:0.18.20" - "@esbuild/android-arm64": "npm:0.18.20" - "@esbuild/android-x64": "npm:0.18.20" - "@esbuild/darwin-arm64": "npm:0.18.20" - "@esbuild/darwin-x64": "npm:0.18.20" - "@esbuild/freebsd-arm64": "npm:0.18.20" - "@esbuild/freebsd-x64": "npm:0.18.20" - "@esbuild/linux-arm": "npm:0.18.20" - "@esbuild/linux-arm64": "npm:0.18.20" - "@esbuild/linux-ia32": "npm:0.18.20" - "@esbuild/linux-loong64": "npm:0.18.20" - "@esbuild/linux-mips64el": "npm:0.18.20" - "@esbuild/linux-ppc64": "npm:0.18.20" - "@esbuild/linux-riscv64": "npm:0.18.20" - "@esbuild/linux-s390x": "npm:0.18.20" - "@esbuild/linux-x64": "npm:0.18.20" - "@esbuild/netbsd-x64": "npm:0.18.20" - "@esbuild/openbsd-x64": "npm:0.18.20" - "@esbuild/sunos-x64": "npm:0.18.20" - "@esbuild/win32-arm64": "npm:0.18.20" - "@esbuild/win32-ia32": "npm:0.18.20" - "@esbuild/win32-x64": "npm:0.18.20" +"esbuild@npm:^0.20.1": + version: 0.20.1 + resolution: "esbuild@npm:0.20.1" + dependencies: + "@esbuild/aix-ppc64": "npm:0.20.1" + "@esbuild/android-arm": "npm:0.20.1" + "@esbuild/android-arm64": "npm:0.20.1" + "@esbuild/android-x64": "npm:0.20.1" + "@esbuild/darwin-arm64": "npm:0.20.1" + "@esbuild/darwin-x64": "npm:0.20.1" + "@esbuild/freebsd-arm64": "npm:0.20.1" + "@esbuild/freebsd-x64": "npm:0.20.1" + "@esbuild/linux-arm": "npm:0.20.1" + "@esbuild/linux-arm64": "npm:0.20.1" + "@esbuild/linux-ia32": "npm:0.20.1" + "@esbuild/linux-loong64": "npm:0.20.1" + "@esbuild/linux-mips64el": "npm:0.20.1" + "@esbuild/linux-ppc64": "npm:0.20.1" + "@esbuild/linux-riscv64": "npm:0.20.1" + "@esbuild/linux-s390x": "npm:0.20.1" + "@esbuild/linux-x64": "npm:0.20.1" + "@esbuild/netbsd-x64": "npm:0.20.1" + "@esbuild/openbsd-x64": "npm:0.20.1" + "@esbuild/sunos-x64": "npm:0.20.1" + "@esbuild/win32-arm64": "npm:0.20.1" + "@esbuild/win32-ia32": "npm:0.20.1" + "@esbuild/win32-x64": "npm:0.20.1" dependenciesMeta: + "@esbuild/aix-ppc64": + optional: true "@esbuild/android-arm": optional: true "@esbuild/android-arm64": @@ -14284,7 +14294,7 @@ __metadata: optional: true bin: esbuild: bin/esbuild - checksum: 473b1d92842f50a303cf948a11ebd5f69581cd254d599dd9d62f9989858e0533f64e83b723b5e1398a5b488c0f5fd088795b4235f65ecaf4f007d4b79f04bc88 + checksum: 7e0303cb80defd55f3f7b85108081afc9c2f3852dda13bf70975a89210f20cd658fc02540d34247401806cb069c4ec489f7cf0df833e040ee361826484926c3a languageName: node linkType: hard diff --git a/scripts/package.json b/scripts/package.json index 52d2013ec288..34ae8e6f6a23 100644 --- a/scripts/package.json +++ b/scripts/package.json @@ -55,7 +55,7 @@ }, "resolutions": { "@testing-library/jest-dom": "^5.11.9", - "esbuild": "^0.18.0", + "esbuild": "^0.20.1", "serialize-javascript": "^3.1.0", "type-fest": "~2.19" }, diff --git a/scripts/yarn.lock b/scripts/yarn.lock index fd8ab47be372..85371e960f38 100644 --- a/scripts/yarn.lock +++ b/scripts/yarn.lock @@ -1490,156 +1490,163 @@ __metadata: languageName: node linkType: hard -"@esbuild/android-arm64@npm:0.18.20": - version: 0.18.20 - resolution: "@esbuild/android-arm64@npm:0.18.20" +"@esbuild/aix-ppc64@npm:0.20.1": + version: 0.20.1 + resolution: "@esbuild/aix-ppc64@npm:0.20.1" + conditions: os=aix & cpu=ppc64 + languageName: node + linkType: hard + +"@esbuild/android-arm64@npm:0.20.1": + version: 0.20.1 + resolution: "@esbuild/android-arm64@npm:0.20.1" conditions: os=android & cpu=arm64 languageName: node linkType: hard -"@esbuild/android-arm@npm:0.18.20": - version: 0.18.20 - resolution: "@esbuild/android-arm@npm:0.18.20" +"@esbuild/android-arm@npm:0.20.1": + version: 0.20.1 + resolution: "@esbuild/android-arm@npm:0.20.1" conditions: os=android & cpu=arm languageName: node linkType: hard -"@esbuild/android-x64@npm:0.18.20": - version: 0.18.20 - resolution: "@esbuild/android-x64@npm:0.18.20" +"@esbuild/android-x64@npm:0.20.1": + version: 0.20.1 + resolution: "@esbuild/android-x64@npm:0.20.1" conditions: os=android & cpu=x64 languageName: node linkType: hard -"@esbuild/darwin-arm64@npm:0.18.20": - version: 0.18.20 - resolution: "@esbuild/darwin-arm64@npm:0.18.20" +"@esbuild/darwin-arm64@npm:0.20.1": + version: 0.20.1 + resolution: "@esbuild/darwin-arm64@npm:0.20.1" conditions: os=darwin & cpu=arm64 languageName: node linkType: hard -"@esbuild/darwin-x64@npm:0.18.20": - version: 0.18.20 - resolution: "@esbuild/darwin-x64@npm:0.18.20" +"@esbuild/darwin-x64@npm:0.20.1": + version: 0.20.1 + resolution: "@esbuild/darwin-x64@npm:0.20.1" conditions: os=darwin & cpu=x64 languageName: node linkType: hard -"@esbuild/freebsd-arm64@npm:0.18.20": - version: 0.18.20 - resolution: "@esbuild/freebsd-arm64@npm:0.18.20" +"@esbuild/freebsd-arm64@npm:0.20.1": + version: 0.20.1 + resolution: "@esbuild/freebsd-arm64@npm:0.20.1" conditions: os=freebsd & cpu=arm64 languageName: node linkType: hard -"@esbuild/freebsd-x64@npm:0.18.20": - version: 0.18.20 - resolution: "@esbuild/freebsd-x64@npm:0.18.20" +"@esbuild/freebsd-x64@npm:0.20.1": + version: 0.20.1 + resolution: "@esbuild/freebsd-x64@npm:0.20.1" conditions: os=freebsd & cpu=x64 languageName: node linkType: hard -"@esbuild/linux-arm64@npm:0.18.20": - version: 0.18.20 - resolution: "@esbuild/linux-arm64@npm:0.18.20" +"@esbuild/linux-arm64@npm:0.20.1": + version: 0.20.1 + resolution: "@esbuild/linux-arm64@npm:0.20.1" conditions: os=linux & cpu=arm64 languageName: node linkType: hard -"@esbuild/linux-arm@npm:0.18.20": - version: 0.18.20 - resolution: "@esbuild/linux-arm@npm:0.18.20" +"@esbuild/linux-arm@npm:0.20.1": + version: 0.20.1 + resolution: "@esbuild/linux-arm@npm:0.20.1" conditions: os=linux & cpu=arm languageName: node linkType: hard -"@esbuild/linux-ia32@npm:0.18.20": - version: 0.18.20 - resolution: "@esbuild/linux-ia32@npm:0.18.20" +"@esbuild/linux-ia32@npm:0.20.1": + version: 0.20.1 + resolution: "@esbuild/linux-ia32@npm:0.20.1" conditions: os=linux & cpu=ia32 languageName: node linkType: hard -"@esbuild/linux-loong64@npm:0.18.20": - version: 0.18.20 - resolution: "@esbuild/linux-loong64@npm:0.18.20" +"@esbuild/linux-loong64@npm:0.20.1": + version: 0.20.1 + resolution: "@esbuild/linux-loong64@npm:0.20.1" conditions: os=linux & cpu=loong64 languageName: node linkType: hard -"@esbuild/linux-mips64el@npm:0.18.20": - version: 0.18.20 - resolution: "@esbuild/linux-mips64el@npm:0.18.20" +"@esbuild/linux-mips64el@npm:0.20.1": + version: 0.20.1 + resolution: "@esbuild/linux-mips64el@npm:0.20.1" conditions: os=linux & cpu=mips64el languageName: node linkType: hard -"@esbuild/linux-ppc64@npm:0.18.20": - version: 0.18.20 - resolution: "@esbuild/linux-ppc64@npm:0.18.20" +"@esbuild/linux-ppc64@npm:0.20.1": + version: 0.20.1 + resolution: "@esbuild/linux-ppc64@npm:0.20.1" conditions: os=linux & cpu=ppc64 languageName: node linkType: hard -"@esbuild/linux-riscv64@npm:0.18.20": - version: 0.18.20 - resolution: "@esbuild/linux-riscv64@npm:0.18.20" +"@esbuild/linux-riscv64@npm:0.20.1": + version: 0.20.1 + resolution: "@esbuild/linux-riscv64@npm:0.20.1" conditions: os=linux & cpu=riscv64 languageName: node linkType: hard -"@esbuild/linux-s390x@npm:0.18.20": - version: 0.18.20 - resolution: "@esbuild/linux-s390x@npm:0.18.20" +"@esbuild/linux-s390x@npm:0.20.1": + version: 0.20.1 + resolution: "@esbuild/linux-s390x@npm:0.20.1" conditions: os=linux & cpu=s390x languageName: node linkType: hard -"@esbuild/linux-x64@npm:0.18.20": - version: 0.18.20 - resolution: "@esbuild/linux-x64@npm:0.18.20" +"@esbuild/linux-x64@npm:0.20.1": + version: 0.20.1 + resolution: "@esbuild/linux-x64@npm:0.20.1" conditions: os=linux & cpu=x64 languageName: node linkType: hard -"@esbuild/netbsd-x64@npm:0.18.20": - version: 0.18.20 - resolution: "@esbuild/netbsd-x64@npm:0.18.20" +"@esbuild/netbsd-x64@npm:0.20.1": + version: 0.20.1 + resolution: "@esbuild/netbsd-x64@npm:0.20.1" conditions: os=netbsd & cpu=x64 languageName: node linkType: hard -"@esbuild/openbsd-x64@npm:0.18.20": - version: 0.18.20 - resolution: "@esbuild/openbsd-x64@npm:0.18.20" +"@esbuild/openbsd-x64@npm:0.20.1": + version: 0.20.1 + resolution: "@esbuild/openbsd-x64@npm:0.20.1" conditions: os=openbsd & cpu=x64 languageName: node linkType: hard -"@esbuild/sunos-x64@npm:0.18.20": - version: 0.18.20 - resolution: "@esbuild/sunos-x64@npm:0.18.20" +"@esbuild/sunos-x64@npm:0.20.1": + version: 0.20.1 + resolution: "@esbuild/sunos-x64@npm:0.20.1" conditions: os=sunos & cpu=x64 languageName: node linkType: hard -"@esbuild/win32-arm64@npm:0.18.20": - version: 0.18.20 - resolution: "@esbuild/win32-arm64@npm:0.18.20" +"@esbuild/win32-arm64@npm:0.20.1": + version: 0.20.1 + resolution: "@esbuild/win32-arm64@npm:0.20.1" conditions: os=win32 & cpu=arm64 languageName: node linkType: hard -"@esbuild/win32-ia32@npm:0.18.20": - version: 0.18.20 - resolution: "@esbuild/win32-ia32@npm:0.18.20" +"@esbuild/win32-ia32@npm:0.20.1": + version: 0.20.1 + resolution: "@esbuild/win32-ia32@npm:0.20.1" conditions: os=win32 & cpu=ia32 languageName: node linkType: hard -"@esbuild/win32-x64@npm:0.18.20": - version: 0.18.20 - resolution: "@esbuild/win32-x64@npm:0.18.20" +"@esbuild/win32-x64@npm:0.20.1": + version: 0.20.1 + resolution: "@esbuild/win32-x64@npm:0.20.1" conditions: os=win32 & cpu=x64 languageName: node linkType: hard @@ -6567,33 +6574,36 @@ __metadata: languageName: node linkType: hard -"esbuild@npm:^0.18.0": - version: 0.18.20 - resolution: "esbuild@npm:0.18.20" - dependencies: - "@esbuild/android-arm": "npm:0.18.20" - "@esbuild/android-arm64": "npm:0.18.20" - "@esbuild/android-x64": "npm:0.18.20" - "@esbuild/darwin-arm64": "npm:0.18.20" - "@esbuild/darwin-x64": "npm:0.18.20" - "@esbuild/freebsd-arm64": "npm:0.18.20" - "@esbuild/freebsd-x64": "npm:0.18.20" - "@esbuild/linux-arm": "npm:0.18.20" - "@esbuild/linux-arm64": "npm:0.18.20" - "@esbuild/linux-ia32": "npm:0.18.20" - "@esbuild/linux-loong64": "npm:0.18.20" - "@esbuild/linux-mips64el": "npm:0.18.20" - "@esbuild/linux-ppc64": "npm:0.18.20" - "@esbuild/linux-riscv64": "npm:0.18.20" - "@esbuild/linux-s390x": "npm:0.18.20" - "@esbuild/linux-x64": "npm:0.18.20" - "@esbuild/netbsd-x64": "npm:0.18.20" - "@esbuild/openbsd-x64": "npm:0.18.20" - "@esbuild/sunos-x64": "npm:0.18.20" - "@esbuild/win32-arm64": "npm:0.18.20" - "@esbuild/win32-ia32": "npm:0.18.20" - "@esbuild/win32-x64": "npm:0.18.20" +"esbuild@npm:^0.20.1": + version: 0.20.1 + resolution: "esbuild@npm:0.20.1" + dependencies: + "@esbuild/aix-ppc64": "npm:0.20.1" + "@esbuild/android-arm": "npm:0.20.1" + "@esbuild/android-arm64": "npm:0.20.1" + "@esbuild/android-x64": "npm:0.20.1" + "@esbuild/darwin-arm64": "npm:0.20.1" + "@esbuild/darwin-x64": "npm:0.20.1" + "@esbuild/freebsd-arm64": "npm:0.20.1" + "@esbuild/freebsd-x64": "npm:0.20.1" + "@esbuild/linux-arm": "npm:0.20.1" + "@esbuild/linux-arm64": "npm:0.20.1" + "@esbuild/linux-ia32": "npm:0.20.1" + "@esbuild/linux-loong64": "npm:0.20.1" + "@esbuild/linux-mips64el": "npm:0.20.1" + "@esbuild/linux-ppc64": "npm:0.20.1" + "@esbuild/linux-riscv64": "npm:0.20.1" + "@esbuild/linux-s390x": "npm:0.20.1" + "@esbuild/linux-x64": "npm:0.20.1" + "@esbuild/netbsd-x64": "npm:0.20.1" + "@esbuild/openbsd-x64": "npm:0.20.1" + "@esbuild/sunos-x64": "npm:0.20.1" + "@esbuild/win32-arm64": "npm:0.20.1" + "@esbuild/win32-ia32": "npm:0.20.1" + "@esbuild/win32-x64": "npm:0.20.1" dependenciesMeta: + "@esbuild/aix-ppc64": + optional: true "@esbuild/android-arm": optional: true "@esbuild/android-arm64": @@ -6640,7 +6650,7 @@ __metadata: optional: true bin: esbuild: bin/esbuild - checksum: 473b1d92842f50a303cf948a11ebd5f69581cd254d599dd9d62f9989858e0533f64e83b723b5e1398a5b488c0f5fd088795b4235f65ecaf4f007d4b79f04bc88 + checksum: 7e0303cb80defd55f3f7b85108081afc9c2f3852dda13bf70975a89210f20cd658fc02540d34247401806cb069c4ec489f7cf0df833e040ee361826484926c3a languageName: node linkType: hard From 7bcbb3c0f4f5cdb0d69d5b03064b5cfb8e08bdb0 Mon Sep 17 00:00:00 2001 From: Vanessa Yuen <6842965+vanessayuenn@users.noreply.github.com> Date: Thu, 29 Feb 2024 15:32:43 +0100 Subject: [PATCH 024/132] only use contributors' github handles in release notes --- scripts/release/utils/get-github-info.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/release/utils/get-github-info.ts b/scripts/release/utils/get-github-info.ts index bdfe995a9001..0247e8319e04 100644 --- a/scripts/release/utils/get-github-info.ts +++ b/scripts/release/utils/get-github-info.ts @@ -73,7 +73,7 @@ function makeQuery(repos: ReposWithCommitsAndPRsToFetch) { nodes { name } - } + } mergeCommit { commitUrl oid @@ -255,7 +255,7 @@ export async function getPullInfoFromCommit(request: { pull: associatedPullRequest ? `[#${associatedPullRequest.number}](${associatedPullRequest.url})` : null, - user: user ? `[@${user.login}](${user.url})` : null, + user: user ? `@${user.login}` : null, }, }; } @@ -294,7 +294,7 @@ export async function getPullInfoFromPullRequest(request: { links: { commit: commit ? `[\`${commit.oid}\`](${commit.commitUrl})` : null, pull: `[#${request.pull}](https://github.com/${request.repo}/pull/${request.pull})`, - user: user ? `[@${user.login}](${user.url})` : null, + user: user ? `@${user.login}` : null, }, }; } From d9596876b6bad5e7d107f94a342a22aabcf23bc2 Mon Sep 17 00:00:00 2001 From: 43081j <43081j@users.noreply.github.com> Date: Sat, 2 Mar 2024 12:22:05 +0000 Subject: [PATCH 025/132] chore: remove qs dependency from manager-api & channels This removes the `qs` dependency from the `manager-api` and `channels` packages, instead using `URLSearchParams` (native functionality). --- code/lib/channels/package.json | 1 - code/lib/channels/src/postmessage/index.ts | 5 ++--- code/lib/manager-api/src/tests/url.test.js | 13 ++++++------- code/yarn.lock | 1 - 4 files changed, 8 insertions(+), 12 deletions(-) diff --git a/code/lib/channels/package.json b/code/lib/channels/package.json index 6abecbb236fc..9a4bb3c30fc1 100644 --- a/code/lib/channels/package.json +++ b/code/lib/channels/package.json @@ -47,7 +47,6 @@ "@storybook/client-logger": "workspace:*", "@storybook/core-events": "workspace:*", "@storybook/global": "^5.0.0", - "qs": "^6.10.0", "telejson": "^7.2.0", "tiny-invariant": "^1.3.1" }, diff --git a/code/lib/channels/src/postmessage/index.ts b/code/lib/channels/src/postmessage/index.ts index 267e8a34f18a..1320a6577b4c 100644 --- a/code/lib/channels/src/postmessage/index.ts +++ b/code/lib/channels/src/postmessage/index.ts @@ -5,7 +5,6 @@ import { global } from '@storybook/global'; import * as EVENTS from '@storybook/core-events'; import { logger, pretty } from '@storybook/client-logger'; import { isJSON, parse, stringify } from 'telejson'; -import qs from 'qs'; import invariant from 'tiny-invariant'; import type { ChannelTransport, @@ -102,13 +101,13 @@ export class PostMessageTransport implements ChannelTransport { const frames = this.getFrames(target); - const query = qs.parse(location?.search || '', { ignoreQueryPrefix: true }); + const query = new URLSearchParams(location?.search || ''); const data = stringify( { key: KEY, event, - refId: query.refId, + refId: query.get('refId'), }, stringifyOptions ); diff --git a/code/lib/manager-api/src/tests/url.test.js b/code/lib/manager-api/src/tests/url.test.js index 02048e903c37..3374505870cb 100644 --- a/code/lib/manager-api/src/tests/url.test.js +++ b/code/lib/manager-api/src/tests/url.test.js @@ -1,5 +1,4 @@ import { describe, beforeEach, it, expect, vi } from 'vitest'; -import qs from 'qs'; import { SET_CURRENT_STORY, GLOBALS_UPDATED, UPDATE_QUERY_PARAMS } from '@storybook/core-events'; @@ -15,7 +14,7 @@ describe('initial state', () => { describe('config query parameters', () => { it('handles full parameter', () => { const navigate = vi.fn(); - const location = { search: qs.stringify({ full: '1' }) }; + const location = { search: new URLSearchParams(({ full: '1' })).toString() }; const { state: { layout }, @@ -30,7 +29,7 @@ describe('initial state', () => { it('handles nav parameter', () => { const navigate = vi.fn(); - const location = { search: qs.stringify({ nav: '0' }) }; + const location = { search: new URLSearchParams(({ nav: '0' })).toString() }; const { state: { layout }, @@ -41,7 +40,7 @@ describe('initial state', () => { it('handles shortcuts parameter', () => { const navigate = vi.fn(); - const location = { search: qs.stringify({ shortcuts: '0' }) }; + const location = { search: new URLSearchParams(({ shortcuts: '0' })).toString() }; const { state: { ui }, @@ -52,7 +51,7 @@ describe('initial state', () => { it('handles panel parameter, bottom', () => { const navigate = vi.fn(); - const location = { search: qs.stringify({ panel: 'bottom' }) }; + const location = { search: new URLSearchParams(({ panel: 'bottom' })).toString() }; const { state: { layout }, @@ -63,7 +62,7 @@ describe('initial state', () => { it('handles panel parameter, right', () => { const navigate = vi.fn(); - const location = { search: qs.stringify({ panel: 'right' }) }; + const location = { search: new URLSearchParams(({ panel: 'right' })).toString() }; const { state: { layout }, @@ -74,7 +73,7 @@ describe('initial state', () => { it('handles panel parameter, 0', () => { const navigate = vi.fn(); - const location = { search: qs.stringify({ panel: '0' }) }; + const location = { search: new URLSearchParams(({ panel: '0' })).toString() }; const { state: { layout }, diff --git a/code/yarn.lock b/code/yarn.lock index 039c28a0c940..5955691d40e7 100644 --- a/code/yarn.lock +++ b/code/yarn.lock @@ -5581,7 +5581,6 @@ __metadata: "@storybook/client-logger": "workspace:*" "@storybook/core-events": "workspace:*" "@storybook/global": "npm:^5.0.0" - qs: "npm:^6.10.0" telejson: "npm:^7.2.0" tiny-invariant: "npm:^1.3.1" typescript: "npm:^5.3.2" From 9f0bc7db7e57b830f21311a2b7ea97ff56a476e7 Mon Sep 17 00:00:00 2001 From: Valentin Palkovic Date: Mon, 4 Mar 2024 10:29:57 +0100 Subject: [PATCH 026/132] Add @storybook/addons automigration --- .../src/automigrate/fixes/addon-postcss.ts | 2 +- .../src/automigrate/fixes/addons-api.test.ts | 44 ++++++++++++++++++ .../cli/src/automigrate/fixes/addons-api.ts | 45 +++++++++++++++++++ code/lib/cli/src/automigrate/fixes/index.ts | 2 + 4 files changed, 92 insertions(+), 1 deletion(-) create mode 100644 code/lib/cli/src/automigrate/fixes/addons-api.test.ts create mode 100644 code/lib/cli/src/automigrate/fixes/addons-api.ts diff --git a/code/lib/cli/src/automigrate/fixes/addon-postcss.ts b/code/lib/cli/src/automigrate/fixes/addon-postcss.ts index 7978e545a1c5..f8d134183c0b 100644 --- a/code/lib/cli/src/automigrate/fixes/addon-postcss.ts +++ b/code/lib/cli/src/automigrate/fixes/addon-postcss.ts @@ -29,7 +29,7 @@ export const addonPostCSS: Fix = { return dedent` ${chalk.bold( 'Attention' - )}: We've detected that you're using the following package which are incompatible with Storybook 8 and beyond: + )}: We've detected that you're using the following package which is incompatible with Storybook 8 and beyond: - ${chalk.cyan(`@storybook/addon-postcss`)} diff --git a/code/lib/cli/src/automigrate/fixes/addons-api.test.ts b/code/lib/cli/src/automigrate/fixes/addons-api.test.ts new file mode 100644 index 000000000000..2bae14386d3b --- /dev/null +++ b/code/lib/cli/src/automigrate/fixes/addons-api.test.ts @@ -0,0 +1,44 @@ +import { addonsAPI } from './addons-api'; +import type { StorybookConfig } from '@storybook/types'; +import type { JsPackageManager } from '@storybook/core-common'; +import { expect, describe, it } from 'vitest'; + +const checkAddonsAPI = async ({ + packageManager, + mainConfig = {}, + storybookVersion = '7.0.0', +}: { + packageManager?: Partial; + mainConfig?: Partial; + storybookVersion?: string; +}) => { + return addonsAPI.check({ + packageManager: packageManager as any, + storybookVersion, + mainConfig: mainConfig as any, + }); +}; + +describe('check function', () => { + it('should return { usesAddonsAPI: true } if @storybook/addons is installed', async () => { + await expect( + checkAddonsAPI({ + packageManager: { + getAllDependencies: async () => ({ + '@storybook/addons': '6.0.0', + }), + }, + }) + ).resolves.toEqual({ usesAddonsAPI: true }); + }); + + it('should return null if @storybook/addons is not installed', async () => { + await expect( + checkAddonsAPI({ + packageManager: { + getAllDependencies: async () => ({}), + }, + }) + ).resolves.toBeNull(); + }); +}); diff --git a/code/lib/cli/src/automigrate/fixes/addons-api.ts b/code/lib/cli/src/automigrate/fixes/addons-api.ts new file mode 100644 index 000000000000..f193898aa82f --- /dev/null +++ b/code/lib/cli/src/automigrate/fixes/addons-api.ts @@ -0,0 +1,45 @@ +import chalk from 'chalk'; +import { dedent } from 'ts-dedent'; +import type { Fix } from '../types'; + +interface AddonsAPIRunOptions { + usesAddonsAPI: boolean; +} + +export const addonsAPI: Fix = { + id: 'addons-api', + + versionRange: ['<8', '>=8'], + + promptType: 'notification', + + async check({ packageManager }) { + const allDependencies = await packageManager.getAllDependencies(); + const usesAddonsAPI = !!allDependencies['@storybook/addons']; + + if (!usesAddonsAPI) { + return null; + } + + return { usesAddonsAPI: true }; + }, + + prompt() { + return dedent` + ${chalk.bold( + 'Attention' + )}: We've detected that you're using the following package which is removed in Storybook 8 and beyond: + + - ${chalk.cyan(`@storybook/addons`)} + + This package has been deprecated and replaced with ${chalk.cyan( + `@storybook/preview-api` + )} and ${chalk.cyan(`@storybook/manager-api`)}. + + You can find more information about the new addons API in the migration guide: + ${chalk.yellow( + 'https://github.com/storybookjs/storybook/blob/next/MIGRATION.md#new-addons-api' + )} + `; + }, +}; diff --git a/code/lib/cli/src/automigrate/fixes/index.ts b/code/lib/cli/src/automigrate/fixes/index.ts index 91ba9a27927f..17b3d4942be1 100644 --- a/code/lib/cli/src/automigrate/fixes/index.ts +++ b/code/lib/cli/src/automigrate/fixes/index.ts @@ -23,12 +23,14 @@ import { storyshotsMigration } from './storyshots-migration'; import { removeArgtypesRegex } from './remove-argtypes-regex'; import { webpack5CompilerSetup } from './webpack5-compiler-setup'; import { removeJestTestingLibrary } from './remove-jest-testing-library'; +import { addonsAPI } from './addons-api'; import { mdx1to3 } from './mdx-1-to-3'; import { addonPostCSS } from './addon-postcss'; export * from '../types'; export const allFixes: Fix[] = [ + addonsAPI, newFrameworks, cra5, webpack5, From c9a26c6f25217cc5a595189e8dbbe828937b4437 Mon Sep 17 00:00:00 2001 From: Norbert de Langen Date: Mon, 4 Mar 2024 13:30:49 +0100 Subject: [PATCH 027/132] fix the bug and add tests to ensure it doesn't fail ever again --- code/lib/cli/src/add.test.ts | 140 +++++++++++++++++++++++++++ code/lib/cli/src/add.ts | 82 +++++++--------- code/lib/cli/src/postinstallAddon.ts | 19 ++++ 3 files changed, 196 insertions(+), 45 deletions(-) create mode 100644 code/lib/cli/src/add.test.ts create mode 100644 code/lib/cli/src/postinstallAddon.ts diff --git a/code/lib/cli/src/add.test.ts b/code/lib/cli/src/add.test.ts new file mode 100644 index 000000000000..2da3bd8e184b --- /dev/null +++ b/code/lib/cli/src/add.test.ts @@ -0,0 +1,140 @@ +import { describe, expect, test, vi } from 'vitest'; +import { add, getVersionSpecifier } from './add'; + +const MockedConfig = vi.hoisted(() => { + return { + appendValueToArray: vi.fn(), + }; +}); +const MockedPackageManager = vi.hoisted(() => { + return { + retrievePackageJson: vi.fn(() => ({})), + latestVersion: vi.fn(() => '1.0.0'), + addDependencies: vi.fn(() => {}), + type: 'npm', + }; +}); +const MockedPostInstall = vi.hoisted(() => { + return { + postinstallAddon: vi.fn(), + }; +}); + +const MockedConsole = { + log: vi.fn(), + warn: vi.fn(), + error: vi.fn(), +} as any as Console; + +vi.mock('@storybook/csf-tools', () => { + return { + readConfig: vi.fn(() => MockedConfig), + writeConfig: vi.fn(), + }; +}); +vi.mock('./postinstallAddon', () => { + return MockedPostInstall; +}); + +vi.mock('@storybook/core-common', () => { + return { + getStorybookInfo: vi.fn(() => ({ mainConfig: {}, configDir: '' })), + serverRequire: vi.fn(() => ({})), + JsPackageManagerFactory: { + getPackageManager: vi.fn(() => MockedPackageManager), + }, + versions: { + '@storybook/addon-onboarding': '8.0.0', + }, + }; +}); + +describe('getVersionSpecifier', (it) => { + test.each([ + ['@storybook/addon-docs', ['@storybook/addon-docs', undefined]], + ['@storybook/addon-docs@7.0.1', ['@storybook/addon-docs', '7.0.1']], + ['@storybook/addon-docs@7.0.1-beta.1', ['@storybook/addon-docs', '7.0.1-beta.1']], + ['@storybook/addon-docs@~7.0.1-beta.1', ['@storybook/addon-docs', '~7.0.1-beta.1']], + ['@storybook/addon-docs@^7.0.1-beta.1', ['@storybook/addon-docs', '^7.0.1-beta.1']], + ['@storybook/addon-docs@next', ['@storybook/addon-docs', 'next']], + ])('%s => %s', (input, expected) => { + const result = getVersionSpecifier(input); + expect(result[0]).toEqual(expected[0]); + expect(result[1]).toEqual(expected[1]); + }); +}); + +describe('add', () => { + const testData = [ + { full: 'aa', expected: 'aa@^1.0.0' }, // resolves to the latest version + { full: 'aa@4', expected: 'aa@^4' }, + { full: 'aa@4.1.0', expected: 'aa@^4.1.0' }, + { full: 'aa@^4', expected: 'aa@^4' }, + { full: 'aa@~4', expected: 'aa@~4' }, + { full: 'aa@4.1.0-alpha.1', expected: 'aa@^4.1.0-alpha.1' }, + { full: 'aa@next', expected: 'aa@next' }, + + { full: '@org/aa', expected: '@org/aa@^1.0.0' }, + { full: '@org/aa@4', expected: '@org/aa@^4' }, + { full: '@org/aa@4.1.0', expected: '@org/aa@^4.1.0' }, + { full: '@org/aa@4.1.0-alpha.1', expected: '@org/aa@^4.1.0-alpha.1' }, + { full: '@org/aa@next', expected: '@org/aa@next' }, + + { full: '@storybook/addon-onboarding@~4', expected: '@storybook/addon-onboarding@~4' }, + { full: '@storybook/addon-onboarding@next', expected: '@storybook/addon-onboarding@next' }, + { full: '@storybook/addon-onboarding', expected: '@storybook/addon-onboarding@^8.0.0' }, // takes it from the versions file + ]; + + test.each(testData)('$full', async ({ full, expected }) => { + const [input] = getVersionSpecifier(full); + + await add(full, { packageManager: 'npm', skipPostinstall: true }, MockedConsole); + + expect(MockedConfig.appendValueToArray).toHaveBeenCalledWith( + expect.arrayContaining(['addons']), + input + ); + + expect(MockedPackageManager.addDependencies).toHaveBeenCalledWith( + { installAsDevDependencies: true }, + [expected] + ); + }); +}); + +describe('add (extra)', () => { + test('not warning when installing the correct version of storybook', async () => { + await add( + '@storybook/addon-onboarding', + { packageManager: 'npm', skipPostinstall: true }, + MockedConsole + ); + + expect(MockedConsole.warn).not.toHaveBeenCalledWith( + `The version of @storybook/addon-onboarding you are installing is not the same as the version of Storybook you are using. This may lead to unexpected behavior.` + ); + }); + test('warning when installing a specific version of storybook', async () => { + await add( + '@storybook/addon-onboarding@2.0.0', + { packageManager: 'npm', skipPostinstall: true }, + MockedConsole + ); + + expect(MockedConsole.warn).toHaveBeenCalledWith( + `The version of @storybook/addon-onboarding you are installing is not the same as the version of Storybook you are using. This may lead to unexpected behavior.` + ); + }); + + test('postInstall', async () => { + await add( + '@storybook/addon-onboarding', + { packageManager: 'npm', skipPostinstall: false }, + MockedConsole + ); + + expect(MockedPostInstall.postinstallAddon).toHaveBeenCalledWith('@storybook/addon-onboarding', { + packageManager: 'npm', + }); + }); +}); diff --git a/code/lib/cli/src/add.ts b/code/lib/cli/src/add.ts index 0321ec966fd7..a19249ddb453 100644 --- a/code/lib/cli/src/add.ts +++ b/code/lib/cli/src/add.ts @@ -1,44 +1,31 @@ import { getStorybookInfo, serverRequire, - getCoercedStorybookVersion, - isCorePackage, JsPackageManagerFactory, + versions, type PackageManagerName, } from '@storybook/core-common'; import { readConfig, writeConfig } from '@storybook/csf-tools'; import { isAbsolute, join } from 'path'; import SemVer from 'semver'; import dedent from 'ts-dedent'; +import { postinstallAddon } from './postinstallAddon'; -const logger = console; - -interface PostinstallOptions { +export interface PostinstallOptions { packageManager: PackageManagerName; } -const postinstallAddon = async (addonName: string, options: PostinstallOptions) => { - try { - const modulePath = require.resolve(`${addonName}/postinstall`, { paths: [process.cwd()] }); - - const postinstall = require(modulePath); - - try { - logger.log(`Running postinstall script for ${addonName}`); - await postinstall(options); - } catch (e) { - logger.error(`Error running postinstall script for ${addonName}`); - logger.error(e); - } - } catch (e) { - // no postinstall script - } -}; - -const getVersionSpecifier = (addon: string) => { - const groups = /^(...*)@(.*)$/.exec(addon); +/** + * Extract the addon name and version specifier from the input string + * @param addon - the input string + * @returns [addonName, versionSpecifier] + * @example + * getVersionSpecifier('@storybook/addon-docs@7.0.1') => ['@storybook/addon-docs', '7.0.1'] + */ +export const getVersionSpecifier = (addon: string) => { + const groups = /^(@{0,1}[^@]+)(?:@(.+))?$/.exec(addon); if (groups) { - return [groups[0], groups[2]] as const; + return [groups[1], groups[2]] as const; } return [addon, undefined] as const; }; @@ -71,9 +58,11 @@ const checkInstalled = (addonName: string, main: any) => { */ export async function add( addon: string, - options: { packageManager: PackageManagerName; skipPostinstall: boolean } + options: { packageManager: PackageManagerName; skipPostinstall: boolean }, + logger = console ) { const { packageManager: pkgMgr } = options; + const [addonName, inputVersion] = getVersionSpecifier(addon); const packageManager = JsPackageManagerFactory.getPackageManager({ force: pkgMgr }); const packageJson = await packageManager.retrievePackageJson(); @@ -85,38 +74,38 @@ export async function add( `); } - if (checkInstalled(addon, requireMain(configDir))) { - throw new Error(dedent` - Addon ${addon} is already installed; we skipped adding it to your ${mainConfig}. - `); - } - - const [addonName, versionSpecifier] = getVersionSpecifier(addon); - if (!mainConfig) { logger.error('Unable to find storybook main.js config'); return; } + + if (checkInstalled(addonName, requireMain(configDir))) { + throw new Error(dedent` + Addon ${addonName} is already installed; we skipped adding it to your ${mainConfig}. + `); + } + const main = await readConfig(mainConfig); logger.log(`Verifying ${addonName}`); - const latestVersion = await packageManager.latestVersion(addonName); - if (!latestVersion) { - logger.error(`Unknown addon ${addonName}`); - } - // add to package.json + const storybookVersion = versions[addonName as keyof typeof versions] as string | undefined; const isStorybookAddon = addonName.startsWith('@storybook/'); - const isAddonFromCore = isCorePackage(addonName); - const storybookVersion = await getCoercedStorybookVersion(packageManager); - const version = versionSpecifier || (isAddonFromCore ? storybookVersion : latestVersion); + const version = + inputVersion || storybookVersion || (await packageManager.latestVersion(addonName)); + + if (storybookVersion && version !== storybookVersion) { + logger.warn( + `The version of ${addonName} you are installing is not the same as the version of Storybook you are using. This may lead to unexpected behavior.` + ); + } - const addonWithVersion = SemVer.valid(version) + const addonWithVersion = isValidVersion(version) ? `${addonName}@^${version}` : `${addonName}@${version}`; + logger.log(`Installing ${addonWithVersion}`); await packageManager.addDependencies({ installAsDevDependencies: true }, [addonWithVersion]); - // add to main.js logger.log(`Adding '${addon}' to main.js addons field.`); main.appendValueToArray(['addons'], addonName); await writeConfig(main); @@ -125,3 +114,6 @@ export async function add( await postinstallAddon(addonName, { packageManager: packageManager.type }); } } +function isValidVersion(version: string) { + return SemVer.valid(version) || version.match(/^\d+$/); +} diff --git a/code/lib/cli/src/postinstallAddon.ts b/code/lib/cli/src/postinstallAddon.ts new file mode 100644 index 000000000000..50719c29e29c --- /dev/null +++ b/code/lib/cli/src/postinstallAddon.ts @@ -0,0 +1,19 @@ +import type { PostinstallOptions } from './add'; + +export const postinstallAddon = async (addonName: string, options: PostinstallOptions) => { + try { + const modulePath = require.resolve(`${addonName}/postinstall`, { paths: [process.cwd()] }); + + const postinstall = require(modulePath); + + try { + console.log(`Running postinstall script for ${addonName}`); + await postinstall(options); + } catch (e) { + console.error(`Error running postinstall script for ${addonName}`); + console.error(e); + } + } catch (e) { + // no postinstall script + } +}; From 8f07e61ef02b3aa752da91576cf016367beaa454 Mon Sep 17 00:00:00 2001 From: Norbert de Langen Date: Mon, 4 Mar 2024 14:02:07 +0100 Subject: [PATCH 028/132] fixes --- code/lib/cli/src/add.test.ts | 25 ++++++++++++++----------- code/lib/cli/src/add.ts | 21 +++++++++++++++------ 2 files changed, 29 insertions(+), 17 deletions(-) diff --git a/code/lib/cli/src/add.test.ts b/code/lib/cli/src/add.test.ts index 2da3bd8e184b..16d86d7c6851 100644 --- a/code/lib/cli/src/add.test.ts +++ b/code/lib/cli/src/add.test.ts @@ -43,8 +43,9 @@ vi.mock('@storybook/core-common', () => { JsPackageManagerFactory: { getPackageManager: vi.fn(() => MockedPackageManager), }, + getCoercedStorybookVersion: vi.fn(() => '8.0.0'), versions: { - '@storybook/addon-onboarding': '8.0.0', + 'storybook/addon-docs': '^8.0.0', }, }; }); @@ -80,9 +81,9 @@ describe('add', () => { { full: '@org/aa@4.1.0-alpha.1', expected: '@org/aa@^4.1.0-alpha.1' }, { full: '@org/aa@next', expected: '@org/aa@next' }, - { full: '@storybook/addon-onboarding@~4', expected: '@storybook/addon-onboarding@~4' }, - { full: '@storybook/addon-onboarding@next', expected: '@storybook/addon-onboarding@next' }, - { full: '@storybook/addon-onboarding', expected: '@storybook/addon-onboarding@^8.0.0' }, // takes it from the versions file + { full: 'storybook/addon-docs@~4', expected: 'storybook/addon-docs@~4' }, + { full: 'storybook/addon-docs@next', expected: 'storybook/addon-docs@next' }, + { full: 'storybook/addon-docs', expected: 'storybook/addon-docs@^8.0.0' }, // takes it from the versions file ]; test.each(testData)('$full', async ({ full, expected }) => { @@ -105,35 +106,37 @@ describe('add', () => { describe('add (extra)', () => { test('not warning when installing the correct version of storybook', async () => { await add( - '@storybook/addon-onboarding', + 'storybook/addon-docs', { packageManager: 'npm', skipPostinstall: true }, MockedConsole ); expect(MockedConsole.warn).not.toHaveBeenCalledWith( - `The version of @storybook/addon-onboarding you are installing is not the same as the version of Storybook you are using. This may lead to unexpected behavior.` + expect.stringContaining(`is not the same as the version of Storybook you are using.`) ); }); - test('warning when installing a specific version of storybook', async () => { + test('warning when installing a core addon mismatching version of storybook', async () => { await add( - '@storybook/addon-onboarding@2.0.0', + 'storybook/addon-docs@2.0.0', { packageManager: 'npm', skipPostinstall: true }, MockedConsole ); expect(MockedConsole.warn).toHaveBeenCalledWith( - `The version of @storybook/addon-onboarding you are installing is not the same as the version of Storybook you are using. This may lead to unexpected behavior.` + expect.stringContaining( + `The version of storybook/addon-docs you are installing is not the same as the version of Storybook you are using. This may lead to unexpected behavior.` + ) ); }); test('postInstall', async () => { await add( - '@storybook/addon-onboarding', + 'storybook/addon-docs', { packageManager: 'npm', skipPostinstall: false }, MockedConsole ); - expect(MockedPostInstall.postinstallAddon).toHaveBeenCalledWith('@storybook/addon-onboarding', { + expect(MockedPostInstall.postinstallAddon).toHaveBeenCalledWith('storybook/addon-docs', { packageManager: 'npm', }); }); diff --git a/code/lib/cli/src/add.ts b/code/lib/cli/src/add.ts index a19249ddb453..a0ddcdbf7cb7 100644 --- a/code/lib/cli/src/add.ts +++ b/code/lib/cli/src/add.ts @@ -2,8 +2,9 @@ import { getStorybookInfo, serverRequire, JsPackageManagerFactory, - versions, + getCoercedStorybookVersion, type PackageManagerName, + versions, } from '@storybook/core-common'; import { readConfig, writeConfig } from '@storybook/csf-tools'; import { isAbsolute, join } from 'path'; @@ -45,6 +46,8 @@ const checkInstalled = (addonName: string, main: any) => { return !!existingAddon; }; +const isCoreAddon = (addonName: string) => !!versions[addonName as keyof typeof versions]; + /** * Install the given addon package and add it to main.js * @@ -88,10 +91,16 @@ export async function add( const main = await readConfig(mainConfig); logger.log(`Verifying ${addonName}`); - const storybookVersion = versions[addonName as keyof typeof versions] as string | undefined; - const isStorybookAddon = addonName.startsWith('@storybook/'); - const version = - inputVersion || storybookVersion || (await packageManager.latestVersion(addonName)); + const storybookVersion = await getCoercedStorybookVersion(packageManager); + + let version = inputVersion; + + if (!version && isCoreAddon(addonName) && storybookVersion) { + version = storybookVersion; + } + if (!version) { + version = await packageManager.latestVersion(addonName); + } if (storybookVersion && version !== storybookVersion) { logger.warn( @@ -110,7 +119,7 @@ export async function add( main.appendValueToArray(['addons'], addonName); await writeConfig(main); - if (!options.skipPostinstall && isStorybookAddon) { + if (!options.skipPostinstall && isCoreAddon(addonName)) { await postinstallAddon(addonName, { packageManager: packageManager.type }); } } From eacdd37e2b02846c98883a4f1b241a6058a718d0 Mon Sep 17 00:00:00 2001 From: Norbert de Langen Date: Mon, 4 Mar 2024 14:08:49 +0100 Subject: [PATCH 029/132] rename for clarity --- code/lib/cli/src/add.test.ts | 42 ++++++++++++++++++------------------ 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/code/lib/cli/src/add.test.ts b/code/lib/cli/src/add.test.ts index 16d86d7c6851..868d0ff7057d 100644 --- a/code/lib/cli/src/add.test.ts +++ b/code/lib/cli/src/add.test.ts @@ -67,33 +67,33 @@ describe('getVersionSpecifier', (it) => { describe('add', () => { const testData = [ - { full: 'aa', expected: 'aa@^1.0.0' }, // resolves to the latest version - { full: 'aa@4', expected: 'aa@^4' }, - { full: 'aa@4.1.0', expected: 'aa@^4.1.0' }, - { full: 'aa@^4', expected: 'aa@^4' }, - { full: 'aa@~4', expected: 'aa@~4' }, - { full: 'aa@4.1.0-alpha.1', expected: 'aa@^4.1.0-alpha.1' }, - { full: 'aa@next', expected: 'aa@next' }, - - { full: '@org/aa', expected: '@org/aa@^1.0.0' }, - { full: '@org/aa@4', expected: '@org/aa@^4' }, - { full: '@org/aa@4.1.0', expected: '@org/aa@^4.1.0' }, - { full: '@org/aa@4.1.0-alpha.1', expected: '@org/aa@^4.1.0-alpha.1' }, - { full: '@org/aa@next', expected: '@org/aa@next' }, - - { full: 'storybook/addon-docs@~4', expected: 'storybook/addon-docs@~4' }, - { full: 'storybook/addon-docs@next', expected: 'storybook/addon-docs@next' }, - { full: 'storybook/addon-docs', expected: 'storybook/addon-docs@^8.0.0' }, // takes it from the versions file + { input: 'aa', expected: 'aa@^1.0.0' }, // resolves to the latest version + { input: 'aa@4', expected: 'aa@^4' }, + { input: 'aa@4.1.0', expected: 'aa@^4.1.0' }, + { input: 'aa@^4', expected: 'aa@^4' }, + { input: 'aa@~4', expected: 'aa@~4' }, + { input: 'aa@4.1.0-alpha.1', expected: 'aa@^4.1.0-alpha.1' }, + { input: 'aa@next', expected: 'aa@next' }, + + { input: '@org/aa', expected: '@org/aa@^1.0.0' }, + { input: '@org/aa@4', expected: '@org/aa@^4' }, + { input: '@org/aa@4.1.0', expected: '@org/aa@^4.1.0' }, + { input: '@org/aa@4.1.0-alpha.1', expected: '@org/aa@^4.1.0-alpha.1' }, + { input: '@org/aa@next', expected: '@org/aa@next' }, + + { input: 'storybook/addon-docs@~4', expected: 'storybook/addon-docs@~4' }, + { input: 'storybook/addon-docs@next', expected: 'storybook/addon-docs@next' }, + { input: 'storybook/addon-docs', expected: 'storybook/addon-docs@^8.0.0' }, // takes it from the versions file ]; - test.each(testData)('$full', async ({ full, expected }) => { - const [input] = getVersionSpecifier(full); + test.each(testData)('$full', async ({ input, expected }) => { + const [packageName] = getVersionSpecifier(input); - await add(full, { packageManager: 'npm', skipPostinstall: true }, MockedConsole); + await add(input, { packageManager: 'npm', skipPostinstall: true }, MockedConsole); expect(MockedConfig.appendValueToArray).toHaveBeenCalledWith( expect.arrayContaining(['addons']), - input + packageName ); expect(MockedPackageManager.addDependencies).toHaveBeenCalledWith( From 2d66683bf127e6d347b7dd555bcd3b0a49958ff8 Mon Sep 17 00:00:00 2001 From: Norbert de Langen Date: Mon, 4 Mar 2024 14:10:06 +0100 Subject: [PATCH 030/132] cleanup --- code/lib/cli/src/add.test.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/code/lib/cli/src/add.test.ts b/code/lib/cli/src/add.test.ts index 868d0ff7057d..b7bcf5b93ac5 100644 --- a/code/lib/cli/src/add.test.ts +++ b/code/lib/cli/src/add.test.ts @@ -19,7 +19,6 @@ const MockedPostInstall = vi.hoisted(() => { postinstallAddon: vi.fn(), }; }); - const MockedConsole = { log: vi.fn(), warn: vi.fn(), @@ -35,7 +34,6 @@ vi.mock('@storybook/csf-tools', () => { vi.mock('./postinstallAddon', () => { return MockedPostInstall; }); - vi.mock('@storybook/core-common', () => { return { getStorybookInfo: vi.fn(() => ({ mainConfig: {}, configDir: '' })), From be683bf8bc01ba945eb2072ab6bbec0ba3ab0d34 Mon Sep 17 00:00:00 2001 From: Norbert de Langen Date: Mon, 4 Mar 2024 14:16:52 +0100 Subject: [PATCH 031/132] use hasOwn, which is type-safe, no need for casting --- code/lib/cli/src/add.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/lib/cli/src/add.ts b/code/lib/cli/src/add.ts index a0ddcdbf7cb7..cc56b3f5695d 100644 --- a/code/lib/cli/src/add.ts +++ b/code/lib/cli/src/add.ts @@ -46,7 +46,7 @@ const checkInstalled = (addonName: string, main: any) => { return !!existingAddon; }; -const isCoreAddon = (addonName: string) => !!versions[addonName as keyof typeof versions]; +const isCoreAddon = (addonName: string) => Object.hasOwn(versions, addonName); /** * Install the given addon package and add it to main.js From 320fd3decd4400805634ef20e9f2bd234c1c9ae9 Mon Sep 17 00:00:00 2001 From: Norbert de Langen Date: Mon, 4 Mar 2024 16:14:12 +0100 Subject: [PATCH 032/132] found a flaw thanks to review from valentin --- code/lib/cli/src/add.test.ts | 31 +++++++++++++++++++++---------- code/lib/cli/src/add.ts | 2 +- 2 files changed, 22 insertions(+), 11 deletions(-) diff --git a/code/lib/cli/src/add.test.ts b/code/lib/cli/src/add.test.ts index b7bcf5b93ac5..4dc12eb48986 100644 --- a/code/lib/cli/src/add.test.ts +++ b/code/lib/cli/src/add.test.ts @@ -43,7 +43,7 @@ vi.mock('@storybook/core-common', () => { }, getCoercedStorybookVersion: vi.fn(() => '8.0.0'), versions: { - 'storybook/addon-docs': '^8.0.0', + '@storybook/addon-docs': '^8.0.0', }, }; }); @@ -79,12 +79,12 @@ describe('add', () => { { input: '@org/aa@4.1.0-alpha.1', expected: '@org/aa@^4.1.0-alpha.1' }, { input: '@org/aa@next', expected: '@org/aa@next' }, - { input: 'storybook/addon-docs@~4', expected: 'storybook/addon-docs@~4' }, - { input: 'storybook/addon-docs@next', expected: 'storybook/addon-docs@next' }, - { input: 'storybook/addon-docs', expected: 'storybook/addon-docs@^8.0.0' }, // takes it from the versions file + { input: '@storybook/addon-docs@~4', expected: '@storybook/addon-docs@~4' }, + { input: '@storybook/addon-docs@next', expected: '@storybook/addon-docs@next' }, + { input: '@storybook/addon-docs', expected: '@storybook/addon-docs@^8.0.0' }, // takes it from the versions file ]; - test.each(testData)('$full', async ({ input, expected }) => { + test.each(testData)('$input', async ({ input, expected }) => { const [packageName] = getVersionSpecifier(input); await add(input, { packageManager: 'npm', skipPostinstall: true }, MockedConsole); @@ -104,7 +104,18 @@ describe('add', () => { describe('add (extra)', () => { test('not warning when installing the correct version of storybook', async () => { await add( - 'storybook/addon-docs', + '@storybook/addon-docs', + { packageManager: 'npm', skipPostinstall: true }, + MockedConsole + ); + + expect(MockedConsole.warn).not.toHaveBeenCalledWith( + expect.stringContaining(`is not the same as the version of Storybook you are using.`) + ); + }); + test('not warning when installing unrelated package', async () => { + await add( + '@storybook/addon-docs', { packageManager: 'npm', skipPostinstall: true }, MockedConsole ); @@ -115,26 +126,26 @@ describe('add (extra)', () => { }); test('warning when installing a core addon mismatching version of storybook', async () => { await add( - 'storybook/addon-docs@2.0.0', + '@storybook/addon-docs@2.0.0', { packageManager: 'npm', skipPostinstall: true }, MockedConsole ); expect(MockedConsole.warn).toHaveBeenCalledWith( expect.stringContaining( - `The version of storybook/addon-docs you are installing is not the same as the version of Storybook you are using. This may lead to unexpected behavior.` + `The version of @storybook/addon-docs you are installing is not the same as the version of Storybook you are using. This may lead to unexpected behavior.` ) ); }); test('postInstall', async () => { await add( - 'storybook/addon-docs', + '@storybook/addon-docs', { packageManager: 'npm', skipPostinstall: false }, MockedConsole ); - expect(MockedPostInstall.postinstallAddon).toHaveBeenCalledWith('storybook/addon-docs', { + expect(MockedPostInstall.postinstallAddon).toHaveBeenCalledWith('@storybook/addon-docs', { packageManager: 'npm', }); }); diff --git a/code/lib/cli/src/add.ts b/code/lib/cli/src/add.ts index cc56b3f5695d..19a4b552fcc0 100644 --- a/code/lib/cli/src/add.ts +++ b/code/lib/cli/src/add.ts @@ -102,7 +102,7 @@ export async function add( version = await packageManager.latestVersion(addonName); } - if (storybookVersion && version !== storybookVersion) { + if (isCoreAddon(addonName) && version !== storybookVersion) { logger.warn( `The version of ${addonName} you are installing is not the same as the version of Storybook you are using. This may lead to unexpected behavior.` ); From b6b98eb9912727d8de135b96e2ea3d3e85ae96da Mon Sep 17 00:00:00 2001 From: Norbert de Langen Date: Mon, 4 Mar 2024 16:16:43 +0100 Subject: [PATCH 033/132] change package name for test --- code/lib/cli/src/add.test.ts | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/code/lib/cli/src/add.test.ts b/code/lib/cli/src/add.test.ts index 4dc12eb48986..3025da275e49 100644 --- a/code/lib/cli/src/add.test.ts +++ b/code/lib/cli/src/add.test.ts @@ -114,11 +114,7 @@ describe('add (extra)', () => { ); }); test('not warning when installing unrelated package', async () => { - await add( - '@storybook/addon-docs', - { packageManager: 'npm', skipPostinstall: true }, - MockedConsole - ); + await add('aa', { packageManager: 'npm', skipPostinstall: true }, MockedConsole); expect(MockedConsole.warn).not.toHaveBeenCalledWith( expect.stringContaining(`is not the same as the version of Storybook you are using.`) From 9e01244dac13d8c59ee808ffc8a852030a0d66f9 Mon Sep 17 00:00:00 2001 From: Lars Rickert Date: Mon, 4 Mar 2024 20:01:02 +0100 Subject: [PATCH 034/132] fix(vue-component-meta): prevent reference error when using re-exports --- .../vue3-vite/src/plugins/vue-component-meta.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/code/frameworks/vue3-vite/src/plugins/vue-component-meta.ts b/code/frameworks/vue3-vite/src/plugins/vue-component-meta.ts index bd6a22fe338a..7ec671bddf62 100644 --- a/code/frameworks/vue3-vite/src/plugins/vue-component-meta.ts +++ b/code/frameworks/vue3-vite/src/plugins/vue-component-meta.ts @@ -94,7 +94,13 @@ export async function vueComponentMeta(): Promise { // we can only add the "__docgenInfo" to variables that are actually defined in the current file // so e.g. re-exports like "export { default as MyComponent } from './MyComponent.vue'" must be ignored // to prevent runtime errors - if (new RegExp(`export {.*${name}.*}`).test(src)) { + if ( + new RegExp(`export {.*${name}.*}`).test(src) || + new RegExp(`export \\* from ['"]\\S*${name}['"]`).test(src) || + // when using re-exports, some exports might be resolved via checker.getExportNames + // but are not directly exported inside the current file so we need to ignore them too + !src.includes(name) + ) { return; } From f0a23ca35dcd62bfce1c27bb2997149108528764 Mon Sep 17 00:00:00 2001 From: Norbert de Langen Date: Mon, 4 Mar 2024 20:19:13 +0100 Subject: [PATCH 035/132] improve the refs detection This should make it possible to have refs share the same origin as each other and as the main storybook. This is useful if you have static-storybooks in static directories --- code/lib/channels/src/postmessage/getEventSourceUrl.ts | 8 ++++++++ code/lib/manager-api/src/lib/events.ts | 10 +++++++--- code/lib/manager-api/src/modules/refs.ts | 8 ++++---- 3 files changed, 19 insertions(+), 7 deletions(-) diff --git a/code/lib/channels/src/postmessage/getEventSourceUrl.ts b/code/lib/channels/src/postmessage/getEventSourceUrl.ts index da3f4ec4d2f6..33c5729a7a08 100644 --- a/code/lib/channels/src/postmessage/getEventSourceUrl.ts +++ b/code/lib/channels/src/postmessage/getEventSourceUrl.ts @@ -7,6 +7,14 @@ export const getEventSourceUrl = (event: MessageEvent) => { // try to find the originating iframe by matching it's contentWindow // This might not be cross-origin safe const [frame, ...remainder] = frames.filter((element) => { + try { + return ( + element.contentWindow?.location.origin === (event.source as Window).location.origin && + element.contentWindow?.location.pathname === (event.source as Window).location.pathname + ); + } catch (err) { + // continue + } try { return element.contentWindow === event.source; } catch (err) { diff --git a/code/lib/manager-api/src/lib/events.ts b/code/lib/manager-api/src/lib/events.ts index c66c5a9e1403..1892d71ed57a 100644 --- a/code/lib/manager-api/src/lib/events.ts +++ b/code/lib/manager-api/src/lib/events.ts @@ -19,9 +19,13 @@ export const getEventMetadata = (context: Meta, fullAPI: API) => { const { source, refId, type } = context; const [sourceType, sourceLocation] = getSourceType(source!, refId); - const ref = - refId && fullAPI.getRefs()[refId] ? fullAPI.getRefs()[refId] : fullAPI.findRef(sourceLocation!); - + let ref: API_ComposedRef | undefined; + if (refId || sourceType === 'external') { + ref = + refId && fullAPI.getRefs()[refId] + ? fullAPI.getRefs()[refId] + : fullAPI.findRef(sourceLocation!); + } const meta = { source, sourceType, diff --git a/code/lib/manager-api/src/modules/refs.ts b/code/lib/manager-api/src/modules/refs.ts index 906798848e16..bc4b94755a53 100644 --- a/code/lib/manager-api/src/modules/refs.ts +++ b/code/lib/manager-api/src/modules/refs.ts @@ -20,8 +20,6 @@ import type { ModuleFn } from '../lib/types'; const { location, fetch } = global; -const findFilename = /(\/((?:[^\/]+?)\.[^\/]+?)|\/)$/; - export interface SubState { refs: API_Refs; } @@ -75,8 +73,10 @@ export const getSourceType = (source: string, refId?: string) => { const { origin: localOrigin, pathname: localPathname } = location; const { origin: sourceOrigin, pathname: sourcePathname } = new URL(source); - const localFull = `${localOrigin + localPathname}`.replace(findFilename, ''); - const sourceFull = `${sourceOrigin + sourcePathname}`.replace(findFilename, ''); + const localFull = `${localOrigin + localPathname}`.replace('/iframe.html', '').replace(/\/$/, ''); + const sourceFull = `${sourceOrigin + sourcePathname}` + .replace('/iframe.html', '') + .replace(/\/$/, ''); if (localFull === sourceFull) { return ['local', sourceFull]; From dc07edd92d94164690e619b0d5322c9e89ddb15e Mon Sep 17 00:00:00 2001 From: Valentin Palkovic Date: Tue, 5 Mar 2024 09:02:46 +0100 Subject: [PATCH 036/132] Update minimum Node.js version requirement --- code/lib/cli/bin/index.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/code/lib/cli/bin/index.js b/code/lib/cli/bin/index.js index 7131e95a311d..af7869a6e043 100755 --- a/code/lib/cli/bin/index.js +++ b/code/lib/cli/bin/index.js @@ -1,8 +1,8 @@ #!/usr/bin/env node -const majorNodeVersion = parseInt(process.version.toString().replace('v', '').split('.')[0], 10); -if (majorNodeVersion < 16) { - console.error('To run storybook you need to have node 16 or higher'); +const majorNodeVersion = parseInt(process.versions.node, 10); +if (majorNodeVersion < 18) { + console.error('To run Storybook you need to have Node.js 18 or higher'); process.exit(1); } From 7e6438f7ef201a6e844b48d94eb3a34b500be012 Mon Sep 17 00:00:00 2001 From: Norbert de Langen Date: Tue, 5 Mar 2024 10:07:38 +0100 Subject: [PATCH 037/132] fix test --- code/lib/manager-api/src/tests/refs.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/lib/manager-api/src/tests/refs.test.ts b/code/lib/manager-api/src/tests/refs.test.ts index afdb0747e39e..791325c27337 100644 --- a/code/lib/manager-api/src/tests/refs.test.ts +++ b/code/lib/manager-api/src/tests/refs.test.ts @@ -25,7 +25,7 @@ vi.mock('@storybook/global', () => { // Add additional variations of global.location mock return values in this array. // NOTE: The order must match the order that global.location is called in the unit tests. const edgecaseLocations = [ - { origin: 'https://storybook.js.org', pathname: '/storybook/index.html' }, + { origin: 'https://storybook.js.org', pathname: '/storybook/iframe.html' }, ]; // global.location value after all edgecaseLocations are returned const lastLocation = { origin: 'https://storybook.js.org', pathname: '/storybook/' }; From b4a274007790b5317f8abe939b104494e6cef6c6 Mon Sep 17 00:00:00 2001 From: Jeppe Reinhold Date: Tue, 5 Mar 2024 12:16:13 +0100 Subject: [PATCH 038/132] make composeStory in Vue return a component instead of a function --- .../composeStories/portable-stories.test.ts | 22 +++++++++---------- code/renderers/vue3/src/portable-stories.ts | 11 +++++++++- 2 files changed, 21 insertions(+), 12 deletions(-) diff --git a/code/renderers/vue3/src/__tests__/composeStories/portable-stories.test.ts b/code/renderers/vue3/src/__tests__/composeStories/portable-stories.test.ts index 36aa7c2e9c56..00257ba3aba0 100644 --- a/code/renderers/vue3/src/__tests__/composeStories/portable-stories.test.ts +++ b/code/renderers/vue3/src/__tests__/composeStories/portable-stories.test.ts @@ -17,34 +17,34 @@ const Secondary = composeStory(stories.CSF2Secondary, stories.default); describe('renders', () => { it('renders primary button', () => { - render(CSF3Primary({ label: 'Hello world' })); + render(CSF3Primary, { props: { label: 'Hello world' } }); const buttonElement = screen.getByText(/Hello world/i); expect(buttonElement).toBeInTheDocument(); }); it('reuses args from composed story', () => { - render(Secondary()); + render(Secondary); const buttonElement = screen.getByRole('button'); expect(buttonElement.textContent).toEqual(Secondary.args.label); }); it('myClickEvent handler is called', async () => { const myClickEventSpy = vi.fn(); - render(Secondary({ onMyClickEvent: myClickEventSpy })); + render(Secondary, { props: { onMyClickEvent: myClickEventSpy } }); const buttonElement = screen.getByRole('button'); buttonElement.click(); expect(myClickEventSpy).toHaveBeenCalled(); }); it('reuses args from composeStories', () => { - const { getByText } = render(CSF3Primary()); + const { getByText } = render(CSF3Primary); const buttonElement = getByText(/foo/i); expect(buttonElement).toBeInTheDocument(); }); it('should call and compose loaders data', async () => { await LoaderStory.load(); - const { getByTestId } = render(LoaderStory()); + const { getByTestId } = render(LoaderStory); expect(getByTestId('spy-data').textContent).toEqual('mockFn return value'); expect(getByTestId('loaded-data').textContent).toEqual('loaded data'); // spy assertions happen in the play function and should work @@ -63,7 +63,7 @@ describe('projectAnnotations', () => { }, ]); const WithEnglishText = composeStory(stories.CSF2StoryWithLocale, stories.default); - const { getByText } = render(WithEnglishText()); + const { getByText } = render(WithEnglishText); const buttonElement = getByText('Hello!'); expect(buttonElement).toBeInTheDocument(); }); @@ -72,7 +72,7 @@ describe('projectAnnotations', () => { const WithPortugueseText = composeStory(stories.CSF2StoryWithLocale, stories.default, { globals: { locale: 'pt' }, }); - const { getByText } = render(WithPortugueseText()); + const { getByText } = render(WithPortugueseText); const buttonElement = getByText('Olรก!'); expect(buttonElement).toBeInTheDocument(); }); @@ -88,7 +88,7 @@ describe('CSF3', () => { it('renders with inferred globalRender', () => { const Primary = composeStory(stories.CSF3Button, stories.default); - render(Primary({ label: 'Hello world' })); + render(Primary, { props: { label: 'Hello world' } }); const buttonElement = screen.getByText(/Hello world/i); expect(buttonElement).toBeInTheDocument(); }); @@ -96,14 +96,14 @@ describe('CSF3', () => { it('renders with custom render function', () => { const Primary = composeStory(stories.CSF3ButtonWithRender, stories.default); - render(Primary()); + render(Primary); expect(screen.getByTestId('custom-render')).toBeInTheDocument(); }); it('renders with play function', async () => { const CSF3InputFieldFilled = composeStory(stories.CSF3InputFieldFilled, stories.default); - const { container } = render(CSF3InputFieldFilled()); + const { container } = render(CSF3InputFieldFilled); await CSF3InputFieldFilled.play!({ canvasElement: container as HTMLElement }); @@ -122,7 +122,7 @@ it('should pass with decorators that need addons channel', () => { }, ], }); - render(PrimaryWithChannels({ label: 'Hello world' })); + render(PrimaryWithChannels, { props: { label: 'Hello world' } }); const buttonElement = screen.getByText(/Hello world/i); expect(buttonElement).not.toBeNull(); }); diff --git a/code/renderers/vue3/src/portable-stories.ts b/code/renderers/vue3/src/portable-stories.ts index aef26b39a5e7..6321e4957bcd 100644 --- a/code/renderers/vue3/src/portable-stories.ts +++ b/code/renderers/vue3/src/portable-stories.ts @@ -11,6 +11,7 @@ import type { Store_CSFExports, StoriesWithPartialProps, } from '@storybook/types'; +import { h } from 'vue'; import * as vueProjectAnnotations from './entry-preview'; import type { Meta } from './public-types'; @@ -84,13 +85,21 @@ export function composeStory( projectAnnotations?: ProjectAnnotations, exportsName?: string ) { - return originalComposeStory( + const composedStory = originalComposeStory( story as StoryAnnotationsOrFn, componentAnnotations, projectAnnotations, defaultProjectAnnotations, exportsName ); + + // Returning h(composedStory) instead makes it an actual Vue component renderable by @testing-library/vue, Playwright CT, etc. + const renderable = (...args: Parameters) => h(composedStory(...args)); + Object.assign(renderable, composedStory); + + // typing this as newable means TS allows it to be used as a JSX element + // TODO: we should do the same for composeStories as well + return renderable as unknown as typeof composedStory & { new (...args: any[]): any }; } /** From fcd8bf2ce6d12b0eb7684f0c0ab906a9f10a949b Mon Sep 17 00:00:00 2001 From: Jeppe Reinhold Date: Tue, 5 Mar 2024 12:19:53 +0100 Subject: [PATCH 039/132] fix testing-react import in migration notes --- MIGRATION.md | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/MIGRATION.md b/MIGRATION.md index 5919ec501c42..07116d774005 100644 --- a/MIGRATION.md +++ b/MIGRATION.md @@ -89,17 +89,17 @@ - [Tab addons cannot manually route, Tool addons can filter their visibility via tabId](#tab-addons-cannot-manually-route-tool-addons-can-filter-their-visibility-via-tabid) - [Removed `config` preset](#removed-config-preset-1) - [From version 7.5.0 to 7.6.0](#from-version-750-to-760) - - [CommonJS with Vite is deprecated](#commonjs-with-vite-is-deprecated) - - [Using implicit actions during rendering is deprecated](#using-implicit-actions-during-rendering-is-deprecated) - - [typescript.skipBabel deprecated](#typescriptskipbabel-deprecated) - - [Primary doc block accepts of prop](#primary-doc-block-accepts-of-prop) - - [Addons no longer need a peer dependency on React](#addons-no-longer-need-a-peer-dependency-on-react) + - [CommonJS with Vite is deprecated](#commonjs-with-vite-is-deprecated) + - [Using implicit actions during rendering is deprecated](#using-implicit-actions-during-rendering-is-deprecated) + - [typescript.skipBabel deprecated](#typescriptskipbabel-deprecated) + - [Primary doc block accepts of prop](#primary-doc-block-accepts-of-prop) + - [Addons no longer need a peer dependency on React](#addons-no-longer-need-a-peer-dependency-on-react) - [From version 7.4.0 to 7.5.0](#from-version-740-to-750) - - [`storyStoreV6` and `storiesOf` is deprecated](#storystorev6-and-storiesof-is-deprecated) - - [`storyIndexers` is replaced with `experimental_indexers`](#storyindexers-is-replaced-with-experimental_indexers) + - [`storyStoreV6` and `storiesOf` is deprecated](#storystorev6-and-storiesof-is-deprecated) + - [`storyIndexers` is replaced with `experimental_indexers`](#storyindexers-is-replaced-with-experimental_indexers) - [From version 7.0.0 to 7.2.0](#from-version-700-to-720) - - [Addon API is more type-strict](#addon-api-is-more-type-strict) - - [Addon-controls hideNoControlsWarning parameter is deprecated](#addon-controls-hidenocontrolswarning-parameter-is-deprecated) + - [Addon API is more type-strict](#addon-api-is-more-type-strict) + - [Addon-controls hideNoControlsWarning parameter is deprecated](#addon-controls-hidenocontrolswarning-parameter-is-deprecated) - [From version 6.5.x to 7.0.0](#from-version-65x-to-700) - [7.0 breaking changes](#70-breaking-changes) - [Dropped support for Node 15 and below](#dropped-support-for-node-15-and-below) @@ -125,7 +125,7 @@ - [Deploying build artifacts](#deploying-build-artifacts) - [Dropped support for file URLs](#dropped-support-for-file-urls) - [Serving with nginx](#serving-with-nginx) - - [Ignore story files from node_modules](#ignore-story-files-from-node_modules) + - [Ignore story files from node\_modules](#ignore-story-files-from-node_modules) - [7.0 Core changes](#70-core-changes) - [7.0 feature flags removed](#70-feature-flags-removed) - [Story context is prepared before for supporting fine grained updates](#story-context-is-prepared-before-for-supporting-fine-grained-updates) @@ -139,7 +139,7 @@ - [Addon-interactions: Interactions debugger is now default](#addon-interactions-interactions-debugger-is-now-default) - [7.0 Vite changes](#70-vite-changes) - [Vite builder uses Vite config automatically](#vite-builder-uses-vite-config-automatically) - - [Vite cache moved to node_modules/.cache/.vite-storybook](#vite-cache-moved-to-node_modulescachevite-storybook) + - [Vite cache moved to node\_modules/.cache/.vite-storybook](#vite-cache-moved-to-node_modulescachevite-storybook) - [7.0 Webpack changes](#70-webpack-changes) - [Webpack4 support discontinued](#webpack4-support-discontinued) - [Babel mode v7 exclusively](#babel-mode-v7-exclusively) @@ -189,7 +189,7 @@ - [Dropped addon-docs manual babel configuration](#dropped-addon-docs-manual-babel-configuration) - [Dropped addon-docs manual configuration](#dropped-addon-docs-manual-configuration) - [Autoplay in docs](#autoplay-in-docs) - - [Removed STORYBOOK_REACT_CLASSES global](#removed-storybook_react_classes-global) + - [Removed STORYBOOK\_REACT\_CLASSES global](#removed-storybook_react_classes-global) - [7.0 Deprecations and default changes](#70-deprecations-and-default-changes) - [storyStoreV7 enabled by default](#storystorev7-enabled-by-default) - [`Story` type deprecated](#story-type-deprecated) @@ -1061,7 +1061,7 @@ The `hideNoControlsWarning` parameter is now removed. [More info here](#addon-co The `setGlobalConfig` (used for reusing stories in your tests) is now removed in favor of `setProjectAnnotations`. ```ts -import { setProjectAnnotations } from `@storybook/testing-react`. +import { setProjectAnnotations } from `@storybook/react`. ``` #### StorybookViteConfig type from @storybook/builder-vite From e286d2b986fd59fd358fc54c355356228a142d3d Mon Sep 17 00:00:00 2001 From: Jeppe Reinhold Date: Tue, 5 Mar 2024 12:31:31 +0100 Subject: [PATCH 040/132] add migration note about new composeStory Vue API --- MIGRATION.md | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/MIGRATION.md b/MIGRATION.md index 07116d774005..dd4bfee85ee6 100644 --- a/MIGRATION.md +++ b/MIGRATION.md @@ -5,6 +5,7 @@ - [Project annotations are now merged instead of overwritten in composeStory](#project-annotations-are-now-merged-instead-of-overwritten-in-composestory) - [Type change in `composeStories` API](#type-change-in-composestories-api) - [DOM structure changed in portable stories](#dom-structure-changed-in-portable-stories) + - [Composed Vue stories are now components instead of functions](#composed-vue-stories-are-now-components-instead-of-functions) - [Tab addons are now routed to a query parameter](#tab-addons-are-now-routed-to-a-query-parameter) - [Default keyboard shortcuts changed](#default-keyboard-shortcuts-changed) - [Manager addons are now rendered with React 18](#manager-addons-are-now-rendered-with-react-18) @@ -467,6 +468,25 @@ test("snapshots the story with custom id", () => { }); ``` +#### Composed Vue stories are now components instead of functions + +`composeStory` (and `composeStories`) from `@storybook/vue3` now returns Vue components rather than story functions that return components. This means that when rendering these composed stories you just pass the composed story _without_ first calling it. + +Previously when using `composeStory` from `@storybook/testing-vue` you would render composed stories with eg. `render(MyStoryComposedStory({ someProps: true}))`. That is now changed to more [closely match how you would render regular Vue components](https://testing-library.com/docs/vue-testing-library/examples). Here's an example using `@testing-library/vue` and Vitest: + +```diff +import { it } from 'vitest'; +import { render } from '@testing-library/vue'; +import * as stories from './Button.stories'; +import { composeStory } from '@storybook/vue3'; + +it('renders primary button', () => { + const ComposedButton = composeStory(sotries.Primary); +- render(ComposedButton({ label: 'Hello world' })); ++ render(ComposedButton, { props: { label: 'Hello world' } }); +}); +``` + ### Tab addons are now routed to a query parameter The URL of a tab used to be: `http://localhost:6006/?path=/my-addon-tab/my-story`. From 12f5c82b2ef74c094e697c3a771431b17238c5d8 Mon Sep 17 00:00:00 2001 From: Jeppe Reinhold Date: Tue, 5 Mar 2024 12:56:04 +0100 Subject: [PATCH 041/132] use `user` directly from GH PR info instead of links.user --- scripts/release/generate-pr-description.ts | 4 +--- scripts/release/utils/get-changes.ts | 9 ++++----- scripts/release/utils/get-github-info.ts | 4 ++-- 3 files changed, 7 insertions(+), 10 deletions(-) diff --git a/scripts/release/generate-pr-description.ts b/scripts/release/generate-pr-description.ts index 438c13fb4a91..7b4e397dea2c 100644 --- a/scripts/release/generate-pr-description.ts +++ b/scripts/release/generate-pr-description.ts @@ -1,4 +1,3 @@ -/* eslint-disable no-console */ import chalk from 'chalk'; import program from 'commander'; import { z } from 'zod'; @@ -65,7 +64,6 @@ export const mapToChangelist = ({ }): string => { return changes .filter((change) => { - // eslint-disable-next-line no-restricted-syntax for (const titleToIgnore of CHANGE_TITLES_TO_IGNORE) { if (change.title?.match(titleToIgnore)) { return false; @@ -227,7 +225,7 @@ export const generateNonReleaseDescription = ( - Merge this PR - [Follow the run of the publish action](https://github.com/storybookjs/storybook/actions/workflows/publish.yml)` // don't mention contributors in the release PR, to avoid spamming them - .replaceAll('[@', '[@ ') + .replaceAll('@', '') .replaceAll('"', '\\"') .replaceAll('`', '\\`') .replaceAll("'", "\\'") diff --git a/scripts/release/utils/get-changes.ts b/scripts/release/utils/get-changes.ts index 416ea624fb50..8d2811d486db 100644 --- a/scripts/release/utils/get-changes.ts +++ b/scripts/release/utils/get-changes.ts @@ -1,4 +1,3 @@ -/* eslint-disable no-console */ import chalk from 'chalk'; import semver from 'semver'; import type { PullRequestInfo } from './get-github-info'; @@ -206,11 +205,11 @@ export const getChangelogText = ({ return entry.labels?.some((label) => Object.keys(RELEASED_LABELS).includes(label)); }) .map((entry) => { - const { title, links } = entry; - const { pull, commit, user } = links; + const { title, user, links } = entry; + const { pull, commit } = links; return pull - ? `- ${title} - ${pull}, thanks ${user}!` - : `- โš ๏ธ _Direct commit_ ${title} - ${commit} by ${user}`; + ? `- ${title} - ${pull}, thanks @${user}!` + : `- โš ๏ธ _Direct commit_ ${title} - ${commit} by @${user}`; }) .sort(); const text = [heading, '', ...formattedEntries].join('\n'); diff --git a/scripts/release/utils/get-github-info.ts b/scripts/release/utils/get-github-info.ts index 0247e8319e04..e124026d7133 100644 --- a/scripts/release/utils/get-github-info.ts +++ b/scripts/release/utils/get-github-info.ts @@ -255,7 +255,7 @@ export async function getPullInfoFromCommit(request: { pull: associatedPullRequest ? `[#${associatedPullRequest.number}](${associatedPullRequest.url})` : null, - user: user ? `@${user.login}` : null, + user: user ? `[@${user.login}](${user.url})` : null, }, }; } @@ -294,7 +294,7 @@ export async function getPullInfoFromPullRequest(request: { links: { commit: commit ? `[\`${commit.oid}\`](${commit.commitUrl})` : null, pull: `[#${request.pull}](https://github.com/${request.repo}/pull/${request.pull})`, - user: user ? `@${user.login}` : null, + user: user ? `[@${user.login}](${user.url})` : null, }, }; } From 9fdc7a23a91aa0f9cbc1e502f5b30751a291583e Mon Sep 17 00:00:00 2001 From: jonniebigodes Date: Tue, 5 Mar 2024 12:12:20 +0000 Subject: [PATCH 042/132] Docs: Snapshot testing updates --- ...napshot-tests-portable-stories.jest.js.mdx | 69 ++++++++ ...napshot-tests-portable-stories.jest.ts.mdx | 82 +++++++++ ...pshot-tests-portable-stories.vitest.js.mdx | 64 +++++++ ...pshot-tests-portable-stories.vitest.ts.mdx | 74 ++++++++ ...napshot-tests-portable-stories.jest.js.mdx | 64 +++++++ ...napshot-tests-portable-stories.jest.ts.mdx | 72 ++++++++ ...pshot-tests-portable-stories.vitest.js.mdx | 62 +++++++ ...pshot-tests-portable-stories.vitest.ts.mdx | 72 ++++++++ ...-snapshot-resolver-custom-directory.js.mdx | 19 ++ ...snapshot-test-portable-stories.jest.js.mdx | 14 ++ ...apshot-test-portable-stories.vitest.js.mdx | 18 ++ ...-testing-addon-optional-config.vite.js.mdx | 20 +++ ...-testing-addon-optional-config.vite.ts.mdx | 21 +++ ...tton-snapshot-test-portable-stories.js.mdx | 18 ++ docs/toc.js | 4 +- docs/writing-tests/snapshot-testing.md | 165 +++++++++++++----- docs/writing-tests/storyshots-fail.png | Bin 81300 -> 0 bytes docs/writing-tests/storyshots-pass.png | Bin 52729 -> 0 bytes 18 files changed, 792 insertions(+), 46 deletions(-) create mode 100644 docs/snippets/common/individual-snapshot-tests-portable-stories.jest.js.mdx create mode 100644 docs/snippets/common/individual-snapshot-tests-portable-stories.jest.ts.mdx create mode 100644 docs/snippets/common/individual-snapshot-tests-portable-stories.vitest.js.mdx create mode 100644 docs/snippets/common/individual-snapshot-tests-portable-stories.vitest.ts.mdx create mode 100644 docs/snippets/common/snapshot-tests-portable-stories.jest.js.mdx create mode 100644 docs/snippets/common/snapshot-tests-portable-stories.jest.ts.mdx create mode 100644 docs/snippets/common/snapshot-tests-portable-stories.vitest.js.mdx create mode 100644 docs/snippets/common/snapshot-tests-portable-stories.vitest.ts.mdx create mode 100644 docs/snippets/common/test-runner-snapshot-resolver-custom-directory.js.mdx create mode 100644 docs/snippets/react/button-snapshot-test-portable-stories.jest.js.mdx create mode 100644 docs/snippets/react/button-snapshot-test-portable-stories.vitest.js.mdx create mode 100644 docs/snippets/react/storybook-testing-addon-optional-config.vite.js.mdx create mode 100644 docs/snippets/react/storybook-testing-addon-optional-config.vite.ts.mdx create mode 100644 docs/snippets/vue/button-snapshot-test-portable-stories.js.mdx delete mode 100644 docs/writing-tests/storyshots-fail.png delete mode 100644 docs/writing-tests/storyshots-pass.png diff --git a/docs/snippets/common/individual-snapshot-tests-portable-stories.jest.js.mdx b/docs/snippets/common/individual-snapshot-tests-portable-stories.jest.js.mdx new file mode 100644 index 000000000000..e9523fa3b322 --- /dev/null +++ b/docs/snippets/common/individual-snapshot-tests-portable-stories.jest.js.mdx @@ -0,0 +1,69 @@ +```js +// storybook.test.js +import path from 'path'; +import * as glob from 'glob'; + +//๐Ÿ‘‡ Augment expect with jest-specific-snapshot +import 'jest-specific-snapshot'; + +import { describe, test, expect } from '@jest/globals'; + +// Replace your-testing-library with one of the supported testing libraries (e.g., react, vue) +import { render } from '@testing-library/your-testing-library'; + +// Adjust the import based on the supported framework or Storybook's testing libraries (e.g., react, vue3) +import { composeStories } from '@storybook/your-framework'; + +const compose = (entry) => { + try { + return composeStories(entry); + } catch (e) { + throw new Error( + `There was an issue composing stories for the module: ${JSON.stringify(entry)}, ${e}`, + ); + } +}; + +function getAllStoryFiles() { + // Place the glob you want to match your stories files + const storyFiles = glob.sync( + path.join(__dirname, 'stories/**/*.{stories,story}.{js,jsx,mjs,ts,tsx}'), + ); + + return storyFiles.map((filePath) => { + const storyFile = require(filePath); + const storyDir = path.dirname(filePath); + const componentName = path.basename(filePath).replace(/\.(stories|story)\.[^/.]+$/, ''); + + return { filePath, storyFile, storyDir, componentName }; + }); +} + +describe('Stories Snapshots', () => { + getAllStoryFiles().forEach(({ storyFile, componentName }) => { + const meta = storyFile.default; + const title = meta.title || componentName; + + describe(title, () => { + const stories = Object.entries(compose(storyFile)).map(([name, story]) => ({ name, story })); + + if (stories.length <= 0) { + throw new Error( + `No stories found for this module: ${title}. Make sure there is at least one valid story for this module.`, + ); + } + + stories.forEach(({ name, story }) => { + test(name, async () => { + const mounted = render(story()); + // Ensures a consistent snapshot by waiting for the component to render by adding a delay of 1 ms before taking the snapshot. + await new Promise((resolve) => setTimeout(resolve, 1)); + // Defines the custom snapshot path location and file name + const customSnaphotPath = `./__snapshots__/${componentName}.test.js.snap`; + expect(mounted.container).toMatchSpecificSnapshot(customSnaphotPath); + }); + }); + }); + }); +}); +``` diff --git a/docs/snippets/common/individual-snapshot-tests-portable-stories.jest.ts.mdx b/docs/snippets/common/individual-snapshot-tests-portable-stories.jest.ts.mdx new file mode 100644 index 000000000000..e245ec4c1ee9 --- /dev/null +++ b/docs/snippets/common/individual-snapshot-tests-portable-stories.jest.ts.mdx @@ -0,0 +1,82 @@ +```ts +// storybook.test.ts +// Replace your-framework with one of the supported Storybook frameworks (react, vue3) +import type { Meta, StoryFn } from '@storybook/your-framework'; + +import path from "path"; +import * as glob from "glob"; + +//๐Ÿ‘‡ Augment expect with jest-specific-snapshot +import "jest-specific-snapshot"; + +import { describe, test, expect } from "@jest/globals"; + +// Replace your-testing-library with one of the supported testing libraries (e.g., react, vue) +import { render } from '@testing-library/your-testing-library'; + +// Adjust the import based on the supported framework or Storybook's testing libraries (e.g., react, vue3) +import { composeStories } from '@storybook/your-framework'; + +type StoryFile = { + default: Meta; + [name: string]: StoryFn | Meta; +}; + +const compose = ( + entry: StoryFile +): ReturnType> => { + try { + return composeStories(entry); + } catch (e) { + throw new Error( + `There was an issue composing stories for the module: ${JSON.stringify(entry)}, ${e}` + ); + } +}; + +function getAllStoryFiles() { + // Place the glob you want to match your stories files + const storyFiles = glob.sync( + path.join(__dirname, 'stories/**/*.{stories,story}.{js,jsx,mjs,ts,tsx}'), + ); + + return storyFiles.map((filePath) => { + const storyFile = require(filePath); + const storyDir = path.dirname(filePath); + const componentName = path + .basename(filePath) + .replace(/\.(stories|story)\.[^/.]+$/, ""); + + return { filePath, storyFile, storyDir, componentName }; + }); +} + +describe("Stories Snapshots", () => { + getAllStoryFiles().forEach(({ storyFile, componentName }) => { + const meta = storyFile.default; + const title = meta.title || componentName; + + describe(title, () => { + const stories = Object.entries(compose(storyFile)).map( + ([name, story]) => ({ name, story }) + ); + + if (stories.length <= 0) { + throw new Error( + `No stories found for this module: ${title}. Make sure there is at least one valid story for this module.` + ); + } + + stories.forEach(({ name, story }) => { + test(name, async () => { + const mounted = render(story()); + // Ensures a consistent snapshot by waiting for the component to render by adding a delay of 1 ms before taking the snapshot. + await new Promise((resolve) => setTimeout(resolve, 1)); + // Defines the custom snapshot path location and file name + const customSnaphotPath = `./__snapshots__/${componentName}.test.ts.snap`; + expect(mounted.container).toMatchSpecificSnapshot(customSnaphotPath); + }); + }); + }); +}); +``` diff --git a/docs/snippets/common/individual-snapshot-tests-portable-stories.vitest.js.mdx b/docs/snippets/common/individual-snapshot-tests-portable-stories.vitest.js.mdx new file mode 100644 index 000000000000..111149d958bb --- /dev/null +++ b/docs/snippets/common/individual-snapshot-tests-portable-stories.vitest.js.mdx @@ -0,0 +1,64 @@ +```js +// storybook.test.js +// @vitest-environment jsdom + +import path from 'path'; +import { describe, expect, test } from 'vitest'; + +// Replace your-testing-library with one of the supported testing libraries (e.g., react, vue) +import { render } from '@testing-library/your-testing-library'; + +// Adjust the import based on the supported framework or Storybook's testing libraries (e.g., react, vue3) +import { composeStories } from '@storybook/your-framework'; + +const compose = (entry) => { + try { + return composeStories(entry); + } catch (error) { + throw new Error( + `There was an issue composing stories for the module: ${JSON.stringify(entry)}, ${error}`, + ); + } +}; +function getAllStoryFiles() { + // Place the glob you want to match your story files + const storyFiles = Object.entries( + import.meta.glob('./stories/**/*.(stories|story).@(js|jsx|mjs|ts|tsx)', { + eager: true, + }), + ); + + return storyFiles.map(([filePath, storyFile]) => { + const storyDir = path.dirname(filePath); + const componentName = path.basename(filePath).replace(/\.(stories|story)\.[^/.]+$/, ''); + return { filePath, storyFile, componentName, storyDir }; + }); +} +describe('Stories Snapshots', () => { + getAllStoryFiles().forEach(({ storyFile, componentName }) => { + const meta = storyFile.default; + const title = meta.title || componentName; + + describe(title, () => { + const stories = Object.entries(compose(storyFile)).map(([name, story]) => ({ name, story })); + + if (stories.length <= 0) { + throw new Error( + `No stories found for this module: ${title}. Make sure there is at least one valid story for this module.`, + ); + } + + stories.forEach(({ name, story }) => { + test(name, async () => { + const mounted = render(story()); + // Ensures a consistent snapshot by waiting for the component to render by adding a delay of 1 ms before taking the snapshot. + await new Promise((resolve) => setTimeout(resolve, 1)); + // Defines the custom snapshot path location and file name + const customSnaphotPath = `./__snapshots__/${componentName}.spec.js.snap`; + expect(mounted.container).toMatchFileSnapshot(customSnaphotPath); + }); + }); + }); + }); +}); +``` diff --git a/docs/snippets/common/individual-snapshot-tests-portable-stories.vitest.ts.mdx b/docs/snippets/common/individual-snapshot-tests-portable-stories.vitest.ts.mdx new file mode 100644 index 000000000000..5c3f6097dae8 --- /dev/null +++ b/docs/snippets/common/individual-snapshot-tests-portable-stories.vitest.ts.mdx @@ -0,0 +1,74 @@ +```ts +// storybook.test.ts +// @vitest-environment jsdom + +// Replace your-framework with one of the supported Storybook frameworks (react, vue3) +import type { Meta, StoryFn } from '@storybook/your-framework'; + +import path from 'path'; +import { describe, expect, test } from 'vitest'; + +// Replace your-testing-library with one of the supported testing libraries (e.g., react, vue) +import { render } from '@testing-library/your-testing-library'; + +// Adjust the import based on the supported framework or Storybook's testing libraries (e.g., react, vue3) +import { composeStories } from '@storybook/your-framework'; + +type StoryFile = { + default: Meta; + [name: string]: StoryFn | Meta; +}; + +const compose = (entry: StoryFile): ReturnType> => { + try { + return composeStories(entry); + } catch (e) { + throw new Error( + `There was an issue composing stories for the module: ${JSON.stringify(entry)}, ${e}`, + ); + } +}; + +function getAllStoryFiles() { + // Place the glob you want to match your story files + const storyFiles = Object.entries( + import.meta.glob('./stories/**/*.(stories|story).@(js|jsx|mjs|ts|tsx)', { + eager: true, + }), + ); + + return storyFiles.map(([filePath, storyFile]) => { + const storyDir = path.dirname(filePath); + const componentName = path.basename(filePath).replace(/\.(stories|story)\.[^/.]+$/, ''); + return { filePath, storyFile, componentName, storyDir }; + }); +} + +describe('Stories Snapshots', () => { + getAllStoryFiles().forEach(({ storyFile, componentName }) => { + const meta = storyFile.default; + const title = meta.title || componentName; + + describe(title, () => { + const stories = Object.entries(compose(storyFile)).map(([name, story]) => ({ name, story })); + + if (stories.length <= 0) { + throw new Error( + `No stories found for this module: ${title}. Make sure there is at least one valid story for this module.`, + ); + } + + stories.forEach(({ name, story }) => { + test(name, async () => { + const mounted = render(story()); + // Ensures a consistent snapshot by waiting for the component to render by adding a delay of 1 ms before taking the snapshot. + await new Promise((resolve) => setTimeout(resolve, 1)); + // Defines the custom snapshot path location and file name + const customSnaphotPath = `./__snapshots__/${componentName}.spec.ts.snap`; + expect(mounted.container).toMatchFileSnapshot(customSnaphotPath); + }); + }); + }); + }); +}); +``` diff --git a/docs/snippets/common/snapshot-tests-portable-stories.jest.js.mdx b/docs/snippets/common/snapshot-tests-portable-stories.jest.js.mdx new file mode 100644 index 000000000000..eddd82a08227 --- /dev/null +++ b/docs/snippets/common/snapshot-tests-portable-stories.jest.js.mdx @@ -0,0 +1,64 @@ +```js +// storybook.test.js +import path from 'path'; +import * as glob from 'glob'; + +import { describe, test, expect } from '@jest/globals'; + +// Replace your-testing-library with one of the supported testing libraries (e.g., react, vue) +import { render } from '@testing-library/your-testing-library'; + +// Adjust the import based on the supported framework or Storybook's testing libraries (e.g., react, vue3) +import { composeStories } from '@storybook/your-framework'; + +const compose = (entry) => { + try { + return composeStories(entry); + } catch (e) { + throw new Error( + `There was an issue composing stories for the module: ${JSON.stringify(entry)}, ${e}`, + ); + } +}; + +function getAllStoryFiles() { + // Place the glob you want to match your stories files + const storyFiles = glob.sync( + path.join(__dirname, 'stories/**/*.{stories,story}.{js,jsx,mjs,ts,tsx}'), + ); + + return storyFiles.map((filePath) => { + const storyFile = require(filePath); + const storyDir = path.dirname(filePath); + const componentName = path.basename(filePath).replace(/\.(stories|story)\.[^/.]+$/, ''); + + return { filePath, storyFile, storyDir, componentName }; + }); +} + +describe('Stories Snapshots', () => { + getAllStoryFiles().forEach(({ storyFile, componentName }) => { + const meta = storyFile.default; + const title = meta.title || componentName; + + describe(title, () => { + const stories = Object.entries(compose(storyFile)).map(([name, story]) => ({ name, story })); + + if (stories.length <= 0) { + throw new Error( + `No stories found for this module: ${title}. Make sure there is at least one valid story for this module.`, + ); + } + + stories.forEach(({ name, story }) => { + test(name, async () => { + const mounted = render(story()); + // Ensures a consistent snapshot by waiting for the component to render by adding a delay of 1 ms before taking the snapshot. + await new Promise((resolve) => setTimeout(resolve, 1)); + expect(mounted.container).toMatchSnapshot(); + }); + }); + }); + }); +}); +``` diff --git a/docs/snippets/common/snapshot-tests-portable-stories.jest.ts.mdx b/docs/snippets/common/snapshot-tests-portable-stories.jest.ts.mdx new file mode 100644 index 000000000000..1cfbe1bdbb35 --- /dev/null +++ b/docs/snippets/common/snapshot-tests-portable-stories.jest.ts.mdx @@ -0,0 +1,72 @@ +```ts +// storybook.test.ts +// Replace your-framework with one of the supported Storybook frameworks (react, vue3) +import type { Meta, StoryFn } from '@storybook/your-framework'; + +import path from 'path'; +import * as glob from 'glob'; + +import { describe, test, expect } from '@jest/globals'; + +// Replace your-testing-library with one of the supported testing libraries (e.g., react, vue) +import { render } from '@testing-library/your-testing-library'; + +// Adjust the import based on the supported framework or Storybook's testing libraries (e.g., react, vue3) +import { composeStories } from '@storybook/your-framework'; + +type StoryFile = { + default: Meta; + [name: string]: StoryFn | Meta; +}; + +const compose = (entry: StoryFile): ReturnType> => { + try { + return composeStories(entry); + } catch (e) { + throw new Error( + `There was an issue composing stories for the module: ${JSON.stringify(entry)}, ${e}`, + ); + } +}; + +function getAllStoryFiles() { + // Place the glob you want to match your stories files + const storyFiles = glob.sync( + path.join(__dirname, 'stories/**/*.{stories,story}.{js,jsx,mjs,ts,tsx}'), + ); + + return storyFiles.map((filePath) => { + const storyFile = require(filePath); + const storyDir = path.dirname(filePath); + const componentName = path.basename(filePath).replace(/\.(stories|story)\.[^/.]+$/, ''); + + return { filePath, storyFile, storyDir, componentName }; + }); +} + +describe('Stories Snapshots', () => { + getAllStoryFiles().forEach(({ storyFile, componentName }) => { + const meta = storyFile.default; + const title = meta.title || componentName; + + describe(title, () => { + const stories = Object.entries(compose(storyFile)).map(([name, story]) => ({ name, story })); + + if (stories.length <= 0) { + throw new Error( + `No stories found for this module: ${title}. Make sure there is at least one valid story for this module.`, + ); + } + + stories.forEach(({ name, story }) => { + test(name, async () => { + const mounted = render(story()); + // Ensures a consistent snapshot by waiting for the component to render by adding a delay of 1 ms before taking the snapshot. + await new Promise((resolve) => setTimeout(resolve, 1)); + expect(mounted.container).toMatchSnapshot(); + }); + }); + }); + }); +}); +``` diff --git a/docs/snippets/common/snapshot-tests-portable-stories.vitest.js.mdx b/docs/snippets/common/snapshot-tests-portable-stories.vitest.js.mdx new file mode 100644 index 000000000000..dbaa397f1bb3 --- /dev/null +++ b/docs/snippets/common/snapshot-tests-portable-stories.vitest.js.mdx @@ -0,0 +1,62 @@ +```js +// storybook.test.js +// @vitest-environment jsdom + +import path from 'path'; +import { describe, expect, test } from 'vitest'; + +// Replace your-testing-library with one of the supported testing libraries (e.g., react, vue) +import { render } from '@testing-library/your-testing-library'; + +// Adjust the import based on the supported framework or Storybook's testing libraries (e.g., react, vue3) +import { composeStories } from '@storybook/your-framework'; + +const compose = (entry) => { + try { + return composeStories(entry); + } catch (error) { + throw new Error( + `There was an issue composing stories for the module: ${JSON.stringify(entry)}, ${error}`, + ); + } +}; +function getAllStoryFiles() { + // Place the glob you want to match your story files + const storyFiles = Object.entries( + import.meta.glob('./stories/**/*.(stories|story).@(js|jsx|mjs|ts|tsx)', { + eager: true, + }), + ); + + return storyFiles.map(([filePath, storyFile]) => { + const storyDir = path.dirname(filePath); + const componentName = path.basename(filePath).replace(/\.(stories|story)\.[^/.]+$/, ''); + return { filePath, storyFile, componentName, storyDir }; + }); +} +describe('Stories Snapshots', () => { + getAllStoryFiles().forEach(({ storyFile, componentName }) => { + const meta = storyFile.default; + const title = meta.title || componentName; + + describe(title, () => { + const stories = Object.entries(compose(storyFile)).map(([name, story]) => ({ name, story })); + + if (stories.length <= 0) { + throw new Error( + `No stories found for this module: ${title}. Make sure there is at least one valid story for this module.`, + ); + } + + stories.forEach(({ name, story }) => { + test(name, async () => { + const mounted = render(story()); + // Ensures a consistent snapshot by waiting for the component to render by adding a delay of 1 ms before taking the snapshot. + await new Promise((resolve) => setTimeout(resolve, 1)); + expect(mounted.container).toMatchSnapshot(); + }); + }); + }); + }); +}); +``` diff --git a/docs/snippets/common/snapshot-tests-portable-stories.vitest.ts.mdx b/docs/snippets/common/snapshot-tests-portable-stories.vitest.ts.mdx new file mode 100644 index 000000000000..456bf5a1ae9d --- /dev/null +++ b/docs/snippets/common/snapshot-tests-portable-stories.vitest.ts.mdx @@ -0,0 +1,72 @@ +```ts +// storybook.test.ts +// @vitest-environment jsdom + +// Replace your-framework with one of the supported Storybook frameworks (react, vue3) +import type { Meta, StoryFn } from '@storybook/your-framework'; + +import path from 'path'; +import { describe, expect, test } from 'vitest'; + +// Replace your-testing-library with one of the supported testing libraries (e.g., react, vue) +import { render } from '@testing-library/your-testing-library'; + +// Adjust the import based on the supported framework or Storybook's testing libraries (e.g., react, vue3) +import { composeStories } from '@storybook/your-framework'; + +type StoryFile = { + default: Meta; + [name: string]: StoryFn | Meta; +}; + +const compose = (entry: StoryFile): ReturnType> => { + try { + return composeStories(entry); + } catch (e) { + throw new Error( + `There was an issue composing stories for the module: ${JSON.stringify(entry)}, ${e}`, + ); + } +}; + +function getAllStoryFiles() { + // Place the glob you want to match your story files + const storyFiles = Object.entries( + import.meta.glob('./stories/**/*.(stories|story).@(js|jsx|mjs|ts|tsx)', { + eager: true, + }), + ); + + return storyFiles.map(([filePath, storyFile]) => { + const storyDir = path.dirname(filePath); + const componentName = path.basename(filePath).replace(/\.(stories|story)\.[^/.]+$/, ''); + return { filePath, storyFile, componentName, storyDir }; + }); +} + +describe('Stories Snapshots', () => { + getAllStoryFiles().forEach(({ storyFile, componentName }) => { + const meta = storyFile.default; + const title = meta.title || componentName; + + describe(title, () => { + const stories = Object.entries(compose(storyFile)).map(([name, story]) => ({ name, story })); + + if (stories.length <= 0) { + throw new Error( + `No stories found for this module: ${title}. Make sure there is at least one valid story for this module.`, + ); + } + + stories.forEach(({ name, story }) => { + test(name, async () => { + const mounted = render(story()); + // Ensures a consistent snapshot by waiting for the component to render by adding a delay of 1 ms before taking the snapshot. + await new Promise((resolve) => setTimeout(resolve, 1)); + expect(mounted.container).toMatchSnapshot(); + }); + }); + }); + }); +}); +``` diff --git a/docs/snippets/common/test-runner-snapshot-resolver-custom-directory.js.mdx b/docs/snippets/common/test-runner-snapshot-resolver-custom-directory.js.mdx new file mode 100644 index 000000000000..203c8d30cbb2 --- /dev/null +++ b/docs/snippets/common/test-runner-snapshot-resolver-custom-directory.js.mdx @@ -0,0 +1,19 @@ +```js +// ./snapshot-resolver.js +import path from 'path'; + +export default { + resolveSnapshotPath: (testPath) => { + const fileName = path.basename(testPath); + const fileNameWithoutExtension = fileName.replace(/\.[^/.]+$/, ''); + // Defines the file extension for the snapshot file + const modifiedFileName = `${fileNameWithoutExtension}.snap`; + + // Configure Jest to generate snapshot files using the following convention (./src/test/__snapshots__/Button.stories.snap) + return path.join('./src/test/__snapshots__', modifiedFileName); + }, + resolveTestPath: (snapshotFilePath, snapshotExtension) => + path.basename(snapshotFilePath, snapshotExtension), + testPathForConsistencyCheck: 'example', +}; +``` diff --git a/docs/snippets/react/button-snapshot-test-portable-stories.jest.js.mdx b/docs/snippets/react/button-snapshot-test-portable-stories.jest.js.mdx new file mode 100644 index 000000000000..335eb461d736 --- /dev/null +++ b/docs/snippets/react/button-snapshot-test-portable-stories.jest.js.mdx @@ -0,0 +1,14 @@ +```js +// test/Button.test.js|ts +import { render } from '@testing-library/react'; + +import { composeStories } from '@storybook/react'; + +import * as stories from '../stories/Button.stories'; + +const { Primary } = composeStories(stories); +test('Button snapshot', async () => { + const mounted = render(); + expect(mounted.container).toMatchSnapshot(); +}); +``` diff --git a/docs/snippets/react/button-snapshot-test-portable-stories.vitest.js.mdx b/docs/snippets/react/button-snapshot-test-portable-stories.vitest.js.mdx new file mode 100644 index 000000000000..982992cc65aa --- /dev/null +++ b/docs/snippets/react/button-snapshot-test-portable-stories.vitest.js.mdx @@ -0,0 +1,18 @@ +```js +// test/Button.test.js|ts +// @vitest-environment jsdom + +import { expect, test } from 'vitest'; + +import { render } from '@testing-library/react'; + +import { composeStories } from '@storybook/react'; + +import * as stories from '../stories/Button.stories'; + +const { Primary } = composeStories(stories); +test('Button snapshot', async () => { + const mounted = render(Primary()); + expect(mounted.container).toMatchSnapshot(); +}); +``` diff --git a/docs/snippets/react/storybook-testing-addon-optional-config.vite.js.mdx b/docs/snippets/react/storybook-testing-addon-optional-config.vite.js.mdx new file mode 100644 index 000000000000..a50bd78cb49b --- /dev/null +++ b/docs/snippets/react/storybook-testing-addon-optional-config.vite.js.mdx @@ -0,0 +1,20 @@ +```js +// vitest.config.js + +import { defineConfig } from 'vitest/config'; +import { mergeConfig } from 'vite'; + +import viteConfig from './vite.config'; + +export default mergeConfig( + viteConfig, + defineConfig({ + test: { + globals: true, + environment: 'jsdom', + clearMocks: true, + setupFiles: './src/setupTests.js', //๐Ÿ‘ˆ Our configuration file enabled here + }, + }), +); +``` diff --git a/docs/snippets/react/storybook-testing-addon-optional-config.vite.ts.mdx b/docs/snippets/react/storybook-testing-addon-optional-config.vite.ts.mdx new file mode 100644 index 000000000000..3161eb45448c --- /dev/null +++ b/docs/snippets/react/storybook-testing-addon-optional-config.vite.ts.mdx @@ -0,0 +1,21 @@ +```ts +// vitest.config.ts + +/// +import { defineConfig } from 'vitest/config'; +import { mergeConfig } from 'vite'; + +import viteConfig from './vite.config'; + +export default mergeConfig( + viteConfig, + defineConfig({ + test: { + globals: true, + environment: 'jsdom', + clearMocks: true, + setupFiles: './src/setupTests.ts', //๐Ÿ‘ˆ Our configuration file enabled here + }, + }), +); +``` diff --git a/docs/snippets/vue/button-snapshot-test-portable-stories.js.mdx b/docs/snippets/vue/button-snapshot-test-portable-stories.js.mdx new file mode 100644 index 000000000000..06d28200e454 --- /dev/null +++ b/docs/snippets/vue/button-snapshot-test-portable-stories.js.mdx @@ -0,0 +1,18 @@ +```js +// __tests__/Button.spec.js|ts +// @vitest-environment jsdom + +import { expect, test } from 'vitest'; + +import { render } from '@testing-library/vue'; + +import { composeStories } from '@storybook/vue3'; + +import * as stories from '../stories/Button.stories'; + +const { Primary } = composeStories(stories); +test('Button snapshot', async () => { + const mounted = render(Primary()); + expect(mounted.container).toMatchSnapshot(); +}); +``` diff --git a/docs/toc.js b/docs/toc.js index b7ee152fb8c6..c15cda4c5bec 100644 --- a/docs/toc.js +++ b/docs/toc.js @@ -173,12 +173,12 @@ module.exports = { children: [ { pathSegment: 'snapshot-testing', - title: 'Storyshots', + title: 'Write', type: 'link', }, { pathSegment: 'storyshots-migration-guide', - title: 'Migration guide', + title: 'Storyshots migration guide', type: 'link', }, ], diff --git a/docs/writing-tests/snapshot-testing.md b/docs/writing-tests/snapshot-testing.md index 438258b36adb..36616674380d 100644 --- a/docs/writing-tests/snapshot-testing.md +++ b/docs/writing-tests/snapshot-testing.md @@ -1,5 +1,5 @@ --- -title: 'Snapshot testing with Storyshots' +title: 'Write snapshot tests' --- Snapshot tests compare the rendered markup of every story against known baselines. Itโ€™s a way to identify markup changes that trigger rendering errors and warnings. @@ -8,118 +8,195 @@ Storybook is a helpful tool for snapshot testing because every story is essentia ![Example Snapshot test](./snapshot-test.png) -## Migrating Tests + -The Storyshots addon was the original testing solution for Storybook, offering a highly extensible API and a wide range of configuration options for testing. However, it was difficult to set up and maintain, and it needed to be compatible with the latest version of Storybook, which introduced some significant architectural changes, including a high-performance [on-demand story loading](../configure/index.md#on-demand-story-loading) feature. As a result, Storyshots is now officially deprecated, is no longer being maintained, and will be removed in the next major release of Storybook. We recommend following the [migration guide](./storyshots-migration-guide.md) we've prepared to help you during this transition period. +If you're [upgrading](../configure/upgrading.md) to Storybook 8.0 and were using the Storyshots addon for snapshot testing, it was officially deprecated and removed with this release. See the [migration guide](./storyshots-migration-guide.md) for more information. -## Set up Storyshots + + +## Automate snapshot tests with the test-runner + +Storybook test-runner turns all of your stories into executable tests. Powered by [Jest](https://jestjs.io/) and [Playwright](https://playwright.dev/). It's a standalone, framework-agnostic utility that runs parallel to your Storybook. It enables you to run multiple testing patterns in a multi-browser environment, including interaction testing with the [play function](./interaction-testing.md), DOM snapshot, and [accessibility testing](./accessibility-testing.md). - +### Setup -The Storyshots addon was deprecated and has been removed in Storybook 8. See the [migration guide](./storyshots-migration-guide.md) for more information. +To enable snapshot testing with the test-runner, you'll need to take additional steps to set it up properly. We recommend you go through the [test-runner documentation](./test-runner.md) before proceeding with the rest of the required configuration to learn more about the available options and APIs. + +Add a new [configuration file](./test-runner.md#test-hook-api) inside your Storybook directory with the following inside: + + + + + + + + + +The `postVisit` hook allows you to extend the test runner's default configuration. Read more about them [here](./test-runner.md#test-hook-api). -[Storyshots](https://storybook.js.org/addons/@storybook/addon-storyshots/) is a Storybook addon that enables snapshot testing, powered by [Jest](https://jestjs.io/docs/getting-started). +When you execute the test-runner (for example, with `yarn test-storybook`), it will run through all of your stories and run the snapshot tests, generating a snapshot file for each story in your project located in the `__snapshots__` directory. + +### Configure -Run the following command to install Storyshots: +Out of the box, the test-runner provides an inbuilt snapshot testing configuration covering most use cases. You can also fine-tune the configuration to fit your needs via `test-storybook --eject` or by creating a `test-runner-jest.config.js` file at the root of your project. + +#### Override the default snapshot directory + +The test-runner uses a specific naming convention and path for the generated snapshot files by default. If you need to customize the snapshot directory, you can define a custom snapshot resolver to specify the directory where the snapshots are stored. + +Create a `snapshot-resolver.js` file to implement a custom snapshot resolver: -Add a test file to your environment with the following contents to configure Storyshots: +Update the `test-runner-jest.config.js` file and enable the `snapshotResolver` option to use the custom snapshot resolver: - +When the test-runner is executed, it will cycle through all of your stories and run the snapshot tests, generating a snapshot file for each story in your project located in the custom directory you specified. -You can name the test file differently to suit your needs. Bear in mind that it requires to be picked up by Jest. +#### Customize snapshot serialization - +By default, the test-runner uses [`jest-serializer-html`](https://github.com/algolia/jest-serializer-html) to serialize HTML snapshots. This may cause issues if you use specific CSS-in-JS libraries like [Emotion](https://emotion.sh/docs/introduction), Angular's `ng` attributes, or similar libraries that generate hash-based identifiers for CSS classes. If you need to customize the serialization of your snapshots, you can define a custom snapshot serializer to specify how the snapshots are serialized. -Run your first test. Storyshots will recognize your stories (based on [.storybook/main.js's setup](../configure/story-rendering.md)) and save them in the **snapshots** directory. +Create a `snapshot-serializer.js` file to implement a custom snapshot serializer: -```shell -npm test storybook.test.js -``` + -![Successful snapshot tests](./storyshots-pass.png) + -When you make changes to your components or stories, rerun the test to identify the changes to the rendered markup. + -![Failing snapshots](./storyshots-fail.png) +Update the `test-runner-jest.config.js` file and enable the `snapshotSerializers` option to use the custom snapshot resolver: -If they're intentional, accept them as new baselines. If the changes are bugs, fix the underlying code, then rerun the snapshot tests. + -### Configure the snapshot's directory + -If your project has a custom setup for snapshot testing, you'll need to take additional steps to run Storyshots. You'll need to install both [@storybook/addon-storyshots-puppeteer](https://storybook.js.org/addons/@storybook/addon-storyshots-puppeteer) and [puppeteer](https://github.com/puppeteer/puppeteer): + + +When the test-runner executes your tests, it will introspect the resulting HTML, replacing the dynamically generated attributes with the static ones provided by the regular expression in the custom serializer file before snapshotting the component. This ensures that the snapshots are consistent across different test runs. + + + + -```shell -# With npm -npm i -D @storybook/addon-storyshots-puppeteer puppeteer +## Snapshot tests with Portable Stories -# With yarn -yarn add @storybook/addon-storyshots-puppeteer puppeteer -``` +Storybook provides a `composeStories` utility that helps convert stories from a test file into renderable elements that can be reused in your Node tests with JSDOM. It also allows you to apply other Storybook features that you have enabled your project (e.g., [decorators](../writing-stories/decorators.md), [args](../writing-stories/args.md)) into your tests, enabling you to reuse your stories in your testing environment of choice (e.g., [Jest](https://jestjs.io/), [Vitest](https://vitest.dev/)), ensuring your tests are always in sync with your stories without having to rewrite them. This is what we refer to as portable stories in Storybook. -Next, update your test file (for example, `storybook.test.js`) to the following: +### Configure + +By default, Storybook offers a zero-config setup for React, Vue, and other frameworks via addons, allowing you to run your stories as tests with your testing environment of choice. However, if you're running tests and you've set up specific configurations in your Storybook instance (e.g., global [decorators](../writing-stories/decorators.md#global-decorators), [parameters](../writing-stories/parameters.md#global-parameters)) that you want to use in your tests, you'll need to extend your test setup to include these configurations. To do so, create a `setup.js|ts` file as follows: - +Update your test configuration file (e.g., `vite.config.js|ts`) if you're using [Vitest](https://vitest.dev/) or your test script if you're using [Jest](https://jestjs.io/): -Don't forget to replace your-custom-directory with your own. + - + -When you run your tests, the snapshots will be available in your specified directory. + -### Framework configuration +### Run tests on a single story -By default, Storyshots detects your project's framework. If you encounter a situation where this is not the case, you can adjust the configuration object and specify your framework. For example, if you wanted to configure the addon for a Vue 3 project: +If you need to run tests on a single story, you can use the `composeStories` function from the appropriate framework to process it and apply any configuration you've defined in your stories (e.g., [decorators](../writing-stories/decorators.md), [args](../writing-stories/args.md)) and combine it with your testing environment to generate a snapshot file. For example, if you're working on a component and you want to test its default state, ensuring the expected DOM structure doesn't change, here's how you could write your test: -These are the frameworks currently supported by Storyshots: `angular`, `html`, `preact`, `react`, `react-native`, `svelte`, `vue`, `vue3`, and `web-components`. +### Execute tests on multiple stories -### Additional customization +You can also use the `composeStories` function to test multiple stories. This is useful when you want to extend your test coverage to generate snapshots for the different states of the components in your project. To do so, you can write your test as follows: -Storyshots is highly customizable and includes options for various advanced use cases. You can read more in the [addonโ€™s documentation](https://github.com/storybookjs/storybook/tree/master/addons/storyshots/storyshots-core#options). + ---- + + + + +When your tests are executed in your testing environment, they will generate a single snapshot file with all the stories in your project (i.e.,`storybook.test.ts|js.snap`). However, if you need, you can extend your test file to generate individual snapshot files for each story in your project with Vitest's [`toMatchFileSnapshot`](https://vitest.dev/guide/snapshot.html#file-snapshots) API or Jest's [`jest-specific-snapshot`](https://github.com/igor-dv/jest-specific-snapshot) package. For example: + + + + + + + + #### Whatโ€™s the difference between snapshot tests and visual tests? diff --git a/docs/writing-tests/storyshots-fail.png b/docs/writing-tests/storyshots-fail.png deleted file mode 100644 index 1cf3677509f5fdc1bf2646253eeb722acc5c7164..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 81300 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 diff --git a/docs/writing-tests/storyshots-pass.png b/docs/writing-tests/storyshots-pass.png deleted file mode 100644 index b93d218c8f34add60e35825c47a2fe05082265ff..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 52729 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 LNkvXXu0mjfBJkj; From 788aaac74729a17f9d08eeba02f9d8905a3451a6 Mon Sep 17 00:00:00 2001 From: Norbert de Langen Date: Tue, 5 Mar 2024 13:34:46 +0100 Subject: [PATCH 043/132] add functionality of emitting an event & and test for websocket-transport --- code/lib/channels/src/index.test.ts | 125 ++++++++++++++++++++++- code/lib/channels/src/index.ts | 2 +- code/lib/channels/src/websocket/index.ts | 14 ++- code/lib/core-events/src/index.ts | 2 + code/ui/manager/src/globals/exports.ts | 1 + 5 files changed, 139 insertions(+), 5 deletions(-) diff --git a/code/lib/channels/src/index.test.ts b/code/lib/channels/src/index.test.ts index 07f6d605af10..04c295d98cff 100644 --- a/code/lib/channels/src/index.test.ts +++ b/code/lib/channels/src/index.test.ts @@ -1,9 +1,43 @@ import { describe, beforeEach, it, expect, vi } from 'vitest'; import type { ChannelTransport, Listener } from '.'; -import { Channel } from '.'; +import { Channel, WebsocketTransport } from '.'; vi.useFakeTimers(); +const MockedWebsocket = vi.hoisted(() => { + const ref = { current: undefined as unknown as InstanceType }; + class MyMockedWebsocket { + onopen: () => void; + + onmessage: (event: { data: string }) => void; + + onerror: (e: any) => void; + + onclose: () => void; + + constructor(url: string) { + this.onopen = vi.fn(); + this.onmessage = vi.fn(); + this.onerror = vi.fn(); + this.onclose = vi.fn(); + + ref.current = this; + } + + send(data: string) { + this.onmessage({ data }); + } + } + return { MyMockedWebsocket, ref }; +}); + +vi.mock('@storybook/global', () => ({ + global: { + ...global, + WebSocket: MockedWebsocket.MyMockedWebsocket, + }, +})); + describe('Channel', () => { let transport: ChannelTransport; let channel: Channel; @@ -232,3 +266,92 @@ describe('Channel', () => { }); }); }); + +describe('WebsocketTransport', () => { + it('should connect', async () => { + const onError = vi.fn(); + const handler = vi.fn(); + + const transport = new WebsocketTransport({ + url: 'ws://localhost:6006', + page: 'preview', + onError, + }); + + transport.setHandler(handler); + MockedWebsocket.ref.current.onopen(); + + expect(handler).toHaveBeenCalledTimes(0); + }); + it('should send message upon disconnect', async () => { + const onError = vi.fn(); + const handler = vi.fn(); + + const transport = new WebsocketTransport({ + url: 'ws://localhost:6006', + page: 'preview', + onError, + }); + + transport.setHandler(handler); + MockedWebsocket.ref.current.onclose(); + + expect(handler.mock.calls).toMatchInlineSnapshot(` + [ + [ + { + "args": [], + "from": "preview", + "type": "channelWSDisconnect", + }, + ], + ] + `); + }); + it('should send message when send', async () => { + const onError = vi.fn(); + const handler = vi.fn(); + + const transport = new WebsocketTransport({ + url: 'ws://localhost:6006', + page: 'preview', + onError, + }); + + transport.setHandler(handler); + MockedWebsocket.ref.current.send('{ "type": "test", "args": [], "from": "preview" }'); + + expect(handler.mock.calls).toMatchInlineSnapshot(` + [ + [ + { + "args": [], + "from": "preview", + "type": "test", + }, + ], + ] + `); + }); + it('should call onError handler', async () => { + const onError = vi.fn(); + const handler = vi.fn(); + + const transport = new WebsocketTransport({ + url: 'ws://localhost:6006', + page: 'preview', + onError, + }); + + transport.setHandler(handler); + MockedWebsocket.ref.current.onerror(new Error('testError')); + + expect(onError.mock.calls).toMatchInlineSnapshot(` + [ + [ + [Error: testError], + ], + ] + `); + }); +}); diff --git a/code/lib/channels/src/index.ts b/code/lib/channels/src/index.ts index 7942d57fa4f3..80a865f31904 100644 --- a/code/lib/channels/src/index.ts +++ b/code/lib/channels/src/index.ts @@ -35,7 +35,7 @@ export function createBrowserChannel({ page, extraTransports = [] }: Options): C const { hostname, port } = window.location; const channelUrl = `${protocol}://${hostname}:${port}/storybook-server-channel`; - transports.push(new WebsocketTransport({ url: channelUrl, onError: () => {} })); + transports.push(new WebsocketTransport({ url: channelUrl, onError: () => {}, page })); } return new Channel({ transports }); diff --git a/code/lib/channels/src/websocket/index.ts b/code/lib/channels/src/websocket/index.ts index a46df1c28610..790f69a8deaa 100644 --- a/code/lib/channels/src/websocket/index.ts +++ b/code/lib/channels/src/websocket/index.ts @@ -5,13 +5,16 @@ import { global } from '@storybook/global'; import { isJSON, parse, stringify } from 'telejson'; import invariant from 'tiny-invariant'; -import type { ChannelTransport, ChannelHandler } from '../types'; +// I tried to use an import statement, but it didn't work +const { CHANNEL_WS_DISCONNECT } = require('@storybook/core-events'); + +import type { ChannelTransport, ChannelHandler, Config } from '../types'; const { WebSocket } = global; type OnError = (message: Event) => void; -interface WebsocketTransportArgs { +interface WebsocketTransportArgs extends Partial { url: string; onError: OnError; } @@ -25,7 +28,8 @@ export class WebsocketTransport implements ChannelTransport { private isReady = false; - constructor({ url, onError }: WebsocketTransportArgs) { + constructor({ url, onError, page }: WebsocketTransportArgs) { + console.log({ WebSocket }); this.socket = new WebSocket(url); this.socket.onopen = () => { this.isReady = true; @@ -41,6 +45,10 @@ export class WebsocketTransport implements ChannelTransport { onError(e); } }; + this.socket.onclose = () => { + invariant(this.handler, 'WebsocketTransport handler should be set'); + this.handler({ type: CHANNEL_WS_DISCONNECT, args: [], from: page || 'preview' }); + }; } setHandler(handler: ChannelHandler) { diff --git a/code/lib/core-events/src/index.ts b/code/lib/core-events/src/index.ts index 6d98e6291200..7542d0aa4e57 100644 --- a/code/lib/core-events/src/index.ts +++ b/code/lib/core-events/src/index.ts @@ -1,5 +1,6 @@ // eslint-disable-next-line @typescript-eslint/naming-convention enum events { + CHANNEL_WS_DISCONNECT = 'channelWSDisconnect', CHANNEL_CREATED = 'channelCreated', // There was an error executing the config, likely an bug in the user's preview.js CONFIG_ERROR = 'configError', @@ -80,6 +81,7 @@ export default events; // Enables: `import * as Events from ...` or `import { CHANNEL_CREATED } as Events from ...` // This is the preferred method export const { + CHANNEL_WS_DISCONNECT, CHANNEL_CREATED, CONFIG_ERROR, CURRENT_STORY_WAS_SET, diff --git a/code/ui/manager/src/globals/exports.ts b/code/ui/manager/src/globals/exports.ts index b8e2d5b14868..079340369fcb 100644 --- a/code/ui/manager/src/globals/exports.ts +++ b/code/ui/manager/src/globals/exports.ts @@ -130,6 +130,7 @@ export default { ], '@storybook/core-events': [ 'CHANNEL_CREATED', + 'CHANNEL_WS_DISCONNECT', 'CONFIG_ERROR', 'CURRENT_STORY_WAS_SET', 'DOCS_PREPARED', From ff54701ed7e9eadd1b8ceda4e6c042285c59c9e9 Mon Sep 17 00:00:00 2001 From: Norbert de Langen Date: Tue, 5 Mar 2024 14:11:05 +0100 Subject: [PATCH 044/132] fix --- code/lib/channels/src/index.test.ts | 40 ++++++++---------------- code/lib/channels/src/websocket/index.ts | 7 ++--- 2 files changed, 15 insertions(+), 32 deletions(-) diff --git a/code/lib/channels/src/index.test.ts b/code/lib/channels/src/index.test.ts index 04c295d98cff..f99e04f6099c 100644 --- a/code/lib/channels/src/index.test.ts +++ b/code/lib/channels/src/index.test.ts @@ -296,16 +296,12 @@ describe('WebsocketTransport', () => { transport.setHandler(handler); MockedWebsocket.ref.current.onclose(); - expect(handler.mock.calls).toMatchInlineSnapshot(` - [ - [ - { - "args": [], - "from": "preview", - "type": "channelWSDisconnect", - }, - ], - ] + expect(handler.mock.calls[0][0]).toMatchInlineSnapshot(` + { + "args": [], + "from": "preview", + "type": "channelWSDisconnect", + } `); }); it('should send message when send', async () => { @@ -321,16 +317,12 @@ describe('WebsocketTransport', () => { transport.setHandler(handler); MockedWebsocket.ref.current.send('{ "type": "test", "args": [], "from": "preview" }'); - expect(handler.mock.calls).toMatchInlineSnapshot(` - [ - [ - { - "args": [], - "from": "preview", - "type": "test", - }, - ], - ] + expect(handler.mock.calls[0][0]).toMatchInlineSnapshot(` + { + "args": [], + "from": "preview", + "type": "test", + } `); }); it('should call onError handler', async () => { @@ -346,12 +338,6 @@ describe('WebsocketTransport', () => { transport.setHandler(handler); MockedWebsocket.ref.current.onerror(new Error('testError')); - expect(onError.mock.calls).toMatchInlineSnapshot(` - [ - [ - [Error: testError], - ], - ] - `); + expect(onError.mock.calls[0][0]).toMatchInlineSnapshot(`[Error: testError]`); }); }); diff --git a/code/lib/channels/src/websocket/index.ts b/code/lib/channels/src/websocket/index.ts index 790f69a8deaa..0cc73345507d 100644 --- a/code/lib/channels/src/websocket/index.ts +++ b/code/lib/channels/src/websocket/index.ts @@ -5,9 +5,7 @@ import { global } from '@storybook/global'; import { isJSON, parse, stringify } from 'telejson'; import invariant from 'tiny-invariant'; -// I tried to use an import statement, but it didn't work -const { CHANNEL_WS_DISCONNECT } = require('@storybook/core-events'); - +import * as EVENTS from '@storybook/core-events'; import type { ChannelTransport, ChannelHandler, Config } from '../types'; const { WebSocket } = global; @@ -29,7 +27,6 @@ export class WebsocketTransport implements ChannelTransport { private isReady = false; constructor({ url, onError, page }: WebsocketTransportArgs) { - console.log({ WebSocket }); this.socket = new WebSocket(url); this.socket.onopen = () => { this.isReady = true; @@ -47,7 +44,7 @@ export class WebsocketTransport implements ChannelTransport { }; this.socket.onclose = () => { invariant(this.handler, 'WebsocketTransport handler should be set'); - this.handler({ type: CHANNEL_WS_DISCONNECT, args: [], from: page || 'preview' }); + this.handler({ type: EVENTS.CHANNEL_WS_DISCONNECT, args: [], from: page || 'preview' }); }; } From c4956e2a1fe338b25599555f1e2f5bca5a236b5b Mon Sep 17 00:00:00 2001 From: Norbert de Langen Date: Tue, 5 Mar 2024 14:31:24 +0100 Subject: [PATCH 045/132] broaden version range for vite compatibility --- code/builders/builder-manager/package.json | 2 +- code/lib/core-common/package.json | 2 +- code/package.json | 2 +- code/yarn.lock | 78 ++++------------------ scripts/package.json | 2 +- scripts/yarn.lock | 11 +-- 6 files changed, 18 insertions(+), 79 deletions(-) diff --git a/code/builders/builder-manager/package.json b/code/builders/builder-manager/package.json index 56b28e9c4fbf..98022250a086 100644 --- a/code/builders/builder-manager/package.json +++ b/code/builders/builder-manager/package.json @@ -52,7 +52,7 @@ "@yarnpkg/esbuild-plugin-pnp": "^3.0.0-rc.10", "browser-assert": "^1.2.1", "ejs": "^3.1.8", - "esbuild": "^0.20.1", + "esbuild": "^18.0.0 || ^19.0.0 || ^0.20.0", "esbuild-plugin-alias": "^0.2.1", "express": "^4.17.3", "fs-extra": "^11.1.0", diff --git a/code/lib/core-common/package.json b/code/lib/core-common/package.json index be5bac6b4cf8..c136e06ea40d 100644 --- a/code/lib/core-common/package.json +++ b/code/lib/core-common/package.json @@ -52,7 +52,7 @@ "@yarnpkg/libzip": "2.3.0", "chalk": "^4.1.0", "cross-spawn": "^7.0.3", - "esbuild": "^0.20.1", + "esbuild": "^18.0.0 || ^19.0.0 || ^0.20.0", "esbuild-register": "^3.5.0", "execa": "^5.0.0", "file-system-cache": "2.3.0", diff --git a/code/package.json b/code/package.json index b73a51626082..ee2e28d00986 100644 --- a/code/package.json +++ b/code/package.json @@ -190,7 +190,7 @@ "concurrently": "^5.3.0", "cross-env": "^7.0.3", "danger": "^11.2.6", - "esbuild": "^0.18.0", + "esbuild": "^18.0.0 || ^19.0.0 || ^0.20.0", "esbuild-loader": "^3.0.0", "esbuild-plugin-alias": "^0.2.1", "eslint": "^8.56.0", diff --git a/code/yarn.lock b/code/yarn.lock index d155696ae2d0..a34bb7d5f3b7 100644 --- a/code/yarn.lock +++ b/code/yarn.lock @@ -5477,7 +5477,7 @@ __metadata: "@yarnpkg/esbuild-plugin-pnp": "npm:^3.0.0-rc.10" browser-assert: "npm:^1.2.1" ejs: "npm:^3.1.8" - esbuild: "npm:^0.20.1" + esbuild: "npm:^18.0.0 || ^19.0.0 || ^0.20.0" esbuild-plugin-alias: "npm:^0.2.1" express: "npm:^4.17.3" fs-extra: "npm:^11.1.0" @@ -5744,7 +5744,7 @@ __metadata: "@yarnpkg/libzip": "npm:2.3.0" chalk: "npm:^4.1.0" cross-spawn: "npm:^7.0.3" - esbuild: "npm:^0.20.1" + esbuild: "npm:^18.0.0 || ^19.0.0 || ^0.20.0" esbuild-register: "npm:^3.5.0" execa: "npm:^5.0.0" file-system-cache: "npm:2.3.0" @@ -6682,7 +6682,7 @@ __metadata: concurrently: "npm:^5.3.0" cross-env: "npm:^7.0.3" danger: "npm:^11.2.6" - esbuild: "npm:^0.18.0" + esbuild: "npm:^18.0.0 || ^19.0.0 || ^0.20.0" esbuild-loader: "npm:^3.0.0" esbuild-plugin-alias: "npm:^0.2.1" eslint: "npm:^8.56.0" @@ -7093,7 +7093,7 @@ __metadata: languageName: node linkType: hard -"@sveltejs/vite-plugin-svelte-inspector@npm:^2.0.0, @sveltejs/vite-plugin-svelte-inspector@npm:^2.0.0-next.0 || ^2.0.0": +"@sveltejs/vite-plugin-svelte-inspector@npm:^2.0.0": version: 2.0.0 resolution: "@sveltejs/vite-plugin-svelte-inspector@npm:2.0.0" dependencies: @@ -7106,25 +7106,7 @@ __metadata: languageName: node linkType: hard -"@sveltejs/vite-plugin-svelte@npm:^3.0.1": - version: 3.0.1 - resolution: "@sveltejs/vite-plugin-svelte@npm:3.0.1" - dependencies: - "@sveltejs/vite-plugin-svelte-inspector": "npm:^2.0.0-next.0 || ^2.0.0" - debug: "npm:^4.3.4" - deepmerge: "npm:^4.3.1" - kleur: "npm:^4.1.5" - magic-string: "npm:^0.30.5" - svelte-hmr: "npm:^0.15.3" - vitefu: "npm:^0.2.5" - peerDependencies: - svelte: ^4.0.0 || ^5.0.0-next.0 - vite: ^5.0.0 - checksum: 889d41014d4cc5dfb578cb0a80e64f72c0f8c143e9a299c3a4e2372fd582d982ce118dad5e158e0b747d1df7354a909ed9490b1adcd1bf982b56c82fffd4652c - languageName: node - linkType: hard - -"@sveltejs/vite-plugin-svelte@npm:^3.0.2": +"@sveltejs/vite-plugin-svelte@npm:^3.0.1, @sveltejs/vite-plugin-svelte@npm:^3.0.2": version: 3.0.2 resolution: "@sveltejs/vite-plugin-svelte@npm:3.0.2" dependencies: @@ -7601,10 +7583,10 @@ __metadata: languageName: node linkType: hard -"@types/estree@npm:*, @types/estree@npm:^1.0.0, @types/estree@npm:^1.0.1": - version: 1.0.2 - resolution: "@types/estree@npm:1.0.2" - checksum: 4b5c601d435ea8e2205458de15fd1556b5ae6c9a8323bad8a940ea502d6c824664faca94234c0bf76bf9c87cbf6ac41abee550c9e20433256549d589c9b543bd +"@types/estree@npm:*, @types/estree@npm:^1.0.0, @types/estree@npm:^1.0.1, @types/estree@npm:^1.0.5": + version: 1.0.5 + resolution: "@types/estree@npm:1.0.5" + checksum: b3b0e334288ddb407c7b3357ca67dbee75ee22db242ca7c56fe27db4e1a31989cb8af48a84dd401deb787fe10cc6b2ab1ee82dc4783be87ededbe3d53c79c70d languageName: node linkType: hard @@ -7615,13 +7597,6 @@ __metadata: languageName: node linkType: hard -"@types/estree@npm:^1.0.5": - version: 1.0.5 - resolution: "@types/estree@npm:1.0.5" - checksum: b3b0e334288ddb407c7b3357ca67dbee75ee22db242ca7c56fe27db4e1a31989cb8af48a84dd401deb787fe10cc6b2ab1ee82dc4783be87ededbe3d53c79c70d - languageName: node - linkType: hard - "@types/express-serve-static-core@npm:*, @types/express-serve-static-core@npm:^4.17.33": version: 4.17.37 resolution: "@types/express-serve-static-core@npm:4.17.37" @@ -9564,16 +9539,7 @@ __metadata: languageName: node linkType: hard -"acorn@npm:^8.0.0, acorn@npm:^8.10.0, acorn@npm:^8.11.2, acorn@npm:^8.4.1, acorn@npm:^8.6.0, acorn@npm:^8.7.1, acorn@npm:^8.8.2, acorn@npm:^8.9.0": - version: 8.11.2 - resolution: "acorn@npm:8.11.2" - bin: - acorn: bin/acorn - checksum: a3ed76c761b75ec54b1ec3068fb7f113a182e95aea7f322f65098c2958d232e3d211cb6dac35ff9c647024b63714bc528a26d54a925d1fef2c25585b4c8e4017 - languageName: node - linkType: hard - -"acorn@npm:^8.11.3": +"acorn@npm:^8.0.0, acorn@npm:^8.10.0, acorn@npm:^8.11.2, acorn@npm:^8.11.3, acorn@npm:^8.4.1, acorn@npm:^8.6.0, acorn@npm:^8.7.1, acorn@npm:^8.8.2, acorn@npm:^8.9.0": version: 8.11.3 resolution: "acorn@npm:8.11.3" bin: @@ -25026,20 +24992,7 @@ __metadata: languageName: node linkType: hard -"recast@npm:^0.23.1, recast@npm:^0.23.3": - version: 0.23.4 - resolution: "recast@npm:0.23.4" - dependencies: - assert: "npm:^2.0.0" - ast-types: "npm:^0.16.1" - esprima: "npm:~4.0.0" - source-map: "npm:~0.6.1" - tslib: "npm:^2.0.1" - checksum: d719633be8029e28f23b8191d4a525c5dbdac721792ab3cb5e9dfcf1694fb93f3c147b186916195a9c7fa0711f1e4990ba457cdcee02faed3899d4a80da1bd1f - languageName: node - linkType: hard - -"recast@npm:^0.23.5": +"recast@npm:^0.23.1, recast@npm:^0.23.3, recast@npm:^0.23.5": version: 0.23.5 resolution: "recast@npm:0.23.5" dependencies: @@ -28077,14 +28030,7 @@ __metadata: languageName: node linkType: hard -"tiny-invariant@npm:^1.3.1": - version: 1.3.1 - resolution: "tiny-invariant@npm:1.3.1" - checksum: 5b87c1d52847d9452b60d0dcb77011b459044e0361ca8253bfe7b43d6288106e12af926adb709a6fc28900e3864349b91dad9a4ac93c39aa15f360b26c2ff4db - languageName: node - linkType: hard - -"tiny-invariant@npm:^1.3.3": +"tiny-invariant@npm:^1.3.1, tiny-invariant@npm:^1.3.3": version: 1.3.3 resolution: "tiny-invariant@npm:1.3.3" checksum: 65af4a07324b591a059b35269cd696aba21bef2107f29b9f5894d83cc143159a204b299553435b03874ebb5b94d019afa8b8eff241c8a4cfee95872c2e1c1c4a diff --git a/scripts/package.json b/scripts/package.json index e2f19d61148b..542bca5d2fd0 100644 --- a/scripts/package.json +++ b/scripts/package.json @@ -122,7 +122,7 @@ "detect-port": "^1.3.0", "ejs": "^3.1.8", "ejs-lint": "^2.0.0", - "esbuild": "^0.18.0", + "esbuild": "^0.20.1", "esbuild-plugin-alias": "^0.2.1", "esbuild-register": "^3.5.0", "eslint": "^8.56.0", diff --git a/scripts/yarn.lock b/scripts/yarn.lock index 8e10967d94ab..4bd7c8b5c0c3 100644 --- a/scripts/yarn.lock +++ b/scripts/yarn.lock @@ -2769,7 +2769,7 @@ __metadata: detect-port: "npm:^1.3.0" ejs: "npm:^3.1.8" ejs-lint: "npm:^2.0.0" - esbuild: "npm:^0.18.0" + esbuild: "npm:^0.20.1" esbuild-plugin-alias: "npm:^0.2.1" esbuild-register: "npm:^3.5.0" eslint: "npm:^8.56.0" @@ -14563,14 +14563,7 @@ __metadata: languageName: node linkType: hard -"tiny-invariant@npm:^1.3.1": - version: 1.3.1 - resolution: "tiny-invariant@npm:1.3.1" - checksum: 5b87c1d52847d9452b60d0dcb77011b459044e0361ca8253bfe7b43d6288106e12af926adb709a6fc28900e3864349b91dad9a4ac93c39aa15f360b26c2ff4db - languageName: node - linkType: hard - -"tiny-invariant@npm:^1.3.3": +"tiny-invariant@npm:^1.3.1, tiny-invariant@npm:^1.3.3": version: 1.3.3 resolution: "tiny-invariant@npm:1.3.3" checksum: 65af4a07324b591a059b35269cd696aba21bef2107f29b9f5894d83cc143159a204b299553435b03874ebb5b94d019afa8b8eff241c8a4cfee95872c2e1c1c4a From 861cfb0b478a0c4a95c36df53684bfcda2316c88 Mon Sep 17 00:00:00 2001 From: Valentin Palkovic Date: Tue, 5 Mar 2024 15:50:41 +0100 Subject: [PATCH 046/132] Remove 'left' property from TooltipLinkList and Link components and adjust documentation and Migration guide --- MIGRATION.md | 40 +++++++++++++++++++++++++ code/addons/toolbars/src/types.ts | 1 - docs/essentials/toolbars-and-globals.md | 1 - 3 files changed, 40 insertions(+), 2 deletions(-) diff --git a/MIGRATION.md b/MIGRATION.md index 5919ec501c42..d954414a2342 100644 --- a/MIGRATION.md +++ b/MIGRATION.md @@ -64,6 +64,7 @@ - [Removed `passArgsFirst` option](#removed-passargsfirst-option) - [Methods and properties from AddonStore](#methods-and-properties-from-addonstore) - [Methods and properties from PreviewAPI](#methods-and-properties-from-previewapi) + - [Removals in @storybook/components](#removals-in-storybookcomponents) - [Removals in @storybook/types](#removals-in-storybooktypes) - [--use-npm flag in storybook CLI](#--use-npm-flag-in-storybook-cli) - [hideNoControlsWarning parameter from addon controls](#hidenocontrolswarning-parameter-from-addon-controls) @@ -1040,6 +1041,45 @@ The following exports from `@storybook/preview-api` are now removed: Please file an issue if you need these APIs. +#### Removals in @storybook/components + +The `TooltipLinkList` component accepts a `links` property where, for each link, a `left` property could be passed. The left property is now removed in Storybook 8 and beyond. Use `icon` instead. The side-effect is that the `left` property is now removed from the `Link` component. The Link component is used to define `globalTypes` in the `preview.js` file, among other places: + +```diff +// Replace your-framework with the framework you are using (e.g., react, vue3) +import { Preview } from '@storybook/your-framework'; + +const preview: Preview = { + globalTypes: { + locale: { + description: 'Internationalization locale', + defaultValue: 'en', + toolbar: { + icon: 'globe', + items: [ + { + value: 'en', + right: '๐Ÿ‡บ๐Ÿ‡ธ', +- left: '๏ผ„' ++ icon: 'facehappy' + title: 'English' + }, + { value: 'fr', right: '๐Ÿ‡ซ๐Ÿ‡ท', title: 'Franรงais' }, + { value: 'es', right: '๐Ÿ‡ช๐Ÿ‡ธ', title: 'Espaรฑol' }, + { value: 'zh', right: '๐Ÿ‡จ๐Ÿ‡ณ', title: 'ไธญๆ–‡' }, + { value: 'kr', right: '๐Ÿ‡ฐ๐Ÿ‡ท', title: 'ํ•œ๊ตญ์–ด' }, + ], + }, + }, + }, +}; + +export default preview; +``` + +The icon property only supports a limited set of icons, which are defined here: +https://storybook.js.org/docs/8.0/faq#what-icons-are-available-for-my-toolbar-or-my-addon + #### Removals in @storybook/types The following exports from `@storybook/types` are now removed: diff --git a/code/addons/toolbars/src/types.ts b/code/addons/toolbars/src/types.ts index e07d11f73ae0..8427c53e4606 100644 --- a/code/addons/toolbars/src/types.ts +++ b/code/addons/toolbars/src/types.ts @@ -15,7 +15,6 @@ export type ToolbarShortcuts = Record Date: Tue, 5 Mar 2024 17:41:15 +0100 Subject: [PATCH 047/132] use h helper in vue3 decorators instead, update migration notes --- MIGRATION.md | 42 +++++++++++-------- .../composeStories/portable-stories.test.ts | 8 ++-- code/renderers/vue3/src/portable-stories.ts | 14 +++---- 3 files changed, 34 insertions(+), 30 deletions(-) diff --git a/MIGRATION.md b/MIGRATION.md index dd4bfee85ee6..6488919f513b 100644 --- a/MIGRATION.md +++ b/MIGRATION.md @@ -90,17 +90,17 @@ - [Tab addons cannot manually route, Tool addons can filter their visibility via tabId](#tab-addons-cannot-manually-route-tool-addons-can-filter-their-visibility-via-tabid) - [Removed `config` preset](#removed-config-preset-1) - [From version 7.5.0 to 7.6.0](#from-version-750-to-760) - - [CommonJS with Vite is deprecated](#commonjs-with-vite-is-deprecated) - - [Using implicit actions during rendering is deprecated](#using-implicit-actions-during-rendering-is-deprecated) - - [typescript.skipBabel deprecated](#typescriptskipbabel-deprecated) - - [Primary doc block accepts of prop](#primary-doc-block-accepts-of-prop) - - [Addons no longer need a peer dependency on React](#addons-no-longer-need-a-peer-dependency-on-react) + - [CommonJS with Vite is deprecated](#commonjs-with-vite-is-deprecated) + - [Using implicit actions during rendering is deprecated](#using-implicit-actions-during-rendering-is-deprecated) + - [typescript.skipBabel deprecated](#typescriptskipbabel-deprecated) + - [Primary doc block accepts of prop](#primary-doc-block-accepts-of-prop) + - [Addons no longer need a peer dependency on React](#addons-no-longer-need-a-peer-dependency-on-react) - [From version 7.4.0 to 7.5.0](#from-version-740-to-750) - - [`storyStoreV6` and `storiesOf` is deprecated](#storystorev6-and-storiesof-is-deprecated) - - [`storyIndexers` is replaced with `experimental_indexers`](#storyindexers-is-replaced-with-experimental_indexers) + - [`storyStoreV6` and `storiesOf` is deprecated](#storystorev6-and-storiesof-is-deprecated) + - [`storyIndexers` is replaced with `experimental_indexers`](#storyindexers-is-replaced-with-experimental_indexers) - [From version 7.0.0 to 7.2.0](#from-version-700-to-720) - - [Addon API is more type-strict](#addon-api-is-more-type-strict) - - [Addon-controls hideNoControlsWarning parameter is deprecated](#addon-controls-hidenocontrolswarning-parameter-is-deprecated) + - [Addon API is more type-strict](#addon-api-is-more-type-strict) + - [Addon-controls hideNoControlsWarning parameter is deprecated](#addon-controls-hidenocontrolswarning-parameter-is-deprecated) - [From version 6.5.x to 7.0.0](#from-version-65x-to-700) - [7.0 breaking changes](#70-breaking-changes) - [Dropped support for Node 15 and below](#dropped-support-for-node-15-and-below) @@ -126,7 +126,7 @@ - [Deploying build artifacts](#deploying-build-artifacts) - [Dropped support for file URLs](#dropped-support-for-file-urls) - [Serving with nginx](#serving-with-nginx) - - [Ignore story files from node\_modules](#ignore-story-files-from-node_modules) + - [Ignore story files from node_modules](#ignore-story-files-from-node_modules) - [7.0 Core changes](#70-core-changes) - [7.0 feature flags removed](#70-feature-flags-removed) - [Story context is prepared before for supporting fine grained updates](#story-context-is-prepared-before-for-supporting-fine-grained-updates) @@ -140,7 +140,7 @@ - [Addon-interactions: Interactions debugger is now default](#addon-interactions-interactions-debugger-is-now-default) - [7.0 Vite changes](#70-vite-changes) - [Vite builder uses Vite config automatically](#vite-builder-uses-vite-config-automatically) - - [Vite cache moved to node\_modules/.cache/.vite-storybook](#vite-cache-moved-to-node_modulescachevite-storybook) + - [Vite cache moved to node_modules/.cache/.vite-storybook](#vite-cache-moved-to-node_modulescachevite-storybook) - [7.0 Webpack changes](#70-webpack-changes) - [Webpack4 support discontinued](#webpack4-support-discontinued) - [Babel mode v7 exclusively](#babel-mode-v7-exclusively) @@ -190,7 +190,7 @@ - [Dropped addon-docs manual babel configuration](#dropped-addon-docs-manual-babel-configuration) - [Dropped addon-docs manual configuration](#dropped-addon-docs-manual-configuration) - [Autoplay in docs](#autoplay-in-docs) - - [Removed STORYBOOK\_REACT\_CLASSES global](#removed-storybook_react_classes-global) + - [Removed STORYBOOK_REACT_CLASSES global](#removed-storybook_react_classes-global) - [7.0 Deprecations and default changes](#70-deprecations-and-default-changes) - [storyStoreV7 enabled by default](#storystorev7-enabled-by-default) - [`Story` type deprecated](#story-type-deprecated) @@ -470,9 +470,17 @@ test("snapshots the story with custom id", () => { #### Composed Vue stories are now components instead of functions -`composeStory` (and `composeStories`) from `@storybook/vue3` now returns Vue components rather than story functions that return components. This means that when rendering these composed stories you just pass the composed story _without_ first calling it. +`composeStory` (and `composeStories`) from `@storybook/vue3` now return Vue components rather than story functions that return components. This means that when rendering these composed stories you just pass the composed story _without_ first calling it. -Previously when using `composeStory` from `@storybook/testing-vue` you would render composed stories with eg. `render(MyStoryComposedStory({ someProps: true}))`. That is now changed to more [closely match how you would render regular Vue components](https://testing-library.com/docs/vue-testing-library/examples). Here's an example using `@testing-library/vue` and Vitest: +Previously when using `composeStory` from `@storybook/testing-vue3`, you would render composed stories with e.g. `render(MyStoryComposedStory({ someProp: true}))`. That is now changed to more [closely match how you would render regular Vue components](https://testing-library.com/docs/vue-testing-library/examples). + +When migrating from `@storybook/testing-vue3`, you will likely hit the following error: + +```ts +TypeError: Cannot read properties of undefined (reading 'devtoolsRawSetupState') +``` + +To fix it, you should change the usage of the composed story to reference it instead of calling it as a function. Here's an example using `@testing-library/vue` and Vitest: ```diff import { it } from 'vitest'; @@ -481,9 +489,9 @@ import * as stories from './Button.stories'; import { composeStory } from '@storybook/vue3'; it('renders primary button', () => { - const ComposedButton = composeStory(sotries.Primary); -- render(ComposedButton({ label: 'Hello world' })); -+ render(ComposedButton, { props: { label: 'Hello world' } }); + const Primary = composeStory(stories.Primary, stories.default); +- render(Primary({ label: 'Hello world' })); ++ render(Primary, { props: { label: 'Hello world' } }); }); ``` diff --git a/code/renderers/vue3/src/__tests__/composeStories/portable-stories.test.ts b/code/renderers/vue3/src/__tests__/composeStories/portable-stories.test.ts index 00257ba3aba0..7491a376e07c 100644 --- a/code/renderers/vue3/src/__tests__/composeStories/portable-stories.test.ts +++ b/code/renderers/vue3/src/__tests__/composeStories/portable-stories.test.ts @@ -103,9 +103,9 @@ describe('CSF3', () => { it('renders with play function', async () => { const CSF3InputFieldFilled = composeStory(stories.CSF3InputFieldFilled, stories.default); - const { container } = render(CSF3InputFieldFilled); + render(CSF3InputFieldFilled); - await CSF3InputFieldFilled.play!({ canvasElement: container as HTMLElement }); + await CSF3InputFieldFilled.play!(); const input = screen.getByTestId('input') as HTMLInputElement; expect(input.value).toEqual('Hello world!'); @@ -151,8 +151,8 @@ it.each(testCases)('Renders %s story', async (_storyName, Story) => { } await Story.load(); - const { container, baseElement } = await render(Story()); - await Story.play?.({ canvasElement: container as HTMLElement }); + const { baseElement } = await render(Story); + await Story.play?.(); await new Promise((resolve) => setTimeout(resolve, 0)); expect(baseElement).toMatchSnapshot(); diff --git a/code/renderers/vue3/src/portable-stories.ts b/code/renderers/vue3/src/portable-stories.ts index 6321e4957bcd..73c7991f16a6 100644 --- a/code/renderers/vue3/src/portable-stories.ts +++ b/code/renderers/vue3/src/portable-stories.ts @@ -20,13 +20,9 @@ import type { VueRenderer } from './types'; const defaultProjectAnnotations: ProjectAnnotations = { ...vueProjectAnnotations, decorators: [ - function addStorybookId(story, { id }) { - return { - components: { story }, - template: `
- -
`, - }; + function (story, { id }) { + const wrapperProps = { 'data-story': true, id: getPortableStoryWrapperId(id) }; + return h('div', wrapperProps, h(story())); }, ], }; @@ -69,7 +65,7 @@ export function setProjectAnnotations( * const Primary = composeStory(PrimaryStory, Meta); * * test('renders primary button with Hello World', () => { - * const { getByText } = render(Primary({label: "Hello world"})); + * const { getByText } = render(Primary, { props: { label: "Hello world" } }); * expect(getByText(/Hello world/i)).not.toBeNull(); * }); *``` @@ -119,7 +115,7 @@ export function composeStory( * const { Primary, Secondary } = composeStories(stories); * * test('renders primary button with Hello World', () => { - * const { getByText } = render(Primary({label: "Hello world"})); + * const { getByText } = render(Primary, { props: { label: "Hello world" } }); * expect(getByText(/Hello world/i)).not.toBeNull(); * }); *``` From e37e194e2d71e1aeebe74dcacbb60d1c83b37943 Mon Sep 17 00:00:00 2001 From: jonniebigodes Date: Tue, 5 Mar 2024 16:58:41 +0000 Subject: [PATCH 048/132] Docs: Fix FAQ --- docs/faq.md | 57 ++--------------------------------------------------- 1 file changed, 2 insertions(+), 55 deletions(-) diff --git a/docs/faq.md b/docs/faq.md index 1cceba208102..af3aa33158c9 100644 --- a/docs/faq.md +++ b/docs/faq.md @@ -2,36 +2,7 @@ title: 'Frequently Asked Questions' --- -Here are some answers to frequently asked questions. If you have a question, you can ask it by opening an issue on the [Storybook Repository](https://github.com/storybookjs/storybook/). - -- [Error: No angular.json file found](#error-no-angularjson-file-found) -- [How can I opt-out of Angular Ivy?](#how-can-i-opt-out-of-angular-ivy) -- [How can I opt-out of Angular ngcc?](#how-can-i-opt-out-of-angular-ngcc) -- [How can I run coverage tests with Create React App and leave out stories?](#how-can-i-run-coverage-tests-with-create-react-app-and-leave-out-stories) -- [How do I setup Storybook to share Webpack configuration with Next.js?](#how-do-i-setup-storybook-to-share-webpack-configuration-with-nextjs) -- [How do I fix module resolution in special environments?](#how-do-i-fix-module-resolution-in-special-environments) -- [How do I setup the new React Context Root API with Storybook?](#how-do-i-setup-the-new-react-context-root-api-with-storybook) -- [Why is there no addons channel?](#why-is-there-no-addons-channel) -- [Why aren't Controls visible in the Canvas panel but visible in Docs?](#why-arent-controls-visible-in-the-canvas-panel-but-visible-in-docs) -- [Why aren't the addons working in a composed Storybook?](#why-arent-the-addons-working-in-a-composed-storybook) -- [Can I have a Storybook with no local stories?](#can-i-have-a-storybook-with-no-local-stories) -- [Which community addons are compatible with the latest version of Storybook?](#which-community-addons-are-compatible-with-the-latest-version-of-storybook) -- [Is it possible to browse the documentation for past versions of Storybook?](#is-it-possible-to-browse-the-documentation-for-past-versions-of-storybook) -- [What icons are available for my toolbar or my addon?](#what-icons-are-available-for-my-toolbar-or-my-addon) -- [I see a "No Preview" error with a Storybook production build](#i-see-a-no-preview-error-with-a-storybook-production-build) -- [Can I use Storybook with Vue 2?](#can-i-use-storybook-with-vue-2) -- [Why aren't my code blocks highlighted with Storybook MDX](#why-arent-my-code-blocks-highlighted-with-storybook-mdx) -- [Why aren't my MDX stories working in Storybook?](#why-arent-my-mdx-stories-working-in-storybook) -- [Why are my mocked GraphQL queries failing with Storybook's MSW addon?](#why-are-my-mocked-graphql-queries-failing-with-storybooks-msw-addon) -- [Can I use other GraphQL providers with Storybook's MSW addon?](#can-i-use-other-graphql-providers-with-storybooks-msw-addon) -- [Can I mock GraphQL mutations with Storybook's MSW addon?](#can-i-mock-graphql-mutations-with-storybooks-msw-addon) -- [How can my code detect if it is running in Storybook?](#how-can-my-code-detect-if-it-is-running-in-storybook) -- [Why are my stories not showing up correctly when using certain characters?](#why-are-my-stories-not-showing-up-correctly-when-using-certain-characters) -- [Why are the TypeScript examples and documentation using `as` for type safety?](#why-are-the-typescript-examples-and-documentation-using-as-for-type-safety) -- [Why is Storybook's source loader returning undefined with curried functions?](#why-is-storybooks-source-loader-returning-undefined-with-curried-functions) -- [Why are my args no longer displaying the default values?](#why-are-my-args-no-longer-displaying-the-default-values) -- [Why isn't Storybook's test runner working?](#why-isnt-storybooks-test-runner-working) -- [How does Storybook handle environment variables?](#how-does-storybook-handle-environment-variables) +Here are some answers to frequently asked questions. If you have a question, you can ask it in our [GitHub discussions](https://github.com/storybookjs/storybook/discussions/new?category=help). ## Error: No angular.json file found @@ -222,7 +193,7 @@ Starting with Storybook version 6.0, we've introduced some great features aimed With this, we would like to point out that if you plan on using addons created by our fantastic community, you need to consider that some of those addons might be working with an outdated version of Storybook. -We're actively working to provide a better way to address this situation, but in the meantime, we would ask for a bit of caution on your end so that you don't run into unexpected problems. Let us know by creating an issue in the [Storybook repo](https://github.com/storybookjs/storybook/issues) so that we can gather information and create a curated list with those addons to help not only you but the rest of the community. +We're actively working to provide a better way to address this situation, but in the meantime, we'd like to ask for a bit of caution on your end so that you don't run into unexpected problems. Let us know by leaving a comment in the following [GitHub issue](https://github.com/storybookjs/storybook/issues/26031) so that we can gather information and expand the current list of addons that need to be updated to work with the latest version of Storybook. ## Is it possible to browse the documentation for past versions of Storybook? @@ -465,30 +436,6 @@ You can do this by checking for the `IS_STORYBOOK` global variable, which will e Storybook allows you to use most characters while naming your stories. Still, specific characters (e.g., `#`) can lead to issues when Storybook generates the internal identifier for the story, leading to collisions and incorrectly outputting the correct story. We recommend using such characters sparsely. -## Why are the TypeScript examples and documentation using `as` for type safety? - -We're aware that the default Typescript story construct might seem outdated and could potentially introduce a less than ideal way of handling type safety and strictness and could be rewritten as such: - -```ts -// Button.stories.ts|tsx - -import React from 'react'; -import type { ComponentStory, ComponentMeta } from '@storybook/react'; - -const StoryMeta: ComponentMeta = { - /* ๐Ÿ‘‡ 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, -}; - -export default meta; -``` - -Although valid, it introduces additional boilerplate code to the story definition. Instead, we're working towards implementing a safer mechanism based on what's currently being discussed in the following [issue](https://github.com/microsoft/TypeScript/issues/7481). Once the feature is released, we'll migrate our existing examples and documentation accordingly. - ## Why is Storybook's source loader returning undefined with curried functions? This is a known issue with Storybook. If you're interested in getting it fixed, open an issue with a [working reproduction](./contribute/how-to-reproduce.md) so that it can be triaged and fixed in future releases. From ad2f10dd19e190ab5c5945ed9184efe4c522f03c Mon Sep 17 00:00:00 2001 From: storybook-bot <32066757+storybook-bot@users.noreply.github.com> Date: Tue, 5 Mar 2024 17:28:00 +0000 Subject: [PATCH 049/132] Write changelog for 8.0.0-rc.2 [skip ci] --- CHANGELOG.prerelease.md | 16 ++++++++++++++++ code/package.json | 3 ++- docs/versions/next.json | 2 +- 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.prerelease.md b/CHANGELOG.prerelease.md index 6e9e1eb4ba44..dce7c33f53c7 100644 --- a/CHANGELOG.prerelease.md +++ b/CHANGELOG.prerelease.md @@ -1,3 +1,19 @@ +## 8.0.0-rc.2 + +- CLI: Add @storybook/addons automigration - [#26295](https://github.com/storybookjs/storybook/pull/26295), thanks [@valentinpalkovic](https://github.com/valentinpalkovic)! +- CLI: Fix vite config automigration to resolve from project root - [#26262](https://github.com/storybookjs/storybook/pull/26262), thanks [@valentinpalkovic](https://github.com/valentinpalkovic)! +- CLI: Improve `add` command & add tests - [#26298](https://github.com/storybookjs/storybook/pull/26298), thanks [@ndelangen](https://github.com/ndelangen)! +- CLI: Update minimum Node.js version requirement - [#26312](https://github.com/storybookjs/storybook/pull/26312), thanks [@valentinpalkovic](https://github.com/valentinpalkovic)! +- CSF-tools/Codemods: Upgrade recast - [#26286](https://github.com/storybookjs/storybook/pull/26286), thanks [@43081j](https://github.com/43081j)! +- Controls: Fix type summary when table.type unset - [#26283](https://github.com/storybookjs/storybook/pull/26283), thanks [@shilman](https://github.com/shilman)! +- Core: Add event when serverChannel disconnects - [#26322](https://github.com/storybookjs/storybook/pull/26322), thanks [@ndelangen](https://github.com/ndelangen)! +- Core: Fix composition of storybooks on same origin - [#26304](https://github.com/storybookjs/storybook/pull/26304), thanks [@ndelangen](https://github.com/ndelangen)! +- Portable stories: Improve existing APIs, add loaders support - [#26267](https://github.com/storybookjs/storybook/pull/26267), thanks [@yannbf](https://github.com/yannbf)! +- React: Handle TypeScript path aliases in react-docgen loader - [#26273](https://github.com/storybookjs/storybook/pull/26273), thanks [@valentinpalkovic](https://github.com/valentinpalkovic)! +- Svelte: Support `5.0.0-next.65` prerelease - [#26188](https://github.com/storybookjs/storybook/pull/26188), thanks [@JReinhold](https://github.com/JReinhold)! +- Upgrade: Add missing isUpgrade parameter to automigrate function - [#26293](https://github.com/storybookjs/storybook/pull/26293), thanks [@valentinpalkovic](https://github.com/valentinpalkovic)! +- Vue: Return component from `composeStory` - [#26317](https://github.com/storybookjs/storybook/pull/26317), thanks [@JReinhold](https://github.com/JReinhold)! + ## 8.0.0-rc.1 - CLI: Fix addon compatibility check error reporting in storybook dev - [#26258](https://github.com/storybookjs/storybook/pull/26258), thanks [@yannbf](https://github.com/yannbf)! diff --git a/code/package.json b/code/package.json index b929f5390127..2055b55ef7e6 100644 --- a/code/package.json +++ b/code/package.json @@ -294,5 +294,6 @@ "Dependency Upgrades" ] ] - } + }, + "deferredNextVersion": "8.0.0-rc.2" } diff --git a/docs/versions/next.json b/docs/versions/next.json index a1c6e9350e50..aefc27f51f56 100644 --- a/docs/versions/next.json +++ b/docs/versions/next.json @@ -1 +1 @@ -{"version":"8.0.0-rc.1","info":{"plain":"- CLI: Fix addon compatibility check error reporting in storybook dev - [#26258](https://github.com/storybookjs/storybook/pull/26258), thanks [@yannbf](https://github.com/yannbf)!\n- Onboarding: Fix manager dist reference - [#26282](https://github.com/storybookjs/storybook/pull/26282), thanks [@shilman](https://github.com/shilman)!\n- ReactVite: Docgen ignore un-parsable files - [#26254](https://github.com/storybookjs/storybook/pull/26254), thanks [@ndelangen](https://github.com/ndelangen)!"}} +{"version":"8.0.0-rc.2","info":{"plain":"- CLI: Add @storybook/addons automigration - [#26295](https://github.com/storybookjs/storybook/pull/26295), thanks [@valentinpalkovic](https://github.com/valentinpalkovic)!\n- CLI: Fix vite config automigration to resolve from project root - [#26262](https://github.com/storybookjs/storybook/pull/26262), thanks [@valentinpalkovic](https://github.com/valentinpalkovic)!\n- CLI: Improve `add` command & add tests - [#26298](https://github.com/storybookjs/storybook/pull/26298), thanks [@ndelangen](https://github.com/ndelangen)!\n- CLI: Update minimum Node.js version requirement - [#26312](https://github.com/storybookjs/storybook/pull/26312), thanks [@valentinpalkovic](https://github.com/valentinpalkovic)!\n- CSF-tools/Codemods: Upgrade recast - [#26286](https://github.com/storybookjs/storybook/pull/26286), thanks [@43081j](https://github.com/43081j)!\n- Controls: Fix type summary when table.type unset - [#26283](https://github.com/storybookjs/storybook/pull/26283), thanks [@shilman](https://github.com/shilman)!\n- Core: Add event when serverChannel disconnects - [#26322](https://github.com/storybookjs/storybook/pull/26322), thanks [@ndelangen](https://github.com/ndelangen)!\n- Core: Fix composition of storybooks on same origin - [#26304](https://github.com/storybookjs/storybook/pull/26304), thanks [@ndelangen](https://github.com/ndelangen)!\n- Portable stories: Improve existing APIs, add loaders support - [#26267](https://github.com/storybookjs/storybook/pull/26267), thanks [@yannbf](https://github.com/yannbf)!\n- React: Handle TypeScript path aliases in react-docgen loader - [#26273](https://github.com/storybookjs/storybook/pull/26273), thanks [@valentinpalkovic](https://github.com/valentinpalkovic)!\n- Svelte: Support `5.0.0-next.65` prerelease - [#26188](https://github.com/storybookjs/storybook/pull/26188), thanks [@JReinhold](https://github.com/JReinhold)!\n- Upgrade: Add missing isUpgrade parameter to automigrate function - [#26293](https://github.com/storybookjs/storybook/pull/26293), thanks [@valentinpalkovic](https://github.com/valentinpalkovic)!\n- Vue: Return component from `composeStory` - [#26317](https://github.com/storybookjs/storybook/pull/26317), thanks [@JReinhold](https://github.com/JReinhold)!"}} From ebec658a5fe730385260ad03183827ce3a184199 Mon Sep 17 00:00:00 2001 From: storybook-bot <32066757+storybook-bot@users.noreply.github.com> Date: Tue, 5 Mar 2024 18:02:09 +0000 Subject: [PATCH 050/132] Bump version from "8.0.0-rc.1" to "8.0.0-rc.2" [skip ci] --- code/addons/a11y/package.json | 2 +- code/addons/actions/package.json | 2 +- code/addons/backgrounds/package.json | 2 +- code/addons/controls/package.json | 2 +- code/addons/docs/package.json | 2 +- code/addons/essentials/package.json | 2 +- code/addons/gfm/package.json | 2 +- code/addons/highlight/package.json | 2 +- code/addons/interactions/package.json | 2 +- code/addons/jest/package.json | 2 +- code/addons/links/package.json | 2 +- code/addons/measure/package.json | 2 +- code/addons/onboarding/package.json | 2 +- code/addons/outline/package.json | 2 +- code/addons/storysource/package.json | 2 +- code/addons/themes/package.json | 2 +- code/addons/toolbars/package.json | 2 +- code/addons/viewport/package.json | 2 +- code/builders/builder-manager/package.json | 2 +- code/builders/builder-vite/package.json | 2 +- code/builders/builder-webpack5/package.json | 2 +- code/frameworks/angular/package.json | 2 +- code/frameworks/ember/package.json | 2 +- code/frameworks/html-vite/package.json | 2 +- code/frameworks/html-webpack5/package.json | 2 +- code/frameworks/nextjs/package.json | 2 +- code/frameworks/preact-vite/package.json | 2 +- code/frameworks/preact-webpack5/package.json | 2 +- code/frameworks/react-vite/package.json | 2 +- code/frameworks/react-webpack5/package.json | 2 +- code/frameworks/server-webpack5/package.json | 2 +- code/frameworks/svelte-vite/package.json | 2 +- code/frameworks/svelte-webpack5/package.json | 2 +- code/frameworks/sveltekit/package.json | 2 +- code/frameworks/vue3-vite/package.json | 2 +- code/frameworks/vue3-webpack5/package.json | 2 +- .../web-components-vite/package.json | 2 +- .../web-components-webpack5/package.json | 2 +- code/lib/channels/package.json | 2 +- code/lib/cli-sb/package.json | 2 +- code/lib/cli-storybook/package.json | 2 +- code/lib/cli/package.json | 2 +- code/lib/client-logger/package.json | 2 +- code/lib/codemod/package.json | 2 +- code/lib/core-common/package.json | 2 +- code/lib/core-common/src/versions.ts | 160 +++++++++--------- code/lib/core-events/package.json | 2 +- code/lib/core-server/package.json | 2 +- code/lib/core-webpack/package.json | 2 +- code/lib/csf-plugin/package.json | 2 +- code/lib/csf-tools/package.json | 2 +- code/lib/docs-tools/package.json | 2 +- code/lib/instrumenter/package.json | 2 +- code/lib/manager-api/package.json | 2 +- code/lib/manager-api/src/version.ts | 2 +- code/lib/node-logger/package.json | 2 +- code/lib/preview-api/package.json | 2 +- code/lib/preview/package.json | 2 +- code/lib/react-dom-shim/package.json | 2 +- code/lib/router/package.json | 2 +- code/lib/source-loader/package.json | 2 +- code/lib/telemetry/package.json | 2 +- code/lib/test/package.json | 2 +- code/lib/theming/package.json | 2 +- code/lib/types/package.json | 2 +- code/package.json | 5 +- code/presets/create-react-app/package.json | 2 +- code/presets/html-webpack/package.json | 2 +- code/presets/preact-webpack/package.json | 2 +- code/presets/react-webpack/package.json | 2 +- code/presets/server-webpack/package.json | 2 +- code/presets/svelte-webpack/package.json | 2 +- code/presets/vue3-webpack/package.json | 2 +- code/renderers/html/package.json | 2 +- code/renderers/preact/package.json | 2 +- code/renderers/react/package.json | 2 +- code/renderers/server/package.json | 2 +- code/renderers/svelte/package.json | 2 +- code/renderers/vue3/package.json | 2 +- code/renderers/web-components/package.json | 2 +- code/ui/blocks/package.json | 2 +- code/ui/components/package.json | 2 +- code/ui/manager/package.json | 2 +- 83 files changed, 163 insertions(+), 164 deletions(-) diff --git a/code/addons/a11y/package.json b/code/addons/a11y/package.json index ebae68256c87..abe43c249f6b 100644 --- a/code/addons/a11y/package.json +++ b/code/addons/a11y/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/addon-a11y", - "version": "8.0.0-rc.1", + "version": "8.0.0-rc.2", "description": "Test component compliance with web accessibility standards", "keywords": [ "a11y", diff --git a/code/addons/actions/package.json b/code/addons/actions/package.json index bc89e2f5e5c7..5dcdd61e3c52 100644 --- a/code/addons/actions/package.json +++ b/code/addons/actions/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/addon-actions", - "version": "8.0.0-rc.1", + "version": "8.0.0-rc.2", "description": "Get UI feedback when an action is performed on an interactive element", "keywords": [ "storybook", diff --git a/code/addons/backgrounds/package.json b/code/addons/backgrounds/package.json index 4fbdfc5c027c..17a842b06f13 100644 --- a/code/addons/backgrounds/package.json +++ b/code/addons/backgrounds/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/addon-backgrounds", - "version": "8.0.0-rc.1", + "version": "8.0.0-rc.2", "description": "Switch backgrounds to view components in different settings", "keywords": [ "addon", diff --git a/code/addons/controls/package.json b/code/addons/controls/package.json index 588947d02c70..3df650748609 100644 --- a/code/addons/controls/package.json +++ b/code/addons/controls/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/addon-controls", - "version": "8.0.0-rc.1", + "version": "8.0.0-rc.2", "description": "Interact with component inputs dynamically in the Storybook UI", "keywords": [ "addon", diff --git a/code/addons/docs/package.json b/code/addons/docs/package.json index a159c03063b6..a74ff2e67653 100644 --- a/code/addons/docs/package.json +++ b/code/addons/docs/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/addon-docs", - "version": "8.0.0-rc.1", + "version": "8.0.0-rc.2", "description": "Document component usage and properties in Markdown", "keywords": [ "addon", diff --git a/code/addons/essentials/package.json b/code/addons/essentials/package.json index 61dbf507bbb1..5b01bbd974b1 100644 --- a/code/addons/essentials/package.json +++ b/code/addons/essentials/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/addon-essentials", - "version": "8.0.0-rc.1", + "version": "8.0.0-rc.2", "description": "Curated addons to bring out the best of Storybook", "keywords": [ "addon", diff --git a/code/addons/gfm/package.json b/code/addons/gfm/package.json index 5491ba3a58e4..031416826745 100644 --- a/code/addons/gfm/package.json +++ b/code/addons/gfm/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/addon-mdx-gfm", - "version": "8.0.0-rc.1", + "version": "8.0.0-rc.2", "description": "GitHub Flavored Markdown in Storybook", "keywords": [ "addon", diff --git a/code/addons/highlight/package.json b/code/addons/highlight/package.json index 28f331bf4dc8..e4802d08da43 100644 --- a/code/addons/highlight/package.json +++ b/code/addons/highlight/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/addon-highlight", - "version": "8.0.0-rc.1", + "version": "8.0.0-rc.2", "description": "Highlight DOM nodes within your stories", "keywords": [ "storybook-addons", diff --git a/code/addons/interactions/package.json b/code/addons/interactions/package.json index daece4716036..29d753da6fbf 100644 --- a/code/addons/interactions/package.json +++ b/code/addons/interactions/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/addon-interactions", - "version": "8.0.0-rc.1", + "version": "8.0.0-rc.2", "description": "Automate, test and debug user interactions", "keywords": [ "storybook-addons", diff --git a/code/addons/jest/package.json b/code/addons/jest/package.json index 3b194968932c..7284de78eec3 100644 --- a/code/addons/jest/package.json +++ b/code/addons/jest/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/addon-jest", - "version": "8.0.0-rc.1", + "version": "8.0.0-rc.2", "description": "React storybook addon that show component jest report", "keywords": [ "addon", diff --git a/code/addons/links/package.json b/code/addons/links/package.json index d1777a65aa4d..a23690c6e9b2 100644 --- a/code/addons/links/package.json +++ b/code/addons/links/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/addon-links", - "version": "8.0.0-rc.1", + "version": "8.0.0-rc.2", "description": "Link stories together to build demos and prototypes with your UI components", "keywords": [ "addon", diff --git a/code/addons/measure/package.json b/code/addons/measure/package.json index 2d23660bdac2..843dd37f5197 100644 --- a/code/addons/measure/package.json +++ b/code/addons/measure/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/addon-measure", - "version": "8.0.0-rc.1", + "version": "8.0.0-rc.2", "description": "Inspect layouts by visualizing the box model", "keywords": [ "storybook-addons", diff --git a/code/addons/onboarding/package.json b/code/addons/onboarding/package.json index 057221c7df4e..5064aa48addb 100644 --- a/code/addons/onboarding/package.json +++ b/code/addons/onboarding/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/addon-onboarding", - "version": "8.0.0-rc.1", + "version": "8.0.0-rc.2", "description": "Storybook Addon Onboarding - Introduces a new onboarding experience", "keywords": [ "storybook-addons", diff --git a/code/addons/outline/package.json b/code/addons/outline/package.json index a0a1ff61ab03..b5b5771d6049 100644 --- a/code/addons/outline/package.json +++ b/code/addons/outline/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/addon-outline", - "version": "8.0.0-rc.1", + "version": "8.0.0-rc.2", "description": "Outline all elements with CSS to help with layout placement and alignment", "keywords": [ "storybook-addons", diff --git a/code/addons/storysource/package.json b/code/addons/storysource/package.json index c9fc3680601d..e060751d1a6f 100644 --- a/code/addons/storysource/package.json +++ b/code/addons/storysource/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/addon-storysource", - "version": "8.0.0-rc.1", + "version": "8.0.0-rc.2", "description": "View a storyโ€™s source code to see how it works and paste into your app", "keywords": [ "addon", diff --git a/code/addons/themes/package.json b/code/addons/themes/package.json index c28b3426d2e1..a13dcf595c17 100644 --- a/code/addons/themes/package.json +++ b/code/addons/themes/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/addon-themes", - "version": "8.0.0-rc.1", + "version": "8.0.0-rc.2", "description": "Switch between multiple themes for you components in Storybook", "keywords": [ "css", diff --git a/code/addons/toolbars/package.json b/code/addons/toolbars/package.json index f9aa8edb217e..b1bdae2a70cd 100644 --- a/code/addons/toolbars/package.json +++ b/code/addons/toolbars/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/addon-toolbars", - "version": "8.0.0-rc.1", + "version": "8.0.0-rc.2", "description": "Create your own toolbar items that control story rendering", "keywords": [ "addon", diff --git a/code/addons/viewport/package.json b/code/addons/viewport/package.json index 55459bde0a95..ae6af334349d 100644 --- a/code/addons/viewport/package.json +++ b/code/addons/viewport/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/addon-viewport", - "version": "8.0.0-rc.1", + "version": "8.0.0-rc.2", "description": "Build responsive components by adjusting Storybookโ€™s viewport size and orientation", "keywords": [ "addon", diff --git a/code/builders/builder-manager/package.json b/code/builders/builder-manager/package.json index e892d2dbf0e9..8f4a9c8c964a 100644 --- a/code/builders/builder-manager/package.json +++ b/code/builders/builder-manager/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/builder-manager", - "version": "8.0.0-rc.1", + "version": "8.0.0-rc.2", "description": "Storybook manager builder", "keywords": [ "storybook" diff --git a/code/builders/builder-vite/package.json b/code/builders/builder-vite/package.json index b1dd337500cb..affa9c2fa59b 100644 --- a/code/builders/builder-vite/package.json +++ b/code/builders/builder-vite/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/builder-vite", - "version": "8.0.0-rc.1", + "version": "8.0.0-rc.2", "description": "A plugin to run and build Storybooks with Vite", "homepage": "https://github.com/storybookjs/storybook/tree/next/code/builders/builder-vite/#readme", "bugs": { diff --git a/code/builders/builder-webpack5/package.json b/code/builders/builder-webpack5/package.json index 09e2717e316a..9565198092f8 100644 --- a/code/builders/builder-webpack5/package.json +++ b/code/builders/builder-webpack5/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/builder-webpack5", - "version": "8.0.0-rc.1", + "version": "8.0.0-rc.2", "description": "Storybook framework-agnostic API", "keywords": [ "storybook" diff --git a/code/frameworks/angular/package.json b/code/frameworks/angular/package.json index b58cb37738cf..8639c28d08c2 100644 --- a/code/frameworks/angular/package.json +++ b/code/frameworks/angular/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/angular", - "version": "8.0.0-rc.1", + "version": "8.0.0-rc.2", "description": "Storybook for Angular: Develop Angular components in isolation with hot reloading.", "keywords": [ "storybook", diff --git a/code/frameworks/ember/package.json b/code/frameworks/ember/package.json index f279db33b3ed..db1b2cfe14aa 100644 --- a/code/frameworks/ember/package.json +++ b/code/frameworks/ember/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/ember", - "version": "8.0.0-rc.1", + "version": "8.0.0-rc.2", "description": "Storybook for Ember: Develop Ember Component in isolation with Hot Reloading.", "homepage": "https://github.com/storybookjs/storybook/tree/next/code/frameworks/ember", "bugs": { diff --git a/code/frameworks/html-vite/package.json b/code/frameworks/html-vite/package.json index c4004391a219..5fb64a4a8c48 100644 --- a/code/frameworks/html-vite/package.json +++ b/code/frameworks/html-vite/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/html-vite", - "version": "8.0.0-rc.1", + "version": "8.0.0-rc.2", "description": "Storybook for HTML and Vite: Develop HTML in isolation with Hot Reloading.", "keywords": [ "storybook" diff --git a/code/frameworks/html-webpack5/package.json b/code/frameworks/html-webpack5/package.json index 81cc4e41b756..55e6496baa3c 100644 --- a/code/frameworks/html-webpack5/package.json +++ b/code/frameworks/html-webpack5/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/html-webpack5", - "version": "8.0.0-rc.1", + "version": "8.0.0-rc.2", "description": "Storybook for HTML: View HTML snippets in isolation with Hot Reloading.", "keywords": [ "storybook" diff --git a/code/frameworks/nextjs/package.json b/code/frameworks/nextjs/package.json index 73b56bd55c4b..f622f9eeaabe 100644 --- a/code/frameworks/nextjs/package.json +++ b/code/frameworks/nextjs/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/nextjs", - "version": "8.0.0-rc.1", + "version": "8.0.0-rc.2", "description": "Storybook for Next.js", "keywords": [ "storybook", diff --git a/code/frameworks/preact-vite/package.json b/code/frameworks/preact-vite/package.json index e059321937b6..19e035c0740d 100644 --- a/code/frameworks/preact-vite/package.json +++ b/code/frameworks/preact-vite/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/preact-vite", - "version": "8.0.0-rc.1", + "version": "8.0.0-rc.2", "description": "Storybook for Preact and Vite: Develop Preact components in isolation with Hot Reloading.", "keywords": [ "storybook" diff --git a/code/frameworks/preact-webpack5/package.json b/code/frameworks/preact-webpack5/package.json index 1bfffc99ab65..8423ab98fade 100644 --- a/code/frameworks/preact-webpack5/package.json +++ b/code/frameworks/preact-webpack5/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/preact-webpack5", - "version": "8.0.0-rc.1", + "version": "8.0.0-rc.2", "description": "Storybook for Preact: Develop Preact Component in isolation.", "keywords": [ "storybook" diff --git a/code/frameworks/react-vite/package.json b/code/frameworks/react-vite/package.json index 5673d4caf9dd..a76d1c4cbddc 100644 --- a/code/frameworks/react-vite/package.json +++ b/code/frameworks/react-vite/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/react-vite", - "version": "8.0.0-rc.1", + "version": "8.0.0-rc.2", "description": "Storybook for React and Vite: Develop React components in isolation with Hot Reloading.", "keywords": [ "storybook" diff --git a/code/frameworks/react-webpack5/package.json b/code/frameworks/react-webpack5/package.json index 448905c2a899..a2096ef8e059 100644 --- a/code/frameworks/react-webpack5/package.json +++ b/code/frameworks/react-webpack5/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/react-webpack5", - "version": "8.0.0-rc.1", + "version": "8.0.0-rc.2", "description": "Storybook for React: Develop React Component in isolation with Hot Reloading.", "keywords": [ "storybook" diff --git a/code/frameworks/server-webpack5/package.json b/code/frameworks/server-webpack5/package.json index 8b00bc35433d..7c3771652cfd 100644 --- a/code/frameworks/server-webpack5/package.json +++ b/code/frameworks/server-webpack5/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/server-webpack5", - "version": "8.0.0-rc.1", + "version": "8.0.0-rc.2", "description": "Storybook for Server: View HTML snippets from a server in isolation with Hot Reloading.", "keywords": [ "storybook" diff --git a/code/frameworks/svelte-vite/package.json b/code/frameworks/svelte-vite/package.json index be8d6b0c228e..edac75e5589d 100644 --- a/code/frameworks/svelte-vite/package.json +++ b/code/frameworks/svelte-vite/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/svelte-vite", - "version": "8.0.0-rc.1", + "version": "8.0.0-rc.2", "description": "Storybook for Svelte and Vite: Develop Svelte components in isolation with Hot Reloading.", "keywords": [ "storybook" diff --git a/code/frameworks/svelte-webpack5/package.json b/code/frameworks/svelte-webpack5/package.json index 3979794e33b1..85a17dfc6a76 100644 --- a/code/frameworks/svelte-webpack5/package.json +++ b/code/frameworks/svelte-webpack5/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/svelte-webpack5", - "version": "8.0.0-rc.1", + "version": "8.0.0-rc.2", "description": "Storybook for Svelte: Develop Svelte Component in isolation with Hot Reloading.", "keywords": [ "storybook" diff --git a/code/frameworks/sveltekit/package.json b/code/frameworks/sveltekit/package.json index 8dd860c61d21..b6450c030f5f 100644 --- a/code/frameworks/sveltekit/package.json +++ b/code/frameworks/sveltekit/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/sveltekit", - "version": "8.0.0-rc.1", + "version": "8.0.0-rc.2", "description": "Storybook for SvelteKit", "keywords": [ "storybook", diff --git a/code/frameworks/vue3-vite/package.json b/code/frameworks/vue3-vite/package.json index ad452ade8d46..58e9602305b1 100644 --- a/code/frameworks/vue3-vite/package.json +++ b/code/frameworks/vue3-vite/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/vue3-vite", - "version": "8.0.0-rc.1", + "version": "8.0.0-rc.2", "description": "Storybook for Vue3 and Vite: Develop Vue3 components in isolation with Hot Reloading.", "keywords": [ "storybook" diff --git a/code/frameworks/vue3-webpack5/package.json b/code/frameworks/vue3-webpack5/package.json index 6b6504531dbf..a23d5980b17f 100644 --- a/code/frameworks/vue3-webpack5/package.json +++ b/code/frameworks/vue3-webpack5/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/vue3-webpack5", - "version": "8.0.0-rc.1", + "version": "8.0.0-rc.2", "description": "Storybook for Vue 3: Develop Vue 3 Components in isolation with Hot Reloading.", "keywords": [ "storybook" diff --git a/code/frameworks/web-components-vite/package.json b/code/frameworks/web-components-vite/package.json index c4151a92ca89..6c559ff1a849 100644 --- a/code/frameworks/web-components-vite/package.json +++ b/code/frameworks/web-components-vite/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/web-components-vite", - "version": "8.0.0-rc.1", + "version": "8.0.0-rc.2", "description": "Storybook for web-components and Vite: Develop Web Components in isolation with Hot Reloading.", "keywords": [ "storybook" diff --git a/code/frameworks/web-components-webpack5/package.json b/code/frameworks/web-components-webpack5/package.json index 7e0ab8ec6130..04f0b31cbf1f 100644 --- a/code/frameworks/web-components-webpack5/package.json +++ b/code/frameworks/web-components-webpack5/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/web-components-webpack5", - "version": "8.0.0-rc.1", + "version": "8.0.0-rc.2", "description": "Storybook for web-components: View web components snippets in isolation with Hot Reloading.", "keywords": [ "lit", diff --git a/code/lib/channels/package.json b/code/lib/channels/package.json index 6abecbb236fc..6020059195b0 100644 --- a/code/lib/channels/package.json +++ b/code/lib/channels/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/channels", - "version": "8.0.0-rc.1", + "version": "8.0.0-rc.2", "description": "", "keywords": [ "storybook" diff --git a/code/lib/cli-sb/package.json b/code/lib/cli-sb/package.json index fb2741dc33a2..821450e6252c 100644 --- a/code/lib/cli-sb/package.json +++ b/code/lib/cli-sb/package.json @@ -1,6 +1,6 @@ { "name": "sb", - "version": "8.0.0-rc.1", + "version": "8.0.0-rc.2", "description": "Storybook CLI", "keywords": [ "storybook" diff --git a/code/lib/cli-storybook/package.json b/code/lib/cli-storybook/package.json index f4e2319a57cb..17585083a303 100644 --- a/code/lib/cli-storybook/package.json +++ b/code/lib/cli-storybook/package.json @@ -1,6 +1,6 @@ { "name": "storybook", - "version": "8.0.0-rc.1", + "version": "8.0.0-rc.2", "description": "Storybook CLI", "keywords": [ "storybook" diff --git a/code/lib/cli/package.json b/code/lib/cli/package.json index ed8b9f90bcf6..0f8d72361143 100644 --- a/code/lib/cli/package.json +++ b/code/lib/cli/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/cli", - "version": "8.0.0-rc.1", + "version": "8.0.0-rc.2", "description": "Storybook's CLI - install, dev, build, upgrade, and more", "keywords": [ "cli", diff --git a/code/lib/client-logger/package.json b/code/lib/client-logger/package.json index f5f6f32ed843..60716ac1c3cb 100644 --- a/code/lib/client-logger/package.json +++ b/code/lib/client-logger/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/client-logger", - "version": "8.0.0-rc.1", + "version": "8.0.0-rc.2", "description": "", "keywords": [ "storybook" diff --git a/code/lib/codemod/package.json b/code/lib/codemod/package.json index cdb05de5da4d..dbcac376c369 100644 --- a/code/lib/codemod/package.json +++ b/code/lib/codemod/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/codemod", - "version": "8.0.0-rc.1", + "version": "8.0.0-rc.2", "description": "A collection of codemod scripts written with JSCodeshift", "keywords": [ "storybook" diff --git a/code/lib/core-common/package.json b/code/lib/core-common/package.json index 169977d00655..b4804a0b2772 100644 --- a/code/lib/core-common/package.json +++ b/code/lib/core-common/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/core-common", - "version": "8.0.0-rc.1", + "version": "8.0.0-rc.2", "description": "Storybook framework-agnostic API", "keywords": [ "storybook" diff --git a/code/lib/core-common/src/versions.ts b/code/lib/core-common/src/versions.ts index 346f3d272c65..1de3269c4e5b 100644 --- a/code/lib/core-common/src/versions.ts +++ b/code/lib/core-common/src/versions.ts @@ -1,83 +1,83 @@ // auto generated file, do not edit export default { - '@storybook/addon-a11y': '8.0.0-rc.1', - '@storybook/addon-actions': '8.0.0-rc.1', - '@storybook/addon-backgrounds': '8.0.0-rc.1', - '@storybook/addon-controls': '8.0.0-rc.1', - '@storybook/addon-docs': '8.0.0-rc.1', - '@storybook/addon-essentials': '8.0.0-rc.1', - '@storybook/addon-highlight': '8.0.0-rc.1', - '@storybook/addon-interactions': '8.0.0-rc.1', - '@storybook/addon-jest': '8.0.0-rc.1', - '@storybook/addon-links': '8.0.0-rc.1', - '@storybook/addon-mdx-gfm': '8.0.0-rc.1', - '@storybook/addon-measure': '8.0.0-rc.1', - '@storybook/addon-onboarding': '8.0.0-rc.1', - '@storybook/addon-outline': '8.0.0-rc.1', - '@storybook/addon-storysource': '8.0.0-rc.1', - '@storybook/addon-themes': '8.0.0-rc.1', - '@storybook/addon-toolbars': '8.0.0-rc.1', - '@storybook/addon-viewport': '8.0.0-rc.1', - '@storybook/angular': '8.0.0-rc.1', - '@storybook/blocks': '8.0.0-rc.1', - '@storybook/builder-manager': '8.0.0-rc.1', - '@storybook/builder-vite': '8.0.0-rc.1', - '@storybook/builder-webpack5': '8.0.0-rc.1', - '@storybook/channels': '8.0.0-rc.1', - '@storybook/cli': '8.0.0-rc.1', - '@storybook/client-logger': '8.0.0-rc.1', - '@storybook/codemod': '8.0.0-rc.1', - '@storybook/components': '8.0.0-rc.1', - '@storybook/core-common': '8.0.0-rc.1', - '@storybook/core-events': '8.0.0-rc.1', - '@storybook/core-server': '8.0.0-rc.1', - '@storybook/core-webpack': '8.0.0-rc.1', - '@storybook/csf-plugin': '8.0.0-rc.1', - '@storybook/csf-tools': '8.0.0-rc.1', - '@storybook/docs-tools': '8.0.0-rc.1', - '@storybook/ember': '8.0.0-rc.1', - '@storybook/html': '8.0.0-rc.1', - '@storybook/html-vite': '8.0.0-rc.1', - '@storybook/html-webpack5': '8.0.0-rc.1', - '@storybook/instrumenter': '8.0.0-rc.1', - '@storybook/manager': '8.0.0-rc.1', - '@storybook/manager-api': '8.0.0-rc.1', - '@storybook/nextjs': '8.0.0-rc.1', - '@storybook/node-logger': '8.0.0-rc.1', - '@storybook/preact': '8.0.0-rc.1', - '@storybook/preact-vite': '8.0.0-rc.1', - '@storybook/preact-webpack5': '8.0.0-rc.1', - '@storybook/preset-create-react-app': '8.0.0-rc.1', - '@storybook/preset-html-webpack': '8.0.0-rc.1', - '@storybook/preset-preact-webpack': '8.0.0-rc.1', - '@storybook/preset-react-webpack': '8.0.0-rc.1', - '@storybook/preset-server-webpack': '8.0.0-rc.1', - '@storybook/preset-svelte-webpack': '8.0.0-rc.1', - '@storybook/preset-vue3-webpack': '8.0.0-rc.1', - '@storybook/preview': '8.0.0-rc.1', - '@storybook/preview-api': '8.0.0-rc.1', - '@storybook/react': '8.0.0-rc.1', - '@storybook/react-dom-shim': '8.0.0-rc.1', - '@storybook/react-vite': '8.0.0-rc.1', - '@storybook/react-webpack5': '8.0.0-rc.1', - '@storybook/router': '8.0.0-rc.1', - '@storybook/server': '8.0.0-rc.1', - '@storybook/server-webpack5': '8.0.0-rc.1', - '@storybook/source-loader': '8.0.0-rc.1', - '@storybook/svelte': '8.0.0-rc.1', - '@storybook/svelte-vite': '8.0.0-rc.1', - '@storybook/svelte-webpack5': '8.0.0-rc.1', - '@storybook/sveltekit': '8.0.0-rc.1', - '@storybook/telemetry': '8.0.0-rc.1', - '@storybook/test': '8.0.0-rc.1', - '@storybook/theming': '8.0.0-rc.1', - '@storybook/types': '8.0.0-rc.1', - '@storybook/vue3': '8.0.0-rc.1', - '@storybook/vue3-vite': '8.0.0-rc.1', - '@storybook/vue3-webpack5': '8.0.0-rc.1', - '@storybook/web-components': '8.0.0-rc.1', - '@storybook/web-components-vite': '8.0.0-rc.1', - '@storybook/web-components-webpack5': '8.0.0-rc.1', - sb: '8.0.0-rc.1', - storybook: '8.0.0-rc.1', + '@storybook/addon-a11y': '8.0.0-rc.2', + '@storybook/addon-actions': '8.0.0-rc.2', + '@storybook/addon-backgrounds': '8.0.0-rc.2', + '@storybook/addon-controls': '8.0.0-rc.2', + '@storybook/addon-docs': '8.0.0-rc.2', + '@storybook/addon-essentials': '8.0.0-rc.2', + '@storybook/addon-highlight': '8.0.0-rc.2', + '@storybook/addon-interactions': '8.0.0-rc.2', + '@storybook/addon-jest': '8.0.0-rc.2', + '@storybook/addon-links': '8.0.0-rc.2', + '@storybook/addon-mdx-gfm': '8.0.0-rc.2', + '@storybook/addon-measure': '8.0.0-rc.2', + '@storybook/addon-onboarding': '8.0.0-rc.2', + '@storybook/addon-outline': '8.0.0-rc.2', + '@storybook/addon-storysource': '8.0.0-rc.2', + '@storybook/addon-themes': '8.0.0-rc.2', + '@storybook/addon-toolbars': '8.0.0-rc.2', + '@storybook/addon-viewport': '8.0.0-rc.2', + '@storybook/angular': '8.0.0-rc.2', + '@storybook/blocks': '8.0.0-rc.2', + '@storybook/builder-manager': '8.0.0-rc.2', + '@storybook/builder-vite': '8.0.0-rc.2', + '@storybook/builder-webpack5': '8.0.0-rc.2', + '@storybook/channels': '8.0.0-rc.2', + '@storybook/cli': '8.0.0-rc.2', + '@storybook/client-logger': '8.0.0-rc.2', + '@storybook/codemod': '8.0.0-rc.2', + '@storybook/components': '8.0.0-rc.2', + '@storybook/core-common': '8.0.0-rc.2', + '@storybook/core-events': '8.0.0-rc.2', + '@storybook/core-server': '8.0.0-rc.2', + '@storybook/core-webpack': '8.0.0-rc.2', + '@storybook/csf-plugin': '8.0.0-rc.2', + '@storybook/csf-tools': '8.0.0-rc.2', + '@storybook/docs-tools': '8.0.0-rc.2', + '@storybook/ember': '8.0.0-rc.2', + '@storybook/html': '8.0.0-rc.2', + '@storybook/html-vite': '8.0.0-rc.2', + '@storybook/html-webpack5': '8.0.0-rc.2', + '@storybook/instrumenter': '8.0.0-rc.2', + '@storybook/manager': '8.0.0-rc.2', + '@storybook/manager-api': '8.0.0-rc.2', + '@storybook/nextjs': '8.0.0-rc.2', + '@storybook/node-logger': '8.0.0-rc.2', + '@storybook/preact': '8.0.0-rc.2', + '@storybook/preact-vite': '8.0.0-rc.2', + '@storybook/preact-webpack5': '8.0.0-rc.2', + '@storybook/preset-create-react-app': '8.0.0-rc.2', + '@storybook/preset-html-webpack': '8.0.0-rc.2', + '@storybook/preset-preact-webpack': '8.0.0-rc.2', + '@storybook/preset-react-webpack': '8.0.0-rc.2', + '@storybook/preset-server-webpack': '8.0.0-rc.2', + '@storybook/preset-svelte-webpack': '8.0.0-rc.2', + '@storybook/preset-vue3-webpack': '8.0.0-rc.2', + '@storybook/preview': '8.0.0-rc.2', + '@storybook/preview-api': '8.0.0-rc.2', + '@storybook/react': '8.0.0-rc.2', + '@storybook/react-dom-shim': '8.0.0-rc.2', + '@storybook/react-vite': '8.0.0-rc.2', + '@storybook/react-webpack5': '8.0.0-rc.2', + '@storybook/router': '8.0.0-rc.2', + '@storybook/server': '8.0.0-rc.2', + '@storybook/server-webpack5': '8.0.0-rc.2', + '@storybook/source-loader': '8.0.0-rc.2', + '@storybook/svelte': '8.0.0-rc.2', + '@storybook/svelte-vite': '8.0.0-rc.2', + '@storybook/svelte-webpack5': '8.0.0-rc.2', + '@storybook/sveltekit': '8.0.0-rc.2', + '@storybook/telemetry': '8.0.0-rc.2', + '@storybook/test': '8.0.0-rc.2', + '@storybook/theming': '8.0.0-rc.2', + '@storybook/types': '8.0.0-rc.2', + '@storybook/vue3': '8.0.0-rc.2', + '@storybook/vue3-vite': '8.0.0-rc.2', + '@storybook/vue3-webpack5': '8.0.0-rc.2', + '@storybook/web-components': '8.0.0-rc.2', + '@storybook/web-components-vite': '8.0.0-rc.2', + '@storybook/web-components-webpack5': '8.0.0-rc.2', + sb: '8.0.0-rc.2', + storybook: '8.0.0-rc.2', }; diff --git a/code/lib/core-events/package.json b/code/lib/core-events/package.json index 03a63f346e27..8ada1c3ee9a4 100644 --- a/code/lib/core-events/package.json +++ b/code/lib/core-events/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/core-events", - "version": "8.0.0-rc.1", + "version": "8.0.0-rc.2", "description": "Event names used in storybook core", "keywords": [ "storybook" diff --git a/code/lib/core-server/package.json b/code/lib/core-server/package.json index 663facee0635..1d4f1d43c88b 100644 --- a/code/lib/core-server/package.json +++ b/code/lib/core-server/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/core-server", - "version": "8.0.0-rc.1", + "version": "8.0.0-rc.2", "description": "Storybook framework-agnostic API", "keywords": [ "storybook" diff --git a/code/lib/core-webpack/package.json b/code/lib/core-webpack/package.json index 46f38e226ea1..84199b59fc20 100644 --- a/code/lib/core-webpack/package.json +++ b/code/lib/core-webpack/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/core-webpack", - "version": "8.0.0-rc.1", + "version": "8.0.0-rc.2", "description": "Storybook framework-agnostic API", "keywords": [ "storybook" diff --git a/code/lib/csf-plugin/package.json b/code/lib/csf-plugin/package.json index c447831f6657..7c69964a2bf5 100644 --- a/code/lib/csf-plugin/package.json +++ b/code/lib/csf-plugin/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/csf-plugin", - "version": "8.0.0-rc.1", + "version": "8.0.0-rc.2", "description": "Enrich CSF files via static analysis", "keywords": [ "storybook" diff --git a/code/lib/csf-tools/package.json b/code/lib/csf-tools/package.json index 9004d3e3beae..3aecb2b4c989 100644 --- a/code/lib/csf-tools/package.json +++ b/code/lib/csf-tools/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/csf-tools", - "version": "8.0.0-rc.1", + "version": "8.0.0-rc.2", "description": "Parse and manipulate CSF and Storybook config files", "keywords": [ "storybook" diff --git a/code/lib/docs-tools/package.json b/code/lib/docs-tools/package.json index 06e103124ee1..faead07c757d 100644 --- a/code/lib/docs-tools/package.json +++ b/code/lib/docs-tools/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/docs-tools", - "version": "8.0.0-rc.1", + "version": "8.0.0-rc.2", "description": "Shared utility functions for frameworks to implement docs", "keywords": [ "storybook" diff --git a/code/lib/instrumenter/package.json b/code/lib/instrumenter/package.json index 32c7c06686a8..29aafd117e78 100644 --- a/code/lib/instrumenter/package.json +++ b/code/lib/instrumenter/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/instrumenter", - "version": "8.0.0-rc.1", + "version": "8.0.0-rc.2", "description": "", "keywords": [ "storybook" diff --git a/code/lib/manager-api/package.json b/code/lib/manager-api/package.json index a790395da7a3..6ce5d7c94478 100644 --- a/code/lib/manager-api/package.json +++ b/code/lib/manager-api/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/manager-api", - "version": "8.0.0-rc.1", + "version": "8.0.0-rc.2", "description": "Core Storybook Manager API & Context", "keywords": [ "storybook" diff --git a/code/lib/manager-api/src/version.ts b/code/lib/manager-api/src/version.ts index 156fd9c6a94a..7900754c895d 100644 --- a/code/lib/manager-api/src/version.ts +++ b/code/lib/manager-api/src/version.ts @@ -1 +1 @@ -export const version = '8.0.0-rc.1'; +export const version = '8.0.0-rc.2'; diff --git a/code/lib/node-logger/package.json b/code/lib/node-logger/package.json index 12672e9c0278..eab0c64bfa00 100644 --- a/code/lib/node-logger/package.json +++ b/code/lib/node-logger/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/node-logger", - "version": "8.0.0-rc.1", + "version": "8.0.0-rc.2", "description": "", "keywords": [ "storybook" diff --git a/code/lib/preview-api/package.json b/code/lib/preview-api/package.json index 75d64c9a87b8..8706fb1e6f0e 100644 --- a/code/lib/preview-api/package.json +++ b/code/lib/preview-api/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/preview-api", - "version": "8.0.0-rc.1", + "version": "8.0.0-rc.2", "description": "", "keywords": [ "storybook" diff --git a/code/lib/preview/package.json b/code/lib/preview/package.json index cea251ed2dad..d7f6a6bf9713 100644 --- a/code/lib/preview/package.json +++ b/code/lib/preview/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/preview", - "version": "8.0.0-rc.1", + "version": "8.0.0-rc.2", "description": "", "keywords": [ "storybook" diff --git a/code/lib/react-dom-shim/package.json b/code/lib/react-dom-shim/package.json index 417322b679f2..52f45ceba617 100644 --- a/code/lib/react-dom-shim/package.json +++ b/code/lib/react-dom-shim/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/react-dom-shim", - "version": "8.0.0-rc.1", + "version": "8.0.0-rc.2", "description": "", "keywords": [ "storybook" diff --git a/code/lib/router/package.json b/code/lib/router/package.json index 28bc6525c2d2..79520d10ffbb 100644 --- a/code/lib/router/package.json +++ b/code/lib/router/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/router", - "version": "8.0.0-rc.1", + "version": "8.0.0-rc.2", "description": "Core Storybook Router", "keywords": [ "storybook" diff --git a/code/lib/source-loader/package.json b/code/lib/source-loader/package.json index 634c33cf3d8c..dfd1ee424bc4 100644 --- a/code/lib/source-loader/package.json +++ b/code/lib/source-loader/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/source-loader", - "version": "8.0.0-rc.1", + "version": "8.0.0-rc.2", "description": "Source loader", "keywords": [ "lib", diff --git a/code/lib/telemetry/package.json b/code/lib/telemetry/package.json index bacd55a2207c..430a2add1bdf 100644 --- a/code/lib/telemetry/package.json +++ b/code/lib/telemetry/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/telemetry", - "version": "8.0.0-rc.1", + "version": "8.0.0-rc.2", "description": "Telemetry logging for crash reports and usage statistics", "keywords": [ "storybook" diff --git a/code/lib/test/package.json b/code/lib/test/package.json index 5258ec216e55..d0ae52a03d6f 100644 --- a/code/lib/test/package.json +++ b/code/lib/test/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/test", - "version": "8.0.0-rc.1", + "version": "8.0.0-rc.2", "description": "", "keywords": [ "storybook" diff --git a/code/lib/theming/package.json b/code/lib/theming/package.json index dc6f964b604e..ab85acf2481c 100644 --- a/code/lib/theming/package.json +++ b/code/lib/theming/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/theming", - "version": "8.0.0-rc.1", + "version": "8.0.0-rc.2", "description": "Core Storybook Components", "keywords": [ "storybook" diff --git a/code/lib/types/package.json b/code/lib/types/package.json index 96f6089b73dc..0eb61cdce388 100644 --- a/code/lib/types/package.json +++ b/code/lib/types/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/types", - "version": "8.0.0-rc.1", + "version": "8.0.0-rc.2", "description": "Core Storybook TS Types", "keywords": [ "storybook" diff --git a/code/package.json b/code/package.json index 2055b55ef7e6..687106394b60 100644 --- a/code/package.json +++ b/code/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/root", - "version": "8.0.0-rc.1", + "version": "8.0.0-rc.2", "private": true, "description": "Storybook root", "homepage": "https://storybook.js.org/", @@ -294,6 +294,5 @@ "Dependency Upgrades" ] ] - }, - "deferredNextVersion": "8.0.0-rc.2" + } } diff --git a/code/presets/create-react-app/package.json b/code/presets/create-react-app/package.json index 5275fade6100..ed53ffee0fe9 100644 --- a/code/presets/create-react-app/package.json +++ b/code/presets/create-react-app/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/preset-create-react-app", - "version": "8.0.0-rc.1", + "version": "8.0.0-rc.2", "description": "Storybook for Create React App preset", "keywords": [ "storybook" diff --git a/code/presets/html-webpack/package.json b/code/presets/html-webpack/package.json index c85346ee246a..1ca061b42459 100644 --- a/code/presets/html-webpack/package.json +++ b/code/presets/html-webpack/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/preset-html-webpack", - "version": "8.0.0-rc.1", + "version": "8.0.0-rc.2", "description": "Storybook for HTML: View HTML snippets in isolation with Hot Reloading.", "keywords": [ "storybook" diff --git a/code/presets/preact-webpack/package.json b/code/presets/preact-webpack/package.json index 0edddb4d473d..0fff0481f38d 100644 --- a/code/presets/preact-webpack/package.json +++ b/code/presets/preact-webpack/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/preset-preact-webpack", - "version": "8.0.0-rc.1", + "version": "8.0.0-rc.2", "description": "Storybook for Preact: Develop Preact Component in isolation.", "keywords": [ "storybook" diff --git a/code/presets/react-webpack/package.json b/code/presets/react-webpack/package.json index b3f4377f9da2..dd5f11b03793 100644 --- a/code/presets/react-webpack/package.json +++ b/code/presets/react-webpack/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/preset-react-webpack", - "version": "8.0.0-rc.1", + "version": "8.0.0-rc.2", "description": "Storybook for React: Develop React Component in isolation with Hot Reloading", "keywords": [ "storybook" diff --git a/code/presets/server-webpack/package.json b/code/presets/server-webpack/package.json index 0c57f088153d..39e509374b67 100644 --- a/code/presets/server-webpack/package.json +++ b/code/presets/server-webpack/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/preset-server-webpack", - "version": "8.0.0-rc.1", + "version": "8.0.0-rc.2", "description": "Storybook for Server: View HTML snippets from a server in isolation with Hot Reloading.", "keywords": [ "storybook" diff --git a/code/presets/svelte-webpack/package.json b/code/presets/svelte-webpack/package.json index d80d06b70c22..efcbd040827c 100644 --- a/code/presets/svelte-webpack/package.json +++ b/code/presets/svelte-webpack/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/preset-svelte-webpack", - "version": "8.0.0-rc.1", + "version": "8.0.0-rc.2", "description": "Storybook for Svelte: Develop Svelte Component in isolation with Hot Reloading.", "keywords": [ "storybook" diff --git a/code/presets/vue3-webpack/package.json b/code/presets/vue3-webpack/package.json index 774e7247eafb..f19a6e689a0e 100644 --- a/code/presets/vue3-webpack/package.json +++ b/code/presets/vue3-webpack/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/preset-vue3-webpack", - "version": "8.0.0-rc.1", + "version": "8.0.0-rc.2", "description": "Storybook for Vue 3: Develop Vue 3 Components in isolation with Hot Reloading.", "keywords": [ "storybook" diff --git a/code/renderers/html/package.json b/code/renderers/html/package.json index ce6c017145aa..d65de0340b40 100644 --- a/code/renderers/html/package.json +++ b/code/renderers/html/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/html", - "version": "8.0.0-rc.1", + "version": "8.0.0-rc.2", "description": "Storybook HTML renderer", "keywords": [ "storybook" diff --git a/code/renderers/preact/package.json b/code/renderers/preact/package.json index 685eb8e50aaa..964a280e875c 100644 --- a/code/renderers/preact/package.json +++ b/code/renderers/preact/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/preact", - "version": "8.0.0-rc.1", + "version": "8.0.0-rc.2", "description": "Storybook Preact renderer", "keywords": [ "storybook" diff --git a/code/renderers/react/package.json b/code/renderers/react/package.json index de60e151b77c..a42882c38ebf 100644 --- a/code/renderers/react/package.json +++ b/code/renderers/react/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/react", - "version": "8.0.0-rc.1", + "version": "8.0.0-rc.2", "description": "Storybook React renderer", "keywords": [ "storybook" diff --git a/code/renderers/server/package.json b/code/renderers/server/package.json index f4c892e2a87a..e17abd07240a 100644 --- a/code/renderers/server/package.json +++ b/code/renderers/server/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/server", - "version": "8.0.0-rc.1", + "version": "8.0.0-rc.2", "description": "Storybook Server renderer", "keywords": [ "storybook" diff --git a/code/renderers/svelte/package.json b/code/renderers/svelte/package.json index da7ad794fca2..f33c169654cd 100644 --- a/code/renderers/svelte/package.json +++ b/code/renderers/svelte/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/svelte", - "version": "8.0.0-rc.1", + "version": "8.0.0-rc.2", "description": "Storybook Svelte renderer", "keywords": [ "storybook" diff --git a/code/renderers/vue3/package.json b/code/renderers/vue3/package.json index ec3d8037453a..cc5a72a3cde1 100644 --- a/code/renderers/vue3/package.json +++ b/code/renderers/vue3/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/vue3", - "version": "8.0.0-rc.1", + "version": "8.0.0-rc.2", "description": "Storybook Vue 3 renderer", "keywords": [ "storybook" diff --git a/code/renderers/web-components/package.json b/code/renderers/web-components/package.json index fcd133473b18..1483eb3de461 100644 --- a/code/renderers/web-components/package.json +++ b/code/renderers/web-components/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/web-components", - "version": "8.0.0-rc.1", + "version": "8.0.0-rc.2", "description": "Storybook web-components renderer", "keywords": [ "lit", diff --git a/code/ui/blocks/package.json b/code/ui/blocks/package.json index c48cbadc893a..790612807846 100644 --- a/code/ui/blocks/package.json +++ b/code/ui/blocks/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/blocks", - "version": "8.0.0-rc.1", + "version": "8.0.0-rc.2", "description": "Storybook Doc Blocks", "keywords": [ "storybook" diff --git a/code/ui/components/package.json b/code/ui/components/package.json index 248ed68c73c5..fcb4235f18e1 100644 --- a/code/ui/components/package.json +++ b/code/ui/components/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/components", - "version": "8.0.0-rc.1", + "version": "8.0.0-rc.2", "description": "Core Storybook Components", "keywords": [ "storybook" diff --git a/code/ui/manager/package.json b/code/ui/manager/package.json index b13135e4eb4f..05c4b076ed7b 100644 --- a/code/ui/manager/package.json +++ b/code/ui/manager/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/manager", - "version": "8.0.0-rc.1", + "version": "8.0.0-rc.2", "description": "Core Storybook UI", "keywords": [ "storybook" From 96213412f4726f9ce7bd14d3baba514342e699bb Mon Sep 17 00:00:00 2001 From: Jeppe Reinhold Date: Tue, 5 Mar 2024 21:11:10 +0100 Subject: [PATCH 051/132] use dynamic vite imports in docs snippets --- docs/snippets/common/main-config-vite-final-env.js.mdx | 4 ++-- docs/snippets/common/main-config-vite-final.js.mdx | 4 ++-- docs/snippets/common/main-config-vite-final.ts-4-9.mdx | 4 ++-- docs/snippets/common/main-config-vite-final.ts.mdx | 3 ++- docs/snippets/common/storybook-vite-builder-aliasing.js.mdx | 4 ++-- 5 files changed, 10 insertions(+), 9 deletions(-) diff --git a/docs/snippets/common/main-config-vite-final-env.js.mdx b/docs/snippets/common/main-config-vite-final-env.js.mdx index 73926f408471..e1ddc08d9644 100644 --- a/docs/snippets/common/main-config-vite-final-env.js.mdx +++ b/docs/snippets/common/main-config-vite-final-env.js.mdx @@ -1,14 +1,14 @@ ```js // .storybook/main.js|ts -import { mergeConfig } from 'vite'; - export default { stories: ['../src/**/*.mdx', '../stories/**/*.stories.@(js|jsx|mjs|ts|tsx)'], core: { builder: '@storybook/builder-vite', }, async viteFinal(config, { configType }) { + const { mergeConfig } = await import('vite'); + if (configType === 'DEVELOPMENT') { // Your development configuration goes here } diff --git a/docs/snippets/common/main-config-vite-final.js.mdx b/docs/snippets/common/main-config-vite-final.js.mdx index b2987dcd412c..dbb5d70555ba 100644 --- a/docs/snippets/common/main-config-vite-final.js.mdx +++ b/docs/snippets/common/main-config-vite-final.js.mdx @@ -1,13 +1,13 @@ ```js // .storybook/main.js -import { mergeConfig } from 'vite'; - export default { // Replace your-framework with the framework you are using (e.g., react-vite, vue3-vite) framework: '@storybook/your-framework', stories: ['../src/**/*.mdx', '../stories/**/*.stories.@(js|jsx|mjs|ts|tsx)'], async viteFinal(config, { configType }) { + const { mergeConfig } = await import('vite'); + if (configType === 'DEVELOPMENT') { // Your development configuration goes here } diff --git a/docs/snippets/common/main-config-vite-final.ts-4-9.mdx b/docs/snippets/common/main-config-vite-final.ts-4-9.mdx index 42d7f8cf8b9d..f5f36cdafdba 100644 --- a/docs/snippets/common/main-config-vite-final.ts-4-9.mdx +++ b/docs/snippets/common/main-config-vite-final.ts-4-9.mdx @@ -4,13 +4,13 @@ // Replace your-framework with the framework you are using (e.g., react-vite, vue3-vite) import type { StorybookConfig } from '@storybook/your-framework'; -import { mergeConfig } from 'vite'; - const config: StorybookConfig = { // Replace your-framework with the framework you are using (e.g., react-vite, vue3-vite) framework: '@storybook/your-framework', stories: ['../src/**/*.mdx', '../stories/**/*.stories.@(js|jsx|mjs|ts|tsx)'], async viteFinal(config, { configType }) { + const { mergeConfig } = await import('vite'); + if (configType === 'DEVELOPMENT') { // Your development configuration goes here } diff --git a/docs/snippets/common/main-config-vite-final.ts.mdx b/docs/snippets/common/main-config-vite-final.ts.mdx index a82973f98afc..2df5faf42cd5 100644 --- a/docs/snippets/common/main-config-vite-final.ts.mdx +++ b/docs/snippets/common/main-config-vite-final.ts.mdx @@ -3,12 +3,13 @@ // Replace your-framework with the framework you are using (e.g., react-vite, vue3-vite) import type { StorybookConfig } from '@storybook/your-framework'; -import { mergeConfig } from 'vite'; const config = { framework: '@storybook/your-framework', stories: ['../src/**/*.mdx', '../stories/**/*.stories.@(js|jsx|mjs|ts|tsx)'], async viteFinal(config, { configType }) { + const { mergeConfig } = await import('vite'); + if (configType === 'DEVELOPMENT') { // Your development configuration goes here } diff --git a/docs/snippets/common/storybook-vite-builder-aliasing.js.mdx b/docs/snippets/common/storybook-vite-builder-aliasing.js.mdx index ea5f2e7550de..c6dfb19d7581 100644 --- a/docs/snippets/common/storybook-vite-builder-aliasing.js.mdx +++ b/docs/snippets/common/storybook-vite-builder-aliasing.js.mdx @@ -1,8 +1,6 @@ ```js // .storybook/main.js|ts -import { mergeConfig } from 'vite'; - export default { stories: ['../src/**/*.mdx', '../stories/**/*.stories.@(js|jsx|mjs|ts|tsx)'], addons: ['@storybook/addon-links', '@storybook/addon-essentials'], @@ -11,6 +9,8 @@ export default { }, async viteFinal(config) { // Merge custom configuration into the default config + const { mergeConfig } = await import('vite'); + return mergeConfig(config, { // Add dependencies to pre-optimization optimizeDeps: { From 9d90dc19f8197909d33686897607ca7cf8c269b0 Mon Sep 17 00:00:00 2001 From: Jeppe Reinhold Date: Tue, 5 Mar 2024 22:19:26 +0100 Subject: [PATCH 052/132] don't re-render sidebar whenever any manager UI state changes --- .../manager/src/components/sidebar/Sidebar.tsx | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/code/ui/manager/src/components/sidebar/Sidebar.tsx b/code/ui/manager/src/components/sidebar/Sidebar.tsx index 3ea23f6b48a5..f881e3d68d4d 100644 --- a/code/ui/manager/src/components/sidebar/Sidebar.tsx +++ b/code/ui/manager/src/components/sidebar/Sidebar.tsx @@ -17,7 +17,7 @@ import { Explorer } from './Explorer'; import { Search } from './Search'; import { SearchResults } from './SearchResults'; -import type { Refs, CombinedDataset, Selection } from './types'; +import type { CombinedDataset, Selection } from './types'; import { useLastViewed } from './useLastViewed'; import { MEDIA_DESKTOP_BREAKPOINT } from '../../constants'; @@ -79,20 +79,26 @@ const Swap = React.memo(function Swap({ }); const useCombination = ( - defaultRefData: API_LoadedRefData & { status: State['status'] }, - refs: Refs + index: SidebarProps['index'], + indexError: SidebarProps['indexError'], + previewInitialized: SidebarProps['previewInitialized'], + status: SidebarProps['status'], + refs: SidebarProps['refs'] ): CombinedDataset => { const hash = useMemo( () => ({ [DEFAULT_REF_ID]: { - ...defaultRefData, + index, + indexError, + previewInitialized, + status, title: null, id: DEFAULT_REF_ID, url: 'iframe.html', }, ...refs, }), - [refs, defaultRefData] + [refs, index, indexError, previewInitialized, status] ); return useMemo(() => ({ hash, entries: Object.entries(hash) }), [hash]); }; @@ -126,7 +132,7 @@ export const Sidebar = React.memo(function Sidebar({ onMenuClick, }: SidebarProps) { const selected: Selection = useMemo(() => storyId && { storyId, refId }, [storyId, refId]); - const dataset = useCombination({ index, indexError, previewInitialized, status }, refs); + const dataset = useCombination(index, indexError, previewInitialized, status, refs); const isLoading = !index && !indexError; const lastViewedProps = useLastViewed(selected); From cd2dac32d9fae818e86f5f8c9bb164a4e5ef853a Mon Sep 17 00:00:00 2001 From: Jeppe Reinhold Date: Wed, 6 Mar 2024 08:00:00 +0100 Subject: [PATCH 053/132] add story for testing scroll behavior --- .../components/sidebar/Sidebar.stories.tsx | 96 +++++++++++++++++-- 1 file changed, 87 insertions(+), 9 deletions(-) diff --git a/code/ui/manager/src/components/sidebar/Sidebar.stories.tsx b/code/ui/manager/src/components/sidebar/Sidebar.stories.tsx index 3e7b7e2b23f3..e8af8d457021 100644 --- a/code/ui/manager/src/components/sidebar/Sidebar.stories.tsx +++ b/code/ui/manager/src/components/sidebar/Sidebar.stories.tsx @@ -1,14 +1,13 @@ import React from 'react'; import type { IndexHash, State } from '@storybook/manager-api'; -import { types } from '@storybook/manager-api'; +import { ManagerContext, types } from '@storybook/manager-api'; import type { StoryObj, Meta } from '@storybook/react'; -import { within, userEvent } from '@storybook/testing-library'; +import { within, userEvent, expect } from '@storybook/test'; import { Button, IconButton } from '@storybook/components'; import { FaceHappyIcon } from '@storybook/icons'; import { Sidebar, DEFAULT_REF_ID } from './Sidebar'; import { standardData as standardHeaderData } from './Heading.stories'; -import * as ExplorerStories from './Explorer.stories'; import { mockDataset } from './mockdata'; import type { RefType } from './types'; import { LayoutProvider } from '../layout/LayoutProvider'; @@ -25,15 +24,34 @@ const meta = { excludeStories: /.*Data$/, parameters: { layout: 'fullscreen' }, decorators: [ - ExplorerStories.default.decorators[0], (storyFn) => ( - - - {storyFn()} - + {}, + on: () => {}, + off: () => {}, + getShortcutKeys: () => ({ search: ['control', 'shift', 's'] }), + }, + } as any + } + > + + + {storyFn()} + + ), ], -} as Meta; +} satisfies Meta; export default meta; @@ -57,6 +75,7 @@ const refs: Record = { }, }; +// eslint-disable-next-line local-rules/no-uncategorized-errors const indexError = new Error('Failed to load index'); const refsError = { @@ -328,3 +347,62 @@ export const Bottom: Story = { /> ), }; + +/** + * Given the following sequence of events: + * 1. Story is selected at the top of the sidebar + * 2. The sidebar is scrolled to the bottom + * 3. Some re-rendering happens because of a changed state/prop + * The sidebar should remain scrolled to the bottom + */ +export const Scrolled: Story = { + parameters: { + // we need a very short viewport + viewport: { + defaultViewport: 'mobile1', + defaultOrientation: 'landscape', + }, + }, + render: (args) => { + const [, setState] = React.useState(0); + return ( + <> + + + + ); + }, + play: async ({ canvasElement, step }) => { + const canvas = await within(canvasElement); + const scrollable = await canvasElement.querySelector('[data-radix-scroll-area-viewport]'); + await step('expand component', async () => { + const componentNode = await canvas.queryAllByText('Child A2')[1]; + userEvent.click(componentNode); + }); + await wait(100); + await step('scroll to bottom', async () => { + scrollable.scrollTo(0, scrollable.scrollHeight); + }); + await step('toggle parent state', async () => { + const button = await canvas.findByRole('button', { name: 'Change state' }); + button.click(); + }); + await wait(100); + + // expect the scrollable to be scrolled to the bottom + expect(scrollable.scrollTop).toBe(scrollable.scrollHeight - scrollable.clientHeight); + }, +}; From 43a70e9af82560fa48d7aa06c0059a319a5e8535 Mon Sep 17 00:00:00 2001 From: Jeppe Reinhold Date: Wed, 6 Mar 2024 08:11:52 +0100 Subject: [PATCH 054/132] refactor Sidebar stories --- .../components/sidebar/Sidebar.stories.tsx | 249 +++++------------- 1 file changed, 70 insertions(+), 179 deletions(-) diff --git a/code/ui/manager/src/components/sidebar/Sidebar.stories.tsx b/code/ui/manager/src/components/sidebar/Sidebar.stories.tsx index e8af8d457021..253775bc07c7 100644 --- a/code/ui/manager/src/components/sidebar/Sidebar.stories.tsx +++ b/code/ui/manager/src/components/sidebar/Sidebar.stories.tsx @@ -4,6 +4,7 @@ import type { IndexHash, State } from '@storybook/manager-api'; import { ManagerContext, types } from '@storybook/manager-api'; import type { StoryObj, Meta } from '@storybook/react'; import { within, userEvent, expect } from '@storybook/test'; +import type { Addon_SidebarTopType } from '@storybook/types'; import { Button, IconButton } from '@storybook/components'; import { FaceHappyIcon } from '@storybook/icons'; import { Sidebar, DEFAULT_REF_ID } from './Sidebar'; @@ -18,11 +19,28 @@ const wait = (ms: number) => setTimeout(resolve, ms); }); +const { menu } = standardHeaderData; +const index = mockDataset.withRoot as IndexHash; +const storyId = 'root-1-child-a2--grandchild-a1-1'; + +export const simpleData = { menu, index, storyId }; +export const loadingData = { menu }; + const meta = { component: Sidebar, title: 'Sidebar/Sidebar', excludeStories: /.*Data$/, parameters: { layout: 'fullscreen' }, + args: { + previewInitialized: true, + menu, + extra: [] as Addon_SidebarTopType[], + index: index, + storyId, + refId: DEFAULT_REF_ID, + refs: {}, + status: {}, + }, decorators: [ (storyFn) => ( ; -const { menu } = standardHeaderData; -const index = mockDataset.withRoot as IndexHash; -const storyId = 'root-1-child-a2--grandchild-a1-1'; - -export const simpleData = { menu, index, storyId }; -export const loadingData = { menu }; - const refs: Record = { optimized: { id: 'optimized', @@ -94,146 +105,56 @@ const refsEmpty = { }, }; -export const Simple: Story = { - args: { previewInitialized: true }, - render: (args) => ( - - ), -}; +export const Simple: Story = {}; export const Loading: Story = { - args: { previewInitialized: false }, - render: (args) => ( - - ), + args: { + previewInitialized: false, + index: undefined, + }, }; export const Empty: Story = { args: { - previewInitialized: true, + index: {}, }, - render: (args) => ( - - ), }; export const IndexError: Story = { args: { - previewInitialized: true, + indexError, }, - render: (args) => ( - - ), }; export const WithRefs: Story = { args: { - previewInitialized: true, + refs, }, - render: (args) => ( - - ), }; export const LoadingWithRefs: Story = { args: { - previewInitialized: false, + ...Loading.args, + refs, }, - render: (args) => ( - - ), }; export const LoadingWithRefError: Story = { args: { - previewInitialized: false, + ...Loading.args, + refs: refsError, }, - render: (args) => ( - - ), }; export const WithRefEmpty: Story = { args: { - previewInitialized: true, + ...Empty.args, + refs: refsEmpty, }, - render: (args) => ( - - ), }; export const StatusesCollapsed: Story = { args: { - previewInitialized: true, status: Object.entries(index).reduce((acc, [id, item]) => { if (item.type !== 'story') { return acc; @@ -251,17 +172,6 @@ export const StatusesCollapsed: Story = { return acc; }, {}), }, - render: (args) => ( - - ), }; export const StatusesOpen: Story = { @@ -286,7 +196,7 @@ export const StatusesOpen: Story = { export const Searching: Story = { ...StatusesOpen, - parameters: { theme: 'light', chromatic: { delay: 2200 } }, + parameters: { chromatic: { delay: 2200 } }, play: async ({ canvasElement, step }) => { await step('wait 2000ms', () => wait(2000)); const canvas = await within(canvasElement); @@ -298,54 +208,40 @@ export const Searching: Story = { export const Bottom: Story = { args: { - previewInitialized: true, + bottom: [ + { + id: '1', + type: types.experimental_SIDEBAR_BOTTOM, + render: () => ( + + ), + }, + { + id: '2', + type: types.experimental_SIDEBAR_BOTTOM, + render: () => ( + + ), + }, + { + id: '3', + type: types.experimental_SIDEBAR_BOTTOM, + render: () => ( + + {' '} + + + ), + }, + ], }, - parameters: { theme: 'light' }, - render: (args) => ( - ( - - ), - }, - { - id: '2', - type: types.experimental_SIDEBAR_BOTTOM, - render: () => ( - - ), - }, - { - id: '3', - type: types.experimental_SIDEBAR_BOTTOM, - render: () => ( - - {' '} - - - ), - }, - ]} - /> - ), }; /** @@ -363,6 +259,9 @@ export const Scrolled: Story = { defaultOrientation: 'landscape', }, }, + args: { + storyId: 'group-1--child-b1', + }, render: (args) => { const [, setState] = React.useState(0); return ( @@ -373,15 +272,7 @@ export const Scrolled: Story = { > Change state - + ); }, From 85ab8aada703240adfc797056c14b39c4a8cb095 Mon Sep 17 00:00:00 2001 From: Valentin Palkovic Date: Wed, 6 Mar 2024 08:43:17 +0100 Subject: [PATCH 055/132] Update MIGRATION.md --- MIGRATION.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MIGRATION.md b/MIGRATION.md index d954414a2342..935788cbd9c9 100644 --- a/MIGRATION.md +++ b/MIGRATION.md @@ -1043,7 +1043,7 @@ Please file an issue if you need these APIs. #### Removals in @storybook/components -The `TooltipLinkList` component accepts a `links` property where, for each link, a `left` property could be passed. The left property is now removed in Storybook 8 and beyond. Use `icon` instead. The side-effect is that the `left` property is now removed from the `Link` component. The Link component is used to define `globalTypes` in the `preview.js` file, among other places: +The `TooltipLinkList` component accepts a `links` property where, for each link, a `left` property could be passed. The left property is now removed in Storybook 8 and beyond. Use `icon` instead. The side-effect is that the `left` property is now removed from the `Link` component. This has an effect on the `globalTypes` definition in the `preview.js` file, among other places: ```diff // Replace your-framework with the framework you are using (e.g., react, vue3) From f352857f1f1151895482017b1ef877eb53259308 Mon Sep 17 00:00:00 2001 From: Jeppe Reinhold Date: Wed, 6 Mar 2024 09:25:17 +0100 Subject: [PATCH 056/132] use npm to create qwik sandbox --- code/lib/cli/src/sandbox-templates.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/lib/cli/src/sandbox-templates.ts b/code/lib/cli/src/sandbox-templates.ts index 182e49798148..b28021be7049 100644 --- a/code/lib/cli/src/sandbox-templates.ts +++ b/code/lib/cli/src/sandbox-templates.ts @@ -443,7 +443,7 @@ const baseTemplates = { }, 'qwik-vite/default-ts': { name: 'Qwik CLI Latest (Vite | TypeScript)', - script: 'yarn create qwik basic {{beforeDir}}', + script: 'npm create qwik basic {{beforeDir}}', // TODO: The community template does not provide standard stories, which is required for e2e tests. Reenable once it does. inDevelopment: true, expected: { From e4a47f577b3b07986962811118ed954d7351cb3a Mon Sep 17 00:00:00 2001 From: Norbert de Langen Date: Wed, 6 Mar 2024 14:55:23 +0100 Subject: [PATCH 057/132] replace testing-library with test in monorepo --- .../stories/docspage/autoplay.stories.ts | 3 +- code/addons/interactions/package.json | 2 +- .../src/components/Interaction.stories.tsx | 3 +- .../components/InteractionsPanel.stories.tsx | 3 +- code/addons/onboarding/package.json | 1 - .../src/components/List/List.stories.tsx | 3 +- .../src/components/Modal/Modal.stories.tsx | 3 +- .../PulsatingEffect.stories.tsx | 3 +- .../WriteStoriesModal.stories.tsx | 3 +- .../with-browser-animations.stories.ts | 3 +- .../with-noop-browser-animations.stories.ts | 3 +- .../nextjs/template/stories/Image.stories.jsx | 1 - .../Head.stories.jsx | 3 +- .../template/stories/argMapping.stories.ts | 3 +- .../template/stories/argTypes.stories.ts | 3 +- .../template/stories/args.stories.ts | 3 +- .../stories/component-play.stories.ts | 3 +- .../template/stories/decorators.stories.ts | 3 +- .../template/stories/globals.stories.ts | 3 +- .../template/stories/hooks.stories.ts | 2 +- .../template/stories/loaders.stories.ts | 3 +- .../template/stories/parameters.stories.ts | 3 +- .../template/stories/rendering.stories.ts | 3 +- .../template/stories/shortcuts.stories.ts | 3 +- .../template/stories/tags.stories.ts | 3 +- .../svelte/template/stories/args.stories.js | 10 +-- .../GlobalSetup.stories.ts | 3 +- .../ReactiveArgs.stories.ts | 3 +- .../ReactiveDecorators.stories.ts | 2 +- .../ReactiveSlots.stories.ts | 3 +- .../ScopedSlots.stories.ts | 3 +- .../blocks/src/components/Story.stories.tsx | 2 +- .../blocks/src/controls/Boolean.stories.tsx | 3 +- .../ui/blocks/src/examples/Button.stories.tsx | 3 +- .../src/components/tabs/tabs.stories.tsx | 9 +-- .../mobile/about/MobileAbout.stories.tsx | 2 +- .../navigation/MobileNavigation.stories.tsx | 2 +- .../src/components/sidebar/Menu.stories.tsx | 3 +- .../src/components/sidebar/Tree.stories.tsx | 4 +- code/yarn.lock | 75 +++---------------- scripts/yarn.lock | 9 +-- 41 files changed, 49 insertions(+), 156 deletions(-) diff --git a/code/addons/docs/template/stories/docspage/autoplay.stories.ts b/code/addons/docs/template/stories/docspage/autoplay.stories.ts index 36fc395949d8..6ebdc43b3ad7 100644 --- a/code/addons/docs/template/stories/docspage/autoplay.stories.ts +++ b/code/addons/docs/template/stories/docspage/autoplay.stories.ts @@ -1,6 +1,5 @@ import { global as globalThis } from '@storybook/global'; -import { expect } from '@storybook/test'; -import { within } from '@storybook/testing-library'; +import { expect, within } from '@storybook/test'; export default { component: globalThis.Components.Pre, diff --git a/code/addons/interactions/package.json b/code/addons/interactions/package.json index 29d753da6fbf..851843fe0e2b 100644 --- a/code/addons/interactions/package.json +++ b/code/addons/interactions/package.json @@ -65,7 +65,7 @@ "@storybook/instrumenter": "workspace:*", "@storybook/manager-api": "workspace:*", "@storybook/preview-api": "workspace:*", - "@storybook/testing-library": "next", + "@storybook/test": "workspace:*", "@storybook/theming": "workspace:*", "@types/node": "^18.0.0", "formik": "^2.2.9", diff --git a/code/addons/interactions/src/components/Interaction.stories.tsx b/code/addons/interactions/src/components/Interaction.stories.tsx index b18cd7136c6a..a6f8bd3a3b46 100644 --- a/code/addons/interactions/src/components/Interaction.stories.tsx +++ b/code/addons/interactions/src/components/Interaction.stories.tsx @@ -1,7 +1,6 @@ import type { StoryObj, Meta } from '@storybook/react'; -import { expect } from '@storybook/test'; import { CallStates } from '@storybook/instrumenter'; -import { userEvent, within } from '@storybook/testing-library'; +import { userEvent, within, expect } from '@storybook/test'; import { getCalls } from '../mocks'; import { Interaction } from './Interaction'; diff --git a/code/addons/interactions/src/components/InteractionsPanel.stories.tsx b/code/addons/interactions/src/components/InteractionsPanel.stories.tsx index a2435113ef02..89f7ef115b59 100644 --- a/code/addons/interactions/src/components/InteractionsPanel.stories.tsx +++ b/code/addons/interactions/src/components/InteractionsPanel.stories.tsx @@ -2,8 +2,7 @@ import React from 'react'; import type { StoryObj, Meta } from '@storybook/react'; import { CallStates } from '@storybook/instrumenter'; import { styled } from '@storybook/theming'; -import { userEvent, within, waitFor } from '@storybook/testing-library'; -import { expect } from '@storybook/test'; +import { userEvent, within, waitFor, expect } from '@storybook/test'; import isChromatic from 'chromatic/isChromatic'; import { getCalls, getInteractions } from '../mocks'; diff --git a/code/addons/onboarding/package.json b/code/addons/onboarding/package.json index 5064aa48addb..e38e1243bc09 100644 --- a/code/addons/onboarding/package.json +++ b/code/addons/onboarding/package.json @@ -55,7 +55,6 @@ "@storybook/react": "workspace:*", "@storybook/telemetry": "workspace:*", "@storybook/test": "workspace:*", - "@storybook/testing-library": "next", "@storybook/theming": "workspace:*", "@storybook/types": "workspace:*", "framer-motion": "^11.0.3", diff --git a/code/addons/onboarding/src/components/List/List.stories.tsx b/code/addons/onboarding/src/components/List/List.stories.tsx index 380fd07ca4cc..9ff667586fc3 100644 --- a/code/addons/onboarding/src/components/List/List.stories.tsx +++ b/code/addons/onboarding/src/components/List/List.stories.tsx @@ -1,7 +1,6 @@ import React, { useState } from 'react'; import type { Meta, StoryObj } from '@storybook/react'; -import { userEvent, waitFor, within } from '@storybook/testing-library'; -import { expect } from '@storybook/test'; +import { userEvent, waitFor, within, expect } from '@storybook/test'; import { List } from './List'; import { ListItem } from './ListItem/ListItem'; diff --git a/code/addons/onboarding/src/components/Modal/Modal.stories.tsx b/code/addons/onboarding/src/components/Modal/Modal.stories.tsx index 51d19c49b4f5..527aa87d4323 100644 --- a/code/addons/onboarding/src/components/Modal/Modal.stories.tsx +++ b/code/addons/onboarding/src/components/Modal/Modal.stories.tsx @@ -1,7 +1,6 @@ import React, { useState } from 'react'; import type { Meta, StoryObj } from '@storybook/react'; -import { userEvent, within } from '@storybook/testing-library'; -import { expect } from '@storybook/test'; +import { userEvent, within, expect } from '@storybook/test'; import { Modal } from './Modal'; diff --git a/code/addons/onboarding/src/components/PulsatingEffect/PulsatingEffect.stories.tsx b/code/addons/onboarding/src/components/PulsatingEffect/PulsatingEffect.stories.tsx index 67b31843dc45..6a87a2147c0a 100644 --- a/code/addons/onboarding/src/components/PulsatingEffect/PulsatingEffect.stories.tsx +++ b/code/addons/onboarding/src/components/PulsatingEffect/PulsatingEffect.stories.tsx @@ -1,8 +1,7 @@ import type { Meta, StoryObj } from '@storybook/react'; import { PulsatingEffect } from './PulsatingEffect'; import React from 'react'; -import { within } from '@storybook/testing-library'; -import { expect } from '@storybook/test'; +import { within, expect } from '@storybook/test'; const meta: Meta = { component: PulsatingEffect, diff --git a/code/addons/onboarding/src/features/WriteStoriesModal/WriteStoriesModal.stories.tsx b/code/addons/onboarding/src/features/WriteStoriesModal/WriteStoriesModal.stories.tsx index d2284dbd913f..d2fe6ba470b4 100644 --- a/code/addons/onboarding/src/features/WriteStoriesModal/WriteStoriesModal.stories.tsx +++ b/code/addons/onboarding/src/features/WriteStoriesModal/WriteStoriesModal.stories.tsx @@ -1,8 +1,7 @@ import React from 'react'; import type { Meta, StoryObj } from '@storybook/react'; -import { waitFor, within } from '@storybook/testing-library'; -import { expect, fn } from '@storybook/test'; +import { waitFor, within, expect, fn } from '@storybook/test'; import { STORY_INDEX_INVALIDATED, STORY_RENDERED } from '@storybook/core-events'; import { WriteStoriesModal } from './WriteStoriesModal'; import typescriptSnippet from './code/typescript'; diff --git a/code/frameworks/angular/template/stories/core/applicationConfig/with-browser-animations.stories.ts b/code/frameworks/angular/template/stories/core/applicationConfig/with-browser-animations.stories.ts index f61db00d8f0e..ef30854c26f9 100644 --- a/code/frameworks/angular/template/stories/core/applicationConfig/with-browser-animations.stories.ts +++ b/code/frameworks/angular/template/stories/core/applicationConfig/with-browser-animations.stories.ts @@ -1,7 +1,6 @@ import { Meta, StoryObj, applicationConfig } from '@storybook/angular'; import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; -import { within, userEvent } from '@storybook/testing-library'; -import { expect } from '@storybook/test'; +import { within, userEvent, expect } from '@storybook/test'; import { importProvidersFrom } from '@angular/core'; import { OpenCloseComponent } from '../moduleMetadata/angular-src/open-close-component/open-close.component'; diff --git a/code/frameworks/angular/template/stories/core/applicationConfig/with-noop-browser-animations.stories.ts b/code/frameworks/angular/template/stories/core/applicationConfig/with-noop-browser-animations.stories.ts index 1a4341ec77cf..3369b9949d33 100644 --- a/code/frameworks/angular/template/stories/core/applicationConfig/with-noop-browser-animations.stories.ts +++ b/code/frameworks/angular/template/stories/core/applicationConfig/with-noop-browser-animations.stories.ts @@ -1,7 +1,6 @@ import { Meta, StoryObj } from '@storybook/angular'; import { NoopAnimationsModule } from '@angular/platform-browser/animations'; -import { within, userEvent } from '@storybook/testing-library'; -import { expect } from '@storybook/test'; +import { within, userEvent, expect } from '@storybook/test'; import { importProvidersFrom } from '@angular/core'; import { OpenCloseComponent } from '../moduleMetadata/angular-src/open-close-component/open-close.component'; diff --git a/code/frameworks/nextjs/template/stories/Image.stories.jsx b/code/frameworks/nextjs/template/stories/Image.stories.jsx index 8fa4f6a53de1..79ab308e1286 100644 --- a/code/frameworks/nextjs/template/stories/Image.stories.jsx +++ b/code/frameworks/nextjs/template/stories/Image.stories.jsx @@ -1,6 +1,5 @@ import React, { useRef, useState } from 'react'; import Image from 'next/image'; -import { waitFor } from '@storybook/testing-library'; import Accessibility from '../../assets/accessibility.svg'; import AvifImage from '../../assets/avif-test-image.avif'; diff --git a/code/frameworks/nextjs/template/stories_nextjs-default-js/Head.stories.jsx b/code/frameworks/nextjs/template/stories_nextjs-default-js/Head.stories.jsx index f031096d6ced..1e43bb39eba6 100644 --- a/code/frameworks/nextjs/template/stories_nextjs-default-js/Head.stories.jsx +++ b/code/frameworks/nextjs/template/stories_nextjs-default-js/Head.stories.jsx @@ -1,7 +1,6 @@ -import { expect } from '@storybook/test'; import Head from 'next/head'; import React from 'react'; -import { within, userEvent, waitFor } from '@storybook/testing-library'; +import { waitFor, expect } from '@storybook/test'; function Component() { return ( diff --git a/code/lib/preview-api/template/stories/argMapping.stories.ts b/code/lib/preview-api/template/stories/argMapping.stories.ts index cd41237d17af..11322e8b22d7 100644 --- a/code/lib/preview-api/template/stories/argMapping.stories.ts +++ b/code/lib/preview-api/template/stories/argMapping.stories.ts @@ -1,7 +1,6 @@ import { global as globalThis } from '@storybook/global'; import type { PartialStoryFn, PlayFunctionContext, StoryContext } from '@storybook/types'; -import { within } from '@storybook/testing-library'; -import { expect } from '@storybook/test'; +import { within, expect } from '@storybook/test'; const arrows = { ArrowUp: { name: 'ArrowUp' }, diff --git a/code/lib/preview-api/template/stories/argTypes.stories.ts b/code/lib/preview-api/template/stories/argTypes.stories.ts index 5f2b81c004fc..3998ce68f8ad 100644 --- a/code/lib/preview-api/template/stories/argTypes.stories.ts +++ b/code/lib/preview-api/template/stories/argTypes.stories.ts @@ -1,7 +1,6 @@ import { global as globalThis } from '@storybook/global'; import type { PartialStoryFn, PlayFunctionContext, StoryContext } from '@storybook/types'; -import { within } from '@storybook/testing-library'; -import { expect } from '@storybook/test'; +import { expect, within } from '@storybook/test'; export default { component: globalThis.Components.Pre, diff --git a/code/lib/preview-api/template/stories/args.stories.ts b/code/lib/preview-api/template/stories/args.stories.ts index 5315fb2a3dbf..68e601c350e6 100644 --- a/code/lib/preview-api/template/stories/args.stories.ts +++ b/code/lib/preview-api/template/stories/args.stories.ts @@ -1,7 +1,6 @@ import { global as globalThis } from '@storybook/global'; import type { PartialStoryFn, PlayFunctionContext, StoryContext } from '@storybook/types'; -import { within } from '@storybook/testing-library'; -import { expect } from '@storybook/test'; +import { within, expect } from '@storybook/test'; import pick from 'lodash/pick'; import { STORY_ARGS_UPDATED, UPDATE_STORY_ARGS, RESET_STORY_ARGS } from '@storybook/core-events'; diff --git a/code/lib/preview-api/template/stories/component-play.stories.ts b/code/lib/preview-api/template/stories/component-play.stories.ts index 08efe9847b1f..f4611d7219ce 100644 --- a/code/lib/preview-api/template/stories/component-play.stories.ts +++ b/code/lib/preview-api/template/stories/component-play.stories.ts @@ -1,7 +1,6 @@ import { global as globalThis } from '@storybook/global'; import type { PartialStoryFn, PlayFunctionContext, StoryContext } from '@storybook/types'; -import { within } from '@storybook/testing-library'; -import { expect } from '@storybook/test'; +import { within, expect } from '@storybook/test'; export default { component: globalThis.Components.Pre, diff --git a/code/lib/preview-api/template/stories/decorators.stories.ts b/code/lib/preview-api/template/stories/decorators.stories.ts index f374bcf1d640..467f7245f383 100644 --- a/code/lib/preview-api/template/stories/decorators.stories.ts +++ b/code/lib/preview-api/template/stories/decorators.stories.ts @@ -5,8 +5,7 @@ import type { PlayFunctionContext, StoryContext, } from '@storybook/types'; -import { within } from '@storybook/testing-library'; -import { expect } from '@storybook/test'; +import { within, expect } from '@storybook/test'; import { useEffect } from '@storybook/preview-api'; import { STORY_ARGS_UPDATED, UPDATE_STORY_ARGS, RESET_STORY_ARGS } from '@storybook/core-events'; diff --git a/code/lib/preview-api/template/stories/globals.stories.ts b/code/lib/preview-api/template/stories/globals.stories.ts index ff66a964766e..8e49f4b0095d 100644 --- a/code/lib/preview-api/template/stories/globals.stories.ts +++ b/code/lib/preview-api/template/stories/globals.stories.ts @@ -1,7 +1,6 @@ import { global as globalThis } from '@storybook/global'; import type { PartialStoryFn, PlayFunctionContext, StoryContext } from '@storybook/types'; -import { within } from '@storybook/testing-library'; -import { expect } from '@storybook/test'; +import { within, expect } from '@storybook/test'; export default { component: globalThis.Components.Pre, diff --git a/code/lib/preview-api/template/stories/hooks.stories.ts b/code/lib/preview-api/template/stories/hooks.stories.ts index 15a4fe90a2ea..b2c31429359e 100644 --- a/code/lib/preview-api/template/stories/hooks.stories.ts +++ b/code/lib/preview-api/template/stories/hooks.stories.ts @@ -1,7 +1,7 @@ import { global as globalThis } from '@storybook/global'; import type { PartialStoryFn, PlayFunctionContext } from '@storybook/types'; import { useEffect, useState } from '@storybook/preview-api'; -import { within, userEvent } from '@storybook/testing-library'; +import { within, userEvent } from '@storybook/test'; export default { component: globalThis.Components.Button, diff --git a/code/lib/preview-api/template/stories/loaders.stories.ts b/code/lib/preview-api/template/stories/loaders.stories.ts index 000bfe5dc159..dadb82a236f2 100644 --- a/code/lib/preview-api/template/stories/loaders.stories.ts +++ b/code/lib/preview-api/template/stories/loaders.stories.ts @@ -1,7 +1,6 @@ import { global as globalThis } from '@storybook/global'; import type { PartialStoryFn, PlayFunctionContext, StoryContext } from '@storybook/types'; -import { within } from '@storybook/testing-library'; -import { expect } from '@storybook/test'; +import { within, expect } from '@storybook/test'; export default { component: globalThis.Components.Pre, diff --git a/code/lib/preview-api/template/stories/parameters.stories.ts b/code/lib/preview-api/template/stories/parameters.stories.ts index be0a84582ae3..06e9b94ae84b 100644 --- a/code/lib/preview-api/template/stories/parameters.stories.ts +++ b/code/lib/preview-api/template/stories/parameters.stories.ts @@ -1,7 +1,6 @@ import { global as globalThis } from '@storybook/global'; import type { PartialStoryFn, PlayFunctionContext, StoryContext } from '@storybook/types'; -import { within } from '@storybook/testing-library'; -import { expect } from '@storybook/test'; +import { within, expect } from '@storybook/test'; export default { component: globalThis.Components.Pre, diff --git a/code/lib/preview-api/template/stories/rendering.stories.ts b/code/lib/preview-api/template/stories/rendering.stories.ts index ff36890bf265..477e07137987 100644 --- a/code/lib/preview-api/template/stories/rendering.stories.ts +++ b/code/lib/preview-api/template/stories/rendering.stories.ts @@ -1,7 +1,6 @@ import { global as globalThis } from '@storybook/global'; import type { PlayFunctionContext } from '@storybook/types'; -import { within, waitFor } from '@storybook/testing-library'; -import { expect } from '@storybook/test'; +import { within, waitFor, expect } from '@storybook/test'; import { FORCE_REMOUNT, RESET_STORY_ARGS, diff --git a/code/lib/preview-api/template/stories/shortcuts.stories.ts b/code/lib/preview-api/template/stories/shortcuts.stories.ts index 91a597427bb6..be748fb27ea2 100644 --- a/code/lib/preview-api/template/stories/shortcuts.stories.ts +++ b/code/lib/preview-api/template/stories/shortcuts.stories.ts @@ -1,7 +1,6 @@ import { global as globalThis } from '@storybook/global'; -import { userEvent, within } from '@storybook/testing-library'; +import { userEvent, within, expect, fn } from '@storybook/test'; import { PREVIEW_KEYDOWN } from '@storybook/core-events'; -import { expect, fn } from '@storybook/test'; import type { PlayFunctionContext } from '@storybook/csf'; export default { diff --git a/code/lib/preview-api/template/stories/tags.stories.ts b/code/lib/preview-api/template/stories/tags.stories.ts index 96209421f5d6..61ffe8811429 100644 --- a/code/lib/preview-api/template/stories/tags.stories.ts +++ b/code/lib/preview-api/template/stories/tags.stories.ts @@ -1,7 +1,6 @@ import { global as globalThis } from '@storybook/global'; import type { PartialStoryFn, PlayFunctionContext, StoryContext } from '@storybook/types'; -import { within } from '@storybook/testing-library'; -import { expect } from '@storybook/test'; +import { within, expect } from '@storybook/test'; export default { component: globalThis.Components.Pre, diff --git a/code/renderers/svelte/template/stories/args.stories.js b/code/renderers/svelte/template/stories/args.stories.js index 493b5519e6e2..71544066ecd1 100644 --- a/code/renderers/svelte/template/stories/args.stories.js +++ b/code/renderers/svelte/template/stories/args.stories.js @@ -1,11 +1,5 @@ -import { expect } from '@storybook/test'; -import { within, userEvent, waitFor } from '@storybook/testing-library'; -import { - UPDATE_STORY_ARGS, - STORY_ARGS_UPDATED, - RESET_STORY_ARGS, - STORY_RENDERED, -} from '@storybook/core-events'; +import { within, userEvent, waitFor, expect } from '@storybook/test'; +import { UPDATE_STORY_ARGS, RESET_STORY_ARGS, STORY_RENDERED } from '@storybook/core-events'; import { addons } from '@storybook/preview-api'; import ButtonView from './views/ButtonJavaScript.svelte'; diff --git a/code/renderers/vue3/template/stories_vue3-vite-default-ts/GlobalSetup.stories.ts b/code/renderers/vue3/template/stories_vue3-vite-default-ts/GlobalSetup.stories.ts index 5e01135e20c0..725b0e65ee93 100644 --- a/code/renderers/vue3/template/stories_vue3-vite-default-ts/GlobalSetup.stories.ts +++ b/code/renderers/vue3/template/stories_vue3-vite-default-ts/GlobalSetup.stories.ts @@ -1,6 +1,5 @@ -import { expect } from '@storybook/test'; import type { Meta, StoryObj } from '@storybook/vue3'; -import { within } from '@storybook/testing-library'; +import { within, expect } from '@storybook/test'; import { inject } from 'vue'; import GlobalSetup from './GlobalSetup.vue'; diff --git a/code/renderers/vue3/template/stories_vue3-vite-default-ts/ReactiveArgs.stories.ts b/code/renderers/vue3/template/stories_vue3-vite-default-ts/ReactiveArgs.stories.ts index 536c962c2ee1..ff076fcca733 100644 --- a/code/renderers/vue3/template/stories_vue3-vite-default-ts/ReactiveArgs.stories.ts +++ b/code/renderers/vue3/template/stories_vue3-vite-default-ts/ReactiveArgs.stories.ts @@ -1,7 +1,6 @@ -import { expect } from '@storybook/test'; import { global as globalThis } from '@storybook/global'; import type { Meta, StoryObj, StoryFn } from '@storybook/vue3'; -import { within, userEvent } from '@storybook/testing-library'; +import { within, userEvent, expect } from '@storybook/test'; import { UPDATE_STORY_ARGS, STORY_ARGS_UPDATED, RESET_STORY_ARGS } from '@storybook/core-events'; import ReactiveArgs from './ReactiveArgs.vue'; diff --git a/code/renderers/vue3/template/stories_vue3-vite-default-ts/ReactiveDecorators.stories.ts b/code/renderers/vue3/template/stories_vue3-vite-default-ts/ReactiveDecorators.stories.ts index 143cd1784559..d6a7e743d778 100644 --- a/code/renderers/vue3/template/stories_vue3-vite-default-ts/ReactiveDecorators.stories.ts +++ b/code/renderers/vue3/template/stories_vue3-vite-default-ts/ReactiveDecorators.stories.ts @@ -1,5 +1,5 @@ import { global as globalThis } from '@storybook/global'; -import { userEvent, within } from '@storybook/testing-library'; +import { userEvent, within } from '@storybook/test'; import type { Meta, StoryObj } from '@storybook/vue3'; import { h } from 'vue'; import { RESET_STORY_ARGS, STORY_ARGS_UPDATED, UPDATE_STORY_ARGS } from '@storybook/core-events'; diff --git a/code/renderers/vue3/template/stories_vue3-vite-default-ts/ReactiveSlots.stories.ts b/code/renderers/vue3/template/stories_vue3-vite-default-ts/ReactiveSlots.stories.ts index d0042b65a2a5..bde19efc07e8 100644 --- a/code/renderers/vue3/template/stories_vue3-vite-default-ts/ReactiveSlots.stories.ts +++ b/code/renderers/vue3/template/stories_vue3-vite-default-ts/ReactiveSlots.stories.ts @@ -1,6 +1,5 @@ -import { expect } from '@storybook/test'; import { global as globalThis } from '@storybook/global'; -import { within } from '@storybook/testing-library'; +import { within, expect } from '@storybook/test'; import { STORY_ARGS_UPDATED, RESET_STORY_ARGS, UPDATE_STORY_ARGS } from '@storybook/core-events'; import { h } from 'vue'; import type { Meta, StoryObj } from '@storybook/vue3'; diff --git a/code/renderers/vue3/template/stories_vue3-vite-default-ts/ScopedSlots.stories.ts b/code/renderers/vue3/template/stories_vue3-vite-default-ts/ScopedSlots.stories.ts index ef7a625ea413..b255be571d43 100644 --- a/code/renderers/vue3/template/stories_vue3-vite-default-ts/ScopedSlots.stories.ts +++ b/code/renderers/vue3/template/stories_vue3-vite-default-ts/ScopedSlots.stories.ts @@ -1,7 +1,6 @@ -import { expect } from '@storybook/test'; import { global as globalThis } from '@storybook/global'; import type { Channel } from '@storybook/channels'; -import { within } from '@storybook/testing-library'; +import { within, expect } from '@storybook/test'; import { UPDATE_STORY_ARGS, STORY_ARGS_UPDATED, RESET_STORY_ARGS } from '@storybook/core-events'; import type { Meta, StoryObj } from '@storybook/vue3'; diff --git a/code/ui/blocks/src/components/Story.stories.tsx b/code/ui/blocks/src/components/Story.stories.tsx index ae9a277a9425..fa1767d747af 100644 --- a/code/ui/blocks/src/components/Story.stories.tsx +++ b/code/ui/blocks/src/components/Story.stories.tsx @@ -1,6 +1,6 @@ import React from 'react'; import type { Meta, ReactRenderer, StoryObj } from '@storybook/react'; -import { within } from '@storybook/testing-library'; +import { within } from '@storybook/test'; import type { PlayFunctionContext } from '@storybook/csf'; import type { WebRenderer, ModuleExport } from '@storybook/types'; import { RESET_STORY_ARGS, STORY_ARGS_UPDATED, UPDATE_STORY_ARGS } from '@storybook/core-events'; diff --git a/code/ui/blocks/src/controls/Boolean.stories.tsx b/code/ui/blocks/src/controls/Boolean.stories.tsx index e83338c41241..8f7c043701c6 100644 --- a/code/ui/blocks/src/controls/Boolean.stories.tsx +++ b/code/ui/blocks/src/controls/Boolean.stories.tsx @@ -1,6 +1,5 @@ -import { expect } from '@storybook/test'; import type { Meta, StoryObj } from '@storybook/react'; -import { within, fireEvent, waitFor } from '@storybook/testing-library'; +import { within, fireEvent, waitFor, expect } from '@storybook/test'; import { addons } from '@storybook/preview-api'; import { RESET_STORY_ARGS, STORY_ARGS_UPDATED } from '@storybook/core-events'; import { BooleanControl } from './Boolean'; diff --git a/code/ui/blocks/src/examples/Button.stories.tsx b/code/ui/blocks/src/examples/Button.stories.tsx index 7e22aef00064..d99917fdfee8 100644 --- a/code/ui/blocks/src/examples/Button.stories.tsx +++ b/code/ui/blocks/src/examples/Button.stories.tsx @@ -1,6 +1,5 @@ -import { expect } from '@storybook/test'; import type { Meta, StoryObj } from '@storybook/react'; -import { within, fireEvent } from '@storybook/testing-library'; +import { within, fireEvent, expect } from '@storybook/test'; import React from 'react'; import { Button } from './Button'; diff --git a/code/ui/components/src/components/tabs/tabs.stories.tsx b/code/ui/components/src/components/tabs/tabs.stories.tsx index 9312c70c8bec..46a332a87f1f 100644 --- a/code/ui/components/src/components/tabs/tabs.stories.tsx +++ b/code/ui/components/src/components/tabs/tabs.stories.tsx @@ -2,14 +2,7 @@ import { expect } from '@storybook/test'; import React, { Fragment } from 'react'; import { action } from '@storybook/addon-actions'; import type { Meta, StoryObj } from '@storybook/react'; -import { - within, - fireEvent, - waitFor, - screen, - userEvent, - findByText, -} from '@storybook/testing-library'; +import { within, fireEvent, waitFor, screen, userEvent, findByText } from '@storybook/test'; import { CPUIcon, MemoryIcon } from '@storybook/icons'; import { Tabs, TabsState, TabWrapper } from './tabs'; import type { ChildrenList } from './tabs.helpers'; diff --git a/code/ui/manager/src/components/mobile/about/MobileAbout.stories.tsx b/code/ui/manager/src/components/mobile/about/MobileAbout.stories.tsx index 7ef6f9d89f92..b36e2e0854f7 100644 --- a/code/ui/manager/src/components/mobile/about/MobileAbout.stories.tsx +++ b/code/ui/manager/src/components/mobile/about/MobileAbout.stories.tsx @@ -1,7 +1,7 @@ import type { Meta, StoryObj } from '@storybook/react'; import { ManagerContext } from '@storybook/manager-api'; import React, { useEffect } from 'react'; -import { within } from '@storybook/testing-library'; +import { within } from '@storybook/test'; import { MobileAbout } from './MobileAbout'; import { LayoutProvider, useLayout } from '../../layout/LayoutProvider'; diff --git a/code/ui/manager/src/components/mobile/navigation/MobileNavigation.stories.tsx b/code/ui/manager/src/components/mobile/navigation/MobileNavigation.stories.tsx index 7617574cdd4e..8978534f6890 100644 --- a/code/ui/manager/src/components/mobile/navigation/MobileNavigation.stories.tsx +++ b/code/ui/manager/src/components/mobile/navigation/MobileNavigation.stories.tsx @@ -1,7 +1,7 @@ import type { Meta, StoryObj } from '@storybook/react'; import React from 'react'; import { ManagerContext } from '@storybook/manager-api'; -import { within } from '@storybook/testing-library'; +import { within } from '@storybook/test'; import { startCase } from 'lodash'; import { MobileNavigation } from './MobileNavigation'; import { LayoutProvider, useLayout } from '../../layout/LayoutProvider'; diff --git a/code/ui/manager/src/components/sidebar/Menu.stories.tsx b/code/ui/manager/src/components/sidebar/Menu.stories.tsx index 98788518db4b..ca57b4780a67 100644 --- a/code/ui/manager/src/components/sidebar/Menu.stories.tsx +++ b/code/ui/manager/src/components/sidebar/Menu.stories.tsx @@ -1,11 +1,10 @@ import type { ComponentProps } from 'react'; import React from 'react'; -import { expect } from '@storybook/test'; import type { Meta, StoryObj } from '@storybook/react'; import { TooltipLinkList } from '@storybook/components'; import { styled } from '@storybook/theming'; -import { screen, userEvent, within } from '@storybook/testing-library'; +import { screen, userEvent, within, expect } from '@storybook/test'; import type { State } from '@storybook/manager-api'; import { LinkIcon } from '@storybook/icons'; import { SidebarMenu } from './Menu'; diff --git a/code/ui/manager/src/components/sidebar/Tree.stories.tsx b/code/ui/manager/src/components/sidebar/Tree.stories.tsx index eb2aa83959fc..00036a574db5 100644 --- a/code/ui/manager/src/components/sidebar/Tree.stories.tsx +++ b/code/ui/manager/src/components/sidebar/Tree.stories.tsx @@ -4,9 +4,7 @@ import type { ComponentEntry, IndexHash } from '@storybook/manager-api'; import { action } from '@storybook/addon-actions'; import type { StoryObj, Meta } from '@storybook/react'; -import { within } from '@storybook/testing-library'; - -import { expect } from '@storybook/test'; +import { within, expect } from '@storybook/test'; import { Tree } from './Tree'; import { index } from './mockdata.large'; import { DEFAULT_REF_ID } from './Sidebar'; diff --git a/code/yarn.lock b/code/yarn.lock index 5e19c4ce9845..da0e12d44fb8 100644 --- a/code/yarn.lock +++ b/code/yarn.lock @@ -5114,7 +5114,7 @@ __metadata: "@storybook/instrumenter": "workspace:*" "@storybook/manager-api": "workspace:*" "@storybook/preview-api": "workspace:*" - "@storybook/testing-library": "npm:next" + "@storybook/test": "workspace:*" "@storybook/theming": "workspace:*" "@storybook/types": "workspace:*" "@types/node": "npm:^18.0.0" @@ -5216,7 +5216,6 @@ __metadata: "@storybook/react": "workspace:*" "@storybook/telemetry": "workspace:*" "@storybook/test": "workspace:*" - "@storybook/testing-library": "npm:next" "@storybook/theming": "workspace:*" "@storybook/types": "workspace:*" framer-motion: "npm:^11.0.3" @@ -7086,7 +7085,7 @@ __metadata: languageName: node linkType: hard -"@sveltejs/vite-plugin-svelte-inspector@npm:^2.0.0, @sveltejs/vite-plugin-svelte-inspector@npm:^2.0.0-next.0 || ^2.0.0": +"@sveltejs/vite-plugin-svelte-inspector@npm:^2.0.0": version: 2.0.0 resolution: "@sveltejs/vite-plugin-svelte-inspector@npm:2.0.0" dependencies: @@ -7099,25 +7098,7 @@ __metadata: languageName: node linkType: hard -"@sveltejs/vite-plugin-svelte@npm:^3.0.1": - version: 3.0.1 - resolution: "@sveltejs/vite-plugin-svelte@npm:3.0.1" - dependencies: - "@sveltejs/vite-plugin-svelte-inspector": "npm:^2.0.0-next.0 || ^2.0.0" - debug: "npm:^4.3.4" - deepmerge: "npm:^4.3.1" - kleur: "npm:^4.1.5" - magic-string: "npm:^0.30.5" - svelte-hmr: "npm:^0.15.3" - vitefu: "npm:^0.2.5" - peerDependencies: - svelte: ^4.0.0 || ^5.0.0-next.0 - vite: ^5.0.0 - checksum: 889d41014d4cc5dfb578cb0a80e64f72c0f8c143e9a299c3a4e2372fd582d982ce118dad5e158e0b747d1df7354a909ed9490b1adcd1bf982b56c82fffd4652c - languageName: node - linkType: hard - -"@sveltejs/vite-plugin-svelte@npm:^3.0.2": +"@sveltejs/vite-plugin-svelte@npm:^3.0.1, @sveltejs/vite-plugin-svelte@npm:^3.0.2": version: 3.0.2 resolution: "@sveltejs/vite-plugin-svelte@npm:3.0.2" dependencies: @@ -7594,10 +7575,10 @@ __metadata: languageName: node linkType: hard -"@types/estree@npm:*, @types/estree@npm:^1.0.0, @types/estree@npm:^1.0.1": - version: 1.0.2 - resolution: "@types/estree@npm:1.0.2" - checksum: 4b5c601d435ea8e2205458de15fd1556b5ae6c9a8323bad8a940ea502d6c824664faca94234c0bf76bf9c87cbf6ac41abee550c9e20433256549d589c9b543bd +"@types/estree@npm:*, @types/estree@npm:^1.0.0, @types/estree@npm:^1.0.1, @types/estree@npm:^1.0.5": + version: 1.0.5 + resolution: "@types/estree@npm:1.0.5" + checksum: b3b0e334288ddb407c7b3357ca67dbee75ee22db242ca7c56fe27db4e1a31989cb8af48a84dd401deb787fe10cc6b2ab1ee82dc4783be87ededbe3d53c79c70d languageName: node linkType: hard @@ -7608,13 +7589,6 @@ __metadata: languageName: node linkType: hard -"@types/estree@npm:^1.0.5": - version: 1.0.5 - resolution: "@types/estree@npm:1.0.5" - checksum: b3b0e334288ddb407c7b3357ca67dbee75ee22db242ca7c56fe27db4e1a31989cb8af48a84dd401deb787fe10cc6b2ab1ee82dc4783be87ededbe3d53c79c70d - languageName: node - linkType: hard - "@types/express-serve-static-core@npm:*, @types/express-serve-static-core@npm:^4.17.33": version: 4.17.37 resolution: "@types/express-serve-static-core@npm:4.17.37" @@ -9557,16 +9531,7 @@ __metadata: languageName: node linkType: hard -"acorn@npm:^8.0.0, acorn@npm:^8.10.0, acorn@npm:^8.11.2, acorn@npm:^8.4.1, acorn@npm:^8.6.0, acorn@npm:^8.7.1, acorn@npm:^8.8.2, acorn@npm:^8.9.0": - version: 8.11.2 - resolution: "acorn@npm:8.11.2" - bin: - acorn: bin/acorn - checksum: a3ed76c761b75ec54b1ec3068fb7f113a182e95aea7f322f65098c2958d232e3d211cb6dac35ff9c647024b63714bc528a26d54a925d1fef2c25585b4c8e4017 - languageName: node - linkType: hard - -"acorn@npm:^8.11.3": +"acorn@npm:^8.0.0, acorn@npm:^8.10.0, acorn@npm:^8.11.2, acorn@npm:^8.11.3, acorn@npm:^8.4.1, acorn@npm:^8.6.0, acorn@npm:^8.7.1, acorn@npm:^8.8.2, acorn@npm:^8.9.0": version: 8.11.3 resolution: "acorn@npm:8.11.3" bin: @@ -25016,20 +24981,7 @@ __metadata: languageName: node linkType: hard -"recast@npm:^0.23.1, recast@npm:^0.23.3": - version: 0.23.4 - resolution: "recast@npm:0.23.4" - dependencies: - assert: "npm:^2.0.0" - ast-types: "npm:^0.16.1" - esprima: "npm:~4.0.0" - source-map: "npm:~0.6.1" - tslib: "npm:^2.0.1" - checksum: d719633be8029e28f23b8191d4a525c5dbdac721792ab3cb5e9dfcf1694fb93f3c147b186916195a9c7fa0711f1e4990ba457cdcee02faed3899d4a80da1bd1f - languageName: node - linkType: hard - -"recast@npm:^0.23.5": +"recast@npm:^0.23.1, recast@npm:^0.23.3, recast@npm:^0.23.5": version: 0.23.5 resolution: "recast@npm:0.23.5" dependencies: @@ -28067,14 +28019,7 @@ __metadata: languageName: node linkType: hard -"tiny-invariant@npm:^1.3.1": - version: 1.3.1 - resolution: "tiny-invariant@npm:1.3.1" - checksum: 5b87c1d52847d9452b60d0dcb77011b459044e0361ca8253bfe7b43d6288106e12af926adb709a6fc28900e3864349b91dad9a4ac93c39aa15f360b26c2ff4db - languageName: node - linkType: hard - -"tiny-invariant@npm:^1.3.3": +"tiny-invariant@npm:^1.3.1, tiny-invariant@npm:^1.3.3": version: 1.3.3 resolution: "tiny-invariant@npm:1.3.3" checksum: 65af4a07324b591a059b35269cd696aba21bef2107f29b9f5894d83cc143159a204b299553435b03874ebb5b94d019afa8b8eff241c8a4cfee95872c2e1c1c4a diff --git a/scripts/yarn.lock b/scripts/yarn.lock index c87d27c84be7..6ca86bb51922 100644 --- a/scripts/yarn.lock +++ b/scripts/yarn.lock @@ -14553,14 +14553,7 @@ __metadata: languageName: node linkType: hard -"tiny-invariant@npm:^1.3.1": - version: 1.3.1 - resolution: "tiny-invariant@npm:1.3.1" - checksum: 5b87c1d52847d9452b60d0dcb77011b459044e0361ca8253bfe7b43d6288106e12af926adb709a6fc28900e3864349b91dad9a4ac93c39aa15f360b26c2ff4db - languageName: node - linkType: hard - -"tiny-invariant@npm:^1.3.3": +"tiny-invariant@npm:^1.3.1, tiny-invariant@npm:^1.3.3": version: 1.3.3 resolution: "tiny-invariant@npm:1.3.3" checksum: 65af4a07324b591a059b35269cd696aba21bef2107f29b9f5894d83cc143159a204b299553435b03874ebb5b94d019afa8b8eff241c8a4cfee95872c2e1c1c4a From dbef8b58816db49bf7d22f1b21f52b61dbfb99ee Mon Sep 17 00:00:00 2001 From: Kasper Peulen Date: Wed, 6 Mar 2024 15:45:00 +0100 Subject: [PATCH 058/132] Add explicit actions to CLI header story --- code/frameworks/angular/template/cli/header.stories.ts | 6 ++++++ code/frameworks/ember/template/cli/Button.stories.js | 4 ++-- .../nextjs/template/cli/js/Header.stories.js | 6 ++++++ .../nextjs/template/cli/ts-3-8/Header.stories.ts | 7 +++++++ .../nextjs/template/cli/ts-4-9/Header.stories.ts | 6 ++++++ code/renderers/html/template/cli/js/Header.stories.js | 10 +++++----- .../html/template/cli/ts-3-8/Header.stories.ts | 9 +++++---- .../html/template/cli/ts-4-9/Header.stories.ts | 9 +++++---- code/renderers/preact/template/cli/Header.stories.jsx | 8 ++++---- code/renderers/react/template/cli/js/Header.stories.js | 6 ++++++ .../react/template/cli/ts-3-8/Header.stories.ts | 6 ++++++ .../react/template/cli/ts-4-9/Header.stories.ts | 6 ++++++ code/renderers/vue3/template/cli/js/Header.stories.js | 6 ++++++ .../vue3/template/cli/ts-3-8/Header.stories.ts | 6 ++++++ .../vue3/template/cli/ts-4-9/Header.stories.ts | 6 ++++++ .../web-components/template/cli/js/Button.stories.js | 3 ++- .../web-components/template/cli/js/Header.stories.js | 7 ++++++- .../template/cli/ts-3-8/Button.stories.ts | 3 ++- .../template/cli/ts-3-8/Header.stories.ts | 6 ++++++ .../template/cli/ts-4-9/Button.stories.ts | 3 ++- .../template/cli/ts-4-9/Header.stories.ts | 6 ++++++ 21 files changed, 106 insertions(+), 23 deletions(-) diff --git a/code/frameworks/angular/template/cli/header.stories.ts b/code/frameworks/angular/template/cli/header.stories.ts index 3222518ace44..3f3fb684e855 100644 --- a/code/frameworks/angular/template/cli/header.stories.ts +++ b/code/frameworks/angular/template/cli/header.stories.ts @@ -1,6 +1,7 @@ import type { Meta, StoryObj } from '@storybook/angular'; import { HeaderComponent } from './header.component'; +import { fn } from '@storybook/test'; const meta: Meta = { title: 'Example/Header', @@ -11,6 +12,11 @@ const meta: Meta = { // More on how to position stories at: https://storybook.js.org/docs/configure/story-layout layout: 'fullscreen', }, + args: { + onLogin: fn(), + onLogout: fn(), + onCreateAccount: fn(), + }, }; export default meta; diff --git a/code/frameworks/ember/template/cli/Button.stories.js b/code/frameworks/ember/template/cli/Button.stories.js index 61de1a4f9cc9..c8fffd70feb0 100644 --- a/code/frameworks/ember/template/cli/Button.stories.js +++ b/code/frameworks/ember/template/cli/Button.stories.js @@ -1,6 +1,7 @@ import { hbs } from 'ember-cli-htmlbars'; import { action } from '@storybook/addon-actions'; import { linkTo } from '@storybook/addon-links'; +import { fn } from '@storybook/test'; // More on how to set up stories at: https://storybook.js.org/docs/writing-stories export default { @@ -14,20 +15,19 @@ export default { }, // This component will have an automatically generated Autodocs entry: https://storybook.js.org/docs/ember/writing-docs/autodocs tags: ['autodocs'], + args: { onClick: fn() }, }; // More on writing stories with args: https://storybook.js.org/docs/writing-stories/args export const Text = { args: { label: 'Button', - onClick: action('onClick'), }, }; export const Emoji = { args: { label: '๐Ÿ˜€ ๐Ÿ˜Ž ๐Ÿ‘ ๐Ÿ’ฏ', - onClick: action('onClick'), }, }; diff --git a/code/frameworks/nextjs/template/cli/js/Header.stories.js b/code/frameworks/nextjs/template/cli/js/Header.stories.js index a1d32b3ad65e..982cd970fb5c 100644 --- a/code/frameworks/nextjs/template/cli/js/Header.stories.js +++ b/code/frameworks/nextjs/template/cli/js/Header.stories.js @@ -1,3 +1,4 @@ +import { fn } from '@storybook/test'; import { Header } from './Header'; export default { @@ -9,6 +10,11 @@ export default { // More on how to position stories at: https://storybook.js.org/docs/configure/story-layout layout: 'fullscreen', }, + args: { + onLogin: fn(), + onLogout: fn(), + onCreateAccount: fn(), + }, }; export const LoggedIn = { args: { diff --git a/code/frameworks/nextjs/template/cli/ts-3-8/Header.stories.ts b/code/frameworks/nextjs/template/cli/ts-3-8/Header.stories.ts index 82a109720879..feddeae98faf 100644 --- a/code/frameworks/nextjs/template/cli/ts-3-8/Header.stories.ts +++ b/code/frameworks/nextjs/template/cli/ts-3-8/Header.stories.ts @@ -1,4 +1,6 @@ import type { Meta, StoryObj } from '@storybook/react'; +import { fn } from '@storybook/test'; + import { Header } from './Header'; const meta: Meta = { @@ -10,6 +12,11 @@ const meta: Meta = { // More on how to position stories at: https://storybook.js.org/docs/configure/story-layout layout: 'fullscreen', }, + args: { + onLogin: fn(), + onLogout: fn(), + onCreateAccount: fn(), + }, }; export default meta; diff --git a/code/frameworks/nextjs/template/cli/ts-4-9/Header.stories.ts b/code/frameworks/nextjs/template/cli/ts-4-9/Header.stories.ts index 046982e62673..39d15874f4c1 100644 --- a/code/frameworks/nextjs/template/cli/ts-4-9/Header.stories.ts +++ b/code/frameworks/nextjs/template/cli/ts-4-9/Header.stories.ts @@ -1,4 +1,5 @@ import type { Meta, StoryObj } from '@storybook/react'; +import { fn } from '@storybook/test'; import { Header } from './Header'; const meta = { @@ -10,6 +11,11 @@ const meta = { // More on how to position stories at: https://storybook.js.org/docs/configure/story-layout layout: 'fullscreen', }, + args: { + onLogin: fn(), + onLogout: fn(), + onCreateAccount: fn(), + }, } satisfies Meta; export default meta; diff --git a/code/renderers/html/template/cli/js/Header.stories.js b/code/renderers/html/template/cli/js/Header.stories.js index 44fa3cbbff46..08894335b548 100644 --- a/code/renderers/html/template/cli/js/Header.stories.js +++ b/code/renderers/html/template/cli/js/Header.stories.js @@ -1,3 +1,4 @@ +import { fn } from '@storybook/test'; import { createHeader } from './Header'; export default { @@ -9,11 +10,10 @@ export default { // More on how to position stories at: https://storybook.js.org/docs/configure/story-layout layout: 'fullscreen', }, - // More on argTypes: https://storybook.js.org/docs/api/argtypes - argTypes: { - onLogin: { action: 'onLogin' }, - onLogout: { action: 'onLogout' }, - onCreateAccount: { action: 'onCreateAccount' }, + args: { + onLogin: fn(), + onLogout: fn(), + onCreateAccount: fn(), }, }; diff --git a/code/renderers/html/template/cli/ts-3-8/Header.stories.ts b/code/renderers/html/template/cli/ts-3-8/Header.stories.ts index 0bc5d9ce3aba..08da33ecc719 100644 --- a/code/renderers/html/template/cli/ts-3-8/Header.stories.ts +++ b/code/renderers/html/template/cli/ts-3-8/Header.stories.ts @@ -1,4 +1,5 @@ import type { Meta, StoryObj } from '@storybook/html'; +import { fn } from '@storybook/test'; import type { HeaderProps } from './Header'; import { createHeader } from './Header'; @@ -12,10 +13,10 @@ const meta: Meta = { layout: 'fullscreen', }, // More on argTypes: https://storybook.js.org/docs/api/argtypes - argTypes: { - onLogin: { action: 'onLogin' }, - onLogout: { action: 'onLogout' }, - onCreateAccount: { action: 'onCreateAccount' }, + args: { + onLogin: fn(), + onLogout: fn(), + onCreateAccount: fn(), }, }; diff --git a/code/renderers/html/template/cli/ts-4-9/Header.stories.ts b/code/renderers/html/template/cli/ts-4-9/Header.stories.ts index 7570a625a869..189c6c8abebd 100644 --- a/code/renderers/html/template/cli/ts-4-9/Header.stories.ts +++ b/code/renderers/html/template/cli/ts-4-9/Header.stories.ts @@ -1,4 +1,5 @@ import type { Meta, StoryObj } from '@storybook/html'; +import { fn } from '@storybook/test'; import type { HeaderProps } from './Header'; import { createHeader } from './Header'; @@ -12,10 +13,10 @@ const meta = { layout: 'fullscreen', }, // More on argTypes: https://storybook.js.org/docs/api/argtypes - argTypes: { - onLogin: { action: 'onLogin' }, - onLogout: { action: 'onLogout' }, - onCreateAccount: { action: 'onCreateAccount' }, + args: { + onLogin: fn(), + onLogout: fn(), + onCreateAccount: fn(), }, } satisfies Meta; diff --git a/code/renderers/preact/template/cli/Header.stories.jsx b/code/renderers/preact/template/cli/Header.stories.jsx index 58b353a57db2..072d3136727b 100644 --- a/code/renderers/preact/template/cli/Header.stories.jsx +++ b/code/renderers/preact/template/cli/Header.stories.jsx @@ -9,10 +9,10 @@ export default { // More on how to position stories at: https://storybook.js.org/docs/configure/story-layout layout: 'fullscreen', }, - argTypes: { - onLogin: { action: 'onLogin' }, - onLogout: { action: 'onLogout' }, - onCreateAccount: { action: 'onCreateAccount' }, + args: { + onLogin: fn(), + onLogout: fn(), + onCreateAccount: fn(), }, }; diff --git a/code/renderers/react/template/cli/js/Header.stories.js b/code/renderers/react/template/cli/js/Header.stories.js index 16920e1be754..17323e698c5b 100644 --- a/code/renderers/react/template/cli/js/Header.stories.js +++ b/code/renderers/react/template/cli/js/Header.stories.js @@ -1,4 +1,5 @@ import { Header } from './Header'; +import { fn } from '@storybook/test'; export default { title: 'Example/Header', @@ -9,6 +10,11 @@ export default { // More on how to position stories at: https://storybook.js.org/docs/configure/story-layout layout: 'fullscreen', }, + args: { + onLogin: fn(), + onLogout: fn(), + onCreateAccount: fn(), + }, }; export const LoggedIn = { diff --git a/code/renderers/react/template/cli/ts-3-8/Header.stories.ts b/code/renderers/react/template/cli/ts-3-8/Header.stories.ts index 19e5e2c0f667..901b5639b162 100644 --- a/code/renderers/react/template/cli/ts-3-8/Header.stories.ts +++ b/code/renderers/react/template/cli/ts-3-8/Header.stories.ts @@ -1,4 +1,5 @@ import type { Meta, StoryObj } from '@storybook/react'; +import { fn } from '@storybook/test'; import { Header } from './Header'; @@ -11,6 +12,11 @@ const meta: Meta = { // More on Story layout: https://storybook.js.org/docs/configure/story-layout layout: 'fullscreen', }, + args: { + onLogin: fn(), + onLogout: fn(), + onCreateAccount: fn(), + }, }; export default meta; diff --git a/code/renderers/react/template/cli/ts-4-9/Header.stories.ts b/code/renderers/react/template/cli/ts-4-9/Header.stories.ts index 61cf98aa0c4e..80c71d0f520e 100644 --- a/code/renderers/react/template/cli/ts-4-9/Header.stories.ts +++ b/code/renderers/react/template/cli/ts-4-9/Header.stories.ts @@ -1,4 +1,5 @@ import type { Meta, StoryObj } from '@storybook/react'; +import { fn } from '@storybook/test'; import { Header } from './Header'; @@ -11,6 +12,11 @@ const meta = { // More on how to position stories at: https://storybook.js.org/docs/configure/story-layout layout: 'fullscreen', }, + args: { + onLogin: fn(), + onLogout: fn(), + onCreateAccount: fn(), + }, } satisfies Meta; export default meta; diff --git a/code/renderers/vue3/template/cli/js/Header.stories.js b/code/renderers/vue3/template/cli/js/Header.stories.js index 380492e24b24..6b0d1821f117 100644 --- a/code/renderers/vue3/template/cli/js/Header.stories.js +++ b/code/renderers/vue3/template/cli/js/Header.stories.js @@ -1,3 +1,4 @@ +import { fn } from '@storybook/test'; import MyHeader from './Header.vue'; export default { @@ -24,6 +25,11 @@ export default { // More on how to position stories at: https://storybook.js.org/docs/configure/story-layout layout: 'fullscreen', }, + args: { + onLogin: fn(), + onLogout: fn(), + onCreateAccount: fn(), + }, }; export const LoggedIn = { diff --git a/code/renderers/vue3/template/cli/ts-3-8/Header.stories.ts b/code/renderers/vue3/template/cli/ts-3-8/Header.stories.ts index fd0ba06e9c5d..4982d99d85f3 100644 --- a/code/renderers/vue3/template/cli/ts-3-8/Header.stories.ts +++ b/code/renderers/vue3/template/cli/ts-3-8/Header.stories.ts @@ -1,3 +1,4 @@ +import { fn } from '@storybook/test'; import type { Meta, StoryObj } from '@storybook/vue3'; import MyHeader from './Header.vue'; @@ -21,6 +22,11 @@ const meta: Meta = { layout: 'fullscreen', }, // This component will have an automatically generated docsPage entry: https://storybook.js.org/docs/writing-docs/autodocs + args: { + onLogin: fn(), + onLogout: fn(), + onCreateAccount: fn(), + }, tags: ['autodocs'], }; diff --git a/code/renderers/vue3/template/cli/ts-4-9/Header.stories.ts b/code/renderers/vue3/template/cli/ts-4-9/Header.stories.ts index eb8fc1fcee56..350a5d22a48a 100644 --- a/code/renderers/vue3/template/cli/ts-4-9/Header.stories.ts +++ b/code/renderers/vue3/template/cli/ts-4-9/Header.stories.ts @@ -1,4 +1,5 @@ import type { Meta, StoryObj } from '@storybook/vue3'; +import { fn } from '@storybook/test'; import MyHeader from './Header.vue'; @@ -20,6 +21,11 @@ const meta = { // More on how to position stories at: https://storybook.js.org/docs/configure/story-layout layout: 'fullscreen', }, + args: { + onLogin: fn(), + onLogout: fn(), + onCreateAccount: fn(), + }, // This component will have an automatically generated docsPage entry: https://storybook.js.org/docs/writing-docs/autodocs tags: ['autodocs'], } satisfies Meta; diff --git a/code/renderers/web-components/template/cli/js/Button.stories.js b/code/renderers/web-components/template/cli/js/Button.stories.js index d406b990ff7b..dfb4ad43ee74 100644 --- a/code/renderers/web-components/template/cli/js/Button.stories.js +++ b/code/renderers/web-components/template/cli/js/Button.stories.js @@ -1,3 +1,4 @@ +import { fn } from '@storybook/test'; import { Button } from './Button'; // More on how to set up stories at: https://storybook.js.org/docs/writing-stories @@ -7,12 +8,12 @@ export default { render: (args) => Button(args), argTypes: { backgroundColor: { control: 'color' }, - onClick: { action: 'onClick' }, size: { control: { type: 'select' }, options: ['small', 'medium', 'large'], }, }, + args: { onClick: fn() }, }; // More on writing stories with args: https://storybook.js.org/docs/writing-stories/args diff --git a/code/renderers/web-components/template/cli/js/Header.stories.js b/code/renderers/web-components/template/cli/js/Header.stories.js index d399cb869950..cfb94e39fc0c 100644 --- a/code/renderers/web-components/template/cli/js/Header.stories.js +++ b/code/renderers/web-components/template/cli/js/Header.stories.js @@ -1,3 +1,4 @@ +import { fn } from '@storybook/test'; import { Header } from './Header'; export default { @@ -5,8 +6,12 @@ export default { // This component will have an automatically generated Autodocs entry: https://storybook.js.org/web-components/vue/writing-docs/autodocs tags: ['autodocs'], render: (args) => Header(args), + args: { + onLogin: fn(), + onLogout: fn(), + onCreateAccount: fn(), + }, }; - export const LoggedIn = { args: { user: { diff --git a/code/renderers/web-components/template/cli/ts-3-8/Button.stories.ts b/code/renderers/web-components/template/cli/ts-3-8/Button.stories.ts index 62d561636779..e34857751666 100644 --- a/code/renderers/web-components/template/cli/ts-3-8/Button.stories.ts +++ b/code/renderers/web-components/template/cli/ts-3-8/Button.stories.ts @@ -1,4 +1,5 @@ import type { Meta, StoryObj } from '@storybook/web-components'; +import { fn } from '@storybook/test'; import type { ButtonProps } from './Button'; import { Button } from './Button'; @@ -9,12 +10,12 @@ const meta: Meta = { render: (args) => Button(args), argTypes: { backgroundColor: { control: 'color' }, - onClick: { action: 'onClick' }, size: { control: { type: 'select' }, options: ['small', 'medium', 'large'], }, }, + args: { onClick: fn() }, }; export default meta; diff --git a/code/renderers/web-components/template/cli/ts-3-8/Header.stories.ts b/code/renderers/web-components/template/cli/ts-3-8/Header.stories.ts index aab89ba6a4b3..08b47d7692d8 100644 --- a/code/renderers/web-components/template/cli/ts-3-8/Header.stories.ts +++ b/code/renderers/web-components/template/cli/ts-3-8/Header.stories.ts @@ -1,4 +1,5 @@ import type { Meta, StoryObj } from '@storybook/web-components'; +import { fn } from '@storybook/test'; import type { HeaderProps } from './Header'; import { Header } from './Header'; @@ -7,6 +8,11 @@ const meta: Meta = { // This component will have an automatically generated Autodocs entry: https://storybook.js.org/docs/writing-docs/autodocs tags: ['autodocs'], render: (args: HeaderProps) => Header(args), + args: { + onLogin: fn(), + onLogout: fn(), + onCreateAccount: fn(), + }, }; export default meta; diff --git a/code/renderers/web-components/template/cli/ts-4-9/Button.stories.ts b/code/renderers/web-components/template/cli/ts-4-9/Button.stories.ts index 03516d6c1abf..52f3ae8ebd62 100644 --- a/code/renderers/web-components/template/cli/ts-4-9/Button.stories.ts +++ b/code/renderers/web-components/template/cli/ts-4-9/Button.stories.ts @@ -1,4 +1,5 @@ import type { Meta, StoryObj } from '@storybook/web-components'; +import { fn } from '@storybook/test'; import type { ButtonProps } from './Button'; import { Button } from './Button'; @@ -9,12 +10,12 @@ const meta = { render: (args) => Button(args), argTypes: { backgroundColor: { control: 'color' }, - onClick: { action: 'onClick' }, size: { control: { type: 'select' }, options: ['small', 'medium', 'large'], }, }, + args: { onClick: fn() }, } satisfies Meta; export default meta; diff --git a/code/renderers/web-components/template/cli/ts-4-9/Header.stories.ts b/code/renderers/web-components/template/cli/ts-4-9/Header.stories.ts index 628e199db1f4..be13bf07cde4 100644 --- a/code/renderers/web-components/template/cli/ts-4-9/Header.stories.ts +++ b/code/renderers/web-components/template/cli/ts-4-9/Header.stories.ts @@ -1,4 +1,5 @@ import type { Meta, StoryObj } from '@storybook/web-components'; +import { fn } from '@storybook/test'; import type { HeaderProps } from './Header'; import { Header } from './Header'; @@ -7,6 +8,11 @@ const meta = { // This component will have an automatically generated Autodocs entry: https://storybook.js.org/docs/writing-docs/autodocs tags: ['autodocs'], render: (args: HeaderProps) => Header(args), + args: { + onLogin: fn(), + onLogout: fn(), + onCreateAccount: fn(), + }, } satisfies Meta; export default meta; From 430cf1edd9b0af8c3815142319e6974765480ab5 Mon Sep 17 00:00:00 2001 From: Valentin Palkovic Date: Wed, 6 Mar 2024 15:53:21 +0100 Subject: [PATCH 059/132] Fix theme addon ID --- code/addons/themes/src/constants.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/addons/themes/src/constants.ts b/code/addons/themes/src/constants.ts index a1872de9e88e..677c9499a7b4 100644 --- a/code/addons/themes/src/constants.ts +++ b/code/addons/themes/src/constants.ts @@ -1,5 +1,5 @@ export const PARAM_KEY = 'themes' as const; -export const ADDON_ID = `storybook/${PARAM_KEY}}` as const; +export const ADDON_ID = `storybook/${PARAM_KEY}` as const; export const GLOBAL_KEY = 'theme' as const; export const THEME_SWITCHER_ID = `${ADDON_ID}/theme-switcher` as const; From 6b09614817f8a6166cb18dd7a65ecf08c0fb0f63 Mon Sep 17 00:00:00 2001 From: Valentin Palkovic Date: Wed, 6 Mar 2024 16:07:01 +0100 Subject: [PATCH 060/132] Update MIGRATION.md Co-authored-by: jonniebigodes --- MIGRATION.md | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/MIGRATION.md b/MIGRATION.md index 935788cbd9c9..025766de392f 100644 --- a/MIGRATION.md +++ b/MIGRATION.md @@ -1043,9 +1043,10 @@ Please file an issue if you need these APIs. #### Removals in @storybook/components -The `TooltipLinkList` component accepts a `links` property where, for each link, a `left` property could be passed. The left property is now removed in Storybook 8 and beyond. Use `icon` instead. The side-effect is that the `left` property is now removed from the `Link` component. This has an effect on the `globalTypes` definition in the `preview.js` file, among other places: +The `TooltipLinkList` UI component used to customize the Storybook toolbar has been updated to use the `icon` property instead of the `left` property to position its content. If you've enabled this property in your `globalTypes` configuration, addons, or any other place, you'll need to replace it with an `icon` property to mimic the same behavior. For example: ```diff +// .storybook/preview.js|ts // Replace your-framework with the framework you are using (e.g., react, vue3) import { Preview } from '@storybook/your-framework'; @@ -1076,9 +1077,7 @@ const preview: Preview = { export default preview; ``` - -The icon property only supports a limited set of icons, which are defined here: -https://storybook.js.org/docs/8.0/faq#what-icons-are-available-for-my-toolbar-or-my-addon +To learn more about the available icons and their names, see the [Storybook documentation](https://storybook.js.org/docs/8.0/faq#what-icons-are-available-for-my-toolbar-or-my-addon). #### Removals in @storybook/types From 4e0b97f12d141ab1384512d1c1c3608cfbbfe696 Mon Sep 17 00:00:00 2001 From: Valentin Palkovic Date: Wed, 6 Mar 2024 16:11:44 +0100 Subject: [PATCH 061/132] Update theme-switcher to initialize the addon appropriate after Storybook startup Co-authored-by: Norbert de Langen --- code/addons/themes/src/theme-switcher.tsx | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/code/addons/themes/src/theme-switcher.tsx b/code/addons/themes/src/theme-switcher.tsx index ef27f0d25769..0a0ac5f34bec 100644 --- a/code/addons/themes/src/theme-switcher.tsx +++ b/code/addons/themes/src/theme-switcher.tsx @@ -1,5 +1,11 @@ import React, { Fragment, useMemo } from 'react'; -import { useAddonState, useChannel, useGlobals, useParameter } from '@storybook/manager-api'; +import { + useAddonState, + useChannel, + useGlobals, + useParameter, + addons, +} from '@storybook/manager-api'; import { styled } from '@storybook/theming'; import { IconButton, WithTooltip, TooltipLinkList } from '@storybook/components'; @@ -20,16 +26,23 @@ const IconButtonLabel = styled.div(({ theme }) => ({ const hasMultipleThemes = (themesList: ThemeAddonState['themesList']) => themesList.length > 1; const hasTwoThemes = (themesList: ThemeAddonState['themesList']) => themesList.length === 2; -export const ThemeSwitcher = () => { +export const ThemeSwitcher = React.memo(function ThemeSwitcher() { const { themeOverride } = useParameter( PARAM_KEY, DEFAULT_THEME_PARAMETERS ) as ThemeParameters; const [{ theme: selected }, updateGlobals] = useGlobals(); + const channel = addons.getChannel(); + const fromLast = channel.last(THEMING_EVENTS.REGISTER_THEMES); + const initializeThemeState = Object.assign({}, DEFAULT_ADDON_STATE, { + themesList: fromLast?.[0]?.themes || [], + themeDefault: fromLast?.[0]?.defaultTheme || '', + }); + const [{ themesList, themeDefault }, updateState] = useAddonState( THEME_SWITCHER_ID, - DEFAULT_ADDON_STATE + initializeThemeState ); useChannel({ @@ -103,4 +116,4 @@ export const ThemeSwitcher = () => { } return null; -}; +}); From f1bdb704b2d325b6354fff8c7fae2da49bda192e Mon Sep 17 00:00:00 2001 From: Kasper Peulen Date: Wed, 6 Mar 2024 16:45:27 +0100 Subject: [PATCH 062/132] what's new modal changes --- code/lib/manager-api/src/modules/whatsnew.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/code/lib/manager-api/src/modules/whatsnew.ts b/code/lib/manager-api/src/modules/whatsnew.ts index eeeb9558a59f..8f465325d503 100644 --- a/code/lib/manager-api/src/modules/whatsnew.ts +++ b/code/lib/manager-api/src/modules/whatsnew.ts @@ -92,10 +92,10 @@ export const init: ModuleFn = ({ fullAPI, store, provider }) => { id: WHATS_NEW_NOTIFICATION_ID, link: '/settings/whats-new', content: { - headline: whatsNewData.excerpt, - subHeadline: "Click to learn what's new in Storybook", + headline: whatsNewData.title, + subHeadline: "Learn what's new in Storybook", }, - icon: { name: 'hearthollow' }, + icon: { name: 'storybook' }, onClear({ dismissed }: any) { if (dismissed) { setWhatsNewCache({ lastDismissedPost: whatsNewData.url }); From b3fa8c56daa4d57e62b34a01b20f993ae3fc74a2 Mon Sep 17 00:00:00 2001 From: Norbert de Langen Date: Wed, 6 Mar 2024 18:10:41 +0100 Subject: [PATCH 063/132] load refs in sequence, await writing to state --- code/lib/manager-api/src/modules/refs.ts | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/code/lib/manager-api/src/modules/refs.ts b/code/lib/manager-api/src/modules/refs.ts index bc4b94755a53..34e1574b3e2a 100644 --- a/code/lib/manager-api/src/modules/refs.ts +++ b/code/lib/manager-api/src/modules/refs.ts @@ -276,7 +276,7 @@ export const init: ModuleFn = ( return refs; }, - setRef: (id, { storyIndex, setStoriesData, ...rest }, ready = false) => { + setRef: async (id, { storyIndex, setStoriesData, ...rest }, ready = false) => { if (singleStory) { return; } @@ -307,10 +307,10 @@ export const init: ModuleFn = ( index = addRefIds(index, ref); } - api.updateRef(id, { ...ref, ...rest, index, internal_index }); + await api.updateRef(id, { ...ref, ...rest, index, internal_index }); }, - updateRef: (id, data) => { + updateRef: async (id, data) => { const { [id]: ref, ...updated } = api.getRefs(); updated[id] = { ...ref, ...data }; @@ -320,7 +320,7 @@ export const init: ModuleFn = ( return obj; }, {}); - store.setState({ + await store.setState({ refs: ordered, }); }, @@ -331,9 +331,10 @@ export const init: ModuleFn = ( const initialState: SubState['refs'] = refs; if (runCheck) { - Object.entries(refs).forEach(([id, ref]) => { - api.checkRef({ ...ref!, stories: {} } as API_SetRefData); - }); + Object.entries(refs).reduce(async (accc, [id, ref]) => { + await accc; + await api.checkRef({ ...ref!, stories: {} } as API_SetRefData); + }, Promise.resolve()); } return { From b045da1682eebf623f822e044df1069fd70b4298 Mon Sep 17 00:00:00 2001 From: Norbert de Langen Date: Wed, 6 Mar 2024 19:56:18 +0100 Subject: [PATCH 064/132] rename & fix test --- code/lib/manager-api/src/modules/refs.ts | 4 ++-- code/lib/manager-api/src/tests/refs.test.ts | 6 ++++++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/code/lib/manager-api/src/modules/refs.ts b/code/lib/manager-api/src/modules/refs.ts index 34e1574b3e2a..f783f7db6496 100644 --- a/code/lib/manager-api/src/modules/refs.ts +++ b/code/lib/manager-api/src/modules/refs.ts @@ -331,8 +331,8 @@ export const init: ModuleFn = ( const initialState: SubState['refs'] = refs; if (runCheck) { - Object.entries(refs).reduce(async (accc, [id, ref]) => { - await accc; + Object.entries(refs).reduce(async (acc, [id, ref]) => { + await acc; await api.checkRef({ ...ref!, stories: {} } as API_SetRefData); }, Promise.resolve()); } diff --git a/code/lib/manager-api/src/tests/refs.test.ts b/code/lib/manager-api/src/tests/refs.test.ts index 791325c27337..af16eee0bbfa 100644 --- a/code/lib/manager-api/src/tests/refs.test.ts +++ b/code/lib/manager-api/src/tests/refs.test.ts @@ -171,6 +171,9 @@ describe('Refs API', () => { // given initRefs({ provider, store } as any); + // the `runCheck` is async, so we need to wait for it to finish + await Promise.resolve(); + expect(fetchMock.mock.calls).toMatchInlineSnapshot(` [ [ @@ -207,6 +210,9 @@ describe('Refs API', () => { }; initRefs({ provider, store } as any); + // the `runCheck` is async, so we need to wait for it to finish + await Promise.resolve(); + expect(fetchMock.mock.calls).toMatchInlineSnapshot(` [ [ From 414193b9365fe7a9f6735e50cc6b7beb8365ef04 Mon Sep 17 00:00:00 2001 From: Norbert de Langen Date: Wed, 6 Mar 2024 21:12:26 +0100 Subject: [PATCH 065/132] improve understandability of the test --- code/lib/manager-api/src/tests/refs.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/lib/manager-api/src/tests/refs.test.ts b/code/lib/manager-api/src/tests/refs.test.ts index af16eee0bbfa..950b5e3e7a63 100644 --- a/code/lib/manager-api/src/tests/refs.test.ts +++ b/code/lib/manager-api/src/tests/refs.test.ts @@ -172,7 +172,7 @@ describe('Refs API', () => { initRefs({ provider, store } as any); // the `runCheck` is async, so we need to wait for it to finish - await Promise.resolve(); + await vi.waitFor(() => fetchMock.mock.calls.length > 0); expect(fetchMock.mock.calls).toMatchInlineSnapshot(` [ @@ -211,7 +211,7 @@ describe('Refs API', () => { initRefs({ provider, store } as any); // the `runCheck` is async, so we need to wait for it to finish - await Promise.resolve(); + await vi.waitFor(() => fetchMock.mock.calls.length > 0); expect(fetchMock.mock.calls).toMatchInlineSnapshot(` [ From 52babf0e0b50d94e3d236a95897461feeef8865c Mon Sep 17 00:00:00 2001 From: Norbert de Langen Date: Wed, 6 Mar 2024 21:19:04 +0100 Subject: [PATCH 066/132] fix linting --- code/lib/manager-api/src/tests/url.test.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/code/lib/manager-api/src/tests/url.test.js b/code/lib/manager-api/src/tests/url.test.js index 3374505870cb..817cb118ff41 100644 --- a/code/lib/manager-api/src/tests/url.test.js +++ b/code/lib/manager-api/src/tests/url.test.js @@ -14,7 +14,7 @@ describe('initial state', () => { describe('config query parameters', () => { it('handles full parameter', () => { const navigate = vi.fn(); - const location = { search: new URLSearchParams(({ full: '1' })).toString() }; + const location = { search: new URLSearchParams({ full: '1' }).toString() }; const { state: { layout }, @@ -29,7 +29,7 @@ describe('initial state', () => { it('handles nav parameter', () => { const navigate = vi.fn(); - const location = { search: new URLSearchParams(({ nav: '0' })).toString() }; + const location = { search: new URLSearchParams({ nav: '0' }).toString() }; const { state: { layout }, @@ -40,7 +40,7 @@ describe('initial state', () => { it('handles shortcuts parameter', () => { const navigate = vi.fn(); - const location = { search: new URLSearchParams(({ shortcuts: '0' })).toString() }; + const location = { search: new URLSearchParams({ shortcuts: '0' }).toString() }; const { state: { ui }, @@ -51,7 +51,7 @@ describe('initial state', () => { it('handles panel parameter, bottom', () => { const navigate = vi.fn(); - const location = { search: new URLSearchParams(({ panel: 'bottom' })).toString() }; + const location = { search: new URLSearchParams({ panel: 'bottom' }).toString() }; const { state: { layout }, @@ -62,7 +62,7 @@ describe('initial state', () => { it('handles panel parameter, right', () => { const navigate = vi.fn(); - const location = { search: new URLSearchParams(({ panel: 'right' })).toString() }; + const location = { search: new URLSearchParams({ panel: 'right' }).toString() }; const { state: { layout }, @@ -73,7 +73,7 @@ describe('initial state', () => { it('handles panel parameter, 0', () => { const navigate = vi.fn(); - const location = { search: new URLSearchParams(({ panel: '0' })).toString() }; + const location = { search: new URLSearchParams({ panel: '0' }).toString() }; const { state: { layout }, From e467a0e6000e07f1611b310cdc52efddc04d48bd Mon Sep 17 00:00:00 2001 From: Norbert de Langen Date: Wed, 6 Mar 2024 21:22:28 +0100 Subject: [PATCH 067/132] remove unused dependency --- code/lib/manager-api/package.json | 1 - code/yarn.lock | 1 - 2 files changed, 2 deletions(-) diff --git a/code/lib/manager-api/package.json b/code/lib/manager-api/package.json index 6ce5d7c94478..285799d6434e 100644 --- a/code/lib/manager-api/package.json +++ b/code/lib/manager-api/package.json @@ -65,7 +65,6 @@ "@types/qs": "^6", "@types/semver": "^7.3.4", "flush-promises": "^1.0.2", - "qs": "^6.10.0", "react": "^18.2.0", "react-dom": "^18.2.0", "semver": "^7.3.7", diff --git a/code/yarn.lock b/code/yarn.lock index 6c439a2c9c5e..2162ad549315 100644 --- a/code/yarn.lock +++ b/code/yarn.lock @@ -6108,7 +6108,6 @@ __metadata: flush-promises: "npm:^1.0.2" lodash: "npm:^4.17.21" memoizerific: "npm:^1.11.3" - qs: "npm:^6.10.0" react: "npm:^18.2.0" react-dom: "npm:^18.2.0" semver: "npm:^7.3.7" From e76e062988e8599f1fe65ad21ab6063ac473eb22 Mon Sep 17 00:00:00 2001 From: Kyle Gach Date: Thu, 29 Feb 2024 16:44:23 -0700 Subject: [PATCH 068/132] Add `angular` framework doc --- code/frameworks/angular/README.md | 323 +------------ docs/get-started/angular.md | 440 ++++++++++++++++++ .../angular/angular-add-framework.js.mdx | 7 + .../angular/angular-add-framework.ts.mdx | 11 + .../angular/angular-install.npm.js.mdx | 3 + .../angular/angular-install.pnpm.js.mdx | 3 + .../angular/angular-install.yarn.js.mdx | 3 + docs/toc.js | 5 + 8 files changed, 473 insertions(+), 322 deletions(-) create mode 100644 docs/get-started/angular.md create mode 100644 docs/snippets/angular/angular-add-framework.js.mdx create mode 100644 docs/snippets/angular/angular-add-framework.ts.mdx create mode 100644 docs/snippets/angular/angular-install.npm.js.mdx create mode 100644 docs/snippets/angular/angular-install.pnpm.js.mdx create mode 100644 docs/snippets/angular/angular-install.yarn.js.mdx diff --git a/code/frameworks/angular/README.md b/code/frameworks/angular/README.md index d97e1ab93f2a..4bfadb7f16f4 100644 --- a/code/frameworks/angular/README.md +++ b/code/frameworks/angular/README.md @@ -1,324 +1,3 @@ # Storybook for Angular -- [Storybook for Angular](#storybook-for-angular) - - [Getting Started](#getting-started) - - [Setup Storybook for your Angular projects](#setup-storybook-for-your-angular-projects) - - [Run Storybook](#run-storybook) - - [Setup Compodoc](#setup-compodoc) - - [Automatic setup](#automatic-setup) - - [Manual setup](#manual-setup) - - [moduleMetadata decorator](#modulemetadata-decorator) - - [applicationConfig decorator](#applicationconfig-decorator) - - [FAQ](#faq) - - [How do I migrate to an Angular Storybook builder?](#how-do-i-migrate-to-an-angular-storybook-builder) - - [Do you have only one Angular project in your workspace?](#do-you-have-only-one-angular-project-in-your-workspace) - - [Adjust your `package.json`](#adjust-your-packagejson) - - [I have multiple projects in my Angular workspace](#i-have-multiple-projects-in-my-angular-workspace) - -Storybook for Angular is a UI development environment for your Angular 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-angular-app -npx storybook@latest init -``` - -## Setup Storybook for your Angular projects - -Storybook supports Angular multi-project workspace. You can setup Storybook for each project in the workspace. When running `npx storybook@latest init` you will be asked for which project Storybook should be set up. Essentially, during initialization, the `.storybook` folder will be created and the `angular.json` will be edited to add the Storybook configuration for the selected project. The configuration looks approximately like this: - -```json -// angular.json -{ - ... - "projects": { - ... - "your-project": { - ... - "architect": { - ... - "storybook": { - "builder": "@storybook/angular:start-storybook", - "options": { - // the path to the storybook config directory - "configDir": ".storybook", - // the build target of your project - "browserTarget": "your-project:build", - // the port you want to start Storybook on - "port": 6006 - // further options are available and can be found in - // https://github.com/storybookjs/storybook/tree/next/code/frameworks/angular/src/builders/start-storybook/schema.json - } - }, - "build-storybook": { - "builder": "@storybook/angular:build-storybook", - "options": { - "configDir": ".storybook", - "browserTarget": "your-project:build", - "outputDir": "dist/storybook/your-project" - // further options are available and can be found in - // https://github.com/storybookjs/storybook/tree/next/code/frameworks/angular/src/builders/build-storybook/schema.json - } - } - } - } - } -} -``` - -## Run Storybook - -To run Storybook for a particular project, please run: - -```sh -ng run :storybook -``` - -To build Storybook, run: - -```sh -ng run :build-storybook -``` - -You will find the output in `dist/storybook/your-project`. - -For more information visit: [storybook.js.org](https://storybook.js.org) - -## Setup Compodoc - -You can include JSDoc comments above components, directives, and other parts of your Angular code to include documentation for those elements. Compodoc uses these comments to generate documentation for your application. In Storybook, it is useful to add explanatory comments above @Inputs and @Outputs, since these are the main elements that Storybook displays in its user interface. The @Inputs and @Outputs are the elements that you can interact with in Storybook, such as controls. - -### Automatic setup - -When installing Storybook via `sb init`, you will be given the option to set up Compodoc automatically. - -### Manual setup - -If you have already installed Storybook, you can set up Compodoc manually. - -Install the following dependencies: - -```sh -npm i -D @compodoc/compodoc -``` - -Add the following option to your to the Storybook Builder: - -```json -{ - ... - "projects": { - ... - "your-project": { - ... - "architect": { - ... - "storybook": { - "builder": "@storybook/angular:start-storybook", - "options": { - ... - "compodoc": true, - "compodocArgs": [ - "-e", - "json", - "-d", - // Where to store the generated documentation. It's usually the root of your Angular project. It's not necessarily the root of your Angular Workspace! - "." - ], - } - }, - "build-storybook": { - "builder": "@storybook/angular:build-storybook", - "options": { - ... - "compodoc": true, - "compodocArgs": [ - "-e", - "json", - "-d", - "." - ], - } - } - } - } - } -} -``` - -Go to your `.storybook/preview.js` and add the following: - -```js -import { setCompodocJson } from '@storybook/addon-docs/angular'; -import docJson from '../documentation.json'; -setCompodocJson(docJson); - -const preview: Preview = { - ... -}; - -export default preview; -``` - -## moduleMetadata decorator - -If your component has dependencies on other Angular directives and modules, these can be supplied using the moduleMetadata decorator either for all stories or for individual stories. - -```js -import { StoryFn, Meta, moduleMetadata } from '@storybook/angular'; -import { SomeComponent } from './some.component'; - -export default { - component: SomeComponent, - decorators: [ - // Apply metadata to all stories - moduleMetadata({ - // import necessary ngModules or standalone components - imports: [...], - // declare components that are used in the template - declarations: [...], - // List of providers that should be available to the root component and all its children. - providers: [...], - }), - ], -} as Meta; - -const Template = (): StoryFn => (args) => ({ - props: args, -}); - -export const Base = Template(); - -export const WithCustomProvider = Template(); -WithCustomProvider.decorators = [ - // Apply metadata to a specific story - moduleMetadata({ - imports: [...], - declarations: [...], - providers: [...] - }), -]; -``` - -## applicationConfig decorator - -If your component relies on application-wide providers, like the ones defined by BrowserAnimationsModule or any other modules which use the forRoot pattern to provide a ModuleWithProviders, you can use the applicationConfig decorator on the meta default export to provide them to the [bootstrapApplication function](https://angular.io/guide/standalone-components#configuring-dependency-injection), which we use to bootstrap the component in Storybook. - -```js - -import { StoryObj, Meta, applicationConfig } from '@storybook/angular'; -import { BrowserAnimationsModule, provideAnimations } from '@angular/platform-browser/animations'; -import { importProvidersFrom } from '@angular/core'; -import { ChipsModule } from './angular-src/chips.module'; - -const meta: Meta = { - component: ChipsGroupComponent, - decorators: [ - // Apply application config to all stories - applicationConfig({ - // List of providers and environment providers that should be available to the root component and all its children. - providers: [ - ... - // Import application-wide providers from a module - importProvidersFrom(BrowserAnimationsModule) - // Or use provide-style functions if available instead, e.g. - provideAnimations() - ], - }), - ], -}; - -export default meta; - -type Story = StoryObj; - -export const WithCustomApplicationProvider: Story = { - render: () => ({ - // Apply application config to a specific story - applicationConfig: { - // The providers will be merged with the ones defined in the applicationConfig decorators providers array of the global meta object - providers: [...] - } - }) -} -``` - -## FAQ - -### How do I migrate to an Angular Storybook builder? - -The Storybook [Angular builder](https://angular.io/guide/glossary#builder) is a new way to run Storybook in an Angular workspace. It is a drop-in replacement for running `storybook dev` and `storybook build` directly. - -You can run `npx storybook@next automigrate` to try let Storybook detect and automatically fix your configuration. Otherwise, you can follow the next steps to manually adjust your configuration. - -#### Do you have only one Angular project in your workspace? - -In this case go to your `angular.json` and add `storybook` and `build-storybook` entries in `architect` section of your project like shown above. - -##### Adjust your `package.json` - -Go to your `package.json` and adjust your script section. Usually, it will look like this: - -```json -{ - "scripts": { - "storybook": "start-storybook -p 6006", // or `storybook dev -p 6006` - "build-storybook": "build-storybook" // or `storybook build` - } -} -``` - -Now, you can run Storybook with `ng run :storybook` and build it with `ng run :build-storybook`. Adjust the scripts in your `package.json` accordingly. - -```json -{ - "scripts": { - "storybook": "ng run :storybook", // or `storybook dev -p 6006` - "build-storybook": "ng run :build-storybook" // or `storybook build` - } -} -``` - -Also remove the compodoc part in your script section if you have set it up previously. -It is now built-in in `@storybook/angular` and you don't have to call it explicitly: - -```json -{ - "scripts": { - "docs:json": "compodoc -p tsconfig.json -e json -d ./documentation", - "storybook": "npm run docs:json && start-storybook -p 6006", - "build-storybook": "npm run docs:json && build-storybook" - } -} -``` - -Change it to: - -```json -{ - "scripts": { - "storybook": "ng run :storybook", - "build-storybook": "ng run :build-storybook" - } -} -``` - -#### I have multiple projects in my Angular workspace - -In this case you have to adjust your `angular.json` and `package.json` as described above for each project in which you want to use Storybook. Please note, that each project should have a dedicated `.storybook` folder, which should be placed in the root of the project. - -You can run `npx sb init` sequentially for each project to setup Storybook for each of them to automatically create the `.storybook` folder and create the necessary configuration in your `angular.json`. - -You can then use [Storybook composition](https://storybook.js.org/docs/angular/sharing/storybook-composition) to composite multiple Storybooks into one. - ---- - -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/angular/sharing/publish-storybook) of your Storybook and deploy it anywhere you want. +See [documentation](https://storybook.js.org/docs/8.0/get-started/angular?renderer=angular) for installation instructions, usage examples, APIs, and more. diff --git a/docs/get-started/angular.md b/docs/get-started/angular.md new file mode 100644 index 000000000000..0ba81ea5c1e9 --- /dev/null +++ b/docs/get-started/angular.md @@ -0,0 +1,440 @@ +--- +title: Storybook for Angular +--- + +export const SUPPORTED_RENDERER = 'angular'; + +Storybook for Angular is a [framework](../contribute/framework.md) that makes it easy to develop and test UI components in isolation for [Angular](https://angular.io/) applications. It includes: + +- ๐Ÿงฑ Uses Angular builders +- ๐ŸŽ›๏ธ Compodoc integration +- ๐Ÿ’ซ and more! + + + + + +Storybook for Angular is only supported in [Angular](?renderer=angular) projects. + + + + + + + + + +## Requirements + +- Angular โ‰ฅ 14.1.0 < 18.0.0 +- Webpack โ‰ฅ 5.0 +- Storybook โ‰ฅ 7.0 + +## Getting started + +### In a project without Storybook + +Follow the prompts after running this command in your Angular project's root directory: + + + + + + + +[More on getting started with Storybook.](./install.md) + +### In a project with Storybook + +This framework is designed to work with Storybook 7+. If youโ€™re not already using v7, upgrade with this command: + + + + + + + +#### Automatic migration + +When running the `upgrade` command above, you should get a prompt asking you to migrate to `@storybook/angular`, which should handle everything for you. In case that auto-migration does not work for your project, refer to the manual migration below. + +#### Manual migration + +First, install the framework: + + + + + + + +Then, update your `.storybook/main.js|ts` to change the framework property: + + + + + + + +Finally, update your `angular.json` to include the Storybook builder: + +```jsonc +// angular.json +{ + ... + "projects": { + ... + "your-project": { + ... + "architect": { + ... + "storybook": { + "builder": "@storybook/angular:start-storybook", + "options": { + // The path to the storybook config directory + "configDir": ".storybook", + // The build target of your project + "browserTarget": "your-project:build", + // The port you want to start Storybook on + "port": 6006 + // More options available, documented here: + // https://github.com/storybookjs/storybook/tree/next/code/frameworks/angular/src/builders/start-storybook/schema.json + } + }, + "build-storybook": { + "builder": "@storybook/angular:build-storybook", + "options": { + "configDir": ".storybook", + "browserTarget": "your-project:build", + "outputDir": "dist/storybook/your-project" + // More options available, documented here: + // https://github.com/storybookjs/storybook/tree/next/code/frameworks/angular/src/builders/build-storybook/schema.json + } + } + } + } + } +} +``` + +## Run Storybook + +To run Storybook for a particular project, please run: + +```sh +ng run :storybook +``` + +To build Storybook, run: + +```sh +ng run :build-storybook +``` + +You will find the output in the configured `outputDir` (default is `dist/storybook/`). + +## Setup Compodoc + +You can include JSDoc comments above components, directives, and other parts of your Angular code to include documentation for those elements. Compodoc uses these comments to [generate documentation](../writing-docs/autodocs.md) for your application. In Storybook, it is useful to add explanatory comments above `@Inputs` and `@Outputs`, since these are the main elements that Storybook displays in its user interface. The `@Inputs` and `@Outputs` are the elements that you can interact with in Storybook, such as [controls](../essentials/controls.md). + +### Automatic setup + +When installing Storybook via `npx storybook@latest init`, you will be given the option to set up Compodoc automatically. + +### Manual setup + +If you have already installed Storybook, you can set up Compodoc manually. + +Install the following dependencies: + +```sh +npm install --save-dev @compodoc/compodoc +``` + +Add the following option to your Storybook Builder: + +```jsonc +// angular.json +{ + ... + "projects": { + ... + "your-project": { + ... + "architect": { + ... + "storybook": { + "builder": "@storybook/angular:start-storybook", + "options": { + ... + // ๐Ÿ‘‡ Add these + "compodoc": true, + "compodocArgs": [ + "-e", + "json", + "-d", + // Where to store the generated documentation. It's usually the root of your Angular project. It's not necessarily the root of your Angular Workspace! + "." + ], + } + }, + "build-storybook": { + "builder": "@storybook/angular:build-storybook", + "options": { + ... + // ๐Ÿ‘‡ Add these + "compodoc": true, + "compodocArgs": [ + "-e", + "json", + "-d", + "." + ], + } + } + } + } + } +} +``` + +Go to your `.storybook/preview.js` and add the following: + +```js +// .storybook/preview.js +// ๐Ÿ‘‡ Add these +import { setCompodocJson } from '@storybook/addon-docs/angular'; +import docJson from '../documentation.json'; +setCompodocJson(docJson); + +// ... rest of file +``` + +## `applicationConfig` decorator + +If your component relies on application-wide providers, like the ones defined by BrowserAnimationsModule or any other modules which use the forRoot pattern to provide a ModuleWithProviders, you can apply the `applicationConfig` [decorator](../writing-stories/decorators.md) to all stories for that component. This will provide them to the [bootstrapApplication function](https://angular.io/guide/standalone-components#configuring-dependency-injection), which is used to bootstrap the component in Storybook. + +```ts +// ChipsModule.stories.ts +import { Meta, applicationConfig, StoryObj } from '@storybook/angular'; +import { BrowserAnimationsModule, provideAnimations } from '@angular/platform-browser/animations'; +import { importProvidersFrom } from '@angular/core'; + +import { ChipsModule } from './angular-src/chips.module'; + +const meta: Meta = { + component: ChipsModule, + decorators: [ + // Apply application config to all stories + applicationConfig({ + // List of providers and environment providers that should be available to the root component and all its children. + providers: [ + ... + // Import application-wide providers from a module + importProvidersFrom(BrowserAnimationsModule) + // Or use provide-style functions if available instead, e.g. + provideAnimations() + ], + }), + ], +}; + +export default meta; + +type Story = StoryObj; + +export const WithCustomApplicationProvider: Story = { + render: () => ({ + // Apply application config to a specific story + applicationConfig: { + // The providers will be merged with the ones defined in the applicationConfig decorators providers array of the global meta object + providers: [...], + } + }) +} +``` + +## `moduleMetadata` decorator + +If your component has dependencies on other Angular directives and modules, these can be supplied using the `moduleMetadata` [decorator](../writing-stories/decorators.md) either for all stories of a component or for individual stories. + +```ts +// YourComponent.stories.ts +import { Meta, moduleMetadata, StoryObj } from '@storybook/angular'; + +import { YourComponent } from './your.component'; + +const meta: Meta = { + component: YourComponent, + decorators: [ + // Apply metadata to all stories + moduleMetadata({ + // import necessary ngModules or standalone components + imports: [...], + // declare components that are used in the template + declarations: [...], + // List of providers that should be available to the root component and all its children. + providers: [...], + }), + ], +}; +export default meta; + +type Story = StoryObj; + +export const Base: Story = {}; + +export const WithCustomProvider: Story = { + decorators: [ + // Apply metadata to a specific story + moduleMetadata({ + imports: [...], + declarations: [...], + providers: [...], + }), + ], +}; +``` + +## FAQ + +### How do I migrate to an Angular Storybook builder? + +The Storybook [Angular builder](https://angular.io/guide/glossary#builder) is a way to run Storybook in an Angular workspace. It is a drop-in replacement for running `storybook dev` and `storybook build` directly. + +You can run `npx storybook@next automigrate` to try let Storybook detect and automatically fix your configuration. Otherwise, you can follow the next steps to manually adjust your configuration. + +#### Do you have only one Angular project in your workspace? + +First, go to your `angular.json` and add `storybook` and `build-storybook` entries in `architect` section of your project like shown above. + +Second, adjust your `package.json` script section. Usually, it will look like this: + +```jsonc +{ + "scripts": { + "storybook": "start-storybook -p 6006", // or `storybook dev -p 6006` + "build-storybook": "build-storybook" // or `storybook build` + } +} +``` + +Now, you can run Storybook with `ng run :storybook` and build it with `ng run :build-storybook`. Adjust the scripts in your `package.json` accordingly. + +```json +{ + "scripts": { + "storybook": "ng run :storybook", + "build-storybook": "ng run :build-storybook" + } +} +``` + +Also compodoc is now built-in in `@storybook/angular` and you don't have to call it explicitly. If were running compodoc in your `package.json` scripts like this: + +```json +{ + "scripts": { + "docs:json": "compodoc -p tsconfig.json -e json -d ./documentation", + "storybook": "npm run docs:json && start-storybook -p 6006", + "build-storybook": "npm run docs:json && build-storybook" + } +} +``` + +Change it to: + +```json +{ + "scripts": { + "storybook": "ng run :storybook", + "build-storybook": "ng run :build-storybook" + } +} +``` + +#### I have multiple projects in my Angular workspace + +In this case you have to adjust your `angular.json` and `package.json` as described above for each project in which you want to use Storybook. Please note, that each project should have a dedicated `.storybook` folder, which should be placed in the root of the project. + +You can run `npx storybook@latest init` sequentially for each project to setup Storybook for each of them to automatically create the `.storybook` folder and create the necessary configuration in your `angular.json`. + +You can then use [Storybook composition](https://storybook.js.org/docs/angular/sharing/storybook-composition) to composite multiple Storybooks into one. + +### How do I configure Angular's builder for Storybook?v + +These are the supported options for the Angular builder: + +| Configuration element | Description | +| ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| `"browserTarget"` | Build target to be served using the following format.
`"example-project:builder:config"` | +| `"tsConfig"` | Location of the TypeScript configuration file, relative to the current workspace.
`"tsConfig": "./tsconfig.json"`. | +| `"port"` | Port used by Storybook.
`"port": 6006` | +| `"host"` | Set up a custom host for Storybook.
`"host": "http://my-custom-host"` | +| `"configDir"` | Storybook configuration directory location.
`"configDir": ".storybook"` | +| `"https"` | Starts Storybook with HTTPS enabled.
`"https": true`
Requires custom certificate information. | +| `"sslCa"` | Provides an SSL certificate authority.
`"sslCa": "your-custom-certificate-authority"`
Optional usage with `"https"` | +| `"sslCert"` | Provides an SSL certificate.
`"sslCert": "your-custom-certificate"`
Required for `https` | +| `"sslKey"` | Provides an SSL key to serve Storybook.
`"sslKey": "your-ssl-key"` | +| `"smokeTest"` | Exit Storybook after successful start.
`"smokeTest": true` | +| `"ci"` | Starts Storybook in CI mode (skips interactive prompts and will not open browser window).
`"ci": true` | +| `"quiet"` | Filters Storybook verbose build output.
`"quiet": true` | +| `"docs"` | Starts Storybook in [documentation mode](../writing-docs/build-documentation.md#preview-storybooks-documentation).
`"docs": true` | +| `"styles"` | Provide the location of the [application's styles](../configure/styling-and-css.md#importing-css-files) to be used with Storybook.
`"styles": ["src/styles.css", "src/styles.scss"]`
| +| `"stylePreprocessorOptions"` | Provides further customization for style preprocessors resolved to the workspace root.
`"stylePreprocessorOptions": { "includePaths": ["src/styles"] }` | + +## API + +### Options + +You can pass an options object for additional configuration if needed: + +```js +// .storybook/main.js +import * as path from 'path'; + +export default { + // ... + framework: { + name: '@storybook/angular', + options: { + // ... + }, + }, +}; +``` + +The available options are: + +#### `builder` + +Type: `Record` + +Configure options for the [framework's builder](../api/main-config-framework.md#optionsbuilder). For Angular, , available options can be found in the [Webpack builder docs](../builders/webpack.md). + + + +
diff --git a/docs/snippets/angular/angular-add-framework.js.mdx b/docs/snippets/angular/angular-add-framework.js.mdx new file mode 100644 index 000000000000..00e5c2474ab6 --- /dev/null +++ b/docs/snippets/angular/angular-add-framework.js.mdx @@ -0,0 +1,7 @@ +```js +// .storybook/main.js +export default { + // ... + framework: '@storybook/angular', // ๐Ÿ‘ˆ Add this +}; +``` diff --git a/docs/snippets/angular/angular-add-framework.ts.mdx b/docs/snippets/angular/angular-add-framework.ts.mdx new file mode 100644 index 000000000000..cdc3c6ccd1e3 --- /dev/null +++ b/docs/snippets/angular/angular-add-framework.ts.mdx @@ -0,0 +1,11 @@ +```ts +// .storybook/main.ts +import { StorybookConfig } from '@storybook/angular'; + +const config: StorybookConfig = { + // ... + framework: '@storybook/angular', // ๐Ÿ‘ˆ Add this +}; + +export default config; +``` diff --git a/docs/snippets/angular/angular-install.npm.js.mdx b/docs/snippets/angular/angular-install.npm.js.mdx new file mode 100644 index 000000000000..c8728d58c565 --- /dev/null +++ b/docs/snippets/angular/angular-install.npm.js.mdx @@ -0,0 +1,3 @@ +```shell +npm install --save-dev @storybook/angular +``` diff --git a/docs/snippets/angular/angular-install.pnpm.js.mdx b/docs/snippets/angular/angular-install.pnpm.js.mdx new file mode 100644 index 000000000000..5467721722b2 --- /dev/null +++ b/docs/snippets/angular/angular-install.pnpm.js.mdx @@ -0,0 +1,3 @@ +```shell +pnpm install --save-dev @storybook/angular +``` diff --git a/docs/snippets/angular/angular-install.yarn.js.mdx b/docs/snippets/angular/angular-install.yarn.js.mdx new file mode 100644 index 000000000000..9943e0163db2 --- /dev/null +++ b/docs/snippets/angular/angular-install.yarn.js.mdx @@ -0,0 +1,3 @@ +```shell +yarn add --dev @storybook/angular +``` diff --git a/docs/toc.js b/docs/toc.js index b7ee152fb8c6..afaf9ea6164d 100644 --- a/docs/toc.js +++ b/docs/toc.js @@ -23,6 +23,11 @@ module.exports = { title: 'Frameworks', type: 'menu', children: [ + { + pathSegment: 'angular', + title: 'Angular', + type: 'link', + }, { pathSegment: 'nextjs', title: 'Next.js', From 6bc602c19981200112d72e3f8493dc7564355cc8 Mon Sep 17 00:00:00 2001 From: Kyle Gach Date: Wed, 6 Mar 2024 13:49:36 -0700 Subject: [PATCH 069/132] Rename snippet --- docs/faq.md | 6 +++--- docs/get-started/install.md | 6 +++--- .../common/init-command-specific-version.npx.js.mdx | 3 --- .../common/init-command-specific-version.pnpm.js.mdx | 3 --- .../common/init-command-specific-version.yarn.js.mdx | 3 --- docs/snippets/common/storybook-init-v7.npx.js.mdx | 3 +++ docs/snippets/common/storybook-init-v7.pnpm.js.mdx | 3 +++ docs/snippets/common/storybook-init-v7.yarn.js.mdx | 3 +++ 8 files changed, 15 insertions(+), 15 deletions(-) delete mode 100644 docs/snippets/common/init-command-specific-version.npx.js.mdx delete mode 100644 docs/snippets/common/init-command-specific-version.pnpm.js.mdx delete mode 100644 docs/snippets/common/init-command-specific-version.yarn.js.mdx create mode 100644 docs/snippets/common/storybook-init-v7.npx.js.mdx create mode 100644 docs/snippets/common/storybook-init-v7.pnpm.js.mdx create mode 100644 docs/snippets/common/storybook-init-v7.yarn.js.mdx diff --git a/docs/faq.md b/docs/faq.md index af3aa33158c9..aa597d0f4f57 100644 --- a/docs/faq.md +++ b/docs/faq.md @@ -339,9 +339,9 @@ Vue 2 entered [End of Life](https://v2.vuejs.org/lts/) (EOL) on December 31, 202 diff --git a/docs/get-started/install.md b/docs/get-started/install.md index 70922d5c96e3..138c0164312b 100644 --- a/docs/get-started/install.md +++ b/docs/get-started/install.md @@ -203,9 +203,9 @@ Vue 2 entered [End of Life](https://v2.vuejs.org/lts/) (EOL) on December 31st, 2 diff --git a/docs/snippets/common/init-command-specific-version.npx.js.mdx b/docs/snippets/common/init-command-specific-version.npx.js.mdx deleted file mode 100644 index fd10b63fb0ce..000000000000 --- a/docs/snippets/common/init-command-specific-version.npx.js.mdx +++ /dev/null @@ -1,3 +0,0 @@ -```shell -npx storybook@7.6.6 init -``` diff --git a/docs/snippets/common/init-command-specific-version.pnpm.js.mdx b/docs/snippets/common/init-command-specific-version.pnpm.js.mdx deleted file mode 100644 index 351ed4eda295..000000000000 --- a/docs/snippets/common/init-command-specific-version.pnpm.js.mdx +++ /dev/null @@ -1,3 +0,0 @@ -```shell -pnpm dlx storybook@7.6.6 init -``` diff --git a/docs/snippets/common/init-command-specific-version.yarn.js.mdx b/docs/snippets/common/init-command-specific-version.yarn.js.mdx deleted file mode 100644 index af093e4f96dd..000000000000 --- a/docs/snippets/common/init-command-specific-version.yarn.js.mdx +++ /dev/null @@ -1,3 +0,0 @@ -```shell -yarn dlx storybook@7.6.6 init -``` diff --git a/docs/snippets/common/storybook-init-v7.npx.js.mdx b/docs/snippets/common/storybook-init-v7.npx.js.mdx new file mode 100644 index 000000000000..33a0a5b19737 --- /dev/null +++ b/docs/snippets/common/storybook-init-v7.npx.js.mdx @@ -0,0 +1,3 @@ +```shell +npx storybook@^7 init +``` diff --git a/docs/snippets/common/storybook-init-v7.pnpm.js.mdx b/docs/snippets/common/storybook-init-v7.pnpm.js.mdx new file mode 100644 index 000000000000..19ae54c8d049 --- /dev/null +++ b/docs/snippets/common/storybook-init-v7.pnpm.js.mdx @@ -0,0 +1,3 @@ +```shell +pnpm dlx storybook@^7 init +``` diff --git a/docs/snippets/common/storybook-init-v7.yarn.js.mdx b/docs/snippets/common/storybook-init-v7.yarn.js.mdx new file mode 100644 index 000000000000..8001609fe3ca --- /dev/null +++ b/docs/snippets/common/storybook-init-v7.yarn.js.mdx @@ -0,0 +1,3 @@ +```shell +yarn dlx storybook@^7 init +``` From 3612c0bad62072232afbc6ab196114030ea41a97 Mon Sep 17 00:00:00 2001 From: Kyle Gach Date: Tue, 27 Feb 2024 16:09:52 -0700 Subject: [PATCH 070/132] Add docs for `vue3-vite` framework --- docs/get-started/nextjs.md | 2 +- ...ue-component-meta-event-types-controls.png | Bin 0 -> 78474 bytes ...-component-meta-exposed-types-controls.png | Bin 0 -> 68047 bytes ...vue-component-meta-slot-types-controls.png | Bin 0 -> 99119 bytes docs/get-started/vue-vite.md | 268 ++++++++++++++++++ .../vue/vue3-vite-add-framework.js.mdx | 7 + .../vue/vue3-vite-add-framework.ts.mdx | 11 + .../snippets/vue/vue3-vite-install.npm.js.mdx | 3 + .../vue/vue3-vite-install.pnpm.js.mdx | 3 + .../vue/vue3-vite-install.yarn.js.mdx | 3 + docs/toc.js | 5 + 11 files changed, 301 insertions(+), 1 deletion(-) create mode 100644 docs/get-started/vue-component-meta-event-types-controls.png create mode 100644 docs/get-started/vue-component-meta-exposed-types-controls.png create mode 100644 docs/get-started/vue-component-meta-slot-types-controls.png create mode 100644 docs/get-started/vue-vite.md create mode 100644 docs/snippets/vue/vue3-vite-add-framework.js.mdx create mode 100644 docs/snippets/vue/vue3-vite-add-framework.ts.mdx create mode 100644 docs/snippets/vue/vue3-vite-install.npm.js.mdx create mode 100644 docs/snippets/vue/vue3-vite-install.pnpm.js.mdx create mode 100644 docs/snippets/vue/vue3-vite-install.yarn.js.mdx diff --git a/docs/get-started/nextjs.md b/docs/get-started/nextjs.md index 9c765276058b..64e207a683b8 100644 --- a/docs/get-started/nextjs.md +++ b/docs/get-started/nextjs.md @@ -14,7 +14,7 @@ Storybook for Next.js is a [framework](../contribute/framework.md) that makes it ## Requirements - Next.js >= 13.5 -- Storybook >= 7.x +- Storybook >= 7.0 ## Getting started diff --git a/docs/get-started/vue-component-meta-event-types-controls.png b/docs/get-started/vue-component-meta-event-types-controls.png new file mode 100644 index 0000000000000000000000000000000000000000..a25c91c37c0396975d1a0388c799ecf6496cb534 GIT binary patch literal 78474 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

BuU$UKj7~vt{tJwq8`7br?%v3KDo=Muuf~1w)uG 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

c; zlCMzyXgO~`A^hD-t-G#qvy6DzC2AQH$1=9-<>vB?JvCh|My`pn9w32sH*7MQN`!Mc0Y%XFAl;gt2YmSrs*oa2OGjo)_V@-+vwRt(5O z@G8xbUbuCS^G-yZ^*-?+ez$!Ws%^|ATnFpxCoUPilJ2i`MXp&`ZTDh)1vI#&B8u(r z%b_Oar>Z3GBiPejyKNujR*x=zCX~XUvA>V+lfg9#Ad zxkD0_-za$5H2q@9`yKJ5g^U2N)BTFmnY>hT&^g`ZRmxDqx60Yd_$j_Qw7A#%qv!9; z4b_^EGa!s{^6pLUscqdWW3Hp_U-k%L+oR3}K*$}M-K!I&c{=G2z8;I@0w_UhX_`7n zhqz;-1b{`ByRqqC|B6}7XwPJ6eqEsag>QjMiE3!Y%H_8khcTP24u`=fbZYlsbXzTo zpOQl9*G!57e3^ri0-D#N*uQX|xYle^{5UVJ{A&LuCN}MUNvEEd?ZO@Im&42@5Lu6v zM`>oSL_4$^uqeY`qbwSggrrB}EL6jh8Y}^79yGh|sPncF!nv*v#Q=3h;zaPja(_SK zpSM&1?>Vy1EwYxeppljHF;Rz5&!Y)r28C%=yGdL5O%i;S+okTCgLsxvF7fg9>z{q z@v=G+7LWLhf&@M65qjTB$gh;RBI_&rMC6sIw$6&-mW>=&y+!h($OkEj@218Hy&{jU z0QT#RZ8t7=FWDGWIZzdwC?~0atNwP?UK`tUUFEM1nv%)GtFW|wmwrqE$p{^WK=(An=Al#g7fxmPAc88yO^2-=HBA7}D&k2Ap zp=deWx)S-ezPi;4xEnRa%l-F}mW{Cnsu5=&&gR2=)a&03+F|TogQAj}1A3UY0|xv6 zqzpl=SwpIV`JTAa-q)dmpk~Cw1M|&`zckfUJJgbdDN4P*<|p^_f5FxRu58xU)>VmVxTa>oJW52jQ>lGy;1@05r}&A z+gPO|AL3JK-c`2uFg>_8p4c3I1NS0*>NmE8*DtB%BlcVjR!IEZ%Rx^u!Ez;2Wm2PK z`+GnC5Y;ug{c0q3X7k$Ftm%48->rAgwn5}Pb>+HOc1QxTibux7C=)__dj~p4ycGHy zqOINj{{uu@R9RGgB`$w7MR_GsRIiEhxxFv$bE#Td@Hh4Hvv$-q83k z^u1isV=;(!C#%n8sHLA*&uOMyI$l3k36jdpF#$j)M@HL>z6+=TeCz(~cO3Ej0_Lib z#aiT#+YWQSqbrqoz#`nwgkvFMI?=Pc4_^98v#=ig_(Hz-W0`_wpPdAf{PDVn;ws2y zT=$M6wPl7Vp0}pj<}EFGGC<>Kz5ryj%>hl8_nmsxBH5lTz!Qsh`l?rNXHcNZD$(^! zGwzTv5(h3=T@!fg0cVph?xt|V&UfN7V)q`rw4jacMr%?oZ9(%bG$ii$u*w;~EPzY^ zlM_m)J9D_XYS2S{C#7Fd2Fq!!v%Jo^Bi4l4V4TaxE>s zB>+$(x6OwBRq9lRgh#NCU_<{2d{I9Y1=$?UH|s1c40!^W^i!_qx2jdC+e@yKhv&2rJM?+W2f00WL92t2e@$^ zLxnbMV&Nf3CHTar#(bO21#a)$MWb;>;>oNkqUsq^P50vBk&T)Q z67@r%FQ)b89!TRtuW2)I813BS=Qj)GZ|B?((+jXogg~2O-iw)5ooyzh?F7KhpMwC5 zXwlGp>(NZb^;fvd)oUt6bR59JN>op#7qkkMzQQ_4-8z6Hfcm#lA4PjdImfo8n`sJ9 zQav39sn~<)r6gLb6sAdt^~}Jz%N8*w@RgkQCoYHm|;gr+vi#-v!adN1G zr1Kp#P~$D*Gm|YMW&S|5Uw%E8d)w-Cu>vk`Rm*U5VU=*$XQR#Zv$jQhoRF+Pi5mpm zdiyvKRqXgNIY%|nTw*-E@J8~8b>GCfVWCmz00B)KJHFHZz`F+$BV>PzQt~VJ&9kT8 z1eG!pxw1j|RH zg7jAXLdv6cla0%{V7+4kx-;r{AJ%2&$?xM~*4-_*146C7P8pBazU{gV(^517u+dQX z%MsJ63f?Q)lNzc zu}Y2>F>1a*$;^Nou`^Ig=bT0UR;NC0`ZEcS@jAkcmvR`ipq3bmM!Tm;RpE!U;$*{l zbF2OUg-3+@c>ZOn;!a@M;_&?I{qe61N6(iYRb5l+oZ#bmL#R!<=X}l~CFQywyMJ-1 zoJiQ!0JS8>tFM%<2F}S@c2$m?ifJ8fZL-5hx6h(|R$8K?UE^Ib>+P`F*b_=mcl^b` z$aN>Nih+`aER$R*!&VJEpxE88liVmcQCz;8C{{^!iFNK9^s-A`)h!46L%2_lIr7f4Yq_rRTPFxd=J?2Oz zVVK$H^f@HaRN|uZw?=euvHehud%p?mIccroC~>n#SSX>nezBpNC4|bIoq$EQhRE#0 zsaXCsr-?dvcGO{`RWb;KQauckF(2c?g9#eNS3m9v5d z4N=8MjZC&tnEIV83Sn@E3x zR8pz)PM;bYone~3Vcv^*N#8$zOyBTE-T;DK&q`|4>nse|>bXVhP%CBV+y zw|wZ}j)1%F!_n6J_pDcm6!pBh^28`I`BEr!UU&fc*!Cbm>!VT$(#wGo$;S8#)txH5oVFBPnit3vff{4W zEF)jVCr;F|CVAhZrDuM?)>#EWR*8=u2W$QMvA-neeF?z2>Us*O(O!HOW4+RzqN{` z#J1-E3^iaIqM$mf$2N1SgLcMtwr!_JR{0&fyg>`+4#b`?#eT~ZtrxT;S~=RQ64Zn{ z#fZ2SR(|;UE%Kr%tx5mv++ebbk@s3{XI8&&L501I<9=GG%B*JGqr8?3-C0d93a{rt z(ojF-Qlt`XW(n@-&`9-6)5lY8sWpiec3c&o$U3|RAp56S(mrA9&Y=}$m|o~dr)bGK zjUa2n9wgq0;iVJ7&0=MzXnbJ@AHO(k3S~oK%k--j@rI7CL3TBa zKR7_F>=K{P#A{zu?{u^Hc!fzn7D!-9#QpQK=Cl%gNI#X6v{a;TSF$YG9jCvUB#y@F z5!BI0e(4JVbTzi8bzHnm%6U))ANb{uz zuOEG%y4)(Pq#((pG0Ca zn?g+K-O7B^hD7wTf(J$f{w3WP?mm6=KE`=AZhPlRW&eXgd4tM|*28Y0L6aSREV(OT zbOsx<1|>HTl>N4OWRPo=b z@b-u?$SK2Mc!7pgPO(AIHdM?}sh8H*KcjbedNwk07jc@a>2Dfj?3V_q%lnfCIr=Cnj6&`rFp`#KiAl-n#z5RgkR=P5-dPp-+vxL^L08vedHuuR&zwWoi^62NRlwr z48o09*Ym@VKxeS5Op&cz4hIm0N4ErNlv6Aj-Psh?5@fzX6ODp}o4K$r;8%L(*o~YJ z22~Q3UAAqRV>xi5?ugrl$o6+mzkY)_i8NAo)B(69hr!z<+-t=_nr(P%M+sE$tx2yo6Db|eeJG8y8HlBe z%t@p8V-o|Du(pVj84Tk&WUhp_dDZD9*R?3wWxJyosK*H(zVCG__4fhS0o8X+_%ZN_vCw( zxYv5v6Ko|RzdzXb@F>c&T|YXiH|z3D1Qw-){w5Y+^NYn1>f?@Z_-UWs{&cJERE_Mg z${UXHUfwR?hEz&o%zSnq0h>Ia=DL|{Qvxp0D#4YjKM8#4*;6I-;kTpD05vs^zcoRu ze`6A>OY_?uzM`nr9-sFJUq48}4@-ID=WY){O4u2Ru8R!|96!}A7;U)|KO#8hySPm5 zI@g17h{>6FJ{fHN%CPJVcw*tyDn{&OT~Eg0fEJ9<{SpVgG+XJ6iwH1jr!GzT<@KyU zug+anhTF*ef|%k6CA2kVH15}-?)VD<+nHDnU@#f?pSs{YQM2Ve)i4(&VvP~;fk4%U z7>Od*g`43&pN`T+L>6!olWzpSxiWZOE7EkEM0N>L*outu9P^sNb+risB2?}@z=zjU zkCHye9)+|7VdY$t-1(EeOuljtANh)t7r`6$!UI`e6i=l@Q%cm(F9y71238`$C$9m% zV+Vq37bEfVy7bLo%o&xU)N4oCXp@nE6+fgI^tsaC4?1_jre$EurYCByCkcv+_FOS_ z&lR_~tmuyvxKUT?C|Dyuin>M+jkA*%Q`%hj_ zN_??@FV1l8%c3O0;`jyY^{HdT-gMu2ibcnW#c<8h8A5!TPoaG`nQ9{3;aF@c$4sXv z_^i#5^baWs@fP-&)S_tO<%cpi=x@JZzbUaHs2=~`f7@b~!#n*_F#XxRht7Tm{QAW& z*_v_h6od6PMSQZV)gnymjosR9LxsJcUK|`MvgZaBD^?!OOOc+YiKe+p>OW7b&GKK3=EW1zP|{+ zmdkbLxCk2Zu&dA@h}m0!`(NktTr{_O{Udoe#* zPvhhTm!5R#@1JxhwmD4S@QtGCUs9xAg=$IX-Wr-n{kaZFu#W%G&HuIt#=V!+5GZV= zSeyK8Mbt%eRh+R^($*r>^KvuH>Jt6ILSZ0G&0LO^r~m%rKfaw#5fRPt&iaH`W-#|h z!ud`Z>F=dx>nQ|Kbv8P|;}%8dfDZ}a{I`Rm+5cVf{*9PLhorZAx+mM=&(_ib@;4Iw+W~YKfyK1CPZh?{pJpUh?fj3$(BJ-X z)L)E5j&~$v`RmVue_qgM+KZcA_}(k?>wo|C*zXr~2#+5GZq-vt#2Be)qJDDZ@2~s) z98hR)81V|@<4-pEk+r}KQA@=R8)z1I^+|PG9jx(70il6cr za4*@KiRpA6){v?pL>iP|S(*I!W8sM>z_yr^7C!uGV@jd>m-5=hCR$6zg27ni+2wn7 zo!2L;P}H7J_AahJ_NQ$Kc*efA=a=~X7wa?b7jtTyMh9s@c#i@qAV(A6h5s;E|IM=a*QXPY0}*_7;JL-0_wbWK2p2%MvX>YC*Nwaa@^pM> z66Zgx>2I`7{67-@ftF|gkA#2Ylz%ZR&@cbTg@2H%{}+Oc__l{Q9i(^Wx9<5Ty+EhA zh{l5|hq#YmibQ9oURD=&-DUk|LRRs*OK+6{#o@C1&|TShXiM`v0gR+LNf8xGgI1$C z^)r$G+xIfw&s2K2lTypRG^$g74gIIP?GnCrj48^JCNOs=nf$i+WU{r9J}jevG^uD{XzC&vAs%>bKr zb$s!E*~s3b`rv{Y$?LrMr#t!AFI#;D`kP&Tt6cNP{?BFo-}?pc z{2vMbcoY8rPD0m|FH`4qlQkCax|(C$GPn1s$I0fj=J=kD!HiprBiMmG<@lFhcEBH) zGcjXVov)mDU0}k|$usJ~jk>AV^j;11EW5xNZY3HI_jLlFaBd{e-fel{;C^uQ`vrip z(xPp(_a7Mp_#7n0Gn(;7OoOPBH$q~L(PH*05ZrY_X1EZ2gO@0x2I-grHGivw7i3Am zw3mv2C}ya9q5MI-zZji=`;DBGTvrb~*l7iIi3GV4M{fIq#GZv2*ZD-LYKN3P8fP>< z95EAAf73ZBIHNE(l4Ort8518WKD;1ReWLdsPEMJ_w??s7F1+eyyVC{$V zM&JBFRtk?I#4(zICrpEyBL}hFm7y2VDF?_#9qmUK;4(HwW1-tV9&ZZsp9g`@Yn%p$ zbl!{bClAFnPpNl_eDo!LZUiQ}l9AgQ#2`?w*$|1*D!`E*7vSu{;aZ&s+C{e!CHAL- z3D~8`DJy$MBmRiRY8oMYB$Vmvz$zrghu!*yU`azLLKhWueumn0C4 zgQR*0Cs9K^jw`RD!nne(B04Bx<_0zMRl7>y>%JVr>uAN%w?IA;8-X3JaRXcT2hMx2 z!nU;?!Tc22mFtK9Z*_6{HwuZ--v~s5aY{ z(*Dz<{V(OGEe}YxR(CDHM(}tCGA?omoN6FA)rUq*UcDP)<)<8~HnqHl`wTtfN~fM- z?u@hnccK2gZMI$}dYV0^em*Vs4sqn|i|+zAuF-;|#6~CLi&o#r4cUjvbHb>)X?5Flm4S zA%X&S5RVzM$d$VYzEJnkUR;b0rt%*pQ(FprXmli2j|cqiTz6G%Z{cI`iiwMU19RCK z|05qOu>uz|=E;r`STML)UDfA+0_gDrCoQ@0AtEIM z^0J;QmsE0cL_5#~D!K*?$U26kYy?>i7i*BmNzFA5sFfpG*@YA81lidNrip@f#dd;Y zNo!vo)q8Pjnm9*$zK^w_3d0JAt|lG3G*@u%0b<*%H(WnBr+7quCdRR94!t&$f**0M zx9@aZt5r?-6~FpVxl4Qkj(8&IHG8inxTfXAiuN6{ItHkuP^!3zlW^YZte@7ue~M|G zMezYmdcLRIY<;Rx!Wc@U;2VQ!k5Vacuko*2o7R>$y!D~(!|Tl=+-TH9*IZYbtGmC@ zkUrlW5{19tnWc{`U5xhuCCI=8bDn=OTRUV+aVs~IV;&F~gJLPZ7;zOozMUR}=fv8r zX`u0*t3KXIN1iyq+C3@;odbxBv9P9F&OLeck-__LYDfQBRL*9DbNZ~D{E!WV+k~F$ z1nofVriZI`I(j9JRzXowm#kgfuwx1_536*16pWWjKJ$1v#DuL`m{O@DC$tZ@*hNzlrP&)nR#Us67E81e z)-#V&Lsjc{5l`>m^^exk(YxSK29i2I?+47tb~WS1QzbvJw?#yWe1}$~8Ui;RX>?4% z2iJh4QupxJiK4K2`%|pE%${ z^LsS#`QdhzvFDh0u)@NtuC<|~O&~8k)?P9otf?^noE|HOMdNmSrS73zR3y(OlQ$M1 zCL+1SWpghXO8Th|txcP5+LZ(-yP;hrR8|CI(NDW`D-qJ#r1j5xF#vm+>g+651sXT} zY=-hvC1oIMi&vi1DbZ3Fk+03+xa#@b3hZBdW+gVe+ji!g6Ih6te3G?=_lKnTV%*pk zdc@TdFG?!jp3UShq0R?yweI4W=I>T!(2`$Q`oxL1_5riS%zDyqdzF>*Lrm;@t$H){ zVCjHX607{BwD>ONJ$kcXVwJ1&z`Ob>ew6znSG(exRd3Rpos=OQ?Oi=zh*=2a99rcx zMT>10G3CVVe{?969)i<&!OO**r46=pBFqM8VJKH9+fvYg0($loZy{Vk>~c*h4%V|3ZA7&(NX4x(is4(N>)GBF%) znh5FsJot}sE5x^bN5wm|ke?~z)hv_AAyiggIgeMnIE*gPe0;EDl}xkx!@Hs4k8cK2 zE!<%DLHGSftpr6j<3~WPt|icXjWSVl9|P!VRkZ{|mn(^w_bR5CeMeR3Cu1fKcABDZ z#MwXUWH$DO-xnTTx>>hqX>)r&S$8#|*kgHUT4;wGNI|E17YyI7nxgt{v~jc0Hmh!` zO+`97R#H5c%Ig)kbMec=wM<%&+nL>9V+sU{jHcYi5*ZebgXkTdn>B*{GsAQ+T;Gqw zco9aWx5IQNy0!MSKJF`bUmUQiW;O%YK~NRVXV%WqBe#b>qw;xnE>J>T;%gUA{P`{#5 z9U@78cg_(*dyk&(faCJ&Ct3>HUpt~H#dR~D;KJE$0yh@EKqFu7%bFS&Oz=IzVd`N} zf$M5^p8D=z8!YEbDA`hNL#oBifD0v@VWny|eyh5-e`*wtOWL#eO&d82b|2nd3(BUF zfu0F=noeuIm6(w0N;H_Q86}J*m|krC0t&fD&8FG(Uwt3cA(o7I_*8874R7bgEBMqE z!Ambj%=L@WjE4Cob`x{*KOf&kw52`{Iwt2~_i1ol%z~B>kh#1hp&8UFIas=2##fQH zL(#sT$Lq;~0rRv9c|l47Fk^X~8fdi`Q?JYDyY3YD;vbZMxsnOKb>S3xDmiH ztCN}(l*~E~uMER!%Xdm4~LgM&l;D^A*dkn%uAv^ zqUp4^L9kNpZ6{PYGL*j~_VB;yZkLyU6oBl=i4Nq>kGjC)6QV1N3)!wmtkQhi#CkOQ z>Kg9Cx95%BciC<(V+YHi8piJb5xqF7leiZF`=E|*u0Gfd?GmzbL@)Q<1Jx>OCi4JK zXQ{}ug7$S!3X}!1+CTS>q5;zcc=k&0RT|$>>4jI-X8y}138Bq;ZVtwlbNX&;H_~za zd-ww-+T?}My7xuCzuUua^&Hjb%Orub#XE=XK-3)uhLPV!>~3PlKI>E>e{PxRO8M;A zF@#p=AzJjsx)MAl2gawu2f9EPc8F1y9oJf=y5lvM`f_X~ zZQ=FORy4}V)^RZm*ZB@D!ZF;Sr8C~Kt^MxaEkkQb7#bE(FDmE252_V4vMY#Mx<$Sc z%4pSZj&wsIDqQKl1)N;d`0m@P=JHTW=Kb%4kY?gr6SfZVMZakR6U2z?cUJl5bu6*> z=!p*WX7TVuS94lxDVX2xI^sz%erExXbZl277#VrgvUO&drOgdwnDMx89nNdH*o{_J zq%hMO)8d0c;#*LW_tIH*gD2m&Oz=`9_kII8P`;pDKH|?0JqmB8&cK#8r5?jQX=gC# zvGT>5{mo+h0mAt=vp2i3)IMWbYxWlpt6$buhsbmBoA>ibc&G~(&ppcP(NU`#vdv+$ zPC;;%EHF^QOe^s1{lLolo`>tg1QhidNkkaAG|p@CO2K?be6W=%&=|W4XJA;$r?h8i z1G`u59O>;{$dm6cI5rdya4X6aar3VP8Qx6*|&J;n%ovb-hONBFhqU1?^^EvoRa3a*mfTFP;41Bo=U_ ze~80~lN=3QO>z}md-x&NLw@@#=G$Q-y?-;35RdkO(-BKZN^pa1`SI7p`z#%%Cthuo z*A^JjTN44mTS%+rb|l-TR#Vtb<=a5hsm@L6tljCcf;Jh;RB!8g@5Nm1*?0x}-QGoP zO&*Hm1_9?GPRp4q-h(R@r41*U>Te0gzJ;99hGhfGj-VQfkM~{3SU>Oe3buM>j|D3! zwNgilmq*d}nqAd&M2h!LBubKrhW1HJlB6KZZ{FV?50=9Q3c=xef$e<9qMR2mV|<-E zUvPw-x#&>TS}Z=*EM}P<0k85JXFiRw5xO+42?{PI%0Zfz4cMzfsXFg|#vQCg83gKl zW2B1INX4xwjRkhIQFcX$!q(wwR2s$7VDLX&EijVcBqI?6BiUDdq6*UDsNqO!kF6%5 zoTIkc)X95hL6=YN+UT`s71Ruj^W;4Q3hlh+S1Se|7b2^OnT11kX?AyM#w8d&YdDmV z7y?miTR>Iw03VfFYB02EB1zy2LOp6#&S6|sA^5Q$Zw<|c=2uW!hqR^N5uz`Ecldo{WWjx zxTtUaFsDN8u=f| zunYQodpr{p;-A77b4v0BTU0ExBH^riR^Uo_mI*BN#D|XD()A{*?s5%WY?`HT-V^ke zGhVa`ms>6~DqIFhdq%Hn`k&Y!BK62wokUafw-Mv;wUo$7&?y(FZwhrUPr>QN6<#85 z_M3$68J!=+E;^Rpwzj4~@nb>}l+KV$QMS-C8gE!NWo2k_9%Jz@umKhY;12Isf(M9{ zym?sdKihwkFbqdi)?Kzk{0_<#7GC_~G3>xv&vSYCgx|Unq;&~B_0c-XySI#9ZSLNO zNn9|Cb?pP-z}}0kE-zumB>IBt5**M1==SqMNFH=0IloK6_WWL)ZI^T44nzb!Y15dD z#Qu=B2cm50?Mk$4U|VvScw5V6#5j~H!rKkE+u}Sp4<*<868K7SE0s8wS)3a!){cQ9 z)9EVuH|DyOqI7sCg;SwR2MaGHF4)abLsOLfd3?2(6dx%0u735;8;Iz7v*Ov4}_ATyNK2nROkAHL)P(>hiI~ScE!5tyNK+pl}h{hbA&vz`Z^yh znxDhy$?d?#CVva~jsdq&jhUPG6Co@*6NU&rOV_JU&y>yEMR|0~6&Sp;S0w$PJ-^Q!x1;+09K6rjf3m=l9xrm^XP)?$d&=wFUQlZ*b!qHWbX&)0HH6JkbL z5Y(mTJc3GzDfHU0g@#2iy^?M%1?&RF+O%d<{ss(^P|Z(1-bQOJV+$|_HqSO`rFg)u zKpN=W^NPswHw=`8J4=7d3nFHYcl3aPT0>r69Nvw|B^2``i|-qGG}d}~)$#A){UBmS z8-i?%3JIfqjW$t20t$!TGOT9krp=H-6lUfIJQi~-<%@>erx8@3q}k<`rCl$Wj=tWB zACLfb-__)fGu)0mX;k9Wd}fLPd3d>0_W+-~G=>%c+(Rf~OinCv50Oc<^uY+Ue!08y zpi@JnY2DpnJHv951+#_4)$an2HbhEZ|Y-j1Z^$a-psUB@jmt) z7;tY+N8URLYCs$BZ3sdd7bEr%t*_Q5vnbrN(bZ*B2jYwtnp8Vxt%n|Ox|!Q6E`-c$?WbCr7nu& zZk(~1mFTj&6m9@(s7WQ#JQ2$vDA!`uui&`^&#(hm7WQ~ZYIVPV=hS3r(ARkK$N_JO zGMX^Mo_+pno+_%*vnsPdH~L5f$u!fVyb)ihfMdOs?Tv?$Q(o6^UHDZP=WJb^60fj3 zr>c{LY>&emWk~Yb9e#<>L_8O0z~#j(q;f%gWP4Ui4WcWgpYoi;uIw(w_+I#s6h2<- z@F?5&wA+WPKI{*AGB-~cX=K?}+_-`VV^ZNDP{BuQh!cTP_(Uc}1SGAlY?0GM$k zSTtlJ4LPV`jxU8&WV6Cl5id-$>zcGnh>6)Ls4evT9#ot0I1xobtm1x(B1ArkxK9{0 z$RgY?Fvxvp#wK6glFO0$E%iVCWOi@Wm7etXS|%5u6xDW{7lXT{ySip5^?oD3U8(_1FcM?EXKO$ZdXAR)->IW{F?yCy0H`ka)9SBIP{E@sl_jD ztk~QsBoPa2n$Q^g+SM^GtKsWLp?Ka9eT=0>i)=wxlHf+&+xsx-_%6E5QWi~Y9>yi# z1T+WqaQxFLi~XbT51N=*J$qbIrXsm-i(r2SXphc<7q8pY93(D?C3PN%+2hpNhjEmd zn7)sU^O#97&w z0E0Le_;I!R6*y6(&Xdhh!I6X2g{mk-L}WI)s=3zLAc3zUsrhtwaA`4T zVBW7R-)A)h&8X#YQl+PuvUU$@}sHDJ zVq8j1T6jF`$eTl1r4Lv|4_>@dY9lLfOUfLYt0BT>Z^1wLv5^VPaz=LRWsoQhkIPM0 zWgUYWP0v&myQAK}wT-N`dnSokQ6UM83{~=~ezQaHRga(zXG0rBOSQ*3-N!j0B z@`v#VjRmYVXWU)M>CXVV(T^Isn;G(?Po@M+&T(a$VNa{27yS-pJ<&d-zMeba0Swc3 z#HSWXcR{Lic=#}YPymr<&8yrbG6^4v1~VeweTrOAKo8I$)x@n8l;gOjA!BtfB`bR< zrK-iY=wiAXEmVysR?@k|8p_%EZ;nU(85O~*25m7;Mp0hNT^&1^Ydww>%ue*zkq@$l z3cLqOr%gQUIa_H7u=e z4@#7)oZ$0{-?6GYe6X#^*SF zCxOI6_sLJ7#g_$TQTT|}r_ToVH)fdecOGJUR8@7Ub%kql(C!2E`}`)K|D^s_8JV@| z^?cqnV-G_pu_(fVWZvV5jOoLI!OeBDTE6a#oYoOG5+SKILli~?3M11Ly1!bOCjYmm zeBCv%vQ^ciC;iITyjGB4IV7dbjgO>$Cf*3d-SUqvR<>I`oBZ>gPDmAl6!8M?@k_$+ zmJu-Bn03-Py+KC;xGJi3#Xl3@Lpl0a$%tMN@il+VLkD7fSN-du#~*qy7I>e$SeX@ zh%&Y!BcZ<1sD!aTsWRjyshQh~EAEZX9;@9Gw93>xp+?(oG5NZz&+a(y@js3j)Tazr zNIwqu>ARoW=^*h%wkt~VCFG$D|L$^iU2JYG&#+C<_#^S}3-4A86a>+3b`04&p3__ME;r z{HDi6Q!O*9e&`ON_{2b2eOSw*)iK{BITh67037M3>3tE~0~tVwRXZJe;8MHJmas8g zi|0 zb$!mJ*|5$0$CrYmP`f-cx8O!S3}k7?Yx)Omfwv#OAfz1tuXNbnV@2(vGUkP)!ayJk z^1i}8GWVA&lTE=%VS5uhAJB1?1lO0L8Wrgok2a(d-1N))Ow5iEv4o(2IoAFE7ARXD z_UGf`)|tc6s<`bbD{^^nz8{1hB`Ql;;g1Z7c)ivA^euHRc`Lj&fBJusRcsS7UT!2M z8s-ZtoQDl80oc-q;Tz{X{;XTMFH9~9Iy^CL?p2xD!otBHTjPvf@sIzarF=Z|bWkBW z;eR>SKP8pH3wq;`kNGc6gyh2@&c)YI023DRNOaHEcYaw~iU?a%D5K}z&W@k!pP|;G z!dYZTXTa{}u5^oqvh9Ch!>{G|iR$Q~3dYz#eqF*rD}k6~(BhR_D}ta_DO4=F54Wfb z_d3sojw{wq8O3+MItD$>n3b1mk+LUplb|AGs#L(pp*3a}A342}b((#!rP)(JTXPmFrjO=L1aF}P2y!b2mHH>kG z%xTNH*`dwm(VkbXW7NW%Z}P25`ri}<Y7M(96ydQe*Ji~wchS%AX({vQJ5`FG7_zE&wL@5Zfs@hf)9k2{O!nwN3Xkb zw7Vtc&j<9kk)3kwODeupZ9?60i?O-^#cApp@2RDxg)hA+adiInYS~@B{zqTSTO>EL zOLLpqRIlPAABxl?z6+Fq6<_sZ+GimkGBEuV$IjD_yC*ZI@hES%8eV5A?738L41qpN z_OqCaZP6DWt>y=4x;M_L9_+bn`@+=MPf~UvMK)xDZ;MJBAZsz3+1u9U9?K4;=O zlP1xKGQbxOY+u@e4vctYSvC&7*K4%vnhOjTmB*Qd? z-qX_ny`Jn9Rm_HC8kwdiQk_z|nk%2i;?Vb1<%Ei*maTOvuG_z9*`m9A$?9#6M9QmQ zOEIHQ`u|CqlXo%@EiOqd*-__`M*mKPz0A3qzql>G3)F!GV97qE^}2Hs@V`H=452i= zo-&Vv{)Y#z3N^vsWRw5-VvAz9E>rMgthxEo-%VL!J46!QPcBG(xzc}sY*C&&T+{}F zh5g8Xcu?v%#4xYUz1jB7d+3vQxiA0`LL`4#9sVC4+?EVeiFlcK?9bVKWqgnW)I&Kz znI}yY{KJFBM_?+OuIna!^)-L)A29_A0~n45O7IV15itU$qO&~s@SO6-mrnH4h)@O~ z!zf_6T;|VZ!ToJTQ9_>P)eWmd=OjdbdkoM{A-7-v3~>&8`;`a(HNSVYYbum3tS#HWu?&~oWG;iLxP4hi_?N%w5y ze9|*9`D%oT7odm0oKgf^eh3=a zIGSEJ;KFyxWrQ&6z$L@0LTD*uotn)91p>k&$R~G~epf@1Uid!MxPea3|LXATlHsh% z_hj*VnfTEIZ64F@jk2-ln68x@)LM6P^YMH&8C>_R*=p@lu8@coC*G-cT0zEdcFen{ z(QKmKU`O_O#uJ{Wn(6(42~Z=Hl}DXcrSaE!CD-{Rh3*Lgk&t#*LNgA>3)ScZmP^nW zJuHjlERj?2&VORRe-=q+nI`S!5@zsYA7l3k-%Bg;-Du{tJo}q@4Pv~Rm`e} z#&H2_!rB)y5UsvxFFcy)5lBbl6Ft!PtW3!D5<={TjT`3FBK~^niT9yWvt+L^K+pco zj-1_90j8}+nj?E#QAmQHkQLX;e0m3K(`aIPa~XF!e&n_+j&%%hUILr!4%&y7jKuFs z_SZ4rC0HpncqP<(REBMoJ_ya~K7!jVB&Qf`!5+1acwFy&Z=hu8H#q|ESWQnwAFZ}w zNJ=A=5)~~@D1y*p)=|3 zJfIbB6|xCZeAQQhu!6iqSt^a%=mhPQ!uZmT#_b9Br|yb#O8qAJ^s%&EzN~v|HE?b2 zlWSg&6m?Ct>cIe0TbbW%F!9l`Qw@l^3pvbE0q(S0vvqdm<@R4f)lK7*R`>y-x@!_& zy26h^!syQPmeWv_WN9>ecllrQmIH9vR%g#0e(_M&$DUAGLWM&4ZG#;^S~@<`blT4{ zWTVEO<2%VifOEbG;J$S)s?P>Ci!vH{wrRjNHq{upVBAFQErn98nmuWXxm%N!77_WF z0;un}f?W}R*;@?K)Y9W_{dT)`{M{wm%6jo6pqy8d{g?z5Eo}P9gXb=i`~}Oz#Cz3& zgn8?oBhB!EUpdN`@C*nLdda&wyy8nYQ!i(ohe1!%T__eR&DeG=Si^N@)@zYCe~?xA zjWy8Fm4&Xf7d%$+Z+Z5CLV@BpZ_2=4#k!xwctXy3b6;Fctz+CBm_w%m>J`0^Wolb)+)CS!@y3#>og{D7j}pYxE_E!?3kOnNMaVvIpd) z`+Ayr-cv<=&`ajbtBe$J)%xnGK@#gd%EFRZpP4PjOZQB6Uu(f3iofL5-kV$tcC%-blWC3Dc>@l7GEsj61iqijWPY55cIXM+w|)S*en z8?`Aw7;o7Om=y#}P&LN58T<(3PAENJpP?L-422J-o;33)4v^GlU3|)~$P=GOYH_Qw zP-#N8m%rBDZ9%NFIZydod*$d6qNmf(F&te@7 z*Y&41Z9NUbn_en<;U6zPHeUMHXi*bV7v2Qo*5|Zb<1E|Qo4N^KBKezRa_lI)t-Xhxx`=Ljro}d|xZ}5ICYyv1e{AX-aH+tT{@i>j< z$c?d39zP8n7rRq}ye!BpgxWhHk9@*G>6T?G@Erz>%Q3(YrTu)Dq-NPwJmm7~%>A8P zC~a_Q+$p$Z+C(1h47TblyZMG>*t&P{)n@xgni&r7{%a_YqAkgrK_QnNNJ+q1{l-qy zy1S5b_gdFLbWba6Pgf);I?%aI%afHCyyc!(EAoSeX=gGM-F%41l9jy#uMYoJm-RdJ z;?IbU)>oJTB@?U3_^5t+h(P zpQc!KCjV?wVnAty?p6+&`KGhp`Hc$8D`F6Jl+M?RR?ywlM>cH#?5G7Y!g%oMoUWLE zvpz!*83|+s3>{vD#Keh9;But4;9b&E(s{SthdN4)HqENlY73jXcDgq~pTY&d6wDJ- z@SXN&-vs<-qo#XEPp4aN|G3jN$uOB0zMpg9Oer+wx@A+6s!eqkx&0%GE2{@g z?TE;kV3p2m4E6bT82{|@U-}51(KL+ae@z7g<$t&kf)WVk`DngRD%+Z${vG`LS=Z>$ JW1X|V{tqJhW?ldQ literal 0 HcmV?d00001 diff --git a/docs/get-started/vue-vite.md b/docs/get-started/vue-vite.md new file mode 100644 index 000000000000..398825a0abf8 --- /dev/null +++ b/docs/get-started/vue-vite.md @@ -0,0 +1,268 @@ +--- +title: Storybook for Vue & Vite +--- + +Storybook for Vue & Vite is a [framework](../contribute/framework.md) that makes it easy to develop and test UI components in isolation for [Vue](TK) applications built with [Vite](TK). It includes: + +- TK - Emoji feature list +- ๐Ÿ’ซ and more! + +## Requirements + +- Vue >= 3 +- Vite >= 3.0 (4.X recommended) +- Storybook >= 7.0 + +## Getting started + +### In a project without Storybook + +Follow the prompts after running this command in your Next.js project's root directory: + + + + + + + +[More on getting started with Storybook.](./install.md) + +### In a project with Storybook + +This framework is designed to work with Storybook 7. If youโ€™re not already using v7, upgrade with this command: + + + + + + + +#### Automatic migration + +When running the `upgrade` command above, you should get a prompt asking you to migrate to `@storybook/vue3-vite`, which should handle everything for you. In case that auto-migration does not work for your project, refer to the manual migration below. + +#### Manual migration + +First, install the framework: + + + + + + + +Then, update your `.storybook/main.js|ts` to change the framework property: + + + + + + + +## Extending the Vue application + +Storybook creates a [Vue 3 application](https://vuejs.org/api/application.html#application-api) for your component preview. +When using global custom components (`app.component`), directives (`app.directive`), extensions (`app.use`), or other application methods, you will need to configure those in the `./storybook/preview.js` file. + +Therefore, Storybook provides you with a `setup` function exported from this package, which receives as a callback your Storybook instance, which you can interact with and add your custom configuration. + +```js +// .storybook/preview.js +import { setup } from '@storybook/vue3'; + +setup((app) => { + app.use(MyPlugin); + app.component('my-component', MyComponent); + app.mixin({ + /* My mixin */ + }); +}); + +// Rest of the file... +``` + +## Using `vue-component-meta` + +[`vue-component-meta`](https://github.com/vuejs/language-tools/tree/master/packages/component-meta) is a tool that extracts metadata from Vue components. Storybook can use it to generate the [controls](../essentials/controls.md) for your stories and documentation. It's a more full-featured alternative to `vue-docgen-api` and is recommended for most projects. + +If you want to use `vue-component-meta`, you can configure it in your `.storybook/main.js|ts` file: + +```ts +// .storybook/main.ts +import type { StorybookConfig } from '@storybook/vue3-vite'; + +const config: StorybookConfig = { + framework: { + name: '@storybook/vue3-vite', + options: { + docgen: 'vue-component-meta', + }, + }, +}; + +export default config; +``` + +`vue-component-meta` comes with many benefits and enables more documentation features, such as: + +### Support for multiple component types + +`vue-component-meta` supports from all types of Vue components, including functional, composition / options API components, and from `.vue`, `.ts`, `.tsx`, `.js`, and `.jsx` files. + +It also supports both default and named component exports. + +### Prop description and JSDoc tag annotations + +To provide a description for a prop, including tags, you can use JSDoc comments in your component's props definition: + +```html + + +``` + +### Events types extraction + + + +Due to technical limitations of Volar / vue language features, JSDoc descriptions for emitted events can not be extracted. + + + +To provide a type for an emitted event, you can use TypeScript types in your component's `defineEmits` call: + +```html + + +``` + +Which will generate the following controls: + +![Controls generated from events](./vue-component-meta-event-types-controls.png) + +### Slots types extraction + +The slot types are automatically extracted from your component definition and displayed in the controls panel. + +```html + + + + +``` + +The definition above will generate the following controls: + +![Controls generated from slots](./vue-component-meta-slot-types-controls.png) + +### Exposed properties and methods + +The properties and methods exposed by your component are automatically extracted and displayed in the controls panel. + +```html + + +``` + +The definition above will generate the following controls: + +![Controls generated from exposed properties and methods](./vue-component-meta-exposed-types-controls.png) + +## API + +### Options + +You can pass an options object for additional configuration if needed: + +```ts +// .storybook/main.ts +import type { StorybookConfig } from '@storybook/vue3-vite'; + +const config: StorybookConfig = { + framework: { + name: '@storybook/vue3-vite', + options: { + docgen: 'vue-component-meta', + }, + }, +}; + +export default config; +``` + +#### `docgen` + +Type: `'vue-docgen-api' | 'vue-component-meta'` + +Default: `'vue-docgen-api'` + +Choose which docgen tool to use when generating controls for your components. See [Using `vue-component-meta`](#using-vue-component-meta) for more information. diff --git a/docs/snippets/vue/vue3-vite-add-framework.js.mdx b/docs/snippets/vue/vue3-vite-add-framework.js.mdx new file mode 100644 index 000000000000..009f6f74b579 --- /dev/null +++ b/docs/snippets/vue/vue3-vite-add-framework.js.mdx @@ -0,0 +1,7 @@ +```js +// .storybook/main.js +export default { + // ... + framework: '@storybook/vue3-vite', // ๐Ÿ‘ˆ Add this +}; +``` diff --git a/docs/snippets/vue/vue3-vite-add-framework.ts.mdx b/docs/snippets/vue/vue3-vite-add-framework.ts.mdx new file mode 100644 index 000000000000..c02ed2ed0b3b --- /dev/null +++ b/docs/snippets/vue/vue3-vite-add-framework.ts.mdx @@ -0,0 +1,11 @@ +```ts +// .storybook/main.ts +import { StorybookConfig } from '@storybook/nextjs'; + +const config: StorybookConfig = { + // ... + framework: '@storybook/vue3-vite', // ๐Ÿ‘ˆ Add this +}; + +export default config; +``` diff --git a/docs/snippets/vue/vue3-vite-install.npm.js.mdx b/docs/snippets/vue/vue3-vite-install.npm.js.mdx new file mode 100644 index 000000000000..1d023d6e253c --- /dev/null +++ b/docs/snippets/vue/vue3-vite-install.npm.js.mdx @@ -0,0 +1,3 @@ +```shell +npm install --save-dev @storybook/vue3-vite +``` diff --git a/docs/snippets/vue/vue3-vite-install.pnpm.js.mdx b/docs/snippets/vue/vue3-vite-install.pnpm.js.mdx new file mode 100644 index 000000000000..3c8db13088d7 --- /dev/null +++ b/docs/snippets/vue/vue3-vite-install.pnpm.js.mdx @@ -0,0 +1,3 @@ +```shell +pnpm install --save-dev @storybook/vue3-vite +``` diff --git a/docs/snippets/vue/vue3-vite-install.yarn.js.mdx b/docs/snippets/vue/vue3-vite-install.yarn.js.mdx new file mode 100644 index 000000000000..427eb154d182 --- /dev/null +++ b/docs/snippets/vue/vue3-vite-install.yarn.js.mdx @@ -0,0 +1,3 @@ +```shell +yarn add --dev @storybook/vue3-vite +``` diff --git a/docs/toc.js b/docs/toc.js index b7ee152fb8c6..a08a9a4a767e 100644 --- a/docs/toc.js +++ b/docs/toc.js @@ -28,6 +28,11 @@ module.exports = { title: 'Next.js', type: 'link', }, + { + pathSegment: 'vue-vite', + title: 'vue-vite', + type: 'link', + }, ], }, { From 8f2a88af505e8d4421fb1448e18c6f20f69061c9 Mon Sep 17 00:00:00 2001 From: Kyle Gach Date: Wed, 28 Feb 2024 13:03:28 -0700 Subject: [PATCH 071/132] Apply suggestions from code review Co-authored-by: Lars Rickert --- docs/get-started/vue-vite.md | 47 +++++++++++++++++++++++++----------- 1 file changed, 33 insertions(+), 14 deletions(-) diff --git a/docs/get-started/vue-vite.md b/docs/get-started/vue-vite.md index 398825a0abf8..6a52f84a47d0 100644 --- a/docs/get-started/vue-vite.md +++ b/docs/get-started/vue-vite.md @@ -106,7 +106,9 @@ setup((app) => { ## Using `vue-component-meta` -[`vue-component-meta`](https://github.com/vuejs/language-tools/tree/master/packages/component-meta) is a tool that extracts metadata from Vue components. Storybook can use it to generate the [controls](../essentials/controls.md) for your stories and documentation. It's a more full-featured alternative to `vue-docgen-api` and is recommended for most projects. +[`vue-component-meta`](https://github.com/vuejs/language-tools/tree/master/packages/component-meta) is a tool that extracts metadata from Vue components which is maintained by the official Vue team. Storybook can use it to generate the [controls](../essentials/controls.md) for your stories and documentation. It's a more full-featured alternative to `vue-docgen-api` and is recommended for most projects. + +It requires Storybook >= 8. `vue-component-meta` is currently opt-in but will become the default in future versions of Storybook. If you want to use `vue-component-meta`, you can configure it in your `.storybook/main.js|ts` file: @@ -130,7 +132,7 @@ export default config; ### Support for multiple component types -`vue-component-meta` supports from all types of Vue components, including functional, composition / options API components, and from `.vue`, `.ts`, `.tsx`, `.js`, and `.jsx` files. +`vue-component-meta` supports all types of Vue components (including SFC, functional, composition / options API components) from `.vue`, `.ts`, `.tsx`, `.js`, and `.jsx` files. It also supports both default and named component exports. @@ -141,18 +143,22 @@ To provide a description for a prop, including tags, you can use JSDoc comments ```html ``` @@ -208,6 +214,19 @@ The definition above will generate the following controls: ![Controls generated from slots](./vue-component-meta-slot-types-controls.png) +If using `defineSlots`, the controls will even include the description: +```ts +defineSlots<{ + /** Example description no-bind. */ + noBind(props: {}): any; + /** Example description default. */ + default(props: { num: number }): any; + /** Example description named. */ + named(props: { str: string }): any; + /** Example description vbind. */ + vbind(props: { num: number; str: string }): any; +}>(); + ### Exposed properties and methods The properties and methods exposed by your component are automatically extracted and displayed in the controls panel. From ee11be55a4d2a109fae2bbe0a09bf25ec9329d63 Mon Sep 17 00:00:00 2001 From: Kyle Gach Date: Wed, 28 Feb 2024 14:29:39 -0700 Subject: [PATCH 072/132] Address comments - Update URL & sidebar nav - Improve snippets and update screenshots - Clarify that `docgen` API is only available in SB 8+ - Remove no descriptions limitation from events - Add limitations section --- docs/get-started/nextjs.md | 4 +- ...ue-component-meta-event-types-controls.png | Bin 78474 -> 18776 bytes ...-component-meta-exposed-types-controls.png | Bin 68047 -> 11976 bytes ...vue-component-meta-prop-types-controls.png | Bin 0 -> 15838 bytes ...vue-component-meta-slot-types-controls.png | Bin 99119 -> 28352 bytes .../get-started/{vue-vite.md => vue3-vite.md} | 109 ++++++++++-------- docs/toc.js | 4 +- 7 files changed, 65 insertions(+), 52 deletions(-) create mode 100644 docs/get-started/vue-component-meta-prop-types-controls.png rename docs/get-started/{vue-vite.md => vue3-vite.md} (74%) diff --git a/docs/get-started/nextjs.md b/docs/get-started/nextjs.md index 64e207a683b8..dc0bb08b8477 100644 --- a/docs/get-started/nextjs.md +++ b/docs/get-started/nextjs.md @@ -13,8 +13,8 @@ Storybook for Next.js is a [framework](../contribute/framework.md) that makes it ## Requirements -- Next.js >= 13.5 -- Storybook >= 7.0 +- Next.js โ‰ฅ 13.5 +- Storybook โ‰ฅ 7.0 ## Getting started diff --git a/docs/get-started/vue-component-meta-event-types-controls.png b/docs/get-started/vue-component-meta-event-types-controls.png index a25c91c37c0396975d1a0388c799ecf6496cb534..093b2da0911a0b1af9dee0f11a1f7118e08a7aa4 100644 GIT binary patch literal 18776 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 literal 78474 zcmeFZbyQT}_dkpXf+7MUgVKtWboT&K3ere-_s|^z5`ut;gdicUGz=Xh0)lim3?Usu z!%*{F)OW1U_v72|^T)HEwSK?%tTo&-_ug~PJ^SvnTumG>M*_mI9|W*GZG6g53X-^m6P|7~f~hI- z#-+qSd_mU$d$Yj<(Iv=f-pxw4BnU@tPC^#_E>U$jNu;Z4P(0%@%;p*$USTAIQ0d5=4jT+bEm zod+=9G)I3X5ct{ z7cC?lo)o%wx0>39;oH^c*x~rDa?8>`=M?EQ{$S-t|P&OOP7h#F+aH z1ZACF1})tjQS&RTx=AFr**dPGLn@#Ow1VDo$UAz5WlZvTv750}X6)u~sZ%D@U*Ejj zMYlcHf6o7SR;lbAP3ZM^3oqZWp{hyZxLD(!%PcM7_y{c??8l`DGtbxVUK{N%fBSg0 zp})*&ad8Rft&=ckdRE!?QHq`uH$lIrQg(1b+vy;D_Qcn9aZpTSB|X+i%t)Cw`Nbp~IGOodVo#2?w$=n1 zn~T1=UPvW$#S6QyuzSI=7R~-@;=6Z3!tpq5SJJM&eS2iaVqS%X#zFb4W3B3@!|)Tk zV-`a+g0@Q!6fqM;iEm%xG{9Z==d{Pt`-F$#Z;yXD4xQx@x@Frp#!ptom%ar)EGA#S zl9fhAhR!`h&v!%Xlcha{4*JL^++Hk-0ADr?y#V$tiYKD@&jZ`=F_nX$R6cFDN`r5| zV*G}QDf(XV`YkM)hYug27X3{oUez4lbJyqC3?VOhu-b2VsF{Bke$-j(C)83s3> z1aTW&9z{3%^kkIsMo9dp7h8^eSlxk@pK0uAyfN&8dzwaOz*UsKSEDk}WUfexTV`|u zqvH@g50j)xYtAjtMOS72cys8PmAK1$yZ6UR8Mz7;Oo;*68C|{I7W&Q@iQ#&Ydg0Rn zERrK>Nqx!7+RK;rZXc5dzf@{XFnY&k^Ms3*pbR}Gis6f@VImtbyHCR1PA?{qY!itQ zd2z$&Z5s|(B3B$&kqUx|$c>g8My(Ef?;dpDS_;7V>|p=4%6n38l3oB*fEk z*xw~QnG|KZ%Y)B)lac`5-qyC<#@GJ54clb6<4qe`Of?fH)$WVTM;v!c9)&-?*{`O| z{UO;obuaD-E$OSNuO;7}?5H_1Bhispkr_;q!#Z)y9WlCe+O!i)UMdH%WMcCAkqnip zEYgJimUdQ>bBT4NuPBoa!PSFv9|3AHI5+_!$%=5X5+`hsYu9N|;`l zP>WEDco^|5EC%{8mLSPlWgg`lDlE#uxf&nu#>&ZMgOsC`y>g9Z!elCBqGiTpOl8d9 z99z;SUW$;D&9coP&zXAfqc*H)_Fy-bmywqqu6mxvq0pimRHU5NpWC0aqZwPcnw6Md zBVI1KUqYhQCBZCV8#I2YJlrZ{H+T2llEV^Fryv;NFOYASPVuop=IoVc<#APTc5qbi zBjchkm=Q{HiP^PgrHd?GWr@^Ux0uzL{fAi!oU~Y%Wt?e+WAz>)GNUZ>tWT_Dp^Q*3 zD4p|lmwV2RE+j4#Yd2l))LgBpbry7P-GlCdRttvnM!eD#dd-*VRuFxNew2ZM1-@zV z*R+i1!HC)iqxr?;XB#@f0ps+F?(Y>o5ToA_GXVcWQbqs`s-zh-uRt6{LQf;?cG zf{Y7Na>5-N?0pwbYt8O+W^2Z2){i~o?-KeXG*Z`c8XJ@%ncs3FoFyC*=Nk7RE`*s< zi$M#ixu8|9Szp3avZxiW39q<2;XaXHW?AlGYi-q0DQw`?6KPc0YZs#%GNtZ?OHZNBrH-(Et-jTJ-CGR_Ju&h=^Km!)5hI8q2t8)$Z z0erFVw%uJ%8;;mn!fQiLUN3b|w2;o$ZiOE;U1hl{d9{a7_of?dH+h_F0@RzX!BN*ab0bLw&m3)ZWfJZLB0XLZwR@Ioex>g&W_ zGG+Q|(Up1cbFQ}0eWV!2tA)g;ar+LE-@*vTu8nn9eH^SC~#A9vuir*IU zJy@Sd|DB&(%x?A$WuM43-}Nz@G7rQe1hXz6FDNdkB}l)*zEbDx>uS#HRN6{fn~gCu z*v2QQt3^5c{Y%7P{5OZ!{>|XzMhDR7scS!0xAIx)e=M zZ+OAp(8eCbdc5J@RDoA|z(daJ&Uo>vC@ttm=vkRi-ir2HdO-@3PFZ56+jrOB=Zp8; zkfzu?e!J~t8>{uyaA?HJ(8W*ALe9KE+}1YPbE?9#N>5qD(PTTCR9ZNyf+vAnm8+iw zC(7UWwK1#ji<5Id(nM5hwrS>uj?D}8-Eo4vk$372FI2KJWx%SF_O zt)&KasUrFFg>&^ojlI!c>+Q9#yxP+r8wz~QPYR8N+)uxrKo1EiuYo`M<|CVr2KV__ zcek3uSgTlR^dn#uKD(#`3l3XH>@2iv4t#enJ>wk;l@Go2%<*y`Ubxxb9#o7I zjy8aCPS|6yX<3GqcIm20Y3R_6PwdUO!_smC&@qY@F=GaH4F&&v=_G#cZeM_ ztg5_Fxr8ddgNvG)M7=cln8$o%eoFkIaxrQ$p|O1ffHBlA89(Fp@C>FzLy>=-`@hp zAF))`aMqA}B47-$Wid2?7@4xT+uC1@gC^uI05ok)oeinnZEftF1l)!1eZNBhXkVOW zy+`%^7H4bWdm3_zRN@dvQz{-7HWs#f;A>P=R6>p>W&+9*Qa`%`zl85uI6K=5u(G_pX1t^q*ayI+;3(Lu`RLoxy*-ub-X& ze(`5VA=Znf|BVzs==}XGKxptaA=W=%8u*%7rBW*J9?2{v6jXsDz-1SoOZ>ne`X9%O zb{y)Z$dMKrnkd?12{BdoOY2iub?T;PSX)>a7#Np`RHZg2shtqQjwWhaZ_Um+`nfm{ z+v>U9-tr7}PO4>R$7V0m7jTi<-HOe^4hVR*B?1pzTAD3v!epI1sYNX9@0@qLcYCHX z9=dfS-z}|ha56r=EBXxW5;_JpKGiQ9Tz7jVi_@+W#r)Gv-~0RPh!%fhMgPrs_*A|5 z&kV%MxXk`x(w~(X2!rdz41r;*Q@Tjh7ID9HNNuOnW;2p+``2^-%X1Q^(9T z7QV1_2pk+?R=NM&4W68+=d&@y<@hakuo41?4kube_i2-KP=4npFfNasZ{8^QmDIRA)K7m?}ez3KSwsl zlsDT&5oAy&I^Ff$CH6OQAShgYO7<`Iz-Un_MRb`3%sKLR5c68(C}S&*|E>B_88k zCwc>M{(aFIQdw(-F!r-UKZTsPoaT$Q<>MdoG7)5+k7R2{&35Ja=kvLYni-MDhv)0& z{Rb0vQ)UyTM(F$WTkUy8S@7xe+Pxk+RP3CghYF2e)$!-01DU*{3M-W|!38Kb7rEmo zLAkNW%8~Ivv7xy2pX9Of4}Kp|ggE3cAW|)JIU*r{pn*TWZF=;4KC;`F--{=l^-qJN zw-ICUzJ?+=^Ze{2t7jeg0XloUR=y&)vct2qWUmb#rQ~$A@m!9U-fhyP_sTG@)CKn~ z_l`TBMDUpXw7hy}F~1MdW*Vtl$h@89WQ)=oKne_iBc(rM)sht+a#i@kz~)qyEg znTRQY-B{|l3$dBIF&>v>8+YaUvOX!VXc{Mu(CM=N05|N&G*Q5IoQ&P3s_}TmT7S$h za<$@V7Jv1kRi1792&0DLFx!*w3RjDjO10Os%u_SH2@?nXe4bL9j{Io9h}-MNU*?%W zf+)X6aeo+N_CEN$WSpRGf4G^;tTQ41&O|gr;xcQzf{){2-G0Ch)blolu;-H+#5tB# z$W7kX#muD4adhVErzavPIbuCWO}z~5O1qVic-_fdS8Y33-Hk_r~~nV%82ZuOh&lQwxDzHq_v&T9S^Ur?nTMF|^QA=fG1g}lCk zrzaqnoao~Ay4-AQZY#cjbVR>r&9<~Jc!lut!NeSiRT^z6$EZGo842Qh!fS z)!gdZ01j(J!kYN{kkf4b+H*0>Ak&bnA#jZmN!=TkjU^H%Fze{uKup6yWn!!V%w1$< z+v3HROY6dDZwx4?9Ou}G;WivoMXtdqWJlo6vWc(ubMDYkyi9feTw=MB6=(Ia#!?O& z8lR*ix1RX;hjfQyx)Nnd2i>cJeAnEVi+gHj- z`x%*FIs%JrO{7ygR{QeMK+L&djnfTCN57t(WBCHR7Vi%ena%I}epv6z@H^8EJGmn{ z=Fv*tpChvW)yO#oj5;`i4-knQKW>O@xpMu{Qi{v5PywPzOQU$E=`}Q^`~KEMzSk># z)PY;M__SMUPYyFLJfCNJ@Ka_bT;2zynfXC;*JV7!p^IoFxUW?9l($l{*uZXqN&5Sq zFuN+Dj;*e9mdE9|H(FQjfB9faaP712EdSz*1!*(p0q{Yy%E~s~c`|F|aXVx7*}=GR zvsH+1g#c~K?O*&J=nMd!myrOPVCG9;XyJNTn=PR`#UI=15VWW+#q$e$QXoXsIso&o;{*hvP>I^?Ch5MD^X?67TPh3xCtjVI>Q6+*`HSm9N*d;cXEcq6MGmw#E!TWH!ge$hg#aN_NY09ER%MrKD)b~Km^owj9Ink;g$d&T5JQo+a) zySnXQ%PE&(J7>cDF(1^SU%%5^-O8Yvg$_i+1l`WAs!a#o4~Fe+z|>h^deq_ z`x{m1!+ck~mfqb7jA(!78-KFhQz!#5$GfHPcNW3rIGF1#yq#>@qRfj!pcm>zq7-c2 zmEC&yAt%*?7V*(==M4ix0QUBo?L4^gi#OA5nX^mkz6tAJpgU= zq%7L_Qm5l|ra$b{G=Zp#x#zwA4VKbg6LlwAUSy&9R0}#Px;~PM@MEhjBun{XeyHwc zcBmKMR!BIa51E2mx+;{<)@w8dJna5KuLLiD4_x9~+L0_og*E3DTr{;&brUzVbGmp= zX9OjbTFpiEMC<&ND1G;@re#ybb{ZmI z=FLvN!i5W4Hl*uE;nu#$yjx=ai|ssPZb8@*Z)82-ygq(#L>Kx?Tv>0wP#@M13X)-V z`5&G)l+u6r3eNfKpnHC<`>a-2_A5b4yft{ei3mq&GAA7p5nnZR&GJ~D+kA7y;ses^ zTI{;sV|Wi>gpvtd4LPwL(XAAz)80vbx_LNgSUTzI3(#cAFSHIt`K5>ndwOSh%Wl;&`( zp~`GF%deOovGI8g?0h)2?KL`&KbWGkZCIggu{d88t&3&b?BdoE6Qn=|X|pw@fr z*E8Ln8ZE3Sa@aXwU4UI5Q?ImBAI{P>O^Zy!d=@KGqkOLRbq!J%jY@tAn-8JzRy=23%)LG9~!>@{3c9xh52k#|vNFJWDM_Z~jS zr`{%kR7&JwC>i-qriHZ3IdUBZaoToc`9wkSJG+Ey zFK^xriIL~4P|Cw9TReXJliTSoxP5NAnSV)NQSkXrQ(403IKol={3yr68XZ!{&H^c6 zA0}W1F;z~Mj`im6j42@A`q4e0ICbf12+vOllAITOGKmTWUDhMzFU?Jf6gVvw3RQe! z5pK|^Uv@%;XU6K(?3QD3wUmDQ-lMu@r8f}Y`Dap)d&IlmH*=-^i9_%d%-{LwZSODl~R) z#Bpvj5c7WV5^Gb$8|L?^3W@5vjQ40Qzg&%FT)Eg_uKDrG@cR39S4~3SK2Oo=<|O}- z^VMK)WiA>}m-P3YV7Y*W-p4ibI432Vn~<+CH-)#1sEe<)K`vQmq+S7Hh4qQ4X|qvzDlAr)O>sJY6ib&^$lTFU!n5;Z1#E6)VEf3vfZt zo44tbUrU+$s7k&lbiQyecW2#;eZL;E_JqvaMqr~$;9yF=SfuU|S~~T1Zo(Z_&_8KE zN7_3V;QL`^a9y8nfx3%td_bL=SM*Lk9nsOY9;36H_FhZE%EkuWqM_J=pS6lC=wh_M z+jnq3<`T{ZW6#=Fx0q>SZw10en5WPl09@_TT!KgqLe3$~-(btV^XqHzP`vj=UE3wL zZYbk+BnRD@PX+W08(lAYsxIng>)wWV!&|qnuN2yRnZ*NNCU2Na z5ez4${vGL1AX=c|RyVjE5s1eurP7opX&ZbAJy{}c)@7hiGd!=))Y`hePN$M<(pRVr zr3L~;f!5ROc2=!dpqxF0<+n~2)~79?ZEA0-0ikS~Az5EgF)D=T*IKUj#-e_9dA>p0 zn%OWu*-a+(_#4)tDrvzT#d>SpXgb8J+R`DrEQ~$`} zgqNMVaWxO@fIpAIqJ|4^Ce)=a09F9Aht%MzC*_LE{Iy zWVVUG$Q>SI%vLjqSmCQI!*J#4ksV3z=eY9xXPtFg_kDT<*Y>1{x1uDD4{}6$)+7eL z_Br}Lybun_;s$mBmi$*IwG-*|`L#EHfLB)rR zc;Dyd4}RGYPb+T>=rjJ3IjA~rWk;(|xKB`ckA*QQ(!g*AEoDi>miwQWkA)rJKgHWiwq+z~!2HEWR0wPu%L z%%$XH_?m51#Ey$@)5h(e0NG-c=yO7OFrr`Ro&8R9NM~xqxJ(|VfO9cb;)K9qKzRSI zW;(cCIv7{BmBPjS*yAA1ge!=M=Gbo9u-0~Wb|-4t*dCB3nI%QA6p_pX0T->f?Bo>R z)U2cM#jeyAI!VNvDo0k{x?r`u<~%x)E}bsejCC1kvPS#+eYpdYGGEozo)Q< zR-ZO;OMn*#U&4cJO{8Smnk_LsvXYTB&Y~UJ4TmQyOuMe-i!{}nBYKJredfQ*BoXw5 zBo1x!#!{csXPUA!T3=rj;)m_D^!TyZ#@4%lXg)hh628{9sjv)7V#Spea*tZ%&d_;> ziIc9`VG+iY*vBkW7hBri&bXwD-@G-4J3O!z?5@I_6y`#diVIQXKIGAo<$czUx0Ios zZX9)-*74j(uz4sP!98rO8r1H{7Z<)B&%NS~^08S~^mu&u3`REoV`et3JBCS7Xv#(@}Bw^ZW-&=oY<(;ydP4 zjB!0GEet*+l+%jzfj(l0R_%Ichl?z-reIc9v&F2aO)KF{d$`}`jfLqH(1;7Pi z24X$yK_x1YH<=P($4(99H^`Ynn_iM0<)k>Mxn}q%`wsTmIPS^n=xp&^2fZW_7J$f9 zO)jZB=`1C?NRhCm`GIRMj5Y>ovV(##Q0)nxW?29)QP;H_9oh=?>hw7$#>pj{^sw69 zLg%$2KkdTtIeX_r`z^7uX*-*e^ta#NKJkS{x=wknEO552$&8C3DwM`jL&Z0fCT<0( z>$%$fqLnfx3qggj6(E~TtIO7S<`YdRZ=k}5E)Y|$(rv2V zMRW&Y=jB=Hp~AI_X~*z7obq9ts#C~g>mu#;5!-steVKT@BQYHN7O)O7CN&FozER>0 zH5_4Za_V~8kj-2{kV>rMZ5hU*lfGVc=DJdrdaerAIp02*fGp{?KnWxHA28Rha|B>w zhAR9(njr0LQ=JQ(+rELYRE%3vC^AcwrbY$ zWBjDhX%lC{8luBNIE&K7Gt(mQ)WZ7BV{gComLS^-yXvGsiw&yd=W5>}Iwx$v&r`G; z=CG6UL%b_1WpO?JrV&E!;k<#E->ltyUH^eSO%jk@TAceUoYrHxd{%?Ydr@>LZCYIJ z4D~`r5}s%Kyk^?xfTQ{v72#?7t<8Ckp-gM>#WlKQdmR!U=QbM`(#SUuMW5S^0l{*6 zpowrhk{d$bCdy&^3m~k;MOt+a{eHdKUXOwmXvzw zPLoPJ-=id!kW2!!%$BK1IO2;Np2-o0sOXzHgPeE_88uk*eSfX zMXfT44H$D>PH{h8pd|4|QsoWRy4iTdqXXk3S=O9^9sxSa2+`R?)`qkL&uiWtDG$hlBl)@5;&n?A6GkScx<@7Hu} z(3{xn7vKY$|1m+rfI%bh#`?Kobu1USTzMemh<3ZqJ3j9ksM)pXxTPFfF>e}-{W4CL z%bKDqN!s!@6W_`pr!p5W#ez!eBr_0+kw@BZQ#Y`l&ng@)X7ph`<=3$PGPX2SGdpg& zL|(Sw#tP~XnQw{021%$VC^=)ravt@4#ia1vD*`<4+K<`AeOK0Uuz945>#A=~O%&92 zk0WKD?mA8>H`pa588lAnIB^p*RUwD+g#_AN86A}F>+<5>46nnw z@`=FGPaaBPue{keV}3-n6JY3))|doV=LeTgvMwRqR7Cs^KMyZTqya{lLx~4q$1C(v z8dkpv#8fyt5m`x>g{AgvPSv^{#Le9CD6PyzwR$0BM|Ay+*%L)xS*#V}&&}~A;(D(Y zyg<5koM=x(+fY%M2%W8$l`kfC?0%=H=-D+@Oq@AdXXt%taiF(eSGO6_6KK+RC7$1*s_y4aI2UVKS)sD#Ntalk0PB> z^4)4;9Du{&sYlwLa}KR0%yfHQOGF|-;4Ww2V_yEdsGl68v9fe{ZZqz>RNP z?ML|_Wy`vFAEuREZRVb-hS#zQ$Dd6oy&;OzXYsLw`}EIb#k0^ZFu$rh-3fIz9Sw5{kJZS z_;&-{6H4`lS@&8?S!>VAXtCz+N=)jw&#>ZUS&p5zPQ=IwV}$L~e>V*L&=(BExRNRT z{nI5ltNW}(x38$P`$S8E9%E4+?dMmw5rsWQnnUm7U#fMNy)To`dVb>uImdm!Ww6!W z@-3e=DPnO!M3wmQUJm%}NbN!e{2Om7&zO4#)D=Xb;rLa|GI~1P1cHLS@%1@D^l#-` zKd1Lvudp6>iBI00#TI-QGqoP3`0$N|lv}NBg^Vm~xvJ+`1n&+hz}F`_0yH=x*Y61N z#R6gtz-ToToY|pYtn#uL5DiHbo#$~Nx!^BgAMRR)dL>t<8l6aigXdfq2-V|lDOsl4 zxv-9$tAw;B%=q5fEwr2&$hlqCD!y8Wea8lGvfaYeQ3k<9ngMHSY10D6DNUT4EU?Ma zl`V)Lqcy+fY+a#&SoaLpcMLsO(BH9`ssXSKq4vi*U~@m9pw_^^|$LP zx71aiu@HBtVd9)0?r~m3MI%2VeO_Q&6r#3W2KLs$ExK;-7y!dL+40!UFf5+Az=$t^ zC2wDERG7g-s0q;&W3y{`A^DCeDF%)mYAU&$1!Qy%#9HHryEa3bCt4-Z_FKo2#-dCh z7Q{3S(k)F*F9_+f$SdGHM24eA4GQSVVpN46-8QiCpB{DTY<2I`ZGq;*<9>SX}7D_e#RPH(FyL| z=J$Luz29i8AQTI+D34WtqCajORWXsv?MIL9Ld1j}ee~J=07*R9z!x8g$quV#AvBuK zCWXA&CqFasTuOE`a&ExHG1A_qqI-QTxqLU9o2f5TQ-~f&0RBFU^9|r-q^*X|OKmPD z*(M%L8XpeQ;Sh5@y=QWGme1|KbNL{9wFP$qfL%FK_ovpGPk=Z*_tOF%=FgW}$&ksn zc;mxv%FU(33tL1bwRgoPyN-f^v;kr8o`KjTmlv<#FafpM{@8^5NuLCSYiOeQO;WoJ zA0oi1M;;LFvLR%y61KySTPc%*aY?mEqh8G;iFNzeT{Dd8B8cAyl*Sr}MfCnqAi0d+ zpY)UG!TMWQ_yVEjgl)w~m!U!Xx7A1%;0#f}V?%E>A9?Yul))=r=3xwGFSpj_iT`6Gj(t`KeGFIH&CZAf% z6sfyzHyn&xX8{7KsljQm1n0g6{s|G}mDJYV#Nf#A<8%NIi#|eqE3D1TDy^g-x-h<$ zh0vKXaXb$EzxzI=c_>r zC2drii-_|=oH*5>{9)e;&|A8a(wj*S`_Oy4$CB>i)(V6Q5U_-T@aAY;kPvO>mSP}f zB=Z6oLadc~2d*{&0B`a-;#j=_s$a93sQ-=Q*TA`uo5uVAx9U1MK0 zo1L^fOckc-kbw$qy3yr*rQ$YI=y6Ob={MeKXIam6gkKMwiD{TX&4C(m;Xz~!hhX4b zqe;DxyrO9h7+L@etVzk5GK=B1H|R6*TYQCXOObMo?W>AM5BtW4FXRPaD$zCMO*yaG zdaR*Ixu2K(8)AWR{=4N*7)(0gZdon5tfxw zN}Xs0JK%|4^gTfWsDS{aphV*!rgr1CYsW*7g`qz^a8e44ZRN%D%~T!DbMmbE2j|D?_ZB)nMB5-{p( zU04mQrMYGVYQ45io4@5T;~noXNV9wGe+NPOV4lL8xJtF}8E4fta?ElmKsyTqteYe21AA zgGy-#Wgpp`AmWLz-n}|dJc|sHqLKmsEA2?8- zMDTuD!0W*>(Ph}{vE%9a3hzCd0Ck;7#bd}aSDPFdoCU_=YK`kzFLEE+gCjX>h_o!; z7b4+9n`5{Y{0t6GmQP$`yyLn)<(CKWYZq#`K_A{~6=K&`xX5t2z`8@|!;nA2IG50O z@3Ha17Z#np9E$EYbTl7U48Os4itJA0B4(gbl$j$zKB!mBDsQ_n^!72we3o8i2q*(}=3ZEJBJ^@|TErB9P?7x2BL z6uFD1)C{BE=Foh~z)Cz)b@|Hm1nSC<`-uua;tBWwrY}#{fo+2g1f$Y29AJzo2n&kf3bX3&VfQ0ef)9r}6K4>u3!mun29BnyD6 zZ$x|-d(O1L&u-@ma>gGz;XjA(Q~<6cKiF#jm{K(9>gmG!kO4xJ=L3C|V+T`=>$GJE z&qN&2cNgP-j^W>ZAIPYF+g)Ky^PfY1cc%W^h?n{%f`uD~C`PhGJq;X!w203S! zZD{kOSF;6veajEozx)KqTuxrG5mfu{MEh&@UKxNMY5^a9Mmzs= z4Szj=Kn#%RZZ0qp8T(_3zlQivIzW|yEbLf=kH4VcpU?g;DgXZ=r3Hruo6};aTA`H7 zZ@J?fv&MO)|J@J3-fAX()p~-xYqXv_y-34 zbV^{s!qq#zvTF{R7*VUKJDm2Ca}5HL{Tk%o)c>Y}#NUI^!ZtLm`gpg3m>jaARh&k4 zpB|4mWN;8_l=1_I`_H}bH&XRZV5d{$QjXMq7T7p zZz>_gZJqFJ%}@P@6@0(c87|tCChFlW9~^EQzXlo*7%-2w9LVlcDyC9=jw3Ko6#N_U zB-%=3@!+~*$}nI>xFg#-cH0L8JM1Z#LO+S}b17aYPQ{dJ+BT~B{i0GZNP;hgZO?HY za0iEP@7S{!@uj58vrmtKYo7p7%nqDRE9lJBhk=1ix9m)}ocj1|IlrPZO+LNfuwJgQ z|K=1(2FFdGet%_(lX)^j+c$GTRLq0VEbcPq!mI$T)lP3s-N|OH$H$q7?U??|uPRCT zCini7F288x()okyJu_R5nU$@})39$~6LWz(bhDql<#6guis^sjmb2h=aShv>6^h^g2j2dEsSM+bg0~<7WEh^~!Lzap%tW|~ELnpb5||LgGmuYs5g z!`H$T#hTc}nznZY)*SfoK-YDx4B~2XTbrDo{A!RtHc^_T|65KKPt(Cs@5NrRGpi}8 zHeG0zv)4%uy*8s{+bPDI?ZGNv}D)h^e@z@Sq3$q--24b2` zY`^aE;{gD2-_u|-nMp6l7weM|YwF?f|KIilJWcGIw+e3EnwJbsJGvgWW1rkVctchl zoBP`Ds+W4lFv1KPXK0RxwV3dk63!|`iw#`yjDJI`-WP!F^--b1K&(8P@ZwBaviV`qscy5Es6~!>H!%$&%1V)yP z0ok~6zfk~}&|MgN*);HH{qH?dq_~0B7*KP@ZEx_K=|s~k0aGViw_U|0=+8Xw|GuBU zhr49}E9Tf42c$~+zfoWsiath|I3FVhe{C0i*9HCpKoM9jxFi5`NXqJO+Tp)#F41J5 zJWe$gfS#Qsf&B~ z(b>r%t5nh%({<2ljpDdH08>B2VIH)ZYNhZJl1t&>XRZPAs5i=ott#}`=T~x49~*y( zWRO}~c8Z>^AE;R?6qI(!=pXI0A8b>y+)LP@Z^(r+SB#PsNlX4C zp9vIQa85M>SekjN7t54)2lK_!GNObyTvqzC#%f~d6y)Ks(;Y6KqefZIaBV4rH0QjvMWEsTAqeC*~Xf#^`u>!Rd#h#Z;VHLSD7?5O_nE)kgh@ z9`h9(qsCfaKeyv0LR9BS$*#O$`H>n5h}8`&h}7NdO5mr))$?3|!W&L_YB!9e_%-k$ z2Y6(B#R)^pPHP1KT+LE#lCgqI2gHEbA&0tda(M+6T1{3+cOVJsaN12jY(KsO%0$NQ z(4Xn8EVKnV>J{m3$~l}Yt9umFG;+RE!!;L6Q0{RC+KBgHivFUI@M@au(99F^#S2-- zTseBrwysaA-1BE$)UVWBuOhI#_mAecd2m1yBWT3Bj*rJ7sjS%%JmbaNaoX$)(b5!h z3a4vdp>Sf@=(3?RqZ+67(2n?ivg;(fUz1P8wE{Aa`3T^R5#S zxSyZrQMB|n)P`faFJHA`!WSz^S{hP-%;^xb9 zc|~WE(=DG?a#H&30x`wB=H+;Emh|1h>gS)AL{h;VHX791%Pe;RC~1=rr0d-0JTn5* z8zXs`Z{mxA17xgNeTqMrVBKHtqn5JHs>i^gaNla&iw~h_KV%G`4aCAL+%Wc_dY4y| zK|jL#qfqG=YC&`f03UL}2wM`$ah!7#1B1Bggpd*q)=uN&;z+(9q1sDRjn^yw_+J3O zk_2f?R6qfig=dvqAZE$eYFuKdX)e`49&-R@$#m-Z`jTbmD7yzE2E0v+dO5yaMvq%N84ad3k4LNnJk~II0LXv*^}j(!^=p`z|&n9XqlX%1|V( z3yOI*zu@LSxQ7N%@;9Y819xdO@F!9R>>E$9iJH&fP=0K6cQVbu<$a=UTW#u8Mk?or zs6Xsq5IHqW+&h>U)7}#b6R%8A^g z_1cxtF|(wFsVC3Nf9B=$c`AvB75sNfcAH1N9*SQwMAMOHCyO zJsaifH9OKGG8d`^BIhd#D?kQ)9Bbv*FQhrB z^F!DM0MBlvrI&}&rFe5p`Sb`Q^DP+W1mWkd(+?$@YJTG=;RC?q5DaTq7}ykpY&!S@ zg$)P9AJlvFR*J=8vB5XUNn*yK0Au-$0`b3XINZnWxK#x8ma@tGV3Kpnx0Rd$9ZS4a zw6Vcy^r_e#179p0prSGw$V{r)Tg@w4tnIUXZ)bVzH8Als9Md#)XA8(oj;S=jAGiTt zP8+0K>lgcH3`bN2cs{ugonTvkK;RO$&j#F1O?@9Qs;7;G^Cf~bzVLKA%2?&Y(r4iT z01Eil)Q9;H$g3LXfB_=OkC0COiO31^=}Pif#GtF2m|GAVP_YEm*oHzkTfuQPE^BHN zMMefY-@bap6RPCMchwXxr#5WwUk=m!6Pf?-BBl2c@PY{*XI#Z$(!lppevV`0?pv;k zKN0qWhp$}lZ~}M6i`1rITx%n%{mdl027ckg)7|p0v*UePIN!{(YO6%pU!1C}4QcZC z54>V(7#u_@Z^xy_V=+qfP{{*G#>rZPRNd`*$IqDxO$!7{Pdv;$cl1#*;Y_8Ew0z2k z25tgX-ym%pQ3{URB8Cq=*GpOl7>gQSBi4@B3gUqZwxl^l?|*jR)1m=uj{3C}A;_Yb z>R|CA@&Q;jbK%_M)fMj)eRK87lL5=lvG6k*E9}(qc%jJmskV>Mx5$twClx?`eq0c# zJe;;1WAavf+J2=Ah{lrR37^^n(KM``A?9U+Mu_jp#9k`uymGa-G_5VnGG5p9ZN@Xn zg?80{biUH;zPm^p=y)Jigwezxuz`xkKTiTySbbmYr)BnxfzO&a=y0K}PlJFp{jrOi z-%kv<7-CnqlD!AS)H5-G%t@a+!e&oA_xhvDroTBC{~tq4y1_6WGcypn1FQQg#c6sy`STb56yR4LHgL(G9|XjbQy$=fn9BA(Em|jt z|KshzNUN$dS<%M3)PzhH=NLF3E{O4se;EJb(qQ!k26GiiVE-4r`xhMjzZ!e?cV*a` ze)-n&eWC97Lc`dHZaN@fo^QN4r(U|7>@5u-Fa9@J0IYs`Yo{HPEjCtm)?sDF^1*w&Fc*AdtqE&2& zP0;!ca!RPizTfig+U0DMaW^t0GZOv#YCoNvCkFmUsF_5}$;O@=-w)}nDW1wS%TZK~ z+%Co*g;zf*Ju#{Qehftov%O2qGXr(rjKgn}eRaaF>6X}-gkfK2VQnm8{k6C*HBe@hfy6e}1P{U>)@o2k?KBw<%fe7XW=y@p);57zZj=QEG0o4}BAGBTZ_e_o>g*EB_W;;B;6_dUUP|jw@SNNSG~i`E`t>O9_(ktHv4AqJnqH@BP@CH7UG`+6P8p)uG@2x{sBFiX3Z73N=uPMGiuRGzuZFW-NMf zwG_c?*xGKdoj4a=3Dc3=PtRU8eLQ)@HfHU;*U-+8$NTcH-D-~~xFOD-)}m}_WFfZo zp{a4Y6L(*jvdB=NmE1Fi8V-ioD%1lK5GArxp1){)te7EHM zcYMyI8f;|O?eh(=BJiYMTW5r^X6uJPJUF*>;ofo&*ics1a-JWka?D>zQTppH7qJu& z3h($QRpS?Fy)Wj4W_KZ3AuHyCMZkU9QEajaJ;){=ELAyumRmcPRr>m`8@gZEz@52p zrNnPKfn!c{IDSWR#P~v^a|9vS8)prq{V$pmf=CDDB^jbODo@K+C=~zZSgPPysEOQF z3E&2ggps+j=fQ;;d(SCUFmr?_D~?AcC6*s>KN`szcSU4L;CN)rY%pL;1D!OCx3bT# zbesAdR5O<&#`|Drr<(w@W;N3>U)yA<=YfgOdYLp5q@q}hx&xFKz&J5q8bDlNuG#vw zwYLy!m3|fVS}MMZD(`w_dzT3k!bPjnF4LmJhVinsyB*xXqz8Y^Tnid7mKaev#KQ-~Y{93<0+|ZbRRh{7uG)hU*4MwOod1Yi z_VQ=!6h$uJ@3m)pD0j5+HGd?Ibr`b`RR1!Qtux9;>^3uOW{=!(gTmjS_OF6%VcEy% zXzm`}qr^eotm zmRgMS5a7-A0MJ3Qj?=;9V%A%qr^S)jM!e7r;xgpA@``zTW6P{4aqJn`rH1e2mQ9dr z*`0B~3w|xp|A&wnKL(5~3n`s~QLobY>=Oeq8klg6~2yEUj?Jdi$zsOd&ezNjDwr_M1 z%1BDg;938U9$nof6FK@GeoLlzp&JxR5dxq?DP1RfVHtHdy!tvS7+t zAK{_653!3ig(s#}O?cUaL-W|4S^lvJsMsm>H?xh=)qt)pd{2^*o6n+lG`*Cwk-tRw zW-fuy@@TP<%bcgH|KF4#d#J$AS$s21+XbFXm-prP9b_)h5e}R!i-r~iJAixP$gZ38 zJdAXo+HssE-sZ>lCp2x6r{wFki`u2jFtA^=7p&LNr#!wH*Az&aD9g7#hu3dewWbMZ zF<~>F-=Ap|7aw@z{#T*O#eivo;=isPCP|}>y(-Xc3!_Jwp(_1nmroE1+|D;HwS(otdV{OX6VNX?#EX;Xb~I77C9i1$8O zb+nr<7>~wURj|Y#)~IRy5YhcH6l)omGN0VXu^1m|*{Ln(Uj#RdP225?-cMHN)#E*n z;)S|YZZE|4FT`5LfZ94|VmU8j0S(*m@QDaAL0p#w@_ZaOpj0peJ9p)Tx=){)i9)v_ zi)k0YZ@d;`B_-1;wGqkMVe4h1obeuA(eN#nVeQCT$6iXfHGswJvtZLoMB?-WHU}c% za(H+V6?eoZ9s%p=bPUXBtIz4>ja$%cbqy?=tnA%2Y3hi!sJOd|T($FrkoA;GMh>KC z3=dR^mO~2cV}Gdvrysv7CRjf}6TJ_$bI7+-^taP0+GJmhx0M+)@0V83VWVbFL5yiw z*05;7e27a8QeTLt)(KCUZwjnXtM5z_8+z2x^D+C33?I>&E$Ozi%vQ zqk%5o443HrXcCvB*|;h+@5@<6|A_i!)hTnH(C!JYdRK2QUYT#ekR7g6aCbs9WuV# zUn&g2HobG%%>M;!JzzMXRiJBlz`BS;pmDcFY?`8vS|@oN7#y^x_DE$4562ynO}b)Xa4G+r0&MRU1g=~~yU9=X z9F6>e>ekOdKJie)&ildJj4<;o{4m?8RevbrP;%U1o$^(>)a_VGf5m)d=`7x}C|OeI zZfDb{BE5#;A`65=Yxv`g)0~4muFbH=)#>Sj?wi$!yqt4W@0^nvROn;14qlCNb3Glt zofe8@)D{$zdw!~=rs3ve)oKTud}Q#Q`OpwbzxH^1+J~I!8;qH{^#lr-hoQ23EQ1yv z!Qb9tiH{bQOTf7{#O#h3VVYKXX0ck@N&Htc6$@V`^LlE-4&QSoS*};wCm+s6>Ue}p zHL-h~xyh&57-Z1q9}LsnWOYBx?TF%NAFY1Ta4m#QmV`znFK)WKF}~}8OT8k-122Q} z3la(70nB(AXK@Jj1Y>i#&$a6gn^P37hwGsuBdQf+C&}UT8m!YY?o;thts2q}B-~Cd zXEw2XI_|se>LPqKY9B8dU=86O#47r(pCm6}Z8Ay(m~t~1MZIEXZuE%%t`au+4#8{r zi=V?t&E$WGhFv0G4-L;AF~PkfD0oGd&64hL`jB)NZj$%LO(q8YevuX!@A8zdojc<;W<8M}oic~-A zD3*|SIZeQE+?b$2MaM1lyxz^!J#1&l|Ge`aORC1Ok+9AoDZ5+*gT{v1`fjONWS4x# z0blraH|6(7IQ3pPQHx!HR9*4(CqR<(x50Xp!}bhxq;OtA38t|o+X&++G>?8szKh23 z_~L^}*x#c~S;lOP+VAf{iv^MI0lEBI0s&%~E4!>x#vVD)U5t9D);5k%MxR>H6y= zTub*Ax~0)moy!T*ZwvY_oGZTCxQu7PFNaOu zc@Aqw>+29Q_1{{uyK*+R{j)hu=JeQM1$8~8|Ms5yETm#NoycG~57uG#_0@cFH(z;d z^Y`y99VY#$`mMJQpx<-_d~Z|g4}6$S9!~G4-CG~l8OqUGHRtl^x=*9{B?-F8s2UWr zI!s*431^Asa4nlGzxMR~brSQ8BzEhWHy`gYEAu{6;5Jr>b(~fwZ!Du#!6#ar_9a)Z zYE4_!@vD__*9v*`CJWDhs<4gg3?Sj54dm8V>Pq;OKl4m)qTNQL!p7m$RWh=zPQZJ8 z6^uD*D$_xyM;R&zk;dyf)a2`W^5C_Fjs(g^e|%fk-qkN=v{%>0O4}J+3nUEg_T(o* zS?qsy|D;|T-v){2atJ%#Um4p!^MYj7xZ7_lY8nqFzk6nOTw+V& z+VSibr||RbAC0N{z9BYNX@1EfoQ?Sji5U=1i?poV&^98TyGJhGlbH= z8(lK;yRdZ#hR}z)x8k7>1&^JlYO{ulJFgGrKwctJ><<7H;5q+|8h$Lx3JRaOmFhb(y0;H8N&x00@+ zT6C(Hh0tr1jSPp=DnA><${HO`IG2js^D{r^I6KT*1Sh~ zc0Z^8l1@9Qcg~5T`Q>ZZix5r-w&=mqLSv ziS}5vz;-c_H;rolwtpAOt&K`f-Xw@+7y=~^Ng6RT^SUL;#2ZjMSS zdz=(%xpz-GwzteOjt(OwwBl^j<47Qe)oS)WqSM(nP3($*vKQpWUB*izjG+picff@Y z3-hs>ra1x-3M_>>^$^ z`biAss8NFC=KsY`i-8#Xuu;{~zbJu*b zOd6E5`d@NfIwlOw9HcV_4pNELYKk0juo+oYK1HilWhb*!q)o!6y#Rx!Yh`%kyA`-a zFDar0D(6z&Qy*4NwbrXx$;w_^O+B*(^R(hMmD}Mrs!7i>^l9HNRvre~C%V0KJWq6e z+*j6@|Vg7^JruZrcmchB&0)JAEwWrII zyO3Wpf8I>Wl?u#x*XIl=cO}cpZIQ(q7$JCQNo&DNyJdZ`^4JJmN=e3;*Ih zPmJ3b!UZ!mj??1%`0qJY3)~v9)T*6)CtkKGlriJ(KOfa5;S=CJ+G-G@*rXaRo>vO|Zd?*_I^!TdAPwGUeeRq^exyRZi7Sq~x$L~I0 zA$sVHi>h#;(fxEj8;1yk;Gtdv`7gJR5rE{w`@s8@l2b12+HyB`Z)!I*jTRY5+IcES zKZ368Ejv_P!?L?~6-Th#{Pbfyr+|v0`^?qeEmyKmF4ZKZJ!J-sdo6}crX8vZdbG8D z{O-Gl9X}veV{g0&)Gs?x&o$o=W%e2oIdEGzx&`&hKj6n$4Tvq2`8~I>?*3%5qIF7$Cl{_ zm8TA^Mkqv>-jMw67@FZQy5&(i>DmqMn?`{enr^xBQQL)<*z~Yvd&4nQS+#CC(%tETbN5s9C=O#-NJM9B zwDYTMpZyR%&HdmLfDZ#KBB12uc+XO9aD3lB~i6mYVn5jT<*YVaQ`OPLPlJP_`DrZl!^Ra(2? zXlzkAxq{1AkUx1=JiD4NEm!H?p9`%j+tF`$--YM|o~FQ?H*R>LhF7nE|NLyFKRYs2 zGP3JHtJope&f|>Kzn4O^Mayx@WEhT3ka}=zPm30RTR;OW2I#NMwaN@~=6)Y8b|kHm zIcK(LGqY*fANH5=R4x^fHiGYED$E_P=GjhVGy=C`^118jEu{CACkKyM((>2!th&YX z%QjYlz^*6weA;z0w)g4bIBsfnV3EsyGtqL&Xg@>O(5!WiC z*F_7+gf;C%E|Rq?o{AVk&kOiT>sGywf$iU`@Is-wE?22Y!zJO~emITDSp{$?(S|Dz zs?4Wrq4LEJ#2mH@AE6#*(M&t~Deo6f)$rJ(78RL$ve2xev98`j87^~}5Nc6 zSEx~Esj!~)dS)s&En~8nBewM%!986Zc^cbPob`j}FiOIitvxZFbKGOvwVQ*GxRdYI zn4+(*Z=n|6HEg@j*U&d|6<;`L9zH8}>t(jbt$OY0-#p zZI5rl{4GgiDTh8X(2%Rd;zqq>(iiKKMI^G3?ip)Tnn%;Ts8F?JQFvgt)H9Xgq0H`mm9`fpzTQwQ#W&%SEThFG{0-y>(YU4?hdDcNfRv)f;j|P~OjiXjkQD8FoAQoR zHEFo)e3L_V-=!(0LIgHh(s~V>#I3;3)_1w{QT*e)uiu;#w;DHiT<0Qn+=Ic~;OHi5 zJRgffx)f#=rHjYP01bTbWBU1N`81_y*L{c7K78k0s+GtAFDT-m9kR=3p~hr%fZz!o zD9cn!PZRSvHpyO_D%J=9$O;u5uu#xo7Mp$k?)Ex^oC>hmhDQi@c@+!r(3{t1TBl%5 zVtI-3)G-SmgPWq(ycu?GJJ)h+v;3fxgrdUr2mCOa+R+j*YpOZ%dUWTMfNMueG?mgm zehR(ULl(@t6UO5yi^k!z8K{+BM?TYL-KS3d)y|FxS&@a9_(3&j_}8kwl!1D z7zbuvka_|GkIN8;?532b7zV-8{?eu|h!%@0P~EK_y)HrL z#PEerX8~Un9!?x4p0j7)Am*hDRLWhDLZ4B4`Xfy*S-^8H=4>jjpEyT#8P?`0^ZLol zBT4yWr`JX*Q}td<3!4L{=m+D|7V$ScU_H~Y=1;^FY?DqY#cetT{9LIE$M#jhRA{gk zDbl5U6O30`nbj(Lo3yxNo0(Ly?L!vhZmcG9`3ZI_N3!_niQy021q;Z&*R7EtUFu9S zNK3xr-Tp(OCk9Lc?@8Q~*C9D4TY`zJgSW#fZ05^s^{2G+;`UY%$=xo*JWpRO&>{Fo zjNUn?;5wDYr5^e`PvDh}3Z~6CBbl95ix?OdC3ROFE4BDpOk3K#H!AMMMg%(@qItmK z+$Th%TA=GivTbEgixMAF*KfzrX{tneSdFthe8VuTts8cBugDL=7tJpoxma1D?L9Tz zXvjPGcD=6No5}6Fm{Dr5QO$cn&Jr`~@Qx)C4~xdO@ST;p;oDHzrKRn>boqw)1y5I- z+$Oxz`Hs<}U|C0{FJv_?X9^L|D%RzTEl-d0=fDIyGe!8BL`g-LQ5LE70xRwu551hq z`gDp0Tc+YRNq2ge3bDn$)Be4K8h4KsR97A!C{@c(lgMbFeZgxudo;qXJ9FZ_6*_oj z8ANOmoTX-znrqdECx`)Dah2$0ys6Vok9e{m2bYPC)v-#Yb|Kq=l}b{n9=*DxdYh5Q zJxNy~rv+tDp8%T)H1wvA_h{1cDnzQNP46+qfK0U5?c3MLw5Vb9)Gj|V*cKXg+myP< zwS&#XN@G-5OD^cxB<@QOmisbOFdtnH0Z?vfOVeFrcBVCF3!6X5h5ejJ zW!~eET7H9Xjv3r@>w)1`YnbNgln<|<{iKq*6VLjszeK`I`Gs8hTNv}|^w*k>XP61F zyU$8qR1M)RsGnuJ&y32lBXdR{rsm6{$#2M9+U1YAbRSq_>EXsWIq^6z*1JNSo5<(E z%lsUU4&N*8PJMH?zOdiTDOj;U7sRINZb$cN)RMnC%c)A_)gGHNlf$d;7M^9(b2xXo zedzxpfNEmgrs%>3wRYNA4IQqC-))uH|e`|=vB*0DURm|k1ososq<3T za$;!8JS&g1C@G7{N!ViUsmsVm^1h-koH0uh3Y|$mcpN1I?sHhQ%(U;XS|lpd$BY-H z@e;+b?RHil*q$YrDG6R3*71lx-7@4EbmwPrm^?#-T2w|rxJ z2=qzbZY04Y>(aZ0rLykNK8IR$_&A2@MC&iU-;dKt${W)WWaq5p)7!m4u*bSP7I2Tb zNtv}Lq`1OnF@*1Yf-+Xh-j@)u$C`F>4kuIQdlt`a;8$FQLsZMEL~tOMRPP0P+X}U3 z$3(k&29&L48x0Heu?F7G`MIEoHqUoBwYsLEWBehx8JlOmgd^`v>Wl8iqME{(@?w&- z(afRaf&gnR3X@fjqIi>e@yJ2Ew=4xp{nRn9h3+2b` zj!{k#3W4F>C#TVU>5B!OiVL**UP~NOAILM)Jv3nDc9~jf9vZkL>|~jiWhjCYdDF#s zxhU!52Awg3XQ%OsgG{nIEJJNxE|ZPYl!bFy5zb|pgDPH-&mjh|3*%pZ8&m=r#0%;s zKagB{gST2_6ZI(F4LjEtyrVx0UK{sGOYlD+;fWiV_&E(N7iTi+dYIOM+VyrF8&9z( zxIJ3>?ui<6I)Yv{KSdzDJB|i_0}0``5pK=qJB9u;Dj|Ml0Oy!YQ8aN?a4houjbH%r z>7q=1yi&N6gQ3#s#aR0!!W(_OflB2?y{&fr(OCZZ6?mUws_|%bG$@SnjB1$<`Uy)$ ze2BP3%xnIo8{N-V+E_OM6L+cPR)2;}A?X`uhjh=khV<%f;=2O+{)W*$ zTUIr*j-OO+hki=co~%shybZ-sDbPKL96K4wb zufBhIQFQ#1#ere;ZA$)eOz_z%Y>aH)vS#p1e)9p>`AL7mSX3}Y$Vv3) z$2A@cO9*Qvx*qG$GrAtuvAD!DZj6#!bQp?$?!WwUkh-TB4v3Lml3#P-5HAhb5Odi( zxNqhjAHC{pNAorzN5ej1xG*js?2yLA@xvcuuCLw@MjX-yW<$B5JLS`sqTH@JTWZYT zKEDpluu$7g^@2=6LtQ3QO_;fktMl)QLw!a)-&b^(3L^coKx{RA`!mr$*FhOd1} zD4D%NPmz`Oye2jv#_GgQf#apfkg@o{%HUbFky3j`S2S05z;7{6EliWq_pQM51Eb%+ zdXGcdk;v7&`Dn))g8e=kpeJ_1!bLk+R-Tb&ns`>aY>tC8vi>R#i!n`qSXmedY-z&` zrDKopH!)j$kdb{l{c-K^84hcS<#<;uF_%l2lS)O;yG=$dDm)$M#=OAqx}FImTfr&j zY4|t+#zDf_FZA1@TEoie<8s*QQCv0PxW7`Vw{oCkj`7;NWVJa0x# zBYF<*%sBAmn}97eAw6Zw-o0D5T*nT?nXCVZ+8sm-m z-En$ZSLb9#8f%BMt|g@7GwpqLd=!(xbVkHsH^bm&L0$TgUwgIq-RhpgX?EBJCXOyp>KO3v+L#F~lz;w%O-p2sXieK6lL@ z9p^mK?aNK6b+CpbP~cqsMh%akf{k8}Y6>+8kYzBiosK2R(QX;O`G`h!PS=@eokhFvj~*o2JY0I3L5*%G?4GM9Zw$mIMR-&~?Tt3pMw>9LNR7 zJ?11CTkVHIWj~gHaSv4x=f@Iv!Ps8HgmuHdgZdlS$4WLNMIZ-2>OljS>XRfL9U7Ig zoWqqjIvLMYpBN5^(b#vg@FMuEx01LGvZ9PNo_HiMuQ!C0PlcE;8;(gp)C4TOruDEeX30SHbhsz>+3|YX@{_b1;NbGAdJ>Nm7~_U(Dtzxff)%TJk>jWzotb z10>ZgwVN8X=h`j@EA&-|YlZ#a!Yk$pOm+qo4yZ_#~q5wX#@^Mh0c#{IhBm`)XipOm^f7R?64EFgAE;JnhNd)37$PilK`v2{G40VkX7j8KuG#ixUJRtECu z1Njb&LuRqMX@FiV=j+sXLqeMZnbY9@PWd;E>?OP*Kbr%>e>D2T*QRv}bcfc44eFDH zZQ488+Jgj8p=I0E+fr(`KqSGlP+R7bo*T#EDw1G6!hdfdf0M&vI3EpL(|75zxpD=C zkcPithWu(n37msDT-P+64!eIjZCMW#t7-VqFEj;%A6XK<{U3sV4SVm$3Y+;u(Lmx* zfR-cysz-QQn|pVe^$RgE9$qI{8!y)ZRc1>B0A^HZiaNfzQ0*-eEun5%)s8-@(RO>mlq$=( zSzY?D)n}!@Q|zG8P^c=PWcb!$!ccDWZgPrig86{ly@BjSwKcavM9QJ~_);)Ms$FKw z-R%_8duQh9IY)E-vIc`$f%@m3M{q?hdt*ji<;)+Ng5L;%>{~4o(?xNcB;TP^?QylQ z%NM*$=hTg+Llu2R3Us6m`rdB)c8OrE*_}R2qx&v)Cq`164wq8A3B@LGlK3+H8nND2F1x8;<83d+({h|& zdz+`(Ogj8sd#5piUmcmsSK4Rym-5%6*a%NmcOm3zw?1xol-W`{&zvCyogYXSrIG8SC{s}&_UvwMBtobo?pwN~OK0mB8e_%78 zsxwV^N>V%h#&c)>c)u@MO(9b)<^8n#)MJKsy7kBVI^sHbF0J>79`7!81xH2wwka8u z$O`rMyK;q~SX@Xz(c?^*({95&l9G^)-DU3!4uvx-gZ}e7U}z2G#G}K)hLw?b4aXu^ zJG#AtDc)x+v7=$je-}3T#R;)@fD?*Ih2lcM+JE>mUf+7r)_C{;G#N3&(ELFy`pPW* zrH2kCySbrT{}mHYAMO_}-xT(QG%o3FMZj+!MX&L=GTgrTK_2rR$u$KK8Ik66N3pW> zitXd74%433u)7j?9)C(OC2#%_Al|;vnfg9D zaH=Yv+gU!rbf@H$#1zzgqi_GzGb%N@cRgN2@1WzZFNsLE$4{JSW~E3VjhAEU5Sjy>d18>rjgA;WJ5qXN0X*B(dl^%@8owY zzD@i{P;5lKDji!Mgty?%H(e8}SiMLBcygE7s5O~Va;<323z7&usJMQQb71t~9m(W; zLe-|jl+Q||*E@gxq1Ak9EIEh`w-?0oQ7`&svjUAl1mJTvE)`ll!~jfqTUEz#$pmV^ z1djM4`~NWH#B@hL1Bv_6wYZ3`_n;R|^*@jTjl(JTLoKtQC#nVZg7y@>AUbXY3M8*gbO`-NsJ64x zlulX4d(?Ex-#;@O8&Er3wSu)`*SNF?Q;4Q2`7g+W z@~V;6H^Nygf)h|R9>*f2l#JNoc-NmHE9tMCyME}3W1B$V2|qUTCtzfy_-Q0ro1GU@ zm?8>!cJEvsSv-@805e|2{vT!>9eWRjS}N|LWF%wc^@Z89 zbwdfS6ZlRmF5d~+bnLBTO3AP%6!YcO@VZ>t>Dr>%RV$(9U>(Ovdz+s)Y%KxtTn05X z`*{l2@3ZY@t(F1m?;Y_ZcnGjsjJ|Aus5kM71{`H#+PS>V3PdQQVKhBuQQZP|-^EzG z^}`YA-#I@!Q2XdwtmZ zn*oiDqb8_($1jVU#s=+I2MY0VxuHBd3Pg0j@!EvNao9E$6Ty2=T!#t*Ns9SBQMz`L zg|Q@4-s8j{$`0gFWJsyLJQ*oG;Ecy#X!P_(w}4=2mFb>ww?@#%7OUsy9{MvjP227k z3&nTEb5X<2&#H3u3qiNeRkk^*?co`UP@?-m^mP)>j?qPI9+xOTh$qA&?vwoX%Z0Vk zBJ19l73D95dkbDj+{4F~PZrks-O_ymmTurnq4YzfrAw`>L1=-ej*oy{jCClPn#2!amdd>zrW<{W3 z(9Dn$tx*#fZB&b})e*xC8IZL`($0L=SnZooEqO?IWs5H(9VVn2kxdO_4Jbl*j@ z>StieJv1+m-Gpa!4qQ8aGMT$RQYdJ*f|grX=(x$dYsGLj>k+t^5GoN)OEtz_3goPN z>9A6xYE)|a$$;7M`vDNouygJ=D(>#SY#7#Q2i5viIRFKR)kfTx`ubI-Qh5STq6)Q4 z*zwcoHr>Ix{?>b2f z0#;;sWENCLZZenzTnxelU4*eVf3$wjL7ZFs+}V{_C3=(R}F1cp;8aqf+* zP)QQd+eJ`U2PM=XKFGu;1Yw!td8Oqf#h{ybHJor(MO80dr zrux@XB~s`^buEGM!|8J}AE}lsC4U0Lwty_l*kdhHM^4^>a4ro)7*zFgPUs5CxeOrW zc^862T16T>*KC7o*b7Ls5J)0W4iOT6EI37hfr;B64;W3;@BVhaGg6>~hkiYvu0ySO zuI4b36Q39>#^wMN|L(-a7ZajAf0TrO{djMkTD|_|!k&pZiMTg%4lJynY9{QosNKBO zD@U!EYLx9a>{S+H{q$6JLr43HOh36*-x&ES<=i(8JZ1;0$@p~D8rXPaWUX7mH^%dDev4TM0!OsIb;eW|3}_?frk$ud~NFrFqRsIq3O@RKVY_aqa5*d z_Wf#ujphxnH?ePIdchoCb?yz|~5PqtgFX&Oqd zYErIAXwy}`xx-O$tSR$}ue~zG!JswPYKDUQ)bL(piMb-3m?Sjd)1^Vs2XX3$HAKT` z1$goMTpRxw7Wn6oT6M-!2>0@Cz9EOR*5>Ztyo%;UmZTRc@+o%2XFn~!LS$#Yn^832 zelVB{Y5`5IG=1OOOs3zhVYpk4YZEk}msD;f|JlvCDv>O1h_V=TS|dAhe+XR`G%=8! z)q+slIx=Lq%=D;A5SgN5R3gJ=`9Frszjp-5Fi@yv6T%{!KSge`T7-C0=_k=cEA4EM z5A!}foTT1g84QoQe%H%7b!h@p@3mB&uZe#dAX7Q0 zU5Yt~Mj@SSlZVq0^l&*hAFI5(B<~Y6_iXBocVG3PzlvN#^(?>yxtaFC zeGWaCBlcnqoq6*-|E0x96+(Jzf-Y%x&QuFGJTFo?kMuPaXUKf*90k|BbiS zEhoLusey`)+o1wXQSzS8ke~HjBIvo@Ox>MOtROl!rzc=HZJu}Ik_d_z-{Uzcs&Er- z($mNedMREh5|6=j%EDj5)C^}HdjG0#O`rYACDmI&JD;v! zXN%jM9_%VovTkA&*J185PhV^6=swAbe);Wx7;yz9((6rzslZ3f#Kl@VYz1;nEVgwW z_keq}?AB|kaV!tibCs>%Wh&S8_pxDx zYtCtUhB53T{XdkJ6L8qIezR$#j!_@Iw8D~>+@Rc9bUj_!ehrxaBYDVf)}S~SHA{eyoDx6*bg66(yUZU? z^;he-MhLHhnS)*zqY8%0koGbHy69a0>5u0d&{jRlcu9+P&YE+%26x#7ya;6f{O5zs z)%54qu=@YUXl3mj^~#m=^TCg}=)XhRu1%uH;SCZrZx`c41Yr1iJtB)RA|yIE6N0?( z^TU$ByP4(~Mn#M-z)27m;CHO3cn81mvBMgQeCi`H#_=g0LTak2*qYG@=^~hOV!62C zM#*NU2+i0HvT;|{}+@0^y+3TGL}09 z`MHG<_Wy!ezk$N#%!aBL#F9e&A5H1yFMa=lOca|zC`Z(b@_#1=nFzAQ&K05SIsSp* zPiOtJI6g&2ij&B|Rixxkg#Gi+eRzQk!2>8&XIPUV|94{Ye?-Q`jv&r0zeWE~BK+%@ zUMeCp!&jIDUqAh?NS}fvJuwK2|4aJ+WbOZk^qwE?h)H$_y*>K+ft&S4))A(@{(bI6 z_NkD@{9TS$K$gkcE~F{wpQMTZJI2~nB6-zeTH6$=Nk~Kj!&KwM2M+!lsjAoyDVrp1 zUV4Se$b=QOiZ_mVg(w#gGe{8^r&pR>HJNpS|e04qB&9GY{DJWVZS!Z&UVa z7No7X1v}ty9pd%WNt&8gu5kp>Rvn~`P^L*zNrdmThD7mytqb(KOeJqoAr9rMrV{(n3-t-pRk!C9h~;X9cuQ zib7VWU{`_q{=M+uiLTo?r71EQ*XBB@*PEBTMf<2ILASXAzsI_Mf!KB3)JKJmQr*P+ zccR=u5(WRCi9$7_^ti{r2wx)dQPEG`W{f#uT|@$^gDP6Cx^+~hdfnR#yU73WqF#pe zPpa%mj;C5|5Sf~uhCPVomxDd>nis7)3&QCp`l-!ew~$g<_`)wG0jMv6uK=XtpKjEb zKjv8)D&1_p-4_=LB2r>kDn9ItpjM{Yc) z|D$P=(?@|>PUszKb)sQM-TWZpxlg5v`Ec0Uar5j*e{T^!#1v<20|}LHRgq>BiBM2GoNHC)vd0o_EgEhse_Mg z5%iDSr?r3lZ>~hGTK8*g>IYH_tH7w*-`jNlV9*$O#N^_j$&aE)_lQi4^`Z(dXN59fvFj-N$Hgx?5W8O&-`QqiRP)KR&;y?u3+r+f+GjEFaI(5`V=l-P}pZ8ghh z3^v$=F_O9;6)siZ5=2MOY4|%=o|FXWawqKJI1RGxAxzoreo^Lqj`Zpge&G2Fn;TjN zGd+4C2?+`FbepEmK6V=ePj$~yGyCU#GZG>O1_s{1&lqKnyM1>CK4yl5h0VqCEX=-U za@}x495)f&6KnLtpKp!sK8i@R0`L$`fx9&en1ADH<$?h1u;fE6@R5@M$#O=C7cRfz z7C6k1Uz@I{GJZ=-OOW7Wr4Ve!FVwBAtviL8+6AVArqg$E@At?)!l?b> z9x8hrIFO~Lkfq40SbMZ$2JbtW#(rd1U6os6*59Tfec}!AA$5oXPzR$7l2TG(DP{vf zl|~58BV7r&+BwZFD@ol zkY66Hhf5O6trRoer)WByWw7YXx4`J8Eb`I4rFNj8&cB;DM=psO9P(Jb0m8;+VeTW{ zqjx9jPxAI_K<*nbjdD?y=3Msy3BP^r;Jx_Z4h7KuTtcvp+KSgCUbEYU!`=Xf=fzLo zv$dU_BGykJwh3id-@XwUtsePm5~^tnrKl2me9LX;tSVXQmR;L@Iwz+Nv5J#E$u%bT zzl-kP(F1KMcsJ^<2Q2<0bG-tC%UnFNUhwm2CQ*Q9z@@KE+OH^&0`iotSvyq=)CU%cIyqQ z5DV>t*+Le+_v5XKvz&0ssc&W>U?cbRb!Ay=&uw6*hoMbRvmT*ho?u>c&hA!$1Q6{d98-3-<{~w;xE}L?wcC2drPKOI@4)Y zhJ}gIKBz%VGcGSLJ2-=d01l%>%6=;80*j-+i|XGBl7aCj#KC%~Qnm_MqdzgF{YDZ* z5y1XD;MqCf@lr~IfczK4NG-I=cwQquB;>ZOy^KbgdGPwUQ3LC7gplLj$e_BQB=*epAOrC`Ox%%)+QPW5n(GHe4qb@do-m~pUF z?DkiS+PTs-pB5Ygjn8GiU_?ul6iOHPk(AMFC?{Br*{H2B+OiLOFga=L7Tu#q;$@dk zR28WQMK6fxdKCISqNc1*?bDC>i>eRL(2Hh97b$-x`ZKVxm_EYY+cble&<#_noTwa- zvg_)wRb&R=C7&h8bX)qoa~#5EutpK+SGG;%1xY{)yx^iRjdh)ybI~DxOllh5qepG- zy3?2370L!0X}r!6Km=~Fg%+S}cva+PeA9 ze`LRut95f$W4Fpv{37>Y6?6V&SGK=S=mT6{ z^FPe7)0dm1V^e#jKS7BoRA*9Vei?EB5ObiVZPR~f1E|QRgQ-)_i&0E6{%+Ji&gbHa zyFMPtxO86$eS49(QOUSUM!^ZzrZk-v230~ zEt3$auINt@dS3nT`?*G1#-jjVC=wL|+%mr%W|)-3hdk5;;|nw4g#{Kvb@MBpuEO^7 z!%@#Cs#%<7PEXk7MW8&JWvO_P(j# zG#ef>FlY-4mSn6IyEZv3oA-5r(+i^ZJ?g^D$SH#MWolb(*t1?a0U8FZJ4$Q?zouG} zL7P%Q(UBA#Y5&oXo3Jy@q#hv=x$5u$vu^;v$`oP`&EIcL^f;v?-duhtPAMTq!+d8Q z2Zu-k)mA}eVYwYVm;(QCZIF)psnQLO)a3gr83A!R`3Z`d@{~!-{){yb6QQ-wBdX!) z@%atoQB4fujc2kn_IApXYsx(-5DS6=^nGKHf%&~umi`2P{%I#{3U{WVE0hx z#pC_ja<>X&z8tU%EAiV;ihwV)Dq7BIAhPHmR`lUNT8Yh{Z_O|~{y*%!XIzun);_EV zq99lhP!SLdNbfaNv4Aucq*v)urG*v{P(V>YdXXwcM0yD=K|}%Ry#;~@gc?HcB>x>| z<{UlaJn!>+-mm8i)1TD8>i8XS| zIZl4@%x9fo#!$DBt>qOkEy~>5sNK5&1y^$@L9}?c*jFsG0;E<6u8a_Q5BHhS_lzF+ zu#&y~%`to~YT9!`XW9#*Sbvm?BxakO@&l7kg-}&m8qwuA#E};)yRwdSzPkfuNMFLd zz94v;4zZLD^XPg`-yC=U3gT9!w6DY0_4$F8PLujuM~=s5i#f}Ge*OA_V#ng>&6JZ& z5*l=giOa=_RZ#3@mBc;0ZIvv{Dyeoez!nQlM5RndzOd7)oBTvGQ*Yg~nx- zCAIR|UgoHBJ0xtbC^I{I*Kj^k1ZWf`_7gNsmrl~TQ@Khprb8#PR1PXSDzS~tUd!FcE$8@TY=(85k2*`KIwXJnYP~oil>*|}lOEeF_RsB~!^bF)$ za)aN7SpEo<`HA35OjQ)k4Uo`r5uGQ(Yx6E@13Lv+%2dM)o62dO(AuLT&>$#@mzC5k5`NUEC51Srm)k{xY$#xGQYa-_#8sdy~_XjWX9Y zF&>^&+}OTvAx6STeQB`NvV+OmvxVCYFj3yspE)su(oz+lGSh3@7=JP`Ssx}{oXf__ z+N>TX!_$~R0hchRrt8f&&||tFsJk}eqWv5Ut7$3TM6c#Sp#5CpbMNOiTnmlm4BL%F z#mwh~JmzMzvE{G~HumHN0S!a1ed8B+(@^o- zn6~68J-g}lqz8nZqY()SkEf+X@b|@Y?G1MKqQ8ci&ji#jtgcM8v;Z%?o)_B_NpIw- zc>C1_yF{xpKONwob%kwqG`m)VfGD|t(dUlFif`b9# z{n+~_G)7bYJOC2|9~o)o0rLTx=C^Z0w4S6HB#Ly;qD}b3up5eNF;$is<;!SjrQjH}1lraOLA~IU8L4;RWO|`Ag zr{($B6NWn9o|4rBQ~33k3T-!yJY3zy*V1h)$bg%DSzuO~+ zon`NH7Ow2#u3foOKeDc&cQ=OXeA)DADsrTG3*C@i^BU8GqDN`bnfnW?9oM*pxu3r4 zPK(ZHFKRs6I&o`(hyg`NPrU+FiYugGmbo3g!tZGUHN zIpyK^4$=7T8l^EGJ>W;!5=HD{D6$@f`kY38--$n)D*fo{Oo_0TPJOp}yc zG+shJdQP!2oLex+3i8Kd^Oj-frW*U$#ZeXE$^hREL*G$X0l?%!UDYnU#5-NEbM_L zO?|@e3mD51B*73g1}<%c#p@HICeJ1xWSZ?&+_@pq2}OHoJ;0wY*aF&*(I=(%?omLr zmu8+dPPT#Zun(wpPF6&n|9nfH$}-vGwnC%YyBcsMH&rv*5U=Prtf!9G`FEKzM-ZN<|R$g-6tjDD(gGF;< z4F-A6*R+qUC#3{b=@M%BT_t`5Uzw~VTebUC=Q~v=AJqI~zz|+i>V*Dsd;;rCF!pPA z#}7Ss$`}eH^i~YD75nUaLgp9C?WXb}dc)Io{$w8F1R=q*=&!K`JUj1u_V;%I^UlyF zW&R{%=%dbX7FKVc_q`tuB}<(3JZyZ_JZ#Mz{L0$Jp{JDKTL? zkK+}hYW z|MyLS#v<4dyG%8lMzGQkvW**1B|Aay7*W{nD6~6M4>|-CB$HehiptFUTjMvjp8>HT zzT?i=RWlkP{k;`JM%1?GYgOO9C}rLg zSF@f4Tihx75yG4CZYWFCwJQ7F2)d?n^8r$?vOAD*?MIC&z6D%{Yq)~l-ObpF3Ne)1 zkQYv|K$@T{De3l#m;@NmacPGStPZ4|a#0{n3YEc&#q+y8z*2+hAJ=J=_+k8;CPZj6!< z%o&$hbME5ML1#32ew~W_CgDsC1n)x^@Rm)SRPL=lJI2BC(*{r0<)8*QkibVs zxQ0eYs!1sF)Gi1(sGGp9YM;`ycRPR~hLaO3fnpQ&6# zBN|_IA(ZaMorxKG{W=eN^W*kDbi3shT!*7Fs(n-C@7=&gU zl$RI_1Xpiyj$+18aHT4C+8m>s(bw;P_7z1==VWnh0VVz^_`}>b1A%W3T1IH!nRqUnus zJp7=*?Mx33)k^5e$Oj{=Ll`fZ!aY(LJtp5cy*eLap!BgS%MMlk?eOYU2KBq~(d7(N zxX=3fz(zX^7q`$$F;e^&Y62=cVaS`2Ta$V!AVAEa>unQq>+)*vBjH>fzRt;)}m_9^)%(h z7QY$#U=X8l%#FeFhRaLB#B=7zb_}Jel!)nUg7vze$(7qXJk8`>LcD9WNfI|do5vc? z>17bw5czWQV~&T={-8+s@+g^8!rEAb#7G^3lE0RCCku7MD<;}|ux1%;#~thJ_?Jq) z@wE>9=0nl={j})ZgR8pOxQ@gwJa%+-pjMK!<}h|X>q3;)lpMoo*NW=) z(BA7QnNiQxw(f1DZ?4!DFXzHEXnW|zVGp9zNiC2K>iyiK27(-K>-@Pf`EROq%gSSa zB=bRaX1=a3uEE`i;`J8HCsy@hJBKXBw_^ zV(x|B8`~5>hOTU8lp{Xd4GU@VbY^jptwlb-)vOBe(s9#^do*hdneuReeQi_@TO4(& zIhHSfdM2C{ondM%V(W<5EWXE#6NcvOS?~DCwrt8%DV}*P#-Ho;jMnyWL%E9%9Qo9ClIawzMejUF&|@ ze2NM3%e*x*yp`R!v)VzXDQ88N8&XyW4UNqA2z}4jQL9fi>W;T3z%!qNEQy(oLC}32d z6im*8lM<-(T`43yX`$mylkBauN`$Tx@CvG6lFJ27pnBe1qI4Z(^b4Z02%? z_X(C*v=9t^bleh+14S9{mwixV zm6nr4M6;QcWpQ?pC8GmMpcP)4h@MY+99mW-j#*&ENiA@5ejHO7^)ZwQsPX9{&^`R1 zp~!T8^ZmZTdg!*9dSHdanDk+S3VU#e?x@du0yls%tRE$obY<5liHg40HWPe1S`$Ub z@CM=Hd^vtU5-?*QvBRaO_jfs}6_4bCio3Rth@WJEr(b!`q1jRFaD4UryoHVm?^+mx z40^y&K7KRNSB9LDeaAtTFq-R|T|*eZ!&6bdTXA% zwz#EfH=OW+L@%QSwh6kxhT}Hr(DBC}-JoLH7rLKsv}E1qr;;f8P0xY53_73UyfKt@ zcJ9!a1UizzzUCV`2L>{o;F$Y;lrEn9>PpFvWpD1@Y~-SHV=JfUvg(=R@#tBwnP_-z zvCuWqh7SwR^R+88&7O<(gN_b$qcU;)`t-brkgi6so5_iqPGX}`#(jKWyE7eHsMVjp zOIS{L%oFGJkh~_KRjp7K{v_@Et|sTT8TvODwmLst(aroG{NYa1j{zh2;Q&hu>1)x- zUynGffbl4;qk6h&6U8k&!r0vAyEJ@T-`|DVmTX{$?*_~tkr&?fV4k@Ra@af--%!}r zX-Ip1jBDS7VVP$%BlS(C2@5FH7XacsU#0l$#NWBbi(HGCnI4(K|HDK z@sM`iaT(j;)buv-Q4=BG-|GwXv_wfb)7Pl#!R?}TXrAkaJrpJ&+prmpslKaLse;;D9-ve; z2})MjtaV(viF}Y*b>c{JE&O!e_iTGzenkSNc@L*jkR&}PU0R%)4A-1(Ssd%cV<}g~ z>-<0WnxhV?KxBZ9|0z%5Cy?4_9wHatrl6LEhE=r`DmG(~7M~4|;fW4vONtvBrP^&1 z9ZLv_xi%>#m}P;P1(lsQEEuKe2n#X)c<^siofSt?N@6a)HisH83}+B<4=2`Wk@Ee# zx{J(WP3Y}>+GC|>oXIi2|J%{Gc{9gN5ju9s}g|P*9+fkXbtP^8DzJ_#pQs zo}CzxDe3harGyoaRr)5u5=&G_$Cbd7tI?0Yct2Msgskp(RXE~nT0@eE!9gcv1StfqvJTIIb}$`= zacK}CW6i?$R4xU5B)f)qJJaMZg> z61N$v*2c!t29&KVKYvjaIVA|)`1rJ=WzV~R4(UR%UVDp_lG<~bhFE|hBdS_`@wbyp z3J9bwxRQ^9aG&S7}<1QR-WsM6= zc|>yb4kN90!VYK?W53p*9BgAW zGF-S;xFyX>M~T}Zhn{QQKZ!u5Uho8%SIve8tT#0Po%RuYo0DOvc*0C}&y^GDUN@ro& zH|Ve4C|z?@Rj=?7b(T145YuBBPS4fJqTC?0ckffy+S_%gR<4e+$V11+z3)#KO7f0*?mjC}HpVg0Wu=^FWBCE`=d4n&}}TVYI}MxvXmNdKRHvfDc+T%M`xqkxO{Gz1Cy*=uxzzm8P z)ayTFJW`HVg1gX2rk6l>nrlgGg4l0AH40+1%hiPPxbYur;5zCt31VbbOT72wI$>kk zh*vX(hAX%)d8&q3h#NdG7o}g#CH)v3moMRn*L{OVjT8~rm$RGFXnP~mXw~q_ zUVGs4UfKHd5;wmZ3ZiE=WxRRE;)}4kTDh!PoIRW6TOUsr>_gk@H+cgy6HJa-C?`E` zkdP8vd@p*jp$n6bQp7Ck5oV*cjG`6QvvxX~m$zHll8;?aL|XT->J%>Nc-YLMvL4^Q zTRsmu2kDH-EY;5q3om7lpDEVkeY;u{5?sggN!sFW7OzNVPf4|GJkcdYpT?cDx3~Cw z6wZ8tVGlQ@W!7A3-M!Ut8#ImrOpdrN`;%P>lsd;}7Hlapw6@ujHO4Deo4hvP)7ajQ z+m#jl!OW$-w(!|DH_*ND6nj|F1+H`Ak4ph8WS51X*`$Fj*~H(nE(@qF40Z1_qQdWETp5%Yf15JUafw&EbFLkdxvb(xe`ak9RfaQexpZ>IGVrN5uI8zFcgNOahR z$+dQH*$IS+9)9+cmQ$gIU8$gFHN-HSDytMP#W>tjwmy&Y7}^K^p^o0jhy4iCIV3Pg36gLQwaR(Xj-Eq-MkK6bZS zByZ}d`i~x8&tZ+TakY+V8aetp2_n`DwbxP8pgSKQB`{GxzXs07!K zEeDbP_uw7qzJaKU_FnWC$|GA^{GH{7g~p#No;=9a?Ei4MBW`Tl0|O=WMykb}t`C~! zh)CJ=8-2PxPDa@r%gH9e0~1mPn?2K&3qLNreNTH6dKYqlyW7)_y1&(tMW29gKr4i7zdefG5Hj`kG4jOskZWi83NiH=@^(s2e zRtY|YeduiGtf5y^ec*{VpsknJNlgH7vRJ=>puyCq)H10td8pE80RHjV$zdyriuG+9 zv6iVDd6LrONLEMf_SuwXs!S9ePOKy|LJ`l{jc_vDUJjLDtPX1i5W+O_wA=swkbe)( zusHpk7T8z1ZalKfx^6`LK?A9p%SuCb2fz_*b+U+n44ND@Zxaql}V2m zD47H^sJi>$QG{f*aWWzpTgywBHhf`E5Wu0G7!%R}?8=Uva2TetJ?lx{qGn@FNW38W zM#x#&^v>%D8a2r}y=z)w#Azd7gNNX%WpjNWV;yd@NL!DVC)oQVM{hLp+Oyz$&^> z(2Lu0;2$+Ke>A-R!104q_!lojc985PhjuExxJ#=gw~~zK@{mu`0g`!oekHf{c{dNn-`X&XsI=x%axhd_ZuW=tR}MMYqXOrl zf-)&`+f;P#Uu;4yHe2S^rV)GvUGc61{josYZ&$Pk1j%MBCP#_aXc;*1>E-icOTNIh zE@>Xn4gQb=X8M_uWI})a1CYO+IpNGUf7$uYe7xmb9!})egNU}TY>X)B>goyv#L^W( zesnF?xnmo8ofP5h9?m{gz(SS;bh+(%x}tWBOz-07la`@y8_u9O2wzEJ43~#`gG!t+ zZZHW5G8Q~~YG~zQ+-W>!@D}t-b!pR-2J9c%=ft*ex-~nol^+G=m*wXOc|tj+tprs@ zglUEC&*kPfZ){OK#?Yzfec~)ivDg2gks_TPz#ti;tk7cS=o{9baj2%0Or78yg@@hr{cbv=la6=wHy0&f~`A(@H&$Hw~t2_ zEEpE7P*u@FRpWsl8QM(RjR4j$4~4el{8m~s;Z}{@Om418fZDR9xI{3n`~WQxDyw2U zln5kBaa6D)YN8eA=oWeOUc#tTu0e0EWtc5zq#4|>!k=t=`veCV`)n^`BgOd_+*WoO zM7#IAcO*1BqKxG}Zg5Q#6>PqQg6<~N=qG|D(dU~Ne%De@`!0>x!gsjLUZYp)SR`+} zw~5)7K|2I0bRN3#Hs0gM3$~YrPj%rw2yY7>I-8++Da@ipp64l0|K;U7d44B#=D987 znY60&7P4%JQ!r4-->AfQhV<&{$nm~^tb=uKz16Yy%4K^lw;(fy9fown>O#z9F~)xR z5C=R7=nRyb#ZBw7A^_}Vcx9PE#I~?8XNs_1!7M;uS(5ltK)Vx8IOH{6W{}wLBwrsm z#AxW(zRHs@d)vXjUqg4q$Ey=-6TeFA^;@PCguBy>h+%uxGr@Ge266fR0zHR%rfOyL zfGm{@s0bW7ur$gy1-WmVqQwW(0S%4?zH_=dj}RWr270wfD*Ch2#IX!c(*|B^rDlD( z4@<5s5b(PW4E|kDU(h431B<}>d=#NQG?xHb4&yWLuNAF-G=qD3l-hHBhKJt3J#8R* zgC7+A9j<^wI^v9j6%Uj0xKN1P41pK;d#(kBcVVr?cOGYj0aQH}s8zZn^hR3{ye=yh`Im19^Y4x5@FsdKhkP<3vr!ih}sZyRWEkF~y288C=?B?Sp-$K4Z*04oDBD1aS%<*Jt`97kprqEL3VHZ}QAY*% zQET6Vbwp}?D`~DpIzzW{or*=pv80`ZGz}i1x}tkoKwo=h_5394_R(Es`vGLYM^S>^ z`Oc0LEvC{ae-*TwOXYk?KdM1>b*vUl+T9ccV3>kvYAkMpZkH+NFJSelb)xSxh{5}q|zfp}-E=&!mRPcUXpi;%i{&C$E@VjjhLq2Fuok2ZY6 zq!0I5#Q6c8Wr?+ba_(m1x+@miFGSmx&J0l<9`|J;Ti4%pnVjKwbM~~{d2{FD_z0NG zUCW~;BdAo48$8{q$$R&4{1$_<(PPJY-|l_oBoTx1_>d`dM)XMuH!EHcGSg9MTm&gw ztEXocTkDvMUQuN->uEP-N|9FZ>Phv-tI1p$ z&fZmd-{RXnrj9Vqr?2OXpB_?q!vqrQ_IXe>I@Sb06`(%ESxeNEUYxkXEbS6}+~+OE z3oFH<{ata1IHvPvEvOdF;Oc+)93`cExeIx^O61*MHUf>(>abq}8GwVjhpTbMdR(+` zjm@0vTmoySAX}J%`m`c?yaq=xhb4Lt* zZ&*AV?_&_Lya>BV3sw4yFDg4oN&);e(zNmEM1M#*4HF|hUl@JYm8IU+_!WS<#-5__ z?5(Vn7ZNnoQdO?eEj$Pz(cB(7a3ullc2!JkqUGkiQ4Y%j`Dg0WP0wWw zWo&iXHP2zTLE}ebP$+xV5bTf6G5g#6TAN z(#cF_+?kCmKk zv;9CSH?H-Y>W^!UQlxbn^vNmx6wYen@#GOPF^>a4bNz|P+#vGPf+fNKEJ}j|^)H6{pJQ;{ ztVm-JaQ%i?j5dvGG5|u735xJ7fLr#O>L7zWOz~{B1PEpycDtBJ{HT}rF12Z}>y?;i zo0$b))X91Eg?7BC(1vv7@_!JSTUZYgQ*a&JAYKQotiSo&#Ip^u)K($@wvuP+834eZ zqx?8jtn{F#d#Z3H^C~+(@|=?6T-WvRhyBkE;?`uDhl1Mt$17)r7Inm*4kk6LH7n*$kut3Y+{Pr3$p348E&CpBMf5MOAL zf+!)7SdOJV(AsOlvW0TxKGn*TjlF1C6h+l&X7}|X5jY5z(~$TACx7)}8y6L#VeHmt znCaOvBhGwA`nvtGP{h6<0HW>eh6@sZcaIE^(OqL&{MU)1vF7kzUqBP+Ybe)akN1jP-(gGVHy`73GPYh;<(Yo$pY z7{@b8s|sUO{(iBI!%Idwmd__+>p3wbp6_nPPu|S2!mB*^OltfmEA|gTJ@n63ev36V znsOs6<7LcA z8cE*AKk0h1Ld25FCXm?w2|f6!e{{DV+40uRD#(=2=tPu&xybpG{A}zo|9YtdYyIiV zP2!wMXc!RW`%4A|xWt>fg`bWn@R^@bidGIkbNo1(i-=|-x{=>}34TmG(u;uO_S2Cb zOo^b|fMH7OOV>__8#k;di>?a`>)%7V9Os~)ByAA*{YQZ_`rAH>0+6sjlH-Gz;r?UJ9k~i+Z#J7iewF?2(-@~HcmR$?^R^#Kn`>GJEhIqbeQg|qvl#~JB zle~Uf4xpV*ebHK^tu0u}z#C0@=dk~{!tCuWeW#<&iY9Wnu6`^bhbR(POE ziV*@nZ1EQ0O9MjSRpa|Z0_JA;5%I&TPP_gfVf<=!z{dXFo&f<5u-*tDbNMg1na@1m z$tVQ`1SUWE9Vs@QR@FgzSGKzUP<$bHN6_QPO(Ks+oGCVcw-1ngMQjH0qS<@0DC_($ ze$)Qv6+UsW!b!iZ@Fz+-GxQTwHL4|01|JTXn=Q}j-==sx=^T*3uSL4dcSRb@-D9Eq zCsR9iR*Pu-$)I}klktN#&rDB2t@kPx-kq;vQ<-K`A08HBEZ3wV^ao7-H>c>j1#t}+ zRexE7Q(W4Pgin6O0IochAH$ugIFWcmn#Z4vMZN1EtuHl>s1gAMn(aUN1rW6sM*hV? z`n%QoJvvY;TK@IO#=%6j1+5As=g;^wISZF2?zn0#%nN2`AiU)?J;aU#cva3SYG<;$yVu~BnjN}elsw`#PR#nQjnStfe{BMn6{q2eF(Sz zzpW0yj6$G`QJXQfyx_m#V0L<|Cg*i9ys0%#Y89>#z=35^`{@*nZnw95Mx7oBf#4Ezg$XaK)xsP$5y7Am572bo${QD`uh5V zVU4~)fcqkR0Q&f?JOAyi4{o8)$ca;K3Wb+QuO|HV_lSr2CK#hY0@eC8iaHqL1Nmo< zpLO8z)qe5#AgW%N{O8ajHSWODB>(?AcMuN|CCXqq2hlyPQtYv6%71=V+0;~`%e(cf zf4?lOT_}1@rCU(osyMsc-B^Va|A)`u)=rJ4pw7rd-IMdr(Y%M&;0&g$rud&8Ie>L^~aee+bntFdZ7h=f$Upd47!TJ7IN%FTxo@hV+ z74iJXr8(sHU;Wg7ihTd;aDH~a|LJ=ED_#5hD$q|3r~fGBNZbELc=xI70>wq${HQOD zjY|6ZZ*g6O%H&Gq1}kA2U87B;u;xm&c>H6&`|oJu85am7#c1VONZ}^`Bp~=x5-R(O zlJBg4b-;gPncw)w|JwKer+xod75g_=$N%a=J^kg_Mey>1>E`Lc|R?Vt*KN{X0!!fySPd;X_emrZRVd(ho&{%6Ny&)L-d4Koe- zQ&~PgclGkrSI6l!xYQrqjVnC-XDR*-@HwAGAwQLe{(hKVYRJly>A5XLB6iiWPiB(7 zXDVI2n_g+G)VF;Zd%d;J9){Ci$;Hs=!t>t&vuqY-|NnJv1RH6$j{^2VhIvIokajOX)V5edmGQ+KZ^ zMpI-StGnqG^u(69)_*U+{r%p%F5ox1t8Ug)j&R!wsBezFtZ~mwsxH)-6ZEaxAREJd z)CJmiOS_N$wI~NQGtU2cQItRBYNpbgb4KypH*2g5J>3*S)LdIAJf>Urolm{&UrOBn zE79pfixwV56(#x)v}bkb3n#pfxj&?I*$M^SN{p$}$Cn3dB|A>65u<*BX8qsm{YByCXh+hjU&szB_tY>7~!(1q4*iwkUH*>D3^^MnteSzuU+AFVfGn6}&%J z{o+N!O;bg#qD$%N!6Xj?S5nHpU9>a~lnQXfv@WB^qT>+*K2V*_A5}=RcIW=fvQG~k zCLuj`>XK~g5Gfiz)3PwsLg!B=Lc)FDSc647yxee<&i+LKF6lVzFnf4uuI zzeIXWC=vWXNtf4>_nA{%acbfA^28sYR0fejie}-ZF$J#f?$XDP z(Y3NEz*)e0_>qBU2v_6$Up*u#C59#g1y=g$ClVS^#>=+rs`IavBHWN%YYKK>#t~jE z(=;?vj8-@1!#o??A=p!Sx@8IPHs9UxJsT#y;V!v3Q2TZF%AJP6j>fN#Lbxxqa97*f zmh{ne!5!`9`}5}Y2XKQlkHB;f*Wo#c7;Zr@-3Cx)lDcpI`X)qs0FUlL2VUP&f@dz6fn@9ZApYitWBcwKIXqDveYa_o7ZpU=Z2TDrP)WbaUX^GqRUJER@VT{CUZUOCZ3)(nwXA3Um;G?4D+YC1W|9+z2 z`4Az5Rt4tLDRZjT-d9Vcf#7|x<8WpUUY-H%ncT~Co%rka#~MyT%s+##YMc%DUnw{dRdcxQJX8-(i zI^FB|y~&hxl|+%D<>}|yXJN&PQ~ydb&M9 zeI2i=#IdkivTr(4@#Ox)hqMERuD3pxVJ@uqKfe0A1Nli5JkA!YXFfMMcvz=%WVnN$ zas~z$m)QQ%nOj8Lah*2y>(TiFt?VGvMjs}~+K_OTa(qPDm}_I6&Y?8b`%>i0u)Qa? zwa#M;$`llP*dewnZ7=VQ#Vqcx9y$5KmoWW$VU3-QiQWrac?Xs`{D(dL$Dvtz4Gam% zpT;0m0?bSBf)2^^*x|CIcR{;*YxK)IwS>sB6jx8e z49ap^LfEvy`vSpZwQcKrzjVQV`QO>K;UopzUuBP5U13D3o{mVM^Bkii*R!}8Y3Zi(Q8Mj;F{*F&wZaBuserV8Xwav8h zGY*Kn+^jCg{>Z>*H@-SASiHJUMv32nPfsivF(&nK6>a@^(ulKvnHi%mkh>Z1TZc+{ zH}zrwStOfUD3G5MMSIR;KffweH;p%sd4W5N?*WpQWMA(U@A@o%rGI0ARMA6~KUA6P z0p0=hVUex**pW(gm-&8f6rr2|Y_Oa_+35?;QB*B>P5iksu;+9AohB%IG@3J}15sFoQrP>*&SuBu%^_UksyWlrU?YZ5%90X^cT( zwI!3KwE5=hPny=IFouu9KYZXgYUFJGv1o@tJC8kZZ2w`1vc_`9qtpwH!TEX8pkvuc z$&1w9OV`Bu6qFA?ezKJobQaH3ZGpu&)TBr+)WVv=#eNjlBbN~?_KqEh`bXct(p#Fd z^YJe%rg_Ak?KpW(j4yD19J$~g`C2s8?+DNJWX|>WQtO^aGg6yhSQ+dzwjxHIGJU+0 zrjOJ0jyoP$fcbUe#d;kay~6bvy)U0A+ru>TbZNajTI}F}S56Rt08Ls~$q9mbIEqv4RChNmGs>`VjHbQzP_4r;LsF_au3Qtg!#bgWF< zCg@;8xvcyOvQ$HIdMv)YiWj6`dxt^o>(S#0&eb3KyNV3@ysNVrP7~eypKJ6T#c_|P z&R+;px6GDwmKnCzr5|*8zs>FY)5AnZ+g_H>&z7y0!n8@vKsP{zWZ`69zPGP5DS|P4 zotN{>xX!s_Uzmqc=sMa9hp52D=so&6gv=Pw4%vRlrp;G-b@bq==%T>>BW**d=rZy% z36H8;+99+S%vQ{5GP~0i^NU`l7=pCRP@Y4I*gFDyyetK|ZF!#?zxiD6f_vEL4qc4G zAf!9u=*cj5A)czW6$N2oJ*;uvxBZUbAg1$glIHsDX15f_t9HuQ`wc8Z&!3&k?fK)r zyTHi@YiKJUWMNi=JUf&U$NMi^1%AHv9l$`_0(_s?tm!~p~z~iVNDSje({<5UjT`%6G9&c-wZ?M^Gn?Hg=e}ITIhOh2gV%L^*!2Lg@asuHrb!i zB)iY$Y^}5`>v)01kYKRa)xPqvN)-kpw_KAEcbl(Pf@PN;?6jZ9nRAax)3-`2;>8vI#h zY!B;)TSU!N?=pRbjQPxScjao0nm-R=Qz|uW@INExb%MAMt;9P*+92cv9ars0@e=|< ze&S_r{tI$u&kDZv{ze@&RH-!$P;N1QtE=GWHrwqHiY6@kjlUr|iVM3KpETc_qi&0w zWqr~=o86#^!d=zo3yM2R++ZsnztX+B$+_7#(owk1ausJpgQ(A9#tr7~Gt^j0SRvPE zQH;xxpG*OnNiqd|SBEb;IEC3!_6ccz#oo$iTQVEku%7np6d2u|y_F^_RK9`Bb*@|0 zN-5G^)k~TALvUZ@+Jn7)93dEv_JPnDl-hi(>AqVuev|=(AUrzRYe*1h&>QY~y>egc z`Y6Ti;5Ac6ZoUgyD3o`xo3uT~es+1#H0&z?j$cTDiHKCW&eL&j%;{{c4DUEg3Xaww ziRv8)rVjje$MP5y{Q}2R>%BK~$ELw^K0gtmgk|oKA>2qaaxhnEp+jDR&$1@=N+)4O z%L!$?%7W{lmo50FVLS;s_S%hX!aQb{4rPmQU0djSr=1WZ>ppA5+o&Qs_P`e9Fa|3g z@*2>!$!o20Pk#pSC%g7#<2rG94uUlAaylBWI6bY~uq_ih3I)G__N3_(XIp)+fQx$` zM5$5S2H~HNi5x8FJ$n-2657&&$35v59C4%kZTfs3!ylhM)1kB&c%u9-4+P@ShT~E4 zg#fc!__ZHp*20tlS7mu>w6|bcG)0$4|M_r;$cHP|;=?UK)m3H$O1QXgK;b(e1&|pO zo2Ybm`&a{LNSMrahP%F3cG1{p-|AC_z7C<%{ zV<@q+*v*#D;4S|oJ}BWw62*An1kgyPyx&_&^_O#Z{L{I=7mwy{L`C5T^u>Tqg4pJs z(H)Abt;jMCZx)jQBy8f@MCj{M-;K)YhNaK3%X6qu2xex`Ijq1^;C+FGT-k9tuIoCR z*MPtE+Xf*=IIqrWkQv#3_`?HpD;Y0*VIQJ|KHgj}mgdeSH>$;c`Mf}Bt@p9#hLPy- zm4Ewb@Bz0eiK~QI5T8z>KS}NTzTGSPWJxW&nWG5Y(_eSy^B4&5;m2LTawLR>$t{y% zZjyUV!3p&WCjRWtKiz0sp_u)0i{9`YgF~r_=Bi2n8IBG)rB~60ThD#7hS#&l<@Zg#pttH^WA3<#BeZabALJ6tD)%5W-fb3B^hPHFu|qgY{Q^U z3T&Q~tIB2e3=Ny=$DXh?d=4`hN0C-|kXDf)QaqZs;Qj|XMd6Sb&3P0OGG41tO zB;rW7&_RRA~^Q(70*!pgNb|SSFe;Qa` zfZXBO81cf{&IV{i{=fFFJRIuv?VnTnRUC9Gw8)Z^#8`?VGGi%1jIu;zNcLrtwJZ}Q z6^0HW64{;XV_yalDf^bCn(X^9VT@(W`+Ns4{jT?SI`8}Mo9l92-^+~W`9Al3KllB) zKlk&!zhTFurb4xDk;Y+=d41^>#pvXqP{YOgQ6^-g~0+h3PyaTKnY{b7$U zs{JuH+0CarnRmlBe~kZW035sxWs+*mc(}y&ygJo~A`F`GYJU!akj!v01Tc~|Gk(q6 z-ivIo2r1HQH*k1=ycDyKt%qP;vb5GA#T-l}0riI*U zj>X%C_QO){;O5GCY4h)eNONsX)w81bJ!t%*ZglFR*7a*gd3OBP>QYhZR}K7f*c7_B zj^DSNap~srX+%cp__*70Ijw;O2`5$eFWzBhe{p%&?sKR5TPD3u><@nPD-QjU70+v5 zIF^)Fq|7@hHi$9t>j5xK=uJovHT6JnN>Q!6ALpUW(j{w`2y+W5VwY(S^`Xy>*;X29 zAAj|kUOUw6yTYaSgqld3w9Du0EtRukc@M5-*Rdub?R#iv-MEXr{UU{)pfbF_XzT@! z90o3BHEM^X`pYt5U`25=Q$gJYb9RAqf&M)PBX6{yxUv+*yJ&?hfUSLLn9k&EAjS6I z1!|4uqd8!l0f!|;yf7b|3#nL{9DU~2MdnTvLZplmm*x~T<@!iMT;4Q)`vL*M0w1kN zb20)ia5_TzKp9aJHCyO%@S7S4Xw!%qXaNriB&kQajgxARQZtUgMnPBTmA;oHBZcHa zt>xN%Nci(SbZLu{LyPbBjdg#dQK!3T75ASs;b*bE@u1u1+kuBJAY=NoMT4%nLx9b& z>`EFAFqRK|K%nP;u>lP1=d-?+IyPc;eQ7p?SDqf|XF9{9Q}xfq2NJ`L8hezz#7<=t z5tl$dc3)-tIw+nxAcV+S+SE_Ml9Ek~uS zSfw}UwXm$Tjp?Y~Oa*n}bg>`p&Oo3PnX(UvQ8+1hBPoE^&!iE{>9d2w$jRZ8jICa0 z-33POHw2lvj8W}~A$zjj46|g-*Td-gNUc~NVZPw7ZW&5*RZil**2n1uJ%U##WhVhf zmk$@Yexq8k>ae4}p~sln$vL9FI5P}af6Afhx~uuGemxv9p2VV)E3f=;NqJs#@t~iy ze76_)KkLE;;ww`08(C{~3C%6@z-epkPA7nuYFEoCck&6ES;j_72+yUtE+>CsKB`9V z7!?^9?eghlFA~vud%s1rqXuA#`di{Hg7jRYo#PC6vrYn3?ppAPQz*Ug2B~)>gZ z8{{sC{KVF}^V9YI4x#~$F;@C`@U1bFv4emuICgwNZVNix6`C#w(D6%;@iD2fP<_IC zq^6awHy?|P#NGLE9Vhppj;jNsra}I@_wnDf6UyikvM(75v!y)|%7no}#Qp&I3h((F z4RmmzC$;g)LD;IG6&+Z?WDangL0z67@!1L{2g`G1SKjeC40n&*TplYvzB*@_AG0tp zO`|AtUM{p~a2XU0dK5ERf^IM=UFxyX@8b28iplR8v0!CSNZhY6O+Z}BvwqeApPy@U z=&wT=7~XEF=(=^EImeNC2h(sK&FaL1+&>h0boI@K4tPxE>1*;GL69i}4&zqI$)9aY z`j#g8{SXv+z#)KsrJwVX&f0T&c&>Z}FSg>6tOZ@V98=arCUF5UrYN;d##EpP_~E)b z+3zgLObFUYbH92l#jeJPmTA{obt@b&e)jBYBmNi-MCgxaU5Ce#Ygu~H;d!1*W69YQ zT<%KF&dx5S!-s6Dk>uWjTj$dENEOCQMaf4#GuAVCcrTYhzUQUa@N=oYgb*Bc&NLkE zc~p3)fB<(_ULbz#Zj*xb?){TN^A-P9CK43Y-$X;(lL%EUON_|W5 z>c+JO&1D$a6#eH zS&XARNpVs7IMYtR8P$PY`NnL6e{zi{>B3}t3DV*0y~usrcN*?FAs|*DEX*4mCgXPV zd=-u};TX%mjHGzL1M>Q%Iv|5Q^g5F(CXfnK!mh-+;mwaX6pD@JsF~*JTurxn0wPZ; z*m5x$C8K|;^%LER>Lv5`Cmx)n^w>PXolA&|SzX~E0nF2pO0dW*iz8e{HT7$b3~qyi zWBL^p_Vma~(1Yl8%^w>Jpd%P0tiBCWsMFH{z{ws&c`ce9!DaZv_R8KRKT>3o7HAD% zn76aKM)T%C?FA9p+@a>4b~s)gGs^3?AAh~PlQTS#bxHKFM2cQa*mP$wpKiXk+nvQlr8suI(j@mhyzxHTK ziLR1YW+9F{ZPNX9+Fpy8J2jj*e#2XRz9he8Vw3fi8QvW{)@Tr!ojfC>jhoS#0lBv4 z8^X+0F5(3KDBu!G(`Gi6x|t1eNSdCY|?=v73k>n>{4+CgF^NRlX~}~KFOT6)fNv>{u6S`}fw&|Qsz%Lp8O`gA;`t^n z*|_T^E_ujsCsbB!!Y3{|Ei(%hnS%a-<$na+sL$yt|HS4>3jm-mQ?b~~++Go7^3&0- zPgav(wEl+H@(S7y6DU7PQi9^WCR8!VQ1(>z*)gALxt2XOzyMKSzx^wT4hYsEo&Xuns4|?L=gd_+I*Ra5+t?KP&A3VHX z06PW>UIJ%}cJAFkM}TyUwFPANdl$F>Sm*$8iHqqgR)~Sj8ol*7yfL89bqUCe# zV)rmmHYx|Dw&vS_>-|=%`orA-XzF~$kg_iDggaL<86gZ`9SqTPYPnz<*l{%|hBlX+ z{a#Qge8E3_W{QDH_0iO2XqjS2sBmTrew762)Vy3BxI0x1qW5<~FaScxIT9%?dIp42 z%eEx-=rcQU;J#MWpoMwg2FrZM&HKZ62*lIP63Ahb0514mg+f%491aw62HQY$`hOy` zQawJX*3F_RlB6VI;3IVNj3j0DRJr`V}hRj0P)e0wV` z+#dR&eXCL4tDr&Z)Uq4{auN1qC_{i75<~&{VgkOKvcAc<(ga|O5$aVv6W_xAZy&~U z6Yr0Yk9XMx$xh_DPDc3bDEMe)Gwy9Hul2Sas^e^6#aO7GbDdRL7ztK26!=_{9~3tW zARS_=zn>!$1V2>i%bkqu?f2szZ~Q+rkoq2g+_#0b=76$@zy}l36-b$yYG6QirR^mE z&Q@50QNb6#tGY4lie(o0`pYlOWR>&s>(cuM3c3QBq?t47P*J-0xe#5*xsX|W`H@+u zd5?*k*SMS3)Yd=$ouHqll`Ht6VD1XTA$Eb4wm{ZejR26PTnI`mmM|QpbC!E7m4Kc- zJbt)CD%?%^t8>T1Z>0LlobUas(`@;rQGlH1whqA3A4h4tU!C%DecU+zY{O-V00)U+ z_|g3ucq8!<`v;EeD36fsOrK(>-jij^4tOsy;3?MDmm&<0T$j!bOk^L^L_J<3Wme^BQmCX2DC|9~l~jo}&-Za^X}vCUvoC`Gv)oC#tYb)TvDmcelVWPql&dIIiIWGmAH(dkyyX z87zp#4mnHtGS+BBaJDg`q%Y#wVEPg1u|ro&t^9_K!jrU-@^7J6#4t>&Ao#hf8QNP(xeC=j^ssFcTjy6BA$7*{ZK_k^wVdiAQaFKXaHWDL%IwvQ^7aqh5)+6ctZUgI zeV$l_9sC-p*vBEsZ@~+qO_u@=w)o7BvPmlti1vBHE3&bkIwmUB3Mo7dY3s`omWOt8 zC~#EkPHL-LThr6VU*vp&UmRpj+Z6q#r}%G|v3`-F33ktlH`}Jm{eG-XmHfJmjV{rw zO^I&(aEtgLm#P4Q$+w+ie;_+_E<#lpb>HZEp50A8ssv z{jM}$L7LhAH)ldNrxDbKgloL%D*tV)E%N&*Tu5v`g$r58Ps@e2-%qyyf$g6@_y2=i z$nQ8jjeYqXmGnO!h1`rNyRq7K9~Mx!pA{{ssJ~T+le5pgt?e25-KHsDJ8g z+PghD*HuNTLBC9oGTgNlOy|UA`X$#pnslLoYc`19-d=0le~S)FbM1JIn!N6nkDhk^ zp5LYlv8slzPS}b(8vK~3ZeR=7*aM%{DM%^0KH*4B4Lm)F`LqlRa!mr%oA`a53bk zb9PG8+9`iwJ)@e}lIb z_74xZao67G%A=^Jc$o;T*~y`~bgGzgU)R~dhlx#&i)DI?83~__P4tt$B)rv}zjycg zrc*Pui^6RIRv8zY{u5m*tYUyeMxcV;tvJNF&jFd4m4OKlXXcx&aSNvAiu#TY;aEe% zopx6dmy01PJKM2C3K3n!jt*XwIzfXwPZSyl=F+G?d=Nw9c;vnI_7yq^CJ81H$cjVF z7|T7l4FmKn$IcdpZnOB-26OQ3_!+jq3>nC_S+YyIA@g3g?(!`r4a~KTj^9&L`07-s z%WPe9bF(O;V_X9G`E5L&{MVo02xL}eacT^dBkCbs9k618kbx)Tztp5G0) zKzTAg(z)FoJ&o{@+`-QB{OHHJOx6xqHQGCFKYjZ2&CZdjwOa%-ANPBs_Ll+E!d95B z^=Ex1|HCi^b(hwqFxl3S%)@MpbXvwQhU+}hXn{hu4{ zqC5xfU6*b&%o`isaudM4Z&SRRBo-mou^XXY?R9Y7J_pg((Xl-~Ivx);VX&;&>+I-^ z(BIvaimH9;TWWq42T<};UOw-p`*(A>bw3>DD#`kIcjW{-0Q zo2EhZdDXk72r)Ujl4*dYxcX4;`{xK|L{gy$)FuDs+ z>;V=l(wjjMT@W>@VD;i-D~(AoCpj5;;2D9@$5V4r#|6~g_m?Tlt1f%`9Mj~S4_BvFynJC_N?XmOQx~Ty%jnX1 z>A^iW@F!2eLi>|;;%c7PKc`uoofxI*LEYnf%*M?s+Ga5d(tDYc*l|nH{nn?q#YooJ zz+=LfQ|l;g)c|YYfdwv0XelPMNq*l{%QEaB&EihC7`0@N&H3!Yvi?2Ei_hSSo34iX zD<^GC^m7nn5Z6JuGN!P7&;K)hOw`qZ+qak&Me5Zy=xl_3MCp=+K8%nR7Gq={F+{cK z`IGH8Cx^>=e!>V(nyy}bcve+alYZL`{9LD0QAVtp&B1#1RMYI;ullEE>J%3QH&wt| z3F9vdJpNE2;>N8gnV(vnT*m?)dSmc%6d{}63PhuDRsg^xu33CbHgNH;KCx$>lhTt2y?3zM(!kmM4?3$V>lvy zo`7gQ`7Qmx?-!S^jn=D#JfDqYU8{yXYQtYu0~+_K-4eOZ*CLP)zqN7SczANlS$}(G z3a|O?RyMm?OjByOEcuNazm{>rgOB*z(#KiJv}}Ih@nlg};j&=}3Q$|(t{O+zhPVO? zQ{Q>9(_oOx@rlUl4`u_A&R@6QX~@PtHItz!jX*v%b5s$gd@N!g64&E5$n-+8huQP` zt<~6t@S+(;Xv;PFEX!+HHf1N4nJrIly_a$_ZUTv2(YLyOuCfg*{L0)PPP+|kF7=wB z=?}*N$IIM_``^qCTVDSDh1!&M@238F`O8kn33hXHkg3NzS9N-JNYHsTO|rPKxHEM6 zCN@g2O*~nWjq%uUWaP`{XHRa~Irpa5mtDg)*S3~A`J>4N9>}|aZ|!@1^1ORRvQyw@ zcKoXQBjakfGX4H?;6!)-Nt!Fk01dVq8vh;7yas!`(cY==u*^)I_UiGiw)9HNto}g_ zISzptAB9mX#4^LTtCI_ym)iu?T|!-0q9m(QMlO^(Z&APq7t7OfI@oPKIbVi4YC5tx ze0je~H7wB}9`u3A>V<2Pi5}|@x2MQ7^J=?Aku{}ke|q#W;g9heY~?bJAp+@1_~UM3 zpY)BCOi=lawce`e^B3eCGsQG->fSXhC7bDKJ-hI5QN89qF7i}#htRZs z`Z(;J?zM#rsV`ee$$X@0fiBdO(hiuA%&d%U;_W7Xnel25!f9^3-mkxKA`Z?Nz$}qDSCg1 z_hjxd2`DIIM83$e)W%bh7dznLr+UY+qB;{0&%jI#Rpnx^hCdpsYqn2noD(;;dPRX7 zJY&-}TPL$-sqEM#oxC_cKt1#Rh(v>q>fSU6FZ3Q!IkusG{dMCqWv^`C`>Fm)3k5K@ z79}p6sI#3!qSD?05(?ep~g6{K~>Njls zp84@v!8igYV6(ecn$E}|hG-_ygPoo4m--(~BJ2nPxqrl-hJCHuv@{@DPrgT>u^ z+utA&h~N4Cx`tMlsEA4fi-Z6xc(Jl(;t0Q7vw?gp4M*RC)qZ%=nMPI@WR#V>}O=Ca?-qOLFirLlD0(inYI zEf_nKONW&XZD&P8Q^M?O16cTv-ZjA%zF{2+M+pZa#+ava!c@9-u5RI(@>6-rjDP z(5~eFbgemQ@p&qDp2xl>>rv_Cl2xQ>TyCT7|DH!oR%_DYauP808HR|OA z6TP5-2DUX$j_AAQ2Pe+YVSWQIp=zd1ug?cW?%0^nVZ|iFo(fPgp|}I3C}PC2kue*! zq5mx2BX4lNw=^RE1`Ce3PG`4;1 z#8~@O{NEl-AmGj9G5g%0avsQ?bLbd^c?E3~SkMnYn5g%F_#aZkL$n+n zPHf;I*ZF`#20goYlZnl2?Y!KaoCO5B1_I%%{-CnO_=18SLNJ#BGh74=a8U%X%B#R9 z2%!s@H<42RZ{mx9G!ih_aNu(l3z+vmKR_Ue3eh(LG&_h7yA5>rJ#KR*)Preq_Ix*R z#iy)n0ZS}psEepzq$sI?4h?ki`sIh=NNSP*a9yGd1xy0C&iMSdKSa@0#1-ONBNVuD;MF&s7;Anc|SROsvP`5bq)$DWstY6NI0x|9evsyGciE zAH>TfAfmj21CDn9L|D8vv+BCcxxmb^+8!;(Xf>>2~9ybTtFFz0Iu>_yvtQ6H$ z)nJ`Y2P6p3V~rD$8L#w7hkFi~cYZkDi6-UDVV^R`?&Wul8RQuG!-+IK1A{-udv@m9 zWHjsndxzX!&v-xum!ARfB9(4rndUNv603B6tyS$KH!mZ{I3)OFG`SK$4^9$3yMK&L zOcH28&p1#sJQP?`s8W7G)^T>HZeCx?NJ|LvSO)}p#*5;v4x2AKXf}34*KSSZ8lUKF z%t#8rPG4VwGGC+NQK;|=>*qkbq7kRQ?T+(<41H#`=JhX(?M+SP$)L~M*Q>$sxxula za`Tw|D4I@`#c{x9TbJ-uP38kHd~0V+>3kV287=2flSl0q7FptWVEpFjNZruO;#TO& zuVonuY<_=+A&FL4*$fyy{nfE@yXBgqq^skQwVxaJyz^ z;Y(0j(1lNE@?o z86)WD&waf{wL2*-Ep#Audmmh8xiJZC=>fwHM}}EMOb=CJZPzEBae#vT?Aup*F&Bc7 zhDs1t$MdQ`=n7|Yg2)w&wg_uz5)TYtEbe=%dWlZ_%`Un}MJ=ibK2Mh>AE<0~lGM~B zIP9E1Tp62t&+IDrg(QmL0tsgyU2J5j>#J*Y-;xn8kY?^{X2!H)=g>k;JdX$_g;5H* z#d-L%f+e5T@9d*9Kc;A1)>l~`;wWu*wveP-snq095Gf85yjVw_cgfA39z_jp%8;1In9N$p?opRve2!PmZT8gpGR+pJPe<3(i^C7p-lTN@r}R;5|lK<1X4Dm&)O23^SxGLk3vSc^s)q0L};YiY5itU3g0 z4LA|!4Z7UO)=u4HGSWWN??;Na1+U?ns>_?0wuYcByp-4#5zE8F<_&)b96i;TTsM{! z=c@*>YI2DFQY&ZZRceKj)fY#eeDs+rh#SZ_AvwO*uij#6QMAXGHiWSmZ0 z!09U=S*TGvg}D@I)ZkJ(nM4_D^x6gAJ$KC-H##(y!{K=w;V49_p$7>U{I)w$>AJLB z>TS5C2zlM9LvOC_slJ|}tQ&G&Ab&Me+;+fNKbaX*?Fu}w*Jd!1r+jQ3>6NAb3mS*kc;NM@abxUZQR~s8NFR>PUCWL)-h}f}Gl-iPdT`+S! zf52+kp)tW?S=cNkBi`{6v~&)-IbLb8;*!`D|Q?Ue5ZZ{J9bA(}c7&WPE#f+AF)CDJ2(ZAJL`4S$PKVTE>#^#-NQBoG^v((%Vd zSCu(mo6h9;NAoKB;9)Pa#;Fgkrq4J@e$}~S+Vp24!qE7!CugA|;--wbQASzi=rdLP z7o+?-JUx%XFgtNx@Z#}D;PKOT&1!!aOOtG-vc1Wi)BJ(V;wx-SC3fmtBFk}cM$8Cv zDN5TR3-pir=+rZMl!aTf`F0bIS8lY)-tL)SJ2wa=FR6g?AA>i~7LPmoGw{6XK-W3z z?>udsb#9xWTyJaCZ1COFsWfp;t#Y#YQajdAHaFaf#H}fMU@y#Eq~VnBr@{(Pc~4Z> zBnBgG2MIyOLWWDH9HTLwHsAdZ>aX#47F^-EB4zvIWuLeMrmbcEZm=JW53wQ4F2pw2 zRiu^enRUr4Jw;>7Ocu_8IWV00;UI3jTXenST~etm#=Lr?AoFarB$qLQsGCD(CYJRZ z!pD~`c`v2bZhbGdjrbTbw8ZYa5!uygmIHnlkvG=)|Z+*?^h31Uov$A;+OLWUi=S4EVFgou?->Hq)eK%;e6nHk;ruy;{P5UdaF9yRBO&$XQ2h}CB zm1c!e4-aFs&6yJ7is4%D=*&hMDHLIJlA5DoYYBeV6!N%a-g4K%+r>k|Z-Gf)McAz{-^_nil+BoE zBQS8QDJE4;m|s@c&GZIBQOY$p?`-jRaT7Bp@b&PsjYVVdobel*;FH)D`2D1vYo>&1 zPAPL#W5+QwZmir-CSl%^ngUyPA?U;AL0;a)u$Y21S&~Lf$8r|vGUkBgiSf^>wTaw< zs)y%y1mQ+*ksmBa(YWaB4&4t?5s~2$e%$PP3WDvV(7lnOQt-KQ3ThwvX4ANz4z@Ev z3jO_tc0F_5Z&UX9B^<{};E95IYM)gF2BWho@^DPzCSne;r2>JIpwj2*lwL_H1e^(Z zOXco~(131ZdrV4=@0lbicwrZ-Cih0cxyX(cVavQ~NPHicte43^4jE}!@?%ZorsBI6 zUhkvLYc>pvOq<{QPFX}`s0rT^5l1y@4k#4G>T`d@(`U%l2KzH*%6g%{*cNAXCs43an|}C6{Ro@^HP_zXT-jc*fUguC}yGS;Wj$ zrrhqhVQ(~6m@4z8GTPoOAB+e0)d%E^;Sw2!##;-gp<6@Zc|y&T>sV_^6D$~VK7J}{ z`8Y*>h&G62TjEPXayBdTYt{4X2;`k$BmmGTu>JStIg2E=*UK&85hXHNe?0fNiYyHM z(J@6a8+$3O_!9R9OZK(r0awO*6kvrim1?)*ul)l8QH>&I4-G!}Z0D>j*aZ4Z2K$v> zC4$?_7{xr>f?>6oVuwrV^Rpo0V*vvlM$i9+eIQgL!(V(EG(S5LG!Fpe%c=TC4zq)c z_1feGtyL11e|x#UlK6_n7~u^;ldRu$j%K9*05qt*xm4};RQ)di9%_W;T^zNZ;t;)z zp#^ZOH#)d#xReTIQL^^c^L37Qu)$SbD=nvT_f^DzdDW=Y-Ji!> zJ-3^Q=(s?b6dE)iFx?s09W^=Qd%&saV`iX{qSoMo;gAn7NaSfGr(rMaFY@9niCz(T z#(221yXixXJltHumZLu$;Wxi97nk-u+*X{bfUO)_`1#VaHQ1*jsqD2X=KSU%@PLZ~ z+NnOj+6ry*`x$}pAXLOztgy!KV-;8Xrg0i$`sHqGrga>51ka708c5oq7R?m`)|uiH z%%_3#z+rKeU8)f_a<7tC&c~K)k1CQ^9%fl>)G;mk9k$|vcJ<58vD3*=&^#agO63aR z)MKH0__avzhi!B3O+H{F%rg=7G4Qj0YqWHwXXn->sGY_uCJa5d>;j@=h7|W!{yGXVHY#oz-ENSup}g$yFdc}oW_fzU}uZ3 z^3IFV2V)yEqoxSY_IO9BzWKNOofOzPU?&92wzL*5=!>a5{-{4+qsDT_ba^ST))x{J z?z5x?L3eHipP=|V1^{j@-*b3*4!^A87^v=D4GEw*sstfGP7+!A>b_&mGIA zZe<94-8tlF)vf6D_Fyhj#$k>MoAQi4XWi?*uVJ*M#8Q(Vz#u@Nd|(p6$gUAz>YPFs zc!+Jn4!FcLP->rtc#|C1w5Y~_6fAAkB9@h{gpaF{)j%}mIzs9J(b9m135N%^I2bwo z$sBFXEUhl27T|G2fA%ZRB;hu%)My^8hd5;-q`!D0-ilgCAyH~{v@LyZNGB$FIuS9}TUAii~^e$=v7uTB?7MsBVfvi#5s0f~@_K#6R8ee{Wu$Y;@x% zwtTH@He|w%4o#)g3$u4@P$KGP(4lI^45?X$+yJ~30|l0unHd1eQ^uTnU=fR^;U-O} zgs!IJ~(Zn+jLOLRwHKZO4*&|kVK=X?5csze$%`Km*TN&ca10oWhy%B^bm?T37a ztJu|f6;nO~W>)2ZcANdt&d#39;ggv(Q3{<)t=%pV#jkbrnU77@x59RIKG!zF>JQhm zmCu8eXhp25^Gr9qsj%rt+;F}FG6D37xfpHP7@z`v-031eEPl^vZ1sg{op*Y_gEQpU z5oNSL0dJh|1~AbRT8=*(%%aghKihN;WHdj=f7Tx&!fAj3wgIS8H(fq|;3J3Z0;=^f z$EGagXN-1At;5{EjMcGiP~r72RCXtUoPO*WKFQU~#eGHAarOeCK)bWQRV{kxxA)G^ zp~G}!Uz)7quF4l?%z#xxj`Rr)n?GS$n3e+oSoCc7o{cG|*0_xDl1ATo+Aunec0J80 zbdUr=%89%AFM__|6uP}6pc|7ZXYBLPUWwl@ZveC6^W7))un|u`D(ZWMHDCFX@19`p zsWiZ7DqpYt2|V5L06c0{d2r~TdhhLzwF46ovDJi+7D#$->Ac2jlImxUvsuo57If>| z{}A8Olz7MSwUU6uPkMS!-{3cWq7lxMMf+)AQVuuUBe9Jqm%`pTK#(UQ10i8!pI1aJ z*S$w`Rx(qnG36sFnT=kZ<^m05ipC~78Ip$Qqn8Z4Ld{|6ryi_#hMgh)r{)$+b#*>- zDaT_QJG`kigHlESZgU)W-JGh#N#fG+!hiT7Rv&YWLg^Y$=!Xg7tlU8zY#7bk3U8S^o^UgBJLAn(#@(w!=F8rc-tNCsuyH!j-*pV|WJ)Z)1P=gejI2TvUGNFLcFG!$ z5}{K!V_ov8@-xCt_>Y~`86<9Aq??FuS!ZSiC(Mmyg{S=0`$Bjl98 zzNgbrhxLiUqYytAfkjLKYYXEep8)S#@it9Q)~9z zM6{!YJ8;a+F?YLSc40t9fIK<$GNw97%5B{f$snv^_EyR6G}(idixd|~z>Lz6VQ7aX zi`Wa6=IK`buH7(;uSm+1)lHAC5%Lr|+snUcjQ-}~?s0H_d0gXoWMzOk4q)lm_|*z+ zR(oy;=gQJyeapY#v+!Iq;0F{~p;57r`tGVlmrzFLfh4QaY{O1H^_aSS-~BZ>GjwdL zV9nOA_nrDpM5>*K1GGYRLWiCYh@-?(ASZOERMnF%lMp~7k?j)fo{ zyvNQz#l5`fFd3N$H)1M#>Ld|gxavJBqUC699^+tS5rQr(zG4omJKFdyC~lkV*AF;~ zBot?@3z!m{T}%$0SzITH;Rr#B=pq4L(hD#rG9Z{`_o#>*YCLRC|G^1}J$>-@dLP5% z$Rl_xdIbobOoF~LkU>kU{bmpr&kog#w-rc~hupUBXMmqpc>YewE1eQ5oZF=y{duPH z_yBDl`JO;VTb=rA|5($k6kS`m$0Dpf&|Mvj9N(7p-k2=&sMWMY_a)T-HZQk@Meh~o z+AjB|)ar!*PNdPDV4@SCkJPb{(4E$?5PjBUmPrh!Soj^TKQrPORB_jswqIKl(n9|% zzmi`?X3t}0Y=BNkuRj>g$~K{@?*B&1MUG3FkXnbEAuY>8!VL9`6Yf|Qj*MXy`M)Y6 zy1E3tU4w>vEKQG1VTRYT^UIBC;Tsh>Ri2nOK>^*&p|4b}Mv8gL+FASC4-mZaZtgQ3 z+B#&=ljL+dY`t!i_fp<*f|Ar&K=W@e?h2tz&7SUFk6IbNVA-G!PK?dcmHk9R?Z8HG z>GTnwTz3@QV>+w(Z7~`d%_ggyj(|phU1#mbi=1N7PF=`#vy^Ew(iAu~=#3@vQ6)u2w5($Qm(IR@MC}O^400_d*w|FD@=Q zD{T#Wq{)EysHrwPq+F*Lu;uydPxSRaf2ki|K5$`~F>p}L9G(UnrDrM2Q#y#~Fn4a~ zDCO7lRZz`w13PH7NbQlmxs@8w=a`+h0-~7FwsG1P#+=7^b;jONZ=Y4^Uc#-GsfloM$h0Bj4hnW3}+PjqD6mQRswF+%f0^V+V> zz9R7?sF}euUwog7YR{*!KtCU!x<311jVtPn;Pzm(M1Z|4r7<;`z+IbA= zbl;}j7DD879bD$}#0fO`GsMr^(%RiDPe#a1+WSw`;t8T_3f{XZ!gmwv^|JRQhv^EY zPq(tkN*U+U==qJ1ygY%CVVNrxFZ& z{;c%as^Q~(zbsCW@T}u?Vex!o%zjAGLJ|mo0|54UFj8E5;Jrg1(zgWd$XEQaKyF4Z z%mK|bcaXilgl|~>u29Sc2dl{>&AmIQ(6uV+FJaJlMTBX8U#3JRe2RN9E4$`%G{Kvc zFZu6ck>X+s*^8=%mWs@jUBijy1*~8&(t`h=F_j>$&;DY|tH6H%vfKe+yNAZ@N>0lW zOZzz|&<+}S+w$KS^IKviuKdFbjk242=nwDFRp6=G<~QEtLBCEbdb6m|bXXZB?z}z{ zB3KSGsphnGsI5RA4w8Wat^X&Z=K7293;2HP>P`bZ%5^UAsM2r0!OZG$UFM3$`xTFfnR5>xwpYU@X%?iqYsGOb4uAe_&>~|#7=wrY9-xk1UJ70 z>{0}N`a)rqlkL9y<~sm8l|HSU)hcFT^0jK-*bKEIr{NZZtcD|?+kuM2O+uU&?vUDP zu5S8ZdRA~PIW~V_SWzPB%jdCjN8L&k0Dn*DxU%}Wn?cT>Qa+E>`H42S%&TKIrs4?5+K2Dt zF;!XHUW9Rg6;w020?|&9TOx!e19sy60odOjtEf1^s<8}ixxIW9QJkQbzL4Dsd!lnd zPi2aKX*)AjI=n~@$P0u4>5U_gv zx}8S1VqxI+LhKwZb^}wB#D2J`xaxCMAcOxrIZ-Bv5H+j$qf7KDz&c*WXv+ldZ-!Q! zbO=ueN+F6T)FSsy>yB*%v|&fT>c|M&WE;C9IQ6deL=&T?k5R{aApqS1?35G-9KZXX zg^YD9LqI!G)AIU(Ae20Q-|G8IA2-v`SJk>lK%-&`rl#8UmqMVgy|pp(aopr^pmXBMcnRoqGJd6ltZkHZs3*fNu=eP@|) zgHORfK}G@NSh~Fx&}hlems>?N)+d6GRH@f+4)AIodK~}O>|SHsm$_%>K+4QdR}De= zNqS>HdfdgWGrJ}!MdBedDn*o?yoI>d%+#OwNCEC~#u;fYE{93oiah|lWy@h#DJKth z=I{payOfg&y9A8#0|w;g{8u&)Q0>2T2y9NG26w1$GS~Z>jC551qkz;O>8O@Hd>;J2 E0IrI5GXMYp literal 68047 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

BuU$UKj7~vt{tJwq8`7br?%v3KDo=Muuf~1w)uG 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 ZWJlcj%k39I1heM&QPbaZkDR~$e*mj+1l0fl diff --git a/docs/get-started/vue-component-meta-prop-types-controls.png b/docs/get-started/vue-component-meta-prop-types-controls.png new file mode 100644 index 0000000000000000000000000000000000000000..049bc595c2e90f37322f90a54f691fe47dd8cf66 GIT binary patch literal 15838 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

c; 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 JW1X|V{tqJhW?ldQ diff --git a/docs/get-started/vue-vite.md b/docs/get-started/vue3-vite.md similarity index 74% rename from docs/get-started/vue-vite.md rename to docs/get-started/vue3-vite.md index 6a52f84a47d0..edf881db500c 100644 --- a/docs/get-started/vue-vite.md +++ b/docs/get-started/vue3-vite.md @@ -9,9 +9,9 @@ Storybook for Vue & Vite is a [framework](../contribute/framework.md) that makes ## Requirements -- Vue >= 3 -- Vite >= 3.0 (4.X recommended) -- Storybook >= 7.0 +- Vue โ‰ฅ 3 +- Vite โ‰ฅ 3.0 (4.X recommended) +- Storybook โ‰ฅ 7.0 ## Getting started @@ -106,9 +106,13 @@ setup((app) => { ## Using `vue-component-meta` -[`vue-component-meta`](https://github.com/vuejs/language-tools/tree/master/packages/component-meta) is a tool that extracts metadata from Vue components which is maintained by the official Vue team. Storybook can use it to generate the [controls](../essentials/controls.md) for your stories and documentation. It's a more full-featured alternative to `vue-docgen-api` and is recommended for most projects. + + +`vue-component-meta` is only available in Storybook โ‰ฅ 8. It is currently opt-in, but will become the default in a future version of Storybook. -It requires Storybook >= 8. `vue-component-meta` is currently opt-in but will become the default in future versions of Storybook. + + +[`vue-component-meta`](https://github.com/vuejs/language-tools/tree/master/packages/component-meta) is a tool maintained by the Vue team that extracts metadata from Vue components. Storybook can use it to generate the [controls](../essentials/controls.md) for your stories and documentation. It's a more full-featured alternative to `vue-docgen-api` and is recommended for most projects. If you want to use `vue-component-meta`, you can configure it in your `.storybook/main.js|ts` file: @@ -143,44 +147,43 @@ To provide a description for a prop, including tags, you can use JSDoc comments ```html ``` -### Events types extraction - - +The props definition above will generate the following controls: -Due to technical limitations of Volar / vue language features, JSDoc descriptions for emitted events can not be extracted. +![Controls generated from props](./vue-component-meta-prop-types-controls.png) - +### Events types extraction -To provide a type for an emitted event, you can use TypeScript types in your component's `defineEmits` call: +To provide a type for an emitted event, you can use TypeScript types (including JSDoc comments) in your component's `defineEmits` call: ```html ``` -The definition above will generate the following controls: +If you use `defineSlots`, you can provide a description for each slot using JSDoc comments in your component's slots definition: -![Controls generated from slots](./vue-component-meta-slot-types-controls.png) - -If using `defineSlots`, the controls will even include the description: ```ts defineSlots<{ - /** Example description no-bind. */ - noBind(props: {}): any; - /** Example description default. */ + /** Example description for default */ default(props: { num: number }): any; - /** Example description named. */ + /** Example description for named */ named(props: { str: string }): any; - /** Example description vbind. */ + /** Example description for no-bind */ + noBind(props: {}): any; + /** Example description for vbind */ vbind(props: { num: number; str: string }): any; }>(); +``` + +The definition above will generate the following controls: + +![Controls generated from slots](./vue-component-meta-slot-types-controls.png) ### Exposed properties and methods @@ -240,13 +245,9 @@ The properties and methods exposed by your component are automatically extracted const count = ref(100); defineExpose({ - /** - * a label string - */ + /** A label string */ label, - /** - * a count number - */ + /** A count number */ count, }); @@ -256,6 +257,16 @@ The definition above will generate the following controls: ![Controls generated from exposed properties and methods](./vue-component-meta-exposed-types-controls.png) +### Limitations + +`vue-component-meta` cannot currently reference types from an import alias. You will need to replace any aliased imports with relative ones, as in the example below. See [this issue](https://github.com/vuejs/language-tools/issues/3896) for more information. + +```ts +// YourComponent.ts +import type { MyProps } from '@/types'; // โŒ Cannot be resolved +import type { MyProps } from '../types'; // โœ… Can be resolved +``` + ## API ### Options @@ -284,4 +295,6 @@ Type: `'vue-docgen-api' | 'vue-component-meta'` Default: `'vue-docgen-api'` +Since: `8.0` + Choose which docgen tool to use when generating controls for your components. See [Using `vue-component-meta`](#using-vue-component-meta) for more information. diff --git a/docs/toc.js b/docs/toc.js index a08a9a4a767e..a0d247bd9b8f 100644 --- a/docs/toc.js +++ b/docs/toc.js @@ -29,8 +29,8 @@ module.exports = { type: 'link', }, { - pathSegment: 'vue-vite', - title: 'vue-vite', + pathSegment: 'vue3-vite', + title: 'Vue & Vite', type: 'link', }, ], From b211ec1ccb7463640bece2bfc6edf2720bedc285 Mon Sep 17 00:00:00 2001 From: Kyle Gach Date: Thu, 29 Feb 2024 09:54:03 -0700 Subject: [PATCH 073/132] Add builder options details --- docs/get-started/nextjs.md | 2 +- docs/get-started/vue3-vite.md | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/docs/get-started/nextjs.md b/docs/get-started/nextjs.md index dc0bb08b8477..15a74b896968 100644 --- a/docs/get-started/nextjs.md +++ b/docs/get-started/nextjs.md @@ -920,7 +920,7 @@ The available options are: Type: `Record` -Configure options for the [framework's builder](../api/main-config-framework.md#optionsbuilder). For Next.js, that builder is Webpack 5. +Configure options for the [framework's builder](../api/main-config-framework.md#optionsbuilder). For Next.js, available options can be found in the [Webpack builder docs](../builders/webpack.md). #### `image` diff --git a/docs/get-started/vue3-vite.md b/docs/get-started/vue3-vite.md index edf881db500c..e14092a8c4e1 100644 --- a/docs/get-started/vue3-vite.md +++ b/docs/get-started/vue3-vite.md @@ -289,6 +289,12 @@ const config: StorybookConfig = { export default config; ``` +#### `builder` + +Type: `Record` + +Configure options for the [framework's builder](../api/main-config-framework.md#optionsbuilder). For this framework, available options can be found in the [Vite builder docs](../builders/vite.md). + #### `docgen` Type: `'vue-docgen-api' | 'vue-component-meta'` From 28207a486a1a823be1d5dd5579399b0eef0e98b6 Mon Sep 17 00:00:00 2001 From: Kyle Gach Date: Thu, 29 Feb 2024 10:05:00 -0700 Subject: [PATCH 074/132] Address TKs --- docs/get-started/nextjs.md | 2 +- docs/get-started/vue3-vite.md | 10 ++++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/docs/get-started/nextjs.md b/docs/get-started/nextjs.md index 15a74b896968..126a22c98c13 100644 --- a/docs/get-started/nextjs.md +++ b/docs/get-started/nextjs.md @@ -38,7 +38,7 @@ Follow the prompts after running this command in your Next.js project's root dir ### In a project with Storybook -This framework is designed to work with Storybook 7. If youโ€™re not already using v7, upgrade with this command: +This framework is designed to work with Storybook 7+. If youโ€™re not already using v7, upgrade with this command: diff --git a/docs/get-started/vue3-vite.md b/docs/get-started/vue3-vite.md index e14092a8c4e1..25d6a0dcf503 100644 --- a/docs/get-started/vue3-vite.md +++ b/docs/get-started/vue3-vite.md @@ -2,9 +2,11 @@ title: Storybook for Vue & Vite --- -Storybook for Vue & Vite is a [framework](../contribute/framework.md) that makes it easy to develop and test UI components in isolation for [Vue](TK) applications built with [Vite](TK). It includes: +Storybook for Vue & Vite is a [framework](../contribute/framework.md) that makes it easy to develop and test UI components in isolation for [Vue](https://vuejs.org/) applications built with [Vite](https://vitejs.dev/). It includes: -- TK - Emoji feature list +- ๐ŸŽ๏ธ Pre-bundled for performance +- ๐Ÿช„ Zero config +- ๐Ÿง  Comprehensive docgen - ๐Ÿ’ซ and more! ## Requirements @@ -17,7 +19,7 @@ Storybook for Vue & Vite is a [framework](../contribute/framework.md) that makes ### In a project without Storybook -Follow the prompts after running this command in your Next.js project's root directory: +Follow the prompts after running this command in your Vue project's root directory: @@ -35,7 +37,7 @@ Follow the prompts after running this command in your Next.js project's root dir ### In a project with Storybook -This framework is designed to work with Storybook 7. If youโ€™re not already using v7, upgrade with this command: +This framework is designed to work with Storybook 7+. If youโ€™re not already using v7, upgrade with this command: From 19044b8edf8c8058c78f71a4297da79958ab8d8d Mon Sep 17 00:00:00 2001 From: Kyle Gach Date: Tue, 5 Mar 2024 12:54:09 -0700 Subject: [PATCH 075/132] Make content conditional on required renderer --- docs/get-started/nextjs.md | 20 ++++++++++++++++++++ docs/get-started/vue3-vite.md | 20 ++++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/docs/get-started/nextjs.md b/docs/get-started/nextjs.md index 126a22c98c13..14b9a0bbb040 100644 --- a/docs/get-started/nextjs.md +++ b/docs/get-started/nextjs.md @@ -2,6 +2,8 @@ title: Storybook for Next.js --- +export const SUPPORTED_RENDERER = 'react'; + Storybook for Next.js is a [framework](../contribute/framework.md) that makes it easy to develop and test UI components in isolation for [Next.js](https://nextjs.org/) applications. It includes: - ๐Ÿ”€ Routing @@ -11,6 +13,20 @@ Storybook for Next.js is a [framework](../contribute/framework.md) that makes it - ๐ŸŽ› Webpack & Babel config - ๐Ÿ’ซ and more! + + + + +Storybook for Next.js is only supported in [React](?renderer=react) projects. + + + + + + + + + ## Requirements - Next.js โ‰ฅ 13.5 @@ -933,3 +949,7 @@ Props to pass to every instance of `next/image`. See [next/image docs](https://n Type: `string` The absolute path to the `next.config.js` file. This is necessary if you have a custom `next.config.js` file that is not in the root directory of your project. + + + + diff --git a/docs/get-started/vue3-vite.md b/docs/get-started/vue3-vite.md index 25d6a0dcf503..0418e80a7d56 100644 --- a/docs/get-started/vue3-vite.md +++ b/docs/get-started/vue3-vite.md @@ -2,6 +2,8 @@ title: Storybook for Vue & Vite --- +export const SUPPORTED_RENDERER = 'vue'; + Storybook for Vue & Vite is a [framework](../contribute/framework.md) that makes it easy to develop and test UI components in isolation for [Vue](https://vuejs.org/) applications built with [Vite](https://vitejs.dev/). It includes: - ๐ŸŽ๏ธ Pre-bundled for performance @@ -9,6 +11,20 @@ Storybook for Vue & Vite is a [framework](../contribute/framework.md) that makes - ๐Ÿง  Comprehensive docgen - ๐Ÿ’ซ and more! + + + + +Storybook for Vue & Vite is only supported in [Vue](?renderer=vue) projects. + + + + + + + + + ## Requirements - Vue โ‰ฅ 3 @@ -306,3 +322,7 @@ Default: `'vue-docgen-api'` Since: `8.0` Choose which docgen tool to use when generating controls for your components. See [Using `vue-component-meta`](#using-vue-component-meta) for more information. + + + + From ecb85370d425e62d015b8d425ba72610e162c079 Mon Sep 17 00:00:00 2001 From: Kyle Gach Date: Tue, 5 Mar 2024 12:58:30 -0700 Subject: [PATCH 076/132] Replace README --- code/frameworks/vue3-vite/README.md | 45 ++--------------------------- 1 file changed, 2 insertions(+), 43 deletions(-) diff --git a/code/frameworks/vue3-vite/README.md b/code/frameworks/vue3-vite/README.md index bb1eb15f980e..08eb5ae95c13 100644 --- a/code/frameworks/vue3-vite/README.md +++ b/code/frameworks/vue3-vite/README.md @@ -1,44 +1,3 @@ -# Storybook for Vue 3 and Vite +# Storybook for Vue and Vite -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-vue3-app -npx storybook@latest init -``` - -For more information visit: [storybook.js.org](https://storybook.js.org) - ---- - -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/sharing/publish-storybook) of your Storybook and deploy it anywhere you want. - -## Extending the Vue application - -Storybook creates a [Vue 3 application](https://vuejs.org/api/application.html#application-api) for your component preview. -When using global custom components (`app.component`), directives (`app.directive`), extensions (`app.use`), or other application methods, you will need to configure those in the `./storybook/preview.js` file. - -Therefore, Storybook provides you with a `setup` function exported from this package, which receives as a callback your Storybook instance, which you can interact with and add your custom configuration. - -```js -// .storybook/preview.js - -import { setup } from '@storybook/vue3'; - -setup((app) => { - app.use(MyPlugin); - app.component('my-component', MyComponent); - app.mixin({ - /* My mixin */ - }); -}); -``` +See [documentation](https://storybook.js.org/docs/8.0/get-started/vue3-vite?renderer=vue) for installation instructions, usage examples, APIs, and more. From 5c269f247491bfe71160c7ce131b093309bbc080 Mon Sep 17 00:00:00 2001 From: Kyle Gach Date: Wed, 6 Mar 2024 13:49:20 -0700 Subject: [PATCH 077/132] Add troubleshooting --- docs/get-started/nextjs.md | 8 ++++++++ docs/get-started/vue3-vite.md | 18 ++++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/docs/get-started/nextjs.md b/docs/get-started/nextjs.md index 14b9a0bbb040..6cbd4ac91177 100644 --- a/docs/get-started/nextjs.md +++ b/docs/get-started/nextjs.md @@ -114,6 +114,14 @@ Finally, if you were using Storybook plugins to integrate with Next.js, those ar +## Run the Setup Wizard + +If all goes well, you should see a setup wizard that will help you get started with Storybook introducing you to the main concepts and features, including how the UI is organized, how to write your first story, and how to test your components' response to various inputs utilizing [controls](../essentials/controls). + +![Storybook onboarding](./example-onboarding-wizard.png) + +If you skipped the wizard, you can always run it again by adding the `?path=/onboarding` query parameter to the URL of your Storybook instance, provided that the example stories are still available. + ## Next.js's Image component This framework allows you to use Next.js's [next/image](https://nextjs.org/docs/pages/api-reference/components/image) with no configuration. diff --git a/docs/get-started/vue3-vite.md b/docs/get-started/vue3-vite.md index 0418e80a7d56..e79cc1f3b6fc 100644 --- a/docs/get-started/vue3-vite.md +++ b/docs/get-started/vue3-vite.md @@ -285,6 +285,24 @@ import type { MyProps } from '@/types'; // โŒ Cannot be resolved import type { MyProps } from '../types'; // โœ… Can be resolved ``` +## Troubleshooting + +### Storybook doesn't work with my Vue 2 project + +[Vue 2 entered End of Life](https://v2.vuejs.org/lts/) (EOL) on December 31st, 2023, and is no longer maintained by the Vue team. As a result, Storybook no longer supports Vue 2. We recommend you upgrade your project to Vue 3, which Storybook fully supports. If that's not an option, you can still use Storybook with Vue 2 by installing the latest version of Storybook 7 with the following command: + + + + + + + ## API ### Options From c6ad7e22a035bfc6620bdad6f8a8b7265913e53f Mon Sep 17 00:00:00 2001 From: Michael Shilman Date: Thu, 7 Mar 2024 10:55:41 +0800 Subject: [PATCH 078/132] Viewport: Fix editing when default viewport is set --- code/addons/viewport/src/Tool.tsx | 12 ++++++++++-- code/e2e-tests/addon-viewport.spec.ts | 22 ++++++++++++++++++++++ 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/code/addons/viewport/src/Tool.tsx b/code/addons/viewport/src/Tool.tsx index 9eccf0e8bff3..78788323e431 100644 --- a/code/addons/viewport/src/Tool.tsx +++ b/code/addons/viewport/src/Tool.tsx @@ -136,7 +136,7 @@ export const ViewportTool: FC = memo( useEffect(() => { registerShortcuts(api, globals, updateGlobals, Object.keys(viewports)); - }, [viewports, globals.viewport]); + }, [viewports, globals, globals.viewport, updateGlobals, api]); useEffect(() => { const defaultRotated = defaultOrientation === 'landscape'; @@ -150,7 +150,15 @@ export const ViewportTool: FC = memo( viewportRotated: defaultRotated, }); } - }, [defaultOrientation, defaultViewport, globals, updateGlobals]); + // NOTE: we don't want to re-run this effect when `globals` changes + // due to https://github.com/storybookjs/storybook/issues/26334 + // + // Ultimately this process of "locking in" a parameter value should be + // replaced by https://github.com/storybookjs/storybook/discussions/23347 + // or something similar. + // + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [defaultOrientation, defaultViewport, updateGlobals]); const item = list.find((i) => i.id === globals.viewport) || diff --git a/code/e2e-tests/addon-viewport.spec.ts b/code/e2e-tests/addon-viewport.spec.ts index ec96a3bd93ea..64f8eb097dfb 100644 --- a/code/e2e-tests/addon-viewport.spec.ts +++ b/code/e2e-tests/addon-viewport.spec.ts @@ -40,4 +40,26 @@ test.describe('addon-viewport', () => { // Compare the two widths await expect(adjustedDimensions?.width).not.toBe(originalDimensions?.width); }); + + test('viewport should be editable when a default viewport is set', async ({ page }) => { + const sbPage = new SbPage(page); + + // Story parameters/selected is set to small mobile + await sbPage.navigateToStory('addons/viewport/parameters', 'selected'); + + // Measure the original dimensions of previewRoot + const originalDimensions = await sbPage.getCanvasBodyElement().boundingBox(); + await expect(originalDimensions?.width).toBeDefined(); + + // Manually select "large mobile" and give it time to adjust + await sbPage.selectToolbar('[title="Change the size of the preview"]', '#list-item-mobile2'); + await new Promise((r) => setTimeout(r, 200)); + + // Measure the adjusted dimensions of previewRoot after clicking the mobile item. + const adjustedDimensions = await sbPage.getCanvasBodyElement().boundingBox(); + await expect(adjustedDimensions?.width).toBeDefined(); + + // Compare the two widths + await expect(adjustedDimensions?.width).not.toBe(originalDimensions?.width); + }); }); From fd4c51559290ce1de81ec15ac90758c8bb3ef3d1 Mon Sep 17 00:00:00 2001 From: Michael Shilman Date: Thu, 7 Mar 2024 11:14:54 +0800 Subject: [PATCH 079/132] Update code/addons/viewport/src/Tool.tsx Co-authored-by: Tom Coleman --- code/addons/viewport/src/Tool.tsx | 3 +++ 1 file changed, 3 insertions(+) diff --git a/code/addons/viewport/src/Tool.tsx b/code/addons/viewport/src/Tool.tsx index 78788323e431..37bc22500e9b 100644 --- a/code/addons/viewport/src/Tool.tsx +++ b/code/addons/viewport/src/Tool.tsx @@ -153,6 +153,9 @@ export const ViewportTool: FC = memo( // NOTE: we don't want to re-run this effect when `globals` changes // due to https://github.com/storybookjs/storybook/issues/26334 // + // Also, this *will* rerun every time you change story as the parameter is briefly `undefined`. + // This behaviour is intentional, if a bit of a happy accident in implementation. + // // Ultimately this process of "locking in" a parameter value should be // replaced by https://github.com/storybookjs/storybook/discussions/23347 // or something similar. From 5ca24660935f7797ac0f1c65d391996f5119992a Mon Sep 17 00:00:00 2001 From: Valentin Palkovic Date: Thu, 7 Mar 2024 09:46:22 +0100 Subject: [PATCH 080/132] Core: Fix path separator issue in check-addon-order --- .../utils/__tests__/check-addon-order.test.ts | 17 +++++++++++++++++ .../core-common/src/utils/check-addon-order.ts | 2 +- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/code/lib/core-common/src/utils/__tests__/check-addon-order.test.ts b/code/lib/core-common/src/utils/__tests__/check-addon-order.test.ts index 692402ba5844..db4820b02ec6 100644 --- a/code/lib/core-common/src/utils/__tests__/check-addon-order.test.ts +++ b/code/lib/core-common/src/utils/__tests__/check-addon-order.test.ts @@ -17,6 +17,7 @@ const essentialAddons = [ 'toolbars', 'measure', 'outline', + 'highlight', ]; const pkgName = (entry: CoreCommon_AddonEntry): string => { @@ -42,6 +43,22 @@ afterEach(() => { describe.each([ ['docs', 'controls', ['docs', 'controls']], ['docs', 'controls', ['docs', 'foo/node_modules/@storybook/addon-controls']], + [ + 'actions', + 'interactions', + [ + 'foo\\node_modules\\@storybook\\addon-essentials', + 'foo\\node_modules\\@storybook\\addon-interactions', + ], + ], + [ + 'actions', + 'interactions', + [ + 'foo\\\\node_modules\\\\@storybook\\\\addon-essentials', + 'foo\\\\node_modules\\\\@storybook\\\\addon-interactions', + ], + ], ['docs', 'controls', [{ name: '@storybook/addon-docs' }, 'controls']], ['docs', 'controls', ['essentials', 'controls']], ['docs', 'controls', ['essentials']], diff --git a/code/lib/core-common/src/utils/check-addon-order.ts b/code/lib/core-common/src/utils/check-addon-order.ts index 58faeccee228..b91c93e7df02 100644 --- a/code/lib/core-common/src/utils/check-addon-order.ts +++ b/code/lib/core-common/src/utils/check-addon-order.ts @@ -15,7 +15,7 @@ interface Options { const predicateFor = (addon: string) => (entry: CoreCommon_AddonEntry) => { const name = (entry as CoreCommon_OptionsEntry).name || (entry as string); - return name && name.includes(addon); + return name && name.replaceAll(/(\\){1,2}/g, '/').includes(addon); }; const isCorrectOrder = ( From ef92b276e0dd6421e48fb0adb367c4d8f8129e5c Mon Sep 17 00:00:00 2001 From: storybook-bot <32066757+storybook-bot@users.noreply.github.com> Date: Thu, 7 Mar 2024 09:29:07 +0000 Subject: [PATCH 081/132] Write changelog for 8.0.0-rc.3 [skip ci] --- CHANGELOG.prerelease.md | 11 +++++++++++ code/package.json | 3 ++- docs/versions/next.json | 2 +- 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.prerelease.md b/CHANGELOG.prerelease.md index dce7c33f53c7..fce4b4696b3a 100644 --- a/CHANGELOG.prerelease.md +++ b/CHANGELOG.prerelease.md @@ -1,3 +1,14 @@ +## 8.0.0-rc.3 + +- Addon-themes: Fix switcher initialization after first start - [#26353](https://github.com/storybookjs/storybook/pull/26353), thanks @valentinpalkovic! +- Build: Upgrade `esbuild` (`0.20.1`) - [#26255](https://github.com/storybookjs/storybook/pull/26255), thanks @43081j! +- Core: Fix path separator issue in check-addon-order - [#26362](https://github.com/storybookjs/storybook/pull/26362), thanks @valentinpalkovic! +- Dependencies: Remove `qs` from `@storybook/manager-api` & `@storybook/channels` - [#26285](https://github.com/storybookjs/storybook/pull/26285), thanks @43081j! +- UI: Fix sidebar scrolling to selected story when state changes - [#26337](https://github.com/storybookjs/storybook/pull/26337), thanks @JReinhold! +- UI: Remove 'left' property from TooltipLinkList and Link components - [#26324](https://github.com/storybookjs/storybook/pull/26324), thanks @valentinpalkovic! +- Viewport: Fix editing when default viewport is set - [#26360](https://github.com/storybookjs/storybook/pull/26360), thanks @shilman! +- Vue: Fix reference error when using re-exports with "vue-component-meta" - [#26303](https://github.com/storybookjs/storybook/pull/26303), thanks @larsrickert! + ## 8.0.0-rc.2 - CLI: Add @storybook/addons automigration - [#26295](https://github.com/storybookjs/storybook/pull/26295), thanks [@valentinpalkovic](https://github.com/valentinpalkovic)! diff --git a/code/package.json b/code/package.json index 7b888ff6e9d2..0719457b9ea4 100644 --- a/code/package.json +++ b/code/package.json @@ -294,5 +294,6 @@ "Dependency Upgrades" ] ] - } + }, + "deferredNextVersion": "8.0.0-rc.3" } diff --git a/docs/versions/next.json b/docs/versions/next.json index aefc27f51f56..4de1279548ea 100644 --- a/docs/versions/next.json +++ b/docs/versions/next.json @@ -1 +1 @@ -{"version":"8.0.0-rc.2","info":{"plain":"- CLI: Add @storybook/addons automigration - [#26295](https://github.com/storybookjs/storybook/pull/26295), thanks [@valentinpalkovic](https://github.com/valentinpalkovic)!\n- CLI: Fix vite config automigration to resolve from project root - [#26262](https://github.com/storybookjs/storybook/pull/26262), thanks [@valentinpalkovic](https://github.com/valentinpalkovic)!\n- CLI: Improve `add` command & add tests - [#26298](https://github.com/storybookjs/storybook/pull/26298), thanks [@ndelangen](https://github.com/ndelangen)!\n- CLI: Update minimum Node.js version requirement - [#26312](https://github.com/storybookjs/storybook/pull/26312), thanks [@valentinpalkovic](https://github.com/valentinpalkovic)!\n- CSF-tools/Codemods: Upgrade recast - [#26286](https://github.com/storybookjs/storybook/pull/26286), thanks [@43081j](https://github.com/43081j)!\n- Controls: Fix type summary when table.type unset - [#26283](https://github.com/storybookjs/storybook/pull/26283), thanks [@shilman](https://github.com/shilman)!\n- Core: Add event when serverChannel disconnects - [#26322](https://github.com/storybookjs/storybook/pull/26322), thanks [@ndelangen](https://github.com/ndelangen)!\n- Core: Fix composition of storybooks on same origin - [#26304](https://github.com/storybookjs/storybook/pull/26304), thanks [@ndelangen](https://github.com/ndelangen)!\n- Portable stories: Improve existing APIs, add loaders support - [#26267](https://github.com/storybookjs/storybook/pull/26267), thanks [@yannbf](https://github.com/yannbf)!\n- React: Handle TypeScript path aliases in react-docgen loader - [#26273](https://github.com/storybookjs/storybook/pull/26273), thanks [@valentinpalkovic](https://github.com/valentinpalkovic)!\n- Svelte: Support `5.0.0-next.65` prerelease - [#26188](https://github.com/storybookjs/storybook/pull/26188), thanks [@JReinhold](https://github.com/JReinhold)!\n- Upgrade: Add missing isUpgrade parameter to automigrate function - [#26293](https://github.com/storybookjs/storybook/pull/26293), thanks [@valentinpalkovic](https://github.com/valentinpalkovic)!\n- Vue: Return component from `composeStory` - [#26317](https://github.com/storybookjs/storybook/pull/26317), thanks [@JReinhold](https://github.com/JReinhold)!"}} +{"version":"8.0.0-rc.3","info":{"plain":"- Addon-themes: Fix switcher initialization after first start - [#26353](https://github.com/storybookjs/storybook/pull/26353), thanks @valentinpalkovic!\n- Build: Upgrade `esbuild` (`0.20.1`) - [#26255](https://github.com/storybookjs/storybook/pull/26255), thanks @43081j!\n- Core: Fix path separator issue in check-addon-order - [#26362](https://github.com/storybookjs/storybook/pull/26362), thanks @valentinpalkovic!\n- Dependencies: Remove `qs` from `@storybook/manager-api` & `@storybook/channels` - [#26285](https://github.com/storybookjs/storybook/pull/26285), thanks @43081j!\n- UI: Fix sidebar scrolling to selected story when state changes - [#26337](https://github.com/storybookjs/storybook/pull/26337), thanks @JReinhold!\n- UI: Remove 'left' property from TooltipLinkList and Link components - [#26324](https://github.com/storybookjs/storybook/pull/26324), thanks @valentinpalkovic!\n- Viewport: Fix editing when default viewport is set - [#26360](https://github.com/storybookjs/storybook/pull/26360), thanks @shilman!\n- Vue: Fix reference error when using re-exports with \\\"vue-component-meta\\\" - [#26303](https://github.com/storybookjs/storybook/pull/26303), thanks @larsrickert!"}} From 8f3b3b84eef04798c043eadb7cfe9b299740177d Mon Sep 17 00:00:00 2001 From: Yann Braga Date: Thu, 7 Mar 2024 11:30:41 +0100 Subject: [PATCH 082/132] CLI: Fix doctor compatibility check --- .../src/doctor/getIncompatibleStorybookPackages.ts | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/code/lib/cli/src/doctor/getIncompatibleStorybookPackages.ts b/code/lib/cli/src/doctor/getIncompatibleStorybookPackages.ts index d27694136074..09f0c40d5bb9 100644 --- a/code/lib/cli/src/doctor/getIncompatibleStorybookPackages.ts +++ b/code/lib/cli/src/doctor/getIncompatibleStorybookPackages.ts @@ -19,12 +19,6 @@ type Context = { skipErrors?: boolean; }; -const isPackageIncompatible = (installedVersion: string, currentStorybookVersion: string) => { - const storybookVersion = semver.coerce(currentStorybookVersion); - const packageVersion = semver.coerce(installedVersion); - return storybookVersion?.major !== packageVersion?.major; -}; - export const checkPackageCompatibility = async (dependency: string, context: Context) => { const { currentStorybookVersion, skipErrors, packageManager } = context; try { @@ -46,12 +40,12 @@ export const checkPackageCompatibility = async (dependency: string, context: Con ...peerDependencies, }) .filter(([dep]) => storybookCorePackages[dep as keyof typeof storybookCorePackages]) - .find(([, version]) => { + .find(([_, versionRange]) => { // prevent issues with "tag" based versions e.g. "latest" or "next" instead of actual numbers return ( - version && - semver.validRange(version) && - isPackageIncompatible(version, currentStorybookVersion) + versionRange && + semver.validRange(versionRange) && + !semver.satisfies(currentStorybookVersion, versionRange) ); }); From d6f8526ad1b14914eb1156f6d0d62fe6ddbadffd Mon Sep 17 00:00:00 2001 From: storybook-bot <32066757+storybook-bot@users.noreply.github.com> Date: Thu, 7 Mar 2024 11:11:50 +0000 Subject: [PATCH 083/132] Bump version from "8.0.0-rc.2" to "8.0.0-rc.3" [skip ci] --- code/addons/a11y/package.json | 2 +- code/addons/actions/package.json | 2 +- code/addons/backgrounds/package.json | 2 +- code/addons/controls/package.json | 2 +- code/addons/docs/package.json | 2 +- code/addons/essentials/package.json | 2 +- code/addons/gfm/package.json | 2 +- code/addons/highlight/package.json | 2 +- code/addons/interactions/package.json | 2 +- code/addons/jest/package.json | 2 +- code/addons/links/package.json | 2 +- code/addons/measure/package.json | 2 +- code/addons/onboarding/package.json | 2 +- code/addons/outline/package.json | 2 +- code/addons/storysource/package.json | 2 +- code/addons/themes/package.json | 2 +- code/addons/toolbars/package.json | 2 +- code/addons/viewport/package.json | 2 +- code/builders/builder-manager/package.json | 2 +- code/builders/builder-vite/package.json | 2 +- code/builders/builder-webpack5/package.json | 2 +- code/frameworks/angular/package.json | 2 +- code/frameworks/ember/package.json | 2 +- code/frameworks/html-vite/package.json | 2 +- code/frameworks/html-webpack5/package.json | 2 +- code/frameworks/nextjs/package.json | 2 +- code/frameworks/preact-vite/package.json | 2 +- code/frameworks/preact-webpack5/package.json | 2 +- code/frameworks/react-vite/package.json | 2 +- code/frameworks/react-webpack5/package.json | 2 +- code/frameworks/server-webpack5/package.json | 2 +- code/frameworks/svelte-vite/package.json | 2 +- code/frameworks/svelte-webpack5/package.json | 2 +- code/frameworks/sveltekit/package.json | 2 +- code/frameworks/vue3-vite/package.json | 2 +- code/frameworks/vue3-webpack5/package.json | 2 +- .../web-components-vite/package.json | 2 +- .../web-components-webpack5/package.json | 2 +- code/lib/channels/package.json | 2 +- code/lib/cli-sb/package.json | 2 +- code/lib/cli-storybook/package.json | 2 +- code/lib/cli/package.json | 2 +- code/lib/client-logger/package.json | 2 +- code/lib/codemod/package.json | 2 +- code/lib/core-common/package.json | 2 +- code/lib/core-common/src/versions.ts | 160 +++++++++--------- code/lib/core-events/package.json | 2 +- code/lib/core-server/package.json | 2 +- code/lib/core-webpack/package.json | 2 +- code/lib/csf-plugin/package.json | 2 +- code/lib/csf-tools/package.json | 2 +- code/lib/docs-tools/package.json | 2 +- code/lib/instrumenter/package.json | 2 +- code/lib/manager-api/package.json | 2 +- code/lib/manager-api/src/version.ts | 2 +- code/lib/node-logger/package.json | 2 +- code/lib/preview-api/package.json | 2 +- code/lib/preview/package.json | 2 +- code/lib/react-dom-shim/package.json | 2 +- code/lib/router/package.json | 2 +- code/lib/source-loader/package.json | 2 +- code/lib/telemetry/package.json | 2 +- code/lib/test/package.json | 2 +- code/lib/theming/package.json | 2 +- code/lib/types/package.json | 2 +- code/package.json | 5 +- code/presets/create-react-app/package.json | 2 +- code/presets/html-webpack/package.json | 2 +- code/presets/preact-webpack/package.json | 2 +- code/presets/react-webpack/package.json | 2 +- code/presets/server-webpack/package.json | 2 +- code/presets/svelte-webpack/package.json | 2 +- code/presets/vue3-webpack/package.json | 2 +- code/renderers/html/package.json | 2 +- code/renderers/preact/package.json | 2 +- code/renderers/react/package.json | 2 +- code/renderers/server/package.json | 2 +- code/renderers/svelte/package.json | 2 +- code/renderers/vue3/package.json | 2 +- code/renderers/web-components/package.json | 2 +- code/ui/blocks/package.json | 2 +- code/ui/components/package.json | 2 +- code/ui/manager/package.json | 2 +- 83 files changed, 163 insertions(+), 164 deletions(-) diff --git a/code/addons/a11y/package.json b/code/addons/a11y/package.json index abe43c249f6b..62524c1e5a07 100644 --- a/code/addons/a11y/package.json +++ b/code/addons/a11y/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/addon-a11y", - "version": "8.0.0-rc.2", + "version": "8.0.0-rc.3", "description": "Test component compliance with web accessibility standards", "keywords": [ "a11y", diff --git a/code/addons/actions/package.json b/code/addons/actions/package.json index 5dcdd61e3c52..19af94829530 100644 --- a/code/addons/actions/package.json +++ b/code/addons/actions/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/addon-actions", - "version": "8.0.0-rc.2", + "version": "8.0.0-rc.3", "description": "Get UI feedback when an action is performed on an interactive element", "keywords": [ "storybook", diff --git a/code/addons/backgrounds/package.json b/code/addons/backgrounds/package.json index 17a842b06f13..92c0fb53d8c3 100644 --- a/code/addons/backgrounds/package.json +++ b/code/addons/backgrounds/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/addon-backgrounds", - "version": "8.0.0-rc.2", + "version": "8.0.0-rc.3", "description": "Switch backgrounds to view components in different settings", "keywords": [ "addon", diff --git a/code/addons/controls/package.json b/code/addons/controls/package.json index 3df650748609..660b10007fd1 100644 --- a/code/addons/controls/package.json +++ b/code/addons/controls/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/addon-controls", - "version": "8.0.0-rc.2", + "version": "8.0.0-rc.3", "description": "Interact with component inputs dynamically in the Storybook UI", "keywords": [ "addon", diff --git a/code/addons/docs/package.json b/code/addons/docs/package.json index a74ff2e67653..a902a49bae81 100644 --- a/code/addons/docs/package.json +++ b/code/addons/docs/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/addon-docs", - "version": "8.0.0-rc.2", + "version": "8.0.0-rc.3", "description": "Document component usage and properties in Markdown", "keywords": [ "addon", diff --git a/code/addons/essentials/package.json b/code/addons/essentials/package.json index 5b01bbd974b1..8448dbe7e5b3 100644 --- a/code/addons/essentials/package.json +++ b/code/addons/essentials/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/addon-essentials", - "version": "8.0.0-rc.2", + "version": "8.0.0-rc.3", "description": "Curated addons to bring out the best of Storybook", "keywords": [ "addon", diff --git a/code/addons/gfm/package.json b/code/addons/gfm/package.json index 031416826745..a8a8cfbc87e9 100644 --- a/code/addons/gfm/package.json +++ b/code/addons/gfm/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/addon-mdx-gfm", - "version": "8.0.0-rc.2", + "version": "8.0.0-rc.3", "description": "GitHub Flavored Markdown in Storybook", "keywords": [ "addon", diff --git a/code/addons/highlight/package.json b/code/addons/highlight/package.json index e4802d08da43..19aa4b82b078 100644 --- a/code/addons/highlight/package.json +++ b/code/addons/highlight/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/addon-highlight", - "version": "8.0.0-rc.2", + "version": "8.0.0-rc.3", "description": "Highlight DOM nodes within your stories", "keywords": [ "storybook-addons", diff --git a/code/addons/interactions/package.json b/code/addons/interactions/package.json index 29d753da6fbf..4a7f597bbcb5 100644 --- a/code/addons/interactions/package.json +++ b/code/addons/interactions/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/addon-interactions", - "version": "8.0.0-rc.2", + "version": "8.0.0-rc.3", "description": "Automate, test and debug user interactions", "keywords": [ "storybook-addons", diff --git a/code/addons/jest/package.json b/code/addons/jest/package.json index 7284de78eec3..735dcb6d72d2 100644 --- a/code/addons/jest/package.json +++ b/code/addons/jest/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/addon-jest", - "version": "8.0.0-rc.2", + "version": "8.0.0-rc.3", "description": "React storybook addon that show component jest report", "keywords": [ "addon", diff --git a/code/addons/links/package.json b/code/addons/links/package.json index a23690c6e9b2..1f09384575a8 100644 --- a/code/addons/links/package.json +++ b/code/addons/links/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/addon-links", - "version": "8.0.0-rc.2", + "version": "8.0.0-rc.3", "description": "Link stories together to build demos and prototypes with your UI components", "keywords": [ "addon", diff --git a/code/addons/measure/package.json b/code/addons/measure/package.json index 843dd37f5197..67e401c94f00 100644 --- a/code/addons/measure/package.json +++ b/code/addons/measure/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/addon-measure", - "version": "8.0.0-rc.2", + "version": "8.0.0-rc.3", "description": "Inspect layouts by visualizing the box model", "keywords": [ "storybook-addons", diff --git a/code/addons/onboarding/package.json b/code/addons/onboarding/package.json index 5064aa48addb..668d04b45220 100644 --- a/code/addons/onboarding/package.json +++ b/code/addons/onboarding/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/addon-onboarding", - "version": "8.0.0-rc.2", + "version": "8.0.0-rc.3", "description": "Storybook Addon Onboarding - Introduces a new onboarding experience", "keywords": [ "storybook-addons", diff --git a/code/addons/outline/package.json b/code/addons/outline/package.json index b5b5771d6049..b9f7ec636092 100644 --- a/code/addons/outline/package.json +++ b/code/addons/outline/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/addon-outline", - "version": "8.0.0-rc.2", + "version": "8.0.0-rc.3", "description": "Outline all elements with CSS to help with layout placement and alignment", "keywords": [ "storybook-addons", diff --git a/code/addons/storysource/package.json b/code/addons/storysource/package.json index e060751d1a6f..c4f444ea8bf1 100644 --- a/code/addons/storysource/package.json +++ b/code/addons/storysource/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/addon-storysource", - "version": "8.0.0-rc.2", + "version": "8.0.0-rc.3", "description": "View a storyโ€™s source code to see how it works and paste into your app", "keywords": [ "addon", diff --git a/code/addons/themes/package.json b/code/addons/themes/package.json index a13dcf595c17..d166a0ac638e 100644 --- a/code/addons/themes/package.json +++ b/code/addons/themes/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/addon-themes", - "version": "8.0.0-rc.2", + "version": "8.0.0-rc.3", "description": "Switch between multiple themes for you components in Storybook", "keywords": [ "css", diff --git a/code/addons/toolbars/package.json b/code/addons/toolbars/package.json index b1bdae2a70cd..885e2aab0788 100644 --- a/code/addons/toolbars/package.json +++ b/code/addons/toolbars/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/addon-toolbars", - "version": "8.0.0-rc.2", + "version": "8.0.0-rc.3", "description": "Create your own toolbar items that control story rendering", "keywords": [ "addon", diff --git a/code/addons/viewport/package.json b/code/addons/viewport/package.json index ae6af334349d..72393389d5e0 100644 --- a/code/addons/viewport/package.json +++ b/code/addons/viewport/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/addon-viewport", - "version": "8.0.0-rc.2", + "version": "8.0.0-rc.3", "description": "Build responsive components by adjusting Storybookโ€™s viewport size and orientation", "keywords": [ "addon", diff --git a/code/builders/builder-manager/package.json b/code/builders/builder-manager/package.json index c53e7272fb60..637cdaf29eb3 100644 --- a/code/builders/builder-manager/package.json +++ b/code/builders/builder-manager/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/builder-manager", - "version": "8.0.0-rc.2", + "version": "8.0.0-rc.3", "description": "Storybook manager builder", "keywords": [ "storybook" diff --git a/code/builders/builder-vite/package.json b/code/builders/builder-vite/package.json index affa9c2fa59b..e0fa92542ade 100644 --- a/code/builders/builder-vite/package.json +++ b/code/builders/builder-vite/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/builder-vite", - "version": "8.0.0-rc.2", + "version": "8.0.0-rc.3", "description": "A plugin to run and build Storybooks with Vite", "homepage": "https://github.com/storybookjs/storybook/tree/next/code/builders/builder-vite/#readme", "bugs": { diff --git a/code/builders/builder-webpack5/package.json b/code/builders/builder-webpack5/package.json index 9565198092f8..27484944fc21 100644 --- a/code/builders/builder-webpack5/package.json +++ b/code/builders/builder-webpack5/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/builder-webpack5", - "version": "8.0.0-rc.2", + "version": "8.0.0-rc.3", "description": "Storybook framework-agnostic API", "keywords": [ "storybook" diff --git a/code/frameworks/angular/package.json b/code/frameworks/angular/package.json index 8639c28d08c2..17a361b060f4 100644 --- a/code/frameworks/angular/package.json +++ b/code/frameworks/angular/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/angular", - "version": "8.0.0-rc.2", + "version": "8.0.0-rc.3", "description": "Storybook for Angular: Develop Angular components in isolation with hot reloading.", "keywords": [ "storybook", diff --git a/code/frameworks/ember/package.json b/code/frameworks/ember/package.json index db1b2cfe14aa..c0d113085a11 100644 --- a/code/frameworks/ember/package.json +++ b/code/frameworks/ember/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/ember", - "version": "8.0.0-rc.2", + "version": "8.0.0-rc.3", "description": "Storybook for Ember: Develop Ember Component in isolation with Hot Reloading.", "homepage": "https://github.com/storybookjs/storybook/tree/next/code/frameworks/ember", "bugs": { diff --git a/code/frameworks/html-vite/package.json b/code/frameworks/html-vite/package.json index 5fb64a4a8c48..150d8fc23198 100644 --- a/code/frameworks/html-vite/package.json +++ b/code/frameworks/html-vite/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/html-vite", - "version": "8.0.0-rc.2", + "version": "8.0.0-rc.3", "description": "Storybook for HTML and Vite: Develop HTML in isolation with Hot Reloading.", "keywords": [ "storybook" diff --git a/code/frameworks/html-webpack5/package.json b/code/frameworks/html-webpack5/package.json index 55e6496baa3c..9eaf30c24120 100644 --- a/code/frameworks/html-webpack5/package.json +++ b/code/frameworks/html-webpack5/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/html-webpack5", - "version": "8.0.0-rc.2", + "version": "8.0.0-rc.3", "description": "Storybook for HTML: View HTML snippets in isolation with Hot Reloading.", "keywords": [ "storybook" diff --git a/code/frameworks/nextjs/package.json b/code/frameworks/nextjs/package.json index f622f9eeaabe..8aa2e629d087 100644 --- a/code/frameworks/nextjs/package.json +++ b/code/frameworks/nextjs/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/nextjs", - "version": "8.0.0-rc.2", + "version": "8.0.0-rc.3", "description": "Storybook for Next.js", "keywords": [ "storybook", diff --git a/code/frameworks/preact-vite/package.json b/code/frameworks/preact-vite/package.json index 19e035c0740d..b24dcb6747f8 100644 --- a/code/frameworks/preact-vite/package.json +++ b/code/frameworks/preact-vite/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/preact-vite", - "version": "8.0.0-rc.2", + "version": "8.0.0-rc.3", "description": "Storybook for Preact and Vite: Develop Preact components in isolation with Hot Reloading.", "keywords": [ "storybook" diff --git a/code/frameworks/preact-webpack5/package.json b/code/frameworks/preact-webpack5/package.json index 8423ab98fade..212a29b84f35 100644 --- a/code/frameworks/preact-webpack5/package.json +++ b/code/frameworks/preact-webpack5/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/preact-webpack5", - "version": "8.0.0-rc.2", + "version": "8.0.0-rc.3", "description": "Storybook for Preact: Develop Preact Component in isolation.", "keywords": [ "storybook" diff --git a/code/frameworks/react-vite/package.json b/code/frameworks/react-vite/package.json index a76d1c4cbddc..f7d426298853 100644 --- a/code/frameworks/react-vite/package.json +++ b/code/frameworks/react-vite/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/react-vite", - "version": "8.0.0-rc.2", + "version": "8.0.0-rc.3", "description": "Storybook for React and Vite: Develop React components in isolation with Hot Reloading.", "keywords": [ "storybook" diff --git a/code/frameworks/react-webpack5/package.json b/code/frameworks/react-webpack5/package.json index a2096ef8e059..71a2c244dde1 100644 --- a/code/frameworks/react-webpack5/package.json +++ b/code/frameworks/react-webpack5/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/react-webpack5", - "version": "8.0.0-rc.2", + "version": "8.0.0-rc.3", "description": "Storybook for React: Develop React Component in isolation with Hot Reloading.", "keywords": [ "storybook" diff --git a/code/frameworks/server-webpack5/package.json b/code/frameworks/server-webpack5/package.json index 7c3771652cfd..466376c00d67 100644 --- a/code/frameworks/server-webpack5/package.json +++ b/code/frameworks/server-webpack5/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/server-webpack5", - "version": "8.0.0-rc.2", + "version": "8.0.0-rc.3", "description": "Storybook for Server: View HTML snippets from a server in isolation with Hot Reloading.", "keywords": [ "storybook" diff --git a/code/frameworks/svelte-vite/package.json b/code/frameworks/svelte-vite/package.json index edac75e5589d..44acfb7aed9b 100644 --- a/code/frameworks/svelte-vite/package.json +++ b/code/frameworks/svelte-vite/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/svelte-vite", - "version": "8.0.0-rc.2", + "version": "8.0.0-rc.3", "description": "Storybook for Svelte and Vite: Develop Svelte components in isolation with Hot Reloading.", "keywords": [ "storybook" diff --git a/code/frameworks/svelte-webpack5/package.json b/code/frameworks/svelte-webpack5/package.json index 85a17dfc6a76..3cc2df33f6e4 100644 --- a/code/frameworks/svelte-webpack5/package.json +++ b/code/frameworks/svelte-webpack5/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/svelte-webpack5", - "version": "8.0.0-rc.2", + "version": "8.0.0-rc.3", "description": "Storybook for Svelte: Develop Svelte Component in isolation with Hot Reloading.", "keywords": [ "storybook" diff --git a/code/frameworks/sveltekit/package.json b/code/frameworks/sveltekit/package.json index b6450c030f5f..8321a71cf1b1 100644 --- a/code/frameworks/sveltekit/package.json +++ b/code/frameworks/sveltekit/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/sveltekit", - "version": "8.0.0-rc.2", + "version": "8.0.0-rc.3", "description": "Storybook for SvelteKit", "keywords": [ "storybook", diff --git a/code/frameworks/vue3-vite/package.json b/code/frameworks/vue3-vite/package.json index 58e9602305b1..473b0f6ca101 100644 --- a/code/frameworks/vue3-vite/package.json +++ b/code/frameworks/vue3-vite/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/vue3-vite", - "version": "8.0.0-rc.2", + "version": "8.0.0-rc.3", "description": "Storybook for Vue3 and Vite: Develop Vue3 components in isolation with Hot Reloading.", "keywords": [ "storybook" diff --git a/code/frameworks/vue3-webpack5/package.json b/code/frameworks/vue3-webpack5/package.json index a23d5980b17f..24ce41095e2d 100644 --- a/code/frameworks/vue3-webpack5/package.json +++ b/code/frameworks/vue3-webpack5/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/vue3-webpack5", - "version": "8.0.0-rc.2", + "version": "8.0.0-rc.3", "description": "Storybook for Vue 3: Develop Vue 3 Components in isolation with Hot Reloading.", "keywords": [ "storybook" diff --git a/code/frameworks/web-components-vite/package.json b/code/frameworks/web-components-vite/package.json index 6c559ff1a849..a4bc976dedc5 100644 --- a/code/frameworks/web-components-vite/package.json +++ b/code/frameworks/web-components-vite/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/web-components-vite", - "version": "8.0.0-rc.2", + "version": "8.0.0-rc.3", "description": "Storybook for web-components and Vite: Develop Web Components in isolation with Hot Reloading.", "keywords": [ "storybook" diff --git a/code/frameworks/web-components-webpack5/package.json b/code/frameworks/web-components-webpack5/package.json index 04f0b31cbf1f..bdeb505ac803 100644 --- a/code/frameworks/web-components-webpack5/package.json +++ b/code/frameworks/web-components-webpack5/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/web-components-webpack5", - "version": "8.0.0-rc.2", + "version": "8.0.0-rc.3", "description": "Storybook for web-components: View web components snippets in isolation with Hot Reloading.", "keywords": [ "lit", diff --git a/code/lib/channels/package.json b/code/lib/channels/package.json index 2c32a9940490..3b051a7081af 100644 --- a/code/lib/channels/package.json +++ b/code/lib/channels/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/channels", - "version": "8.0.0-rc.2", + "version": "8.0.0-rc.3", "description": "", "keywords": [ "storybook" diff --git a/code/lib/cli-sb/package.json b/code/lib/cli-sb/package.json index 821450e6252c..637277a30b38 100644 --- a/code/lib/cli-sb/package.json +++ b/code/lib/cli-sb/package.json @@ -1,6 +1,6 @@ { "name": "sb", - "version": "8.0.0-rc.2", + "version": "8.0.0-rc.3", "description": "Storybook CLI", "keywords": [ "storybook" diff --git a/code/lib/cli-storybook/package.json b/code/lib/cli-storybook/package.json index 17585083a303..8181570c7186 100644 --- a/code/lib/cli-storybook/package.json +++ b/code/lib/cli-storybook/package.json @@ -1,6 +1,6 @@ { "name": "storybook", - "version": "8.0.0-rc.2", + "version": "8.0.0-rc.3", "description": "Storybook CLI", "keywords": [ "storybook" diff --git a/code/lib/cli/package.json b/code/lib/cli/package.json index 0f8d72361143..b55e6c46c42d 100644 --- a/code/lib/cli/package.json +++ b/code/lib/cli/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/cli", - "version": "8.0.0-rc.2", + "version": "8.0.0-rc.3", "description": "Storybook's CLI - install, dev, build, upgrade, and more", "keywords": [ "cli", diff --git a/code/lib/client-logger/package.json b/code/lib/client-logger/package.json index 60716ac1c3cb..602983c51ed5 100644 --- a/code/lib/client-logger/package.json +++ b/code/lib/client-logger/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/client-logger", - "version": "8.0.0-rc.2", + "version": "8.0.0-rc.3", "description": "", "keywords": [ "storybook" diff --git a/code/lib/codemod/package.json b/code/lib/codemod/package.json index dbcac376c369..3acf4a8f3f41 100644 --- a/code/lib/codemod/package.json +++ b/code/lib/codemod/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/codemod", - "version": "8.0.0-rc.2", + "version": "8.0.0-rc.3", "description": "A collection of codemod scripts written with JSCodeshift", "keywords": [ "storybook" diff --git a/code/lib/core-common/package.json b/code/lib/core-common/package.json index 303b4cd42734..043fe7f08f3e 100644 --- a/code/lib/core-common/package.json +++ b/code/lib/core-common/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/core-common", - "version": "8.0.0-rc.2", + "version": "8.0.0-rc.3", "description": "Storybook framework-agnostic API", "keywords": [ "storybook" diff --git a/code/lib/core-common/src/versions.ts b/code/lib/core-common/src/versions.ts index 1de3269c4e5b..56e5adfebd73 100644 --- a/code/lib/core-common/src/versions.ts +++ b/code/lib/core-common/src/versions.ts @@ -1,83 +1,83 @@ // auto generated file, do not edit export default { - '@storybook/addon-a11y': '8.0.0-rc.2', - '@storybook/addon-actions': '8.0.0-rc.2', - '@storybook/addon-backgrounds': '8.0.0-rc.2', - '@storybook/addon-controls': '8.0.0-rc.2', - '@storybook/addon-docs': '8.0.0-rc.2', - '@storybook/addon-essentials': '8.0.0-rc.2', - '@storybook/addon-highlight': '8.0.0-rc.2', - '@storybook/addon-interactions': '8.0.0-rc.2', - '@storybook/addon-jest': '8.0.0-rc.2', - '@storybook/addon-links': '8.0.0-rc.2', - '@storybook/addon-mdx-gfm': '8.0.0-rc.2', - '@storybook/addon-measure': '8.0.0-rc.2', - '@storybook/addon-onboarding': '8.0.0-rc.2', - '@storybook/addon-outline': '8.0.0-rc.2', - '@storybook/addon-storysource': '8.0.0-rc.2', - '@storybook/addon-themes': '8.0.0-rc.2', - '@storybook/addon-toolbars': '8.0.0-rc.2', - '@storybook/addon-viewport': '8.0.0-rc.2', - '@storybook/angular': '8.0.0-rc.2', - '@storybook/blocks': '8.0.0-rc.2', - '@storybook/builder-manager': '8.0.0-rc.2', - '@storybook/builder-vite': '8.0.0-rc.2', - '@storybook/builder-webpack5': '8.0.0-rc.2', - '@storybook/channels': '8.0.0-rc.2', - '@storybook/cli': '8.0.0-rc.2', - '@storybook/client-logger': '8.0.0-rc.2', - '@storybook/codemod': '8.0.0-rc.2', - '@storybook/components': '8.0.0-rc.2', - '@storybook/core-common': '8.0.0-rc.2', - '@storybook/core-events': '8.0.0-rc.2', - '@storybook/core-server': '8.0.0-rc.2', - '@storybook/core-webpack': '8.0.0-rc.2', - '@storybook/csf-plugin': '8.0.0-rc.2', - '@storybook/csf-tools': '8.0.0-rc.2', - '@storybook/docs-tools': '8.0.0-rc.2', - '@storybook/ember': '8.0.0-rc.2', - '@storybook/html': '8.0.0-rc.2', - '@storybook/html-vite': '8.0.0-rc.2', - '@storybook/html-webpack5': '8.0.0-rc.2', - '@storybook/instrumenter': '8.0.0-rc.2', - '@storybook/manager': '8.0.0-rc.2', - '@storybook/manager-api': '8.0.0-rc.2', - '@storybook/nextjs': '8.0.0-rc.2', - '@storybook/node-logger': '8.0.0-rc.2', - '@storybook/preact': '8.0.0-rc.2', - '@storybook/preact-vite': '8.0.0-rc.2', - '@storybook/preact-webpack5': '8.0.0-rc.2', - '@storybook/preset-create-react-app': '8.0.0-rc.2', - '@storybook/preset-html-webpack': '8.0.0-rc.2', - '@storybook/preset-preact-webpack': '8.0.0-rc.2', - '@storybook/preset-react-webpack': '8.0.0-rc.2', - '@storybook/preset-server-webpack': '8.0.0-rc.2', - '@storybook/preset-svelte-webpack': '8.0.0-rc.2', - '@storybook/preset-vue3-webpack': '8.0.0-rc.2', - '@storybook/preview': '8.0.0-rc.2', - '@storybook/preview-api': '8.0.0-rc.2', - '@storybook/react': '8.0.0-rc.2', - '@storybook/react-dom-shim': '8.0.0-rc.2', - '@storybook/react-vite': '8.0.0-rc.2', - '@storybook/react-webpack5': '8.0.0-rc.2', - '@storybook/router': '8.0.0-rc.2', - '@storybook/server': '8.0.0-rc.2', - '@storybook/server-webpack5': '8.0.0-rc.2', - '@storybook/source-loader': '8.0.0-rc.2', - '@storybook/svelte': '8.0.0-rc.2', - '@storybook/svelte-vite': '8.0.0-rc.2', - '@storybook/svelte-webpack5': '8.0.0-rc.2', - '@storybook/sveltekit': '8.0.0-rc.2', - '@storybook/telemetry': '8.0.0-rc.2', - '@storybook/test': '8.0.0-rc.2', - '@storybook/theming': '8.0.0-rc.2', - '@storybook/types': '8.0.0-rc.2', - '@storybook/vue3': '8.0.0-rc.2', - '@storybook/vue3-vite': '8.0.0-rc.2', - '@storybook/vue3-webpack5': '8.0.0-rc.2', - '@storybook/web-components': '8.0.0-rc.2', - '@storybook/web-components-vite': '8.0.0-rc.2', - '@storybook/web-components-webpack5': '8.0.0-rc.2', - sb: '8.0.0-rc.2', - storybook: '8.0.0-rc.2', + '@storybook/addon-a11y': '8.0.0-rc.3', + '@storybook/addon-actions': '8.0.0-rc.3', + '@storybook/addon-backgrounds': '8.0.0-rc.3', + '@storybook/addon-controls': '8.0.0-rc.3', + '@storybook/addon-docs': '8.0.0-rc.3', + '@storybook/addon-essentials': '8.0.0-rc.3', + '@storybook/addon-highlight': '8.0.0-rc.3', + '@storybook/addon-interactions': '8.0.0-rc.3', + '@storybook/addon-jest': '8.0.0-rc.3', + '@storybook/addon-links': '8.0.0-rc.3', + '@storybook/addon-mdx-gfm': '8.0.0-rc.3', + '@storybook/addon-measure': '8.0.0-rc.3', + '@storybook/addon-onboarding': '8.0.0-rc.3', + '@storybook/addon-outline': '8.0.0-rc.3', + '@storybook/addon-storysource': '8.0.0-rc.3', + '@storybook/addon-themes': '8.0.0-rc.3', + '@storybook/addon-toolbars': '8.0.0-rc.3', + '@storybook/addon-viewport': '8.0.0-rc.3', + '@storybook/angular': '8.0.0-rc.3', + '@storybook/blocks': '8.0.0-rc.3', + '@storybook/builder-manager': '8.0.0-rc.3', + '@storybook/builder-vite': '8.0.0-rc.3', + '@storybook/builder-webpack5': '8.0.0-rc.3', + '@storybook/channels': '8.0.0-rc.3', + '@storybook/cli': '8.0.0-rc.3', + '@storybook/client-logger': '8.0.0-rc.3', + '@storybook/codemod': '8.0.0-rc.3', + '@storybook/components': '8.0.0-rc.3', + '@storybook/core-common': '8.0.0-rc.3', + '@storybook/core-events': '8.0.0-rc.3', + '@storybook/core-server': '8.0.0-rc.3', + '@storybook/core-webpack': '8.0.0-rc.3', + '@storybook/csf-plugin': '8.0.0-rc.3', + '@storybook/csf-tools': '8.0.0-rc.3', + '@storybook/docs-tools': '8.0.0-rc.3', + '@storybook/ember': '8.0.0-rc.3', + '@storybook/html': '8.0.0-rc.3', + '@storybook/html-vite': '8.0.0-rc.3', + '@storybook/html-webpack5': '8.0.0-rc.3', + '@storybook/instrumenter': '8.0.0-rc.3', + '@storybook/manager': '8.0.0-rc.3', + '@storybook/manager-api': '8.0.0-rc.3', + '@storybook/nextjs': '8.0.0-rc.3', + '@storybook/node-logger': '8.0.0-rc.3', + '@storybook/preact': '8.0.0-rc.3', + '@storybook/preact-vite': '8.0.0-rc.3', + '@storybook/preact-webpack5': '8.0.0-rc.3', + '@storybook/preset-create-react-app': '8.0.0-rc.3', + '@storybook/preset-html-webpack': '8.0.0-rc.3', + '@storybook/preset-preact-webpack': '8.0.0-rc.3', + '@storybook/preset-react-webpack': '8.0.0-rc.3', + '@storybook/preset-server-webpack': '8.0.0-rc.3', + '@storybook/preset-svelte-webpack': '8.0.0-rc.3', + '@storybook/preset-vue3-webpack': '8.0.0-rc.3', + '@storybook/preview': '8.0.0-rc.3', + '@storybook/preview-api': '8.0.0-rc.3', + '@storybook/react': '8.0.0-rc.3', + '@storybook/react-dom-shim': '8.0.0-rc.3', + '@storybook/react-vite': '8.0.0-rc.3', + '@storybook/react-webpack5': '8.0.0-rc.3', + '@storybook/router': '8.0.0-rc.3', + '@storybook/server': '8.0.0-rc.3', + '@storybook/server-webpack5': '8.0.0-rc.3', + '@storybook/source-loader': '8.0.0-rc.3', + '@storybook/svelte': '8.0.0-rc.3', + '@storybook/svelte-vite': '8.0.0-rc.3', + '@storybook/svelte-webpack5': '8.0.0-rc.3', + '@storybook/sveltekit': '8.0.0-rc.3', + '@storybook/telemetry': '8.0.0-rc.3', + '@storybook/test': '8.0.0-rc.3', + '@storybook/theming': '8.0.0-rc.3', + '@storybook/types': '8.0.0-rc.3', + '@storybook/vue3': '8.0.0-rc.3', + '@storybook/vue3-vite': '8.0.0-rc.3', + '@storybook/vue3-webpack5': '8.0.0-rc.3', + '@storybook/web-components': '8.0.0-rc.3', + '@storybook/web-components-vite': '8.0.0-rc.3', + '@storybook/web-components-webpack5': '8.0.0-rc.3', + sb: '8.0.0-rc.3', + storybook: '8.0.0-rc.3', }; diff --git a/code/lib/core-events/package.json b/code/lib/core-events/package.json index 8ada1c3ee9a4..5cae8b0d103c 100644 --- a/code/lib/core-events/package.json +++ b/code/lib/core-events/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/core-events", - "version": "8.0.0-rc.2", + "version": "8.0.0-rc.3", "description": "Event names used in storybook core", "keywords": [ "storybook" diff --git a/code/lib/core-server/package.json b/code/lib/core-server/package.json index 1d4f1d43c88b..5676b03ce288 100644 --- a/code/lib/core-server/package.json +++ b/code/lib/core-server/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/core-server", - "version": "8.0.0-rc.2", + "version": "8.0.0-rc.3", "description": "Storybook framework-agnostic API", "keywords": [ "storybook" diff --git a/code/lib/core-webpack/package.json b/code/lib/core-webpack/package.json index 84199b59fc20..1ff1b0e9bed1 100644 --- a/code/lib/core-webpack/package.json +++ b/code/lib/core-webpack/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/core-webpack", - "version": "8.0.0-rc.2", + "version": "8.0.0-rc.3", "description": "Storybook framework-agnostic API", "keywords": [ "storybook" diff --git a/code/lib/csf-plugin/package.json b/code/lib/csf-plugin/package.json index 7c69964a2bf5..407367b12ec6 100644 --- a/code/lib/csf-plugin/package.json +++ b/code/lib/csf-plugin/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/csf-plugin", - "version": "8.0.0-rc.2", + "version": "8.0.0-rc.3", "description": "Enrich CSF files via static analysis", "keywords": [ "storybook" diff --git a/code/lib/csf-tools/package.json b/code/lib/csf-tools/package.json index 3aecb2b4c989..b15707a80768 100644 --- a/code/lib/csf-tools/package.json +++ b/code/lib/csf-tools/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/csf-tools", - "version": "8.0.0-rc.2", + "version": "8.0.0-rc.3", "description": "Parse and manipulate CSF and Storybook config files", "keywords": [ "storybook" diff --git a/code/lib/docs-tools/package.json b/code/lib/docs-tools/package.json index faead07c757d..b624faa60690 100644 --- a/code/lib/docs-tools/package.json +++ b/code/lib/docs-tools/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/docs-tools", - "version": "8.0.0-rc.2", + "version": "8.0.0-rc.3", "description": "Shared utility functions for frameworks to implement docs", "keywords": [ "storybook" diff --git a/code/lib/instrumenter/package.json b/code/lib/instrumenter/package.json index 29aafd117e78..23fd1a4c97da 100644 --- a/code/lib/instrumenter/package.json +++ b/code/lib/instrumenter/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/instrumenter", - "version": "8.0.0-rc.2", + "version": "8.0.0-rc.3", "description": "", "keywords": [ "storybook" diff --git a/code/lib/manager-api/package.json b/code/lib/manager-api/package.json index 285799d6434e..7f0f18ead48f 100644 --- a/code/lib/manager-api/package.json +++ b/code/lib/manager-api/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/manager-api", - "version": "8.0.0-rc.2", + "version": "8.0.0-rc.3", "description": "Core Storybook Manager API & Context", "keywords": [ "storybook" diff --git a/code/lib/manager-api/src/version.ts b/code/lib/manager-api/src/version.ts index 7900754c895d..22afecdd372a 100644 --- a/code/lib/manager-api/src/version.ts +++ b/code/lib/manager-api/src/version.ts @@ -1 +1 @@ -export const version = '8.0.0-rc.2'; +export const version = '8.0.0-rc.3'; diff --git a/code/lib/node-logger/package.json b/code/lib/node-logger/package.json index eab0c64bfa00..0c7ff57a0d26 100644 --- a/code/lib/node-logger/package.json +++ b/code/lib/node-logger/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/node-logger", - "version": "8.0.0-rc.2", + "version": "8.0.0-rc.3", "description": "", "keywords": [ "storybook" diff --git a/code/lib/preview-api/package.json b/code/lib/preview-api/package.json index 8706fb1e6f0e..8a6c2cd1e00b 100644 --- a/code/lib/preview-api/package.json +++ b/code/lib/preview-api/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/preview-api", - "version": "8.0.0-rc.2", + "version": "8.0.0-rc.3", "description": "", "keywords": [ "storybook" diff --git a/code/lib/preview/package.json b/code/lib/preview/package.json index d7f6a6bf9713..22f4977f5cda 100644 --- a/code/lib/preview/package.json +++ b/code/lib/preview/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/preview", - "version": "8.0.0-rc.2", + "version": "8.0.0-rc.3", "description": "", "keywords": [ "storybook" diff --git a/code/lib/react-dom-shim/package.json b/code/lib/react-dom-shim/package.json index 52f45ceba617..2f4e5054d02c 100644 --- a/code/lib/react-dom-shim/package.json +++ b/code/lib/react-dom-shim/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/react-dom-shim", - "version": "8.0.0-rc.2", + "version": "8.0.0-rc.3", "description": "", "keywords": [ "storybook" diff --git a/code/lib/router/package.json b/code/lib/router/package.json index 79520d10ffbb..a590ca8df996 100644 --- a/code/lib/router/package.json +++ b/code/lib/router/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/router", - "version": "8.0.0-rc.2", + "version": "8.0.0-rc.3", "description": "Core Storybook Router", "keywords": [ "storybook" diff --git a/code/lib/source-loader/package.json b/code/lib/source-loader/package.json index dfd1ee424bc4..ca90db1a633f 100644 --- a/code/lib/source-loader/package.json +++ b/code/lib/source-loader/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/source-loader", - "version": "8.0.0-rc.2", + "version": "8.0.0-rc.3", "description": "Source loader", "keywords": [ "lib", diff --git a/code/lib/telemetry/package.json b/code/lib/telemetry/package.json index 430a2add1bdf..ba2ac459326b 100644 --- a/code/lib/telemetry/package.json +++ b/code/lib/telemetry/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/telemetry", - "version": "8.0.0-rc.2", + "version": "8.0.0-rc.3", "description": "Telemetry logging for crash reports and usage statistics", "keywords": [ "storybook" diff --git a/code/lib/test/package.json b/code/lib/test/package.json index d0ae52a03d6f..cd22fb90d648 100644 --- a/code/lib/test/package.json +++ b/code/lib/test/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/test", - "version": "8.0.0-rc.2", + "version": "8.0.0-rc.3", "description": "", "keywords": [ "storybook" diff --git a/code/lib/theming/package.json b/code/lib/theming/package.json index ab85acf2481c..0d99fade2da8 100644 --- a/code/lib/theming/package.json +++ b/code/lib/theming/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/theming", - "version": "8.0.0-rc.2", + "version": "8.0.0-rc.3", "description": "Core Storybook Components", "keywords": [ "storybook" diff --git a/code/lib/types/package.json b/code/lib/types/package.json index 0eb61cdce388..02ce06531951 100644 --- a/code/lib/types/package.json +++ b/code/lib/types/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/types", - "version": "8.0.0-rc.2", + "version": "8.0.0-rc.3", "description": "Core Storybook TS Types", "keywords": [ "storybook" diff --git a/code/package.json b/code/package.json index 0719457b9ea4..7dbcfb70ed22 100644 --- a/code/package.json +++ b/code/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/root", - "version": "8.0.0-rc.2", + "version": "8.0.0-rc.3", "private": true, "description": "Storybook root", "homepage": "https://storybook.js.org/", @@ -294,6 +294,5 @@ "Dependency Upgrades" ] ] - }, - "deferredNextVersion": "8.0.0-rc.3" + } } diff --git a/code/presets/create-react-app/package.json b/code/presets/create-react-app/package.json index ed53ffee0fe9..4da447b1d7f0 100644 --- a/code/presets/create-react-app/package.json +++ b/code/presets/create-react-app/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/preset-create-react-app", - "version": "8.0.0-rc.2", + "version": "8.0.0-rc.3", "description": "Storybook for Create React App preset", "keywords": [ "storybook" diff --git a/code/presets/html-webpack/package.json b/code/presets/html-webpack/package.json index 1ca061b42459..748df6affd50 100644 --- a/code/presets/html-webpack/package.json +++ b/code/presets/html-webpack/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/preset-html-webpack", - "version": "8.0.0-rc.2", + "version": "8.0.0-rc.3", "description": "Storybook for HTML: View HTML snippets in isolation with Hot Reloading.", "keywords": [ "storybook" diff --git a/code/presets/preact-webpack/package.json b/code/presets/preact-webpack/package.json index 0fff0481f38d..c5c9d587425f 100644 --- a/code/presets/preact-webpack/package.json +++ b/code/presets/preact-webpack/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/preset-preact-webpack", - "version": "8.0.0-rc.2", + "version": "8.0.0-rc.3", "description": "Storybook for Preact: Develop Preact Component in isolation.", "keywords": [ "storybook" diff --git a/code/presets/react-webpack/package.json b/code/presets/react-webpack/package.json index dd5f11b03793..df70d13120c1 100644 --- a/code/presets/react-webpack/package.json +++ b/code/presets/react-webpack/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/preset-react-webpack", - "version": "8.0.0-rc.2", + "version": "8.0.0-rc.3", "description": "Storybook for React: Develop React Component in isolation with Hot Reloading", "keywords": [ "storybook" diff --git a/code/presets/server-webpack/package.json b/code/presets/server-webpack/package.json index 39e509374b67..762d5d7de662 100644 --- a/code/presets/server-webpack/package.json +++ b/code/presets/server-webpack/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/preset-server-webpack", - "version": "8.0.0-rc.2", + "version": "8.0.0-rc.3", "description": "Storybook for Server: View HTML snippets from a server in isolation with Hot Reloading.", "keywords": [ "storybook" diff --git a/code/presets/svelte-webpack/package.json b/code/presets/svelte-webpack/package.json index efcbd040827c..0552c6bd3d7c 100644 --- a/code/presets/svelte-webpack/package.json +++ b/code/presets/svelte-webpack/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/preset-svelte-webpack", - "version": "8.0.0-rc.2", + "version": "8.0.0-rc.3", "description": "Storybook for Svelte: Develop Svelte Component in isolation with Hot Reloading.", "keywords": [ "storybook" diff --git a/code/presets/vue3-webpack/package.json b/code/presets/vue3-webpack/package.json index f19a6e689a0e..3c2e120a2273 100644 --- a/code/presets/vue3-webpack/package.json +++ b/code/presets/vue3-webpack/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/preset-vue3-webpack", - "version": "8.0.0-rc.2", + "version": "8.0.0-rc.3", "description": "Storybook for Vue 3: Develop Vue 3 Components in isolation with Hot Reloading.", "keywords": [ "storybook" diff --git a/code/renderers/html/package.json b/code/renderers/html/package.json index d65de0340b40..8154fa296f89 100644 --- a/code/renderers/html/package.json +++ b/code/renderers/html/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/html", - "version": "8.0.0-rc.2", + "version": "8.0.0-rc.3", "description": "Storybook HTML renderer", "keywords": [ "storybook" diff --git a/code/renderers/preact/package.json b/code/renderers/preact/package.json index 964a280e875c..528f5e0bc060 100644 --- a/code/renderers/preact/package.json +++ b/code/renderers/preact/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/preact", - "version": "8.0.0-rc.2", + "version": "8.0.0-rc.3", "description": "Storybook Preact renderer", "keywords": [ "storybook" diff --git a/code/renderers/react/package.json b/code/renderers/react/package.json index a42882c38ebf..679171d7fc16 100644 --- a/code/renderers/react/package.json +++ b/code/renderers/react/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/react", - "version": "8.0.0-rc.2", + "version": "8.0.0-rc.3", "description": "Storybook React renderer", "keywords": [ "storybook" diff --git a/code/renderers/server/package.json b/code/renderers/server/package.json index e17abd07240a..e8c3a047b49a 100644 --- a/code/renderers/server/package.json +++ b/code/renderers/server/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/server", - "version": "8.0.0-rc.2", + "version": "8.0.0-rc.3", "description": "Storybook Server renderer", "keywords": [ "storybook" diff --git a/code/renderers/svelte/package.json b/code/renderers/svelte/package.json index f33c169654cd..33d851d2a76a 100644 --- a/code/renderers/svelte/package.json +++ b/code/renderers/svelte/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/svelte", - "version": "8.0.0-rc.2", + "version": "8.0.0-rc.3", "description": "Storybook Svelte renderer", "keywords": [ "storybook" diff --git a/code/renderers/vue3/package.json b/code/renderers/vue3/package.json index cc5a72a3cde1..087d5cf3dc14 100644 --- a/code/renderers/vue3/package.json +++ b/code/renderers/vue3/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/vue3", - "version": "8.0.0-rc.2", + "version": "8.0.0-rc.3", "description": "Storybook Vue 3 renderer", "keywords": [ "storybook" diff --git a/code/renderers/web-components/package.json b/code/renderers/web-components/package.json index 1483eb3de461..7955d99c7918 100644 --- a/code/renderers/web-components/package.json +++ b/code/renderers/web-components/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/web-components", - "version": "8.0.0-rc.2", + "version": "8.0.0-rc.3", "description": "Storybook web-components renderer", "keywords": [ "lit", diff --git a/code/ui/blocks/package.json b/code/ui/blocks/package.json index 790612807846..de499745fba3 100644 --- a/code/ui/blocks/package.json +++ b/code/ui/blocks/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/blocks", - "version": "8.0.0-rc.2", + "version": "8.0.0-rc.3", "description": "Storybook Doc Blocks", "keywords": [ "storybook" diff --git a/code/ui/components/package.json b/code/ui/components/package.json index fcb4235f18e1..6b8e39d61b82 100644 --- a/code/ui/components/package.json +++ b/code/ui/components/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/components", - "version": "8.0.0-rc.2", + "version": "8.0.0-rc.3", "description": "Core Storybook Components", "keywords": [ "storybook" diff --git a/code/ui/manager/package.json b/code/ui/manager/package.json index 05c4b076ed7b..c22b8c3e6954 100644 --- a/code/ui/manager/package.json +++ b/code/ui/manager/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/manager", - "version": "8.0.0-rc.2", + "version": "8.0.0-rc.3", "description": "Core Storybook UI", "keywords": [ "storybook" From 1d765656e8d3657baaf1b025c2571be48078171f Mon Sep 17 00:00:00 2001 From: Kasper Peulen Date: Thu, 7 Mar 2024 12:37:42 +0100 Subject: [PATCH 084/132] Fix attaching action, after a spy is restored to the original implementation --- code/addons/actions/src/loaders.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/code/addons/actions/src/loaders.ts b/code/addons/actions/src/loaders.ts index cc6c8494b7fc..3109b79e0322 100644 --- a/code/addons/actions/src/loaders.ts +++ b/code/addons/actions/src/loaders.ts @@ -2,6 +2,8 @@ import type { LoaderFunction } from '@storybook/types'; import { action } from './runtime'; +export const tinySpyInternalState = Symbol.for('tinyspy:spy'); + const attachActionsToFunctionMocks: LoaderFunction = (context) => { const { args, @@ -15,7 +17,9 @@ const attachActionsToFunctionMocks: LoaderFunction = (context) => { typeof value === 'function' && '_isMockFunction' in value && value._isMockFunction ) .forEach(([key, value]) => { - const previous = value.getMockImplementation(); + const previous = + value.getMockImplementation() ?? + (tinySpyInternalState in value ? value[tinySpyInternalState]?.getOriginal() : undefined); if (previous?._actionAttached !== true && previous?.isAction !== true) { const implementation = (...params: unknown[]) => { action(key)(...params); From 880479789f6cdadf5b47874ae1eb78ecd64ba786 Mon Sep 17 00:00:00 2001 From: Norbert de Langen Date: Thu, 7 Mar 2024 14:54:07 +0100 Subject: [PATCH 085/132] add an automigration for upgrading dependencies --- code/lib/cli/src/automigrate/fixes/index.ts | 8 +- .../upgrade-storybook-related-dependencies.ts | 105 ++++++++++++++++++ code/lib/cli/src/automigrate/index.ts | 21 +++- code/lib/cli/src/automigrate/types.ts | 7 +- .../getIncompatibleStorybookPackages.ts | 12 ++ code/lib/cli/src/upgrade.ts | 3 +- 6 files changed, 144 insertions(+), 12 deletions(-) create mode 100644 code/lib/cli/src/automigrate/fixes/upgrade-storybook-related-dependencies.ts diff --git a/code/lib/cli/src/automigrate/fixes/index.ts b/code/lib/cli/src/automigrate/fixes/index.ts index 17b3d4942be1..01bdc2b2aa94 100644 --- a/code/lib/cli/src/automigrate/fixes/index.ts +++ b/code/lib/cli/src/automigrate/fixes/index.ts @@ -26,10 +26,11 @@ import { removeJestTestingLibrary } from './remove-jest-testing-library'; import { addonsAPI } from './addons-api'; import { mdx1to3 } from './mdx-1-to-3'; import { addonPostCSS } from './addon-postcss'; +import { upgradeStorybookRelatedDependencies } from './upgrade-storybook-related-dependencies'; export * from '../types'; -export const allFixes: Fix[] = [ +export const allFixes = [ addonsAPI, newFrameworks, cra5, @@ -56,6 +57,7 @@ export const allFixes: Fix[] = [ removeLegacyMDX1, webpack5CompilerSetup, mdx1to3, -]; + upgradeStorybookRelatedDependencies, +] satisfies Fix[]; -export const initFixes: Fix[] = [eslintPlugin]; +export const initFixes = [eslintPlugin] satisfies Fix[]; diff --git a/code/lib/cli/src/automigrate/fixes/upgrade-storybook-related-dependencies.ts b/code/lib/cli/src/automigrate/fixes/upgrade-storybook-related-dependencies.ts new file mode 100644 index 000000000000..234b35a1451c --- /dev/null +++ b/code/lib/cli/src/automigrate/fixes/upgrade-storybook-related-dependencies.ts @@ -0,0 +1,105 @@ +import { dedent } from 'ts-dedent'; +import type { Fix } from '../types'; +import { underline } from 'chalk'; +import { getIncompatibleStorybookPackages } from '../../doctor/getIncompatibleStorybookPackages'; + +interface Options { + list: { packageName: string; version: string }[]; +} + +type ExcludesFalse = (x: T | undefined) => x is T; + +/** + * Is the user upgrading to the `latest` version of Storybook? + * Let's try to pull along some of the storybook related dependencies to `latest` as well! + * + * We communicate clearly that this migration is a helping hand, but not a complete solution. + * The user should still manually check for other dependencies that might be incompatible. + * + * see: https://github.com/storybookjs/storybook/issues/25731#issuecomment-1977346398 + */ +export const upgradeStorybookRelatedDependencies = { + id: 'upgradeStorybookRelatedDependencies', + + versionRange: ['<8', '>=8'], + + async check({ packageManager, storybookVersion }) { + const out = await getIncompatibleStorybookPackages({ + currentStorybookVersion: storybookVersion, + packageManager, + skipErrors: true, + }); + + const list = await Promise.all( + out.map(async ({ packageName, hasIncompatibleDependencies }) => { + if (!hasIncompatibleDependencies) { + return; + } + + return { + packageName, + version: await packageManager.latestVersion(packageName), + }; + }) + ); + + const filtered = list.filter(Boolean as any as ExcludesFalse); + return { list: filtered }; + }, + + promptType: 'auto-no', + + prompt({ list }) { + return dedent` + You're upgrading to the latest version of Storybook. We recommend upgrading the following packages: + ${list.map(({ packageName, version }) => `${packageName}@${version}`).join(', ')} + + We detected those packages are incompatible with the latest version of Storybook. + ${underline( + `The list might be incomplete, so it's advised to upgrade dependencies manually, but this automigration can help you get started.` + )} + + After upgrading, we will run the dedupe command, which could possibly have effects on dependencies that are not storybook related. + see: https://docs.npmjs.com/cli/commands/npm-dedupe + + Do you want to proceed (upgrade the detected packages)? + `; + }, + + async run({ result: { list }, packageManager, dryRun, mainConfigPath }) { + if (dryRun) { + console.log(dedent` + would have upgrade the following: + ${list.map(({ packageName, version }) => `${packageName}@${version}`).join('\n')} + `); + return; + } + + const packageJson = await packageManager.readPackageJson(); + + // mutate the packageJson data + list.forEach((item) => { + if (!item) { + return; + } + + const { packageName, version } = item; + const prefixed = `^${version}`; + + if (packageJson.dependencies?.[packageName]) { + packageJson.dependencies[packageName] = prefixed; + } + if (packageJson.devDependencies?.[packageName]) { + packageJson.devDependencies[packageName] = prefixed; + } + if (packageJson.peerDependencies?.[packageName]) { + packageJson.peerDependencies[packageName] = prefixed; + } + }); + + await packageManager.writePackageJson(packageJson); + await packageManager.installDependencies(); + + await packageManager.getRunCommand('dedupe'); + }, +} satisfies Fix; diff --git a/code/lib/cli/src/automigrate/index.ts b/code/lib/cli/src/automigrate/index.ts index 8a84476b5e93..843b8f4371d6 100644 --- a/code/lib/cli/src/automigrate/index.ts +++ b/code/lib/cli/src/automigrate/index.ts @@ -29,6 +29,8 @@ import { getMigrationSummary } from './helpers/getMigrationSummary'; import { getStorybookData } from './helpers/mainConfigFile'; import { doctor } from '../doctor'; +import { upgradeStorybookRelatedDependencies } from './fixes/upgrade-storybook-related-dependencies'; + const logger = console; const LOG_FILE_NAME = 'migration-storybook.log'; const LOG_FILE_PATH = join(process.cwd(), LOG_FILE_NAME); @@ -121,8 +123,17 @@ export const automigrate = async ({ return null; } - const selectedFixes = inputFixes || allFixes; - const fixes = fixId ? selectedFixes.filter((f) => f.id === fixId) : selectedFixes; + const selectedFixes: Fix[] = + inputFixes || + allFixes.filter((fix) => { + // we only allow this automigration when the user explicitly asks for it, or they are upgrading to the latest version of storybook + if (fix.id === upgradeStorybookRelatedDependencies.id && isUpgrade !== 'latest') { + return false; + } + + return true; + }); + const fixes: Fix[] = fixId ? selectedFixes.filter((f) => f.id === fixId) : selectedFixes; if (fixId && fixes.length === 0) { logger.info(`๐Ÿ“ญ No migrations found for ${chalk.magenta(fixId)}.`); @@ -143,7 +154,7 @@ export const automigrate = async ({ mainConfigPath, storybookVersion, beforeVersion, - isUpgrade, + isUpgrade: !!isUpgrade, dryRun, yes, }); @@ -308,13 +319,13 @@ export async function runFixes({ fixResults[f.id] = FixStatus.MANUAL_SKIPPED; break; } - } else if (promptType === 'auto') { + } else if (promptType === 'auto' || promptType === 'auto-no') { runAnswer = await prompts( { type: 'confirm', name: 'fix', message: `Do you want to run the '${chalk.cyan(f.id)}' migration on your project?`, - initial: true, + initial: promptType === 'auto-no' ? false : true, }, { onCancel: () => { diff --git a/code/lib/cli/src/automigrate/types.ts b/code/lib/cli/src/automigrate/types.ts index d8cc9f06af3e..45f2b4b72c01 100644 --- a/code/lib/cli/src/automigrate/types.ts +++ b/code/lib/cli/src/automigrate/types.ts @@ -22,10 +22,11 @@ export interface RunOptions { /** * promptType defines how the user will be prompted to apply an automigration fix * - auto: the fix will be applied automatically + * - auto-no: the fix will be applied automatically, but only when the user opts-in * - manual: the user will be prompted to apply the fix * - notification: the user will be notified about some changes. A fix isn't required, though */ -export type Prompt = 'auto' | 'manual' | 'notification'; +export type Prompt = 'auto' | 'auto-no' | 'manual' | 'notification'; type BaseFix = { id: string; @@ -45,7 +46,7 @@ type PromptType = export type Fix = ( | { - promptType?: PromptType; + promptType?: PromptType; run: (options: RunOptions) => Promise; } | { @@ -74,7 +75,7 @@ export interface AutofixOptions extends Omit compare with existing CLI version + +// const norbertStuff = async (dependency: string, context: Context) => { +// const { packageManager } = context; + +// const res = await checkPackageCompatibility(dependency, context); +// if (res.hasIncompatibleDependencies) { +// const hasUpdate = await packageManager.latestVersion(dependency); +// } +// }; + export const checkPackageCompatibility = async (dependency: string, context: Context) => { const { currentStorybookVersion, skipErrors, packageManager } = context; try { diff --git a/code/lib/cli/src/upgrade.ts b/code/lib/cli/src/upgrade.ts index 179c7d806a2f..757ad89bdd7c 100644 --- a/code/lib/cli/src/upgrade.ts +++ b/code/lib/cli/src/upgrade.ts @@ -22,6 +22,7 @@ import { } from '@storybook/core-common'; import { automigrate } from './automigrate/index'; import { autoblock } from './autoblock/index'; +import { is } from '@babel/types'; type Package = { package: string; @@ -261,7 +262,7 @@ export const doUpgrade = async ({ mainConfigPath, beforeVersion, storybookVersion: currentVersion, - isUpgrade: true, + isUpgrade: isOutdated ? true : 'latest', }); } From 32de171b2c67cafe913a00f190e20b1f380941a3 Mon Sep 17 00:00:00 2001 From: Kasper Peulen Date: Thu, 7 Mar 2024 15:39:24 +0100 Subject: [PATCH 086/132] Add a comment --- code/addons/actions/src/loaders.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/code/addons/actions/src/loaders.ts b/code/addons/actions/src/loaders.ts index 3109b79e0322..3acfa9795eef 100644 --- a/code/addons/actions/src/loaders.ts +++ b/code/addons/actions/src/loaders.ts @@ -17,6 +17,8 @@ const attachActionsToFunctionMocks: LoaderFunction = (context) => { typeof value === 'function' && '_isMockFunction' in value && value._isMockFunction ) .forEach(([key, value]) => { + // See this discussion for context: + // https://github.com/vitest-dev/vitest/pull/5352 const previous = value.getMockImplementation() ?? (tinySpyInternalState in value ? value[tinySpyInternalState]?.getOriginal() : undefined); From 54eccd103d247a33c2f3e1b3b9f171e02533938f Mon Sep 17 00:00:00 2001 From: Norbert de Langen Date: Thu, 7 Mar 2024 17:31:50 +0100 Subject: [PATCH 087/132] improvements --- .../upgrade-storybook-related-dependencies.ts | 130 ++++++++++++------ code/lib/cli/src/automigrate/index.ts | 29 +++- code/lib/cli/src/automigrate/types.ts | 6 +- 3 files changed, 112 insertions(+), 53 deletions(-) diff --git a/code/lib/cli/src/automigrate/fixes/upgrade-storybook-related-dependencies.ts b/code/lib/cli/src/automigrate/fixes/upgrade-storybook-related-dependencies.ts index 234b35a1451c..2a0630960226 100644 --- a/code/lib/cli/src/automigrate/fixes/upgrade-storybook-related-dependencies.ts +++ b/code/lib/cli/src/automigrate/fixes/upgrade-storybook-related-dependencies.ts @@ -2,13 +2,13 @@ import { dedent } from 'ts-dedent'; import type { Fix } from '../types'; import { underline } from 'chalk'; import { getIncompatibleStorybookPackages } from '../../doctor/getIncompatibleStorybookPackages'; +import { valid, coerce } from 'semver'; interface Options { - list: { packageName: string; version: string }[]; + upgradable: { packageName: string; version: string }[]; + problematicPackages: { packageName: string; version: string }[]; } -type ExcludesFalse = (x: T | undefined) => x is T; - /** * Is the user upgrading to the `latest` version of Storybook? * Let's try to pull along some of the storybook related dependencies to `latest` as well! @@ -20,36 +20,62 @@ type ExcludesFalse = (x: T | undefined) => x is T; */ export const upgradeStorybookRelatedDependencies = { id: 'upgradeStorybookRelatedDependencies', - - versionRange: ['<8', '>=8'], + versionRange: ['*.*.*', '*.*.*'], + promptType: 'auto', + promptDefaultValue: false, async check({ packageManager, storybookVersion }) { - const out = await getIncompatibleStorybookPackages({ + const packageJson = await packageManager.readPackageJson(); + const analyzed = await getIncompatibleStorybookPackages({ currentStorybookVersion: storybookVersion, packageManager, skipErrors: true, }); - const list = await Promise.all( - out.map(async ({ packageName, hasIncompatibleDependencies }) => { - if (!hasIncompatibleDependencies) { - return; - } + const all = await packageManager.getAllDependencies(); + + const associated = Object.keys(all).filter((dep) => dep.includes('storybook')); + const detected = analyzed + .filter((m) => m.hasIncompatibleDependencies) + .map((m) => m.packageName); + const list = await Promise.all( + Array.from(new Set([...associated, ...detected])).map(async (packageName) => { return { packageName, - version: await packageManager.latestVersion(packageName), + version: await packageManager.latestVersion(packageName).catch((e) => null), }; }) ); - const filtered = list.filter(Boolean as any as ExcludesFalse); - return { list: filtered }; - }, + const data = list.reduce( + (acc, k) => { + const upgradable = !( + !valid(k.version) || + k.version === coerce(packageJson?.dependencies?.[k.packageName])?.toString() || + k.version === coerce(packageJson?.devDependencies?.[k.packageName])?.toString() || + k.version === coerce(packageJson?.peerDependencies?.[k.packageName])?.toString() + ); + + if (upgradable) { + acc.upgradable.push(k); + } else { + acc.problematicPackages.push(k); + } + + return acc; + }, + { upgradable: [], problematicPackages: [] } + ); + + if (data.upgradable.length > 0) { + return data; + } - promptType: 'auto-no', + return null; + }, - prompt({ list }) { + prompt({ upgradable: list }) { return dedent` You're upgrading to the latest version of Storybook. We recommend upgrading the following packages: ${list.map(({ packageName, version }) => `${packageName}@${version}`).join(', ')} @@ -66,40 +92,58 @@ export const upgradeStorybookRelatedDependencies = { `; }, - async run({ result: { list }, packageManager, dryRun, mainConfigPath }) { + async run({ result: { upgradable, problematicPackages }, packageManager, dryRun }) { if (dryRun) { console.log(dedent` - would have upgrade the following: - ${list.map(({ packageName, version }) => `${packageName}@${version}`).join('\n')} + We would have upgrade the following: + ${upgradable.map(({ packageName, version }) => `${packageName}@${version}`).join('\n')} `); return; } - const packageJson = await packageManager.readPackageJson(); + if (upgradable.length > 0) { + const packageJson = await packageManager.readPackageJson(); - // mutate the packageJson data - list.forEach((item) => { - if (!item) { - return; - } - - const { packageName, version } = item; - const prefixed = `^${version}`; - - if (packageJson.dependencies?.[packageName]) { - packageJson.dependencies[packageName] = prefixed; - } - if (packageJson.devDependencies?.[packageName]) { - packageJson.devDependencies[packageName] = prefixed; - } - if (packageJson.peerDependencies?.[packageName]) { - packageJson.peerDependencies[packageName] = prefixed; - } - }); + upgradable.forEach((item) => { + if (!item) { + return; + } + + const { packageName, version } = item; + const prefixed = `^${version}`; + + if (packageJson.dependencies?.[packageName]) { + packageJson.dependencies[packageName] = prefixed; + } + if (packageJson.devDependencies?.[packageName]) { + packageJson.devDependencies[packageName] = prefixed; + } + if (packageJson.peerDependencies?.[packageName]) { + packageJson.peerDependencies[packageName] = prefixed; + } + }); + + await packageManager.writePackageJson(packageJson); + await packageManager.installDependencies(); - await packageManager.writePackageJson(packageJson); - await packageManager.installDependencies(); + await packageManager + .executeCommand({ command: 'dedupe', args: [], stdio: 'ignore' }) + .catch((e) => {}); - await packageManager.getRunCommand('dedupe'); + console.log(dedent` + We upgraded ${upgradable.length} packages: + ${upgradable.map(({ packageName, version }) => `- ${packageName}@${version}`).join('\n')} + `); + } + + if (problematicPackages.length) { + console.log(dedent` + The following packages, could not be upgraded, likely because there's no update available that's compatible with the latest version of Storybook: + ${problematicPackages.map(({ packageName }) => `- ${packageName}`).join('\n')} + + We suggest your reach out to the authors of these packages to get them updated. + But before reporting, please check if there is already an open issue or PR for this. + `); + } }, } satisfies Fix; diff --git a/code/lib/cli/src/automigrate/index.ts b/code/lib/cli/src/automigrate/index.ts index 843b8f4371d6..20cbf98a4166 100644 --- a/code/lib/cli/src/automigrate/index.ts +++ b/code/lib/cli/src/automigrate/index.ts @@ -30,6 +30,7 @@ import { getStorybookData } from './helpers/mainConfigFile'; import { doctor } from '../doctor'; import { upgradeStorybookRelatedDependencies } from './fixes/upgrade-storybook-related-dependencies'; +import dedent from 'ts-dedent'; const logger = console; const LOG_FILE_NAME = 'migration-storybook.log'; @@ -58,8 +59,16 @@ const cleanup = () => { }; const logAvailableMigrations = () => { - const availableFixes = allFixes.map((f) => chalk.yellow(f.id)).join(', '); - logger.info(`\nThe following migrations are available: ${availableFixes}`); + const availableFixes = allFixes + .map((f) => chalk.yellow(f.id)) + .map((x) => `- ${x}`) + .join('\n'); + + console.log(); + logger.info(dedent` + The following migrations are available: + ${availableFixes} + `); }; export const doAutomigrate = async (options: AutofixOptionsFromCLI) => { @@ -86,7 +95,7 @@ export const doAutomigrate = async (options: AutofixOptionsFromCLI) => { throw new Error('Could not determine main config path'); } - await automigrate({ + const outcome = await automigrate({ ...options, packageManager, storybookVersion, @@ -96,7 +105,9 @@ export const doAutomigrate = async (options: AutofixOptionsFromCLI) => { isUpgrade: false, }); - await doctor({ configDir, packageManager: options.packageManager }); + if (outcome) { + await doctor({ configDir, packageManager: options.packageManager }); + } }; export const automigrate = async ({ @@ -127,7 +138,11 @@ export const automigrate = async ({ inputFixes || allFixes.filter((fix) => { // we only allow this automigration when the user explicitly asks for it, or they are upgrading to the latest version of storybook - if (fix.id === upgradeStorybookRelatedDependencies.id && isUpgrade !== 'latest') { + if ( + fix.id === upgradeStorybookRelatedDependencies.id && + isUpgrade !== 'latest' && + fixId !== upgradeStorybookRelatedDependencies.id + ) { return false; } @@ -319,13 +334,13 @@ export async function runFixes({ fixResults[f.id] = FixStatus.MANUAL_SKIPPED; break; } - } else if (promptType === 'auto' || promptType === 'auto-no') { + } else if (promptType === 'auto') { runAnswer = await prompts( { type: 'confirm', name: 'fix', message: `Do you want to run the '${chalk.cyan(f.id)}' migration on your project?`, - initial: promptType === 'auto-no' ? false : true, + initial: f.promptDefaultValue ?? true, }, { onCancel: () => { diff --git a/code/lib/cli/src/automigrate/types.ts b/code/lib/cli/src/automigrate/types.ts index 45f2b4b72c01..8dad3d3d2fa9 100644 --- a/code/lib/cli/src/automigrate/types.ts +++ b/code/lib/cli/src/automigrate/types.ts @@ -22,11 +22,10 @@ export interface RunOptions { /** * promptType defines how the user will be prompted to apply an automigration fix * - auto: the fix will be applied automatically - * - auto-no: the fix will be applied automatically, but only when the user opts-in * - manual: the user will be prompted to apply the fix * - notification: the user will be notified about some changes. A fix isn't required, though */ -export type Prompt = 'auto' | 'auto-no' | 'manual' | 'notification'; +export type Prompt = 'auto' | 'manual' | 'notification'; type BaseFix = { id: string; @@ -38,6 +37,7 @@ type BaseFix = { versionRange: [from: string, to: string]; check: (options: CheckOptions) => Promise; prompt: (result: ResultType) => string; + promptDefaultValue?: boolean; }; type PromptType = @@ -46,7 +46,7 @@ type PromptType = export type Fix = ( | { - promptType?: PromptType; + promptType?: PromptType; run: (options: RunOptions) => Promise; } | { From 5ee7f99a4dc0a7f2c56e9efc25387beccef29002 Mon Sep 17 00:00:00 2001 From: Joe Vaughan <122215197+joevaugh4n@users.noreply.github.com> Date: Thu, 7 Mar 2024 17:13:47 +0000 Subject: [PATCH 088/132] Update index.md the links were broken for me when viewing this in production! --- docs/migration-guide/index.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/migration-guide/index.md b/docs/migration-guide/index.md index 70510a941d86..1f08919343ea 100644 --- a/docs/migration-guide/index.md +++ b/docs/migration-guide/index.md @@ -4,9 +4,9 @@ title: 'Migration guide for Storybook 8.0' Storybook 8 focuses on performance and stability. -- ๐Ÿ’จ [2-4x faster test builds](/blog/optimize-storybook-7-6/#2-4x-faster-builds-with-thetest-flag), [25-50% faster React docgen](/blog/optimize-storybook-7-6/#22x-faster-react-docgen), and [SWC support for Webpack projects](/blog/optimize-storybook-7-6/#using-webpack-enable-swc) +- ๐Ÿ’จ [2-4x faster test builds](https://storybook.com/blog/optimize-storybook-7-6/#2-4x-faster-builds-with-thetest-flag), [25-50% faster React docgen](https://storybook.com/blog/optimize-storybook-7-6/#22x-faster-react-docgen), and [SWC support for Webpack projects](https://storybook.com/blog/optimize-storybook-7-6/#using-webpack-enable-swc) - โœจ Improved framework support: you no longer need to install React as a peer dependency when using a non-React renderer -- ๐ŸŒ [Support for React Server Components (RSC)](/blog/storybook-react-server-components/): our experimental solution renders async RSC in the browser and mocks Node code +- ๐ŸŒ [Support for React Server Components (RSC)](https://storybook.com/blog/storybook-react-server-components/): our experimental solution renders async RSC in the browser and mocks Node code - โž• Much, much more This guide is meant to help you **upgrade from Storybook 7.x to 8.0** successfully! From 3356ca218de45201546f35c0e16342ac8809eecb Mon Sep 17 00:00:00 2001 From: Joe Vaughan <122215197+joevaugh4n@users.noreply.github.com> Date: Thu, 7 Mar 2024 17:14:48 +0000 Subject: [PATCH 089/132] Update index.md --- docs/migration-guide/index.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/migration-guide/index.md b/docs/migration-guide/index.md index 1f08919343ea..3ecf74ddfb57 100644 --- a/docs/migration-guide/index.md +++ b/docs/migration-guide/index.md @@ -4,9 +4,9 @@ title: 'Migration guide for Storybook 8.0' Storybook 8 focuses on performance and stability. -- ๐Ÿ’จ [2-4x faster test builds](https://storybook.com/blog/optimize-storybook-7-6/#2-4x-faster-builds-with-thetest-flag), [25-50% faster React docgen](https://storybook.com/blog/optimize-storybook-7-6/#22x-faster-react-docgen), and [SWC support for Webpack projects](https://storybook.com/blog/optimize-storybook-7-6/#using-webpack-enable-swc) +- ๐Ÿ’จ [2-4x faster test builds](https://storybook.js.org/blog/optimize-storybook-7-6/#2-4x-faster-builds-with-thetest-flag), [25-50% faster React docgen](https://storybook.js.org/blog/optimize-storybook-7-6/#22x-faster-react-docgen), and [SWC support for Webpack projects](https://storybook.js.org/blog/optimize-storybook-7-6/#using-webpack-enable-swc) - โœจ Improved framework support: you no longer need to install React as a peer dependency when using a non-React renderer -- ๐ŸŒ [Support for React Server Components (RSC)](https://storybook.com/blog/storybook-react-server-components/): our experimental solution renders async RSC in the browser and mocks Node code +- ๐ŸŒ [Support for React Server Components (RSC)](https://storybook.js.org/blog/storybook-react-server-components/): our experimental solution renders async RSC in the browser and mocks Node code - โž• Much, much more This guide is meant to help you **upgrade from Storybook 7.x to 8.0** successfully! From 604771126c573dfd2c6cd35df592e96c06847f9a Mon Sep 17 00:00:00 2001 From: Norbert de Langen Date: Thu, 7 Mar 2024 18:16:38 +0100 Subject: [PATCH 090/132] make it look prettier --- .../upgrade-storybook-related-dependencies.ts | 24 ++++++++++++------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/code/lib/cli/src/automigrate/fixes/upgrade-storybook-related-dependencies.ts b/code/lib/cli/src/automigrate/fixes/upgrade-storybook-related-dependencies.ts index 2a0630960226..bed260a4af66 100644 --- a/code/lib/cli/src/automigrate/fixes/upgrade-storybook-related-dependencies.ts +++ b/code/lib/cli/src/automigrate/fixes/upgrade-storybook-related-dependencies.ts @@ -1,6 +1,6 @@ import { dedent } from 'ts-dedent'; import type { Fix } from '../types'; -import { underline } from 'chalk'; +import { cyan, underline, yellow } from 'chalk'; import { getIncompatibleStorybookPackages } from '../../doctor/getIncompatibleStorybookPackages'; import { valid, coerce } from 'semver'; @@ -78,7 +78,9 @@ export const upgradeStorybookRelatedDependencies = { prompt({ upgradable: list }) { return dedent` You're upgrading to the latest version of Storybook. We recommend upgrading the following packages: - ${list.map(({ packageName, version }) => `${packageName}@${version}`).join(', ')} + ${list + .map(({ packageName, version }) => `- ${cyan(packageName)}@${cyan(version)}`) + .join('\n')} We detected those packages are incompatible with the latest version of Storybook. ${underline( @@ -130,20 +132,26 @@ export const upgradeStorybookRelatedDependencies = { .executeCommand({ command: 'dedupe', args: [], stdio: 'ignore' }) .catch((e) => {}); + console.log(); console.log(dedent` - We upgraded ${upgradable.length} packages: - ${upgradable.map(({ packageName, version }) => `- ${packageName}@${version}`).join('\n')} - `); + We upgraded ${yellow(upgradable.length)} packages: + ${upgradable + .map(({ packageName, version }) => `- ${cyan(packageName)}@${cyan(version)}`) + .join('\n')} + `); } if (problematicPackages.length) { + console.log(); console.log(dedent` - The following packages, could not be upgraded, likely because there's no update available that's compatible with the latest version of Storybook: - ${problematicPackages.map(({ packageName }) => `- ${packageName}`).join('\n')} + The following packages, could not be upgraded, + likely because there's no update available compatible with the latest version of Storybook: + ${problematicPackages.map(({ packageName }) => `- ${cyan(packageName)}`).join('\n')} We suggest your reach out to the authors of these packages to get them updated. But before reporting, please check if there is already an open issue or PR for this. - `); + `); } + console.log(); }, } satisfies Fix; From 6c5bb5ea71260dcfa056ab00d1a88e88ebb9d39c Mon Sep 17 00:00:00 2001 From: Norbert de Langen Date: Thu, 7 Mar 2024 18:42:00 +0100 Subject: [PATCH 091/132] revert the use of satisfies --- code/lib/cli/src/automigrate/fixes/index.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/code/lib/cli/src/automigrate/fixes/index.ts b/code/lib/cli/src/automigrate/fixes/index.ts index 01bdc2b2aa94..022074fa8301 100644 --- a/code/lib/cli/src/automigrate/fixes/index.ts +++ b/code/lib/cli/src/automigrate/fixes/index.ts @@ -30,7 +30,7 @@ import { upgradeStorybookRelatedDependencies } from './upgrade-storybook-related export * from '../types'; -export const allFixes = [ +export const allFixes: Fix[] = [ addonsAPI, newFrameworks, cra5, @@ -58,6 +58,6 @@ export const allFixes = [ webpack5CompilerSetup, mdx1to3, upgradeStorybookRelatedDependencies, -] satisfies Fix[]; +]; -export const initFixes = [eslintPlugin] satisfies Fix[]; +export const initFixes: Fix[] = [eslintPlugin]; From e0444ac80560ce45e228ba6911a86d4147f3770a Mon Sep 17 00:00:00 2001 From: Kyle Gach Date: Thu, 7 Mar 2024 10:50:21 -0700 Subject: [PATCH 092/132] Address comments --- docs/get-started/angular.md | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/docs/get-started/angular.md b/docs/get-started/angular.md index 0ba81ea5c1e9..e5c706acc1df 100644 --- a/docs/get-started/angular.md +++ b/docs/get-started/angular.md @@ -26,9 +26,9 @@ Storybook for Angular is only supported in [Angular](?renderer=angular) projects ## Requirements -- Angular โ‰ฅ 14.1.0 < 18.0.0 +- Angular โ‰ฅ 15.0 < 18.0 - Webpack โ‰ฅ 5.0 -- Storybook โ‰ฅ 7.0 +- Storybook โ‰ฅ 8.0 ## Getting started @@ -384,9 +384,9 @@ You can run `npx storybook@latest init` sequentially for each project to setup S You can then use [Storybook composition](https://storybook.js.org/docs/angular/sharing/storybook-composition) to composite multiple Storybooks into one. -### How do I configure Angular's builder for Storybook?v +### How do I configure Angular's builder for Storybook? -These are the supported options for the Angular builder: +These are common options you may need for the Angular builder: | Configuration element | Description | | ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | @@ -406,6 +406,11 @@ These are the supported options for the Angular builder: | `"styles"` | Provide the location of the [application's styles](../configure/styling-and-css.md#importing-css-files) to be used with Storybook.
`"styles": ["src/styles.css", "src/styles.scss"]`
| | `"stylePreprocessorOptions"` | Provides further customization for style preprocessors resolved to the workspace root.
`"stylePreprocessorOptions": { "includePaths": ["src/styles"] }` | +The full list of options can be found in the Angular builder schemas: + +- [Build Storybook](https://github.com/storybookjs/storybook/blob/main/code/frameworks/angular/src/builders/build-storybook/schema.json) +- [Start Storybook](https://github.com/storybookjs/storybook/blob/main/code/frameworks/angular/src/builders/start-storybook/schema.json) + ## API ### Options From 4c60e7b900f1d8903ba0de5eadad1e1b5be6bd18 Mon Sep 17 00:00:00 2001 From: Norbert de Langen Date: Thu, 7 Mar 2024 18:53:13 +0100 Subject: [PATCH 093/132] minor typing issues fixed --- .../fixes/upgrade-storybook-related-dependencies.ts | 4 ++-- code/lib/cli/src/upgrade.ts | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/code/lib/cli/src/automigrate/fixes/upgrade-storybook-related-dependencies.ts b/code/lib/cli/src/automigrate/fixes/upgrade-storybook-related-dependencies.ts index bed260a4af66..1356c07d4c09 100644 --- a/code/lib/cli/src/automigrate/fixes/upgrade-storybook-related-dependencies.ts +++ b/code/lib/cli/src/automigrate/fixes/upgrade-storybook-related-dependencies.ts @@ -43,7 +43,7 @@ export const upgradeStorybookRelatedDependencies = { Array.from(new Set([...associated, ...detected])).map(async (packageName) => { return { packageName, - version: await packageManager.latestVersion(packageName).catch((e) => null), + version: await packageManager.latestVersion(packageName).catch(() => null), }; }) ); @@ -130,7 +130,7 @@ export const upgradeStorybookRelatedDependencies = { await packageManager .executeCommand({ command: 'dedupe', args: [], stdio: 'ignore' }) - .catch((e) => {}); + .catch(() => {}); console.log(); console.log(dedent` diff --git a/code/lib/cli/src/upgrade.ts b/code/lib/cli/src/upgrade.ts index 757ad89bdd7c..e49f668f4f87 100644 --- a/code/lib/cli/src/upgrade.ts +++ b/code/lib/cli/src/upgrade.ts @@ -22,7 +22,6 @@ import { } from '@storybook/core-common'; import { automigrate } from './automigrate/index'; import { autoblock } from './autoblock/index'; -import { is } from '@babel/types'; type Package = { package: string; From 586ba186ae140f7d300755b7abdc121c1168d282 Mon Sep 17 00:00:00 2001 From: Norbert de Langen Date: Thu, 7 Mar 2024 19:00:46 +0100 Subject: [PATCH 094/132] fix another typing issue --- .../upgrade-storybook-related-dependencies.ts | 25 +++++++++++-------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/code/lib/cli/src/automigrate/fixes/upgrade-storybook-related-dependencies.ts b/code/lib/cli/src/automigrate/fixes/upgrade-storybook-related-dependencies.ts index 1356c07d4c09..4f1ab90b818b 100644 --- a/code/lib/cli/src/automigrate/fixes/upgrade-storybook-related-dependencies.ts +++ b/code/lib/cli/src/automigrate/fixes/upgrade-storybook-related-dependencies.ts @@ -50,17 +50,20 @@ export const upgradeStorybookRelatedDependencies = { const data = list.reduce( (acc, k) => { - const upgradable = !( - !valid(k.version) || - k.version === coerce(packageJson?.dependencies?.[k.packageName])?.toString() || - k.version === coerce(packageJson?.devDependencies?.[k.packageName])?.toString() || - k.version === coerce(packageJson?.peerDependencies?.[k.packageName])?.toString() - ); - - if (upgradable) { - acc.upgradable.push(k); - } else { - acc.problematicPackages.push(k); + if (k.version !== null) { + const { packageName, version } = k; + const upgradable = !( + !valid(k.version) || + k.version === coerce(packageJson?.dependencies?.[k.packageName])?.toString() || + k.version === coerce(packageJson?.devDependencies?.[k.packageName])?.toString() || + k.version === coerce(packageJson?.peerDependencies?.[k.packageName])?.toString() + ); + + if (upgradable) { + acc.upgradable.push({ packageName, version }); + } else { + acc.problematicPackages.push({ packageName, version }); + } } return acc; From 9a1c77cd9ef8273747f99df19057dd3c0a1064be Mon Sep 17 00:00:00 2001 From: Norbert de Langen Date: Thu, 7 Mar 2024 19:09:39 +0100 Subject: [PATCH 095/132] make `changeRefVersion` async as well, and correct the types --- code/lib/manager-api/src/modules/refs.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/code/lib/manager-api/src/modules/refs.ts b/code/lib/manager-api/src/modules/refs.ts index f783f7db6496..e686f6f1c1b6 100644 --- a/code/lib/manager-api/src/modules/refs.ts +++ b/code/lib/manager-api/src/modules/refs.ts @@ -43,7 +43,7 @@ export interface SubAPI { * @param {string} id - The ID of the composed ref. * @param {API_ComposedRefUpdate} ref - The update object for the composed ref. */ - updateRef: (id: string, ref: API_ComposedRefUpdate) => void; + updateRef: (id: string, ref: API_ComposedRefUpdate) => Promise; /** * Gets all composed refs. * @returns {API_Refs} - The composed refs object. @@ -60,7 +60,7 @@ export interface SubAPI { * @param {string} id - The ID of the composed ref. * @param {string} url - The new URL for the composed ref. */ - changeRefVersion: (id: string, url: string) => void; + changeRefVersion: (id: string, url: string) => Promise; /** * Changes the state of a composed ref by its ID and previewInitialized flag. * @param {string} id - The ID of the composed ref. @@ -168,12 +168,12 @@ export const init: ModuleFn = ( return Object.values(refs).find(({ url }: any) => url.match(source)); }, - changeRefVersion: (id, url) => { + changeRefVersion: async (id, url) => { const { versions, title } = api.getRefs()[id]; const ref: API_SetRefData = { id, url, versions, title, index: {}, expanded: true }; api.setRef(id, { ...ref, type: 'unknown' }, false); - api.checkRef(ref); + await api.checkRef(ref); }, changeRefState: (id, previewInitialized) => { const { [id]: ref, ...updated } = api.getRefs(); From 4780ae31030197488d66b4fba483867f416bdb0a Mon Sep 17 00:00:00 2001 From: Kyle Gach Date: Thu, 7 Mar 2024 11:12:25 -0700 Subject: [PATCH 096/132] Add section about missing vite config file --- docs/migration-guide/from-older-version.md | 4 ++++ docs/migration-guide/index.md | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/docs/migration-guide/from-older-version.md b/docs/migration-guide/from-older-version.md index b3740aa2f854..89e290bb0216 100644 --- a/docs/migration-guide/from-older-version.md +++ b/docs/migration-guide/from-older-version.md @@ -79,6 +79,10 @@ If you are using the `storiesOf` API (which requires `storyStoreV7: false` in St Storybook 8 uses MDX 3. If you're coming from MDX 1 (used by Storybook 6), there were significant breaking changes in MDX 2. Please reference our [guidance on upgrading successfully](../../release-7-6/docs/migration-guide.md#upgrade-mdx1-to-mdx2). +#### Missing `vite.config.js` file + +If you are using Vite, you may now need to create a `vite.config.js` file in your project root to allow newer versions of Vite to work with Storybook. Additionally, you may need to install and configure a Vite plugin for your framework. More information is available in the [full migration notes](https://github.com/storybookjs/storybook/blob/next/MIGRATION.md#framework-specific-vite-plugins-have-to-be-explicitly-added). + ## Troubleshooting The automatic upgrade should get your Storybook into a working state. If you encounter an error running Storybook after upgrading, hereโ€™s what to do: diff --git a/docs/migration-guide/index.md b/docs/migration-guide/index.md index 3ecf74ddfb57..314a90807140 100644 --- a/docs/migration-guide/index.md +++ b/docs/migration-guide/index.md @@ -79,6 +79,10 @@ If you have `storyStoreV7: false` in your `.storybook/main.js`, you will need to If you are using the `storiesOf` API (which requires `storyStoreV7: false` in Storybook 7), you will need to either [migrate your stories to CSF](../../release-7-6/docs/migration-guide.md#storiesof-to-csf) or use the [new indexer API to continue creating stories dynamically](../../release-7-6/docs/migration-guide.md#storiesof-to-dynamically-created-stories). +#### Missing `vite.config.js` file + +If you are using Vite, you may now need to create a `vite.config.js` file in your project root to allow newer versions of Vite to work with Storybook. Additionally, you may need to install and configure a Vite plugin for your framework. More information is available in the [full migration notes](https://github.com/storybookjs/storybook/blob/next/MIGRATION.md#framework-specific-vite-plugins-have-to-be-explicitly-added). + ## New projects To add Storybook to a project that isnโ€™t currently using Storybook: From 8b0040fe190b67fd7c10fc4d1dfa9c8fbb4b2071 Mon Sep 17 00:00:00 2001 From: Norbert de Langen Date: Thu, 7 Mar 2024 19:24:34 +0100 Subject: [PATCH 097/132] use a shorter link --- code/lib/cli/src/automigrate/fixes/vite-config-file.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/lib/cli/src/automigrate/fixes/vite-config-file.ts b/code/lib/cli/src/automigrate/fixes/vite-config-file.ts index 6a8dd9ec0e02..22d38efddf25 100644 --- a/code/lib/cli/src/automigrate/fixes/vite-config-file.ts +++ b/code/lib/cli/src/automigrate/fixes/vite-config-file.ts @@ -105,7 +105,7 @@ export const viteConfigFile = { If you do already have these plugins, you can ignore this message. You can find more information on how to do this here: - https://github.com/storybookjs/storybook/blob/next/MIGRATION.md#framework-specific-vite-plugins-have-to-be-explicitly-added + https://github.com/storybookjs/storybook/pull/26378 This change was necessary to support newer versions of Vite. `; @@ -115,7 +115,7 @@ export const viteConfigFile = { Please add a vite.config.js file to your project root. You can find more information on how to do this here: - https://github.com/storybookjs/storybook/blob/next/MIGRATION.md#framework-specific-vite-plugins-have-to-be-explicitly-added + https://github.com/storybookjs/storybook/pull/26378 This change was necessary to support newer versions of Vite. `; From 33fd582745f9826e99edf6150928bac637b41c4b Mon Sep 17 00:00:00 2001 From: Norbert de Langen Date: Thu, 7 Mar 2024 19:27:41 +0100 Subject: [PATCH 098/132] use the right link --- code/lib/cli/src/automigrate/fixes/vite-config-file.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/lib/cli/src/automigrate/fixes/vite-config-file.ts b/code/lib/cli/src/automigrate/fixes/vite-config-file.ts index 22d38efddf25..9203b45f225f 100644 --- a/code/lib/cli/src/automigrate/fixes/vite-config-file.ts +++ b/code/lib/cli/src/automigrate/fixes/vite-config-file.ts @@ -105,7 +105,7 @@ export const viteConfigFile = { If you do already have these plugins, you can ignore this message. You can find more information on how to do this here: - https://github.com/storybookjs/storybook/pull/26378 + https://storybook.js.org/docs/8.0/migration-guide/#missing-viteconfigjs-file This change was necessary to support newer versions of Vite. `; @@ -115,7 +115,7 @@ export const viteConfigFile = { Please add a vite.config.js file to your project root. You can find more information on how to do this here: - https://github.com/storybookjs/storybook/pull/26378 + https://storybook.js.org/docs/8.0/migration-guide/#missing-viteconfigjs-file This change was necessary to support newer versions of Vite. `; From c5503309b92ed4fd55aa3081b24e6bd9bc824bc0 Mon Sep 17 00:00:00 2001 From: Joe Vaughan <122215197+joevaugh4n@users.noreply.github.com> Date: Thu, 7 Mar 2024 18:45:17 +0000 Subject: [PATCH 099/132] Docs: update index.md Changed the feature list --- docs/migration-guide/index.md | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/docs/migration-guide/index.md b/docs/migration-guide/index.md index 314a90807140..db216a58cf4b 100644 --- a/docs/migration-guide/index.md +++ b/docs/migration-guide/index.md @@ -1,12 +1,17 @@ --- -title: 'Migration guide for Storybook 8.0' +title: 'Migration guide from Storybook 6.x to 8.0' --- -Storybook 8 focuses on performance and stability. +Storybook 8 focuses on improving performance, compatibility, and stability. Key features include: +- ๐Ÿฉป A new visual testing workflow via [the Visual Tests addon](https://www.chromatic.com/docs/visual-tests-addon/) - ๐Ÿ’จ [2-4x faster test builds](https://storybook.js.org/blog/optimize-storybook-7-6/#2-4x-faster-builds-with-thetest-flag), [25-50% faster React docgen](https://storybook.js.org/blog/optimize-storybook-7-6/#22x-faster-react-docgen), and [SWC support for Webpack projects](https://storybook.js.org/blog/optimize-storybook-7-6/#using-webpack-enable-swc) -- โœจ Improved framework support: you no longer need to install React as a peer dependency when using a non-React renderer +- ๐Ÿงฉ Improved framework support: you no longer need to install React as a peer dependency when using a non-React renderer +- ๐ŸŽ›๏ธย Strengthened control generation in [React](https://storybook.js.org/blog/storybook-8-beta/#major-performance-improvements +) and [Vue](https://storybook.js.org/blog/first-class-vue-support-storybook-8/) projects +- โšก๏ธ Improved Vite architecture, Vitest testing, and Vite 5 support - ๐ŸŒ [Support for React Server Components (RSC)](https://storybook.js.org/blog/storybook-react-server-components/): our experimental solution renders async RSC in the browser and mocks Node code +- โœจ A refreshed desktop UI & mobile UX - โž• Much, much more This guide is meant to help you **upgrade from Storybook 7.x to 8.0** successfully! From 9eea0d4a5a3e0c91558ec76d5c438450ab4de6bc Mon Sep 17 00:00:00 2001 From: Joe Vaughan <122215197+joevaugh4n@users.noreply.github.com> Date: Thu, 7 Mar 2024 18:45:40 +0000 Subject: [PATCH 100/132] Update index.md fixed title change --- docs/migration-guide/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/migration-guide/index.md b/docs/migration-guide/index.md index db216a58cf4b..51962ca7b88d 100644 --- a/docs/migration-guide/index.md +++ b/docs/migration-guide/index.md @@ -1,5 +1,5 @@ --- -title: 'Migration guide from Storybook 6.x to 8.0' +title: 'Migration guide for Storybook 8.0' --- Storybook 8 focuses on improving performance, compatibility, and stability. Key features include: From c2be62fd8dccfcb0adb5c6e09e48f6a441af077f Mon Sep 17 00:00:00 2001 From: Joe Vaughan <122215197+joevaugh4n@users.noreply.github.com> Date: Thu, 7 Mar 2024 18:46:27 +0000 Subject: [PATCH 101/132] Update from-older-version.md updated feature list --- docs/migration-guide/from-older-version.md | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/docs/migration-guide/from-older-version.md b/docs/migration-guide/from-older-version.md index 89e290bb0216..c368c48e39be 100644 --- a/docs/migration-guide/from-older-version.md +++ b/docs/migration-guide/from-older-version.md @@ -2,11 +2,16 @@ title: 'Migration guide from Storybook 6.x to 8.0' --- -Storybook 8 focuses on performance and stability. - -- ๐Ÿ’จ [2-4x faster test builds](/blog/optimize-storybook-7-6/#2-4x-faster-builds-with-thetest-flag), [25-50% faster React docgen](/blog/optimize-storybook-7-6/#22x-faster-react-docgen), and [SWC support for Webpack projects](/blog/optimize-storybook-7-6/#using-webpack-enable-swc) -- โœจ Improved framework support: you no longer need to install React as a peer dependency when using a non-React renderer -- ๐ŸŒ [Support for React Server Components (RSC)](/blog/storybook-react-server-components/): our experimental solution renders async RSC in the browser and mocks Node code +Storybook 8 focuses on improving performance, compatibility, and stability. Key features include: + +- ๐Ÿฉป A new visual testing workflow via [the Visual Tests addon](https://www.chromatic.com/docs/visual-tests-addon/) +- ๐Ÿ’จ [2-4x faster test builds](https://storybook.js.org/blog/optimize-storybook-7-6/#2-4x-faster-builds-with-thetest-flag), [25-50% faster React docgen](https://storybook.js.org/blog/optimize-storybook-7-6/#22x-faster-react-docgen), and [SWC support for Webpack projects](https://storybook.js.org/blog/optimize-storybook-7-6/#using-webpack-enable-swc) +- ๐Ÿงฉ Improved framework support: you no longer need to install React as a peer dependency when using a non-React renderer +- ๐ŸŽ›๏ธย Strengthened control generation in [React](https://storybook.js.org/blog/storybook-8-beta/#major-performance-improvements +) and [Vue](https://storybook.js.org/blog/first-class-vue-support-storybook-8/) projects +- โšก๏ธ Improved Vite architecture, Vitest testing, and Vite 5 support +- ๐ŸŒ [Support for React Server Components (RSC)](https://storybook.js.org/blog/storybook-react-server-components/): our experimental solution renders async RSC in the browser and mocks Node code +- โœจ A refreshed desktop UI & mobile UX - โž• Much, much more This guide is meant to help you **upgrade from Storybook 6.x to 8.0** successfully! From 13e872c838feddf7e2e468977a150efa24b797c5 Mon Sep 17 00:00:00 2001 From: Yann Braga Date: Fri, 8 Mar 2024 11:48:55 +0100 Subject: [PATCH 102/132] React: Support all React component types in JSX Decorator --- .../react/src/docs/jsxDecorator.test.tsx | 105 ++++++++++++------ .../renderers/react/src/docs/jsxDecorator.tsx | 43 ++++++- 2 files changed, 109 insertions(+), 39 deletions(-) diff --git a/code/renderers/react/src/docs/jsxDecorator.test.tsx b/code/renderers/react/src/docs/jsxDecorator.test.tsx index bfb20fdd5f0d..6ed0f0eda179 100644 --- a/code/renderers/react/src/docs/jsxDecorator.test.tsx +++ b/code/renderers/react/src/docs/jsxDecorator.test.tsx @@ -1,3 +1,4 @@ +/* eslint-disable no-underscore-dangle */ import type { FC, PropsWithChildren } from 'react'; import React, { StrictMode, createElement, Profiler } from 'react'; import type { Mock } from 'vitest'; @@ -5,7 +6,7 @@ import { vi, describe, it, expect, beforeEach } from 'vitest'; import PropTypes from 'prop-types'; import { addons, useEffect } from '@storybook/preview-api'; import { SNIPPET_RENDERED } from '@storybook/docs-tools'; -import { renderJsx, jsxDecorator } from './jsxDecorator'; +import { renderJsx, jsxDecorator, getReactSymbolName } from './jsxDecorator'; vi.mock('@storybook/preview-api'); const mockedAddons = vi.mocked(addons); @@ -16,6 +17,18 @@ expect.addSnapshotSerializer({ test: (val) => typeof val === 'string', }); +describe('converts React Symbol to displayName string', () => { + const symbolCases = [ + ['react.suspense', 'React.Suspense'], + ['react.strict_mode', 'React.StrictMode'], + ['react.server_context.defaultValue', 'React.ServerContext.DefaultValue'], + ]; + + it.each(symbolCases)('"%s" to "%s"', (symbol, expectedValue) => { + expect(getReactSymbolName(Symbol(symbol))).toEqual(expectedValue); + }); +}); + describe('renderJsx', () => { it('basic', () => { expect(renderJsx(

, {})).toMatchInlineSnapshot(` @@ -139,53 +152,71 @@ describe('renderJsx', () => { }); it('Profiler', () => { - function ProfilerComponent({ children }: any) { - return ( + expect( + renderJsx( {}}> -
{children}
-
- ); - } - - expect(renderJsx(createElement(ProfilerComponent, {}, 'I am Profiler'), {})) - .toMatchInlineSnapshot(` - - I am Profiler - +
I am in a Profiler
+ , + {} + ) + ).toMatchInlineSnapshot(` + {}} + > +
+ I am in a Profiler +
+
`); }); it('StrictMode', () => { - function StrictModeComponent({ children }: any) { - return ( - -
{children}
-
- ); + expect(renderJsx(I am StrictMode, {})).toMatchInlineSnapshot(` + + I am StrictMode + + `); + }); + + it('displayName coming from docgenInfo', () => { + function BasicComponent({ label }: any) { + return ; } + BasicComponent.__docgenInfo = { + description: 'Some description', + methods: [], + displayName: 'Button', + props: {}, + }; - expect(renderJsx(createElement(StrictModeComponent, {}, 'I am StrictMode'), {})) - .toMatchInlineSnapshot(` - - I am StrictMode - - `); + expect( + renderJsx( + createElement( + BasicComponent, + { + label:

Abcd

, + }, + undefined + ) + ) + ).toMatchInlineSnapshot(` - + Children coming from story args! + `; @@ -21,17 +16,12 @@ exports[`Renders CSF2Secondary story 1`] = ` exports[`Renders CSF2StoryWithParamsAndDecorator story 1`] = `
-
- -
+ foo +
`; @@ -39,17 +29,12 @@ exports[`Renders CSF2StoryWithParamsAndDecorator story 1`] = ` exports[`Renders CSF3Button story 1`] = `
-
- -
+ foo +
`; @@ -57,23 +42,18 @@ exports[`Renders CSF3Button story 1`] = ` exports[`Renders CSF3ButtonWithRender story 1`] = `
-
-
-

- I am a custom render function -

- -
+
+

+ I am a custom render function +

+
@@ -82,14 +62,9 @@ exports[`Renders CSF3ButtonWithRender story 1`] = ` exports[`Renders CSF3InputFieldFilled story 1`] = `
-
- -
+
`; @@ -97,17 +72,12 @@ exports[`Renders CSF3InputFieldFilled story 1`] = ` exports[`Renders CSF3Primary story 1`] = `
-
- -
+ foo +
`; @@ -115,21 +85,16 @@ exports[`Renders CSF3Primary story 1`] = ` exports[`Renders LoaderStory story 1`] = `
-
-
-
- loaded data -
-
- mockFn return value -
+
+
+ loaded data +
+
+ mockFn return value
diff --git a/code/renderers/react/src/portable-stories.tsx b/code/renderers/react/src/portable-stories.ts similarity index 90% rename from code/renderers/react/src/portable-stories.tsx rename to code/renderers/react/src/portable-stories.ts index 3493e0f3b2e5..5994dbc1e408 100644 --- a/code/renderers/react/src/portable-stories.tsx +++ b/code/renderers/react/src/portable-stories.ts @@ -1,9 +1,7 @@ -import React from 'react'; import { composeStory as originalComposeStory, composeStories as originalComposeStories, setProjectAnnotations as originalSetProjectAnnotations, - getPortableStoryWrapperId, } from '@storybook/preview-api'; import type { Args, @@ -13,7 +11,7 @@ import type { StoriesWithPartialProps, } from '@storybook/types'; -import * as reactProjectAnnotations from './entry-preview'; +import * as defaultProjectAnnotations from './entry-preview'; import type { Meta } from './public-types'; import type { ReactRenderer } from './types'; @@ -38,20 +36,6 @@ export function setProjectAnnotations( originalSetProjectAnnotations(projectAnnotations); } -// This will not be necessary once we have auto preset loading -const defaultProjectAnnotations: ProjectAnnotations = { - ...reactProjectAnnotations, - decorators: [ - function addStorybookId(StoryFn, { id }) { - return ( -
- -
- ); - }, - ], -}; - /** * Function that will receive a story along with meta (e.g. a default export from a .stories file) * and optionally projectAnnotations e.g. (import * from '../.storybook/preview) diff --git a/code/renderers/vue3/src/__tests__/composeStories/__snapshots__/portable-stories.test.ts.snap b/code/renderers/vue3/src/__tests__/composeStories/__snapshots__/portable-stories.test.ts.snap index b6e6feff8f61..bb968e20d142 100644 --- a/code/renderers/vue3/src/__tests__/composeStories/__snapshots__/portable-stories.test.ts.snap +++ b/code/renderers/vue3/src/__tests__/composeStories/__snapshots__/portable-stories.test.ts.snap @@ -3,17 +3,12 @@ exports[`Renders CSF2Secondary story 1`] = `
-
- -
+ label coming from story args! +
`; @@ -22,19 +17,14 @@ exports[`Renders CSF2StoryWithParamsAndDecorator story 1`] = `
-
- -
+ foo +
@@ -43,17 +33,12 @@ exports[`Renders CSF2StoryWithParamsAndDecorator story 1`] = ` exports[`Renders CSF3Button story 1`] = `
-
- -
+ foo +
`; @@ -61,23 +46,18 @@ exports[`Renders CSF3Button story 1`] = ` exports[`Renders CSF3ButtonWithRender story 1`] = `
-
-
-

- I am a custom render function -

- -
+
+

+ I am a custom render function +

+
@@ -86,14 +66,9 @@ exports[`Renders CSF3ButtonWithRender story 1`] = ` exports[`Renders CSF3InputFieldFilled story 1`] = `
-
- -
+
`; @@ -101,17 +76,12 @@ exports[`Renders CSF3InputFieldFilled story 1`] = ` exports[`Renders CSF3Primary story 1`] = `
-
- -
+ foo +
`; @@ -119,21 +89,16 @@ exports[`Renders CSF3Primary story 1`] = ` exports[`Renders LoaderStory story 1`] = `
-
-
-
- loaded data -
-
- mockFn return value -
+
+
+ loaded data +
+
+ mockFn return value
diff --git a/code/renderers/vue3/src/portable-stories.ts b/code/renderers/vue3/src/portable-stories.ts index 73c7991f16a6..dca738d205bf 100644 --- a/code/renderers/vue3/src/portable-stories.ts +++ b/code/renderers/vue3/src/portable-stories.ts @@ -2,7 +2,6 @@ import { composeStory as originalComposeStory, composeStories as originalComposeStories, setProjectAnnotations as originalSetProjectAnnotations, - getPortableStoryWrapperId, } from '@storybook/preview-api'; import type { Args, @@ -13,20 +12,10 @@ import type { } from '@storybook/types'; import { h } from 'vue'; -import * as vueProjectAnnotations from './entry-preview'; +import * as defaultProjectAnnotations from './entry-preview'; import type { Meta } from './public-types'; import type { VueRenderer } from './types'; -const defaultProjectAnnotations: ProjectAnnotations = { - ...vueProjectAnnotations, - decorators: [ - function (story, { id }) { - const wrapperProps = { 'data-story': true, id: getPortableStoryWrapperId(id) }; - return h('div', wrapperProps, h(story())); - }, - ], -}; - /** Function that sets the globalConfig of your Storybook. The global config is the preview module of your .storybook folder. * * It should be run a single time, so that your global config (e.g. decorators) is applied to your stories when using `composeStories` or `composeStory`. From af63b0fd0191acb067cfc3036d991c9040f96cde Mon Sep 17 00:00:00 2001 From: Norbert de Langen Date: Fri, 8 Mar 2024 14:48:26 +0100 Subject: [PATCH 110/132] wip --- .../upgrade-storybook-related-dependencies.ts | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/code/lib/cli/src/automigrate/fixes/upgrade-storybook-related-dependencies.ts b/code/lib/cli/src/automigrate/fixes/upgrade-storybook-related-dependencies.ts index b2804e1496bf..afa17b5440c6 100644 --- a/code/lib/cli/src/automigrate/fixes/upgrade-storybook-related-dependencies.ts +++ b/code/lib/cli/src/automigrate/fixes/upgrade-storybook-related-dependencies.ts @@ -1,8 +1,9 @@ import { dedent } from 'ts-dedent'; import type { Fix } from '../types'; -import { cyan, underline, yellow } from 'chalk'; +import { cyan, yellow } from 'chalk'; import { getIncompatibleStorybookPackages } from '../../doctor/getIncompatibleStorybookPackages'; import { valid, coerce } from 'semver'; +import { isCorePackage } from '@storybook/core-common'; interface Options { upgradable: { packageName: string; version: string }[]; @@ -34,7 +35,9 @@ export const upgradeStorybookRelatedDependencies = { const all = await packageManager.getAllDependencies(); - const associated = Object.keys(all).filter((dep) => dep.includes('storybook')); + const associated = Object.keys(all) + .filter((dep) => dep.includes('storybook')) + .filter(isCorePackage); const detected = analyzed .filter((m) => m.hasIncompatibleDependencies) .map((m) => m.packageName); @@ -85,12 +88,7 @@ export const upgradeStorybookRelatedDependencies = { .map(({ packageName, version }) => `- ${cyan(packageName)}@${cyan(version)}`) .join('\n')} - We detected those packages are incompatible with the latest version of Storybook. - ${underline( - `The list might be incomplete, so it's advised to upgrade dependencies manually, but this automigration can help you get started.` - )} - - After upgrading, we will run the dedupe command, which could possibly have effects on dependencies that are not storybook related. + After upgrading, we will run the dedupe command, which could possibly have effects on dependencies that are not Storybook related. see: https://docs.npmjs.com/cli/commands/npm-dedupe Do you want to proceed (upgrade the detected packages)? From 9dfb3aaaceb29d621d9dbcf28b05174123a42956 Mon Sep 17 00:00:00 2001 From: Norbert de Langen Date: Fri, 8 Mar 2024 15:11:38 +0100 Subject: [PATCH 111/132] make it better --- .../upgrade-storybook-related-dependencies.ts | 124 +++++++++++------- 1 file changed, 75 insertions(+), 49 deletions(-) diff --git a/code/lib/cli/src/automigrate/fixes/upgrade-storybook-related-dependencies.ts b/code/lib/cli/src/automigrate/fixes/upgrade-storybook-related-dependencies.ts index afa17b5440c6..aefa841f91c2 100644 --- a/code/lib/cli/src/automigrate/fixes/upgrade-storybook-related-dependencies.ts +++ b/code/lib/cli/src/automigrate/fixes/upgrade-storybook-related-dependencies.ts @@ -3,11 +3,59 @@ import type { Fix } from '../types'; import { cyan, yellow } from 'chalk'; import { getIncompatibleStorybookPackages } from '../../doctor/getIncompatibleStorybookPackages'; import { valid, coerce } from 'semver'; +import type { JsPackageManager } from '@storybook/core-common'; import { isCorePackage } from '@storybook/core-common'; +type PackageMetadata = { + packageName: string; + beforeVersion: string; + afterVersion: string | null; +}; + interface Options { - upgradable: { packageName: string; version: string }[]; - problematicPackages: { packageName: string; version: string }[]; + upgradable: PackageMetadata[]; + problematicPackages: PackageMetadata[]; +} + +async function getLatestVersions( + packageManager: JsPackageManager, + packages: [string, string][] +): Promise { + return Promise.all( + packages.map(async ([packageName, beforeVersion]) => ({ + packageName, + beforeVersion, + afterVersion: await packageManager.latestVersion(packageName).catch(() => null), + })) + ); +} + +function isPackageUpgradable( + version: string, + packageName: string, + allDependencies: Record +) { + const installedVersion = coerce(allDependencies[packageName])?.toString(); + + return valid(version) && version !== installedVersion; +} + +function categorizePackages( + packageVersions: PackageMetadata[], + allDependencies: Record +) { + return packageVersions.reduce( + (acc, { packageName, afterVersion, beforeVersion }) => { + if (afterVersion === null) return acc; + + const isUpgradable = isPackageUpgradable(afterVersion, packageName, allDependencies); + const category = isUpgradable ? 'upgradable' : 'problematicPackages'; + acc[category].push({ packageName, afterVersion, beforeVersion }); + + return acc; + }, + { upgradable: [], problematicPackages: [] } as Options + ); } /** @@ -26,66 +74,37 @@ export const upgradeStorybookRelatedDependencies = { promptDefaultValue: false, async check({ packageManager, storybookVersion }) { - const packageJson = await packageManager.readPackageJson(); - const analyzed = await getIncompatibleStorybookPackages({ + const analyzedPackages = await getIncompatibleStorybookPackages({ currentStorybookVersion: storybookVersion, packageManager, skipErrors: true, }); - const all = await packageManager.getAllDependencies(); - - const associated = Object.keys(all) + const allDependencies = (await packageManager.getAllDependencies()) as Record; + const storybookDependencies = Object.keys(allDependencies) .filter((dep) => dep.includes('storybook')) .filter(isCorePackage); - const detected = analyzed - .filter((m) => m.hasIncompatibleDependencies) - .map((m) => m.packageName); - - const list = await Promise.all( - Array.from(new Set([...associated, ...detected])).map(async (packageName) => { - return { - packageName, - version: await packageManager.latestVersion(packageName).catch(() => null), - }; - }) - ); - - const data = list.reduce( - (acc, k) => { - if (k.version !== null) { - const { packageName, version } = k; - const upgradable = !( - !valid(k.version) || - k.version === coerce(packageJson?.dependencies?.[k.packageName])?.toString() || - k.version === coerce(packageJson?.devDependencies?.[k.packageName])?.toString() || - k.version === coerce(packageJson?.peerDependencies?.[k.packageName])?.toString() - ); - - if (upgradable) { - acc.upgradable.push({ packageName, version }); - } else { - acc.problematicPackages.push({ packageName, version }); - } - } + const incompatibleDependencies = analyzedPackages + .filter((pkg) => pkg.hasIncompatibleDependencies) + .map((pkg) => pkg.packageName); - return acc; - }, - { upgradable: [], problematicPackages: [] } - ); + const uniquePackages = Array.from( + new Set([...storybookDependencies, ...incompatibleDependencies]) + ).map((packageName) => [packageName, allDependencies[packageName]]) as [string, string][]; - if (data.upgradable.length > 0) { - return data; - } + const packageVersions = await getLatestVersions(packageManager, uniquePackages); + const categorizedPackages = categorizePackages(packageVersions, allDependencies); - return null; + return categorizedPackages.upgradable.length > 0 ? categorizedPackages : null; }, prompt({ upgradable: list }) { return dedent` You're upgrading to the latest version of Storybook. We recommend upgrading the following packages: ${list - .map(({ packageName, version }) => `- ${cyan(packageName)}@${cyan(version)}`) + .map(({ packageName, afterVersion, beforeVersion }) => { + return `- ${cyan(packageName)}: ${cyan(beforeVersion)} => ${cyan(afterVersion)}`; + }) .join('\n')} After upgrading, we will run the dedupe command, which could possibly have effects on dependencies that are not Storybook related. @@ -99,7 +118,12 @@ export const upgradeStorybookRelatedDependencies = { if (dryRun) { console.log(dedent` We would have upgrade the following: - ${upgradable.map(({ packageName, version }) => `${packageName}@${version}`).join('\n')} + ${upgradable + .map( + ({ packageName, afterVersion, beforeVersion }) => + `${packageName}: ${beforeVersion} => ${afterVersion}` + ) + .join('\n')} `); return; } @@ -112,7 +136,7 @@ export const upgradeStorybookRelatedDependencies = { return; } - const { packageName, version } = item; + const { packageName, afterVersion: version } = item; const prefixed = `^${version}`; if (packageJson.dependencies?.[packageName]) { @@ -137,7 +161,9 @@ export const upgradeStorybookRelatedDependencies = { console.log(dedent` We upgraded ${yellow(upgradable.length)} packages: ${upgradable - .map(({ packageName, version }) => `- ${cyan(packageName)}@${cyan(version)}`) + .map(({ packageName, afterVersion, beforeVersion }) => { + return `- ${cyan(packageName)}: ${cyan(beforeVersion)} => ${cyan(afterVersion)}`; + }) .join('\n')} `); } From 9d552b2bcd4037cf9c48e1817b46e43a464ca087 Mon Sep 17 00:00:00 2001 From: Norbert de Langen Date: Fri, 8 Mar 2024 15:14:47 +0100 Subject: [PATCH 112/132] even better --- .../fixes/upgrade-storybook-related-dependencies.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/lib/cli/src/automigrate/fixes/upgrade-storybook-related-dependencies.ts b/code/lib/cli/src/automigrate/fixes/upgrade-storybook-related-dependencies.ts index aefa841f91c2..d325ad0f7887 100644 --- a/code/lib/cli/src/automigrate/fixes/upgrade-storybook-related-dependencies.ts +++ b/code/lib/cli/src/automigrate/fixes/upgrade-storybook-related-dependencies.ts @@ -172,10 +172,10 @@ export const upgradeStorybookRelatedDependencies = { console.log(); console.log(dedent` The following packages could not be upgraded, - likely because there's no update available compatible with the latest version of Storybook: + likely because there's no stable update available which is compatible with the latest version of Storybook: ${problematicPackages.map(({ packageName }) => `- ${cyan(packageName)}`).join('\n')} - We suggest your reach out to the authors of these packages to get them updated. + We suggest you to reach out to the maintainers of these packages to get them updated. But before reporting, please check if there is already an open issue or PR for this. `); } From becdbd935851d45b67eba6659b3d05bc5479becf Mon Sep 17 00:00:00 2001 From: Norbert de Langen Date: Fri, 8 Mar 2024 15:35:40 +0100 Subject: [PATCH 113/132] remove the problematicPackages feature --- .../upgrade-storybook-related-dependencies.ts | 53 +++++-------------- 1 file changed, 14 insertions(+), 39 deletions(-) diff --git a/code/lib/cli/src/automigrate/fixes/upgrade-storybook-related-dependencies.ts b/code/lib/cli/src/automigrate/fixes/upgrade-storybook-related-dependencies.ts index d325ad0f7887..3f6ea69f29bc 100644 --- a/code/lib/cli/src/automigrate/fixes/upgrade-storybook-related-dependencies.ts +++ b/code/lib/cli/src/automigrate/fixes/upgrade-storybook-related-dependencies.ts @@ -14,7 +14,6 @@ type PackageMetadata = { interface Options { upgradable: PackageMetadata[]; - problematicPackages: PackageMetadata[]; } async function getLatestVersions( @@ -31,31 +30,13 @@ async function getLatestVersions( } function isPackageUpgradable( - version: string, + afterVersion: string, packageName: string, allDependencies: Record ) { const installedVersion = coerce(allDependencies[packageName])?.toString(); - return valid(version) && version !== installedVersion; -} - -function categorizePackages( - packageVersions: PackageMetadata[], - allDependencies: Record -) { - return packageVersions.reduce( - (acc, { packageName, afterVersion, beforeVersion }) => { - if (afterVersion === null) return acc; - - const isUpgradable = isPackageUpgradable(afterVersion, packageName, allDependencies); - const category = isUpgradable ? 'upgradable' : 'problematicPackages'; - acc[category].push({ packageName, afterVersion, beforeVersion }); - - return acc; - }, - { upgradable: [], problematicPackages: [] } as Options - ); + return valid(afterVersion) && afterVersion !== installedVersion; } /** @@ -83,7 +64,7 @@ export const upgradeStorybookRelatedDependencies = { const allDependencies = (await packageManager.getAllDependencies()) as Record; const storybookDependencies = Object.keys(allDependencies) .filter((dep) => dep.includes('storybook')) - .filter(isCorePackage); + .filter((dep) => !isCorePackage(dep)); const incompatibleDependencies = analyzedPackages .filter((pkg) => pkg.hasIncompatibleDependencies) .map((pkg) => pkg.packageName); @@ -93,15 +74,21 @@ export const upgradeStorybookRelatedDependencies = { ).map((packageName) => [packageName, allDependencies[packageName]]) as [string, string][]; const packageVersions = await getLatestVersions(packageManager, uniquePackages); - const categorizedPackages = categorizePackages(packageVersions, allDependencies); + const upgradablePackages = packageVersions.filter(({ packageName, afterVersion }) => { + if (afterVersion === null) { + return false; + } - return categorizedPackages.upgradable.length > 0 ? categorizedPackages : null; + return isPackageUpgradable(afterVersion, packageName, allDependencies); + }); + + return upgradablePackages.length > 0 ? upgradablePackages : null; }, - prompt({ upgradable: list }) { + prompt({ upgradable }) { return dedent` You're upgrading to the latest version of Storybook. We recommend upgrading the following packages: - ${list + ${upgradable .map(({ packageName, afterVersion, beforeVersion }) => { return `- ${cyan(packageName)}: ${cyan(beforeVersion)} => ${cyan(afterVersion)}`; }) @@ -114,7 +101,7 @@ export const upgradeStorybookRelatedDependencies = { `; }, - async run({ result: { upgradable, problematicPackages }, packageManager, dryRun }) { + async run({ result: { upgradable }, packageManager, dryRun }) { if (dryRun) { console.log(dedent` We would have upgrade the following: @@ -167,18 +154,6 @@ export const upgradeStorybookRelatedDependencies = { .join('\n')} `); } - - if (problematicPackages.length) { - console.log(); - console.log(dedent` - The following packages could not be upgraded, - likely because there's no stable update available which is compatible with the latest version of Storybook: - ${problematicPackages.map(({ packageName }) => `- ${cyan(packageName)}`).join('\n')} - - We suggest you to reach out to the maintainers of these packages to get them updated. - But before reporting, please check if there is already an open issue or PR for this. - `); - } console.log(); }, } satisfies Fix; From 80a112de3c2a2446ab5253d6b9efbe83822d8fb0 Mon Sep 17 00:00:00 2001 From: Norbert de Langen Date: Fri, 8 Mar 2024 15:37:44 +0100 Subject: [PATCH 114/132] fix --- .../automigrate/fixes/upgrade-storybook-related-dependencies.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/lib/cli/src/automigrate/fixes/upgrade-storybook-related-dependencies.ts b/code/lib/cli/src/automigrate/fixes/upgrade-storybook-related-dependencies.ts index 3f6ea69f29bc..3bc835050972 100644 --- a/code/lib/cli/src/automigrate/fixes/upgrade-storybook-related-dependencies.ts +++ b/code/lib/cli/src/automigrate/fixes/upgrade-storybook-related-dependencies.ts @@ -82,7 +82,7 @@ export const upgradeStorybookRelatedDependencies = { return isPackageUpgradable(afterVersion, packageName, allDependencies); }); - return upgradablePackages.length > 0 ? upgradablePackages : null; + return upgradablePackages.length > 0 ? { upgradable: upgradablePackages } : null; }, prompt({ upgradable }) { From b4e944d608fe02a951482e2258e770c129cacc7e Mon Sep 17 00:00:00 2001 From: Norbert de Langen Date: Fri, 8 Mar 2024 15:43:43 +0100 Subject: [PATCH 115/132] ship it --- .../upgrade-storybook-related-dependencies.ts | 21 ++++++++++++------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/code/lib/cli/src/automigrate/fixes/upgrade-storybook-related-dependencies.ts b/code/lib/cli/src/automigrate/fixes/upgrade-storybook-related-dependencies.ts index 3bc835050972..c780d5eff59e 100644 --- a/code/lib/cli/src/automigrate/fixes/upgrade-storybook-related-dependencies.ts +++ b/code/lib/cli/src/automigrate/fixes/upgrade-storybook-related-dependencies.ts @@ -8,7 +8,7 @@ import { isCorePackage } from '@storybook/core-common'; type PackageMetadata = { packageName: string; - beforeVersion: string; + beforeVersion: string | null; afterVersion: string | null; }; @@ -23,7 +23,7 @@ async function getLatestVersions( return Promise.all( packages.map(async ([packageName, beforeVersion]) => ({ packageName, - beforeVersion, + beforeVersion: coerce(beforeVersion)?.toString() || null, afterVersion: await packageManager.latestVersion(packageName).catch(() => null), })) ); @@ -74,13 +74,18 @@ export const upgradeStorybookRelatedDependencies = { ).map((packageName) => [packageName, allDependencies[packageName]]) as [string, string][]; const packageVersions = await getLatestVersions(packageManager, uniquePackages); - const upgradablePackages = packageVersions.filter(({ packageName, afterVersion }) => { - if (afterVersion === null) { - return false; - } + const upgradablePackages = packageVersions.filter( + ({ packageName, afterVersion, beforeVersion }) => { + if (beforeVersion === null) { + return false; + } + if (afterVersion === null) { + return false; + } - return isPackageUpgradable(afterVersion, packageName, allDependencies); - }); + return isPackageUpgradable(afterVersion, packageName, allDependencies); + } + ); return upgradablePackages.length > 0 ? { upgradable: upgradablePackages } : null; }, From 909cb23f3876abc7f642c40f7f365fbee4745458 Mon Sep 17 00:00:00 2001 From: Norbert de Langen Date: Fri, 8 Mar 2024 15:57:34 +0100 Subject: [PATCH 116/132] remove hard-coded login in inner command --- .../upgrade-storybook-related-dependencies.ts | 6 ++++++ code/lib/cli/src/automigrate/index.ts | 16 +--------------- 2 files changed, 7 insertions(+), 15 deletions(-) diff --git a/code/lib/cli/src/automigrate/fixes/upgrade-storybook-related-dependencies.ts b/code/lib/cli/src/automigrate/fixes/upgrade-storybook-related-dependencies.ts index c780d5eff59e..7a57e38c7d8d 100644 --- a/code/lib/cli/src/automigrate/fixes/upgrade-storybook-related-dependencies.ts +++ b/code/lib/cli/src/automigrate/fixes/upgrade-storybook-related-dependencies.ts @@ -55,6 +55,12 @@ export const upgradeStorybookRelatedDependencies = { promptDefaultValue: false, async check({ packageManager, storybookVersion }) { + const latestStorybookVersion = await packageManager.latestVersion('storybook'); + + if (storybookVersion !== latestStorybookVersion) { + return null; + } + const analyzedPackages = await getIncompatibleStorybookPackages({ currentStorybookVersion: storybookVersion, packageManager, diff --git a/code/lib/cli/src/automigrate/index.ts b/code/lib/cli/src/automigrate/index.ts index 20cbf98a4166..8ae73c57102a 100644 --- a/code/lib/cli/src/automigrate/index.ts +++ b/code/lib/cli/src/automigrate/index.ts @@ -29,7 +29,6 @@ import { getMigrationSummary } from './helpers/getMigrationSummary'; import { getStorybookData } from './helpers/mainConfigFile'; import { doctor } from '../doctor'; -import { upgradeStorybookRelatedDependencies } from './fixes/upgrade-storybook-related-dependencies'; import dedent from 'ts-dedent'; const logger = console; @@ -134,20 +133,7 @@ export const automigrate = async ({ return null; } - const selectedFixes: Fix[] = - inputFixes || - allFixes.filter((fix) => { - // we only allow this automigration when the user explicitly asks for it, or they are upgrading to the latest version of storybook - if ( - fix.id === upgradeStorybookRelatedDependencies.id && - isUpgrade !== 'latest' && - fixId !== upgradeStorybookRelatedDependencies.id - ) { - return false; - } - - return true; - }); + const selectedFixes: Fix[] = inputFixes || allFixes; const fixes: Fix[] = fixId ? selectedFixes.filter((f) => f.id === fixId) : selectedFixes; if (fixId && fixes.length === 0) { From b1978746c568716ade7d26dc5bffd95ecee3d3c8 Mon Sep 17 00:00:00 2001 From: Norbert de Langen Date: Fri, 8 Mar 2024 15:58:59 +0100 Subject: [PATCH 117/132] Revert "remove hard-coded login in inner command" This reverts commit 909cb23f3876abc7f642c40f7f365fbee4745458. --- .../upgrade-storybook-related-dependencies.ts | 6 ------ code/lib/cli/src/automigrate/index.ts | 16 +++++++++++++++- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/code/lib/cli/src/automigrate/fixes/upgrade-storybook-related-dependencies.ts b/code/lib/cli/src/automigrate/fixes/upgrade-storybook-related-dependencies.ts index 7a57e38c7d8d..c780d5eff59e 100644 --- a/code/lib/cli/src/automigrate/fixes/upgrade-storybook-related-dependencies.ts +++ b/code/lib/cli/src/automigrate/fixes/upgrade-storybook-related-dependencies.ts @@ -55,12 +55,6 @@ export const upgradeStorybookRelatedDependencies = { promptDefaultValue: false, async check({ packageManager, storybookVersion }) { - const latestStorybookVersion = await packageManager.latestVersion('storybook'); - - if (storybookVersion !== latestStorybookVersion) { - return null; - } - const analyzedPackages = await getIncompatibleStorybookPackages({ currentStorybookVersion: storybookVersion, packageManager, diff --git a/code/lib/cli/src/automigrate/index.ts b/code/lib/cli/src/automigrate/index.ts index 8ae73c57102a..20cbf98a4166 100644 --- a/code/lib/cli/src/automigrate/index.ts +++ b/code/lib/cli/src/automigrate/index.ts @@ -29,6 +29,7 @@ import { getMigrationSummary } from './helpers/getMigrationSummary'; import { getStorybookData } from './helpers/mainConfigFile'; import { doctor } from '../doctor'; +import { upgradeStorybookRelatedDependencies } from './fixes/upgrade-storybook-related-dependencies'; import dedent from 'ts-dedent'; const logger = console; @@ -133,7 +134,20 @@ export const automigrate = async ({ return null; } - const selectedFixes: Fix[] = inputFixes || allFixes; + const selectedFixes: Fix[] = + inputFixes || + allFixes.filter((fix) => { + // we only allow this automigration when the user explicitly asks for it, or they are upgrading to the latest version of storybook + if ( + fix.id === upgradeStorybookRelatedDependencies.id && + isUpgrade !== 'latest' && + fixId !== upgradeStorybookRelatedDependencies.id + ) { + return false; + } + + return true; + }); const fixes: Fix[] = fixId ? selectedFixes.filter((f) => f.id === fixId) : selectedFixes; if (fixId && fixes.length === 0) { From b74ca127bc2eff8ffd9b70b2d61f8327f54c3c40 Mon Sep 17 00:00:00 2001 From: Yann Braga Date: Fri, 8 Mar 2024 16:07:10 +0100 Subject: [PATCH 118/132] add tests --- ...ade-storybook-related-dependencies.test.ts | 95 +++++++++++++++++++ .../upgrade-storybook-related-dependencies.ts | 10 +- 2 files changed, 99 insertions(+), 6 deletions(-) create mode 100644 code/lib/cli/src/automigrate/fixes/upgrade-storybook-related-dependencies.test.ts diff --git a/code/lib/cli/src/automigrate/fixes/upgrade-storybook-related-dependencies.test.ts b/code/lib/cli/src/automigrate/fixes/upgrade-storybook-related-dependencies.test.ts new file mode 100644 index 000000000000..0c16309647bd --- /dev/null +++ b/code/lib/cli/src/automigrate/fixes/upgrade-storybook-related-dependencies.test.ts @@ -0,0 +1,95 @@ +import { describe, afterEach, it, expect, vi } from 'vitest'; +import type { StorybookConfig } from '@storybook/types'; +import type { JsPackageManager } from '@storybook/core-common'; +import * as docsUtils from '../../doctor/getIncompatibleStorybookPackages'; + +import { upgradeStorybookRelatedDependencies } from './upgrade-storybook-related-dependencies'; + +vi.mock('../../doctor/getIncompatibleStorybookPackages'); + +const check = async ({ + packageManager, + main: mainConfig = {}, + storybookVersion = '8.0.0', +}: { + packageManager: Partial; + main?: Partial & Record; + storybookVersion?: string; +}) => { + return upgradeStorybookRelatedDependencies.check({ + packageManager: packageManager as any, + configDir: '', + mainConfig: mainConfig as any, + storybookVersion, + }); +}; + +describe('upgrade-storybook-related-dependencies fix', () => { + afterEach(() => { + vi.restoreAllMocks(); + }); + + it('should detect storyshots registered in main.js', async () => { + const analyzedPackages = [ + { + packageName: '@chromatic-com/storybook', + packageVersion: '1.2.9', + availableUpgrade: '2.0.0', + hasIncompatibleDependencies: false, + }, + { + packageName: '@storybook/jest', + packageVersion: '0.2.3', + availableUpgrade: '1.0.0', + hasIncompatibleDependencies: false, + }, + { + packageName: '@storybook/preset-create-react-app', + packageVersion: '3.2.0', + availableUpgrade: '8.0.0', + hasIncompatibleDependencies: true, + }, + { + packageName: 'storybook', + packageVersion: '8.0.0', + availableUpgrade: undefined, + hasIncompatibleDependencies: true, + }, + ]; + vi.mocked(docsUtils.getIncompatibleStorybookPackages).mockResolvedValue(analyzedPackages); + await expect( + check({ + packageManager: { + getAllDependencies: async () => ({ + '@chromatic-com/storybook': '1.2.9', + '@storybook/jest': '0.2.3', + '@storybook/preset-create-react-app': '3.2.0', + storybook: '8.0.0', + }), + latestVersion: async (pkgName) => + analyzedPackages.find((pkg) => pkg.packageName === pkgName)?.availableUpgrade || '', + }, + }) + ).resolves.toMatchInlineSnapshot(` + { + "upgradable": [ + { + "afterVersion": "2.0.0", + "beforeVersion": "1.2.9", + "packageName": "@chromatic-com/storybook", + }, + { + "afterVersion": "1.0.0", + "beforeVersion": "0.2.3", + "packageName": "@storybook/jest", + }, + { + "afterVersion": "8.0.0", + "beforeVersion": "3.2.0", + "packageName": "@storybook/preset-create-react-app", + }, + ], + } + `); + }); +}); diff --git a/code/lib/cli/src/automigrate/fixes/upgrade-storybook-related-dependencies.ts b/code/lib/cli/src/automigrate/fixes/upgrade-storybook-related-dependencies.ts index c780d5eff59e..5614b7e35ad0 100644 --- a/code/lib/cli/src/automigrate/fixes/upgrade-storybook-related-dependencies.ts +++ b/code/lib/cli/src/automigrate/fixes/upgrade-storybook-related-dependencies.ts @@ -1,10 +1,10 @@ import { dedent } from 'ts-dedent'; -import type { Fix } from '../types'; import { cyan, yellow } from 'chalk'; -import { getIncompatibleStorybookPackages } from '../../doctor/getIncompatibleStorybookPackages'; import { valid, coerce } from 'semver'; import type { JsPackageManager } from '@storybook/core-common'; import { isCorePackage } from '@storybook/core-common'; +import type { Fix } from '../types'; +import { getIncompatibleStorybookPackages } from '../../doctor/getIncompatibleStorybookPackages'; type PackageMetadata = { packageName: string; @@ -74,12 +74,10 @@ export const upgradeStorybookRelatedDependencies = { ).map((packageName) => [packageName, allDependencies[packageName]]) as [string, string][]; const packageVersions = await getLatestVersions(packageManager, uniquePackages); + const upgradablePackages = packageVersions.filter( ({ packageName, afterVersion, beforeVersion }) => { - if (beforeVersion === null) { - return false; - } - if (afterVersion === null) { + if (beforeVersion === null || afterVersion === null) { return false; } From b5eacba75a89cac1af0082bdcb81a9ae2d6b9d0e Mon Sep 17 00:00:00 2001 From: jonniebigodes Date: Sun, 10 Mar 2024 17:07:34 +0000 Subject: [PATCH 119/132] Docs: Fix table alignment --- docs/addons/addons-api.md | 38 ++++++------- docs/api/csf.md | 10 ++-- docs/configure/features-and-behavior.md | 56 +++++++++---------- docs/essentials/toolbars-and-globals.md | 12 ++-- .../naming-components-and-hierarchy.md | 12 ++-- 5 files changed, 64 insertions(+), 64 deletions(-) diff --git a/docs/addons/addons-api.md b/docs/addons/addons-api.md index 8bdc7d62367e..c2c1afad9edb 100644 --- a/docs/addons/addons-api.md +++ b/docs/addons/addons-api.md @@ -244,32 +244,32 @@ This method allows you to override the default Storybook UI configuration (e.g., The following table details how to use the API values: -| Name | Type | Description | Example Value | -| --------------------- | :-------------: | :-----------------------------------------------------: | :-----------------------------------: | -| **navSize** | Number (pixels) | The size of the sidebar that shows a list of stories | `300` | -| **bottomPanelHeight** | Number (pixels) | The size of the addon panel when in the bottom position | `200` | -| **rightPanelWidth** | Number (pixels) | The size of the addon panel when in the right position | `200` | -| **panelPosition** | String | Where to show the addon panel | `'bottom'` or `'right'` | -| **enableShortcuts** | Boolean | Enable/disable shortcuts | `true` | -| **showToolbar** | Boolean | Show/hide toolbar | `true` | -| **theme** | Object | Storybook Theme, see next section | `undefined` | -| **selectedPanel** | String | Id to select an addon panel | `storybook/actions/panel` | -| **initialActive** | String | Select the default active tab on Mobile | `sidebar` or `canvas` or `addons` | -| **sidebar** | Object | Sidebar options, see below | `{ showRoots: false }` | -| **toolbar** | Object | Modify the tools in the toolbar using the addon id | `{ fullscreen: { hidden: false } } }` | +| Name | Type | Description | Example Value | +| --------------------- | --------------- | ------------------------------------------------------- | ------------------------------------- | +| **navSize** | Number (pixels) | The size of the sidebar that shows a list of stories | `300` | +| **bottomPanelHeight** | Number (pixels) | The size of the addon panel when in the bottom position | `200` | +| **rightPanelWidth** | Number (pixels) | The size of the addon panel when in the right position | `200` | +| **panelPosition** | String | Where to show the addon panel | `'bottom'` or `'right'` | +| **enableShortcuts** | Boolean | Enable/disable shortcuts | `true` | +| **showToolbar** | Boolean | Show/hide toolbar | `true` | +| **theme** | Object | Storybook Theme, see next section | `undefined` | +| **selectedPanel** | String | Id to select an addon panel | `storybook/actions/panel` | +| **initialActive** | String | Select the default active tab on Mobile | `sidebar` or `canvas` or `addons` | +| **sidebar** | Object | Sidebar options, see below | `{ showRoots: false }` | +| **toolbar** | Object | Modify the tools in the toolbar using the addon id | `{ fullscreen: { hidden: false } } }` | The following options are configurable under the `sidebar` namespace: -| Name | Type | Description | Example Value | -| ------------------ | :------: | :-----------------------------------------------------------: | :----------------------------------------------: | -| **showRoots** | Boolean | Display the top-level nodes as a "root" in the sidebar | `false` | -| **collapsedRoots** | Array | Set of root node IDs to visually collapse by default | `['misc', 'other']` | +| Name | Type | Description | Example Value | +| ------------------ | -------- | ------------------------------------------------------------- | ------------------------------------------------ | +| **showRoots** | Boolean | Display the top-level nodes as a "root" in the sidebar | `false` | +| **collapsedRoots** | Array | Set of root node IDs to visually collapse by default | `['misc', 'other']` | | **renderLabel** | Function | Create a custom label for tree nodes; must return a ReactNode | `(item) => {item.name}` | The following options are configurable under the `toolbar` namespace: -| Name | Type | Description | Example Value | -| ------ | :----: | :--------------------------------: | :-----------------: | +| Name | Type | Description | Example Value | +| ------ | ------ | ---------------------------------- | ------------------- | | **id** | String | Toggle visibility for toolbar item | `{ hidden: false }` | --- diff --git a/docs/api/csf.md b/docs/api/csf.md index b91f45fd57a4..636195be3761 100644 --- a/docs/api/csf.md +++ b/docs/api/csf.md @@ -64,11 +64,11 @@ With CSF, every named export in the file represents a story object by default. The exported identifiers will be converted to "start case" using Lodash's [startCase](https://lodash.com/docs/#startCase) function. For example: -| Identifier | Transformation | -| ---------------- | :---------------: | -| name | Name | -| someName | Some Name | -| someNAME | Some NAME | +| Identifier | Transformation | +| ---------------- | ----------------- | +| name | Name | +| someName | Some Name | +| someNAME | Some NAME | | some_custom_NAME | Some Custom NAME | | someName1234 | Some Name 1 2 3 4 | diff --git a/docs/configure/features-and-behavior.md b/docs/configure/features-and-behavior.md index a81aa6a55c74..ebfe081a0645 100644 --- a/docs/configure/features-and-behavior.md +++ b/docs/configure/features-and-behavior.md @@ -16,44 +16,44 @@ To control the layout of Storybookโ€™s UI you can use `addons.setConfig` in your The following table details how to use the API values: -| Name | Type | Description | Example Value | -| --------------------- | :-------------: | :-----------------------------------------------------: | :-------------------------------------: | -| **navSize** | Number (pixels) | The size of the sidebar that shows a list of stories | `300` | -| **bottomPanelHeight** | Number (pixels) | The size of the addon panel when in the bottom position | `200` | -| **rightPanelWidth** | Number (pixels) | The size of the addon panel when in the right position | `200` | -| **panelPosition** | String | Where to show the addon panel | `'bottom'` or `'right'` | -| **enableShortcuts** | Boolean | Enable/disable shortcuts | `true` | -| **showToolbar** | Boolean | Show/hide tool bar | `true` | -| **theme** | Object | Storybook Theme, see next section | `undefined` | -| **selectedPanel** | String | Id to select an addon panel | `'storybook/actions/panel'` | -| **initialActive** | String | Select the default active tab on Mobile | `'sidebar'` or `'canvas'` or `'addons'` | -| **sidebar** | Object | Sidebar options, see below | `{ showRoots: false }` | -| **toolbar** | Object | Modify the tools in the toolbar using the addon id | `{ fullscreen: { hidden: false } } }` | +| Name | Type | Description | Example Value | +| --------------------- | --------------- | ------------------------------------------------------- | --------------------------------------- | +| **navSize** | Number (pixels) | The size of the sidebar that shows a list of stories | `300` | +| **bottomPanelHeight** | Number (pixels) | The size of the addon panel when in the bottom position | `200` | +| **rightPanelWidth** | Number (pixels) | The size of the addon panel when in the right position | `200` | +| **panelPosition** | String | Where to show the addon panel | `'bottom'` or `'right'` | +| **enableShortcuts** | Boolean | Enable/disable shortcuts | `true` | +| **showToolbar** | Boolean | Show/hide tool bar | `true` | +| **theme** | Object | Storybook Theme, see next section | `undefined` | +| **selectedPanel** | String | Id to select an addon panel | `'storybook/actions/panel'` | +| **initialActive** | String | Select the default active tab on Mobile | `'sidebar'` or `'canvas'` or `'addons'` | +| **sidebar** | Object | Sidebar options, see below | `{ showRoots: false }` | +| **toolbar** | Object | Modify the tools in the toolbar using the addon id | `{ fullscreen: { hidden: false } } }` | The following options are configurable under the `sidebar` namespace: -| Name | Type | Description | Example Value | -| ------------------ | :------: | :-----------------------------------------------------------: | :----------------------------------------------: | -| **showRoots** | Boolean | Display the top-level nodes as a "root" in the sidebar | `false` | -| **collapsedRoots** | Array | Set of root node IDs to visually collapse by default | `['misc', 'other']` | +| Name | Type | Description | Example Value | +| ------------------ | -------- | ------------------------------------------------------------- | ------------------------------------------------ | +| **showRoots** | Boolean | Display the top-level nodes as a "root" in the sidebar | `false` | +| **collapsedRoots** | Array | Set of root node IDs to visually collapse by default | `['misc', 'other']` | | **renderLabel** | Function | Create a custom label for tree nodes; must return a ReactNode | `(item) => {item.name}` | The following options are configurable under the `toolbar` namespace: -| Name | Type | Description | Example Value | -| ------ | :----: | :--------------------------------: | :-----------------: | +| Name | Type | Description | Example Value | +| ------ | ------ | ---------------------------------- | ------------------- | | **id** | String | Toggle visibility for toolbar item | `{ hidden: false }` | ## Configuring through URL parameters You can use URL parameters to configure some of the available features: -| Config option | Query param | Supported values | -| ------------------- | :----------: | :----------------------------: | -| **enableShortcuts** | `shortcuts` | `false` | -| --- (fullscreen) | `full` | `true`, `false` | -| --- (show sidebar) | `nav` | `true`, `false` | -| --- (show panel) | `panel` | `false`, `'right'`, `'bottom'` | -| **selectedPanel** | `addonPanel` | Any panel ID | -| **showTabs** | `tabs` | `true` | -| --- | `instrument` | `false`, `true` | +| Config option | Query param | Supported values | +| ------------------- | ------------ | ------------------------------ | +| **enableShortcuts** | `shortcuts` | `false` | +| --- (fullscreen) | `full` | `true`, `false` | +| --- (show sidebar) | `nav` | `true`, `false` | +| --- (show panel) | `panel` | `false`, `'right'`, `'bottom'` | +| **selectedPanel** | `addonPanel` | Any panel ID | +| **showTabs** | `tabs` | `true` | +| --- | `instrument` | `false`, `true` | diff --git a/docs/essentials/toolbars-and-globals.md b/docs/essentials/toolbars-and-globals.md index ad212c5f1c97..9c33e952354b 100644 --- a/docs/essentials/toolbars-and-globals.md +++ b/docs/essentials/toolbars-and-globals.md @@ -144,12 +144,12 @@ By adding the configuration element `right`, the text will be displayed on the r Here's a list of the configuration options available. -| MenuItem | Type | Description | Required | -| --------- | :----: | :-------------------------------------------------------------: | :------: | -| **value** | String | The string value of the menu that gets set in the globals | Yes | -| **title** | String | The main text of the title | Yes | -| **right** | String | A string that gets displayed on the right side of the menu | No | -| **icon** | String | An icon that gets shown in the toolbar if this item is selected | No | +| MenuItem | Type | Description | Required | +| --------- | ------ | --------------------------------------------------------------- | -------- | +| **value** | String | The string value of the menu that gets set in the globals | Yes | +| **title** | String | The main text of the title | Yes | +| **right** | String | A string that gets displayed on the right side of the menu | No | +| **icon** | String | An icon that gets shown in the toolbar if this item is selected | No | ## Consuming globals from within a story diff --git a/docs/writing-stories/naming-components-and-hierarchy.md b/docs/writing-stories/naming-components-and-hierarchy.md index 5757a2eda12a..b29b1135e2d5 100644 --- a/docs/writing-stories/naming-components-and-hierarchy.md +++ b/docs/writing-stories/naming-components-and-hierarchy.md @@ -146,12 +146,12 @@ The `storySort` can also accept a configuration object. -| Field | Type | Description | Required | Default Value | Example | -| ---------------- | :-----: | :------------------------------------------------------: | :------: | :---------------------: | :-----------------------: | -| **method** | String | Tells Storybook in which order the stories are displayed | No | Storybook configuration | `'alphabetical'` | -| **order** | Array | The stories to be shown, ordered by supplied name | No | Empty Array `[]` | `['Intro', 'Components']` | -| **includeNames** | Boolean | Include story name in sort calculation | No | `false` | `true` | -| **locales** | String | The locale required to be displayed | No | System locale | `en-US` | +| Field | Type | Description | Required | Default Value | Example | +| ---------------- | ------- | -------------------------------------------------------- | -------- | ----------------------- | ------------------------- | +| **method** | String | Tells Storybook in which order the stories are displayed | No | Storybook configuration | `'alphabetical'` | +| **order** | Array | The stories to be shown, ordered by supplied name | No | Empty Array `[]` | `['Intro', 'Components']` | +| **includeNames** | Boolean | Include story name in sort calculation | No | `false` | `true` | +| **locales** | String | The locale required to be displayed | No | System locale | `en-US` | To sort your stories alphabetically, set `method` to `'alphabetical'` and optionally set the `locales` string. To sort your stories using a custom list, use the `order` array; stories that don't match an item in the `order` list will appear after the items in the list. From 9c2d525b5483bd71da3ddca15dd265ce8d14e9f3 Mon Sep 17 00:00:00 2001 From: Norbert de Langen Date: Mon, 11 Mar 2024 10:12:08 +0100 Subject: [PATCH 120/132] fix the esbuild compatibility versions ranges --- code/builders/builder-manager/package.json | 2 +- code/lib/core-common/package.json | 2 +- code/package.json | 2 +- code/yarn.lock | 6 +++--- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/code/builders/builder-manager/package.json b/code/builders/builder-manager/package.json index 637cdaf29eb3..7a95fbd78831 100644 --- a/code/builders/builder-manager/package.json +++ b/code/builders/builder-manager/package.json @@ -52,7 +52,7 @@ "@yarnpkg/esbuild-plugin-pnp": "^3.0.0-rc.10", "browser-assert": "^1.2.1", "ejs": "^3.1.8", - "esbuild": "^18.0.0 || ^19.0.0 || ^0.20.0", + "esbuild": "^0.18.0 || ^0.19.0 || ^0.20.0", "esbuild-plugin-alias": "^0.2.1", "express": "^4.17.3", "fs-extra": "^11.1.0", diff --git a/code/lib/core-common/package.json b/code/lib/core-common/package.json index 043fe7f08f3e..807bdceaef05 100644 --- a/code/lib/core-common/package.json +++ b/code/lib/core-common/package.json @@ -52,7 +52,7 @@ "@yarnpkg/libzip": "2.3.0", "chalk": "^4.1.0", "cross-spawn": "^7.0.3", - "esbuild": "^18.0.0 || ^19.0.0 || ^0.20.0", + "esbuild": "^0.18.0 || ^0.19.0 || ^0.20.0", "esbuild-register": "^3.5.0", "execa": "^5.0.0", "file-system-cache": "2.3.0", diff --git a/code/package.json b/code/package.json index 7dbcfb70ed22..bde4c2e67503 100644 --- a/code/package.json +++ b/code/package.json @@ -190,7 +190,7 @@ "concurrently": "^5.3.0", "cross-env": "^7.0.3", "danger": "^11.2.6", - "esbuild": "^18.0.0 || ^19.0.0 || ^0.20.0", + "esbuild": "^0.18.0 || ^0.19.0 || ^0.20.0", "esbuild-loader": "^3.0.0", "esbuild-plugin-alias": "^0.2.1", "eslint": "^8.56.0", diff --git a/code/yarn.lock b/code/yarn.lock index 624818aa64ec..19b2f6697c04 100644 --- a/code/yarn.lock +++ b/code/yarn.lock @@ -5476,7 +5476,7 @@ __metadata: "@yarnpkg/esbuild-plugin-pnp": "npm:^3.0.0-rc.10" browser-assert: "npm:^1.2.1" ejs: "npm:^3.1.8" - esbuild: "npm:^18.0.0 || ^19.0.0 || ^0.20.0" + esbuild: "npm:^0.18.0 || ^0.19.0 || ^0.20.0" esbuild-plugin-alias: "npm:^0.2.1" express: "npm:^4.17.3" fs-extra: "npm:^11.1.0" @@ -5742,7 +5742,7 @@ __metadata: "@yarnpkg/libzip": "npm:2.3.0" chalk: "npm:^4.1.0" cross-spawn: "npm:^7.0.3" - esbuild: "npm:^18.0.0 || ^19.0.0 || ^0.20.0" + esbuild: "npm:^0.18.0 || ^0.19.0 || ^0.20.0" esbuild-register: "npm:^3.5.0" execa: "npm:^5.0.0" file-system-cache: "npm:2.3.0" @@ -6679,7 +6679,7 @@ __metadata: concurrently: "npm:^5.3.0" cross-env: "npm:^7.0.3" danger: "npm:^11.2.6" - esbuild: "npm:^18.0.0 || ^19.0.0 || ^0.20.0" + esbuild: "npm:^0.18.0 || ^0.19.0 || ^0.20.0" esbuild-loader: "npm:^3.0.0" esbuild-plugin-alias: "npm:^0.2.1" eslint: "npm:^8.56.0" From a6e4d90993a1a027edd26536091a5751c34d1e94 Mon Sep 17 00:00:00 2001 From: storybook-bot <32066757+storybook-bot@users.noreply.github.com> Date: Mon, 11 Mar 2024 10:36:05 +0000 Subject: [PATCH 121/132] Write changelog for 8.0.0-rc.4 [skip ci] --- CHANGELOG.prerelease.md | 16 ++++++++++++++++ code/package.json | 3 ++- docs/versions/next.json | 2 +- 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.prerelease.md b/CHANGELOG.prerelease.md index fce4b4696b3a..2b0e49086ea5 100644 --- a/CHANGELOG.prerelease.md +++ b/CHANGELOG.prerelease.md @@ -1,3 +1,19 @@ +## 8.0.0-rc.4 + +- Actions: Fix attaching action after a spy is restored to original function - [#26364](https://github.com/storybookjs/storybook/pull/26364), thanks @kasperpeulen! +- CLI: Add explicit actions to header story - [#26352](https://github.com/storybookjs/storybook/pull/26352), thanks @kasperpeulen! +- CLI: Automigration for upgrading storybook related dependencies - [#26377](https://github.com/storybookjs/storybook/pull/26377), thanks @ndelangen! +- CLI: Fix doctor compatibility check - [#26363](https://github.com/storybookjs/storybook/pull/26363), thanks @yannbf! +- CLI: Fix fn reference in preact templates - [#26384](https://github.com/storybookjs/storybook/pull/26384), thanks @kasperpeulen! +- CLI: Remove duplicated dependency warning - [#26385](https://github.com/storybookjs/storybook/pull/26385), thanks @yannbf! +- CLI: Vite migration link (shorter) - [#26379](https://github.com/storybookjs/storybook/pull/26379), thanks @ndelangen! +- Composition: Fix refs not loading when there's multiple - [#26356](https://github.com/storybookjs/storybook/pull/26356), thanks @ndelangen! +- Dependencies: Broaden `esbuild` version range - [#26405](https://github.com/storybookjs/storybook/pull/26405), thanks @ndelangen! +- Maintenance: Replace `@storybook/testing-library` with `@storybook/test` in monorepo - [#26351](https://github.com/storybookjs/storybook/pull/26351), thanks @ndelangen! +- Maintenance: What's new modal changes - [#26355](https://github.com/storybookjs/storybook/pull/26355), thanks @kasperpeulen! +- Portable Stories: Fix injected root element changing layout - [#26387](https://github.com/storybookjs/storybook/pull/26387), thanks @JReinhold! +- React: Support all React component types in JSX Decorator - [#26382](https://github.com/storybookjs/storybook/pull/26382), thanks @yannbf! + ## 8.0.0-rc.3 - Addon-themes: Fix switcher initialization after first start - [#26353](https://github.com/storybookjs/storybook/pull/26353), thanks @valentinpalkovic! diff --git a/code/package.json b/code/package.json index bde4c2e67503..5adc95d90823 100644 --- a/code/package.json +++ b/code/package.json @@ -294,5 +294,6 @@ "Dependency Upgrades" ] ] - } + }, + "deferredNextVersion": "8.0.0-rc.4" } diff --git a/docs/versions/next.json b/docs/versions/next.json index 4de1279548ea..60521e66f7a9 100644 --- a/docs/versions/next.json +++ b/docs/versions/next.json @@ -1 +1 @@ -{"version":"8.0.0-rc.3","info":{"plain":"- Addon-themes: Fix switcher initialization after first start - [#26353](https://github.com/storybookjs/storybook/pull/26353), thanks @valentinpalkovic!\n- Build: Upgrade `esbuild` (`0.20.1`) - [#26255](https://github.com/storybookjs/storybook/pull/26255), thanks @43081j!\n- Core: Fix path separator issue in check-addon-order - [#26362](https://github.com/storybookjs/storybook/pull/26362), thanks @valentinpalkovic!\n- Dependencies: Remove `qs` from `@storybook/manager-api` & `@storybook/channels` - [#26285](https://github.com/storybookjs/storybook/pull/26285), thanks @43081j!\n- UI: Fix sidebar scrolling to selected story when state changes - [#26337](https://github.com/storybookjs/storybook/pull/26337), thanks @JReinhold!\n- UI: Remove 'left' property from TooltipLinkList and Link components - [#26324](https://github.com/storybookjs/storybook/pull/26324), thanks @valentinpalkovic!\n- Viewport: Fix editing when default viewport is set - [#26360](https://github.com/storybookjs/storybook/pull/26360), thanks @shilman!\n- Vue: Fix reference error when using re-exports with \\\"vue-component-meta\\\" - [#26303](https://github.com/storybookjs/storybook/pull/26303), thanks @larsrickert!"}} +{"version":"8.0.0-rc.4","info":{"plain":"- Actions: Fix attaching action after a spy is restored to original function - [#26364](https://github.com/storybookjs/storybook/pull/26364), thanks @kasperpeulen!\n- CLI: Add explicit actions to header story - [#26352](https://github.com/storybookjs/storybook/pull/26352), thanks @kasperpeulen!\n- CLI: Automigration for upgrading storybook related dependencies - [#26377](https://github.com/storybookjs/storybook/pull/26377), thanks @ndelangen!\n- CLI: Fix doctor compatibility check - [#26363](https://github.com/storybookjs/storybook/pull/26363), thanks @yannbf!\n- CLI: Fix fn reference in preact templates - [#26384](https://github.com/storybookjs/storybook/pull/26384), thanks @kasperpeulen!\n- CLI: Remove duplicated dependency warning - [#26385](https://github.com/storybookjs/storybook/pull/26385), thanks @yannbf!\n- CLI: Vite migration link (shorter) - [#26379](https://github.com/storybookjs/storybook/pull/26379), thanks @ndelangen!\n- Composition: Fix refs not loading when there's multiple - [#26356](https://github.com/storybookjs/storybook/pull/26356), thanks @ndelangen!\n- Dependencies: Broaden `esbuild` version range - [#26405](https://github.com/storybookjs/storybook/pull/26405), thanks @ndelangen!\n- Maintenance: Replace `@storybook/testing-library` with `@storybook/test` in monorepo - [#26351](https://github.com/storybookjs/storybook/pull/26351), thanks @ndelangen!\n- Maintenance: What's new modal changes - [#26355](https://github.com/storybookjs/storybook/pull/26355), thanks @kasperpeulen!\n- Portable Stories: Fix injected root element changing layout - [#26387](https://github.com/storybookjs/storybook/pull/26387), thanks @JReinhold!\n- React: Support all React component types in JSX Decorator - [#26382](https://github.com/storybookjs/storybook/pull/26382), thanks @yannbf!"}} From bfa05701390eea3954e853de4208f18b6862cd68 Mon Sep 17 00:00:00 2001 From: storybook-bot <32066757+storybook-bot@users.noreply.github.com> Date: Mon, 11 Mar 2024 12:07:18 +0000 Subject: [PATCH 122/132] Bump version from "8.0.0-rc.3" to "8.0.0-rc.4" [skip ci] --- code/addons/a11y/package.json | 2 +- code/addons/actions/package.json | 2 +- code/addons/backgrounds/package.json | 2 +- code/addons/controls/package.json | 2 +- code/addons/docs/package.json | 2 +- code/addons/essentials/package.json | 2 +- code/addons/gfm/package.json | 2 +- code/addons/highlight/package.json | 2 +- code/addons/interactions/package.json | 2 +- code/addons/jest/package.json | 2 +- code/addons/links/package.json | 2 +- code/addons/measure/package.json | 2 +- code/addons/onboarding/package.json | 2 +- code/addons/outline/package.json | 2 +- code/addons/storysource/package.json | 2 +- code/addons/themes/package.json | 2 +- code/addons/toolbars/package.json | 2 +- code/addons/viewport/package.json | 2 +- code/builders/builder-manager/package.json | 2 +- code/builders/builder-vite/package.json | 2 +- code/builders/builder-webpack5/package.json | 2 +- code/frameworks/angular/package.json | 2 +- code/frameworks/ember/package.json | 2 +- code/frameworks/html-vite/package.json | 2 +- code/frameworks/html-webpack5/package.json | 2 +- code/frameworks/nextjs/package.json | 2 +- code/frameworks/preact-vite/package.json | 2 +- code/frameworks/preact-webpack5/package.json | 2 +- code/frameworks/react-vite/package.json | 2 +- code/frameworks/react-webpack5/package.json | 2 +- code/frameworks/server-webpack5/package.json | 2 +- code/frameworks/svelte-vite/package.json | 2 +- code/frameworks/svelte-webpack5/package.json | 2 +- code/frameworks/sveltekit/package.json | 2 +- code/frameworks/vue3-vite/package.json | 2 +- code/frameworks/vue3-webpack5/package.json | 2 +- .../web-components-vite/package.json | 2 +- .../web-components-webpack5/package.json | 2 +- code/lib/channels/package.json | 2 +- code/lib/cli-sb/package.json | 2 +- code/lib/cli-storybook/package.json | 2 +- code/lib/cli/package.json | 2 +- code/lib/client-logger/package.json | 2 +- code/lib/codemod/package.json | 2 +- code/lib/core-common/package.json | 2 +- code/lib/core-common/src/versions.ts | 160 +++++++++--------- code/lib/core-events/package.json | 2 +- code/lib/core-server/package.json | 2 +- code/lib/core-webpack/package.json | 2 +- code/lib/csf-plugin/package.json | 2 +- code/lib/csf-tools/package.json | 2 +- code/lib/docs-tools/package.json | 2 +- code/lib/instrumenter/package.json | 2 +- code/lib/manager-api/package.json | 2 +- code/lib/manager-api/src/version.ts | 2 +- code/lib/node-logger/package.json | 2 +- code/lib/preview-api/package.json | 2 +- code/lib/preview/package.json | 2 +- code/lib/react-dom-shim/package.json | 2 +- code/lib/router/package.json | 2 +- code/lib/source-loader/package.json | 2 +- code/lib/telemetry/package.json | 2 +- code/lib/test/package.json | 2 +- code/lib/theming/package.json | 2 +- code/lib/types/package.json | 2 +- code/package.json | 5 +- code/presets/create-react-app/package.json | 2 +- code/presets/html-webpack/package.json | 2 +- code/presets/preact-webpack/package.json | 2 +- code/presets/react-webpack/package.json | 2 +- code/presets/server-webpack/package.json | 2 +- code/presets/svelte-webpack/package.json | 2 +- code/presets/vue3-webpack/package.json | 2 +- code/renderers/html/package.json | 2 +- code/renderers/preact/package.json | 2 +- code/renderers/react/package.json | 2 +- code/renderers/server/package.json | 2 +- code/renderers/svelte/package.json | 2 +- code/renderers/vue3/package.json | 2 +- code/renderers/web-components/package.json | 2 +- code/ui/blocks/package.json | 2 +- code/ui/components/package.json | 2 +- code/ui/manager/package.json | 2 +- 83 files changed, 163 insertions(+), 164 deletions(-) diff --git a/code/addons/a11y/package.json b/code/addons/a11y/package.json index 62524c1e5a07..9d832fb1b42f 100644 --- a/code/addons/a11y/package.json +++ b/code/addons/a11y/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/addon-a11y", - "version": "8.0.0-rc.3", + "version": "8.0.0-rc.4", "description": "Test component compliance with web accessibility standards", "keywords": [ "a11y", diff --git a/code/addons/actions/package.json b/code/addons/actions/package.json index 19af94829530..c4e8f4adf0e1 100644 --- a/code/addons/actions/package.json +++ b/code/addons/actions/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/addon-actions", - "version": "8.0.0-rc.3", + "version": "8.0.0-rc.4", "description": "Get UI feedback when an action is performed on an interactive element", "keywords": [ "storybook", diff --git a/code/addons/backgrounds/package.json b/code/addons/backgrounds/package.json index 92c0fb53d8c3..52abe3b3bad4 100644 --- a/code/addons/backgrounds/package.json +++ b/code/addons/backgrounds/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/addon-backgrounds", - "version": "8.0.0-rc.3", + "version": "8.0.0-rc.4", "description": "Switch backgrounds to view components in different settings", "keywords": [ "addon", diff --git a/code/addons/controls/package.json b/code/addons/controls/package.json index 660b10007fd1..5c4714ecf4a1 100644 --- a/code/addons/controls/package.json +++ b/code/addons/controls/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/addon-controls", - "version": "8.0.0-rc.3", + "version": "8.0.0-rc.4", "description": "Interact with component inputs dynamically in the Storybook UI", "keywords": [ "addon", diff --git a/code/addons/docs/package.json b/code/addons/docs/package.json index a902a49bae81..4e41f42a7200 100644 --- a/code/addons/docs/package.json +++ b/code/addons/docs/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/addon-docs", - "version": "8.0.0-rc.3", + "version": "8.0.0-rc.4", "description": "Document component usage and properties in Markdown", "keywords": [ "addon", diff --git a/code/addons/essentials/package.json b/code/addons/essentials/package.json index 8448dbe7e5b3..161b3271408e 100644 --- a/code/addons/essentials/package.json +++ b/code/addons/essentials/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/addon-essentials", - "version": "8.0.0-rc.3", + "version": "8.0.0-rc.4", "description": "Curated addons to bring out the best of Storybook", "keywords": [ "addon", diff --git a/code/addons/gfm/package.json b/code/addons/gfm/package.json index a8a8cfbc87e9..fcd0fb36c190 100644 --- a/code/addons/gfm/package.json +++ b/code/addons/gfm/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/addon-mdx-gfm", - "version": "8.0.0-rc.3", + "version": "8.0.0-rc.4", "description": "GitHub Flavored Markdown in Storybook", "keywords": [ "addon", diff --git a/code/addons/highlight/package.json b/code/addons/highlight/package.json index 19aa4b82b078..d7d172852e7b 100644 --- a/code/addons/highlight/package.json +++ b/code/addons/highlight/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/addon-highlight", - "version": "8.0.0-rc.3", + "version": "8.0.0-rc.4", "description": "Highlight DOM nodes within your stories", "keywords": [ "storybook-addons", diff --git a/code/addons/interactions/package.json b/code/addons/interactions/package.json index da2ff1d5b004..c1262deb3d10 100644 --- a/code/addons/interactions/package.json +++ b/code/addons/interactions/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/addon-interactions", - "version": "8.0.0-rc.3", + "version": "8.0.0-rc.4", "description": "Automate, test and debug user interactions", "keywords": [ "storybook-addons", diff --git a/code/addons/jest/package.json b/code/addons/jest/package.json index 735dcb6d72d2..9ba05ec5f024 100644 --- a/code/addons/jest/package.json +++ b/code/addons/jest/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/addon-jest", - "version": "8.0.0-rc.3", + "version": "8.0.0-rc.4", "description": "React storybook addon that show component jest report", "keywords": [ "addon", diff --git a/code/addons/links/package.json b/code/addons/links/package.json index 1f09384575a8..1d6e3435af24 100644 --- a/code/addons/links/package.json +++ b/code/addons/links/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/addon-links", - "version": "8.0.0-rc.3", + "version": "8.0.0-rc.4", "description": "Link stories together to build demos and prototypes with your UI components", "keywords": [ "addon", diff --git a/code/addons/measure/package.json b/code/addons/measure/package.json index 67e401c94f00..c3ce95d213cf 100644 --- a/code/addons/measure/package.json +++ b/code/addons/measure/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/addon-measure", - "version": "8.0.0-rc.3", + "version": "8.0.0-rc.4", "description": "Inspect layouts by visualizing the box model", "keywords": [ "storybook-addons", diff --git a/code/addons/onboarding/package.json b/code/addons/onboarding/package.json index 62077801df70..c4159cc2d927 100644 --- a/code/addons/onboarding/package.json +++ b/code/addons/onboarding/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/addon-onboarding", - "version": "8.0.0-rc.3", + "version": "8.0.0-rc.4", "description": "Storybook Addon Onboarding - Introduces a new onboarding experience", "keywords": [ "storybook-addons", diff --git a/code/addons/outline/package.json b/code/addons/outline/package.json index b9f7ec636092..129747a9615c 100644 --- a/code/addons/outline/package.json +++ b/code/addons/outline/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/addon-outline", - "version": "8.0.0-rc.3", + "version": "8.0.0-rc.4", "description": "Outline all elements with CSS to help with layout placement and alignment", "keywords": [ "storybook-addons", diff --git a/code/addons/storysource/package.json b/code/addons/storysource/package.json index c4f444ea8bf1..704a1dd6b215 100644 --- a/code/addons/storysource/package.json +++ b/code/addons/storysource/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/addon-storysource", - "version": "8.0.0-rc.3", + "version": "8.0.0-rc.4", "description": "View a storyโ€™s source code to see how it works and paste into your app", "keywords": [ "addon", diff --git a/code/addons/themes/package.json b/code/addons/themes/package.json index d166a0ac638e..f76abb04b06a 100644 --- a/code/addons/themes/package.json +++ b/code/addons/themes/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/addon-themes", - "version": "8.0.0-rc.3", + "version": "8.0.0-rc.4", "description": "Switch between multiple themes for you components in Storybook", "keywords": [ "css", diff --git a/code/addons/toolbars/package.json b/code/addons/toolbars/package.json index 885e2aab0788..68198a7e380c 100644 --- a/code/addons/toolbars/package.json +++ b/code/addons/toolbars/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/addon-toolbars", - "version": "8.0.0-rc.3", + "version": "8.0.0-rc.4", "description": "Create your own toolbar items that control story rendering", "keywords": [ "addon", diff --git a/code/addons/viewport/package.json b/code/addons/viewport/package.json index 72393389d5e0..957d7b13f347 100644 --- a/code/addons/viewport/package.json +++ b/code/addons/viewport/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/addon-viewport", - "version": "8.0.0-rc.3", + "version": "8.0.0-rc.4", "description": "Build responsive components by adjusting Storybookโ€™s viewport size and orientation", "keywords": [ "addon", diff --git a/code/builders/builder-manager/package.json b/code/builders/builder-manager/package.json index 7a95fbd78831..562a6543b8d4 100644 --- a/code/builders/builder-manager/package.json +++ b/code/builders/builder-manager/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/builder-manager", - "version": "8.0.0-rc.3", + "version": "8.0.0-rc.4", "description": "Storybook manager builder", "keywords": [ "storybook" diff --git a/code/builders/builder-vite/package.json b/code/builders/builder-vite/package.json index e0fa92542ade..b757de543cd2 100644 --- a/code/builders/builder-vite/package.json +++ b/code/builders/builder-vite/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/builder-vite", - "version": "8.0.0-rc.3", + "version": "8.0.0-rc.4", "description": "A plugin to run and build Storybooks with Vite", "homepage": "https://github.com/storybookjs/storybook/tree/next/code/builders/builder-vite/#readme", "bugs": { diff --git a/code/builders/builder-webpack5/package.json b/code/builders/builder-webpack5/package.json index 27484944fc21..c84e6ff91318 100644 --- a/code/builders/builder-webpack5/package.json +++ b/code/builders/builder-webpack5/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/builder-webpack5", - "version": "8.0.0-rc.3", + "version": "8.0.0-rc.4", "description": "Storybook framework-agnostic API", "keywords": [ "storybook" diff --git a/code/frameworks/angular/package.json b/code/frameworks/angular/package.json index 17a361b060f4..e95b942c6b6c 100644 --- a/code/frameworks/angular/package.json +++ b/code/frameworks/angular/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/angular", - "version": "8.0.0-rc.3", + "version": "8.0.0-rc.4", "description": "Storybook for Angular: Develop Angular components in isolation with hot reloading.", "keywords": [ "storybook", diff --git a/code/frameworks/ember/package.json b/code/frameworks/ember/package.json index c0d113085a11..63f20400c17f 100644 --- a/code/frameworks/ember/package.json +++ b/code/frameworks/ember/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/ember", - "version": "8.0.0-rc.3", + "version": "8.0.0-rc.4", "description": "Storybook for Ember: Develop Ember Component in isolation with Hot Reloading.", "homepage": "https://github.com/storybookjs/storybook/tree/next/code/frameworks/ember", "bugs": { diff --git a/code/frameworks/html-vite/package.json b/code/frameworks/html-vite/package.json index 150d8fc23198..8939c9d11a13 100644 --- a/code/frameworks/html-vite/package.json +++ b/code/frameworks/html-vite/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/html-vite", - "version": "8.0.0-rc.3", + "version": "8.0.0-rc.4", "description": "Storybook for HTML and Vite: Develop HTML in isolation with Hot Reloading.", "keywords": [ "storybook" diff --git a/code/frameworks/html-webpack5/package.json b/code/frameworks/html-webpack5/package.json index 9eaf30c24120..fb1088cdbc0a 100644 --- a/code/frameworks/html-webpack5/package.json +++ b/code/frameworks/html-webpack5/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/html-webpack5", - "version": "8.0.0-rc.3", + "version": "8.0.0-rc.4", "description": "Storybook for HTML: View HTML snippets in isolation with Hot Reloading.", "keywords": [ "storybook" diff --git a/code/frameworks/nextjs/package.json b/code/frameworks/nextjs/package.json index 8aa2e629d087..6a51cb37c598 100644 --- a/code/frameworks/nextjs/package.json +++ b/code/frameworks/nextjs/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/nextjs", - "version": "8.0.0-rc.3", + "version": "8.0.0-rc.4", "description": "Storybook for Next.js", "keywords": [ "storybook", diff --git a/code/frameworks/preact-vite/package.json b/code/frameworks/preact-vite/package.json index b24dcb6747f8..eee35abf8fd6 100644 --- a/code/frameworks/preact-vite/package.json +++ b/code/frameworks/preact-vite/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/preact-vite", - "version": "8.0.0-rc.3", + "version": "8.0.0-rc.4", "description": "Storybook for Preact and Vite: Develop Preact components in isolation with Hot Reloading.", "keywords": [ "storybook" diff --git a/code/frameworks/preact-webpack5/package.json b/code/frameworks/preact-webpack5/package.json index 212a29b84f35..89f065ab1b12 100644 --- a/code/frameworks/preact-webpack5/package.json +++ b/code/frameworks/preact-webpack5/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/preact-webpack5", - "version": "8.0.0-rc.3", + "version": "8.0.0-rc.4", "description": "Storybook for Preact: Develop Preact Component in isolation.", "keywords": [ "storybook" diff --git a/code/frameworks/react-vite/package.json b/code/frameworks/react-vite/package.json index f7d426298853..9de5b270884c 100644 --- a/code/frameworks/react-vite/package.json +++ b/code/frameworks/react-vite/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/react-vite", - "version": "8.0.0-rc.3", + "version": "8.0.0-rc.4", "description": "Storybook for React and Vite: Develop React components in isolation with Hot Reloading.", "keywords": [ "storybook" diff --git a/code/frameworks/react-webpack5/package.json b/code/frameworks/react-webpack5/package.json index 71a2c244dde1..d69d0f49a329 100644 --- a/code/frameworks/react-webpack5/package.json +++ b/code/frameworks/react-webpack5/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/react-webpack5", - "version": "8.0.0-rc.3", + "version": "8.0.0-rc.4", "description": "Storybook for React: Develop React Component in isolation with Hot Reloading.", "keywords": [ "storybook" diff --git a/code/frameworks/server-webpack5/package.json b/code/frameworks/server-webpack5/package.json index 466376c00d67..82f203429481 100644 --- a/code/frameworks/server-webpack5/package.json +++ b/code/frameworks/server-webpack5/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/server-webpack5", - "version": "8.0.0-rc.3", + "version": "8.0.0-rc.4", "description": "Storybook for Server: View HTML snippets from a server in isolation with Hot Reloading.", "keywords": [ "storybook" diff --git a/code/frameworks/svelte-vite/package.json b/code/frameworks/svelte-vite/package.json index 44acfb7aed9b..3f1c90667782 100644 --- a/code/frameworks/svelte-vite/package.json +++ b/code/frameworks/svelte-vite/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/svelte-vite", - "version": "8.0.0-rc.3", + "version": "8.0.0-rc.4", "description": "Storybook for Svelte and Vite: Develop Svelte components in isolation with Hot Reloading.", "keywords": [ "storybook" diff --git a/code/frameworks/svelte-webpack5/package.json b/code/frameworks/svelte-webpack5/package.json index 3cc2df33f6e4..4012b7283772 100644 --- a/code/frameworks/svelte-webpack5/package.json +++ b/code/frameworks/svelte-webpack5/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/svelte-webpack5", - "version": "8.0.0-rc.3", + "version": "8.0.0-rc.4", "description": "Storybook for Svelte: Develop Svelte Component in isolation with Hot Reloading.", "keywords": [ "storybook" diff --git a/code/frameworks/sveltekit/package.json b/code/frameworks/sveltekit/package.json index 8321a71cf1b1..f05e664c2737 100644 --- a/code/frameworks/sveltekit/package.json +++ b/code/frameworks/sveltekit/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/sveltekit", - "version": "8.0.0-rc.3", + "version": "8.0.0-rc.4", "description": "Storybook for SvelteKit", "keywords": [ "storybook", diff --git a/code/frameworks/vue3-vite/package.json b/code/frameworks/vue3-vite/package.json index 473b0f6ca101..992cbe6bc8f9 100644 --- a/code/frameworks/vue3-vite/package.json +++ b/code/frameworks/vue3-vite/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/vue3-vite", - "version": "8.0.0-rc.3", + "version": "8.0.0-rc.4", "description": "Storybook for Vue3 and Vite: Develop Vue3 components in isolation with Hot Reloading.", "keywords": [ "storybook" diff --git a/code/frameworks/vue3-webpack5/package.json b/code/frameworks/vue3-webpack5/package.json index 24ce41095e2d..0187566a8403 100644 --- a/code/frameworks/vue3-webpack5/package.json +++ b/code/frameworks/vue3-webpack5/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/vue3-webpack5", - "version": "8.0.0-rc.3", + "version": "8.0.0-rc.4", "description": "Storybook for Vue 3: Develop Vue 3 Components in isolation with Hot Reloading.", "keywords": [ "storybook" diff --git a/code/frameworks/web-components-vite/package.json b/code/frameworks/web-components-vite/package.json index a4bc976dedc5..ae3dda76f624 100644 --- a/code/frameworks/web-components-vite/package.json +++ b/code/frameworks/web-components-vite/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/web-components-vite", - "version": "8.0.0-rc.3", + "version": "8.0.0-rc.4", "description": "Storybook for web-components and Vite: Develop Web Components in isolation with Hot Reloading.", "keywords": [ "storybook" diff --git a/code/frameworks/web-components-webpack5/package.json b/code/frameworks/web-components-webpack5/package.json index bdeb505ac803..d2f16a200664 100644 --- a/code/frameworks/web-components-webpack5/package.json +++ b/code/frameworks/web-components-webpack5/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/web-components-webpack5", - "version": "8.0.0-rc.3", + "version": "8.0.0-rc.4", "description": "Storybook for web-components: View web components snippets in isolation with Hot Reloading.", "keywords": [ "lit", diff --git a/code/lib/channels/package.json b/code/lib/channels/package.json index 3b051a7081af..4dde94702018 100644 --- a/code/lib/channels/package.json +++ b/code/lib/channels/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/channels", - "version": "8.0.0-rc.3", + "version": "8.0.0-rc.4", "description": "", "keywords": [ "storybook" diff --git a/code/lib/cli-sb/package.json b/code/lib/cli-sb/package.json index 637277a30b38..e2f7ecca9c6b 100644 --- a/code/lib/cli-sb/package.json +++ b/code/lib/cli-sb/package.json @@ -1,6 +1,6 @@ { "name": "sb", - "version": "8.0.0-rc.3", + "version": "8.0.0-rc.4", "description": "Storybook CLI", "keywords": [ "storybook" diff --git a/code/lib/cli-storybook/package.json b/code/lib/cli-storybook/package.json index 8181570c7186..81dccf1a3750 100644 --- a/code/lib/cli-storybook/package.json +++ b/code/lib/cli-storybook/package.json @@ -1,6 +1,6 @@ { "name": "storybook", - "version": "8.0.0-rc.3", + "version": "8.0.0-rc.4", "description": "Storybook CLI", "keywords": [ "storybook" diff --git a/code/lib/cli/package.json b/code/lib/cli/package.json index b55e6c46c42d..ee01d8cb4bb6 100644 --- a/code/lib/cli/package.json +++ b/code/lib/cli/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/cli", - "version": "8.0.0-rc.3", + "version": "8.0.0-rc.4", "description": "Storybook's CLI - install, dev, build, upgrade, and more", "keywords": [ "cli", diff --git a/code/lib/client-logger/package.json b/code/lib/client-logger/package.json index 602983c51ed5..938191cceb1b 100644 --- a/code/lib/client-logger/package.json +++ b/code/lib/client-logger/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/client-logger", - "version": "8.0.0-rc.3", + "version": "8.0.0-rc.4", "description": "", "keywords": [ "storybook" diff --git a/code/lib/codemod/package.json b/code/lib/codemod/package.json index 3acf4a8f3f41..4142946bc4a0 100644 --- a/code/lib/codemod/package.json +++ b/code/lib/codemod/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/codemod", - "version": "8.0.0-rc.3", + "version": "8.0.0-rc.4", "description": "A collection of codemod scripts written with JSCodeshift", "keywords": [ "storybook" diff --git a/code/lib/core-common/package.json b/code/lib/core-common/package.json index 807bdceaef05..f64dbdb36892 100644 --- a/code/lib/core-common/package.json +++ b/code/lib/core-common/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/core-common", - "version": "8.0.0-rc.3", + "version": "8.0.0-rc.4", "description": "Storybook framework-agnostic API", "keywords": [ "storybook" diff --git a/code/lib/core-common/src/versions.ts b/code/lib/core-common/src/versions.ts index 56e5adfebd73..1c852592eb5a 100644 --- a/code/lib/core-common/src/versions.ts +++ b/code/lib/core-common/src/versions.ts @@ -1,83 +1,83 @@ // auto generated file, do not edit export default { - '@storybook/addon-a11y': '8.0.0-rc.3', - '@storybook/addon-actions': '8.0.0-rc.3', - '@storybook/addon-backgrounds': '8.0.0-rc.3', - '@storybook/addon-controls': '8.0.0-rc.3', - '@storybook/addon-docs': '8.0.0-rc.3', - '@storybook/addon-essentials': '8.0.0-rc.3', - '@storybook/addon-highlight': '8.0.0-rc.3', - '@storybook/addon-interactions': '8.0.0-rc.3', - '@storybook/addon-jest': '8.0.0-rc.3', - '@storybook/addon-links': '8.0.0-rc.3', - '@storybook/addon-mdx-gfm': '8.0.0-rc.3', - '@storybook/addon-measure': '8.0.0-rc.3', - '@storybook/addon-onboarding': '8.0.0-rc.3', - '@storybook/addon-outline': '8.0.0-rc.3', - '@storybook/addon-storysource': '8.0.0-rc.3', - '@storybook/addon-themes': '8.0.0-rc.3', - '@storybook/addon-toolbars': '8.0.0-rc.3', - '@storybook/addon-viewport': '8.0.0-rc.3', - '@storybook/angular': '8.0.0-rc.3', - '@storybook/blocks': '8.0.0-rc.3', - '@storybook/builder-manager': '8.0.0-rc.3', - '@storybook/builder-vite': '8.0.0-rc.3', - '@storybook/builder-webpack5': '8.0.0-rc.3', - '@storybook/channels': '8.0.0-rc.3', - '@storybook/cli': '8.0.0-rc.3', - '@storybook/client-logger': '8.0.0-rc.3', - '@storybook/codemod': '8.0.0-rc.3', - '@storybook/components': '8.0.0-rc.3', - '@storybook/core-common': '8.0.0-rc.3', - '@storybook/core-events': '8.0.0-rc.3', - '@storybook/core-server': '8.0.0-rc.3', - '@storybook/core-webpack': '8.0.0-rc.3', - '@storybook/csf-plugin': '8.0.0-rc.3', - '@storybook/csf-tools': '8.0.0-rc.3', - '@storybook/docs-tools': '8.0.0-rc.3', - '@storybook/ember': '8.0.0-rc.3', - '@storybook/html': '8.0.0-rc.3', - '@storybook/html-vite': '8.0.0-rc.3', - '@storybook/html-webpack5': '8.0.0-rc.3', - '@storybook/instrumenter': '8.0.0-rc.3', - '@storybook/manager': '8.0.0-rc.3', - '@storybook/manager-api': '8.0.0-rc.3', - '@storybook/nextjs': '8.0.0-rc.3', - '@storybook/node-logger': '8.0.0-rc.3', - '@storybook/preact': '8.0.0-rc.3', - '@storybook/preact-vite': '8.0.0-rc.3', - '@storybook/preact-webpack5': '8.0.0-rc.3', - '@storybook/preset-create-react-app': '8.0.0-rc.3', - '@storybook/preset-html-webpack': '8.0.0-rc.3', - '@storybook/preset-preact-webpack': '8.0.0-rc.3', - '@storybook/preset-react-webpack': '8.0.0-rc.3', - '@storybook/preset-server-webpack': '8.0.0-rc.3', - '@storybook/preset-svelte-webpack': '8.0.0-rc.3', - '@storybook/preset-vue3-webpack': '8.0.0-rc.3', - '@storybook/preview': '8.0.0-rc.3', - '@storybook/preview-api': '8.0.0-rc.3', - '@storybook/react': '8.0.0-rc.3', - '@storybook/react-dom-shim': '8.0.0-rc.3', - '@storybook/react-vite': '8.0.0-rc.3', - '@storybook/react-webpack5': '8.0.0-rc.3', - '@storybook/router': '8.0.0-rc.3', - '@storybook/server': '8.0.0-rc.3', - '@storybook/server-webpack5': '8.0.0-rc.3', - '@storybook/source-loader': '8.0.0-rc.3', - '@storybook/svelte': '8.0.0-rc.3', - '@storybook/svelte-vite': '8.0.0-rc.3', - '@storybook/svelte-webpack5': '8.0.0-rc.3', - '@storybook/sveltekit': '8.0.0-rc.3', - '@storybook/telemetry': '8.0.0-rc.3', - '@storybook/test': '8.0.0-rc.3', - '@storybook/theming': '8.0.0-rc.3', - '@storybook/types': '8.0.0-rc.3', - '@storybook/vue3': '8.0.0-rc.3', - '@storybook/vue3-vite': '8.0.0-rc.3', - '@storybook/vue3-webpack5': '8.0.0-rc.3', - '@storybook/web-components': '8.0.0-rc.3', - '@storybook/web-components-vite': '8.0.0-rc.3', - '@storybook/web-components-webpack5': '8.0.0-rc.3', - sb: '8.0.0-rc.3', - storybook: '8.0.0-rc.3', + '@storybook/addon-a11y': '8.0.0-rc.4', + '@storybook/addon-actions': '8.0.0-rc.4', + '@storybook/addon-backgrounds': '8.0.0-rc.4', + '@storybook/addon-controls': '8.0.0-rc.4', + '@storybook/addon-docs': '8.0.0-rc.4', + '@storybook/addon-essentials': '8.0.0-rc.4', + '@storybook/addon-highlight': '8.0.0-rc.4', + '@storybook/addon-interactions': '8.0.0-rc.4', + '@storybook/addon-jest': '8.0.0-rc.4', + '@storybook/addon-links': '8.0.0-rc.4', + '@storybook/addon-mdx-gfm': '8.0.0-rc.4', + '@storybook/addon-measure': '8.0.0-rc.4', + '@storybook/addon-onboarding': '8.0.0-rc.4', + '@storybook/addon-outline': '8.0.0-rc.4', + '@storybook/addon-storysource': '8.0.0-rc.4', + '@storybook/addon-themes': '8.0.0-rc.4', + '@storybook/addon-toolbars': '8.0.0-rc.4', + '@storybook/addon-viewport': '8.0.0-rc.4', + '@storybook/angular': '8.0.0-rc.4', + '@storybook/blocks': '8.0.0-rc.4', + '@storybook/builder-manager': '8.0.0-rc.4', + '@storybook/builder-vite': '8.0.0-rc.4', + '@storybook/builder-webpack5': '8.0.0-rc.4', + '@storybook/channels': '8.0.0-rc.4', + '@storybook/cli': '8.0.0-rc.4', + '@storybook/client-logger': '8.0.0-rc.4', + '@storybook/codemod': '8.0.0-rc.4', + '@storybook/components': '8.0.0-rc.4', + '@storybook/core-common': '8.0.0-rc.4', + '@storybook/core-events': '8.0.0-rc.4', + '@storybook/core-server': '8.0.0-rc.4', + '@storybook/core-webpack': '8.0.0-rc.4', + '@storybook/csf-plugin': '8.0.0-rc.4', + '@storybook/csf-tools': '8.0.0-rc.4', + '@storybook/docs-tools': '8.0.0-rc.4', + '@storybook/ember': '8.0.0-rc.4', + '@storybook/html': '8.0.0-rc.4', + '@storybook/html-vite': '8.0.0-rc.4', + '@storybook/html-webpack5': '8.0.0-rc.4', + '@storybook/instrumenter': '8.0.0-rc.4', + '@storybook/manager': '8.0.0-rc.4', + '@storybook/manager-api': '8.0.0-rc.4', + '@storybook/nextjs': '8.0.0-rc.4', + '@storybook/node-logger': '8.0.0-rc.4', + '@storybook/preact': '8.0.0-rc.4', + '@storybook/preact-vite': '8.0.0-rc.4', + '@storybook/preact-webpack5': '8.0.0-rc.4', + '@storybook/preset-create-react-app': '8.0.0-rc.4', + '@storybook/preset-html-webpack': '8.0.0-rc.4', + '@storybook/preset-preact-webpack': '8.0.0-rc.4', + '@storybook/preset-react-webpack': '8.0.0-rc.4', + '@storybook/preset-server-webpack': '8.0.0-rc.4', + '@storybook/preset-svelte-webpack': '8.0.0-rc.4', + '@storybook/preset-vue3-webpack': '8.0.0-rc.4', + '@storybook/preview': '8.0.0-rc.4', + '@storybook/preview-api': '8.0.0-rc.4', + '@storybook/react': '8.0.0-rc.4', + '@storybook/react-dom-shim': '8.0.0-rc.4', + '@storybook/react-vite': '8.0.0-rc.4', + '@storybook/react-webpack5': '8.0.0-rc.4', + '@storybook/router': '8.0.0-rc.4', + '@storybook/server': '8.0.0-rc.4', + '@storybook/server-webpack5': '8.0.0-rc.4', + '@storybook/source-loader': '8.0.0-rc.4', + '@storybook/svelte': '8.0.0-rc.4', + '@storybook/svelte-vite': '8.0.0-rc.4', + '@storybook/svelte-webpack5': '8.0.0-rc.4', + '@storybook/sveltekit': '8.0.0-rc.4', + '@storybook/telemetry': '8.0.0-rc.4', + '@storybook/test': '8.0.0-rc.4', + '@storybook/theming': '8.0.0-rc.4', + '@storybook/types': '8.0.0-rc.4', + '@storybook/vue3': '8.0.0-rc.4', + '@storybook/vue3-vite': '8.0.0-rc.4', + '@storybook/vue3-webpack5': '8.0.0-rc.4', + '@storybook/web-components': '8.0.0-rc.4', + '@storybook/web-components-vite': '8.0.0-rc.4', + '@storybook/web-components-webpack5': '8.0.0-rc.4', + sb: '8.0.0-rc.4', + storybook: '8.0.0-rc.4', }; diff --git a/code/lib/core-events/package.json b/code/lib/core-events/package.json index 5cae8b0d103c..3f0747cf92aa 100644 --- a/code/lib/core-events/package.json +++ b/code/lib/core-events/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/core-events", - "version": "8.0.0-rc.3", + "version": "8.0.0-rc.4", "description": "Event names used in storybook core", "keywords": [ "storybook" diff --git a/code/lib/core-server/package.json b/code/lib/core-server/package.json index 5676b03ce288..397682e68f88 100644 --- a/code/lib/core-server/package.json +++ b/code/lib/core-server/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/core-server", - "version": "8.0.0-rc.3", + "version": "8.0.0-rc.4", "description": "Storybook framework-agnostic API", "keywords": [ "storybook" diff --git a/code/lib/core-webpack/package.json b/code/lib/core-webpack/package.json index 1ff1b0e9bed1..5a47cdc289e9 100644 --- a/code/lib/core-webpack/package.json +++ b/code/lib/core-webpack/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/core-webpack", - "version": "8.0.0-rc.3", + "version": "8.0.0-rc.4", "description": "Storybook framework-agnostic API", "keywords": [ "storybook" diff --git a/code/lib/csf-plugin/package.json b/code/lib/csf-plugin/package.json index 407367b12ec6..43b1ab413c13 100644 --- a/code/lib/csf-plugin/package.json +++ b/code/lib/csf-plugin/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/csf-plugin", - "version": "8.0.0-rc.3", + "version": "8.0.0-rc.4", "description": "Enrich CSF files via static analysis", "keywords": [ "storybook" diff --git a/code/lib/csf-tools/package.json b/code/lib/csf-tools/package.json index b15707a80768..b1977ce9e9a7 100644 --- a/code/lib/csf-tools/package.json +++ b/code/lib/csf-tools/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/csf-tools", - "version": "8.0.0-rc.3", + "version": "8.0.0-rc.4", "description": "Parse and manipulate CSF and Storybook config files", "keywords": [ "storybook" diff --git a/code/lib/docs-tools/package.json b/code/lib/docs-tools/package.json index b624faa60690..f7794aee8bd5 100644 --- a/code/lib/docs-tools/package.json +++ b/code/lib/docs-tools/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/docs-tools", - "version": "8.0.0-rc.3", + "version": "8.0.0-rc.4", "description": "Shared utility functions for frameworks to implement docs", "keywords": [ "storybook" diff --git a/code/lib/instrumenter/package.json b/code/lib/instrumenter/package.json index 23fd1a4c97da..c5b8107c33da 100644 --- a/code/lib/instrumenter/package.json +++ b/code/lib/instrumenter/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/instrumenter", - "version": "8.0.0-rc.3", + "version": "8.0.0-rc.4", "description": "", "keywords": [ "storybook" diff --git a/code/lib/manager-api/package.json b/code/lib/manager-api/package.json index 7f0f18ead48f..a198d58b9059 100644 --- a/code/lib/manager-api/package.json +++ b/code/lib/manager-api/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/manager-api", - "version": "8.0.0-rc.3", + "version": "8.0.0-rc.4", "description": "Core Storybook Manager API & Context", "keywords": [ "storybook" diff --git a/code/lib/manager-api/src/version.ts b/code/lib/manager-api/src/version.ts index 22afecdd372a..238a50abbb29 100644 --- a/code/lib/manager-api/src/version.ts +++ b/code/lib/manager-api/src/version.ts @@ -1 +1 @@ -export const version = '8.0.0-rc.3'; +export const version = '8.0.0-rc.4'; diff --git a/code/lib/node-logger/package.json b/code/lib/node-logger/package.json index 0c7ff57a0d26..79d051952eb2 100644 --- a/code/lib/node-logger/package.json +++ b/code/lib/node-logger/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/node-logger", - "version": "8.0.0-rc.3", + "version": "8.0.0-rc.4", "description": "", "keywords": [ "storybook" diff --git a/code/lib/preview-api/package.json b/code/lib/preview-api/package.json index 8a6c2cd1e00b..a7a8a9b06751 100644 --- a/code/lib/preview-api/package.json +++ b/code/lib/preview-api/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/preview-api", - "version": "8.0.0-rc.3", + "version": "8.0.0-rc.4", "description": "", "keywords": [ "storybook" diff --git a/code/lib/preview/package.json b/code/lib/preview/package.json index 22f4977f5cda..bd9c345305c8 100644 --- a/code/lib/preview/package.json +++ b/code/lib/preview/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/preview", - "version": "8.0.0-rc.3", + "version": "8.0.0-rc.4", "description": "", "keywords": [ "storybook" diff --git a/code/lib/react-dom-shim/package.json b/code/lib/react-dom-shim/package.json index 2f4e5054d02c..cf959321d247 100644 --- a/code/lib/react-dom-shim/package.json +++ b/code/lib/react-dom-shim/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/react-dom-shim", - "version": "8.0.0-rc.3", + "version": "8.0.0-rc.4", "description": "", "keywords": [ "storybook" diff --git a/code/lib/router/package.json b/code/lib/router/package.json index a590ca8df996..f89a79205956 100644 --- a/code/lib/router/package.json +++ b/code/lib/router/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/router", - "version": "8.0.0-rc.3", + "version": "8.0.0-rc.4", "description": "Core Storybook Router", "keywords": [ "storybook" diff --git a/code/lib/source-loader/package.json b/code/lib/source-loader/package.json index ca90db1a633f..ae7013a8a97a 100644 --- a/code/lib/source-loader/package.json +++ b/code/lib/source-loader/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/source-loader", - "version": "8.0.0-rc.3", + "version": "8.0.0-rc.4", "description": "Source loader", "keywords": [ "lib", diff --git a/code/lib/telemetry/package.json b/code/lib/telemetry/package.json index ba2ac459326b..7622ae48b100 100644 --- a/code/lib/telemetry/package.json +++ b/code/lib/telemetry/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/telemetry", - "version": "8.0.0-rc.3", + "version": "8.0.0-rc.4", "description": "Telemetry logging for crash reports and usage statistics", "keywords": [ "storybook" diff --git a/code/lib/test/package.json b/code/lib/test/package.json index cd22fb90d648..35f70c3fa448 100644 --- a/code/lib/test/package.json +++ b/code/lib/test/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/test", - "version": "8.0.0-rc.3", + "version": "8.0.0-rc.4", "description": "", "keywords": [ "storybook" diff --git a/code/lib/theming/package.json b/code/lib/theming/package.json index 0d99fade2da8..8e05a12d6b02 100644 --- a/code/lib/theming/package.json +++ b/code/lib/theming/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/theming", - "version": "8.0.0-rc.3", + "version": "8.0.0-rc.4", "description": "Core Storybook Components", "keywords": [ "storybook" diff --git a/code/lib/types/package.json b/code/lib/types/package.json index 02ce06531951..a6dda430d034 100644 --- a/code/lib/types/package.json +++ b/code/lib/types/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/types", - "version": "8.0.0-rc.3", + "version": "8.0.0-rc.4", "description": "Core Storybook TS Types", "keywords": [ "storybook" diff --git a/code/package.json b/code/package.json index 5adc95d90823..42309691e56c 100644 --- a/code/package.json +++ b/code/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/root", - "version": "8.0.0-rc.3", + "version": "8.0.0-rc.4", "private": true, "description": "Storybook root", "homepage": "https://storybook.js.org/", @@ -294,6 +294,5 @@ "Dependency Upgrades" ] ] - }, - "deferredNextVersion": "8.0.0-rc.4" + } } diff --git a/code/presets/create-react-app/package.json b/code/presets/create-react-app/package.json index 4da447b1d7f0..cfa0011c37ab 100644 --- a/code/presets/create-react-app/package.json +++ b/code/presets/create-react-app/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/preset-create-react-app", - "version": "8.0.0-rc.3", + "version": "8.0.0-rc.4", "description": "Storybook for Create React App preset", "keywords": [ "storybook" diff --git a/code/presets/html-webpack/package.json b/code/presets/html-webpack/package.json index 748df6affd50..d9c8eb8d668e 100644 --- a/code/presets/html-webpack/package.json +++ b/code/presets/html-webpack/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/preset-html-webpack", - "version": "8.0.0-rc.3", + "version": "8.0.0-rc.4", "description": "Storybook for HTML: View HTML snippets in isolation with Hot Reloading.", "keywords": [ "storybook" diff --git a/code/presets/preact-webpack/package.json b/code/presets/preact-webpack/package.json index c5c9d587425f..86d416bf0635 100644 --- a/code/presets/preact-webpack/package.json +++ b/code/presets/preact-webpack/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/preset-preact-webpack", - "version": "8.0.0-rc.3", + "version": "8.0.0-rc.4", "description": "Storybook for Preact: Develop Preact Component in isolation.", "keywords": [ "storybook" diff --git a/code/presets/react-webpack/package.json b/code/presets/react-webpack/package.json index df70d13120c1..3deb8a330927 100644 --- a/code/presets/react-webpack/package.json +++ b/code/presets/react-webpack/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/preset-react-webpack", - "version": "8.0.0-rc.3", + "version": "8.0.0-rc.4", "description": "Storybook for React: Develop React Component in isolation with Hot Reloading", "keywords": [ "storybook" diff --git a/code/presets/server-webpack/package.json b/code/presets/server-webpack/package.json index 762d5d7de662..ecf9225400e1 100644 --- a/code/presets/server-webpack/package.json +++ b/code/presets/server-webpack/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/preset-server-webpack", - "version": "8.0.0-rc.3", + "version": "8.0.0-rc.4", "description": "Storybook for Server: View HTML snippets from a server in isolation with Hot Reloading.", "keywords": [ "storybook" diff --git a/code/presets/svelte-webpack/package.json b/code/presets/svelte-webpack/package.json index 0552c6bd3d7c..1841c80019fe 100644 --- a/code/presets/svelte-webpack/package.json +++ b/code/presets/svelte-webpack/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/preset-svelte-webpack", - "version": "8.0.0-rc.3", + "version": "8.0.0-rc.4", "description": "Storybook for Svelte: Develop Svelte Component in isolation with Hot Reloading.", "keywords": [ "storybook" diff --git a/code/presets/vue3-webpack/package.json b/code/presets/vue3-webpack/package.json index 3c2e120a2273..e35b0c2f09c0 100644 --- a/code/presets/vue3-webpack/package.json +++ b/code/presets/vue3-webpack/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/preset-vue3-webpack", - "version": "8.0.0-rc.3", + "version": "8.0.0-rc.4", "description": "Storybook for Vue 3: Develop Vue 3 Components in isolation with Hot Reloading.", "keywords": [ "storybook" diff --git a/code/renderers/html/package.json b/code/renderers/html/package.json index 8154fa296f89..cb811c460fd1 100644 --- a/code/renderers/html/package.json +++ b/code/renderers/html/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/html", - "version": "8.0.0-rc.3", + "version": "8.0.0-rc.4", "description": "Storybook HTML renderer", "keywords": [ "storybook" diff --git a/code/renderers/preact/package.json b/code/renderers/preact/package.json index 528f5e0bc060..7f5f1ae7d0e8 100644 --- a/code/renderers/preact/package.json +++ b/code/renderers/preact/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/preact", - "version": "8.0.0-rc.3", + "version": "8.0.0-rc.4", "description": "Storybook Preact renderer", "keywords": [ "storybook" diff --git a/code/renderers/react/package.json b/code/renderers/react/package.json index 679171d7fc16..81b311d0c9f9 100644 --- a/code/renderers/react/package.json +++ b/code/renderers/react/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/react", - "version": "8.0.0-rc.3", + "version": "8.0.0-rc.4", "description": "Storybook React renderer", "keywords": [ "storybook" diff --git a/code/renderers/server/package.json b/code/renderers/server/package.json index e8c3a047b49a..efb3bd37ef39 100644 --- a/code/renderers/server/package.json +++ b/code/renderers/server/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/server", - "version": "8.0.0-rc.3", + "version": "8.0.0-rc.4", "description": "Storybook Server renderer", "keywords": [ "storybook" diff --git a/code/renderers/svelte/package.json b/code/renderers/svelte/package.json index 33d851d2a76a..aa299991281a 100644 --- a/code/renderers/svelte/package.json +++ b/code/renderers/svelte/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/svelte", - "version": "8.0.0-rc.3", + "version": "8.0.0-rc.4", "description": "Storybook Svelte renderer", "keywords": [ "storybook" diff --git a/code/renderers/vue3/package.json b/code/renderers/vue3/package.json index 087d5cf3dc14..0e6200950b6e 100644 --- a/code/renderers/vue3/package.json +++ b/code/renderers/vue3/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/vue3", - "version": "8.0.0-rc.3", + "version": "8.0.0-rc.4", "description": "Storybook Vue 3 renderer", "keywords": [ "storybook" diff --git a/code/renderers/web-components/package.json b/code/renderers/web-components/package.json index 7955d99c7918..1a8fea295854 100644 --- a/code/renderers/web-components/package.json +++ b/code/renderers/web-components/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/web-components", - "version": "8.0.0-rc.3", + "version": "8.0.0-rc.4", "description": "Storybook web-components renderer", "keywords": [ "lit", diff --git a/code/ui/blocks/package.json b/code/ui/blocks/package.json index de499745fba3..6defdcb29635 100644 --- a/code/ui/blocks/package.json +++ b/code/ui/blocks/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/blocks", - "version": "8.0.0-rc.3", + "version": "8.0.0-rc.4", "description": "Storybook Doc Blocks", "keywords": [ "storybook" diff --git a/code/ui/components/package.json b/code/ui/components/package.json index 6b8e39d61b82..f6ebe8539469 100644 --- a/code/ui/components/package.json +++ b/code/ui/components/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/components", - "version": "8.0.0-rc.3", + "version": "8.0.0-rc.4", "description": "Core Storybook Components", "keywords": [ "storybook" diff --git a/code/ui/manager/package.json b/code/ui/manager/package.json index c22b8c3e6954..257a1906b48c 100644 --- a/code/ui/manager/package.json +++ b/code/ui/manager/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/manager", - "version": "8.0.0-rc.3", + "version": "8.0.0-rc.4", "description": "Core Storybook UI", "keywords": [ "storybook" From d978771b182d2a98035fa650f91fa7b949ab2089 Mon Sep 17 00:00:00 2001 From: Norbert de Langen Date: Mon, 11 Mar 2024 13:57:58 +0100 Subject: [PATCH 123/132] add a flag for detecting is the latest version we got from npm matches the version of the CLI exactly --- code/lib/cli/src/automigrate/index.ts | 4 +++- code/lib/cli/src/automigrate/types.ts | 5 +++-- code/lib/cli/src/migrate.ts | 7 ++++--- code/lib/cli/src/upgrade.ts | 4 +++- 4 files changed, 13 insertions(+), 7 deletions(-) diff --git a/code/lib/cli/src/automigrate/index.ts b/code/lib/cli/src/automigrate/index.ts index 20cbf98a4166..340a90f7ec38 100644 --- a/code/lib/cli/src/automigrate/index.ts +++ b/code/lib/cli/src/automigrate/index.ts @@ -103,6 +103,7 @@ export const doAutomigrate = async (options: AutofixOptionsFromCLI) => { mainConfigPath, configDir, isUpgrade: false, + isLatest: false, }); if (outcome) { @@ -125,6 +126,7 @@ export const automigrate = async ({ skipInstall, hideMigrationSummary = false, isUpgrade, + isLatest, }: AutofixOptions): Promise<{ fixResults: Record; preCheckFailure?: PreCheckFailure; @@ -140,7 +142,7 @@ export const automigrate = async ({ // we only allow this automigration when the user explicitly asks for it, or they are upgrading to the latest version of storybook if ( fix.id === upgradeStorybookRelatedDependencies.id && - isUpgrade !== 'latest' && + isLatest === false && fixId !== upgradeStorybookRelatedDependencies.id ) { return false; diff --git a/code/lib/cli/src/automigrate/types.ts b/code/lib/cli/src/automigrate/types.ts index 8dad3d3d2fa9..43447102162f 100644 --- a/code/lib/cli/src/automigrate/types.ts +++ b/code/lib/cli/src/automigrate/types.ts @@ -1,5 +1,5 @@ -import type { StorybookConfigRaw } from '@storybook/types'; import type { JsPackageManager, PackageManagerName } from '@storybook/core-common'; +import type { StorybookConfigRaw } from '@storybook/types'; export interface CheckOptions { packageManager: JsPackageManager; @@ -75,7 +75,8 @@ export interface AutofixOptions extends Omit Date: Mon, 11 Mar 2024 13:43:55 +0000 Subject: [PATCH 124/132] Write changelog for 8.0.0-rc.5 [skip ci] --- CHANGELOG.prerelease.md | 4 ++++ code/package.json | 3 ++- docs/versions/next.json | 2 +- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.prerelease.md b/CHANGELOG.prerelease.md index 2b0e49086ea5..aec117765b12 100644 --- a/CHANGELOG.prerelease.md +++ b/CHANGELOG.prerelease.md @@ -1,3 +1,7 @@ +## 8.0.0-rc.5 + +- CLI: Automigration fix version detection of upgrading related packages - [#26410](https://github.com/storybookjs/storybook/pull/26410), thanks @ndelangen! + ## 8.0.0-rc.4 - Actions: Fix attaching action after a spy is restored to original function - [#26364](https://github.com/storybookjs/storybook/pull/26364), thanks @kasperpeulen! diff --git a/code/package.json b/code/package.json index 42309691e56c..3d37c1912e4f 100644 --- a/code/package.json +++ b/code/package.json @@ -294,5 +294,6 @@ "Dependency Upgrades" ] ] - } + }, + "deferredNextVersion": "8.0.0-rc.5" } diff --git a/docs/versions/next.json b/docs/versions/next.json index 60521e66f7a9..e522ee4c40f2 100644 --- a/docs/versions/next.json +++ b/docs/versions/next.json @@ -1 +1 @@ -{"version":"8.0.0-rc.4","info":{"plain":"- Actions: Fix attaching action after a spy is restored to original function - [#26364](https://github.com/storybookjs/storybook/pull/26364), thanks @kasperpeulen!\n- CLI: Add explicit actions to header story - [#26352](https://github.com/storybookjs/storybook/pull/26352), thanks @kasperpeulen!\n- CLI: Automigration for upgrading storybook related dependencies - [#26377](https://github.com/storybookjs/storybook/pull/26377), thanks @ndelangen!\n- CLI: Fix doctor compatibility check - [#26363](https://github.com/storybookjs/storybook/pull/26363), thanks @yannbf!\n- CLI: Fix fn reference in preact templates - [#26384](https://github.com/storybookjs/storybook/pull/26384), thanks @kasperpeulen!\n- CLI: Remove duplicated dependency warning - [#26385](https://github.com/storybookjs/storybook/pull/26385), thanks @yannbf!\n- CLI: Vite migration link (shorter) - [#26379](https://github.com/storybookjs/storybook/pull/26379), thanks @ndelangen!\n- Composition: Fix refs not loading when there's multiple - [#26356](https://github.com/storybookjs/storybook/pull/26356), thanks @ndelangen!\n- Dependencies: Broaden `esbuild` version range - [#26405](https://github.com/storybookjs/storybook/pull/26405), thanks @ndelangen!\n- Maintenance: Replace `@storybook/testing-library` with `@storybook/test` in monorepo - [#26351](https://github.com/storybookjs/storybook/pull/26351), thanks @ndelangen!\n- Maintenance: What's new modal changes - [#26355](https://github.com/storybookjs/storybook/pull/26355), thanks @kasperpeulen!\n- Portable Stories: Fix injected root element changing layout - [#26387](https://github.com/storybookjs/storybook/pull/26387), thanks @JReinhold!\n- React: Support all React component types in JSX Decorator - [#26382](https://github.com/storybookjs/storybook/pull/26382), thanks @yannbf!"}} +{"version":"8.0.0-rc.5","info":{"plain":"- CLI: Automigration fix version detection of upgrading related packages - [#26410](https://github.com/storybookjs/storybook/pull/26410), thanks @ndelangen!"}} From 9050c69a50e5eb042a4a43b8007ee7ce5cb39c63 Mon Sep 17 00:00:00 2001 From: storybook-bot <32066757+storybook-bot@users.noreply.github.com> Date: Mon, 11 Mar 2024 13:53:47 +0000 Subject: [PATCH 125/132] Bump version from "8.0.0-rc.4" to "8.0.0-rc.5" [skip ci] --- code/addons/a11y/package.json | 2 +- code/addons/actions/package.json | 2 +- code/addons/backgrounds/package.json | 2 +- code/addons/controls/package.json | 2 +- code/addons/docs/package.json | 2 +- code/addons/essentials/package.json | 2 +- code/addons/gfm/package.json | 2 +- code/addons/highlight/package.json | 2 +- code/addons/interactions/package.json | 2 +- code/addons/jest/package.json | 2 +- code/addons/links/package.json | 2 +- code/addons/measure/package.json | 2 +- code/addons/onboarding/package.json | 2 +- code/addons/outline/package.json | 2 +- code/addons/storysource/package.json | 2 +- code/addons/themes/package.json | 2 +- code/addons/toolbars/package.json | 2 +- code/addons/viewport/package.json | 2 +- code/builders/builder-manager/package.json | 2 +- code/builders/builder-vite/package.json | 2 +- code/builders/builder-webpack5/package.json | 2 +- code/frameworks/angular/package.json | 2 +- code/frameworks/ember/package.json | 2 +- code/frameworks/html-vite/package.json | 2 +- code/frameworks/html-webpack5/package.json | 2 +- code/frameworks/nextjs/package.json | 2 +- code/frameworks/preact-vite/package.json | 2 +- code/frameworks/preact-webpack5/package.json | 2 +- code/frameworks/react-vite/package.json | 2 +- code/frameworks/react-webpack5/package.json | 2 +- code/frameworks/server-webpack5/package.json | 2 +- code/frameworks/svelte-vite/package.json | 2 +- code/frameworks/svelte-webpack5/package.json | 2 +- code/frameworks/sveltekit/package.json | 2 +- code/frameworks/vue3-vite/package.json | 2 +- code/frameworks/vue3-webpack5/package.json | 2 +- .../web-components-vite/package.json | 2 +- .../web-components-webpack5/package.json | 2 +- code/lib/channels/package.json | 2 +- code/lib/cli-sb/package.json | 2 +- code/lib/cli-storybook/package.json | 2 +- code/lib/cli/package.json | 2 +- code/lib/client-logger/package.json | 2 +- code/lib/codemod/package.json | 2 +- code/lib/core-common/package.json | 2 +- code/lib/core-common/src/versions.ts | 160 +++++++++--------- code/lib/core-events/package.json | 2 +- code/lib/core-server/package.json | 2 +- code/lib/core-webpack/package.json | 2 +- code/lib/csf-plugin/package.json | 2 +- code/lib/csf-tools/package.json | 2 +- code/lib/docs-tools/package.json | 2 +- code/lib/instrumenter/package.json | 2 +- code/lib/manager-api/package.json | 2 +- code/lib/manager-api/src/version.ts | 2 +- code/lib/node-logger/package.json | 2 +- code/lib/preview-api/package.json | 2 +- code/lib/preview/package.json | 2 +- code/lib/react-dom-shim/package.json | 2 +- code/lib/router/package.json | 2 +- code/lib/source-loader/package.json | 2 +- code/lib/telemetry/package.json | 2 +- code/lib/test/package.json | 2 +- code/lib/theming/package.json | 2 +- code/lib/types/package.json | 2 +- code/package.json | 5 +- code/presets/create-react-app/package.json | 2 +- code/presets/html-webpack/package.json | 2 +- code/presets/preact-webpack/package.json | 2 +- code/presets/react-webpack/package.json | 2 +- code/presets/server-webpack/package.json | 2 +- code/presets/svelte-webpack/package.json | 2 +- code/presets/vue3-webpack/package.json | 2 +- code/renderers/html/package.json | 2 +- code/renderers/preact/package.json | 2 +- code/renderers/react/package.json | 2 +- code/renderers/server/package.json | 2 +- code/renderers/svelte/package.json | 2 +- code/renderers/vue3/package.json | 2 +- code/renderers/web-components/package.json | 2 +- code/ui/blocks/package.json | 2 +- code/ui/components/package.json | 2 +- code/ui/manager/package.json | 2 +- 83 files changed, 163 insertions(+), 164 deletions(-) diff --git a/code/addons/a11y/package.json b/code/addons/a11y/package.json index 9d832fb1b42f..613dbdc000fb 100644 --- a/code/addons/a11y/package.json +++ b/code/addons/a11y/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/addon-a11y", - "version": "8.0.0-rc.4", + "version": "8.0.0-rc.5", "description": "Test component compliance with web accessibility standards", "keywords": [ "a11y", diff --git a/code/addons/actions/package.json b/code/addons/actions/package.json index c4e8f4adf0e1..4724520ee560 100644 --- a/code/addons/actions/package.json +++ b/code/addons/actions/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/addon-actions", - "version": "8.0.0-rc.4", + "version": "8.0.0-rc.5", "description": "Get UI feedback when an action is performed on an interactive element", "keywords": [ "storybook", diff --git a/code/addons/backgrounds/package.json b/code/addons/backgrounds/package.json index 52abe3b3bad4..40173cebe181 100644 --- a/code/addons/backgrounds/package.json +++ b/code/addons/backgrounds/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/addon-backgrounds", - "version": "8.0.0-rc.4", + "version": "8.0.0-rc.5", "description": "Switch backgrounds to view components in different settings", "keywords": [ "addon", diff --git a/code/addons/controls/package.json b/code/addons/controls/package.json index 5c4714ecf4a1..682efb322c40 100644 --- a/code/addons/controls/package.json +++ b/code/addons/controls/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/addon-controls", - "version": "8.0.0-rc.4", + "version": "8.0.0-rc.5", "description": "Interact with component inputs dynamically in the Storybook UI", "keywords": [ "addon", diff --git a/code/addons/docs/package.json b/code/addons/docs/package.json index 4e41f42a7200..86d2d040a1fa 100644 --- a/code/addons/docs/package.json +++ b/code/addons/docs/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/addon-docs", - "version": "8.0.0-rc.4", + "version": "8.0.0-rc.5", "description": "Document component usage and properties in Markdown", "keywords": [ "addon", diff --git a/code/addons/essentials/package.json b/code/addons/essentials/package.json index 161b3271408e..ea286c7e6daf 100644 --- a/code/addons/essentials/package.json +++ b/code/addons/essentials/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/addon-essentials", - "version": "8.0.0-rc.4", + "version": "8.0.0-rc.5", "description": "Curated addons to bring out the best of Storybook", "keywords": [ "addon", diff --git a/code/addons/gfm/package.json b/code/addons/gfm/package.json index fcd0fb36c190..8626bce63870 100644 --- a/code/addons/gfm/package.json +++ b/code/addons/gfm/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/addon-mdx-gfm", - "version": "8.0.0-rc.4", + "version": "8.0.0-rc.5", "description": "GitHub Flavored Markdown in Storybook", "keywords": [ "addon", diff --git a/code/addons/highlight/package.json b/code/addons/highlight/package.json index d7d172852e7b..9bcf61952789 100644 --- a/code/addons/highlight/package.json +++ b/code/addons/highlight/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/addon-highlight", - "version": "8.0.0-rc.4", + "version": "8.0.0-rc.5", "description": "Highlight DOM nodes within your stories", "keywords": [ "storybook-addons", diff --git a/code/addons/interactions/package.json b/code/addons/interactions/package.json index c1262deb3d10..c0773463ab1a 100644 --- a/code/addons/interactions/package.json +++ b/code/addons/interactions/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/addon-interactions", - "version": "8.0.0-rc.4", + "version": "8.0.0-rc.5", "description": "Automate, test and debug user interactions", "keywords": [ "storybook-addons", diff --git a/code/addons/jest/package.json b/code/addons/jest/package.json index 9ba05ec5f024..7f6f3de7b01d 100644 --- a/code/addons/jest/package.json +++ b/code/addons/jest/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/addon-jest", - "version": "8.0.0-rc.4", + "version": "8.0.0-rc.5", "description": "React storybook addon that show component jest report", "keywords": [ "addon", diff --git a/code/addons/links/package.json b/code/addons/links/package.json index 1d6e3435af24..3c218f06f3de 100644 --- a/code/addons/links/package.json +++ b/code/addons/links/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/addon-links", - "version": "8.0.0-rc.4", + "version": "8.0.0-rc.5", "description": "Link stories together to build demos and prototypes with your UI components", "keywords": [ "addon", diff --git a/code/addons/measure/package.json b/code/addons/measure/package.json index c3ce95d213cf..8a6449f6a9e4 100644 --- a/code/addons/measure/package.json +++ b/code/addons/measure/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/addon-measure", - "version": "8.0.0-rc.4", + "version": "8.0.0-rc.5", "description": "Inspect layouts by visualizing the box model", "keywords": [ "storybook-addons", diff --git a/code/addons/onboarding/package.json b/code/addons/onboarding/package.json index c4159cc2d927..df3cad03d039 100644 --- a/code/addons/onboarding/package.json +++ b/code/addons/onboarding/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/addon-onboarding", - "version": "8.0.0-rc.4", + "version": "8.0.0-rc.5", "description": "Storybook Addon Onboarding - Introduces a new onboarding experience", "keywords": [ "storybook-addons", diff --git a/code/addons/outline/package.json b/code/addons/outline/package.json index 129747a9615c..b87b89b4eb3b 100644 --- a/code/addons/outline/package.json +++ b/code/addons/outline/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/addon-outline", - "version": "8.0.0-rc.4", + "version": "8.0.0-rc.5", "description": "Outline all elements with CSS to help with layout placement and alignment", "keywords": [ "storybook-addons", diff --git a/code/addons/storysource/package.json b/code/addons/storysource/package.json index 704a1dd6b215..b9eefe5d2044 100644 --- a/code/addons/storysource/package.json +++ b/code/addons/storysource/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/addon-storysource", - "version": "8.0.0-rc.4", + "version": "8.0.0-rc.5", "description": "View a storyโ€™s source code to see how it works and paste into your app", "keywords": [ "addon", diff --git a/code/addons/themes/package.json b/code/addons/themes/package.json index f76abb04b06a..2e530e1427f3 100644 --- a/code/addons/themes/package.json +++ b/code/addons/themes/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/addon-themes", - "version": "8.0.0-rc.4", + "version": "8.0.0-rc.5", "description": "Switch between multiple themes for you components in Storybook", "keywords": [ "css", diff --git a/code/addons/toolbars/package.json b/code/addons/toolbars/package.json index 68198a7e380c..d5678032c004 100644 --- a/code/addons/toolbars/package.json +++ b/code/addons/toolbars/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/addon-toolbars", - "version": "8.0.0-rc.4", + "version": "8.0.0-rc.5", "description": "Create your own toolbar items that control story rendering", "keywords": [ "addon", diff --git a/code/addons/viewport/package.json b/code/addons/viewport/package.json index 957d7b13f347..e12051424124 100644 --- a/code/addons/viewport/package.json +++ b/code/addons/viewport/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/addon-viewport", - "version": "8.0.0-rc.4", + "version": "8.0.0-rc.5", "description": "Build responsive components by adjusting Storybookโ€™s viewport size and orientation", "keywords": [ "addon", diff --git a/code/builders/builder-manager/package.json b/code/builders/builder-manager/package.json index 562a6543b8d4..818cd8bc9c1f 100644 --- a/code/builders/builder-manager/package.json +++ b/code/builders/builder-manager/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/builder-manager", - "version": "8.0.0-rc.4", + "version": "8.0.0-rc.5", "description": "Storybook manager builder", "keywords": [ "storybook" diff --git a/code/builders/builder-vite/package.json b/code/builders/builder-vite/package.json index b757de543cd2..ecd31fb31953 100644 --- a/code/builders/builder-vite/package.json +++ b/code/builders/builder-vite/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/builder-vite", - "version": "8.0.0-rc.4", + "version": "8.0.0-rc.5", "description": "A plugin to run and build Storybooks with Vite", "homepage": "https://github.com/storybookjs/storybook/tree/next/code/builders/builder-vite/#readme", "bugs": { diff --git a/code/builders/builder-webpack5/package.json b/code/builders/builder-webpack5/package.json index c84e6ff91318..09b3cc203aff 100644 --- a/code/builders/builder-webpack5/package.json +++ b/code/builders/builder-webpack5/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/builder-webpack5", - "version": "8.0.0-rc.4", + "version": "8.0.0-rc.5", "description": "Storybook framework-agnostic API", "keywords": [ "storybook" diff --git a/code/frameworks/angular/package.json b/code/frameworks/angular/package.json index e95b942c6b6c..8b43006f3dc4 100644 --- a/code/frameworks/angular/package.json +++ b/code/frameworks/angular/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/angular", - "version": "8.0.0-rc.4", + "version": "8.0.0-rc.5", "description": "Storybook for Angular: Develop Angular components in isolation with hot reloading.", "keywords": [ "storybook", diff --git a/code/frameworks/ember/package.json b/code/frameworks/ember/package.json index 63f20400c17f..425c1eb5b888 100644 --- a/code/frameworks/ember/package.json +++ b/code/frameworks/ember/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/ember", - "version": "8.0.0-rc.4", + "version": "8.0.0-rc.5", "description": "Storybook for Ember: Develop Ember Component in isolation with Hot Reloading.", "homepage": "https://github.com/storybookjs/storybook/tree/next/code/frameworks/ember", "bugs": { diff --git a/code/frameworks/html-vite/package.json b/code/frameworks/html-vite/package.json index 8939c9d11a13..6cb46be12bd2 100644 --- a/code/frameworks/html-vite/package.json +++ b/code/frameworks/html-vite/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/html-vite", - "version": "8.0.0-rc.4", + "version": "8.0.0-rc.5", "description": "Storybook for HTML and Vite: Develop HTML in isolation with Hot Reloading.", "keywords": [ "storybook" diff --git a/code/frameworks/html-webpack5/package.json b/code/frameworks/html-webpack5/package.json index fb1088cdbc0a..d8181d85aa46 100644 --- a/code/frameworks/html-webpack5/package.json +++ b/code/frameworks/html-webpack5/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/html-webpack5", - "version": "8.0.0-rc.4", + "version": "8.0.0-rc.5", "description": "Storybook for HTML: View HTML snippets in isolation with Hot Reloading.", "keywords": [ "storybook" diff --git a/code/frameworks/nextjs/package.json b/code/frameworks/nextjs/package.json index 6a51cb37c598..4f038bac401d 100644 --- a/code/frameworks/nextjs/package.json +++ b/code/frameworks/nextjs/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/nextjs", - "version": "8.0.0-rc.4", + "version": "8.0.0-rc.5", "description": "Storybook for Next.js", "keywords": [ "storybook", diff --git a/code/frameworks/preact-vite/package.json b/code/frameworks/preact-vite/package.json index eee35abf8fd6..2bb980d16d83 100644 --- a/code/frameworks/preact-vite/package.json +++ b/code/frameworks/preact-vite/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/preact-vite", - "version": "8.0.0-rc.4", + "version": "8.0.0-rc.5", "description": "Storybook for Preact and Vite: Develop Preact components in isolation with Hot Reloading.", "keywords": [ "storybook" diff --git a/code/frameworks/preact-webpack5/package.json b/code/frameworks/preact-webpack5/package.json index 89f065ab1b12..33338d991b79 100644 --- a/code/frameworks/preact-webpack5/package.json +++ b/code/frameworks/preact-webpack5/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/preact-webpack5", - "version": "8.0.0-rc.4", + "version": "8.0.0-rc.5", "description": "Storybook for Preact: Develop Preact Component in isolation.", "keywords": [ "storybook" diff --git a/code/frameworks/react-vite/package.json b/code/frameworks/react-vite/package.json index 9de5b270884c..37b42510626e 100644 --- a/code/frameworks/react-vite/package.json +++ b/code/frameworks/react-vite/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/react-vite", - "version": "8.0.0-rc.4", + "version": "8.0.0-rc.5", "description": "Storybook for React and Vite: Develop React components in isolation with Hot Reloading.", "keywords": [ "storybook" diff --git a/code/frameworks/react-webpack5/package.json b/code/frameworks/react-webpack5/package.json index d69d0f49a329..c43671bb14fb 100644 --- a/code/frameworks/react-webpack5/package.json +++ b/code/frameworks/react-webpack5/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/react-webpack5", - "version": "8.0.0-rc.4", + "version": "8.0.0-rc.5", "description": "Storybook for React: Develop React Component in isolation with Hot Reloading.", "keywords": [ "storybook" diff --git a/code/frameworks/server-webpack5/package.json b/code/frameworks/server-webpack5/package.json index 82f203429481..52cd8d871e45 100644 --- a/code/frameworks/server-webpack5/package.json +++ b/code/frameworks/server-webpack5/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/server-webpack5", - "version": "8.0.0-rc.4", + "version": "8.0.0-rc.5", "description": "Storybook for Server: View HTML snippets from a server in isolation with Hot Reloading.", "keywords": [ "storybook" diff --git a/code/frameworks/svelte-vite/package.json b/code/frameworks/svelte-vite/package.json index 3f1c90667782..1b10dcb99319 100644 --- a/code/frameworks/svelte-vite/package.json +++ b/code/frameworks/svelte-vite/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/svelte-vite", - "version": "8.0.0-rc.4", + "version": "8.0.0-rc.5", "description": "Storybook for Svelte and Vite: Develop Svelte components in isolation with Hot Reloading.", "keywords": [ "storybook" diff --git a/code/frameworks/svelte-webpack5/package.json b/code/frameworks/svelte-webpack5/package.json index 4012b7283772..c63122e40028 100644 --- a/code/frameworks/svelte-webpack5/package.json +++ b/code/frameworks/svelte-webpack5/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/svelte-webpack5", - "version": "8.0.0-rc.4", + "version": "8.0.0-rc.5", "description": "Storybook for Svelte: Develop Svelte Component in isolation with Hot Reloading.", "keywords": [ "storybook" diff --git a/code/frameworks/sveltekit/package.json b/code/frameworks/sveltekit/package.json index f05e664c2737..6cfbe9bf5460 100644 --- a/code/frameworks/sveltekit/package.json +++ b/code/frameworks/sveltekit/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/sveltekit", - "version": "8.0.0-rc.4", + "version": "8.0.0-rc.5", "description": "Storybook for SvelteKit", "keywords": [ "storybook", diff --git a/code/frameworks/vue3-vite/package.json b/code/frameworks/vue3-vite/package.json index 992cbe6bc8f9..a36fc60ad2da 100644 --- a/code/frameworks/vue3-vite/package.json +++ b/code/frameworks/vue3-vite/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/vue3-vite", - "version": "8.0.0-rc.4", + "version": "8.0.0-rc.5", "description": "Storybook for Vue3 and Vite: Develop Vue3 components in isolation with Hot Reloading.", "keywords": [ "storybook" diff --git a/code/frameworks/vue3-webpack5/package.json b/code/frameworks/vue3-webpack5/package.json index 0187566a8403..27cb857d3aac 100644 --- a/code/frameworks/vue3-webpack5/package.json +++ b/code/frameworks/vue3-webpack5/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/vue3-webpack5", - "version": "8.0.0-rc.4", + "version": "8.0.0-rc.5", "description": "Storybook for Vue 3: Develop Vue 3 Components in isolation with Hot Reloading.", "keywords": [ "storybook" diff --git a/code/frameworks/web-components-vite/package.json b/code/frameworks/web-components-vite/package.json index ae3dda76f624..521db343776a 100644 --- a/code/frameworks/web-components-vite/package.json +++ b/code/frameworks/web-components-vite/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/web-components-vite", - "version": "8.0.0-rc.4", + "version": "8.0.0-rc.5", "description": "Storybook for web-components and Vite: Develop Web Components in isolation with Hot Reloading.", "keywords": [ "storybook" diff --git a/code/frameworks/web-components-webpack5/package.json b/code/frameworks/web-components-webpack5/package.json index d2f16a200664..cef8919e5d61 100644 --- a/code/frameworks/web-components-webpack5/package.json +++ b/code/frameworks/web-components-webpack5/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/web-components-webpack5", - "version": "8.0.0-rc.4", + "version": "8.0.0-rc.5", "description": "Storybook for web-components: View web components snippets in isolation with Hot Reloading.", "keywords": [ "lit", diff --git a/code/lib/channels/package.json b/code/lib/channels/package.json index 4dde94702018..7215f9831110 100644 --- a/code/lib/channels/package.json +++ b/code/lib/channels/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/channels", - "version": "8.0.0-rc.4", + "version": "8.0.0-rc.5", "description": "", "keywords": [ "storybook" diff --git a/code/lib/cli-sb/package.json b/code/lib/cli-sb/package.json index e2f7ecca9c6b..64c8731c1701 100644 --- a/code/lib/cli-sb/package.json +++ b/code/lib/cli-sb/package.json @@ -1,6 +1,6 @@ { "name": "sb", - "version": "8.0.0-rc.4", + "version": "8.0.0-rc.5", "description": "Storybook CLI", "keywords": [ "storybook" diff --git a/code/lib/cli-storybook/package.json b/code/lib/cli-storybook/package.json index 81dccf1a3750..eba2ad5c08ce 100644 --- a/code/lib/cli-storybook/package.json +++ b/code/lib/cli-storybook/package.json @@ -1,6 +1,6 @@ { "name": "storybook", - "version": "8.0.0-rc.4", + "version": "8.0.0-rc.5", "description": "Storybook CLI", "keywords": [ "storybook" diff --git a/code/lib/cli/package.json b/code/lib/cli/package.json index ee01d8cb4bb6..6baa876bc0d1 100644 --- a/code/lib/cli/package.json +++ b/code/lib/cli/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/cli", - "version": "8.0.0-rc.4", + "version": "8.0.0-rc.5", "description": "Storybook's CLI - install, dev, build, upgrade, and more", "keywords": [ "cli", diff --git a/code/lib/client-logger/package.json b/code/lib/client-logger/package.json index 938191cceb1b..915205d726f7 100644 --- a/code/lib/client-logger/package.json +++ b/code/lib/client-logger/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/client-logger", - "version": "8.0.0-rc.4", + "version": "8.0.0-rc.5", "description": "", "keywords": [ "storybook" diff --git a/code/lib/codemod/package.json b/code/lib/codemod/package.json index 4142946bc4a0..a973e8585e7c 100644 --- a/code/lib/codemod/package.json +++ b/code/lib/codemod/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/codemod", - "version": "8.0.0-rc.4", + "version": "8.0.0-rc.5", "description": "A collection of codemod scripts written with JSCodeshift", "keywords": [ "storybook" diff --git a/code/lib/core-common/package.json b/code/lib/core-common/package.json index f64dbdb36892..d2beadd15a27 100644 --- a/code/lib/core-common/package.json +++ b/code/lib/core-common/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/core-common", - "version": "8.0.0-rc.4", + "version": "8.0.0-rc.5", "description": "Storybook framework-agnostic API", "keywords": [ "storybook" diff --git a/code/lib/core-common/src/versions.ts b/code/lib/core-common/src/versions.ts index 1c852592eb5a..1f3bf59707c4 100644 --- a/code/lib/core-common/src/versions.ts +++ b/code/lib/core-common/src/versions.ts @@ -1,83 +1,83 @@ // auto generated file, do not edit export default { - '@storybook/addon-a11y': '8.0.0-rc.4', - '@storybook/addon-actions': '8.0.0-rc.4', - '@storybook/addon-backgrounds': '8.0.0-rc.4', - '@storybook/addon-controls': '8.0.0-rc.4', - '@storybook/addon-docs': '8.0.0-rc.4', - '@storybook/addon-essentials': '8.0.0-rc.4', - '@storybook/addon-highlight': '8.0.0-rc.4', - '@storybook/addon-interactions': '8.0.0-rc.4', - '@storybook/addon-jest': '8.0.0-rc.4', - '@storybook/addon-links': '8.0.0-rc.4', - '@storybook/addon-mdx-gfm': '8.0.0-rc.4', - '@storybook/addon-measure': '8.0.0-rc.4', - '@storybook/addon-onboarding': '8.0.0-rc.4', - '@storybook/addon-outline': '8.0.0-rc.4', - '@storybook/addon-storysource': '8.0.0-rc.4', - '@storybook/addon-themes': '8.0.0-rc.4', - '@storybook/addon-toolbars': '8.0.0-rc.4', - '@storybook/addon-viewport': '8.0.0-rc.4', - '@storybook/angular': '8.0.0-rc.4', - '@storybook/blocks': '8.0.0-rc.4', - '@storybook/builder-manager': '8.0.0-rc.4', - '@storybook/builder-vite': '8.0.0-rc.4', - '@storybook/builder-webpack5': '8.0.0-rc.4', - '@storybook/channels': '8.0.0-rc.4', - '@storybook/cli': '8.0.0-rc.4', - '@storybook/client-logger': '8.0.0-rc.4', - '@storybook/codemod': '8.0.0-rc.4', - '@storybook/components': '8.0.0-rc.4', - '@storybook/core-common': '8.0.0-rc.4', - '@storybook/core-events': '8.0.0-rc.4', - '@storybook/core-server': '8.0.0-rc.4', - '@storybook/core-webpack': '8.0.0-rc.4', - '@storybook/csf-plugin': '8.0.0-rc.4', - '@storybook/csf-tools': '8.0.0-rc.4', - '@storybook/docs-tools': '8.0.0-rc.4', - '@storybook/ember': '8.0.0-rc.4', - '@storybook/html': '8.0.0-rc.4', - '@storybook/html-vite': '8.0.0-rc.4', - '@storybook/html-webpack5': '8.0.0-rc.4', - '@storybook/instrumenter': '8.0.0-rc.4', - '@storybook/manager': '8.0.0-rc.4', - '@storybook/manager-api': '8.0.0-rc.4', - '@storybook/nextjs': '8.0.0-rc.4', - '@storybook/node-logger': '8.0.0-rc.4', - '@storybook/preact': '8.0.0-rc.4', - '@storybook/preact-vite': '8.0.0-rc.4', - '@storybook/preact-webpack5': '8.0.0-rc.4', - '@storybook/preset-create-react-app': '8.0.0-rc.4', - '@storybook/preset-html-webpack': '8.0.0-rc.4', - '@storybook/preset-preact-webpack': '8.0.0-rc.4', - '@storybook/preset-react-webpack': '8.0.0-rc.4', - '@storybook/preset-server-webpack': '8.0.0-rc.4', - '@storybook/preset-svelte-webpack': '8.0.0-rc.4', - '@storybook/preset-vue3-webpack': '8.0.0-rc.4', - '@storybook/preview': '8.0.0-rc.4', - '@storybook/preview-api': '8.0.0-rc.4', - '@storybook/react': '8.0.0-rc.4', - '@storybook/react-dom-shim': '8.0.0-rc.4', - '@storybook/react-vite': '8.0.0-rc.4', - '@storybook/react-webpack5': '8.0.0-rc.4', - '@storybook/router': '8.0.0-rc.4', - '@storybook/server': '8.0.0-rc.4', - '@storybook/server-webpack5': '8.0.0-rc.4', - '@storybook/source-loader': '8.0.0-rc.4', - '@storybook/svelte': '8.0.0-rc.4', - '@storybook/svelte-vite': '8.0.0-rc.4', - '@storybook/svelte-webpack5': '8.0.0-rc.4', - '@storybook/sveltekit': '8.0.0-rc.4', - '@storybook/telemetry': '8.0.0-rc.4', - '@storybook/test': '8.0.0-rc.4', - '@storybook/theming': '8.0.0-rc.4', - '@storybook/types': '8.0.0-rc.4', - '@storybook/vue3': '8.0.0-rc.4', - '@storybook/vue3-vite': '8.0.0-rc.4', - '@storybook/vue3-webpack5': '8.0.0-rc.4', - '@storybook/web-components': '8.0.0-rc.4', - '@storybook/web-components-vite': '8.0.0-rc.4', - '@storybook/web-components-webpack5': '8.0.0-rc.4', - sb: '8.0.0-rc.4', - storybook: '8.0.0-rc.4', + '@storybook/addon-a11y': '8.0.0-rc.5', + '@storybook/addon-actions': '8.0.0-rc.5', + '@storybook/addon-backgrounds': '8.0.0-rc.5', + '@storybook/addon-controls': '8.0.0-rc.5', + '@storybook/addon-docs': '8.0.0-rc.5', + '@storybook/addon-essentials': '8.0.0-rc.5', + '@storybook/addon-highlight': '8.0.0-rc.5', + '@storybook/addon-interactions': '8.0.0-rc.5', + '@storybook/addon-jest': '8.0.0-rc.5', + '@storybook/addon-links': '8.0.0-rc.5', + '@storybook/addon-mdx-gfm': '8.0.0-rc.5', + '@storybook/addon-measure': '8.0.0-rc.5', + '@storybook/addon-onboarding': '8.0.0-rc.5', + '@storybook/addon-outline': '8.0.0-rc.5', + '@storybook/addon-storysource': '8.0.0-rc.5', + '@storybook/addon-themes': '8.0.0-rc.5', + '@storybook/addon-toolbars': '8.0.0-rc.5', + '@storybook/addon-viewport': '8.0.0-rc.5', + '@storybook/angular': '8.0.0-rc.5', + '@storybook/blocks': '8.0.0-rc.5', + '@storybook/builder-manager': '8.0.0-rc.5', + '@storybook/builder-vite': '8.0.0-rc.5', + '@storybook/builder-webpack5': '8.0.0-rc.5', + '@storybook/channels': '8.0.0-rc.5', + '@storybook/cli': '8.0.0-rc.5', + '@storybook/client-logger': '8.0.0-rc.5', + '@storybook/codemod': '8.0.0-rc.5', + '@storybook/components': '8.0.0-rc.5', + '@storybook/core-common': '8.0.0-rc.5', + '@storybook/core-events': '8.0.0-rc.5', + '@storybook/core-server': '8.0.0-rc.5', + '@storybook/core-webpack': '8.0.0-rc.5', + '@storybook/csf-plugin': '8.0.0-rc.5', + '@storybook/csf-tools': '8.0.0-rc.5', + '@storybook/docs-tools': '8.0.0-rc.5', + '@storybook/ember': '8.0.0-rc.5', + '@storybook/html': '8.0.0-rc.5', + '@storybook/html-vite': '8.0.0-rc.5', + '@storybook/html-webpack5': '8.0.0-rc.5', + '@storybook/instrumenter': '8.0.0-rc.5', + '@storybook/manager': '8.0.0-rc.5', + '@storybook/manager-api': '8.0.0-rc.5', + '@storybook/nextjs': '8.0.0-rc.5', + '@storybook/node-logger': '8.0.0-rc.5', + '@storybook/preact': '8.0.0-rc.5', + '@storybook/preact-vite': '8.0.0-rc.5', + '@storybook/preact-webpack5': '8.0.0-rc.5', + '@storybook/preset-create-react-app': '8.0.0-rc.5', + '@storybook/preset-html-webpack': '8.0.0-rc.5', + '@storybook/preset-preact-webpack': '8.0.0-rc.5', + '@storybook/preset-react-webpack': '8.0.0-rc.5', + '@storybook/preset-server-webpack': '8.0.0-rc.5', + '@storybook/preset-svelte-webpack': '8.0.0-rc.5', + '@storybook/preset-vue3-webpack': '8.0.0-rc.5', + '@storybook/preview': '8.0.0-rc.5', + '@storybook/preview-api': '8.0.0-rc.5', + '@storybook/react': '8.0.0-rc.5', + '@storybook/react-dom-shim': '8.0.0-rc.5', + '@storybook/react-vite': '8.0.0-rc.5', + '@storybook/react-webpack5': '8.0.0-rc.5', + '@storybook/router': '8.0.0-rc.5', + '@storybook/server': '8.0.0-rc.5', + '@storybook/server-webpack5': '8.0.0-rc.5', + '@storybook/source-loader': '8.0.0-rc.5', + '@storybook/svelte': '8.0.0-rc.5', + '@storybook/svelte-vite': '8.0.0-rc.5', + '@storybook/svelte-webpack5': '8.0.0-rc.5', + '@storybook/sveltekit': '8.0.0-rc.5', + '@storybook/telemetry': '8.0.0-rc.5', + '@storybook/test': '8.0.0-rc.5', + '@storybook/theming': '8.0.0-rc.5', + '@storybook/types': '8.0.0-rc.5', + '@storybook/vue3': '8.0.0-rc.5', + '@storybook/vue3-vite': '8.0.0-rc.5', + '@storybook/vue3-webpack5': '8.0.0-rc.5', + '@storybook/web-components': '8.0.0-rc.5', + '@storybook/web-components-vite': '8.0.0-rc.5', + '@storybook/web-components-webpack5': '8.0.0-rc.5', + sb: '8.0.0-rc.5', + storybook: '8.0.0-rc.5', }; diff --git a/code/lib/core-events/package.json b/code/lib/core-events/package.json index 3f0747cf92aa..0a06fbab9d30 100644 --- a/code/lib/core-events/package.json +++ b/code/lib/core-events/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/core-events", - "version": "8.0.0-rc.4", + "version": "8.0.0-rc.5", "description": "Event names used in storybook core", "keywords": [ "storybook" diff --git a/code/lib/core-server/package.json b/code/lib/core-server/package.json index 397682e68f88..11904f82e863 100644 --- a/code/lib/core-server/package.json +++ b/code/lib/core-server/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/core-server", - "version": "8.0.0-rc.4", + "version": "8.0.0-rc.5", "description": "Storybook framework-agnostic API", "keywords": [ "storybook" diff --git a/code/lib/core-webpack/package.json b/code/lib/core-webpack/package.json index 5a47cdc289e9..e2129ed58c9a 100644 --- a/code/lib/core-webpack/package.json +++ b/code/lib/core-webpack/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/core-webpack", - "version": "8.0.0-rc.4", + "version": "8.0.0-rc.5", "description": "Storybook framework-agnostic API", "keywords": [ "storybook" diff --git a/code/lib/csf-plugin/package.json b/code/lib/csf-plugin/package.json index 43b1ab413c13..f275a090e8d6 100644 --- a/code/lib/csf-plugin/package.json +++ b/code/lib/csf-plugin/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/csf-plugin", - "version": "8.0.0-rc.4", + "version": "8.0.0-rc.5", "description": "Enrich CSF files via static analysis", "keywords": [ "storybook" diff --git a/code/lib/csf-tools/package.json b/code/lib/csf-tools/package.json index b1977ce9e9a7..bb9749cfff93 100644 --- a/code/lib/csf-tools/package.json +++ b/code/lib/csf-tools/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/csf-tools", - "version": "8.0.0-rc.4", + "version": "8.0.0-rc.5", "description": "Parse and manipulate CSF and Storybook config files", "keywords": [ "storybook" diff --git a/code/lib/docs-tools/package.json b/code/lib/docs-tools/package.json index f7794aee8bd5..2863f4b50d55 100644 --- a/code/lib/docs-tools/package.json +++ b/code/lib/docs-tools/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/docs-tools", - "version": "8.0.0-rc.4", + "version": "8.0.0-rc.5", "description": "Shared utility functions for frameworks to implement docs", "keywords": [ "storybook" diff --git a/code/lib/instrumenter/package.json b/code/lib/instrumenter/package.json index c5b8107c33da..a15743e36be3 100644 --- a/code/lib/instrumenter/package.json +++ b/code/lib/instrumenter/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/instrumenter", - "version": "8.0.0-rc.4", + "version": "8.0.0-rc.5", "description": "", "keywords": [ "storybook" diff --git a/code/lib/manager-api/package.json b/code/lib/manager-api/package.json index a198d58b9059..3c5faf93d744 100644 --- a/code/lib/manager-api/package.json +++ b/code/lib/manager-api/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/manager-api", - "version": "8.0.0-rc.4", + "version": "8.0.0-rc.5", "description": "Core Storybook Manager API & Context", "keywords": [ "storybook" diff --git a/code/lib/manager-api/src/version.ts b/code/lib/manager-api/src/version.ts index 238a50abbb29..7a52ddfe9b62 100644 --- a/code/lib/manager-api/src/version.ts +++ b/code/lib/manager-api/src/version.ts @@ -1 +1 @@ -export const version = '8.0.0-rc.4'; +export const version = '8.0.0-rc.5'; diff --git a/code/lib/node-logger/package.json b/code/lib/node-logger/package.json index 79d051952eb2..d8a6f25ba21a 100644 --- a/code/lib/node-logger/package.json +++ b/code/lib/node-logger/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/node-logger", - "version": "8.0.0-rc.4", + "version": "8.0.0-rc.5", "description": "", "keywords": [ "storybook" diff --git a/code/lib/preview-api/package.json b/code/lib/preview-api/package.json index a7a8a9b06751..c040ca46a430 100644 --- a/code/lib/preview-api/package.json +++ b/code/lib/preview-api/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/preview-api", - "version": "8.0.0-rc.4", + "version": "8.0.0-rc.5", "description": "", "keywords": [ "storybook" diff --git a/code/lib/preview/package.json b/code/lib/preview/package.json index bd9c345305c8..ec8800525a3e 100644 --- a/code/lib/preview/package.json +++ b/code/lib/preview/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/preview", - "version": "8.0.0-rc.4", + "version": "8.0.0-rc.5", "description": "", "keywords": [ "storybook" diff --git a/code/lib/react-dom-shim/package.json b/code/lib/react-dom-shim/package.json index cf959321d247..67db8a18ccc8 100644 --- a/code/lib/react-dom-shim/package.json +++ b/code/lib/react-dom-shim/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/react-dom-shim", - "version": "8.0.0-rc.4", + "version": "8.0.0-rc.5", "description": "", "keywords": [ "storybook" diff --git a/code/lib/router/package.json b/code/lib/router/package.json index f89a79205956..52934e8306b4 100644 --- a/code/lib/router/package.json +++ b/code/lib/router/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/router", - "version": "8.0.0-rc.4", + "version": "8.0.0-rc.5", "description": "Core Storybook Router", "keywords": [ "storybook" diff --git a/code/lib/source-loader/package.json b/code/lib/source-loader/package.json index ae7013a8a97a..14e5d3e46527 100644 --- a/code/lib/source-loader/package.json +++ b/code/lib/source-loader/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/source-loader", - "version": "8.0.0-rc.4", + "version": "8.0.0-rc.5", "description": "Source loader", "keywords": [ "lib", diff --git a/code/lib/telemetry/package.json b/code/lib/telemetry/package.json index 7622ae48b100..67713dca4118 100644 --- a/code/lib/telemetry/package.json +++ b/code/lib/telemetry/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/telemetry", - "version": "8.0.0-rc.4", + "version": "8.0.0-rc.5", "description": "Telemetry logging for crash reports and usage statistics", "keywords": [ "storybook" diff --git a/code/lib/test/package.json b/code/lib/test/package.json index 35f70c3fa448..237be906586f 100644 --- a/code/lib/test/package.json +++ b/code/lib/test/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/test", - "version": "8.0.0-rc.4", + "version": "8.0.0-rc.5", "description": "", "keywords": [ "storybook" diff --git a/code/lib/theming/package.json b/code/lib/theming/package.json index 8e05a12d6b02..5d8f48150adf 100644 --- a/code/lib/theming/package.json +++ b/code/lib/theming/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/theming", - "version": "8.0.0-rc.4", + "version": "8.0.0-rc.5", "description": "Core Storybook Components", "keywords": [ "storybook" diff --git a/code/lib/types/package.json b/code/lib/types/package.json index a6dda430d034..aab80d40328c 100644 --- a/code/lib/types/package.json +++ b/code/lib/types/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/types", - "version": "8.0.0-rc.4", + "version": "8.0.0-rc.5", "description": "Core Storybook TS Types", "keywords": [ "storybook" diff --git a/code/package.json b/code/package.json index 3d37c1912e4f..61f01e1274f8 100644 --- a/code/package.json +++ b/code/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/root", - "version": "8.0.0-rc.4", + "version": "8.0.0-rc.5", "private": true, "description": "Storybook root", "homepage": "https://storybook.js.org/", @@ -294,6 +294,5 @@ "Dependency Upgrades" ] ] - }, - "deferredNextVersion": "8.0.0-rc.5" + } } diff --git a/code/presets/create-react-app/package.json b/code/presets/create-react-app/package.json index cfa0011c37ab..55fcc6d076e8 100644 --- a/code/presets/create-react-app/package.json +++ b/code/presets/create-react-app/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/preset-create-react-app", - "version": "8.0.0-rc.4", + "version": "8.0.0-rc.5", "description": "Storybook for Create React App preset", "keywords": [ "storybook" diff --git a/code/presets/html-webpack/package.json b/code/presets/html-webpack/package.json index d9c8eb8d668e..2eb6a823eed7 100644 --- a/code/presets/html-webpack/package.json +++ b/code/presets/html-webpack/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/preset-html-webpack", - "version": "8.0.0-rc.4", + "version": "8.0.0-rc.5", "description": "Storybook for HTML: View HTML snippets in isolation with Hot Reloading.", "keywords": [ "storybook" diff --git a/code/presets/preact-webpack/package.json b/code/presets/preact-webpack/package.json index 86d416bf0635..71606e160146 100644 --- a/code/presets/preact-webpack/package.json +++ b/code/presets/preact-webpack/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/preset-preact-webpack", - "version": "8.0.0-rc.4", + "version": "8.0.0-rc.5", "description": "Storybook for Preact: Develop Preact Component in isolation.", "keywords": [ "storybook" diff --git a/code/presets/react-webpack/package.json b/code/presets/react-webpack/package.json index 3deb8a330927..7db8e8ec09d4 100644 --- a/code/presets/react-webpack/package.json +++ b/code/presets/react-webpack/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/preset-react-webpack", - "version": "8.0.0-rc.4", + "version": "8.0.0-rc.5", "description": "Storybook for React: Develop React Component in isolation with Hot Reloading", "keywords": [ "storybook" diff --git a/code/presets/server-webpack/package.json b/code/presets/server-webpack/package.json index ecf9225400e1..a95582e8c8b9 100644 --- a/code/presets/server-webpack/package.json +++ b/code/presets/server-webpack/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/preset-server-webpack", - "version": "8.0.0-rc.4", + "version": "8.0.0-rc.5", "description": "Storybook for Server: View HTML snippets from a server in isolation with Hot Reloading.", "keywords": [ "storybook" diff --git a/code/presets/svelte-webpack/package.json b/code/presets/svelte-webpack/package.json index 1841c80019fe..c11c76aab89f 100644 --- a/code/presets/svelte-webpack/package.json +++ b/code/presets/svelte-webpack/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/preset-svelte-webpack", - "version": "8.0.0-rc.4", + "version": "8.0.0-rc.5", "description": "Storybook for Svelte: Develop Svelte Component in isolation with Hot Reloading.", "keywords": [ "storybook" diff --git a/code/presets/vue3-webpack/package.json b/code/presets/vue3-webpack/package.json index e35b0c2f09c0..b424bf3ed483 100644 --- a/code/presets/vue3-webpack/package.json +++ b/code/presets/vue3-webpack/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/preset-vue3-webpack", - "version": "8.0.0-rc.4", + "version": "8.0.0-rc.5", "description": "Storybook for Vue 3: Develop Vue 3 Components in isolation with Hot Reloading.", "keywords": [ "storybook" diff --git a/code/renderers/html/package.json b/code/renderers/html/package.json index cb811c460fd1..18b504618783 100644 --- a/code/renderers/html/package.json +++ b/code/renderers/html/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/html", - "version": "8.0.0-rc.4", + "version": "8.0.0-rc.5", "description": "Storybook HTML renderer", "keywords": [ "storybook" diff --git a/code/renderers/preact/package.json b/code/renderers/preact/package.json index 7f5f1ae7d0e8..cd265a5f4285 100644 --- a/code/renderers/preact/package.json +++ b/code/renderers/preact/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/preact", - "version": "8.0.0-rc.4", + "version": "8.0.0-rc.5", "description": "Storybook Preact renderer", "keywords": [ "storybook" diff --git a/code/renderers/react/package.json b/code/renderers/react/package.json index 81b311d0c9f9..065ec55a4f44 100644 --- a/code/renderers/react/package.json +++ b/code/renderers/react/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/react", - "version": "8.0.0-rc.4", + "version": "8.0.0-rc.5", "description": "Storybook React renderer", "keywords": [ "storybook" diff --git a/code/renderers/server/package.json b/code/renderers/server/package.json index efb3bd37ef39..2d2b6b584266 100644 --- a/code/renderers/server/package.json +++ b/code/renderers/server/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/server", - "version": "8.0.0-rc.4", + "version": "8.0.0-rc.5", "description": "Storybook Server renderer", "keywords": [ "storybook" diff --git a/code/renderers/svelte/package.json b/code/renderers/svelte/package.json index aa299991281a..cedaffe33caa 100644 --- a/code/renderers/svelte/package.json +++ b/code/renderers/svelte/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/svelte", - "version": "8.0.0-rc.4", + "version": "8.0.0-rc.5", "description": "Storybook Svelte renderer", "keywords": [ "storybook" diff --git a/code/renderers/vue3/package.json b/code/renderers/vue3/package.json index 0e6200950b6e..09d205d83f9f 100644 --- a/code/renderers/vue3/package.json +++ b/code/renderers/vue3/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/vue3", - "version": "8.0.0-rc.4", + "version": "8.0.0-rc.5", "description": "Storybook Vue 3 renderer", "keywords": [ "storybook" diff --git a/code/renderers/web-components/package.json b/code/renderers/web-components/package.json index 1a8fea295854..6866f00dd368 100644 --- a/code/renderers/web-components/package.json +++ b/code/renderers/web-components/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/web-components", - "version": "8.0.0-rc.4", + "version": "8.0.0-rc.5", "description": "Storybook web-components renderer", "keywords": [ "lit", diff --git a/code/ui/blocks/package.json b/code/ui/blocks/package.json index 6defdcb29635..dae557b18504 100644 --- a/code/ui/blocks/package.json +++ b/code/ui/blocks/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/blocks", - "version": "8.0.0-rc.4", + "version": "8.0.0-rc.5", "description": "Storybook Doc Blocks", "keywords": [ "storybook" diff --git a/code/ui/components/package.json b/code/ui/components/package.json index f6ebe8539469..cef804640bf3 100644 --- a/code/ui/components/package.json +++ b/code/ui/components/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/components", - "version": "8.0.0-rc.4", + "version": "8.0.0-rc.5", "description": "Core Storybook Components", "keywords": [ "storybook" diff --git a/code/ui/manager/package.json b/code/ui/manager/package.json index 257a1906b48c..e0c45acb051c 100644 --- a/code/ui/manager/package.json +++ b/code/ui/manager/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/manager", - "version": "8.0.0-rc.4", + "version": "8.0.0-rc.5", "description": "Core Storybook UI", "keywords": [ "storybook" From 116fd4acd4a86e49d528644e6a375e2984da4007 Mon Sep 17 00:00:00 2001 From: Kyle Gach Date: Thu, 29 Feb 2024 10:32:34 -0700 Subject: [PATCH 126/132] Add react-vite framework doc --- code/frameworks/react-vite/README.md | 4 +- docs/get-started/react-vite.md | 140 ++++++++++++++++++ .../react/react-vite-add-framework.js.mdx | 8 + .../react/react-vite-add-framework.ts.mdx | 12 ++ .../react/react-vite-install.npm.js.mdx | 3 + .../react/react-vite-install.pnpm.js.mdx | 3 + .../react/react-vite-install.yarn.js.mdx | 3 + docs/toc.js | 5 + 8 files changed, 177 insertions(+), 1 deletion(-) create mode 100644 docs/get-started/react-vite.md create mode 100644 docs/snippets/react/react-vite-add-framework.js.mdx create mode 100644 docs/snippets/react/react-vite-add-framework.ts.mdx create mode 100644 docs/snippets/react/react-vite-install.npm.js.mdx create mode 100644 docs/snippets/react/react-vite-install.pnpm.js.mdx create mode 100644 docs/snippets/react/react-vite-install.yarn.js.mdx diff --git a/code/frameworks/react-vite/README.md b/code/frameworks/react-vite/README.md index e8a35450aec9..272f8f50d55f 100644 --- a/code/frameworks/react-vite/README.md +++ b/code/frameworks/react-vite/README.md @@ -1 +1,3 @@ -# Storybook for React +# Storybook for React & Vite + +See [documentation](https://storybook.js.org/docs/8.0/get-started/react-vite?renderer=react) for installation instructions, usage examples, APIs, and more. \ No newline at end of file diff --git a/docs/get-started/react-vite.md b/docs/get-started/react-vite.md new file mode 100644 index 000000000000..edb6db8a9de3 --- /dev/null +++ b/docs/get-started/react-vite.md @@ -0,0 +1,140 @@ +--- +title: Storybook for React & Vite +--- + +export const SUPPORTED_RENDERER = 'react'; + +Storybook for React & Vite is a [framework](../contribute/framework.md) that makes it easy to develop and test UI components in isolation for [React](https://react.dev/) applications built with [Vite](https://vitejs.dev/). It includes: + +- ๐ŸŽ๏ธ Pre-bundled for performance +- ๐Ÿช„ Zero config +- ๐Ÿ’ซ and more! + + + + + +Storybook for React & Vite is only supported in [React](?renderer=react) projects. + + + + + + + + + +## Requirements + +- React โ‰ฅ 16.8 +- Vite โ‰ฅ 3.0 (4+ recommended) +- Storybook โ‰ฅ 7.0 + +## Getting started + +### In a project without Storybook + +Follow the prompts after running this command in your React project's root directory: + + + + + + + +[More on getting started with Storybook.](./install.md) + +### In a project with Storybook + +This framework is designed to work with Storybook 7+. If youโ€™re not already using v7, upgrade with this command: + + + + + + + +#### Automatic migration + +When running the `upgrade` command above, you should get a prompt asking you to migrate to `@storybook/react-vite`, which should handle everything for you. In case that auto-migration does not work for your project, refer to the manual migration below. + +#### Manual migration + +First, install the framework: + + + + + + + +Then, update your `.storybook/main.js|ts` to change the framework property: + + + + + + + +## Run the Setup Wizard + +If all goes well, you should see a setup wizard that will help you get started with Storybook introducing you to the main concepts and features, including how the UI is organized, how to write your first story, and how to test your components' response to various inputs utilizing [controls](../essentials/controls). + +![Storybook onboarding](./example-onboarding-wizard.png) + +If you skipped the wizard, you can always run it again by adding the `?path=/onboarding` query parameter to the URL of your Storybook instance, provided that the example stories are still available. + +## API + +### Options + +You can pass an options object for additional configuration if needed: + +```ts +// .storybook/main.ts +import type { StorybookConfig } from '@storybook/react-vite'; + +const config: StorybookConfig = { + framework: { + name: '@storybook/react-vite', + options: { + // ... + }, + }, +}; + +export default config; +``` + +#### `builder` + +Type: `Record` + +Configure options for the [framework's builder](../api/main-config-framework.md#optionsbuilder). For this framework, available options can be found in the [Vite builder docs](../builders/vite.md). + + + + diff --git a/docs/snippets/react/react-vite-add-framework.js.mdx b/docs/snippets/react/react-vite-add-framework.js.mdx new file mode 100644 index 000000000000..7a268b5768f0 --- /dev/null +++ b/docs/snippets/react/react-vite-add-framework.js.mdx @@ -0,0 +1,8 @@ +```js +// .storybook/main.js +export default { + // ... + // framework: '@storybook/react-webpack5', ๐Ÿ‘ˆ Remove this + framework: '@storybook/react-vite', // ๐Ÿ‘ˆ Add this +}; +``` diff --git a/docs/snippets/react/react-vite-add-framework.ts.mdx b/docs/snippets/react/react-vite-add-framework.ts.mdx new file mode 100644 index 000000000000..c407f12cc0a7 --- /dev/null +++ b/docs/snippets/react/react-vite-add-framework.ts.mdx @@ -0,0 +1,12 @@ +```ts +// .storybook/main.ts +import { StorybookConfig } from '@storybook/react-vite'; + +const config: StorybookConfig = { + // ... + // framework: '@storybook/react-webpack5', ๐Ÿ‘ˆ Remove this + framework: '@storybook/react-vite', // ๐Ÿ‘ˆ Add this +}; + +export default config; +``` diff --git a/docs/snippets/react/react-vite-install.npm.js.mdx b/docs/snippets/react/react-vite-install.npm.js.mdx new file mode 100644 index 000000000000..6a9b052c19bb --- /dev/null +++ b/docs/snippets/react/react-vite-install.npm.js.mdx @@ -0,0 +1,3 @@ +```shell +npm install --save-dev @storybook/react-vite +``` diff --git a/docs/snippets/react/react-vite-install.pnpm.js.mdx b/docs/snippets/react/react-vite-install.pnpm.js.mdx new file mode 100644 index 000000000000..10b128bb0b31 --- /dev/null +++ b/docs/snippets/react/react-vite-install.pnpm.js.mdx @@ -0,0 +1,3 @@ +```shell +pnpm install --save-dev @storybook/react-vite +``` diff --git a/docs/snippets/react/react-vite-install.yarn.js.mdx b/docs/snippets/react/react-vite-install.yarn.js.mdx new file mode 100644 index 000000000000..a566adef61ba --- /dev/null +++ b/docs/snippets/react/react-vite-install.yarn.js.mdx @@ -0,0 +1,3 @@ +```shell +yarn add --dev @storybook/react-vite +``` diff --git a/docs/toc.js b/docs/toc.js index aecde723f11f..7b42d8d677e8 100644 --- a/docs/toc.js +++ b/docs/toc.js @@ -33,6 +33,11 @@ module.exports = { title: 'Next.js', type: 'link', }, + { + pathSegment: 'react-vite', + title: 'React & Vite', + type: 'link', + }, { pathSegment: 'vue3-vite', title: 'Vue & Vite', From 3586fc9b27833b275c7296cf7f38ae48a3ae1e35 Mon Sep 17 00:00:00 2001 From: Kyle Gach Date: Thu, 7 Mar 2024 10:41:56 -0700 Subject: [PATCH 127/132] Address comments --- docs/get-started/react-vite.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/get-started/react-vite.md b/docs/get-started/react-vite.md index edb6db8a9de3..9fbe5eca53af 100644 --- a/docs/get-started/react-vite.md +++ b/docs/get-started/react-vite.md @@ -27,8 +27,8 @@ Storybook for React & Vite is only supported in [React](?renderer=react) project ## Requirements - React โ‰ฅ 16.8 -- Vite โ‰ฅ 3.0 (4+ recommended) -- Storybook โ‰ฅ 7.0 +- Vite โ‰ฅ 4.0 +- Storybook โ‰ฅ 8.0 ## Getting started From d392a9077658200e17151911224081b8eefa628a Mon Sep 17 00:00:00 2001 From: Kyle Gach Date: Tue, 5 Mar 2024 13:11:58 -0700 Subject: [PATCH 128/132] Add `react-webpack5` framework doc --- code/frameworks/react-webpack5/README.md | 48 +----- docs/get-started/react-webpack5.md | 144 ++++++++++++++++++ .../react/react-webpack5-add-framework.js.mdx | 7 + .../react/react-webpack5-add-framework.ts.mdx | 11 ++ .../react/react-webpack5-install.npm.js.mdx | 3 + .../react/react-webpack5-install.pnpm.js.mdx | 3 + .../react/react-webpack5-install.yarn.js.mdx | 3 + docs/toc.js | 5 + 8 files changed, 178 insertions(+), 46 deletions(-) create mode 100644 docs/get-started/react-webpack5.md create mode 100644 docs/snippets/react/react-webpack5-add-framework.js.mdx create mode 100644 docs/snippets/react/react-webpack5-add-framework.ts.mdx create mode 100644 docs/snippets/react/react-webpack5-install.npm.js.mdx create mode 100644 docs/snippets/react/react-webpack5-install.pnpm.js.mdx create mode 100644 docs/snippets/react/react-webpack5-install.yarn.js.mdx diff --git a/code/frameworks/react-webpack5/README.md b/code/frameworks/react-webpack5/README.md index b3b1d877eaa2..53e3de782715 100644 --- a/code/frameworks/react-webpack5/README.md +++ b/code/frameworks/react-webpack5/README.md @@ -1,47 +1,3 @@ -# Storybook for React +# Storybook for React & Webpack -Storybook for React is a UI development environment for your React 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-react-app -npx storybook@latest init -``` - -For more information visit: [storybook.js.org](https://storybook.js.org) - ---- - -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/react/sharing/publish-storybook) of your Storybook and deploy it anywhere you want. - -Here are some featured storybooks that you can reference to see how Storybook works: - -- [Demo of Storybook Design System](https://storybook.js.org/design-system) - [source](https://github.com/storybookjs/design-system) - -## Create React App - -Support for [Create React App](https://create-react-app.dev/) is handled by [`@storybook/preset-create-react-app`](https://github.com/storybookjs/presets/tree/master/packages/preset-create-react-app). - -This preset enables support for all Create React App features, including Sass/SCSS and TypeScript. - -If you're working on an app that was initialized manually (i.e., without the use of Create React App), ensure that your app has [react-dom](https://www.npmjs.com/package/react-dom) included as a dependency. Failing to do so can lead to unforeseen issues with Storybook and your project. - -## Typescript - -`@storybook/react` is now exporting its own types to use with Typescript. -You don't need to have `@types/storybook__react` installed anymore if it was your case. -But you probably also need to use types from `@types/node @types/react`. - -## Docs - -- [Basics](https://storybook.js.org/docs/react/get-started) -- [Configurations](https://storybook.js.org/docs/react/configure) -- [Addons](https://storybook.js.org/docs/react/configure/storybook-addons) +See [documentation](https://storybook.js.org/docs/8.0/get-started/react-webpack5?renderer=react) for installation instructions, usage examples, APIs, and more. \ No newline at end of file diff --git a/docs/get-started/react-webpack5.md b/docs/get-started/react-webpack5.md new file mode 100644 index 000000000000..48f916d45b3f --- /dev/null +++ b/docs/get-started/react-webpack5.md @@ -0,0 +1,144 @@ +--- +title: Storybook for React & Webpack +--- + +export const SUPPORTED_RENDERER = 'react'; + +Storybook for React & Webpack is a [framework](../contribute/framework.md) that makes it easy to develop and test UI components in isolation for [React](https://react.dev/) applications built with [Webpack](https://webpack.js.org/). + + + + + +Storybook for React & Webpack is only supported in [React](?renderer=react) projects. + + + + + + + + + +## Requirements + +- React โ‰ฅ 16.8 +- Webpack โ‰ฅ 5.0 +- Storybook โ‰ฅ 7.0 + +## Getting started + +### In a project without Storybook + +Follow the prompts after running this command in your React project's root directory: + + + + + + + +[More on getting started with Storybook.](./install.md) + +### In a project with Storybook + +This framework is designed to work with Storybook 7+. If youโ€™re not already using v7, upgrade with this command: + + + + + + + +#### Automatic migration + +When running the `upgrade` command above, you should get a prompt asking you to migrate to `@storybook/react-webpack5`, which should handle everything for you. In case that auto-migration does not work for your project, refer to the manual migration below. + +#### Manual migration + +First, install the framework: + + + + + + + +Then, update your `.storybook/main.js|ts` to change the framework property: + + + + + + + +## Run the Setup Wizard + +If all goes well, you should see a setup wizard that will help you get started with Storybook introducing you to the main concepts and features, including how the UI is organized, how to write your first story, and how to test your components' response to various inputs utilizing [controls](../essentials/controls). + +![Storybook onboarding](./example-onboarding-wizard.png) + +If you skipped the wizard, you can always run it again by adding the `?path=/onboarding` query parameter to the URL of your Storybook instance, provided that the example stories are still available. + +## Create React App (CRA) + +Support for [Create React App](https://create-react-app.dev/) is handled by [`@storybook/preset-create-react-app`](https://github.com/storybookjs/presets/tree/master/packages/preset-create-react-app). + +This preset enables support for all CRA features, including Sass/SCSS and TypeScript. + +If you're working on an app that was initialized manually (i.e., without the use of CRA), ensure that your app has [react-dom](https://www.npmjs.com/package/react-dom) included as a dependency. Failing to do so can lead to unforeseen issues with Storybook and your project. + +## API + +### Options + +You can pass an options object for additional configuration if needed: + +```ts +// .storybook/main.ts +import type { StorybookConfig } from '@storybook/react-webpack5'; + +const config: StorybookConfig = { + framework: { + name: '@storybook/react-webpack5', + options: { + // ... + }, + }, +}; + +export default config; +``` + +#### `builder` + +Type: `Record` + +Configure options for the [framework's builder](../api/main-config-framework.md#optionsbuilder). For this framework, available options can be found in the [Webpack builder docs](../builders/webpack.md). + + + + diff --git a/docs/snippets/react/react-webpack5-add-framework.js.mdx b/docs/snippets/react/react-webpack5-add-framework.js.mdx new file mode 100644 index 000000000000..cbacf99bd80a --- /dev/null +++ b/docs/snippets/react/react-webpack5-add-framework.js.mdx @@ -0,0 +1,7 @@ +```js +// .storybook/main.js +export default { + // ... + framework: '@storybook/react-webpack5', // ๐Ÿ‘ˆ Add this +}; +``` diff --git a/docs/snippets/react/react-webpack5-add-framework.ts.mdx b/docs/snippets/react/react-webpack5-add-framework.ts.mdx new file mode 100644 index 000000000000..2417fd5ea98a --- /dev/null +++ b/docs/snippets/react/react-webpack5-add-framework.ts.mdx @@ -0,0 +1,11 @@ +```ts +// .storybook/main.ts +import { StorybookConfig } from '@storybook/react-webpack5'; + +const config: StorybookConfig = { + // ... + framework: '@storybook/react-webpack5', // ๐Ÿ‘ˆ Add this +}; + +export default config; +``` diff --git a/docs/snippets/react/react-webpack5-install.npm.js.mdx b/docs/snippets/react/react-webpack5-install.npm.js.mdx new file mode 100644 index 000000000000..8b54052f3f28 --- /dev/null +++ b/docs/snippets/react/react-webpack5-install.npm.js.mdx @@ -0,0 +1,3 @@ +```shell +npm install --save-dev @storybook/react-webpack5 +``` diff --git a/docs/snippets/react/react-webpack5-install.pnpm.js.mdx b/docs/snippets/react/react-webpack5-install.pnpm.js.mdx new file mode 100644 index 000000000000..840d64ae06c9 --- /dev/null +++ b/docs/snippets/react/react-webpack5-install.pnpm.js.mdx @@ -0,0 +1,3 @@ +```shell +pnpm install --save-dev @storybook/react-webpack5 +``` diff --git a/docs/snippets/react/react-webpack5-install.yarn.js.mdx b/docs/snippets/react/react-webpack5-install.yarn.js.mdx new file mode 100644 index 000000000000..b4f143c8a120 --- /dev/null +++ b/docs/snippets/react/react-webpack5-install.yarn.js.mdx @@ -0,0 +1,3 @@ +```shell +yarn add --dev @storybook/react-webpack5 +``` diff --git a/docs/toc.js b/docs/toc.js index 7b42d8d677e8..ac28d22b26af 100644 --- a/docs/toc.js +++ b/docs/toc.js @@ -38,6 +38,11 @@ module.exports = { title: 'React & Vite', type: 'link', }, + { + pathSegment: 'react-webpack5', + title: 'React & Webpack', + type: 'link', + }, { pathSegment: 'vue3-vite', title: 'Vue & Vite', From f9646ddf049d5bfb0a709dd1ce733b6f17dcc357 Mon Sep 17 00:00:00 2001 From: Kyle Gach Date: Thu, 7 Mar 2024 10:40:54 -0700 Subject: [PATCH 129/132] Address comments --- docs/get-started/react-webpack5.md | 40 ++++++++++++++++++++++++++++-- 1 file changed, 38 insertions(+), 2 deletions(-) diff --git a/docs/get-started/react-webpack5.md b/docs/get-started/react-webpack5.md index 48f916d45b3f..769aa82a0f2d 100644 --- a/docs/get-started/react-webpack5.md +++ b/docs/get-started/react-webpack5.md @@ -24,7 +24,7 @@ Storybook for React & Webpack is only supported in [React](?renderer=react) proj - React โ‰ฅ 16.8 - Webpack โ‰ฅ 5.0 -- Storybook โ‰ฅ 7.0 +- Storybook โ‰ฅ 8.0 ## Getting started @@ -82,7 +82,43 @@ First, install the framework: -Then, update your `.storybook/main.js|ts` to change the framework property: +Next, install and register your appropriate compiler addon, depending on whether you're using SWC (recommended) or Babel: + + + +If your project is using [Create React App](#create-react-app-cra), you can skip this step. + + + + + + + + + +or + + + + + + + +More details can be found in the [Webpack builder docs](../builders/webpack.md#compiler-support). + +Finally, update your `.storybook/main.js|ts` to change the framework property: From fffbbc9db03f9fc4fd1de7c26725f42c779e7f69 Mon Sep 17 00:00:00 2001 From: Kyle Gach Date: Wed, 6 Mar 2024 12:14:47 -0700 Subject: [PATCH 130/132] Add `svelte-vite` framework doc --- code/frameworks/svelte-vite/README.md | 4 +- docs/get-started/svelte-vite.md | 153 ++++++++++++++++++ .../svelte-csf-addon-install.npm.js.mdx | 2 +- .../svelte-csf-addon-install.pnpm.js.mdx | 2 +- .../svelte-csf-addon-install.yarn.js.mdx | 2 +- .../svelte/svelte-vite-add-framework.js.mdx | 7 + .../svelte/svelte-vite-add-framework.ts.mdx | 11 ++ .../svelte/svelte-vite-install.npm.js.mdx | 3 + .../svelte/svelte-vite-install.pnpm.js.mdx | 3 + .../svelte/svelte-vite-install.yarn.js.mdx | 3 + docs/toc.js | 5 + 11 files changed, 191 insertions(+), 4 deletions(-) create mode 100644 docs/get-started/svelte-vite.md create mode 100644 docs/snippets/svelte/svelte-vite-add-framework.js.mdx create mode 100644 docs/snippets/svelte/svelte-vite-add-framework.ts.mdx create mode 100644 docs/snippets/svelte/svelte-vite-install.npm.js.mdx create mode 100644 docs/snippets/svelte/svelte-vite-install.pnpm.js.mdx create mode 100644 docs/snippets/svelte/svelte-vite-install.yarn.js.mdx diff --git a/code/frameworks/svelte-vite/README.md b/code/frameworks/svelte-vite/README.md index 30a7c36ca01e..1f1dc740151d 100644 --- a/code/frameworks/svelte-vite/README.md +++ b/code/frameworks/svelte-vite/README.md @@ -1 +1,3 @@ -# Storybook for Svelte +# Storybook for Svelte & Vite + +See [documentation](https://storybook.js.org/docs/8.0/get-started/svelte-vite?renderer=svelte) for installation instructions, usage examples, APIs, and more. diff --git a/docs/get-started/svelte-vite.md b/docs/get-started/svelte-vite.md new file mode 100644 index 000000000000..2069a18d66ee --- /dev/null +++ b/docs/get-started/svelte-vite.md @@ -0,0 +1,153 @@ +--- +title: Storybook for Svelte & Vite +--- + +export const SUPPORTED_RENDERER = 'svelte'; + +Storybook for Svelte & Vite is a [framework](../contribute/framework.md) that makes it easy to develop and test UI components in isolation for applications using [Svelte](https://svelte.dev/) built with [Vite](https://vitejs.dev/). + + + + + +Storybook for Svelte & Vite is only supported in [Svelte](?renderer=svelte) projects. + + + + + + + + + +## Requirements + +- Svelte โ‰ฅ 4.0 +- Vite โ‰ฅ 4.0 +- Storybook โ‰ฅ 8.0 + +## Getting started + +### In a project without Storybook + +Follow the prompts after running this command in your Sveltekit project's root directory: + + + + + + + +[More on getting started with Storybook.](./install.md) + +### In a project with Storybook + +This framework is designed to work with Storybook 7+. If youโ€™re not already using v7, upgrade with this command: + + + + + + + +#### Automatic migration + +When running the `upgrade` command above, you should get a prompt asking you to migrate to `@storybook/sveltekit`, which should handle everything for you. In case that auto-migration does not work for your project, refer to the manual migration below. + +#### Manual migration + +First, install the framework: + + + + + + + +Then, update your `.storybook/main.js|ts` to change the framework property: + + + + + + + +## Writing native Svelte stories + +Storybook provides a Svelte addon maintained by the community, enabling you to write stories for your Svelte components using the template syntax. You'll need to take some additional steps to enable this feature. + +Run the following command to install the addon. + + + + + + + + + +The community actively maintains the Svelte CSF addon but still lacks some features currently available in the official Storybook Svelte framework support. For more information, see [addon's documentation](https://github.com/storybookjs/addon-svelte-csf). + + + +## API + +### Options + +You can pass an options object for additional configuration if needed: + +```js +// .storybook/main.js +import * as path from 'path'; + +export default { + // ... + framework: { + name: '@storybook/svelte-vite', + options: { + // ... + }, + }, +}; +``` + +The available options are: + +#### `builder` + +Type: `Record` + +Configure options for the [framework's builder](../api/main-config-framework.md#optionsbuilder). For this framework, available options can be found in the [Vite builder docs](../builders/vite.md). + + + + diff --git a/docs/snippets/svelte/svelte-csf-addon-install.npm.js.mdx b/docs/snippets/svelte/svelte-csf-addon-install.npm.js.mdx index 574d63651863..3889ca8909c4 100644 --- a/docs/snippets/svelte/svelte-csf-addon-install.npm.js.mdx +++ b/docs/snippets/svelte/svelte-csf-addon-install.npm.js.mdx @@ -1,3 +1,3 @@ ```shell -npm install @storybook/addon-svelte-csf --save-dev +npx storybook@latest add @storybook/addon-svelte-csf ``` diff --git a/docs/snippets/svelte/svelte-csf-addon-install.pnpm.js.mdx b/docs/snippets/svelte/svelte-csf-addon-install.pnpm.js.mdx index 4ff9be66f107..eb8c09e0708c 100644 --- a/docs/snippets/svelte/svelte-csf-addon-install.pnpm.js.mdx +++ b/docs/snippets/svelte/svelte-csf-addon-install.pnpm.js.mdx @@ -1,3 +1,3 @@ ```shell -pnpm add --save-dev @storybook/addon-svelte-csf +pnpm dlx storybook@latest add @storybook/addon-svelte-csf ``` diff --git a/docs/snippets/svelte/svelte-csf-addon-install.yarn.js.mdx b/docs/snippets/svelte/svelte-csf-addon-install.yarn.js.mdx index 5b3e6dff23f6..52ecff831d4c 100644 --- a/docs/snippets/svelte/svelte-csf-addon-install.yarn.js.mdx +++ b/docs/snippets/svelte/svelte-csf-addon-install.yarn.js.mdx @@ -1,3 +1,3 @@ ```shell -yarn add --dev @storybook/addon-svelte-csf +yarn storybook@latest add @storybook/addon-svelte-csf ``` diff --git a/docs/snippets/svelte/svelte-vite-add-framework.js.mdx b/docs/snippets/svelte/svelte-vite-add-framework.js.mdx new file mode 100644 index 000000000000..a16370254866 --- /dev/null +++ b/docs/snippets/svelte/svelte-vite-add-framework.js.mdx @@ -0,0 +1,7 @@ +```js +// .storybook/main.js +export default { + // ... + framework: '@storybook/svelte-vite', // ๐Ÿ‘ˆ Add this +}; +``` diff --git a/docs/snippets/svelte/svelte-vite-add-framework.ts.mdx b/docs/snippets/svelte/svelte-vite-add-framework.ts.mdx new file mode 100644 index 000000000000..920d91ae6d13 --- /dev/null +++ b/docs/snippets/svelte/svelte-vite-add-framework.ts.mdx @@ -0,0 +1,11 @@ +```ts +// .storybook/main.ts +import { StorybookConfig } from '@storybook/svelte-vite'; + +const config: StorybookConfig = { + // ... + framework: '@storybook/svelte-vite', // ๐Ÿ‘ˆ Add this +}; + +export default config; +``` diff --git a/docs/snippets/svelte/svelte-vite-install.npm.js.mdx b/docs/snippets/svelte/svelte-vite-install.npm.js.mdx new file mode 100644 index 000000000000..8b6986b5ecfa --- /dev/null +++ b/docs/snippets/svelte/svelte-vite-install.npm.js.mdx @@ -0,0 +1,3 @@ +```shell +npm install --save-dev @storybook/svelte-vite +``` diff --git a/docs/snippets/svelte/svelte-vite-install.pnpm.js.mdx b/docs/snippets/svelte/svelte-vite-install.pnpm.js.mdx new file mode 100644 index 000000000000..585bc12393ca --- /dev/null +++ b/docs/snippets/svelte/svelte-vite-install.pnpm.js.mdx @@ -0,0 +1,3 @@ +```shell +pnpm install --save-dev @storybook/svelte-vite +``` diff --git a/docs/snippets/svelte/svelte-vite-install.yarn.js.mdx b/docs/snippets/svelte/svelte-vite-install.yarn.js.mdx new file mode 100644 index 000000000000..7a8b11a4d500 --- /dev/null +++ b/docs/snippets/svelte/svelte-vite-install.yarn.js.mdx @@ -0,0 +1,3 @@ +```shell +yarn add --dev @storybook/svelte-vite +``` diff --git a/docs/toc.js b/docs/toc.js index ac28d22b26af..5b660a93cce5 100644 --- a/docs/toc.js +++ b/docs/toc.js @@ -43,6 +43,11 @@ module.exports = { title: 'React & Webpack', type: 'link', }, + { + pathSegment: 'svelte-vite', + title: 'Svelte & Vite', + type: 'link', + }, { pathSegment: 'vue3-vite', title: 'Vue & Vite', From a5cfe8eafd857cfbae8a8283fd7efe99e817a6e9 Mon Sep 17 00:00:00 2001 From: storybook-bot <32066757+storybook-bot@users.noreply.github.com> Date: Mon, 11 Mar 2024 15:43:51 +0000 Subject: [PATCH 131/132] Bump next to be one minor ahead of main [skip ci] --- code/addons/a11y/package.json | 2 +- code/addons/actions/package.json | 2 +- code/addons/backgrounds/package.json | 2 +- code/addons/controls/package.json | 2 +- code/addons/docs/package.json | 2 +- code/addons/essentials/package.json | 2 +- code/addons/gfm/package.json | 2 +- code/addons/highlight/package.json | 2 +- code/addons/interactions/package.json | 2 +- code/addons/jest/package.json | 2 +- code/addons/links/package.json | 2 +- code/addons/measure/package.json | 2 +- code/addons/onboarding/package.json | 2 +- code/addons/outline/package.json | 2 +- code/addons/storysource/package.json | 2 +- code/addons/themes/package.json | 2 +- code/addons/toolbars/package.json | 2 +- code/addons/viewport/package.json | 2 +- code/builders/builder-manager/package.json | 2 +- code/builders/builder-vite/package.json | 2 +- code/builders/builder-webpack5/package.json | 2 +- code/frameworks/angular/package.json | 2 +- code/frameworks/ember/package.json | 2 +- code/frameworks/html-vite/package.json | 2 +- code/frameworks/html-webpack5/package.json | 2 +- code/frameworks/nextjs/package.json | 2 +- code/frameworks/preact-vite/package.json | 2 +- code/frameworks/preact-webpack5/package.json | 2 +- code/frameworks/react-vite/package.json | 2 +- code/frameworks/react-webpack5/package.json | 2 +- code/frameworks/server-webpack5/package.json | 2 +- code/frameworks/svelte-vite/package.json | 2 +- code/frameworks/svelte-webpack5/package.json | 2 +- code/frameworks/sveltekit/package.json | 2 +- code/frameworks/vue3-vite/package.json | 2 +- code/frameworks/vue3-webpack5/package.json | 2 +- .../web-components-vite/package.json | 2 +- .../web-components-webpack5/package.json | 2 +- code/lib/channels/package.json | 2 +- code/lib/cli-sb/package.json | 2 +- code/lib/cli-storybook/package.json | 2 +- code/lib/cli/package.json | 2 +- code/lib/client-logger/package.json | 2 +- code/lib/codemod/package.json | 2 +- code/lib/core-common/package.json | 2 +- code/lib/core-common/src/versions.ts | 160 +++++++++--------- code/lib/core-events/package.json | 2 +- code/lib/core-server/package.json | 2 +- code/lib/core-webpack/package.json | 2 +- code/lib/csf-plugin/package.json | 2 +- code/lib/csf-tools/package.json | 2 +- code/lib/docs-tools/package.json | 2 +- code/lib/instrumenter/package.json | 2 +- code/lib/manager-api/package.json | 2 +- code/lib/manager-api/src/version.ts | 2 +- code/lib/node-logger/package.json | 2 +- code/lib/preview-api/package.json | 2 +- code/lib/preview/package.json | 2 +- code/lib/react-dom-shim/package.json | 2 +- code/lib/router/package.json | 2 +- code/lib/source-loader/package.json | 2 +- code/lib/telemetry/package.json | 2 +- code/lib/test/package.json | 2 +- code/lib/theming/package.json | 2 +- code/lib/types/package.json | 2 +- code/package.json | 2 +- code/presets/create-react-app/package.json | 2 +- code/presets/html-webpack/package.json | 2 +- code/presets/preact-webpack/package.json | 2 +- code/presets/react-webpack/package.json | 2 +- code/presets/server-webpack/package.json | 2 +- code/presets/svelte-webpack/package.json | 2 +- code/presets/vue3-webpack/package.json | 2 +- code/renderers/html/package.json | 2 +- code/renderers/preact/package.json | 2 +- code/renderers/react/package.json | 2 +- code/renderers/server/package.json | 2 +- code/renderers/svelte/package.json | 2 +- code/renderers/vue3/package.json | 2 +- code/renderers/web-components/package.json | 2 +- code/ui/blocks/package.json | 2 +- code/ui/components/package.json | 2 +- code/ui/manager/package.json | 2 +- 83 files changed, 162 insertions(+), 162 deletions(-) diff --git a/code/addons/a11y/package.json b/code/addons/a11y/package.json index 613dbdc000fb..73f802106851 100644 --- a/code/addons/a11y/package.json +++ b/code/addons/a11y/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/addon-a11y", - "version": "8.0.0-rc.5", + "version": "8.1.0-alpha.0", "description": "Test component compliance with web accessibility standards", "keywords": [ "a11y", diff --git a/code/addons/actions/package.json b/code/addons/actions/package.json index 4724520ee560..2f13f8e98a15 100644 --- a/code/addons/actions/package.json +++ b/code/addons/actions/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/addon-actions", - "version": "8.0.0-rc.5", + "version": "8.1.0-alpha.0", "description": "Get UI feedback when an action is performed on an interactive element", "keywords": [ "storybook", diff --git a/code/addons/backgrounds/package.json b/code/addons/backgrounds/package.json index 40173cebe181..08ea5529d139 100644 --- a/code/addons/backgrounds/package.json +++ b/code/addons/backgrounds/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/addon-backgrounds", - "version": "8.0.0-rc.5", + "version": "8.1.0-alpha.0", "description": "Switch backgrounds to view components in different settings", "keywords": [ "addon", diff --git a/code/addons/controls/package.json b/code/addons/controls/package.json index 682efb322c40..d59821722737 100644 --- a/code/addons/controls/package.json +++ b/code/addons/controls/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/addon-controls", - "version": "8.0.0-rc.5", + "version": "8.1.0-alpha.0", "description": "Interact with component inputs dynamically in the Storybook UI", "keywords": [ "addon", diff --git a/code/addons/docs/package.json b/code/addons/docs/package.json index 86d2d040a1fa..3c6eaa0d625a 100644 --- a/code/addons/docs/package.json +++ b/code/addons/docs/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/addon-docs", - "version": "8.0.0-rc.5", + "version": "8.1.0-alpha.0", "description": "Document component usage and properties in Markdown", "keywords": [ "addon", diff --git a/code/addons/essentials/package.json b/code/addons/essentials/package.json index ea286c7e6daf..3b9143837d78 100644 --- a/code/addons/essentials/package.json +++ b/code/addons/essentials/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/addon-essentials", - "version": "8.0.0-rc.5", + "version": "8.1.0-alpha.0", "description": "Curated addons to bring out the best of Storybook", "keywords": [ "addon", diff --git a/code/addons/gfm/package.json b/code/addons/gfm/package.json index 8626bce63870..b35c226de305 100644 --- a/code/addons/gfm/package.json +++ b/code/addons/gfm/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/addon-mdx-gfm", - "version": "8.0.0-rc.5", + "version": "8.1.0-alpha.0", "description": "GitHub Flavored Markdown in Storybook", "keywords": [ "addon", diff --git a/code/addons/highlight/package.json b/code/addons/highlight/package.json index 9bcf61952789..bae6a544048d 100644 --- a/code/addons/highlight/package.json +++ b/code/addons/highlight/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/addon-highlight", - "version": "8.0.0-rc.5", + "version": "8.1.0-alpha.0", "description": "Highlight DOM nodes within your stories", "keywords": [ "storybook-addons", diff --git a/code/addons/interactions/package.json b/code/addons/interactions/package.json index c0773463ab1a..dbb88085b22b 100644 --- a/code/addons/interactions/package.json +++ b/code/addons/interactions/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/addon-interactions", - "version": "8.0.0-rc.5", + "version": "8.1.0-alpha.0", "description": "Automate, test and debug user interactions", "keywords": [ "storybook-addons", diff --git a/code/addons/jest/package.json b/code/addons/jest/package.json index 7f6f3de7b01d..bd511b8e0b5c 100644 --- a/code/addons/jest/package.json +++ b/code/addons/jest/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/addon-jest", - "version": "8.0.0-rc.5", + "version": "8.1.0-alpha.0", "description": "React storybook addon that show component jest report", "keywords": [ "addon", diff --git a/code/addons/links/package.json b/code/addons/links/package.json index 3c218f06f3de..686c684f829b 100644 --- a/code/addons/links/package.json +++ b/code/addons/links/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/addon-links", - "version": "8.0.0-rc.5", + "version": "8.1.0-alpha.0", "description": "Link stories together to build demos and prototypes with your UI components", "keywords": [ "addon", diff --git a/code/addons/measure/package.json b/code/addons/measure/package.json index 8a6449f6a9e4..1985366f670c 100644 --- a/code/addons/measure/package.json +++ b/code/addons/measure/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/addon-measure", - "version": "8.0.0-rc.5", + "version": "8.1.0-alpha.0", "description": "Inspect layouts by visualizing the box model", "keywords": [ "storybook-addons", diff --git a/code/addons/onboarding/package.json b/code/addons/onboarding/package.json index df3cad03d039..72726fb3726f 100644 --- a/code/addons/onboarding/package.json +++ b/code/addons/onboarding/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/addon-onboarding", - "version": "8.0.0-rc.5", + "version": "8.1.0-alpha.0", "description": "Storybook Addon Onboarding - Introduces a new onboarding experience", "keywords": [ "storybook-addons", diff --git a/code/addons/outline/package.json b/code/addons/outline/package.json index b87b89b4eb3b..f8db2b4ea149 100644 --- a/code/addons/outline/package.json +++ b/code/addons/outline/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/addon-outline", - "version": "8.0.0-rc.5", + "version": "8.1.0-alpha.0", "description": "Outline all elements with CSS to help with layout placement and alignment", "keywords": [ "storybook-addons", diff --git a/code/addons/storysource/package.json b/code/addons/storysource/package.json index b9eefe5d2044..c7326a263ad1 100644 --- a/code/addons/storysource/package.json +++ b/code/addons/storysource/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/addon-storysource", - "version": "8.0.0-rc.5", + "version": "8.1.0-alpha.0", "description": "View a storyโ€™s source code to see how it works and paste into your app", "keywords": [ "addon", diff --git a/code/addons/themes/package.json b/code/addons/themes/package.json index 2e530e1427f3..a3599f8288e2 100644 --- a/code/addons/themes/package.json +++ b/code/addons/themes/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/addon-themes", - "version": "8.0.0-rc.5", + "version": "8.1.0-alpha.0", "description": "Switch between multiple themes for you components in Storybook", "keywords": [ "css", diff --git a/code/addons/toolbars/package.json b/code/addons/toolbars/package.json index d5678032c004..ec4a11506175 100644 --- a/code/addons/toolbars/package.json +++ b/code/addons/toolbars/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/addon-toolbars", - "version": "8.0.0-rc.5", + "version": "8.1.0-alpha.0", "description": "Create your own toolbar items that control story rendering", "keywords": [ "addon", diff --git a/code/addons/viewport/package.json b/code/addons/viewport/package.json index e12051424124..92208b361584 100644 --- a/code/addons/viewport/package.json +++ b/code/addons/viewport/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/addon-viewport", - "version": "8.0.0-rc.5", + "version": "8.1.0-alpha.0", "description": "Build responsive components by adjusting Storybookโ€™s viewport size and orientation", "keywords": [ "addon", diff --git a/code/builders/builder-manager/package.json b/code/builders/builder-manager/package.json index 818cd8bc9c1f..a31a2e91a374 100644 --- a/code/builders/builder-manager/package.json +++ b/code/builders/builder-manager/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/builder-manager", - "version": "8.0.0-rc.5", + "version": "8.1.0-alpha.0", "description": "Storybook manager builder", "keywords": [ "storybook" diff --git a/code/builders/builder-vite/package.json b/code/builders/builder-vite/package.json index ecd31fb31953..1d0dd1b7610c 100644 --- a/code/builders/builder-vite/package.json +++ b/code/builders/builder-vite/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/builder-vite", - "version": "8.0.0-rc.5", + "version": "8.1.0-alpha.0", "description": "A plugin to run and build Storybooks with Vite", "homepage": "https://github.com/storybookjs/storybook/tree/next/code/builders/builder-vite/#readme", "bugs": { diff --git a/code/builders/builder-webpack5/package.json b/code/builders/builder-webpack5/package.json index 09b3cc203aff..31d47498ee40 100644 --- a/code/builders/builder-webpack5/package.json +++ b/code/builders/builder-webpack5/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/builder-webpack5", - "version": "8.0.0-rc.5", + "version": "8.1.0-alpha.0", "description": "Storybook framework-agnostic API", "keywords": [ "storybook" diff --git a/code/frameworks/angular/package.json b/code/frameworks/angular/package.json index 8b43006f3dc4..9ffa620ac401 100644 --- a/code/frameworks/angular/package.json +++ b/code/frameworks/angular/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/angular", - "version": "8.0.0-rc.5", + "version": "8.1.0-alpha.0", "description": "Storybook for Angular: Develop Angular components in isolation with hot reloading.", "keywords": [ "storybook", diff --git a/code/frameworks/ember/package.json b/code/frameworks/ember/package.json index 425c1eb5b888..9c796b2f5b7c 100644 --- a/code/frameworks/ember/package.json +++ b/code/frameworks/ember/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/ember", - "version": "8.0.0-rc.5", + "version": "8.1.0-alpha.0", "description": "Storybook for Ember: Develop Ember Component in isolation with Hot Reloading.", "homepage": "https://github.com/storybookjs/storybook/tree/next/code/frameworks/ember", "bugs": { diff --git a/code/frameworks/html-vite/package.json b/code/frameworks/html-vite/package.json index 6cb46be12bd2..26bcfa5687c7 100644 --- a/code/frameworks/html-vite/package.json +++ b/code/frameworks/html-vite/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/html-vite", - "version": "8.0.0-rc.5", + "version": "8.1.0-alpha.0", "description": "Storybook for HTML and Vite: Develop HTML in isolation with Hot Reloading.", "keywords": [ "storybook" diff --git a/code/frameworks/html-webpack5/package.json b/code/frameworks/html-webpack5/package.json index d8181d85aa46..7c6e27ae25e1 100644 --- a/code/frameworks/html-webpack5/package.json +++ b/code/frameworks/html-webpack5/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/html-webpack5", - "version": "8.0.0-rc.5", + "version": "8.1.0-alpha.0", "description": "Storybook for HTML: View HTML snippets in isolation with Hot Reloading.", "keywords": [ "storybook" diff --git a/code/frameworks/nextjs/package.json b/code/frameworks/nextjs/package.json index 4f038bac401d..f3a10ee4210d 100644 --- a/code/frameworks/nextjs/package.json +++ b/code/frameworks/nextjs/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/nextjs", - "version": "8.0.0-rc.5", + "version": "8.1.0-alpha.0", "description": "Storybook for Next.js", "keywords": [ "storybook", diff --git a/code/frameworks/preact-vite/package.json b/code/frameworks/preact-vite/package.json index 2bb980d16d83..b8b67128ef22 100644 --- a/code/frameworks/preact-vite/package.json +++ b/code/frameworks/preact-vite/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/preact-vite", - "version": "8.0.0-rc.5", + "version": "8.1.0-alpha.0", "description": "Storybook for Preact and Vite: Develop Preact components in isolation with Hot Reloading.", "keywords": [ "storybook" diff --git a/code/frameworks/preact-webpack5/package.json b/code/frameworks/preact-webpack5/package.json index 33338d991b79..51bdc48718ad 100644 --- a/code/frameworks/preact-webpack5/package.json +++ b/code/frameworks/preact-webpack5/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/preact-webpack5", - "version": "8.0.0-rc.5", + "version": "8.1.0-alpha.0", "description": "Storybook for Preact: Develop Preact Component in isolation.", "keywords": [ "storybook" diff --git a/code/frameworks/react-vite/package.json b/code/frameworks/react-vite/package.json index 37b42510626e..da08584b7625 100644 --- a/code/frameworks/react-vite/package.json +++ b/code/frameworks/react-vite/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/react-vite", - "version": "8.0.0-rc.5", + "version": "8.1.0-alpha.0", "description": "Storybook for React and Vite: Develop React components in isolation with Hot Reloading.", "keywords": [ "storybook" diff --git a/code/frameworks/react-webpack5/package.json b/code/frameworks/react-webpack5/package.json index c43671bb14fb..3d5ceb3ba80c 100644 --- a/code/frameworks/react-webpack5/package.json +++ b/code/frameworks/react-webpack5/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/react-webpack5", - "version": "8.0.0-rc.5", + "version": "8.1.0-alpha.0", "description": "Storybook for React: Develop React Component in isolation with Hot Reloading.", "keywords": [ "storybook" diff --git a/code/frameworks/server-webpack5/package.json b/code/frameworks/server-webpack5/package.json index 52cd8d871e45..6aa05a0c122d 100644 --- a/code/frameworks/server-webpack5/package.json +++ b/code/frameworks/server-webpack5/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/server-webpack5", - "version": "8.0.0-rc.5", + "version": "8.1.0-alpha.0", "description": "Storybook for Server: View HTML snippets from a server in isolation with Hot Reloading.", "keywords": [ "storybook" diff --git a/code/frameworks/svelte-vite/package.json b/code/frameworks/svelte-vite/package.json index 1b10dcb99319..9090da475670 100644 --- a/code/frameworks/svelte-vite/package.json +++ b/code/frameworks/svelte-vite/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/svelte-vite", - "version": "8.0.0-rc.5", + "version": "8.1.0-alpha.0", "description": "Storybook for Svelte and Vite: Develop Svelte components in isolation with Hot Reloading.", "keywords": [ "storybook" diff --git a/code/frameworks/svelte-webpack5/package.json b/code/frameworks/svelte-webpack5/package.json index c63122e40028..db4ed258f40c 100644 --- a/code/frameworks/svelte-webpack5/package.json +++ b/code/frameworks/svelte-webpack5/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/svelte-webpack5", - "version": "8.0.0-rc.5", + "version": "8.1.0-alpha.0", "description": "Storybook for Svelte: Develop Svelte Component in isolation with Hot Reloading.", "keywords": [ "storybook" diff --git a/code/frameworks/sveltekit/package.json b/code/frameworks/sveltekit/package.json index 6cfbe9bf5460..2acf401c3f24 100644 --- a/code/frameworks/sveltekit/package.json +++ b/code/frameworks/sveltekit/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/sveltekit", - "version": "8.0.0-rc.5", + "version": "8.1.0-alpha.0", "description": "Storybook for SvelteKit", "keywords": [ "storybook", diff --git a/code/frameworks/vue3-vite/package.json b/code/frameworks/vue3-vite/package.json index a36fc60ad2da..44297c5a4047 100644 --- a/code/frameworks/vue3-vite/package.json +++ b/code/frameworks/vue3-vite/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/vue3-vite", - "version": "8.0.0-rc.5", + "version": "8.1.0-alpha.0", "description": "Storybook for Vue3 and Vite: Develop Vue3 components in isolation with Hot Reloading.", "keywords": [ "storybook" diff --git a/code/frameworks/vue3-webpack5/package.json b/code/frameworks/vue3-webpack5/package.json index 27cb857d3aac..094fb5103f2d 100644 --- a/code/frameworks/vue3-webpack5/package.json +++ b/code/frameworks/vue3-webpack5/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/vue3-webpack5", - "version": "8.0.0-rc.5", + "version": "8.1.0-alpha.0", "description": "Storybook for Vue 3: Develop Vue 3 Components in isolation with Hot Reloading.", "keywords": [ "storybook" diff --git a/code/frameworks/web-components-vite/package.json b/code/frameworks/web-components-vite/package.json index 521db343776a..cbe4ffdc247d 100644 --- a/code/frameworks/web-components-vite/package.json +++ b/code/frameworks/web-components-vite/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/web-components-vite", - "version": "8.0.0-rc.5", + "version": "8.1.0-alpha.0", "description": "Storybook for web-components and Vite: Develop Web Components in isolation with Hot Reloading.", "keywords": [ "storybook" diff --git a/code/frameworks/web-components-webpack5/package.json b/code/frameworks/web-components-webpack5/package.json index cef8919e5d61..866ab3d35e5d 100644 --- a/code/frameworks/web-components-webpack5/package.json +++ b/code/frameworks/web-components-webpack5/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/web-components-webpack5", - "version": "8.0.0-rc.5", + "version": "8.1.0-alpha.0", "description": "Storybook for web-components: View web components snippets in isolation with Hot Reloading.", "keywords": [ "lit", diff --git a/code/lib/channels/package.json b/code/lib/channels/package.json index 7215f9831110..1f583dc9865d 100644 --- a/code/lib/channels/package.json +++ b/code/lib/channels/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/channels", - "version": "8.0.0-rc.5", + "version": "8.1.0-alpha.0", "description": "", "keywords": [ "storybook" diff --git a/code/lib/cli-sb/package.json b/code/lib/cli-sb/package.json index 64c8731c1701..e707547191dd 100644 --- a/code/lib/cli-sb/package.json +++ b/code/lib/cli-sb/package.json @@ -1,6 +1,6 @@ { "name": "sb", - "version": "8.0.0-rc.5", + "version": "8.1.0-alpha.0", "description": "Storybook CLI", "keywords": [ "storybook" diff --git a/code/lib/cli-storybook/package.json b/code/lib/cli-storybook/package.json index eba2ad5c08ce..3eb1547fccc0 100644 --- a/code/lib/cli-storybook/package.json +++ b/code/lib/cli-storybook/package.json @@ -1,6 +1,6 @@ { "name": "storybook", - "version": "8.0.0-rc.5", + "version": "8.1.0-alpha.0", "description": "Storybook CLI", "keywords": [ "storybook" diff --git a/code/lib/cli/package.json b/code/lib/cli/package.json index 6baa876bc0d1..01d064068c60 100644 --- a/code/lib/cli/package.json +++ b/code/lib/cli/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/cli", - "version": "8.0.0-rc.5", + "version": "8.1.0-alpha.0", "description": "Storybook's CLI - install, dev, build, upgrade, and more", "keywords": [ "cli", diff --git a/code/lib/client-logger/package.json b/code/lib/client-logger/package.json index 915205d726f7..83926ddd07ac 100644 --- a/code/lib/client-logger/package.json +++ b/code/lib/client-logger/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/client-logger", - "version": "8.0.0-rc.5", + "version": "8.1.0-alpha.0", "description": "", "keywords": [ "storybook" diff --git a/code/lib/codemod/package.json b/code/lib/codemod/package.json index a973e8585e7c..290164c50f5f 100644 --- a/code/lib/codemod/package.json +++ b/code/lib/codemod/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/codemod", - "version": "8.0.0-rc.5", + "version": "8.1.0-alpha.0", "description": "A collection of codemod scripts written with JSCodeshift", "keywords": [ "storybook" diff --git a/code/lib/core-common/package.json b/code/lib/core-common/package.json index d2beadd15a27..b46b9a1de983 100644 --- a/code/lib/core-common/package.json +++ b/code/lib/core-common/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/core-common", - "version": "8.0.0-rc.5", + "version": "8.1.0-alpha.0", "description": "Storybook framework-agnostic API", "keywords": [ "storybook" diff --git a/code/lib/core-common/src/versions.ts b/code/lib/core-common/src/versions.ts index 1f3bf59707c4..0109c9c2a8a3 100644 --- a/code/lib/core-common/src/versions.ts +++ b/code/lib/core-common/src/versions.ts @@ -1,83 +1,83 @@ // auto generated file, do not edit export default { - '@storybook/addon-a11y': '8.0.0-rc.5', - '@storybook/addon-actions': '8.0.0-rc.5', - '@storybook/addon-backgrounds': '8.0.0-rc.5', - '@storybook/addon-controls': '8.0.0-rc.5', - '@storybook/addon-docs': '8.0.0-rc.5', - '@storybook/addon-essentials': '8.0.0-rc.5', - '@storybook/addon-highlight': '8.0.0-rc.5', - '@storybook/addon-interactions': '8.0.0-rc.5', - '@storybook/addon-jest': '8.0.0-rc.5', - '@storybook/addon-links': '8.0.0-rc.5', - '@storybook/addon-mdx-gfm': '8.0.0-rc.5', - '@storybook/addon-measure': '8.0.0-rc.5', - '@storybook/addon-onboarding': '8.0.0-rc.5', - '@storybook/addon-outline': '8.0.0-rc.5', - '@storybook/addon-storysource': '8.0.0-rc.5', - '@storybook/addon-themes': '8.0.0-rc.5', - '@storybook/addon-toolbars': '8.0.0-rc.5', - '@storybook/addon-viewport': '8.0.0-rc.5', - '@storybook/angular': '8.0.0-rc.5', - '@storybook/blocks': '8.0.0-rc.5', - '@storybook/builder-manager': '8.0.0-rc.5', - '@storybook/builder-vite': '8.0.0-rc.5', - '@storybook/builder-webpack5': '8.0.0-rc.5', - '@storybook/channels': '8.0.0-rc.5', - '@storybook/cli': '8.0.0-rc.5', - '@storybook/client-logger': '8.0.0-rc.5', - '@storybook/codemod': '8.0.0-rc.5', - '@storybook/components': '8.0.0-rc.5', - '@storybook/core-common': '8.0.0-rc.5', - '@storybook/core-events': '8.0.0-rc.5', - '@storybook/core-server': '8.0.0-rc.5', - '@storybook/core-webpack': '8.0.0-rc.5', - '@storybook/csf-plugin': '8.0.0-rc.5', - '@storybook/csf-tools': '8.0.0-rc.5', - '@storybook/docs-tools': '8.0.0-rc.5', - '@storybook/ember': '8.0.0-rc.5', - '@storybook/html': '8.0.0-rc.5', - '@storybook/html-vite': '8.0.0-rc.5', - '@storybook/html-webpack5': '8.0.0-rc.5', - '@storybook/instrumenter': '8.0.0-rc.5', - '@storybook/manager': '8.0.0-rc.5', - '@storybook/manager-api': '8.0.0-rc.5', - '@storybook/nextjs': '8.0.0-rc.5', - '@storybook/node-logger': '8.0.0-rc.5', - '@storybook/preact': '8.0.0-rc.5', - '@storybook/preact-vite': '8.0.0-rc.5', - '@storybook/preact-webpack5': '8.0.0-rc.5', - '@storybook/preset-create-react-app': '8.0.0-rc.5', - '@storybook/preset-html-webpack': '8.0.0-rc.5', - '@storybook/preset-preact-webpack': '8.0.0-rc.5', - '@storybook/preset-react-webpack': '8.0.0-rc.5', - '@storybook/preset-server-webpack': '8.0.0-rc.5', - '@storybook/preset-svelte-webpack': '8.0.0-rc.5', - '@storybook/preset-vue3-webpack': '8.0.0-rc.5', - '@storybook/preview': '8.0.0-rc.5', - '@storybook/preview-api': '8.0.0-rc.5', - '@storybook/react': '8.0.0-rc.5', - '@storybook/react-dom-shim': '8.0.0-rc.5', - '@storybook/react-vite': '8.0.0-rc.5', - '@storybook/react-webpack5': '8.0.0-rc.5', - '@storybook/router': '8.0.0-rc.5', - '@storybook/server': '8.0.0-rc.5', - '@storybook/server-webpack5': '8.0.0-rc.5', - '@storybook/source-loader': '8.0.0-rc.5', - '@storybook/svelte': '8.0.0-rc.5', - '@storybook/svelte-vite': '8.0.0-rc.5', - '@storybook/svelte-webpack5': '8.0.0-rc.5', - '@storybook/sveltekit': '8.0.0-rc.5', - '@storybook/telemetry': '8.0.0-rc.5', - '@storybook/test': '8.0.0-rc.5', - '@storybook/theming': '8.0.0-rc.5', - '@storybook/types': '8.0.0-rc.5', - '@storybook/vue3': '8.0.0-rc.5', - '@storybook/vue3-vite': '8.0.0-rc.5', - '@storybook/vue3-webpack5': '8.0.0-rc.5', - '@storybook/web-components': '8.0.0-rc.5', - '@storybook/web-components-vite': '8.0.0-rc.5', - '@storybook/web-components-webpack5': '8.0.0-rc.5', - sb: '8.0.0-rc.5', - storybook: '8.0.0-rc.5', + '@storybook/addon-a11y': '8.1.0-alpha.0', + '@storybook/addon-actions': '8.1.0-alpha.0', + '@storybook/addon-backgrounds': '8.1.0-alpha.0', + '@storybook/addon-controls': '8.1.0-alpha.0', + '@storybook/addon-docs': '8.1.0-alpha.0', + '@storybook/addon-essentials': '8.1.0-alpha.0', + '@storybook/addon-highlight': '8.1.0-alpha.0', + '@storybook/addon-interactions': '8.1.0-alpha.0', + '@storybook/addon-jest': '8.1.0-alpha.0', + '@storybook/addon-links': '8.1.0-alpha.0', + '@storybook/addon-mdx-gfm': '8.1.0-alpha.0', + '@storybook/addon-measure': '8.1.0-alpha.0', + '@storybook/addon-onboarding': '8.1.0-alpha.0', + '@storybook/addon-outline': '8.1.0-alpha.0', + '@storybook/addon-storysource': '8.1.0-alpha.0', + '@storybook/addon-themes': '8.1.0-alpha.0', + '@storybook/addon-toolbars': '8.1.0-alpha.0', + '@storybook/addon-viewport': '8.1.0-alpha.0', + '@storybook/angular': '8.1.0-alpha.0', + '@storybook/blocks': '8.1.0-alpha.0', + '@storybook/builder-manager': '8.1.0-alpha.0', + '@storybook/builder-vite': '8.1.0-alpha.0', + '@storybook/builder-webpack5': '8.1.0-alpha.0', + '@storybook/channels': '8.1.0-alpha.0', + '@storybook/cli': '8.1.0-alpha.0', + '@storybook/client-logger': '8.1.0-alpha.0', + '@storybook/codemod': '8.1.0-alpha.0', + '@storybook/components': '8.1.0-alpha.0', + '@storybook/core-common': '8.1.0-alpha.0', + '@storybook/core-events': '8.1.0-alpha.0', + '@storybook/core-server': '8.1.0-alpha.0', + '@storybook/core-webpack': '8.1.0-alpha.0', + '@storybook/csf-plugin': '8.1.0-alpha.0', + '@storybook/csf-tools': '8.1.0-alpha.0', + '@storybook/docs-tools': '8.1.0-alpha.0', + '@storybook/ember': '8.1.0-alpha.0', + '@storybook/html': '8.1.0-alpha.0', + '@storybook/html-vite': '8.1.0-alpha.0', + '@storybook/html-webpack5': '8.1.0-alpha.0', + '@storybook/instrumenter': '8.1.0-alpha.0', + '@storybook/manager': '8.1.0-alpha.0', + '@storybook/manager-api': '8.1.0-alpha.0', + '@storybook/nextjs': '8.1.0-alpha.0', + '@storybook/node-logger': '8.1.0-alpha.0', + '@storybook/preact': '8.1.0-alpha.0', + '@storybook/preact-vite': '8.1.0-alpha.0', + '@storybook/preact-webpack5': '8.1.0-alpha.0', + '@storybook/preset-create-react-app': '8.1.0-alpha.0', + '@storybook/preset-html-webpack': '8.1.0-alpha.0', + '@storybook/preset-preact-webpack': '8.1.0-alpha.0', + '@storybook/preset-react-webpack': '8.1.0-alpha.0', + '@storybook/preset-server-webpack': '8.1.0-alpha.0', + '@storybook/preset-svelte-webpack': '8.1.0-alpha.0', + '@storybook/preset-vue3-webpack': '8.1.0-alpha.0', + '@storybook/preview': '8.1.0-alpha.0', + '@storybook/preview-api': '8.1.0-alpha.0', + '@storybook/react': '8.1.0-alpha.0', + '@storybook/react-dom-shim': '8.1.0-alpha.0', + '@storybook/react-vite': '8.1.0-alpha.0', + '@storybook/react-webpack5': '8.1.0-alpha.0', + '@storybook/router': '8.1.0-alpha.0', + '@storybook/server': '8.1.0-alpha.0', + '@storybook/server-webpack5': '8.1.0-alpha.0', + '@storybook/source-loader': '8.1.0-alpha.0', + '@storybook/svelte': '8.1.0-alpha.0', + '@storybook/svelte-vite': '8.1.0-alpha.0', + '@storybook/svelte-webpack5': '8.1.0-alpha.0', + '@storybook/sveltekit': '8.1.0-alpha.0', + '@storybook/telemetry': '8.1.0-alpha.0', + '@storybook/test': '8.1.0-alpha.0', + '@storybook/theming': '8.1.0-alpha.0', + '@storybook/types': '8.1.0-alpha.0', + '@storybook/vue3': '8.1.0-alpha.0', + '@storybook/vue3-vite': '8.1.0-alpha.0', + '@storybook/vue3-webpack5': '8.1.0-alpha.0', + '@storybook/web-components': '8.1.0-alpha.0', + '@storybook/web-components-vite': '8.1.0-alpha.0', + '@storybook/web-components-webpack5': '8.1.0-alpha.0', + sb: '8.1.0-alpha.0', + storybook: '8.1.0-alpha.0', }; diff --git a/code/lib/core-events/package.json b/code/lib/core-events/package.json index 0a06fbab9d30..2fda3e0eb626 100644 --- a/code/lib/core-events/package.json +++ b/code/lib/core-events/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/core-events", - "version": "8.0.0-rc.5", + "version": "8.1.0-alpha.0", "description": "Event names used in storybook core", "keywords": [ "storybook" diff --git a/code/lib/core-server/package.json b/code/lib/core-server/package.json index 11904f82e863..2b44e68b8a22 100644 --- a/code/lib/core-server/package.json +++ b/code/lib/core-server/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/core-server", - "version": "8.0.0-rc.5", + "version": "8.1.0-alpha.0", "description": "Storybook framework-agnostic API", "keywords": [ "storybook" diff --git a/code/lib/core-webpack/package.json b/code/lib/core-webpack/package.json index e2129ed58c9a..d1e6142601ea 100644 --- a/code/lib/core-webpack/package.json +++ b/code/lib/core-webpack/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/core-webpack", - "version": "8.0.0-rc.5", + "version": "8.1.0-alpha.0", "description": "Storybook framework-agnostic API", "keywords": [ "storybook" diff --git a/code/lib/csf-plugin/package.json b/code/lib/csf-plugin/package.json index f275a090e8d6..1761eb435ae1 100644 --- a/code/lib/csf-plugin/package.json +++ b/code/lib/csf-plugin/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/csf-plugin", - "version": "8.0.0-rc.5", + "version": "8.1.0-alpha.0", "description": "Enrich CSF files via static analysis", "keywords": [ "storybook" diff --git a/code/lib/csf-tools/package.json b/code/lib/csf-tools/package.json index bb9749cfff93..f8e58033aff3 100644 --- a/code/lib/csf-tools/package.json +++ b/code/lib/csf-tools/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/csf-tools", - "version": "8.0.0-rc.5", + "version": "8.1.0-alpha.0", "description": "Parse and manipulate CSF and Storybook config files", "keywords": [ "storybook" diff --git a/code/lib/docs-tools/package.json b/code/lib/docs-tools/package.json index 2863f4b50d55..8ecc609ee401 100644 --- a/code/lib/docs-tools/package.json +++ b/code/lib/docs-tools/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/docs-tools", - "version": "8.0.0-rc.5", + "version": "8.1.0-alpha.0", "description": "Shared utility functions for frameworks to implement docs", "keywords": [ "storybook" diff --git a/code/lib/instrumenter/package.json b/code/lib/instrumenter/package.json index a15743e36be3..c411b7c9138c 100644 --- a/code/lib/instrumenter/package.json +++ b/code/lib/instrumenter/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/instrumenter", - "version": "8.0.0-rc.5", + "version": "8.1.0-alpha.0", "description": "", "keywords": [ "storybook" diff --git a/code/lib/manager-api/package.json b/code/lib/manager-api/package.json index 3c5faf93d744..566511f21346 100644 --- a/code/lib/manager-api/package.json +++ b/code/lib/manager-api/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/manager-api", - "version": "8.0.0-rc.5", + "version": "8.1.0-alpha.0", "description": "Core Storybook Manager API & Context", "keywords": [ "storybook" diff --git a/code/lib/manager-api/src/version.ts b/code/lib/manager-api/src/version.ts index 7a52ddfe9b62..f89e3528d2df 100644 --- a/code/lib/manager-api/src/version.ts +++ b/code/lib/manager-api/src/version.ts @@ -1 +1 @@ -export const version = '8.0.0-rc.5'; +export const version = '8.1.0-alpha.0'; diff --git a/code/lib/node-logger/package.json b/code/lib/node-logger/package.json index d8a6f25ba21a..739cd0051874 100644 --- a/code/lib/node-logger/package.json +++ b/code/lib/node-logger/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/node-logger", - "version": "8.0.0-rc.5", + "version": "8.1.0-alpha.0", "description": "", "keywords": [ "storybook" diff --git a/code/lib/preview-api/package.json b/code/lib/preview-api/package.json index c040ca46a430..126be65d5e3a 100644 --- a/code/lib/preview-api/package.json +++ b/code/lib/preview-api/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/preview-api", - "version": "8.0.0-rc.5", + "version": "8.1.0-alpha.0", "description": "", "keywords": [ "storybook" diff --git a/code/lib/preview/package.json b/code/lib/preview/package.json index ec8800525a3e..94821536bc4a 100644 --- a/code/lib/preview/package.json +++ b/code/lib/preview/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/preview", - "version": "8.0.0-rc.5", + "version": "8.1.0-alpha.0", "description": "", "keywords": [ "storybook" diff --git a/code/lib/react-dom-shim/package.json b/code/lib/react-dom-shim/package.json index 67db8a18ccc8..ab34b8084785 100644 --- a/code/lib/react-dom-shim/package.json +++ b/code/lib/react-dom-shim/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/react-dom-shim", - "version": "8.0.0-rc.5", + "version": "8.1.0-alpha.0", "description": "", "keywords": [ "storybook" diff --git a/code/lib/router/package.json b/code/lib/router/package.json index 52934e8306b4..767d40a74d23 100644 --- a/code/lib/router/package.json +++ b/code/lib/router/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/router", - "version": "8.0.0-rc.5", + "version": "8.1.0-alpha.0", "description": "Core Storybook Router", "keywords": [ "storybook" diff --git a/code/lib/source-loader/package.json b/code/lib/source-loader/package.json index 14e5d3e46527..65ab30b64945 100644 --- a/code/lib/source-loader/package.json +++ b/code/lib/source-loader/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/source-loader", - "version": "8.0.0-rc.5", + "version": "8.1.0-alpha.0", "description": "Source loader", "keywords": [ "lib", diff --git a/code/lib/telemetry/package.json b/code/lib/telemetry/package.json index 67713dca4118..f1f12541c50f 100644 --- a/code/lib/telemetry/package.json +++ b/code/lib/telemetry/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/telemetry", - "version": "8.0.0-rc.5", + "version": "8.1.0-alpha.0", "description": "Telemetry logging for crash reports and usage statistics", "keywords": [ "storybook" diff --git a/code/lib/test/package.json b/code/lib/test/package.json index 237be906586f..6717a6912906 100644 --- a/code/lib/test/package.json +++ b/code/lib/test/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/test", - "version": "8.0.0-rc.5", + "version": "8.1.0-alpha.0", "description": "", "keywords": [ "storybook" diff --git a/code/lib/theming/package.json b/code/lib/theming/package.json index 5d8f48150adf..1f65e8cb47b5 100644 --- a/code/lib/theming/package.json +++ b/code/lib/theming/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/theming", - "version": "8.0.0-rc.5", + "version": "8.1.0-alpha.0", "description": "Core Storybook Components", "keywords": [ "storybook" diff --git a/code/lib/types/package.json b/code/lib/types/package.json index aab80d40328c..7441040beb30 100644 --- a/code/lib/types/package.json +++ b/code/lib/types/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/types", - "version": "8.0.0-rc.5", + "version": "8.1.0-alpha.0", "description": "Core Storybook TS Types", "keywords": [ "storybook" diff --git a/code/package.json b/code/package.json index 61f01e1274f8..decb2ffe484c 100644 --- a/code/package.json +++ b/code/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/root", - "version": "8.0.0-rc.5", + "version": "8.1.0-alpha.0", "private": true, "description": "Storybook root", "homepage": "https://storybook.js.org/", diff --git a/code/presets/create-react-app/package.json b/code/presets/create-react-app/package.json index 55fcc6d076e8..c4205df2cd82 100644 --- a/code/presets/create-react-app/package.json +++ b/code/presets/create-react-app/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/preset-create-react-app", - "version": "8.0.0-rc.5", + "version": "8.1.0-alpha.0", "description": "Storybook for Create React App preset", "keywords": [ "storybook" diff --git a/code/presets/html-webpack/package.json b/code/presets/html-webpack/package.json index 2eb6a823eed7..006e4420c607 100644 --- a/code/presets/html-webpack/package.json +++ b/code/presets/html-webpack/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/preset-html-webpack", - "version": "8.0.0-rc.5", + "version": "8.1.0-alpha.0", "description": "Storybook for HTML: View HTML snippets in isolation with Hot Reloading.", "keywords": [ "storybook" diff --git a/code/presets/preact-webpack/package.json b/code/presets/preact-webpack/package.json index 71606e160146..41117bd1edc6 100644 --- a/code/presets/preact-webpack/package.json +++ b/code/presets/preact-webpack/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/preset-preact-webpack", - "version": "8.0.0-rc.5", + "version": "8.1.0-alpha.0", "description": "Storybook for Preact: Develop Preact Component in isolation.", "keywords": [ "storybook" diff --git a/code/presets/react-webpack/package.json b/code/presets/react-webpack/package.json index 7db8e8ec09d4..f047c7b46f4c 100644 --- a/code/presets/react-webpack/package.json +++ b/code/presets/react-webpack/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/preset-react-webpack", - "version": "8.0.0-rc.5", + "version": "8.1.0-alpha.0", "description": "Storybook for React: Develop React Component in isolation with Hot Reloading", "keywords": [ "storybook" diff --git a/code/presets/server-webpack/package.json b/code/presets/server-webpack/package.json index a95582e8c8b9..baee5080f344 100644 --- a/code/presets/server-webpack/package.json +++ b/code/presets/server-webpack/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/preset-server-webpack", - "version": "8.0.0-rc.5", + "version": "8.1.0-alpha.0", "description": "Storybook for Server: View HTML snippets from a server in isolation with Hot Reloading.", "keywords": [ "storybook" diff --git a/code/presets/svelte-webpack/package.json b/code/presets/svelte-webpack/package.json index c11c76aab89f..a15e5e084c25 100644 --- a/code/presets/svelte-webpack/package.json +++ b/code/presets/svelte-webpack/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/preset-svelte-webpack", - "version": "8.0.0-rc.5", + "version": "8.1.0-alpha.0", "description": "Storybook for Svelte: Develop Svelte Component in isolation with Hot Reloading.", "keywords": [ "storybook" diff --git a/code/presets/vue3-webpack/package.json b/code/presets/vue3-webpack/package.json index b424bf3ed483..c1f50f0d3365 100644 --- a/code/presets/vue3-webpack/package.json +++ b/code/presets/vue3-webpack/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/preset-vue3-webpack", - "version": "8.0.0-rc.5", + "version": "8.1.0-alpha.0", "description": "Storybook for Vue 3: Develop Vue 3 Components in isolation with Hot Reloading.", "keywords": [ "storybook" diff --git a/code/renderers/html/package.json b/code/renderers/html/package.json index 18b504618783..c7cefb70c642 100644 --- a/code/renderers/html/package.json +++ b/code/renderers/html/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/html", - "version": "8.0.0-rc.5", + "version": "8.1.0-alpha.0", "description": "Storybook HTML renderer", "keywords": [ "storybook" diff --git a/code/renderers/preact/package.json b/code/renderers/preact/package.json index cd265a5f4285..fe1df6ad774b 100644 --- a/code/renderers/preact/package.json +++ b/code/renderers/preact/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/preact", - "version": "8.0.0-rc.5", + "version": "8.1.0-alpha.0", "description": "Storybook Preact renderer", "keywords": [ "storybook" diff --git a/code/renderers/react/package.json b/code/renderers/react/package.json index 065ec55a4f44..6abc64587845 100644 --- a/code/renderers/react/package.json +++ b/code/renderers/react/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/react", - "version": "8.0.0-rc.5", + "version": "8.1.0-alpha.0", "description": "Storybook React renderer", "keywords": [ "storybook" diff --git a/code/renderers/server/package.json b/code/renderers/server/package.json index 2d2b6b584266..2b0bf9a31e1f 100644 --- a/code/renderers/server/package.json +++ b/code/renderers/server/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/server", - "version": "8.0.0-rc.5", + "version": "8.1.0-alpha.0", "description": "Storybook Server renderer", "keywords": [ "storybook" diff --git a/code/renderers/svelte/package.json b/code/renderers/svelte/package.json index cedaffe33caa..d7084c890c0c 100644 --- a/code/renderers/svelte/package.json +++ b/code/renderers/svelte/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/svelte", - "version": "8.0.0-rc.5", + "version": "8.1.0-alpha.0", "description": "Storybook Svelte renderer", "keywords": [ "storybook" diff --git a/code/renderers/vue3/package.json b/code/renderers/vue3/package.json index 09d205d83f9f..875b5742a5f8 100644 --- a/code/renderers/vue3/package.json +++ b/code/renderers/vue3/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/vue3", - "version": "8.0.0-rc.5", + "version": "8.1.0-alpha.0", "description": "Storybook Vue 3 renderer", "keywords": [ "storybook" diff --git a/code/renderers/web-components/package.json b/code/renderers/web-components/package.json index 6866f00dd368..73fe293ad3e3 100644 --- a/code/renderers/web-components/package.json +++ b/code/renderers/web-components/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/web-components", - "version": "8.0.0-rc.5", + "version": "8.1.0-alpha.0", "description": "Storybook web-components renderer", "keywords": [ "lit", diff --git a/code/ui/blocks/package.json b/code/ui/blocks/package.json index dae557b18504..c32ad8074761 100644 --- a/code/ui/blocks/package.json +++ b/code/ui/blocks/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/blocks", - "version": "8.0.0-rc.5", + "version": "8.1.0-alpha.0", "description": "Storybook Doc Blocks", "keywords": [ "storybook" diff --git a/code/ui/components/package.json b/code/ui/components/package.json index cef804640bf3..0cb6cc2278d3 100644 --- a/code/ui/components/package.json +++ b/code/ui/components/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/components", - "version": "8.0.0-rc.5", + "version": "8.1.0-alpha.0", "description": "Core Storybook Components", "keywords": [ "storybook" diff --git a/code/ui/manager/package.json b/code/ui/manager/package.json index e0c45acb051c..1c2507505030 100644 --- a/code/ui/manager/package.json +++ b/code/ui/manager/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/manager", - "version": "8.0.0-rc.5", + "version": "8.1.0-alpha.0", "description": "Core Storybook UI", "keywords": [ "storybook" From ec3f7ceab62868966fb6e553344149a9fbdfb229 Mon Sep 17 00:00:00 2001 From: storybook-bot <32066757+storybook-bot@users.noreply.github.com> Date: Mon, 11 Mar 2024 15:43:53 +0000 Subject: [PATCH 132/132] Update CHANGELOG.md for v8.0.0 [skip ci] --- CHANGELOG.md | 187 ++++++++++++++++++++++++++++----------------------- 1 file changed, 102 insertions(+), 85 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 649310bf1c11..6a1978abc0d9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,20 @@ +## 8.0.0 + +#### Storybook 8.0 is here + +It brings major improvements to Storybook's feature set for testing and documentation, with strengthened framework support across React, Vue, Angular, web-components, Svelte, and more. + +- ๐Ÿฉป Built-in visual testing +- โš›๏ธ React Server Component support +- ๐ŸŽ›๏ธ Improved controls for React and Vue projects +- โšก๏ธ Improved Vite architecture, Vitest testing, and Vite 5 support +- ๐Ÿงช 2-4x faster Storybooks for testing +- โœจ Refreshed desktop UI +- ๐Ÿ“ฒ Rebuilt mobile UX +- ๐Ÿ™…โ€โ™€๏ธ No more React requirement in non-React projects + +Please checkout our [Migration Guide](https://storybook.js.org/docs/8.0/migration-guide) to upgrade from earlier versions of Storybook. To see a comprehensive list of changes that went into 8.0, you can refer to the [8.0 prerelease changelogs](https://github.com/storybookjs/storybook/blob/next/CHANGELOG.prerelease.md). + ## 7.6.17 - Addon-docs: Fix Table of Contents heading leak - [#23677](https://github.com/storybookjs/storybook/pull/23677), thanks [@vmizg](https://github.com/vmizg)! @@ -105,91 +122,91 @@ Storybook 7.6 is here with increased performance and much more! List of all updates - - Actions: Attach spies on actions across stories when defined in meta - [#24451](https://github.com/storybookjs/storybook/pull/24451), thanks [@kasperpeulen](https://github.com/kasperpeulen)! - - Actions: Fix `@storybook/core-events/preview-errors` dependency missing for Yarn PnP - [#24973](https://github.com/storybookjs/storybook/pull/24973), thanks [@JReinhold](https://github.com/JReinhold)! - - Actions: Fix missing crypto module crashing React Native - [#24546](https://github.com/storybookjs/storybook/pull/24546), thanks [@dannyhw](https://github.com/dannyhw)! - - Actions: Warn on implicit actions - [#24856](https://github.com/storybookjs/storybook/pull/24856), thanks [@kasperpeulen](https://github.com/kasperpeulen)! - - Addon A11y: Avoid CSP issue - [#24477](https://github.com/storybookjs/storybook/pull/24477), thanks [@Marklb](https://github.com/Marklb)! - - Addon: Move Visual Test addon to the code directory - [#24771](https://github.com/storybookjs/storybook/pull/24771), thanks [@cdedreuille](https://github.com/cdedreuille)! - - Addons, core: Make `react` and Storybook packages `devDependencies` where possible - [#24676](https://github.com/storybookjs/storybook/pull/24676), thanks [@JReinhold](https://github.com/JReinhold)! - - Addons, core: Make `react` and Storybook packages `devDependencies` where possible - ATTEMPT 2 - [#24834](https://github.com/storybookjs/storybook/pull/24834), thanks [@JReinhold](https://github.com/JReinhold)! - - Angular: Add source-map option to builder - [#24466](https://github.com/storybookjs/storybook/pull/24466), thanks [@valentinpalkovic](https://github.com/valentinpalkovic)! - - Angular: Handle nested module metadata - [#24798](https://github.com/storybookjs/storybook/pull/24798), thanks [@valentinpalkovic](https://github.com/valentinpalkovic)! - - Angular: Include object configured styles - [#24768](https://github.com/storybookjs/storybook/pull/24768), thanks [@valentinpalkovic](https://github.com/valentinpalkovic)! - - Babel: Update all @babel/* dependencies - [#24610](https://github.com/storybookjs/storybook/pull/24610), thanks [@valentinpalkovic](https://github.com/valentinpalkovic)! - - CLI: Add "doctor" command - [#22236](https://github.com/storybookjs/storybook/pull/22236), thanks [@yannbf](https://github.com/yannbf)! - - CLI: Add @storybook/addon-designs to non-core list - [#24507](https://github.com/storybookjs/storybook/pull/24507), thanks [@yannbf](https://github.com/yannbf)! - - CLI: Ensure errors with opening the browser are caught - [#24668](https://github.com/storybookjs/storybook/pull/24668), thanks [@xueyawei](https://github.com/xueyawei)! - - CLI: Ignore `addon-onboarding` when checking versions - [#24634](https://github.com/storybookjs/storybook/pull/24634), thanks [@JReinhold](https://github.com/JReinhold)! - - CLI: Use @storybook/test in template stories - [#24393](https://github.com/storybookjs/storybook/pull/24393), thanks [@yannbf](https://github.com/yannbf)! - - Controls: Improve accessibility of BooleanControl for screen readers - [#24418](https://github.com/storybookjs/storybook/pull/24418), thanks [@danielmarcano](https://github.com/danielmarcano)! - - Core-Server: Ignore all node_module folders for watchpack - [#24553](https://github.com/storybookjs/storybook/pull/24553), thanks [@valentinpalkovic](https://github.com/valentinpalkovic)! - - Core: Add deprecation notice for Vite + CommonJS - [#23950](https://github.com/storybookjs/storybook/pull/23950), thanks [@JReinhold](https://github.com/JReinhold)! - - Core: Detect no matching export error in storybook start and build - [#24877](https://github.com/storybookjs/storybook/pull/24877), thanks [@yannbf](https://github.com/yannbf)! - - Core: Fix `useStoryPrepared` hook failing with `undefined` data - [#22631](https://github.com/storybookjs/storybook/pull/22631), thanks [@SpookyJelly](https://github.com/SpookyJelly)! - - Core: Fix pnp support when cache dir is outside working dir - [#24572](https://github.com/storybookjs/storybook/pull/24572), thanks [@valentinpalkovic](https://github.com/valentinpalkovic)! - - Core: Fix post message channel location.search access for React Native - [#24545](https://github.com/storybookjs/storybook/pull/24545), thanks [@dannyhw](https://github.com/dannyhw)! - - Core: Gracefully handle error when parsing preview.js file - [#24858](https://github.com/storybookjs/storybook/pull/24858), thanks [@yannbf](https://github.com/yannbf)! - - Core: Make warnOnIncompatibleAddons fault-tolerant - [#24880](https://github.com/storybookjs/storybook/pull/24880), thanks [@taozhou-glean](https://github.com/taozhou-glean)! - - Dependencies: Fix Yarn 4 failing to install due to jscodeshift dependency issue - [#24914](https://github.com/storybookjs/storybook/pull/24914), thanks [@samvv](https://github.com/samvv)! - - Dependencies: Update @babel/traverse and @babel/core to fix vulnerability - [#24670](https://github.com/storybookjs/storybook/pull/24670), thanks [@valentinpalkovic](https://github.com/valentinpalkovic)! - - Dependencies: Update browserify-sign transitive dependency - [#24674](https://github.com/storybookjs/storybook/pull/24674), thanks [@valentinpalkovic](https://github.com/valentinpalkovic)! - - Dependencies: Update jscodeshift to v0.15.1 - [#24882](https://github.com/storybookjs/storybook/pull/24882), thanks [@epreston](https://github.com/epreston)! - - Dependencies: Update nx dependencies to v17 - [#24671](https://github.com/storybookjs/storybook/pull/24671), thanks [@valentinpalkovic](https://github.com/valentinpalkovic)! - - Doc Blocks: Add support for `of` prop to `Primary` block - [#23849](https://github.com/storybookjs/storybook/pull/23849), thanks [@Wilson2k](https://github.com/Wilson2k)! - - Doc Blocks: Remove `defaultProps` in `Stories` block - [#24506](https://github.com/storybookjs/storybook/pull/24506), thanks [@WouterK12](https://github.com/WouterK12)! - - Docs: Changes corresponding to docs design updates - [#24925](https://github.com/storybookjs/storybook/pull/24925), thanks [@kylegach](https://github.com/kylegach)! - - Maintenance: Split renderers preview entrypoints - [#24623](https://github.com/storybookjs/storybook/pull/24623), thanks [@ndelangen](https://github.com/ndelangen)! - - Manager: Update `store.settings.lastTrackedStoryId` - [#24115](https://github.com/storybookjs/storybook/pull/24115), thanks [@rashidshamloo](https://github.com/rashidshamloo)! - - ManagerAPI: Fix setting status without index, crashes storybook - [#24866](https://github.com/storybookjs/storybook/pull/24866), thanks [@ndelangen](https://github.com/ndelangen)! - - ManagerBuilder: Fix `"type": "commonjs"` compatibility - [#24534](https://github.com/storybookjs/storybook/pull/24534), thanks [@ndelangen](https://github.com/ndelangen)! - - Next.js: Add avif support - [#24611](https://github.com/storybookjs/storybook/pull/24611), thanks [@valentinpalkovic](https://github.com/valentinpalkovic)! - - Next.js: Add back image context CommonJS export - [#24885](https://github.com/storybookjs/storybook/pull/24885), thanks [@martinnabhan](https://github.com/martinnabhan)! - - Next.js: Add experimental SWC support - [#24852](https://github.com/storybookjs/storybook/pull/24852), thanks [@valentinpalkovic](https://github.com/valentinpalkovic)! - - Next.js: Fix Fast Refresh config for SWC mode - [#24991](https://github.com/storybookjs/storybook/pull/24991), thanks [@valentinpalkovic](https://github.com/valentinpalkovic)! - - Next.js: Fix forwarding ref for Image component - [#24648](https://github.com/storybookjs/storybook/pull/24648), thanks [@valentinpalkovic](https://github.com/valentinpalkovic)! - - Next.js: Fix import path in swc loader - [#24922](https://github.com/storybookjs/storybook/pull/24922), thanks [@valentinpalkovic](https://github.com/valentinpalkovic)! - - Next.js: Fix react-docgen usage with preset-env settings - [#24993](https://github.com/storybookjs/storybook/pull/24993), thanks [@valentinpalkovic](https://github.com/valentinpalkovic)! - - Next.js: Remove duplicate Fast Refresh plugin init - [#24963](https://github.com/storybookjs/storybook/pull/24963), thanks [@valentinpalkovic](https://github.com/valentinpalkovic)! - - React: Upgrade `react-docgen` to v7 - [#24530](https://github.com/storybookjs/storybook/pull/24530), thanks [@shilman](https://github.com/shilman)! - - ReactNative: Fix missing assert dep in docs-tools - [#24732](https://github.com/storybookjs/storybook/pull/24732), thanks [@dannyhw](https://github.com/dannyhw)! - - Svelte: Fix decorators always running twice - [#24921](https://github.com/storybookjs/storybook/pull/24921), thanks [@paoloricciuti](https://github.com/paoloricciuti)! - - Svelte: Fix source with decorators always showing the `SlotDecorator` component - [#24800](https://github.com/storybookjs/storybook/pull/24800), thanks [@JReinhold](https://github.com/JReinhold)! - - SvelteKit: Add experimental page and navigation mocking - [#24795](https://github.com/storybookjs/storybook/pull/24795), thanks [@paoloricciuti](https://github.com/paoloricciuti)! - - SvelteKit: Default to log an action for `goto`, `invalidate` and `invalidateAll` - [#24955](https://github.com/storybookjs/storybook/pull/24955), thanks [@paoloricciuti](https://github.com/paoloricciuti)! - - SWC: Add settings for react and preact - [#24805](https://github.com/storybookjs/storybook/pull/24805), thanks [@valentinpalkovic](https://github.com/valentinpalkovic)! - - Test Build: Add env-variable support to `--test` CLI-flag - [#24862](https://github.com/storybookjs/storybook/pull/24862), thanks [@ndelangen](https://github.com/ndelangen)! - - Test Build: Add tests and rename to camelCase - [#24911](https://github.com/storybookjs/storybook/pull/24911), thanks [@ndelangen](https://github.com/ndelangen)! - - Test Build: Disable composition when `--test` is `true` - [#24799](https://github.com/storybookjs/storybook/pull/24799), thanks [@ndelangen](https://github.com/ndelangen)! - - Test Build: Disable docs related stuff for test builds - [#24691](https://github.com/storybookjs/storybook/pull/24691), thanks [@ndelangen](https://github.com/ndelangen)! - - Test Build: Disable telemetry for test builds - [#24706](https://github.com/storybookjs/storybook/pull/24706), thanks [@kasperpeulen](https://github.com/kasperpeulen)! - - Test Build: Disable warnOnIncompatibleAddons - [#24797](https://github.com/storybookjs/storybook/pull/24797), thanks [@ndelangen](https://github.com/ndelangen)! - - Test Build: Filter out addon-docs from essentials in the test build - [#24994](https://github.com/storybookjs/storybook/pull/24994), thanks [@kasperpeulen](https://github.com/kasperpeulen)! - - Test Build: Fix disabledAddons filter - [#24924](https://github.com/storybookjs/storybook/pull/24924), thanks [@IanVS](https://github.com/IanVS)! - - Test Build: Fix indexer bug - [#24890](https://github.com/storybookjs/storybook/pull/24890), thanks [@ndelangen](https://github.com/ndelangen)! - - Test Build: Globalize `@storybook/blocks` if `build.test.emptyBlocks` is `true` - [#24650](https://github.com/storybookjs/storybook/pull/24650), thanks [@ndelangen](https://github.com/ndelangen)! - - Test Build: Implement builder options for test build - [#24826](https://github.com/storybookjs/storybook/pull/24826), thanks [@kasperpeulen](https://github.com/kasperpeulen)! - - Test Build: Improve config loading & naming - [#24837](https://github.com/storybookjs/storybook/pull/24837), thanks [@ndelangen](https://github.com/ndelangen)! - - Test Build: No sourcemaps for test builds - [#24804](https://github.com/storybookjs/storybook/pull/24804), thanks [@ndelangen](https://github.com/ndelangen)! - - Test Build: Revert defaulting to SWC in test build, but keep using esbuild for minification - [#24843](https://github.com/storybookjs/storybook/pull/24843), thanks [@kasperpeulen](https://github.com/kasperpeulen)! - - Test: Create @storybook/test package based on vitest - [#24392](https://github.com/storybookjs/storybook/pull/24392), thanks [@kasperpeulen](https://github.com/kasperpeulen)! - - Test: Don\'t attach action to function mock if action was added already - [#24966](https://github.com/storybookjs/storybook/pull/24966), thanks [@tmeasday](https://github.com/tmeasday)! - - Test: Model loaders as before each and restore mocks properly - [#24948](https://github.com/storybookjs/storybook/pull/24948), thanks [@kasperpeulen](https://github.com/kasperpeulen)! - - Theming: Add theme variable to set the preview background color - [#24575](https://github.com/storybookjs/storybook/pull/24575), thanks [@JReinhold](https://github.com/JReinhold)! - - Typescript: Add \'skipCompiler\' option to TypeScript presets - [#24847](https://github.com/storybookjs/storybook/pull/24847), thanks [@valentinpalkovic](https://github.com/valentinpalkovic)! - - UI: Fix horizontal scroll bar in Canvas hidden by styling - [#24408](https://github.com/storybookjs/storybook/pull/24408), thanks [@yoshi2no](https://github.com/yoshi2no)! - - UI: improve A11Y remove redundant styling rules, update icon color - [#24402](https://github.com/storybookjs/storybook/pull/24402), thanks [@tolkadot](https://github.com/tolkadot)! - - UI: Logo fixed value - [#24726](https://github.com/storybookjs/storybook/pull/24726), thanks [@black-arm](https://github.com/black-arm)! - - UI: Update zIndex on NotificationList to fix the notification not being clickable in certain cases - [#24602](https://github.com/storybookjs/storybook/pull/24602), thanks [@yoshi2no](https://github.com/yoshi2no)! - - Viewport: Add newer device viewports - [#24777](https://github.com/storybookjs/storybook/pull/24777), thanks [@Tomo5524](https://github.com/Tomo5524)! - - Vite: Prevent non-deterministic build output - [#24833](https://github.com/storybookjs/storybook/pull/24833), thanks [@henkerik](https://github.com/henkerik)! - - Webpack: Add export-order-loader and remove babel-plugin-named-exports-order - [#24749](https://github.com/storybookjs/storybook/pull/24749), thanks [@valentinpalkovic](https://github.com/valentinpalkovic)! - - Webpack: Add react-docgen loader and remove babel-plugin-react-docgen - [#24762](https://github.com/storybookjs/storybook/pull/24762), thanks [@valentinpalkovic](https://github.com/valentinpalkovic)! - - Webpack: Fix race condition for export-order loader - [#24817](https://github.com/storybookjs/storybook/pull/24817), thanks [@valentinpalkovic](https://github.com/valentinpalkovic)! - - Webpack: Hide critical dependency warning - [#24784](https://github.com/storybookjs/storybook/pull/24784), thanks [@valentinpalkovic](https://github.com/valentinpalkovic)! - - Webpack: Only load babel config when babel-loader is used - [#25002](https://github.com/storybookjs/storybook/pull/25002), thanks [@valentinpalkovic](https://github.com/valentinpalkovic)! - - Webpack: Resolve circular dependency and fix HMR - [#24974](https://github.com/storybookjs/storybook/pull/24974), thanks [@valentinpalkovic](https://github.com/valentinpalkovic)! - +- Actions: Attach spies on actions across stories when defined in meta - [#24451](https://github.com/storybookjs/storybook/pull/24451), thanks [@kasperpeulen](https://github.com/kasperpeulen)! +- Actions: Fix `@storybook/core-events/preview-errors` dependency missing for Yarn PnP - [#24973](https://github.com/storybookjs/storybook/pull/24973), thanks [@JReinhold](https://github.com/JReinhold)! +- Actions: Fix missing crypto module crashing React Native - [#24546](https://github.com/storybookjs/storybook/pull/24546), thanks [@dannyhw](https://github.com/dannyhw)! +- Actions: Warn on implicit actions - [#24856](https://github.com/storybookjs/storybook/pull/24856), thanks [@kasperpeulen](https://github.com/kasperpeulen)! +- Addon A11y: Avoid CSP issue - [#24477](https://github.com/storybookjs/storybook/pull/24477), thanks [@Marklb](https://github.com/Marklb)! +- Addon: Move Visual Test addon to the code directory - [#24771](https://github.com/storybookjs/storybook/pull/24771), thanks [@cdedreuille](https://github.com/cdedreuille)! +- Addons, core: Make `react` and Storybook packages `devDependencies` where possible - [#24676](https://github.com/storybookjs/storybook/pull/24676), thanks [@JReinhold](https://github.com/JReinhold)! +- Addons, core: Make `react` and Storybook packages `devDependencies` where possible - ATTEMPT 2 - [#24834](https://github.com/storybookjs/storybook/pull/24834), thanks [@JReinhold](https://github.com/JReinhold)! +- Angular: Add source-map option to builder - [#24466](https://github.com/storybookjs/storybook/pull/24466), thanks [@valentinpalkovic](https://github.com/valentinpalkovic)! +- Angular: Handle nested module metadata - [#24798](https://github.com/storybookjs/storybook/pull/24798), thanks [@valentinpalkovic](https://github.com/valentinpalkovic)! +- Angular: Include object configured styles - [#24768](https://github.com/storybookjs/storybook/pull/24768), thanks [@valentinpalkovic](https://github.com/valentinpalkovic)! +- Babel: Update all @babel/\* dependencies - [#24610](https://github.com/storybookjs/storybook/pull/24610), thanks [@valentinpalkovic](https://github.com/valentinpalkovic)! +- CLI: Add "doctor" command - [#22236](https://github.com/storybookjs/storybook/pull/22236), thanks [@yannbf](https://github.com/yannbf)! +- CLI: Add @storybook/addon-designs to non-core list - [#24507](https://github.com/storybookjs/storybook/pull/24507), thanks [@yannbf](https://github.com/yannbf)! +- CLI: Ensure errors with opening the browser are caught - [#24668](https://github.com/storybookjs/storybook/pull/24668), thanks [@xueyawei](https://github.com/xueyawei)! +- CLI: Ignore `addon-onboarding` when checking versions - [#24634](https://github.com/storybookjs/storybook/pull/24634), thanks [@JReinhold](https://github.com/JReinhold)! +- CLI: Use @storybook/test in template stories - [#24393](https://github.com/storybookjs/storybook/pull/24393), thanks [@yannbf](https://github.com/yannbf)! +- Controls: Improve accessibility of BooleanControl for screen readers - [#24418](https://github.com/storybookjs/storybook/pull/24418), thanks [@danielmarcano](https://github.com/danielmarcano)! +- Core-Server: Ignore all node_module folders for watchpack - [#24553](https://github.com/storybookjs/storybook/pull/24553), thanks [@valentinpalkovic](https://github.com/valentinpalkovic)! +- Core: Add deprecation notice for Vite + CommonJS - [#23950](https://github.com/storybookjs/storybook/pull/23950), thanks [@JReinhold](https://github.com/JReinhold)! +- Core: Detect no matching export error in storybook start and build - [#24877](https://github.com/storybookjs/storybook/pull/24877), thanks [@yannbf](https://github.com/yannbf)! +- Core: Fix `useStoryPrepared` hook failing with `undefined` data - [#22631](https://github.com/storybookjs/storybook/pull/22631), thanks [@SpookyJelly](https://github.com/SpookyJelly)! +- Core: Fix pnp support when cache dir is outside working dir - [#24572](https://github.com/storybookjs/storybook/pull/24572), thanks [@valentinpalkovic](https://github.com/valentinpalkovic)! +- Core: Fix post message channel location.search access for React Native - [#24545](https://github.com/storybookjs/storybook/pull/24545), thanks [@dannyhw](https://github.com/dannyhw)! +- Core: Gracefully handle error when parsing preview.js file - [#24858](https://github.com/storybookjs/storybook/pull/24858), thanks [@yannbf](https://github.com/yannbf)! +- Core: Make warnOnIncompatibleAddons fault-tolerant - [#24880](https://github.com/storybookjs/storybook/pull/24880), thanks [@taozhou-glean](https://github.com/taozhou-glean)! +- Dependencies: Fix Yarn 4 failing to install due to jscodeshift dependency issue - [#24914](https://github.com/storybookjs/storybook/pull/24914), thanks [@samvv](https://github.com/samvv)! +- Dependencies: Update @babel/traverse and @babel/core to fix vulnerability - [#24670](https://github.com/storybookjs/storybook/pull/24670), thanks [@valentinpalkovic](https://github.com/valentinpalkovic)! +- Dependencies: Update browserify-sign transitive dependency - [#24674](https://github.com/storybookjs/storybook/pull/24674), thanks [@valentinpalkovic](https://github.com/valentinpalkovic)! +- Dependencies: Update jscodeshift to v0.15.1 - [#24882](https://github.com/storybookjs/storybook/pull/24882), thanks [@epreston](https://github.com/epreston)! +- Dependencies: Update nx dependencies to v17 - [#24671](https://github.com/storybookjs/storybook/pull/24671), thanks [@valentinpalkovic](https://github.com/valentinpalkovic)! +- Doc Blocks: Add support for `of` prop to `Primary` block - [#23849](https://github.com/storybookjs/storybook/pull/23849), thanks [@Wilson2k](https://github.com/Wilson2k)! +- Doc Blocks: Remove `defaultProps` in `Stories` block - [#24506](https://github.com/storybookjs/storybook/pull/24506), thanks [@WouterK12](https://github.com/WouterK12)! +- Docs: Changes corresponding to docs design updates - [#24925](https://github.com/storybookjs/storybook/pull/24925), thanks [@kylegach](https://github.com/kylegach)! +- Maintenance: Split renderers preview entrypoints - [#24623](https://github.com/storybookjs/storybook/pull/24623), thanks [@ndelangen](https://github.com/ndelangen)! +- Manager: Update `store.settings.lastTrackedStoryId` - [#24115](https://github.com/storybookjs/storybook/pull/24115), thanks [@rashidshamloo](https://github.com/rashidshamloo)! +- ManagerAPI: Fix setting status without index, crashes storybook - [#24866](https://github.com/storybookjs/storybook/pull/24866), thanks [@ndelangen](https://github.com/ndelangen)! +- ManagerBuilder: Fix `"type": "commonjs"` compatibility - [#24534](https://github.com/storybookjs/storybook/pull/24534), thanks [@ndelangen](https://github.com/ndelangen)! +- Next.js: Add avif support - [#24611](https://github.com/storybookjs/storybook/pull/24611), thanks [@valentinpalkovic](https://github.com/valentinpalkovic)! +- Next.js: Add back image context CommonJS export - [#24885](https://github.com/storybookjs/storybook/pull/24885), thanks [@martinnabhan](https://github.com/martinnabhan)! +- Next.js: Add experimental SWC support - [#24852](https://github.com/storybookjs/storybook/pull/24852), thanks [@valentinpalkovic](https://github.com/valentinpalkovic)! +- Next.js: Fix Fast Refresh config for SWC mode - [#24991](https://github.com/storybookjs/storybook/pull/24991), thanks [@valentinpalkovic](https://github.com/valentinpalkovic)! +- Next.js: Fix forwarding ref for Image component - [#24648](https://github.com/storybookjs/storybook/pull/24648), thanks [@valentinpalkovic](https://github.com/valentinpalkovic)! +- Next.js: Fix import path in swc loader - [#24922](https://github.com/storybookjs/storybook/pull/24922), thanks [@valentinpalkovic](https://github.com/valentinpalkovic)! +- Next.js: Fix react-docgen usage with preset-env settings - [#24993](https://github.com/storybookjs/storybook/pull/24993), thanks [@valentinpalkovic](https://github.com/valentinpalkovic)! +- Next.js: Remove duplicate Fast Refresh plugin init - [#24963](https://github.com/storybookjs/storybook/pull/24963), thanks [@valentinpalkovic](https://github.com/valentinpalkovic)! +- React: Upgrade `react-docgen` to v7 - [#24530](https://github.com/storybookjs/storybook/pull/24530), thanks [@shilman](https://github.com/shilman)! +- ReactNative: Fix missing assert dep in docs-tools - [#24732](https://github.com/storybookjs/storybook/pull/24732), thanks [@dannyhw](https://github.com/dannyhw)! +- Svelte: Fix decorators always running twice - [#24921](https://github.com/storybookjs/storybook/pull/24921), thanks [@paoloricciuti](https://github.com/paoloricciuti)! +- Svelte: Fix source with decorators always showing the `SlotDecorator` component - [#24800](https://github.com/storybookjs/storybook/pull/24800), thanks [@JReinhold](https://github.com/JReinhold)! +- SvelteKit: Add experimental page and navigation mocking - [#24795](https://github.com/storybookjs/storybook/pull/24795), thanks [@paoloricciuti](https://github.com/paoloricciuti)! +- SvelteKit: Default to log an action for `goto`, `invalidate` and `invalidateAll` - [#24955](https://github.com/storybookjs/storybook/pull/24955), thanks [@paoloricciuti](https://github.com/paoloricciuti)! +- SWC: Add settings for react and preact - [#24805](https://github.com/storybookjs/storybook/pull/24805), thanks [@valentinpalkovic](https://github.com/valentinpalkovic)! +- Test Build: Add env-variable support to `--test` CLI-flag - [#24862](https://github.com/storybookjs/storybook/pull/24862), thanks [@ndelangen](https://github.com/ndelangen)! +- Test Build: Add tests and rename to camelCase - [#24911](https://github.com/storybookjs/storybook/pull/24911), thanks [@ndelangen](https://github.com/ndelangen)! +- Test Build: Disable composition when `--test` is `true` - [#24799](https://github.com/storybookjs/storybook/pull/24799), thanks [@ndelangen](https://github.com/ndelangen)! +- Test Build: Disable docs related stuff for test builds - [#24691](https://github.com/storybookjs/storybook/pull/24691), thanks [@ndelangen](https://github.com/ndelangen)! +- Test Build: Disable telemetry for test builds - [#24706](https://github.com/storybookjs/storybook/pull/24706), thanks [@kasperpeulen](https://github.com/kasperpeulen)! +- Test Build: Disable warnOnIncompatibleAddons - [#24797](https://github.com/storybookjs/storybook/pull/24797), thanks [@ndelangen](https://github.com/ndelangen)! +- Test Build: Filter out addon-docs from essentials in the test build - [#24994](https://github.com/storybookjs/storybook/pull/24994), thanks [@kasperpeulen](https://github.com/kasperpeulen)! +- Test Build: Fix disabledAddons filter - [#24924](https://github.com/storybookjs/storybook/pull/24924), thanks [@IanVS](https://github.com/IanVS)! +- Test Build: Fix indexer bug - [#24890](https://github.com/storybookjs/storybook/pull/24890), thanks [@ndelangen](https://github.com/ndelangen)! +- Test Build: Globalize `@storybook/blocks` if `build.test.emptyBlocks` is `true` - [#24650](https://github.com/storybookjs/storybook/pull/24650), thanks [@ndelangen](https://github.com/ndelangen)! +- Test Build: Implement builder options for test build - [#24826](https://github.com/storybookjs/storybook/pull/24826), thanks [@kasperpeulen](https://github.com/kasperpeulen)! +- Test Build: Improve config loading & naming - [#24837](https://github.com/storybookjs/storybook/pull/24837), thanks [@ndelangen](https://github.com/ndelangen)! +- Test Build: No sourcemaps for test builds - [#24804](https://github.com/storybookjs/storybook/pull/24804), thanks [@ndelangen](https://github.com/ndelangen)! +- Test Build: Revert defaulting to SWC in test build, but keep using esbuild for minification - [#24843](https://github.com/storybookjs/storybook/pull/24843), thanks [@kasperpeulen](https://github.com/kasperpeulen)! +- Test: Create @storybook/test package based on vitest - [#24392](https://github.com/storybookjs/storybook/pull/24392), thanks [@kasperpeulen](https://github.com/kasperpeulen)! +- Test: Don\'t attach action to function mock if action was added already - [#24966](https://github.com/storybookjs/storybook/pull/24966), thanks [@tmeasday](https://github.com/tmeasday)! +- Test: Model loaders as before each and restore mocks properly - [#24948](https://github.com/storybookjs/storybook/pull/24948), thanks [@kasperpeulen](https://github.com/kasperpeulen)! +- Theming: Add theme variable to set the preview background color - [#24575](https://github.com/storybookjs/storybook/pull/24575), thanks [@JReinhold](https://github.com/JReinhold)! +- Typescript: Add \'skipCompiler\' option to TypeScript presets - [#24847](https://github.com/storybookjs/storybook/pull/24847), thanks [@valentinpalkovic](https://github.com/valentinpalkovic)! +- UI: Fix horizontal scroll bar in Canvas hidden by styling - [#24408](https://github.com/storybookjs/storybook/pull/24408), thanks [@yoshi2no](https://github.com/yoshi2no)! +- UI: improve A11Y remove redundant styling rules, update icon color - [#24402](https://github.com/storybookjs/storybook/pull/24402), thanks [@tolkadot](https://github.com/tolkadot)! +- UI: Logo fixed value - [#24726](https://github.com/storybookjs/storybook/pull/24726), thanks [@black-arm](https://github.com/black-arm)! +- UI: Update zIndex on NotificationList to fix the notification not being clickable in certain cases - [#24602](https://github.com/storybookjs/storybook/pull/24602), thanks [@yoshi2no](https://github.com/yoshi2no)! +- Viewport: Add newer device viewports - [#24777](https://github.com/storybookjs/storybook/pull/24777), thanks [@Tomo5524](https://github.com/Tomo5524)! +- Vite: Prevent non-deterministic build output - [#24833](https://github.com/storybookjs/storybook/pull/24833), thanks [@henkerik](https://github.com/henkerik)! +- Webpack: Add export-order-loader and remove babel-plugin-named-exports-order - [#24749](https://github.com/storybookjs/storybook/pull/24749), thanks [@valentinpalkovic](https://github.com/valentinpalkovic)! +- Webpack: Add react-docgen loader and remove babel-plugin-react-docgen - [#24762](https://github.com/storybookjs/storybook/pull/24762), thanks [@valentinpalkovic](https://github.com/valentinpalkovic)! +- Webpack: Fix race condition for export-order loader - [#24817](https://github.com/storybookjs/storybook/pull/24817), thanks [@valentinpalkovic](https://github.com/valentinpalkovic)! +- Webpack: Hide critical dependency warning - [#24784](https://github.com/storybookjs/storybook/pull/24784), thanks [@valentinpalkovic](https://github.com/valentinpalkovic)! +- Webpack: Only load babel config when babel-loader is used - [#25002](https://github.com/storybookjs/storybook/pull/25002), thanks [@valentinpalkovic](https://github.com/valentinpalkovic)! +- Webpack: Resolve circular dependency and fix HMR - [#24974](https://github.com/storybookjs/storybook/pull/24974), thanks [@valentinpalkovic](https://github.com/valentinpalkovic)! + ## 7.5.2

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 ZWJlcj%k39I1heM&QPbaZkDR~$e*mj+1l0fl literal 0 HcmV?d00001 diff --git a/docs/get-started/vue-component-meta-slot-types-controls.png b/docs/get-started/vue-component-meta-slot-types-controls.png new file mode 100644 index 0000000000000000000000000000000000000000..9a451963ce6e0957e52c2bd06736b60097c78bd9 GIT binary patch literal 99119 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