mirror of
https://github.com/storybookjs/storybook.git
synced 2025-04-08 11:11:53 +08:00
Merge branch 'next' into fix/stats-json-in-angular-executor
This commit is contained in:
commit
30293dd3de
25
.github/PULL_REQUEST_TEMPLATE.md
vendored
25
.github/PULL_REQUEST_TEMPLATE.md
vendored
@ -19,6 +19,7 @@ Thank you for contributing to Storybook! Please submit all PRs to the `next` bra
|
||||
<!-- Please check (put an "x" inside the "[ ]") the applicable items below to communicate how to test your changes -->
|
||||
|
||||
#### The changes in this PR are covered in the following automated tests:
|
||||
|
||||
- [ ] stories
|
||||
- [ ] unit tests
|
||||
- [ ] integration tests
|
||||
@ -46,21 +47,21 @@ _This section is mandatory for all contributions. If you believe no manual test
|
||||
|
||||
## Checklist for Maintainers
|
||||
|
||||
- [ ] When this PR is ready for testing, make sure to add `ci:normal`, `ci:merged` or `ci:daily` GH label to it to run a specific set of sandboxes. The particular set of sandboxes can be found in `code/lib/cli/src/sandbox-templates.ts`
|
||||
- [ ] When this PR is ready for testing, make sure to add `ci:normal`, `ci:merged` or `ci:daily` GH label to it to run a specific set of sandboxes. The particular set of sandboxes can be found in `code/lib/cli-storybook/src/sandbox-templates.ts`
|
||||
- [ ] Make sure this PR contains **one** of the labels below:
|
||||
<details>
|
||||
<summary>Available labels</summary>
|
||||
|
||||
- `bug`: Internal changes that fixes incorrect behavior.
|
||||
- `maintenance`: User-facing maintenance tasks.
|
||||
- `dependencies`: Upgrading (sometimes downgrading) dependencies.
|
||||
- `build`: Internal-facing build tooling & test updates. Will not show up in release changelog.
|
||||
- `cleanup`: Minor cleanup style change. Will not show up in release changelog.
|
||||
- `documentation`: Documentation **only** changes. Will not show up in release changelog.
|
||||
- `feature request`: Introducing a new feature.
|
||||
- `BREAKING CHANGE`: Changes that break compatibility in some way with current major version.
|
||||
- `other`: Changes that don't fit in the above categories.
|
||||
|
||||
- `bug`: Internal changes that fixes incorrect behavior.
|
||||
- `maintenance`: User-facing maintenance tasks.
|
||||
- `dependencies`: Upgrading (sometimes downgrading) dependencies.
|
||||
- `build`: Internal-facing build tooling & test updates. Will not show up in release changelog.
|
||||
- `cleanup`: Minor cleanup style change. Will not show up in release changelog.
|
||||
- `documentation`: Documentation **only** changes. Will not show up in release changelog.
|
||||
- `feature request`: Introducing a new feature.
|
||||
- `BREAKING CHANGE`: Changes that break compatibility in some way with current major version.
|
||||
- `other`: Changes that don't fit in the above categories.
|
||||
|
||||
</details>
|
||||
|
||||
### 🦋 Canary release
|
||||
@ -74,4 +75,4 @@ _core team members can create a canary release [here](https://github.com/storybo
|
||||
<!-- CANARY_RELEASE_SECTION -->
|
||||
|
||||
<!-- BENCHMARK_SECTION -->
|
||||
<!-- BENCHMARK_SECTION -->
|
||||
<!-- BENCHMARK_SECTION -->
|
||||
|
72
CHANGELOG.md
72
CHANGELOG.md
@ -1,3 +1,75 @@
|
||||
## 8.4.1
|
||||
|
||||
- Core: Relax peer dep constraint of shim packages - [#29503](https://github.com/storybookjs/storybook/pull/29503), thanks @kasperpeulen!
|
||||
|
||||
## 8.4.0
|
||||
|
||||
Storybook 8.4 comes with a ton of exciting new features designed to give you the best experience developing, testing, and debugging tests in the browser!
|
||||
|
||||
- ▶️ **Unified UI** for component testing
|
||||
- 5️⃣ **Svelte 5** and Svelte CSF support
|
||||
- ⚛️ **React Native Storybook 8** release
|
||||
- 🏷️ **Tags-based filtering** to organize your Storybook
|
||||
- 🫧 **Dependency cleanup** to reduce install footprint
|
||||
- 💯 **Hundreds** more improvements
|
||||
|
||||
<details>
|
||||
<summary>List of all updates</summary>
|
||||
|
||||
- Addon Test: Adjust file exports to be ESM/CJS compatible - [#29471](https://github.com/storybookjs/storybook/pull/29471), thanks @valentinpalkovic!
|
||||
- Addon Test: Error when addon interactions exists - [#29434](https://github.com/storybookjs/storybook/pull/29434), thanks @valentinpalkovic!
|
||||
- Addon Test: Escape XML when converting ANSI to HTML in test errors - [#29446](https://github.com/storybookjs/storybook/pull/29446), thanks @ghengeveld!
|
||||
- Addon Test: Fix hiding stacktrace for assertion errors in test panel - [#29458](https://github.com/storybookjs/storybook/pull/29458), thanks @ghengeveld!
|
||||
- Addon Test: Improve Error Handling - [#29476](https://github.com/storybookjs/storybook/pull/29476), thanks @valentinpalkovic!
|
||||
- Addon Test: Improve postinstall script - [#29479](https://github.com/storybookjs/storybook/pull/29479), thanks @yannbf!
|
||||
- Addon Test: Improve unsupported vitest message - [#29486](https://github.com/storybookjs/storybook/pull/29486), thanks @valentinpalkovic!
|
||||
- Addon Test: Only register testing module in Vite projects - [#29472](https://github.com/storybookjs/storybook/pull/29472), thanks @yannbf!
|
||||
- Addon Test: Throttle Vitest progress updates more heavily - [#29482](https://github.com/storybookjs/storybook/pull/29482), thanks @ghengeveld!
|
||||
- Addon-docs, blocks: Prebundle dependencies - [#29301](https://github.com/storybookjs/storybook/pull/29301), thanks @JReinhold!
|
||||
- Addon-Test: Support for `@vitest/browser` v2.1.2 - [#29407](https://github.com/storybookjs/storybook/pull/29407), thanks @strozw!
|
||||
- Blocks: Prebundle `es-toolkit` - [#29259](https://github.com/storybookjs/storybook/pull/29259), thanks @JReinhold!
|
||||
- Builder-vite: Replace .at() call with [] in codegen - [#29048](https://github.com/storybookjs/storybook/pull/29048), thanks @Chudesnov!
|
||||
- CLI: Don't add `@storybook/addon-links` by default - [#29177](https://github.com/storybookjs/storybook/pull/29177), thanks @tobiasdiez!
|
||||
- CLI: Ensure `.gitignore` updated via CLI ends with a newline - [#29124](https://github.com/storybookjs/storybook/pull/29124), thanks @3w36zj6!
|
||||
- CLI: Fix `yarn` detection - [#29448](https://github.com/storybookjs/storybook/pull/29448), thanks @ndelangen!
|
||||
- CLI: Migrate from `chalk` to `picocolors` - [#28262](https://github.com/storybookjs/storybook/pull/28262), thanks @43081j!
|
||||
- CLI: Refactor NPMProxy error parsing logic - [#29459](https://github.com/storybookjs/storybook/pull/29459), thanks @yannbf!
|
||||
- ConfigFile: Fix `export { X }` parsing - [#29344](https://github.com/storybookjs/storybook/pull/29344), thanks @vctqs1!
|
||||
- Core: Add unified UI Testing Module - [#29241](https://github.com/storybookjs/storybook/pull/29241), thanks @yannbf!
|
||||
- Core: Close story status menu when selecting an item - [#29455](https://github.com/storybookjs/storybook/pull/29455), thanks @ghengeveld!
|
||||
- Core: Fix building Storybook deleting project root files - [#29371](https://github.com/storybookjs/storybook/pull/29371), thanks @JReinhold!
|
||||
- Core: Fix race condition during empty folder init - [#29490](https://github.com/storybookjs/storybook/pull/29490), thanks @valentinpalkovic!
|
||||
- Core: Make `prettier` an optional peer dependency - [#29223](https://github.com/storybookjs/storybook/pull/29223), thanks @JReinhold!
|
||||
- Core: Migrate from `express` to `polka` - [#29230](https://github.com/storybookjs/storybook/pull/29230), thanks @43081j!
|
||||
- Core: Migrate from `qs` to `picoquery` - [#28315](https://github.com/storybookjs/storybook/pull/28315), thanks @43081j!
|
||||
- Core: Open 'Component tests' addon panel when clicking a story status - [#29456](https://github.com/storybookjs/storybook/pull/29456), thanks @ghengeveld!
|
||||
- Core: Remove `handlebars` usage - [#29208](https://github.com/storybookjs/storybook/pull/29208), thanks @ndelangen!
|
||||
- Core: Remove dependence on `file-system-cache` - [#29256](https://github.com/storybookjs/storybook/pull/29256), thanks @ndelangen!
|
||||
- Core: Replace `fs-extra` with the native APIs - [#29126](https://github.com/storybookjs/storybook/pull/29126), thanks @ziebam!
|
||||
- Core: Replace `lodash` with `es-toolkit` - [#28981](https://github.com/storybookjs/storybook/pull/28981), thanks @ndelangen!
|
||||
- Core: Show checkmark icon in story status dropdown and update status label for component tests - [#29451](https://github.com/storybookjs/storybook/pull/29451), thanks @ghengeveld!
|
||||
- Core: Show tooltip on filter toggles to clarify their purpose - [#29447](https://github.com/storybookjs/storybook/pull/29447), thanks @ghengeveld!
|
||||
- Core: Track test provider state in sessionStorage - [#29450](https://github.com/storybookjs/storybook/pull/29450), thanks @ghengeveld!
|
||||
- Core: Upgrade `esbuild`, broadening version range - [#29254](https://github.com/storybookjs/storybook/pull/29254), thanks @ndelangen!
|
||||
- Dependencies: Upgrade VTA to v3.1.0 - [#29449](https://github.com/storybookjs/storybook/pull/29449), thanks @ghengeveld!
|
||||
- Dependencies: Upgrade VTA to v3.2.0 to resolve peerDep conflict - [#29461](https://github.com/storybookjs/storybook/pull/29461), thanks @ghengeveld!
|
||||
- Interactions: Escape xml of interactions errors - [#29414](https://github.com/storybookjs/storybook/pull/29414), thanks @kasperpeulen!
|
||||
- Maintenance: Fix broken and outdated documentation links - [#29412](https://github.com/storybookjs/storybook/pull/29412), thanks @jonniebigodes!
|
||||
- Manager: Add tags property to ComponentEntry objects - [#29343](https://github.com/storybookjs/storybook/pull/29343), thanks @Sidnioulz!
|
||||
- React: Prebundle all of `renderers/react`'s dependencies - [#29298](https://github.com/storybookjs/storybook/pull/29298), thanks @ndelangen!
|
||||
- Svelte: Improve argTypes inference with `svelte2tsx` - support runes - [#29423](https://github.com/storybookjs/storybook/pull/29423), thanks @JReinhold!
|
||||
- Test: Remove unused `util` dependency - [#29310](https://github.com/storybookjs/storybook/pull/29310), thanks @JReinhold!
|
||||
- UI: Brand image css class conflict causes image to resize on hot reloads - [#29129](https://github.com/storybookjs/storybook/pull/29129), thanks @ShreySinha02!
|
||||
- UI: Fix RefIndicator to use CheckIcon instead of string - [#29209](https://github.com/storybookjs/storybook/pull/29209), thanks @JSMike!
|
||||
- UI: Simple tag filtering - [#29333](https://github.com/storybookjs/storybook/pull/29333), thanks @shilman!
|
||||
- UI: Use production-mode `react` in manager - [#29197](https://github.com/storybookjs/storybook/pull/29197), thanks @ndelangen!
|
||||
- Viewport-addon: Add InitialViewportKeys type to viewport addon - [#29182](https://github.com/storybookjs/storybook/pull/29182), thanks @hyeongrok7874!
|
||||
- Vite: Add jsdoc-type-pratt-parser to `optimizeDeps` - [#29179](https://github.com/storybookjs/storybook/pull/29179), thanks @tobiasdiez!
|
||||
- Vite: Cleanup and prebundle dependencies - [#29302](https://github.com/storybookjs/storybook/pull/29302), thanks @JReinhold!
|
||||
- Webpack: Fix export 'act' (imported as 'React4') was not found in 'react' errors in webpack - [#29235](https://github.com/storybookjs/storybook/pull/29235), thanks @kasperpeulen!
|
||||
|
||||
</details>
|
||||
|
||||
## 8.3.6
|
||||
|
||||
- CLI: Install Svelte CSF v5 in Svelte5 projects - [#29323](https://github.com/storybookjs/storybook/pull/29323), thanks @shilman!
|
||||
|
@ -1,3 +1,34 @@
|
||||
## 8.5.0-alpha.2
|
||||
|
||||
- Addon Test: Only render the TestingModule component in development mode - [#29501](https://github.com/storybookjs/storybook/pull/29501), thanks @yannbf!
|
||||
- CLI: Fix Solid init by installing `@storybook/test` - [#29514](https://github.com/storybookjs/storybook/pull/29514), thanks @shilman!
|
||||
- Core: Add bun support with npm fallback - [#29267](https://github.com/storybookjs/storybook/pull/29267), thanks @stephenjason89!
|
||||
- Core: Shim CJS-only globals in ESM output - [#29157](https://github.com/storybookjs/storybook/pull/29157), thanks @valentinpalkovic!
|
||||
- Next.js: Fix bundled react and react-dom in monorepos - [#29444](https://github.com/storybookjs/storybook/pull/29444), thanks @sentience!
|
||||
- Next.js: Upgrade sass-loader from ^13.2.0 to ^14.2.1 - [#29264](https://github.com/storybookjs/storybook/pull/29264), thanks @HoncharenkoZhenya!
|
||||
- UI: Add support for groups to `TooltipLinkList` and use it in main menu - [#29507](https://github.com/storybookjs/storybook/pull/29507), thanks @ghengeveld!
|
||||
|
||||
## 8.5.0-alpha.1
|
||||
|
||||
- Core: Relax peer dep constraint of shim packages - [#29503](https://github.com/storybookjs/storybook/pull/29503), thanks @kasperpeulen!
|
||||
|
||||
## 8.5.0-alpha.0
|
||||
|
||||
|
||||
## 8.4.0-beta.5
|
||||
|
||||
- Addon Test: Improve unsupported vitest message - [#29486](https://github.com/storybookjs/storybook/pull/29486), thanks @valentinpalkovic!
|
||||
- Core: Fix race condition during empty folder init - [#29490](https://github.com/storybookjs/storybook/pull/29490), thanks @valentinpalkovic!
|
||||
|
||||
## 8.4.0-beta.4
|
||||
|
||||
- Addon Test: Improve Error Handling - [#29476](https://github.com/storybookjs/storybook/pull/29476), thanks @valentinpalkovic!
|
||||
- Addon Test: Improve postinstall script - [#29479](https://github.com/storybookjs/storybook/pull/29479), thanks @yannbf!
|
||||
- Addon Test: Throttle Vitest progress updates more heavily - [#29482](https://github.com/storybookjs/storybook/pull/29482), thanks @ghengeveld!
|
||||
- CLI: Refactor NPMProxy error parsing logic - [#29459](https://github.com/storybookjs/storybook/pull/29459), thanks @yannbf!
|
||||
- Core: Track test provider state in sessionStorage - [#29450](https://github.com/storybookjs/storybook/pull/29450), thanks @ghengeveld!
|
||||
- Dependencies: Upgrade VTA to v3.2.0 to resolve peerDep conflict - [#29461](https://github.com/storybookjs/storybook/pull/29461), thanks @ghengeveld!
|
||||
|
||||
## 8.4.0-beta.3
|
||||
|
||||
- Addon Test: Only register testing module in Vite projects - [#29472](https://github.com/storybookjs/storybook/pull/29472), thanks @yannbf!
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@storybook/addon-a11y",
|
||||
"version": "8.4.0-beta.3",
|
||||
"version": "8.5.0-alpha.2",
|
||||
"description": "Test component compliance with web accessibility standards",
|
||||
"keywords": [
|
||||
"a11y",
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@storybook/addon-actions",
|
||||
"version": "8.4.0-beta.3",
|
||||
"version": "8.5.0-alpha.2",
|
||||
"description": "Get UI feedback when an action is performed on an interactive element",
|
||||
"keywords": [
|
||||
"storybook",
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@storybook/addon-backgrounds",
|
||||
"version": "8.4.0-beta.3",
|
||||
"version": "8.5.0-alpha.2",
|
||||
"description": "Switch backgrounds to view components in different settings",
|
||||
"keywords": [
|
||||
"addon",
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@storybook/addon-controls",
|
||||
"version": "8.4.0-beta.3",
|
||||
"version": "8.5.0-alpha.2",
|
||||
"description": "Interact with component inputs dynamically in the Storybook UI",
|
||||
"keywords": [
|
||||
"addon",
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@storybook/addon-docs",
|
||||
"version": "8.4.0-beta.3",
|
||||
"version": "8.5.0-alpha.2",
|
||||
"description": "Document component usage and properties in Markdown",
|
||||
"keywords": [
|
||||
"addon",
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@storybook/addon-essentials",
|
||||
"version": "8.4.0-beta.3",
|
||||
"version": "8.5.0-alpha.2",
|
||||
"description": "Curated addons to bring out the best of Storybook",
|
||||
"keywords": [
|
||||
"addon",
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@storybook/addon-mdx-gfm",
|
||||
"version": "8.4.0-beta.3",
|
||||
"version": "8.5.0-alpha.2",
|
||||
"description": "GitHub Flavored Markdown in Storybook",
|
||||
"keywords": [
|
||||
"addon",
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@storybook/addon-highlight",
|
||||
"version": "8.4.0-beta.3",
|
||||
"version": "8.5.0-alpha.2",
|
||||
"description": "Highlight DOM nodes within your stories",
|
||||
"keywords": [
|
||||
"storybook-addons",
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@storybook/addon-interactions",
|
||||
"version": "8.4.0-beta.3",
|
||||
"version": "8.5.0-alpha.2",
|
||||
"description": "Automate, test and debug user interactions",
|
||||
"keywords": [
|
||||
"storybook-addons",
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@storybook/addon-jest",
|
||||
"version": "8.4.0-beta.3",
|
||||
"version": "8.5.0-alpha.2",
|
||||
"description": "React storybook addon that show component jest report",
|
||||
"keywords": [
|
||||
"addon",
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@storybook/addon-links",
|
||||
"version": "8.4.0-beta.3",
|
||||
"version": "8.5.0-alpha.2",
|
||||
"description": "Link stories together to build demos and prototypes with your UI components",
|
||||
"keywords": [
|
||||
"storybook-addons",
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@storybook/addon-measure",
|
||||
"version": "8.4.0-beta.3",
|
||||
"version": "8.5.0-alpha.2",
|
||||
"description": "Inspect layouts by visualizing the box model",
|
||||
"keywords": [
|
||||
"storybook-addons",
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@storybook/addon-onboarding",
|
||||
"version": "8.4.0-beta.3",
|
||||
"version": "8.5.0-alpha.2",
|
||||
"description": "Storybook Addon Onboarding - Introduces a new onboarding experience",
|
||||
"keywords": [
|
||||
"storybook-addons",
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@storybook/addon-outline",
|
||||
"version": "8.4.0-beta.3",
|
||||
"version": "8.5.0-alpha.2",
|
||||
"description": "Outline all elements with CSS to help with layout placement and alignment",
|
||||
"keywords": [
|
||||
"storybook-addons",
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@storybook/addon-storysource",
|
||||
"version": "8.4.0-beta.3",
|
||||
"version": "8.5.0-alpha.2",
|
||||
"description": "View a story’s source code to see how it works and paste into your app",
|
||||
"keywords": [
|
||||
"addon",
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@storybook/experimental-addon-test",
|
||||
"version": "8.4.0-beta.3",
|
||||
"version": "8.5.0-alpha.2",
|
||||
"description": "Integrate Vitest with Storybook",
|
||||
"keywords": [
|
||||
"storybook-addons",
|
||||
|
@ -88,7 +88,7 @@ export default async function postInstall(options: PostinstallOptions) {
|
||||
if (coercedVitestVersion && !satisfies(coercedVitestVersion, '>=2.1.0')) {
|
||||
reasons.push(dedent`
|
||||
• The addon requires Vitest 2.1.0 or later. You are currently using ${picocolors.bold(vitestVersionSpecifier)}.
|
||||
Please update your ${picocolors.bold(colors.pink('vitest'))} dependency and try again.
|
||||
Please update all of your Vitest dependencies and try again.
|
||||
`);
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@storybook/addon-themes",
|
||||
"version": "8.4.0-beta.3",
|
||||
"version": "8.5.0-alpha.2",
|
||||
"description": "Switch between multiple themes for you components in Storybook",
|
||||
"keywords": [
|
||||
"css",
|
||||
|
@ -5,6 +5,7 @@ const PACKAGE_MANAGER_TO_COMMAND = {
|
||||
pnpm: ['pnpm', 'dlx'],
|
||||
yarn1: ['npx'],
|
||||
yarn2: ['yarn', 'dlx'],
|
||||
bun: ['bunx'],
|
||||
};
|
||||
|
||||
const selectPackageManagerCommand = (packageManager) => PACKAGE_MANAGER_TO_COMMAND[packageManager];
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@storybook/addon-toolbars",
|
||||
"version": "8.4.0-beta.3",
|
||||
"version": "8.5.0-alpha.2",
|
||||
"description": "Create your own toolbar items that control story rendering",
|
||||
"keywords": [
|
||||
"addon",
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@storybook/addon-viewport",
|
||||
"version": "8.4.0-beta.3",
|
||||
"version": "8.5.0-alpha.2",
|
||||
"description": "Build responsive components by adjusting Storybook’s viewport size and orientation",
|
||||
"keywords": [
|
||||
"addon",
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@storybook/builder-vite",
|
||||
"version": "8.4.0-beta.3",
|
||||
"version": "8.5.0-alpha.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": {
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@storybook/builder-webpack5",
|
||||
"version": "8.4.0-beta.3",
|
||||
"version": "8.5.0-alpha.2",
|
||||
"description": "Storybook framework-agnostic API",
|
||||
"keywords": [
|
||||
"storybook"
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@storybook/core",
|
||||
"version": "8.4.0-beta.3",
|
||||
"version": "8.5.0-alpha.2",
|
||||
"description": "Storybook framework-agnostic API",
|
||||
"keywords": [
|
||||
"storybook"
|
||||
|
332
code/core/src/common/js-package-manager/BUNProxy.ts
Normal file
332
code/core/src/common/js-package-manager/BUNProxy.ts
Normal file
@ -0,0 +1,332 @@
|
||||
import { existsSync, readFileSync } from 'node:fs';
|
||||
import { platform } from 'node:os';
|
||||
import { join } from 'node:path';
|
||||
|
||||
import { logger } from '@storybook/core/node-logger';
|
||||
import { FindPackageVersionsError } from '@storybook/core/server-errors';
|
||||
|
||||
import { findUp } from 'find-up';
|
||||
import sort from 'semver/functions/sort.js';
|
||||
import { dedent } from 'ts-dedent';
|
||||
|
||||
import { createLogStream } from '../utils/cli';
|
||||
import { JsPackageManager } from './JsPackageManager';
|
||||
import type { PackageJson } from './PackageJson';
|
||||
import type { InstallationMetadata, PackageMetadata } from './types';
|
||||
|
||||
type NpmDependency = {
|
||||
version: string;
|
||||
resolved?: string;
|
||||
overridden?: boolean;
|
||||
dependencies?: NpmDependencies;
|
||||
};
|
||||
|
||||
type NpmDependencies = {
|
||||
[key: string]: NpmDependency;
|
||||
};
|
||||
|
||||
export type NpmListOutput = {
|
||||
dependencies: NpmDependencies;
|
||||
};
|
||||
|
||||
const NPM_ERROR_REGEX = /npm ERR! code (\w+)/;
|
||||
const NPM_ERROR_CODES = {
|
||||
E401: 'Authentication failed or is required.',
|
||||
E403: 'Access to the resource is forbidden.',
|
||||
E404: 'Requested resource not found.',
|
||||
EACCES: 'Permission issue.',
|
||||
EAI_FAIL: 'DNS lookup failed.',
|
||||
EBADENGINE: 'Engine compatibility check failed.',
|
||||
EBADPLATFORM: 'Platform not supported.',
|
||||
ECONNREFUSED: 'Connection refused.',
|
||||
ECONNRESET: 'Connection reset.',
|
||||
EEXIST: 'File or directory already exists.',
|
||||
EINVALIDTYPE: 'Invalid type encountered.',
|
||||
EISGIT: 'Git operation failed or conflicts with an existing file.',
|
||||
EJSONPARSE: 'Error parsing JSON data.',
|
||||
EMISSINGARG: 'Required argument missing.',
|
||||
ENEEDAUTH: 'Authentication needed.',
|
||||
ENOAUDIT: 'No audit available.',
|
||||
ENOENT: 'File or directory does not exist.',
|
||||
ENOGIT: 'Git not found or failed to run.',
|
||||
ENOLOCK: 'Lockfile missing.',
|
||||
ENOSPC: 'Insufficient disk space.',
|
||||
ENOTFOUND: 'Resource not found.',
|
||||
EOTP: 'One-time password required.',
|
||||
EPERM: 'Permission error.',
|
||||
EPUBLISHCONFLICT: 'Conflict during package publishing.',
|
||||
ERESOLVE: 'Dependency resolution error.',
|
||||
EROFS: 'File system is read-only.',
|
||||
ERR_SOCKET_TIMEOUT: 'Socket timed out.',
|
||||
ETARGET: 'Package target not found.',
|
||||
ETIMEDOUT: 'Operation timed out.',
|
||||
ETOOMANYARGS: 'Too many arguments provided.',
|
||||
EUNKNOWNTYPE: 'Unknown type encountered.',
|
||||
};
|
||||
|
||||
export class BUNProxy extends JsPackageManager {
|
||||
readonly type = 'bun';
|
||||
|
||||
installArgs: string[] | undefined;
|
||||
|
||||
async initPackageJson() {
|
||||
await this.executeCommand({ command: 'bun', args: ['init'] });
|
||||
}
|
||||
|
||||
getRunStorybookCommand(): string {
|
||||
return 'bun run storybook';
|
||||
}
|
||||
|
||||
getRunCommand(command: string): string {
|
||||
return `bun run ${command}`;
|
||||
}
|
||||
|
||||
getRemoteRunCommand(): string {
|
||||
return 'bunx';
|
||||
}
|
||||
|
||||
public async getPackageJSON(
|
||||
packageName: string,
|
||||
basePath = this.cwd
|
||||
): Promise<PackageJson | null> {
|
||||
const packageJsonPath = await findUp(
|
||||
(dir) => {
|
||||
const possiblePath = join(dir, 'node_modules', packageName, 'package.json');
|
||||
return existsSync(possiblePath) ? possiblePath : undefined;
|
||||
},
|
||||
{ cwd: basePath }
|
||||
);
|
||||
|
||||
if (!packageJsonPath) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));
|
||||
return packageJson;
|
||||
}
|
||||
|
||||
getInstallArgs(): string[] {
|
||||
if (!this.installArgs) {
|
||||
this.installArgs = [];
|
||||
}
|
||||
return this.installArgs;
|
||||
}
|
||||
|
||||
public runPackageCommandSync(
|
||||
command: string,
|
||||
args: string[],
|
||||
cwd?: string,
|
||||
stdio?: 'pipe' | 'inherit'
|
||||
): string {
|
||||
return this.executeCommandSync({
|
||||
command: 'bun',
|
||||
args: ['run', command, ...args],
|
||||
cwd,
|
||||
stdio,
|
||||
});
|
||||
}
|
||||
|
||||
public async runPackageCommand(command: string, args: string[], cwd?: string): Promise<string> {
|
||||
return this.executeCommand({
|
||||
command: 'bun',
|
||||
args: ['run', command, ...args],
|
||||
cwd,
|
||||
});
|
||||
}
|
||||
|
||||
public async findInstallations(pattern: string[], { depth = 99 }: { depth?: number } = {}) {
|
||||
const exec = async ({ packageDepth }: { packageDepth: number }) => {
|
||||
const pipeToNull = platform() === 'win32' ? '2>NUL' : '2>/dev/null';
|
||||
return this.executeCommand({
|
||||
command: 'npm',
|
||||
args: ['ls', '--json', `--depth=${packageDepth}`, pipeToNull],
|
||||
env: {
|
||||
FORCE_COLOR: 'false',
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
try {
|
||||
const commandResult = await exec({ packageDepth: depth });
|
||||
const parsedOutput = JSON.parse(commandResult);
|
||||
|
||||
return this.mapDependencies(parsedOutput, pattern);
|
||||
} catch (e) {
|
||||
// when --depth is higher than 0, npm can return a non-zero exit code
|
||||
// in case the user's project has peer dependency issues. So we try again with no depth
|
||||
try {
|
||||
const commandResult = await exec({ packageDepth: 0 });
|
||||
const parsedOutput = JSON.parse(commandResult);
|
||||
|
||||
return this.mapDependencies(parsedOutput, pattern);
|
||||
} catch (err) {
|
||||
logger.warn(`An issue occurred while trying to find dependencies metadata using npm.`);
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected getResolutions(packageJson: PackageJson, versions: Record<string, string>) {
|
||||
return {
|
||||
overrides: {
|
||||
...packageJson.overrides,
|
||||
...versions,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
protected async runInstall() {
|
||||
await this.executeCommand({
|
||||
command: 'bun',
|
||||
args: ['install', ...this.getInstallArgs()],
|
||||
stdio: 'inherit',
|
||||
});
|
||||
}
|
||||
|
||||
public async getRegistryURL() {
|
||||
const res = await this.executeCommand({
|
||||
command: 'npm',
|
||||
// "npm config" commands are not allowed in workspaces per default
|
||||
// https://github.com/npm/cli/issues/6099#issuecomment-1847584792
|
||||
args: ['config', 'get', 'registry', '-ws=false', '-iwr'],
|
||||
});
|
||||
const url = res.trim();
|
||||
return url === 'undefined' ? undefined : url;
|
||||
}
|
||||
|
||||
protected async runAddDeps(dependencies: string[], installAsDevDependencies: boolean) {
|
||||
const { logStream, readLogFile, moveLogFile, removeLogFile } = await createLogStream();
|
||||
let args = [...dependencies];
|
||||
|
||||
if (installAsDevDependencies) {
|
||||
args = ['-D', ...args];
|
||||
}
|
||||
|
||||
try {
|
||||
await this.executeCommand({
|
||||
command: 'bun',
|
||||
args: ['add', ...args, ...this.getInstallArgs()],
|
||||
stdio: process.env.CI ? 'inherit' : ['ignore', logStream, logStream],
|
||||
});
|
||||
} catch (err) {
|
||||
const stdout = await readLogFile();
|
||||
|
||||
const errorMessage = this.parseErrorFromLogs(stdout);
|
||||
|
||||
await moveLogFile();
|
||||
|
||||
throw new Error(
|
||||
dedent`${errorMessage}
|
||||
|
||||
Please check the logfile generated at ./storybook.log for troubleshooting and try again.`
|
||||
);
|
||||
}
|
||||
|
||||
await removeLogFile();
|
||||
}
|
||||
|
||||
protected async runRemoveDeps(dependencies: string[]) {
|
||||
const args = [...dependencies];
|
||||
|
||||
await this.executeCommand({
|
||||
command: 'bun',
|
||||
args: ['remove', ...args, ...this.getInstallArgs()],
|
||||
stdio: 'inherit',
|
||||
});
|
||||
}
|
||||
|
||||
protected async runGetVersions<T extends boolean>(
|
||||
packageName: string,
|
||||
fetchAllVersions: T
|
||||
): Promise<T extends true ? string[] : string> {
|
||||
const args = [fetchAllVersions ? 'versions' : 'version', '--json'];
|
||||
try {
|
||||
const commandResult = await this.executeCommand({
|
||||
command: 'npm',
|
||||
args: ['info', packageName, ...args],
|
||||
});
|
||||
|
||||
const parsedOutput = JSON.parse(commandResult);
|
||||
|
||||
if (parsedOutput.error?.summary) {
|
||||
// this will be handled in the catch block below
|
||||
throw parsedOutput.error.summary;
|
||||
}
|
||||
|
||||
return parsedOutput;
|
||||
} catch (error) {
|
||||
throw new FindPackageVersionsError({
|
||||
error,
|
||||
packageManager: 'NPM',
|
||||
packageName,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param input The output of `npm ls --json`
|
||||
* @param pattern A list of package names to filter the result. * can be used as a placeholder
|
||||
*/
|
||||
protected mapDependencies(input: NpmListOutput, pattern: string[]): InstallationMetadata {
|
||||
const acc: Record<string, PackageMetadata[]> = {};
|
||||
const existingVersions: Record<string, string[]> = {};
|
||||
const duplicatedDependencies: Record<string, string[]> = {};
|
||||
|
||||
const recurse = ([name, packageInfo]: [string, NpmDependency]): void => {
|
||||
// transform pattern into regex where `*` is replaced with `.*`
|
||||
if (!name || !pattern.some((p) => new RegExp(`^${p.replace(/\*/g, '.*')}$`).test(name))) {
|
||||
return;
|
||||
}
|
||||
|
||||
const value = {
|
||||
version: packageInfo.version,
|
||||
location: '',
|
||||
};
|
||||
|
||||
if (!existingVersions[name]?.includes(value.version)) {
|
||||
if (acc[name]) {
|
||||
acc[name].push(value);
|
||||
} else {
|
||||
acc[name] = [value];
|
||||
}
|
||||
existingVersions[name] = sort([...(existingVersions[name] || []), value.version]);
|
||||
|
||||
if (existingVersions[name].length > 1) {
|
||||
duplicatedDependencies[name] = existingVersions[name];
|
||||
}
|
||||
}
|
||||
|
||||
if (packageInfo.dependencies) {
|
||||
Object.entries(packageInfo.dependencies).forEach(recurse);
|
||||
}
|
||||
};
|
||||
|
||||
Object.entries(input.dependencies).forEach(recurse);
|
||||
|
||||
return {
|
||||
dependencies: acc,
|
||||
duplicatedDependencies,
|
||||
infoCommand: 'npm ls --depth=1',
|
||||
dedupeCommand: 'npm dedupe',
|
||||
};
|
||||
}
|
||||
|
||||
public parseErrorFromLogs(logs: string): string {
|
||||
let finalMessage = 'NPM error';
|
||||
const match = logs.match(NPM_ERROR_REGEX);
|
||||
|
||||
if (match) {
|
||||
const errorCode = match[1] as keyof typeof NPM_ERROR_CODES;
|
||||
if (errorCode) {
|
||||
finalMessage = `${finalMessage} ${errorCode}`;
|
||||
}
|
||||
|
||||
const errorMessage = NPM_ERROR_CODES[errorCode];
|
||||
if (errorMessage) {
|
||||
finalMessage = `${finalMessage} - ${errorMessage}`;
|
||||
}
|
||||
}
|
||||
|
||||
return finalMessage.trim();
|
||||
}
|
||||
}
|
@ -16,7 +16,7 @@ import type { InstallationMetadata } from './types';
|
||||
|
||||
const logger = console;
|
||||
|
||||
export type PackageManagerName = 'npm' | 'yarn1' | 'yarn2' | 'pnpm';
|
||||
export type PackageManagerName = 'npm' | 'yarn1' | 'yarn2' | 'pnpm' | 'bun';
|
||||
|
||||
type StorybookPackage = keyof typeof storybookPackagesVersions;
|
||||
|
||||
|
@ -5,6 +5,7 @@ import { beforeEach, describe, expect, it, vi } from 'vitest';
|
||||
import { sync as spawnSync } from 'cross-spawn';
|
||||
import { findUpSync } from 'find-up';
|
||||
|
||||
import { BUNProxy } from './BUNProxy';
|
||||
import { JsPackageManagerFactory } from './JsPackageManagerFactory';
|
||||
import { NPMProxy } from './NPMProxy';
|
||||
import { PNPMProxy } from './PNPMProxy';
|
||||
@ -354,6 +355,91 @@ describe('CLASS: JsPackageManagerFactory', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('Yarn 2 proxy', () => {
|
||||
it('FORCE: it should return a Yarn2 proxy when `force` option is `yarn2`', () => {
|
||||
expect(JsPackageManagerFactory.getPackageManager({ force: 'yarn2' })).toBeInstanceOf(
|
||||
Yarn2Proxy
|
||||
);
|
||||
});
|
||||
|
||||
it('USER AGENT: it should infer yarn2 from the user agent', () => {
|
||||
process.env.npm_config_user_agent = 'yarn/2.2.10';
|
||||
expect(JsPackageManagerFactory.getPackageManager()).toBeInstanceOf(Yarn2Proxy);
|
||||
});
|
||||
|
||||
it('ONLY YARN 2: when Yarn command is ok, Yarn version is >=2, NPM is ko, PNPM is ko', () => {
|
||||
spawnSyncMock.mockImplementation((command) => {
|
||||
// Yarn is ok
|
||||
if (command === 'yarn') {
|
||||
return {
|
||||
status: 0,
|
||||
output: '2.0.0-rc.33',
|
||||
};
|
||||
}
|
||||
// NPM is ko
|
||||
if (command === 'npm') {
|
||||
return {
|
||||
status: 1,
|
||||
};
|
||||
}
|
||||
// PNPM is ko
|
||||
if (command === 'pnpm') {
|
||||
return {
|
||||
status: 1,
|
||||
};
|
||||
}
|
||||
// Unknown package manager is ko
|
||||
return {
|
||||
status: 1,
|
||||
} as any;
|
||||
});
|
||||
|
||||
expect(JsPackageManagerFactory.getPackageManager()).toBeInstanceOf(Yarn2Proxy);
|
||||
});
|
||||
|
||||
it('when Yarn command is ok, Yarn version is >=2, NPM and PNPM are ok, there is a `yarn.lock` file', () => {
|
||||
spawnSyncMock.mockImplementation((command) => {
|
||||
// Yarn is ok
|
||||
if (command === 'yarn') {
|
||||
return {
|
||||
status: 0,
|
||||
output: '2.0.0-rc.33',
|
||||
};
|
||||
}
|
||||
// NPM is ok
|
||||
if (command === 'npm') {
|
||||
return {
|
||||
status: 0,
|
||||
output: '6.5.12',
|
||||
};
|
||||
}
|
||||
// PNPM is ok
|
||||
if (command === 'pnpm') {
|
||||
return {
|
||||
status: 0,
|
||||
output: '7.9.5',
|
||||
};
|
||||
}
|
||||
|
||||
if (command === 'bun') {
|
||||
return {
|
||||
status: 0,
|
||||
output: '1.0.0',
|
||||
};
|
||||
}
|
||||
// Unknown package manager is ko
|
||||
return {
|
||||
status: 1,
|
||||
} as any;
|
||||
});
|
||||
|
||||
// There is a yarn.lock
|
||||
findUpSyncMock.mockImplementation(() => '/Users/johndoe/Documents/bun.lockb');
|
||||
|
||||
expect(JsPackageManagerFactory.getPackageManager()).toBeInstanceOf(BUNProxy);
|
||||
});
|
||||
});
|
||||
|
||||
it('throws an error if Yarn, NPM, and PNPM are not found', () => {
|
||||
spawnSyncMock.mockReturnValue({ status: 1 } as any);
|
||||
expect(() => JsPackageManagerFactory.getPackageManager()).toThrow();
|
||||
|
@ -3,6 +3,7 @@ import { basename, parse, relative } from 'node:path';
|
||||
import { sync as spawnSync } from 'cross-spawn';
|
||||
import { findUpSync } from 'find-up';
|
||||
|
||||
import { BUNProxy } from './BUNProxy';
|
||||
import type { JsPackageManager, PackageManagerName } from './JsPackageManager';
|
||||
import { NPMProxy } from './NPMProxy';
|
||||
import { PNPMProxy } from './PNPMProxy';
|
||||
@ -12,12 +13,14 @@ import { Yarn2Proxy } from './Yarn2Proxy';
|
||||
const NPM_LOCKFILE = 'package-lock.json';
|
||||
const PNPM_LOCKFILE = 'pnpm-lock.yaml';
|
||||
const YARN_LOCKFILE = 'yarn.lock';
|
||||
const BUN_LOCKFILE = 'bun.lockb';
|
||||
|
||||
type PackageManagerProxy =
|
||||
| typeof NPMProxy
|
||||
| typeof PNPMProxy
|
||||
| typeof Yarn1Proxy
|
||||
| typeof Yarn2Proxy;
|
||||
| typeof Yarn2Proxy
|
||||
| typeof BUNProxy;
|
||||
|
||||
export class JsPackageManagerFactory {
|
||||
public static getPackageManager(
|
||||
@ -33,6 +36,7 @@ export class JsPackageManagerFactory {
|
||||
findUpSync(YARN_LOCKFILE, { cwd }),
|
||||
findUpSync(PNPM_LOCKFILE, { cwd }),
|
||||
findUpSync(NPM_LOCKFILE, { cwd }),
|
||||
findUpSync(BUN_LOCKFILE, { cwd }),
|
||||
]
|
||||
.filter(Boolean)
|
||||
.sort((a, b) => {
|
||||
@ -59,6 +63,7 @@ export class JsPackageManagerFactory {
|
||||
|
||||
const hasNPMCommand = hasNPM(cwd);
|
||||
const hasPNPMCommand = hasPNPM(cwd);
|
||||
const hasBunCommand = hasBun(cwd);
|
||||
const yarnVersion = getYarnVersion(cwd);
|
||||
|
||||
if (yarnVersion && (closestLockfile === YARN_LOCKFILE || (!hasNPMCommand && !hasPNPMCommand))) {
|
||||
@ -73,6 +78,10 @@ export class JsPackageManagerFactory {
|
||||
return new NPMProxy({ cwd });
|
||||
}
|
||||
|
||||
if (hasBunCommand && closestLockfile === BUN_LOCKFILE) {
|
||||
return new BUNProxy({ cwd });
|
||||
}
|
||||
|
||||
// Option 3: If the user is running a command via npx/pnpx/yarn create/etc, we infer the package manager from the command
|
||||
const inferredPackageManager = this.inferPackageManagerFromUserAgent();
|
||||
if (inferredPackageManager && inferredPackageManager in this.PROXY_MAP) {
|
||||
@ -94,6 +103,7 @@ export class JsPackageManagerFactory {
|
||||
pnpm: PNPMProxy,
|
||||
yarn1: Yarn1Proxy,
|
||||
yarn2: Yarn2Proxy,
|
||||
bun: BUNProxy,
|
||||
};
|
||||
|
||||
/**
|
||||
@ -136,6 +146,18 @@ function hasNPM(cwd?: string) {
|
||||
return npmVersionCommand.status === 0;
|
||||
}
|
||||
|
||||
function hasBun(cwd?: string) {
|
||||
const pnpmVersionCommand = spawnSync('bun', ['--version'], {
|
||||
cwd,
|
||||
shell: true,
|
||||
env: {
|
||||
...process.env,
|
||||
COREPACK_ENABLE_STRICT: '0',
|
||||
},
|
||||
});
|
||||
return pnpmVersionCommand.status === 0;
|
||||
}
|
||||
|
||||
function hasPNPM(cwd?: string) {
|
||||
const pnpmVersionCommand = spawnSync('pnpm', ['--version'], {
|
||||
cwd,
|
||||
|
@ -85,10 +85,6 @@ export class NPMProxy extends JsPackageManager {
|
||||
return 'npx';
|
||||
}
|
||||
|
||||
async getNpmVersion(): Promise<string> {
|
||||
return this.executeCommand({ command: 'npm', args: ['--version'] });
|
||||
}
|
||||
|
||||
public async getPackageJSON(
|
||||
packageName: string,
|
||||
basePath = this.cwd
|
||||
|
@ -85,6 +85,7 @@ export class FileSystemCache {
|
||||
orgOpts: CacheSetOptions | number = {}
|
||||
): Promise<void> {
|
||||
const opts: CacheSetOptions = typeof orgOpts === 'number' ? { ttl: orgOpts } : orgOpts;
|
||||
mkdirSync(this.cache_dir, { recursive: true });
|
||||
await writeFile(this.generateHash(name), this.parseSetData(name, data, opts), {
|
||||
encoding: opts.encoding || 'utf8',
|
||||
});
|
||||
@ -92,6 +93,7 @@ export class FileSystemCache {
|
||||
|
||||
public setSync<T>(name: string, data: T, orgOpts: CacheSetOptions | number = {}): void {
|
||||
const opts: CacheSetOptions = typeof orgOpts === 'number' ? { ttl: orgOpts } : orgOpts;
|
||||
mkdirSync(this.cache_dir, { recursive: true });
|
||||
writeFileSync(this.generateHash(name), this.parseSetData(name, data, opts), {
|
||||
encoding: opts.encoding || 'utf8',
|
||||
});
|
||||
|
@ -1,87 +1,87 @@
|
||||
// auto generated file, do not edit
|
||||
export default {
|
||||
'@storybook/addon-a11y': '8.4.0-beta.3',
|
||||
'@storybook/addon-actions': '8.4.0-beta.3',
|
||||
'@storybook/addon-backgrounds': '8.4.0-beta.3',
|
||||
'@storybook/addon-controls': '8.4.0-beta.3',
|
||||
'@storybook/addon-docs': '8.4.0-beta.3',
|
||||
'@storybook/addon-essentials': '8.4.0-beta.3',
|
||||
'@storybook/addon-mdx-gfm': '8.4.0-beta.3',
|
||||
'@storybook/addon-highlight': '8.4.0-beta.3',
|
||||
'@storybook/addon-interactions': '8.4.0-beta.3',
|
||||
'@storybook/addon-jest': '8.4.0-beta.3',
|
||||
'@storybook/addon-links': '8.4.0-beta.3',
|
||||
'@storybook/addon-measure': '8.4.0-beta.3',
|
||||
'@storybook/addon-onboarding': '8.4.0-beta.3',
|
||||
'@storybook/addon-outline': '8.4.0-beta.3',
|
||||
'@storybook/addon-storysource': '8.4.0-beta.3',
|
||||
'@storybook/experimental-addon-test': '8.4.0-beta.3',
|
||||
'@storybook/addon-themes': '8.4.0-beta.3',
|
||||
'@storybook/addon-toolbars': '8.4.0-beta.3',
|
||||
'@storybook/addon-viewport': '8.4.0-beta.3',
|
||||
'@storybook/builder-vite': '8.4.0-beta.3',
|
||||
'@storybook/builder-webpack5': '8.4.0-beta.3',
|
||||
'@storybook/core': '8.4.0-beta.3',
|
||||
'@storybook/builder-manager': '8.4.0-beta.3',
|
||||
'@storybook/channels': '8.4.0-beta.3',
|
||||
'@storybook/client-logger': '8.4.0-beta.3',
|
||||
'@storybook/components': '8.4.0-beta.3',
|
||||
'@storybook/core-common': '8.4.0-beta.3',
|
||||
'@storybook/core-events': '8.4.0-beta.3',
|
||||
'@storybook/core-server': '8.4.0-beta.3',
|
||||
'@storybook/csf-tools': '8.4.0-beta.3',
|
||||
'@storybook/docs-tools': '8.4.0-beta.3',
|
||||
'@storybook/manager': '8.4.0-beta.3',
|
||||
'@storybook/manager-api': '8.4.0-beta.3',
|
||||
'@storybook/node-logger': '8.4.0-beta.3',
|
||||
'@storybook/preview': '8.4.0-beta.3',
|
||||
'@storybook/preview-api': '8.4.0-beta.3',
|
||||
'@storybook/router': '8.4.0-beta.3',
|
||||
'@storybook/telemetry': '8.4.0-beta.3',
|
||||
'@storybook/theming': '8.4.0-beta.3',
|
||||
'@storybook/types': '8.4.0-beta.3',
|
||||
'@storybook/angular': '8.4.0-beta.3',
|
||||
'@storybook/ember': '8.4.0-beta.3',
|
||||
'@storybook/experimental-nextjs-vite': '8.4.0-beta.3',
|
||||
'@storybook/html-vite': '8.4.0-beta.3',
|
||||
'@storybook/html-webpack5': '8.4.0-beta.3',
|
||||
'@storybook/nextjs': '8.4.0-beta.3',
|
||||
'@storybook/preact-vite': '8.4.0-beta.3',
|
||||
'@storybook/preact-webpack5': '8.4.0-beta.3',
|
||||
'@storybook/react-vite': '8.4.0-beta.3',
|
||||
'@storybook/react-webpack5': '8.4.0-beta.3',
|
||||
'@storybook/server-webpack5': '8.4.0-beta.3',
|
||||
'@storybook/svelte-vite': '8.4.0-beta.3',
|
||||
'@storybook/svelte-webpack5': '8.4.0-beta.3',
|
||||
'@storybook/sveltekit': '8.4.0-beta.3',
|
||||
'@storybook/vue3-vite': '8.4.0-beta.3',
|
||||
'@storybook/vue3-webpack5': '8.4.0-beta.3',
|
||||
'@storybook/web-components-vite': '8.4.0-beta.3',
|
||||
'@storybook/web-components-webpack5': '8.4.0-beta.3',
|
||||
'@storybook/blocks': '8.4.0-beta.3',
|
||||
storybook: '8.4.0-beta.3',
|
||||
sb: '8.4.0-beta.3',
|
||||
'@storybook/cli': '8.4.0-beta.3',
|
||||
'@storybook/codemod': '8.4.0-beta.3',
|
||||
'@storybook/core-webpack': '8.4.0-beta.3',
|
||||
'create-storybook': '8.4.0-beta.3',
|
||||
'@storybook/csf-plugin': '8.4.0-beta.3',
|
||||
'@storybook/instrumenter': '8.4.0-beta.3',
|
||||
'@storybook/react-dom-shim': '8.4.0-beta.3',
|
||||
'@storybook/source-loader': '8.4.0-beta.3',
|
||||
'@storybook/test': '8.4.0-beta.3',
|
||||
'@storybook/preset-create-react-app': '8.4.0-beta.3',
|
||||
'@storybook/preset-html-webpack': '8.4.0-beta.3',
|
||||
'@storybook/preset-preact-webpack': '8.4.0-beta.3',
|
||||
'@storybook/preset-react-webpack': '8.4.0-beta.3',
|
||||
'@storybook/preset-server-webpack': '8.4.0-beta.3',
|
||||
'@storybook/preset-svelte-webpack': '8.4.0-beta.3',
|
||||
'@storybook/preset-vue3-webpack': '8.4.0-beta.3',
|
||||
'@storybook/html': '8.4.0-beta.3',
|
||||
'@storybook/preact': '8.4.0-beta.3',
|
||||
'@storybook/react': '8.4.0-beta.3',
|
||||
'@storybook/server': '8.4.0-beta.3',
|
||||
'@storybook/svelte': '8.4.0-beta.3',
|
||||
'@storybook/vue3': '8.4.0-beta.3',
|
||||
'@storybook/web-components': '8.4.0-beta.3',
|
||||
'@storybook/addon-a11y': '8.5.0-alpha.2',
|
||||
'@storybook/addon-actions': '8.5.0-alpha.2',
|
||||
'@storybook/addon-backgrounds': '8.5.0-alpha.2',
|
||||
'@storybook/addon-controls': '8.5.0-alpha.2',
|
||||
'@storybook/addon-docs': '8.5.0-alpha.2',
|
||||
'@storybook/addon-essentials': '8.5.0-alpha.2',
|
||||
'@storybook/addon-mdx-gfm': '8.5.0-alpha.2',
|
||||
'@storybook/addon-highlight': '8.5.0-alpha.2',
|
||||
'@storybook/addon-interactions': '8.5.0-alpha.2',
|
||||
'@storybook/addon-jest': '8.5.0-alpha.2',
|
||||
'@storybook/addon-links': '8.5.0-alpha.2',
|
||||
'@storybook/addon-measure': '8.5.0-alpha.2',
|
||||
'@storybook/addon-onboarding': '8.5.0-alpha.2',
|
||||
'@storybook/addon-outline': '8.5.0-alpha.2',
|
||||
'@storybook/addon-storysource': '8.5.0-alpha.2',
|
||||
'@storybook/experimental-addon-test': '8.5.0-alpha.2',
|
||||
'@storybook/addon-themes': '8.5.0-alpha.2',
|
||||
'@storybook/addon-toolbars': '8.5.0-alpha.2',
|
||||
'@storybook/addon-viewport': '8.5.0-alpha.2',
|
||||
'@storybook/builder-vite': '8.5.0-alpha.2',
|
||||
'@storybook/builder-webpack5': '8.5.0-alpha.2',
|
||||
'@storybook/core': '8.5.0-alpha.2',
|
||||
'@storybook/builder-manager': '8.5.0-alpha.2',
|
||||
'@storybook/channels': '8.5.0-alpha.2',
|
||||
'@storybook/client-logger': '8.5.0-alpha.2',
|
||||
'@storybook/components': '8.5.0-alpha.2',
|
||||
'@storybook/core-common': '8.5.0-alpha.2',
|
||||
'@storybook/core-events': '8.5.0-alpha.2',
|
||||
'@storybook/core-server': '8.5.0-alpha.2',
|
||||
'@storybook/csf-tools': '8.5.0-alpha.2',
|
||||
'@storybook/docs-tools': '8.5.0-alpha.2',
|
||||
'@storybook/manager': '8.5.0-alpha.2',
|
||||
'@storybook/manager-api': '8.5.0-alpha.2',
|
||||
'@storybook/node-logger': '8.5.0-alpha.2',
|
||||
'@storybook/preview': '8.5.0-alpha.2',
|
||||
'@storybook/preview-api': '8.5.0-alpha.2',
|
||||
'@storybook/router': '8.5.0-alpha.2',
|
||||
'@storybook/telemetry': '8.5.0-alpha.2',
|
||||
'@storybook/theming': '8.5.0-alpha.2',
|
||||
'@storybook/types': '8.5.0-alpha.2',
|
||||
'@storybook/angular': '8.5.0-alpha.2',
|
||||
'@storybook/ember': '8.5.0-alpha.2',
|
||||
'@storybook/experimental-nextjs-vite': '8.5.0-alpha.2',
|
||||
'@storybook/html-vite': '8.5.0-alpha.2',
|
||||
'@storybook/html-webpack5': '8.5.0-alpha.2',
|
||||
'@storybook/nextjs': '8.5.0-alpha.2',
|
||||
'@storybook/preact-vite': '8.5.0-alpha.2',
|
||||
'@storybook/preact-webpack5': '8.5.0-alpha.2',
|
||||
'@storybook/react-vite': '8.5.0-alpha.2',
|
||||
'@storybook/react-webpack5': '8.5.0-alpha.2',
|
||||
'@storybook/server-webpack5': '8.5.0-alpha.2',
|
||||
'@storybook/svelte-vite': '8.5.0-alpha.2',
|
||||
'@storybook/svelte-webpack5': '8.5.0-alpha.2',
|
||||
'@storybook/sveltekit': '8.5.0-alpha.2',
|
||||
'@storybook/vue3-vite': '8.5.0-alpha.2',
|
||||
'@storybook/vue3-webpack5': '8.5.0-alpha.2',
|
||||
'@storybook/web-components-vite': '8.5.0-alpha.2',
|
||||
'@storybook/web-components-webpack5': '8.5.0-alpha.2',
|
||||
'@storybook/blocks': '8.5.0-alpha.2',
|
||||
storybook: '8.5.0-alpha.2',
|
||||
sb: '8.5.0-alpha.2',
|
||||
'@storybook/cli': '8.5.0-alpha.2',
|
||||
'@storybook/codemod': '8.5.0-alpha.2',
|
||||
'@storybook/core-webpack': '8.5.0-alpha.2',
|
||||
'create-storybook': '8.5.0-alpha.2',
|
||||
'@storybook/csf-plugin': '8.5.0-alpha.2',
|
||||
'@storybook/instrumenter': '8.5.0-alpha.2',
|
||||
'@storybook/react-dom-shim': '8.5.0-alpha.2',
|
||||
'@storybook/source-loader': '8.5.0-alpha.2',
|
||||
'@storybook/test': '8.5.0-alpha.2',
|
||||
'@storybook/preset-create-react-app': '8.5.0-alpha.2',
|
||||
'@storybook/preset-html-webpack': '8.5.0-alpha.2',
|
||||
'@storybook/preset-preact-webpack': '8.5.0-alpha.2',
|
||||
'@storybook/preset-react-webpack': '8.5.0-alpha.2',
|
||||
'@storybook/preset-server-webpack': '8.5.0-alpha.2',
|
||||
'@storybook/preset-svelte-webpack': '8.5.0-alpha.2',
|
||||
'@storybook/preset-vue3-webpack': '8.5.0-alpha.2',
|
||||
'@storybook/html': '8.5.0-alpha.2',
|
||||
'@storybook/preact': '8.5.0-alpha.2',
|
||||
'@storybook/react': '8.5.0-alpha.2',
|
||||
'@storybook/server': '8.5.0-alpha.2',
|
||||
'@storybook/svelte': '8.5.0-alpha.2',
|
||||
'@storybook/vue3': '8.5.0-alpha.2',
|
||||
'@storybook/web-components': '8.5.0-alpha.2',
|
||||
};
|
||||
|
@ -123,6 +123,7 @@ const Item = styled.div<ItemProps>(
|
||||
({ theme }) => ({
|
||||
width: '100%',
|
||||
border: 'none',
|
||||
borderRadius: theme.appBorderRadius,
|
||||
background: 'none',
|
||||
fontSize: theme.typography.size.s1,
|
||||
transition: 'all 150ms ease-out',
|
||||
|
@ -109,7 +109,7 @@ const Wrapper = styled.div<WrapperProps>(
|
||||
drop-shadow(0px 5px 5px rgba(0,0,0,0.05))
|
||||
drop-shadow(0 1px 3px rgba(0,0,0,0.1))
|
||||
`,
|
||||
borderRadius: theme.appBorderRadius,
|
||||
borderRadius: theme.appBorderRadius + 2,
|
||||
fontSize: theme.typography.size.s1,
|
||||
}
|
||||
: {}
|
||||
|
@ -191,3 +191,45 @@ export const WithCustomIcon = {
|
||||
],
|
||||
},
|
||||
} satisfies Story;
|
||||
|
||||
export const WithGroups = {
|
||||
args: {
|
||||
links: [
|
||||
[
|
||||
{
|
||||
id: '1',
|
||||
title: 'Link 1',
|
||||
center: 'This is an addition description',
|
||||
href: 'http://google.com',
|
||||
onClick: onLinkClick,
|
||||
},
|
||||
],
|
||||
[
|
||||
{
|
||||
id: '1',
|
||||
title: 'Link 1',
|
||||
center: 'This is an addition description',
|
||||
icon: <LinkIcon />,
|
||||
href: 'http://google.com',
|
||||
onClick: onLinkClick,
|
||||
},
|
||||
{
|
||||
id: '2',
|
||||
title: 'Link 2',
|
||||
center: 'This is an addition description',
|
||||
href: 'http://google.com',
|
||||
onClick: onLinkClick,
|
||||
},
|
||||
],
|
||||
[
|
||||
{
|
||||
id: '2',
|
||||
title: 'Link 2',
|
||||
center: 'This is an addition description',
|
||||
href: 'http://google.com',
|
||||
onClick: onLinkClick,
|
||||
},
|
||||
],
|
||||
],
|
||||
},
|
||||
} satisfies Story;
|
||||
|
@ -11,13 +11,20 @@ const List = styled.div(
|
||||
minWidth: 180,
|
||||
overflow: 'hidden',
|
||||
overflowY: 'auto',
|
||||
maxHeight: 15.5 * 32, // 11.5 items
|
||||
maxHeight: 15.5 * 32 + 8, // 15.5 items at 32px each + 8px padding
|
||||
},
|
||||
({ theme }) => ({
|
||||
borderRadius: theme.appBorderRadius,
|
||||
borderRadius: theme.appBorderRadius + 2,
|
||||
})
|
||||
);
|
||||
|
||||
const Group = styled.div(({ theme }) => ({
|
||||
padding: 4,
|
||||
'& + &': {
|
||||
borderTop: `1px solid ${theme.appBorderColor}`,
|
||||
},
|
||||
}));
|
||||
|
||||
export interface Link extends Omit<ListItemProps, 'onClick'> {
|
||||
id: string;
|
||||
onClick?: (
|
||||
@ -42,17 +49,26 @@ const Item = ({ id, onClick, ...rest }: ItemProps) => {
|
||||
};
|
||||
|
||||
export interface TooltipLinkListProps extends ComponentProps<typeof List> {
|
||||
links: Link[];
|
||||
links: Link[] | Link[][];
|
||||
LinkWrapper?: LinkWrapperType;
|
||||
}
|
||||
|
||||
export const TooltipLinkList = ({ links, LinkWrapper, ...props }: TooltipLinkListProps) => {
|
||||
const isIndented = links.some((link) => link.icon);
|
||||
const groups = Array.isArray(links[0]) ? (links as Link[][]) : [links as Link[]];
|
||||
const isIndented = groups.some((group) => group.some((link) => link.icon));
|
||||
return (
|
||||
<List {...props}>
|
||||
{links.map((link) => (
|
||||
<Item key={link.id} isIndented={isIndented} LinkWrapper={LinkWrapper} {...link} />
|
||||
))}
|
||||
{groups
|
||||
.filter((group) => group.length)
|
||||
.map((group, index) => {
|
||||
return (
|
||||
<Group key={group.map((link) => link.id).join(`~${index}~`)}>
|
||||
{group.map((link) => (
|
||||
<Item key={link.id} isIndented={isIndented} LinkWrapper={LinkWrapper} {...link} />
|
||||
))}
|
||||
</Group>
|
||||
);
|
||||
})}
|
||||
</List>
|
||||
);
|
||||
};
|
||||
|
@ -1 +1 @@
|
||||
export const version = '8.4.0-beta.3';
|
||||
export const version = '8.5.0-alpha.2';
|
||||
|
@ -8,9 +8,10 @@ import { CloseIcon, CogIcon } from '@storybook/icons';
|
||||
|
||||
import { transparentize } from 'polished';
|
||||
|
||||
import type { useMenu } from '../../container/Menu';
|
||||
import { useLayout } from '../layout/LayoutProvider';
|
||||
|
||||
export type MenuList = ComponentProps<typeof TooltipLinkList>['links'];
|
||||
export type MenuList = ReturnType<typeof useMenu>;
|
||||
|
||||
export const SidebarIconButton: FC<ComponentProps<typeof Button> & { highlighted: boolean }> =
|
||||
styled(IconButton)<
|
||||
@ -60,17 +61,21 @@ const SidebarMenuList: FC<{
|
||||
menu: MenuList;
|
||||
onHide: () => void;
|
||||
}> = ({ menu, onHide }) => {
|
||||
const links = useMemo(() => {
|
||||
return menu.map(({ onClick, ...rest }) => ({
|
||||
...rest,
|
||||
onClick: ((event, item) => {
|
||||
if (onClick) {
|
||||
onClick(event, item);
|
||||
}
|
||||
onHide();
|
||||
}) as ClickHandler,
|
||||
}));
|
||||
}, [menu, onHide]);
|
||||
const links = useMemo(
|
||||
() =>
|
||||
menu.map((group) =>
|
||||
group.map(({ onClick, ...rest }) => ({
|
||||
...rest,
|
||||
onClick: ((event, item) => {
|
||||
if (onClick) {
|
||||
onClick(event, item);
|
||||
}
|
||||
onHide();
|
||||
}) as ClickHandler,
|
||||
}))
|
||||
),
|
||||
[menu, onHide]
|
||||
);
|
||||
return <TooltipLinkList links={links} />;
|
||||
};
|
||||
|
||||
|
@ -85,6 +85,7 @@ const meta = {
|
||||
refs: {},
|
||||
status: {},
|
||||
showCreateStoryButton: true,
|
||||
isDevelopment: true,
|
||||
},
|
||||
decorators: [
|
||||
(storyFn) => (
|
||||
|
@ -109,7 +109,6 @@ const useCombination = (
|
||||
return useMemo(() => ({ hash, entries: Object.entries(hash) }), [hash]);
|
||||
};
|
||||
|
||||
const isDevelopment = global.CONFIG_TYPE === 'DEVELOPMENT';
|
||||
const isRendererReact = global.STORYBOOK_RENDERER === 'react';
|
||||
|
||||
export interface SidebarProps extends API_LoadedRefData {
|
||||
@ -124,6 +123,7 @@ export interface SidebarProps extends API_LoadedRefData {
|
||||
onMenuClick?: HeadingProps['onMenuClick'];
|
||||
showCreateStoryButton?: boolean;
|
||||
indexJson?: StoryIndex;
|
||||
isDevelopment?: boolean;
|
||||
}
|
||||
export const Sidebar = React.memo(function Sidebar({
|
||||
// @ts-expect-error (non strict)
|
||||
@ -138,6 +138,7 @@ export const Sidebar = React.memo(function Sidebar({
|
||||
extra,
|
||||
menuHighlighted = false,
|
||||
enableShortcuts = true,
|
||||
isDevelopment = global.CONFIG_TYPE === 'DEVELOPMENT',
|
||||
refs = {},
|
||||
onMenuClick,
|
||||
showCreateStoryButton = isDevelopment && isRendererReact,
|
||||
@ -229,7 +230,7 @@ export const Sidebar = React.memo(function Sidebar({
|
||||
)}
|
||||
</Search>
|
||||
</Top>
|
||||
{isMobile || isLoading ? null : <SidebarBottom />}
|
||||
{isMobile || isLoading ? null : <SidebarBottom isDevelopment={isDevelopment} />}
|
||||
</ScrollArea>
|
||||
</Container>
|
||||
);
|
||||
|
@ -6,6 +6,7 @@ import { SidebarBottomBase } from './SidebarBottom';
|
||||
export default {
|
||||
component: SidebarBottomBase,
|
||||
args: {
|
||||
isDevelopment: true,
|
||||
api: {
|
||||
clearNotification: fn(),
|
||||
emit: fn(),
|
||||
|
@ -92,9 +92,15 @@ interface SidebarBottomProps {
|
||||
api: API;
|
||||
notifications: State['notifications'];
|
||||
status: State['status'];
|
||||
isDevelopment?: boolean;
|
||||
}
|
||||
|
||||
export const SidebarBottomBase = ({ api, notifications = [], status = {} }: SidebarBottomProps) => {
|
||||
export const SidebarBottomBase = ({
|
||||
api,
|
||||
notifications = [],
|
||||
status = {},
|
||||
isDevelopment,
|
||||
}: SidebarBottomProps) => {
|
||||
const spacerRef = useRef<HTMLDivElement | null>(null);
|
||||
const wrapperRef = useRef<HTMLDivElement | null>(null);
|
||||
const [warningsActive, setWarningsActive] = useState(false);
|
||||
@ -228,27 +234,36 @@ export const SidebarBottomBase = ({ api, notifications = [], status = {} }: Side
|
||||
<div id={SIDEBAR_BOTTOM_SPACER_ID} ref={spacerRef}>
|
||||
<Content id={SIDEBAR_BOTTOM_WRAPPER_ID} ref={wrapperRef}>
|
||||
<NotificationList notifications={notifications} clearNotification={api.clearNotification} />
|
||||
<TestingModule
|
||||
{...{
|
||||
testProviders: testProvidersArray,
|
||||
errorCount: errors.length,
|
||||
errorsActive,
|
||||
setErrorsActive,
|
||||
warningCount: warnings.length,
|
||||
warningsActive,
|
||||
setWarningsActive,
|
||||
onRunTests,
|
||||
onCancelTests,
|
||||
onSetWatchMode,
|
||||
}}
|
||||
/>
|
||||
{isDevelopment && (
|
||||
<TestingModule
|
||||
{...{
|
||||
testProviders: testProvidersArray,
|
||||
errorCount: errors.length,
|
||||
errorsActive,
|
||||
setErrorsActive,
|
||||
warningCount: warnings.length,
|
||||
warningsActive,
|
||||
setWarningsActive,
|
||||
onRunTests,
|
||||
onCancelTests,
|
||||
onSetWatchMode,
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</Content>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export const SidebarBottom = () => {
|
||||
export const SidebarBottom = ({ isDevelopment }: { isDevelopment?: boolean }) => {
|
||||
const api = useStorybookApi();
|
||||
const { notifications, status } = useStorybookState();
|
||||
return <SidebarBottomBase api={api} notifications={notifications} status={status} />;
|
||||
return (
|
||||
<SidebarBottomBase
|
||||
api={api}
|
||||
notifications={notifications}
|
||||
status={status}
|
||||
isDevelopment={isDevelopment}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
@ -7,6 +7,8 @@ import type { Tag } from '@storybook/types';
|
||||
|
||||
import type { API } from '@storybook/core/manager-api';
|
||||
|
||||
import type { Link } from '../../../components/components/tooltip/TooltipLinkList';
|
||||
|
||||
const BUILT_IN_TAGS_SHOW = new Set(['play-fn']);
|
||||
|
||||
const Wrapper = styled.div({
|
||||
@ -29,56 +31,60 @@ export const TagsFilterPanel = ({
|
||||
toggleTag,
|
||||
isDevelopment,
|
||||
}: TagsFilterPanelProps) => {
|
||||
const theme = useTheme();
|
||||
const userTags = allTags.filter((tag) => !BUILT_IN_TAGS_SHOW.has(tag));
|
||||
const docsUrl = api.getDocsUrl({ subpath: 'writing-stories/tags#filtering-by-custom-tags' });
|
||||
const items = allTags.map((tag) => {
|
||||
const checked = selectedTags.includes(tag);
|
||||
const id = `tag-${tag}`;
|
||||
return {
|
||||
id,
|
||||
title: tag,
|
||||
right: (
|
||||
<input
|
||||
type="checkbox"
|
||||
id={id}
|
||||
name={id}
|
||||
value={tag}
|
||||
checked={checked}
|
||||
onChange={() => {
|
||||
// The onClick handler higher up the tree will handle the toggle
|
||||
// For controlled inputs, a onClick handler is needed, though
|
||||
// Accessibility-wise this isn't optimal, but I guess that's a limitation
|
||||
// of the current design of TooltipLinkList
|
||||
}}
|
||||
/>
|
||||
),
|
||||
onClick: () => toggleTag(tag),
|
||||
};
|
||||
}) as any[];
|
||||
|
||||
const groups = [
|
||||
allTags.map((tag) => {
|
||||
const checked = selectedTags.includes(tag);
|
||||
const id = `tag-${tag}`;
|
||||
return {
|
||||
id,
|
||||
title: tag,
|
||||
right: (
|
||||
<input
|
||||
type="checkbox"
|
||||
id={id}
|
||||
name={id}
|
||||
value={tag}
|
||||
checked={checked}
|
||||
onChange={() => {
|
||||
// The onClick handler higher up the tree will handle the toggle
|
||||
// For controlled inputs, a onClick handler is needed, though
|
||||
// Accessibility-wise this isn't optimal, but I guess that's a limitation
|
||||
// of the current design of TooltipLinkList
|
||||
}}
|
||||
/>
|
||||
),
|
||||
onClick: () => toggleTag(tag),
|
||||
};
|
||||
}),
|
||||
] as Link[][];
|
||||
|
||||
if (allTags.length === 0) {
|
||||
items.push({
|
||||
id: 'no-tags',
|
||||
title: 'There are no tags. Use tags to organize and filter your Storybook.',
|
||||
isIndented: false,
|
||||
});
|
||||
}
|
||||
if (userTags.length === 0 && isDevelopment) {
|
||||
items.push({
|
||||
id: 'tags-docs',
|
||||
title: 'Learn how to add tags',
|
||||
icon: <ShareAltIcon />,
|
||||
href: docsUrl,
|
||||
style: {
|
||||
borderTop: `4px solid ${theme.appBorderColor}`,
|
||||
groups.push([
|
||||
{
|
||||
id: 'no-tags',
|
||||
title: 'There are no tags. Use tags to organize and filter your Storybook.',
|
||||
isIndented: false,
|
||||
},
|
||||
});
|
||||
]);
|
||||
}
|
||||
|
||||
if (userTags.length === 0 && isDevelopment) {
|
||||
groups.push([
|
||||
{
|
||||
id: 'tags-docs',
|
||||
title: 'Learn how to add tags',
|
||||
icon: <ShareAltIcon />,
|
||||
href: docsUrl,
|
||||
},
|
||||
]);
|
||||
}
|
||||
|
||||
return (
|
||||
<Wrapper>
|
||||
<TooltipLinkList links={items} />
|
||||
<TooltipLinkList links={groups} />
|
||||
</Wrapper>
|
||||
);
|
||||
};
|
||||
|
@ -229,7 +229,12 @@ export const TestingModule = ({
|
||||
const testing = testProviders.length > 0;
|
||||
|
||||
return (
|
||||
<Outline running={running} crashed={crashed} failed={failed || errorCount > 0}>
|
||||
<Outline
|
||||
id="storybook-testing-module"
|
||||
running={running}
|
||||
crashed={crashed}
|
||||
failed={failed || errorCount > 0}
|
||||
>
|
||||
<Card>
|
||||
<Collapsible
|
||||
style={{
|
||||
|
@ -9,6 +9,8 @@ import { STORIES_COLLAPSE_ALL } from '@storybook/core/core-events';
|
||||
import type { API, State } from '@storybook/core/manager-api';
|
||||
import { shortcutToHumanString } from '@storybook/core/manager-api';
|
||||
|
||||
import type { Link } from '../../components/components/tooltip/TooltipLinkList';
|
||||
|
||||
const focusableUIElements = {
|
||||
storySearchField: 'storybook-explorer-searchfield',
|
||||
storyListMenu: 'storybook-explorer-menu',
|
||||
@ -58,8 +60,7 @@ export const useMenu = (
|
||||
isPanelShown: boolean,
|
||||
isNavShown: boolean,
|
||||
enableShortcuts: boolean
|
||||
) => {
|
||||
const theme = useTheme();
|
||||
): Link[][] => {
|
||||
const shortcutKeys = api.getShortcutKeys();
|
||||
|
||||
const about = useMemo(
|
||||
@ -105,11 +106,8 @@ export const useMenu = (
|
||||
title: 'Keyboard shortcuts',
|
||||
onClick: () => api.changeSettingsTab('shortcuts'),
|
||||
right: enableShortcuts ? <Shortcut keys={shortcutKeys.shortcutsPage} /> : null,
|
||||
style: {
|
||||
borderBottom: `4px solid ${theme.appBorderColor}`,
|
||||
},
|
||||
}),
|
||||
[api, enableShortcuts, shortcutKeys.shortcutsPage, theme.appBorderColor]
|
||||
[api, enableShortcuts, shortcutKeys.shortcutsPage]
|
||||
);
|
||||
|
||||
const sidebarToggle = useMemo(
|
||||
@ -244,24 +242,29 @@ export const useMenu = (
|
||||
}, [api, enableShortcuts, shortcutKeys]);
|
||||
|
||||
return useMemo(
|
||||
() => [
|
||||
about,
|
||||
...(state.whatsNewData?.status === 'SUCCESS' ? [whatsNew] : []),
|
||||
documentation,
|
||||
shortcuts,
|
||||
sidebarToggle,
|
||||
toolbarToogle,
|
||||
addonsToggle,
|
||||
addonsOrientationToggle,
|
||||
fullscreenToggle,
|
||||
searchToggle,
|
||||
up,
|
||||
down,
|
||||
prev,
|
||||
next,
|
||||
collapse,
|
||||
...getAddonsShortcuts(),
|
||||
],
|
||||
() =>
|
||||
[
|
||||
[
|
||||
about,
|
||||
...(state.whatsNewData?.status === 'SUCCESS' ? [whatsNew] : []),
|
||||
documentation,
|
||||
shortcuts,
|
||||
],
|
||||
[
|
||||
sidebarToggle,
|
||||
toolbarToogle,
|
||||
addonsToggle,
|
||||
addonsOrientationToggle,
|
||||
fullscreenToggle,
|
||||
searchToggle,
|
||||
up,
|
||||
down,
|
||||
prev,
|
||||
next,
|
||||
collapse,
|
||||
],
|
||||
getAddonsShortcuts(),
|
||||
] satisfies Link[][],
|
||||
[
|
||||
about,
|
||||
state,
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@storybook/builder-manager",
|
||||
"version": "8.4.0-beta.3",
|
||||
"version": "8.5.0-alpha.2",
|
||||
"description": "Storybook manager builder",
|
||||
"keywords": [
|
||||
"storybook"
|
||||
@ -39,7 +39,7 @@
|
||||
"*.d.ts"
|
||||
],
|
||||
"peerDependencies": {
|
||||
"storybook": "workspace:^"
|
||||
"storybook": "^8.2.0 || ^8.3.0-0 || ^8.4.0-0 || ^8.5.0-0 || ^8.6.0-0"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@storybook/channels",
|
||||
"version": "8.4.0-beta.3",
|
||||
"version": "8.5.0-alpha.2",
|
||||
"description": "",
|
||||
"keywords": [
|
||||
"storybook"
|
||||
@ -39,7 +39,7 @@
|
||||
"*.d.ts"
|
||||
],
|
||||
"peerDependencies": {
|
||||
"storybook": "workspace:^"
|
||||
"storybook": "^8.2.0 || ^8.3.0-0 || ^8.4.0-0 || ^8.5.0-0 || ^8.6.0-0"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@storybook/client-logger",
|
||||
"version": "8.4.0-beta.3",
|
||||
"version": "8.5.0-alpha.2",
|
||||
"description": "",
|
||||
"keywords": [
|
||||
"storybook"
|
||||
@ -39,7 +39,7 @@
|
||||
"*.d.ts"
|
||||
],
|
||||
"peerDependencies": {
|
||||
"storybook": "workspace:^"
|
||||
"storybook": "^8.2.0 || ^8.3.0-0 || ^8.4.0-0 || ^8.5.0-0 || ^8.6.0-0"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@storybook/components",
|
||||
"version": "8.4.0-beta.3",
|
||||
"version": "8.5.0-alpha.2",
|
||||
"description": "Core Storybook Components",
|
||||
"keywords": [
|
||||
"storybook"
|
||||
@ -39,7 +39,7 @@
|
||||
"*.d.ts"
|
||||
],
|
||||
"peerDependencies": {
|
||||
"storybook": "workspace:^"
|
||||
"storybook": "^8.2.0 || ^8.3.0-0 || ^8.4.0-0 || ^8.5.0-0 || ^8.6.0-0"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@storybook/core-common",
|
||||
"version": "8.4.0-beta.3",
|
||||
"version": "8.5.0-alpha.2",
|
||||
"description": "Storybook framework-agnostic API",
|
||||
"keywords": [
|
||||
"storybook"
|
||||
@ -38,7 +38,7 @@
|
||||
"*.d.ts"
|
||||
],
|
||||
"peerDependencies": {
|
||||
"storybook": "workspace:^"
|
||||
"storybook": "^8.2.0 || ^8.3.0-0 || ^8.4.0-0 || ^8.5.0-0 || ^8.6.0-0"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@storybook/core-events",
|
||||
"version": "8.4.0-beta.3",
|
||||
"version": "8.5.0-alpha.2",
|
||||
"description": "Event names used in storybook core",
|
||||
"keywords": [
|
||||
"storybook"
|
||||
@ -70,7 +70,7 @@
|
||||
"*.d.ts"
|
||||
],
|
||||
"peerDependencies": {
|
||||
"storybook": "workspace:^"
|
||||
"storybook": "^8.2.0 || ^8.3.0-0 || ^8.4.0-0 || ^8.5.0-0 || ^8.6.0-0"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@storybook/core-server",
|
||||
"version": "8.4.0-beta.3",
|
||||
"version": "8.5.0-alpha.2",
|
||||
"description": "Storybook framework-agnostic API",
|
||||
"keywords": [
|
||||
"storybook"
|
||||
@ -39,7 +39,7 @@
|
||||
"*.d.ts"
|
||||
],
|
||||
"peerDependencies": {
|
||||
"storybook": "workspace:^"
|
||||
"storybook": "^8.2.0 || ^8.3.0-0 || ^8.4.0-0 || ^8.5.0-0 || ^8.6.0-0"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@storybook/csf-tools",
|
||||
"version": "8.4.0-beta.3",
|
||||
"version": "8.5.0-alpha.2",
|
||||
"description": "Parse and manipulate CSF and Storybook config files",
|
||||
"keywords": [
|
||||
"storybook"
|
||||
@ -38,7 +38,7 @@
|
||||
"*.d.ts"
|
||||
],
|
||||
"peerDependencies": {
|
||||
"storybook": "workspace:^"
|
||||
"storybook": "^8.2.0 || ^8.3.0-0 || ^8.4.0-0 || ^8.5.0-0 || ^8.6.0-0"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@storybook/docs-tools",
|
||||
"version": "8.4.0-beta.3",
|
||||
"version": "8.5.0-alpha.2",
|
||||
"description": "Shared utility functions for frameworks to implement docs",
|
||||
"keywords": [
|
||||
"storybook"
|
||||
@ -39,7 +39,7 @@
|
||||
"*.d.ts"
|
||||
],
|
||||
"peerDependencies": {
|
||||
"storybook": "workspace:^"
|
||||
"storybook": "^8.2.0 || ^8.3.0-0 || ^8.4.0-0 || ^8.5.0-0 || ^8.6.0-0"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@storybook/manager-api",
|
||||
"version": "8.4.0-beta.3",
|
||||
"version": "8.5.0-alpha.2",
|
||||
"description": "Core Storybook Manager API & Context",
|
||||
"keywords": [
|
||||
"storybook"
|
||||
@ -38,7 +38,7 @@
|
||||
"*.d.ts"
|
||||
],
|
||||
"peerDependencies": {
|
||||
"storybook": "workspace:^"
|
||||
"storybook": "^8.2.0 || ^8.3.0-0 || ^8.4.0-0 || ^8.5.0-0 || ^8.6.0-0"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@storybook/manager",
|
||||
"version": "8.4.0-beta.3",
|
||||
"version": "8.5.0-alpha.2",
|
||||
"description": "Core Storybook UI",
|
||||
"keywords": [
|
||||
"storybook"
|
||||
@ -36,7 +36,7 @@
|
||||
"*.d.ts"
|
||||
],
|
||||
"peerDependencies": {
|
||||
"storybook": "workspace:^"
|
||||
"storybook": "^8.2.0 || ^8.3.0-0 || ^8.4.0-0 || ^8.5.0-0 || ^8.6.0-0"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@storybook/node-logger",
|
||||
"version": "8.4.0-beta.3",
|
||||
"version": "8.5.0-alpha.2",
|
||||
"description": "",
|
||||
"keywords": [
|
||||
"storybook"
|
||||
@ -39,7 +39,7 @@
|
||||
"*.d.ts"
|
||||
],
|
||||
"peerDependencies": {
|
||||
"storybook": "workspace:^"
|
||||
"storybook": "^8.2.0 || ^8.3.0-0 || ^8.4.0-0 || ^8.5.0-0 || ^8.6.0-0"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@storybook/preview-api",
|
||||
"version": "8.4.0-beta.3",
|
||||
"version": "8.5.0-alpha.2",
|
||||
"description": "",
|
||||
"keywords": [
|
||||
"storybook"
|
||||
@ -40,7 +40,7 @@
|
||||
"*.d.ts"
|
||||
],
|
||||
"peerDependencies": {
|
||||
"storybook": "workspace:^"
|
||||
"storybook": "^8.2.0 || ^8.3.0-0 || ^8.4.0-0 || ^8.5.0-0 || ^8.6.0-0"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@storybook/preview",
|
||||
"version": "8.4.0-beta.3",
|
||||
"version": "8.5.0-alpha.2",
|
||||
"description": "",
|
||||
"keywords": [
|
||||
"storybook"
|
||||
@ -36,7 +36,7 @@
|
||||
"*.d.ts"
|
||||
],
|
||||
"peerDependencies": {
|
||||
"storybook": "workspace:^"
|
||||
"storybook": "^8.2.0 || ^8.3.0-0 || ^8.4.0-0 || ^8.5.0-0 || ^8.6.0-0"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@storybook/router",
|
||||
"version": "8.4.0-beta.3",
|
||||
"version": "8.5.0-alpha.2",
|
||||
"description": "Core Storybook Router",
|
||||
"keywords": [
|
||||
"storybook"
|
||||
@ -44,7 +44,7 @@
|
||||
"*.d.ts"
|
||||
],
|
||||
"peerDependencies": {
|
||||
"storybook": "workspace:^"
|
||||
"storybook": "^8.2.0 || ^8.3.0-0 || ^8.4.0-0 || ^8.5.0-0 || ^8.6.0-0"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@storybook/telemetry",
|
||||
"version": "8.4.0-beta.3",
|
||||
"version": "8.5.0-alpha.2",
|
||||
"description": "Telemetry logging for crash reports and usage statistics",
|
||||
"keywords": [
|
||||
"storybook"
|
||||
@ -39,7 +39,7 @@
|
||||
"*.d.ts"
|
||||
],
|
||||
"peerDependencies": {
|
||||
"storybook": "workspace:^"
|
||||
"storybook": "^8.2.0 || ^8.3.0-0 || ^8.4.0-0 || ^8.5.0-0 || ^8.6.0-0"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@storybook/theming",
|
||||
"version": "8.4.0-beta.3",
|
||||
"version": "8.5.0-alpha.2",
|
||||
"description": "Core Storybook Components",
|
||||
"keywords": [
|
||||
"storybook"
|
||||
@ -44,7 +44,7 @@
|
||||
"*.d.ts"
|
||||
],
|
||||
"peerDependencies": {
|
||||
"storybook": "workspace:^"
|
||||
"storybook": "^8.2.0 || ^8.3.0-0 || ^8.4.0-0 || ^8.5.0-0 || ^8.6.0-0"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@storybook/types",
|
||||
"version": "8.4.0-beta.3",
|
||||
"version": "8.5.0-alpha.2",
|
||||
"description": "Core Storybook TS Types",
|
||||
"keywords": [
|
||||
"storybook"
|
||||
@ -39,7 +39,7 @@
|
||||
"*.d.ts"
|
||||
],
|
||||
"peerDependencies": {
|
||||
"storybook": "workspace:^"
|
||||
"storybook": "^8.2.0 || ^8.3.0-0 || ^8.4.0-0 || ^8.5.0-0 || ^8.6.0-0"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@storybook/angular",
|
||||
"version": "8.4.0-beta.3",
|
||||
"version": "8.5.0-alpha.2",
|
||||
"description": "Storybook for Angular: Develop Angular components in isolation with hot reloading.",
|
||||
"keywords": [
|
||||
"storybook",
|
||||
@ -38,12 +38,12 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@storybook/builder-webpack5": "workspace:*",
|
||||
"@storybook/components": "workspace:^",
|
||||
"@storybook/components": "workspace:*",
|
||||
"@storybook/core-webpack": "workspace:*",
|
||||
"@storybook/global": "^5.0.0",
|
||||
"@storybook/manager-api": "workspace:^",
|
||||
"@storybook/preview-api": "workspace:^",
|
||||
"@storybook/theming": "workspace:^",
|
||||
"@storybook/manager-api": "workspace:*",
|
||||
"@storybook/preview-api": "workspace:*",
|
||||
"@storybook/theming": "workspace:*",
|
||||
"@types/node": "^22.0.0",
|
||||
"@types/react": "^18.0.37",
|
||||
"@types/react-dom": "^18.0.11",
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@storybook/ember",
|
||||
"version": "8.4.0-beta.3",
|
||||
"version": "8.5.0-alpha.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": {
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@storybook/experimental-nextjs-vite",
|
||||
"version": "8.4.0-beta.3",
|
||||
"version": "8.5.0-alpha.2",
|
||||
"description": "Storybook for Next.js and Vite",
|
||||
"keywords": [
|
||||
"storybook",
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@storybook/html-vite",
|
||||
"version": "8.4.0-beta.3",
|
||||
"version": "8.5.0-alpha.2",
|
||||
"description": "Storybook for HTML and Vite: Develop HTML in isolation with Hot Reloading.",
|
||||
"keywords": [
|
||||
"storybook"
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@storybook/html-webpack5",
|
||||
"version": "8.4.0-beta.3",
|
||||
"version": "8.5.0-alpha.2",
|
||||
"description": "Storybook for HTML: View HTML snippets in isolation with Hot Reloading.",
|
||||
"keywords": [
|
||||
"storybook"
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@storybook/nextjs",
|
||||
"version": "8.4.0-beta.3",
|
||||
"version": "8.5.0-alpha.2",
|
||||
"description": "Storybook for Next.js",
|
||||
"keywords": [
|
||||
"storybook",
|
||||
@ -156,7 +156,7 @@
|
||||
"postcss-loader": "^8.1.1",
|
||||
"react-refresh": "^0.14.0",
|
||||
"resolve-url-loader": "^5.0.0",
|
||||
"sass-loader": "^13.2.0",
|
||||
"sass-loader": "^14.2.1",
|
||||
"semver": "^7.3.5",
|
||||
"style-loader": "^3.3.1",
|
||||
"styled-jsx": "^5.1.6",
|
||||
|
@ -36,16 +36,16 @@ export const configureConfig = async ({
|
||||
addScopedAlias(baseConfig, 'react', 'next/dist/compiled/react');
|
||||
}
|
||||
if (tryResolve('next/dist/compiled/react-dom/cjs/react-dom-test-utils.production.js')) {
|
||||
setAlias(
|
||||
addScopedAlias(
|
||||
baseConfig,
|
||||
'react-dom/test-utils',
|
||||
'next/dist/compiled/react-dom/cjs/react-dom-test-utils.production.js'
|
||||
);
|
||||
}
|
||||
if (tryResolve('next/dist/compiled/react-dom')) {
|
||||
setAlias(baseConfig, 'react-dom$', 'next/dist/compiled/react-dom');
|
||||
setAlias(baseConfig, 'react-dom/client', 'next/dist/compiled/react-dom/client');
|
||||
setAlias(baseConfig, 'react-dom/server', 'next/dist/compiled/react-dom/server');
|
||||
addScopedAlias(baseConfig, 'react-dom$', 'next/dist/compiled/react-dom');
|
||||
addScopedAlias(baseConfig, 'react-dom/client', 'next/dist/compiled/react-dom/client');
|
||||
addScopedAlias(baseConfig, 'react-dom/server', 'next/dist/compiled/react-dom/server');
|
||||
}
|
||||
|
||||
setupRuntimeConfig(baseConfig, nextConfig);
|
||||
|
@ -51,18 +51,36 @@ export const addScopedAlias = (baseConfig: WebpackConfig, name: string, alias?:
|
||||
};
|
||||
|
||||
/**
|
||||
* @example // before main script path truncation require.resolve('styled-jsx') ===
|
||||
* '/some/path/node_modules/styled-jsx/index.js // after main script path truncation
|
||||
* scopedResolve('styled-jsx') === '/some/path/node_modules/styled-jsx'
|
||||
* @example
|
||||
*
|
||||
* @param id The module id
|
||||
* @returns A path to the module id scoped to the project folder without the main script path at the
|
||||
* end
|
||||
* ```
|
||||
* // before main script path truncation
|
||||
* require.resolve('styled-jsx') === '/some/path/node_modules/styled-jsx/index.js
|
||||
* // after main script path truncation
|
||||
* scopedResolve('styled-jsx') === '/some/path/node_modules/styled-jsx'
|
||||
* ```
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* ```
|
||||
* // referencing a named export of a package
|
||||
* scopedResolve('next/dist/compiled/react-dom/client') ===
|
||||
* // returns the path to the package export without the script filename
|
||||
* '/some/path/node_modules/next/dist/compiled/react-dom/client';
|
||||
*
|
||||
* // referencing a specific file within a CJS package
|
||||
* scopedResolve('next/dist/compiled/react-dom/cjs/react-dom-test-utils.production.js') ===
|
||||
* // returns the path to the physical file, including the script filename
|
||||
* '/some/path/node_modules/next/dist/compiled/react-dom/cjs/react-dom-test-utils.production.js';
|
||||
* ```
|
||||
*
|
||||
* @param id The module id or script file to resolve
|
||||
* @returns An absolute path to the specified module id or script file scoped to the project folder
|
||||
* @summary
|
||||
* This is to help the addon in development.
|
||||
* Without it, the addon resolves packages in its node_modules instead of the example's node_modules.
|
||||
* Because require.resolve will also include the main script as part of the path, this function strips
|
||||
* that to just include the path to the module folder
|
||||
* that to just include the path to the module folder when the id provided is a package or named export.
|
||||
*/
|
||||
export const scopedResolve = (id: string): string => {
|
||||
let scopedModulePath;
|
||||
@ -74,9 +92,15 @@ export const scopedResolve = (id: string): string => {
|
||||
scopedModulePath = require.resolve(id);
|
||||
}
|
||||
|
||||
const moduleFolderStrPosition = scopedModulePath.lastIndexOf(
|
||||
id.replace(/\//g /* all '/' occurances */, sep)
|
||||
);
|
||||
const idWithNativePathSep = id.replace(/\//g /* all '/' occurrences */, sep);
|
||||
|
||||
// If the id referenced the file specifically, return the full module path & filename
|
||||
if (scopedModulePath.endsWith(idWithNativePathSep)) {
|
||||
return scopedModulePath;
|
||||
}
|
||||
|
||||
// Otherwise, return just the path to the module folder or named export
|
||||
const moduleFolderStrPosition = scopedModulePath.lastIndexOf(idWithNativePathSep);
|
||||
const beginningOfMainScriptPath = moduleFolderStrPosition + id.length;
|
||||
return scopedModulePath.substring(0, beginningOfMainScriptPath);
|
||||
};
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@storybook/preact-vite",
|
||||
"version": "8.4.0-beta.3",
|
||||
"version": "8.5.0-alpha.2",
|
||||
"description": "Storybook for Preact and Vite: Develop Preact components in isolation with Hot Reloading.",
|
||||
"keywords": [
|
||||
"storybook"
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@storybook/preact-webpack5",
|
||||
"version": "8.4.0-beta.3",
|
||||
"version": "8.5.0-alpha.2",
|
||||
"description": "Storybook for Preact: Develop Preact Component in isolation.",
|
||||
"keywords": [
|
||||
"storybook"
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@storybook/react-vite",
|
||||
"version": "8.4.0-beta.3",
|
||||
"version": "8.5.0-alpha.2",
|
||||
"description": "Storybook for React and Vite: Develop React components in isolation with Hot Reloading.",
|
||||
"keywords": [
|
||||
"storybook"
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@storybook/react-webpack5",
|
||||
"version": "8.4.0-beta.3",
|
||||
"version": "8.5.0-alpha.2",
|
||||
"description": "Storybook for React: Develop React Component in isolation with Hot Reloading.",
|
||||
"keywords": [
|
||||
"storybook"
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@storybook/server-webpack5",
|
||||
"version": "8.4.0-beta.3",
|
||||
"version": "8.5.0-alpha.2",
|
||||
"description": "Storybook for Server: View HTML snippets from a server in isolation with Hot Reloading.",
|
||||
"keywords": [
|
||||
"storybook"
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@storybook/svelte-vite",
|
||||
"version": "8.4.0-beta.3",
|
||||
"version": "8.5.0-alpha.2",
|
||||
"description": "Storybook for Svelte and Vite: Develop Svelte components in isolation with Hot Reloading.",
|
||||
"keywords": [
|
||||
"storybook"
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@storybook/svelte-webpack5",
|
||||
"version": "8.4.0-beta.3",
|
||||
"version": "8.5.0-alpha.2",
|
||||
"description": "Storybook for Svelte: Develop Svelte Component in isolation with Hot Reloading.",
|
||||
"keywords": [
|
||||
"storybook"
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@storybook/sveltekit",
|
||||
"version": "8.4.0-beta.3",
|
||||
"version": "8.5.0-alpha.2",
|
||||
"description": "Storybook for SvelteKit",
|
||||
"keywords": [
|
||||
"storybook",
|
||||
|
@ -1,16 +1,21 @@
|
||||
import { resolve } from 'node:path';
|
||||
import { dirname, resolve } from 'node:path';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
|
||||
import type { Plugin } from 'vite';
|
||||
|
||||
// @ts-expect-error We are building for CJS and ESM, so we have to use import.meta.url for the ESM output
|
||||
const filename = __filename ?? fileURLToPath(import.meta.url);
|
||||
const dir = dirname(filename);
|
||||
|
||||
export async function mockSveltekitStores() {
|
||||
return {
|
||||
name: 'storybook:sveltekit-mock-stores',
|
||||
config: () => ({
|
||||
resolve: {
|
||||
alias: {
|
||||
'$app/forms': resolve(__dirname, '../src/mocks/app/forms.ts'),
|
||||
'$app/navigation': resolve(__dirname, '../src/mocks/app/navigation.ts'),
|
||||
'$app/stores': resolve(__dirname, '../src/mocks/app/stores.ts'),
|
||||
'$app/forms': resolve(dir, '../src/mocks/app/forms.ts'),
|
||||
'$app/navigation': resolve(dir, '../src/mocks/app/navigation.ts'),
|
||||
'$app/stores': resolve(dir, '../src/mocks/app/stores.ts'),
|
||||
},
|
||||
},
|
||||
}),
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@storybook/vue3-vite",
|
||||
"version": "8.4.0-beta.3",
|
||||
"version": "8.5.0-alpha.2",
|
||||
"description": "Storybook for Vue3 and Vite: Develop Vue3 components in isolation with Hot Reloading.",
|
||||
"keywords": [
|
||||
"storybook"
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@storybook/vue3-webpack5",
|
||||
"version": "8.4.0-beta.3",
|
||||
"version": "8.5.0-alpha.2",
|
||||
"description": "Storybook for Vue 3: Develop Vue 3 Components in isolation with Hot Reloading.",
|
||||
"keywords": [
|
||||
"storybook"
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@storybook/web-components-vite",
|
||||
"version": "8.4.0-beta.3",
|
||||
"version": "8.5.0-alpha.2",
|
||||
"description": "Storybook for web-components and Vite: Develop Web Components in isolation with Hot Reloading.",
|
||||
"keywords": [
|
||||
"storybook"
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@storybook/web-components-webpack5",
|
||||
"version": "8.4.0-beta.3",
|
||||
"version": "8.5.0-alpha.2",
|
||||
"description": "Storybook for web-components: View web components snippets in isolation with Hot Reloading.",
|
||||
"keywords": [
|
||||
"lit",
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@storybook/blocks",
|
||||
"version": "8.4.0-beta.3",
|
||||
"version": "8.5.0-alpha.2",
|
||||
"description": "Storybook Doc Blocks",
|
||||
"keywords": [
|
||||
"storybook"
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "sb",
|
||||
"version": "8.4.0-beta.3",
|
||||
"version": "8.5.0-alpha.2",
|
||||
"description": "Storybook CLI",
|
||||
"keywords": [
|
||||
"storybook"
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@storybook/cli",
|
||||
"version": "8.4.0-beta.3",
|
||||
"version": "8.5.0-alpha.2",
|
||||
"description": "Storybook CLI",
|
||||
"keywords": [
|
||||
"storybook"
|
||||
|
@ -43,7 +43,7 @@ const command = (name: string) =>
|
||||
command('add <addon>')
|
||||
.description('Add an addon to your Storybook')
|
||||
.option(
|
||||
'--package-manager <npm|pnpm|yarn1|yarn2>',
|
||||
'--package-manager <npm|pnpm|yarn1|yarn2|bun>',
|
||||
'Force package manager for installing dependencies'
|
||||
)
|
||||
.option('-c, --config-dir <dir-name>', 'Directory where to load Storybook configurations from')
|
||||
@ -54,7 +54,7 @@ command('add <addon>')
|
||||
command('remove <addon>')
|
||||
.description('Remove an addon from your Storybook')
|
||||
.option(
|
||||
'--package-manager <npm|pnpm|yarn1|yarn2>',
|
||||
'--package-manager <npm|pnpm|yarn1|yarn2|bun>',
|
||||
'Force package manager for installing dependencies'
|
||||
)
|
||||
.option('-c, --config-dir <dir-name>', 'Directory where to load Storybook configurations from')
|
||||
@ -70,7 +70,7 @@ command('remove <addon>')
|
||||
command('upgrade')
|
||||
.description(`Upgrade your Storybook packages to v${versions.storybook}`)
|
||||
.option(
|
||||
'--package-manager <npm|pnpm|yarn1|yarn2>',
|
||||
'--package-manager <npm|pnpm|yarn1|yarn2|bun>',
|
||||
'Force package manager for installing dependencies'
|
||||
)
|
||||
.option('-y --yes', 'Skip prompting the user')
|
||||
@ -157,7 +157,7 @@ command('automigrate [fixId]')
|
||||
.description('Check storybook for incompatibilities or migrations and apply fixes')
|
||||
.option('-y --yes', 'Skip prompting the user')
|
||||
.option('-n --dry-run', 'Only check for fixes, do not actually run them')
|
||||
.option('--package-manager <npm|pnpm|yarn1|yarn2>', 'Force package manager')
|
||||
.option('--package-manager <npm|pnpm|yarn1|yarn2|bun>', 'Force package manager')
|
||||
.option('-l --list', 'List available migrations')
|
||||
.option('-c, --config-dir <dir-name>', 'Directory of Storybook configurations to migrate')
|
||||
.option('-s --skip-install', 'Skip installing deps')
|
||||
@ -174,7 +174,7 @@ command('automigrate [fixId]')
|
||||
|
||||
command('doctor')
|
||||
.description('Check Storybook for known problems and provide suggestions or fixes')
|
||||
.option('--package-manager <npm|pnpm|yarn1|yarn2>', 'Force package manager')
|
||||
.option('--package-manager <npm|pnpm|yarn1|yarn2|bun>', 'Force package manager')
|
||||
.option('-c, --config-dir <dir-name>', 'Directory of Storybook configuration')
|
||||
.action(async (options) => {
|
||||
await doctor(options).catch((e) => {
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "storybook",
|
||||
"version": "8.4.0-beta.3",
|
||||
"version": "8.5.0-alpha.2",
|
||||
"description": "Storybook's CLI - install, dev, build, upgrade, and more",
|
||||
"keywords": [
|
||||
"cli",
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@storybook/codemod",
|
||||
"version": "8.4.0-beta.3",
|
||||
"version": "8.5.0-alpha.2",
|
||||
"description": "A collection of codemod scripts written with JSCodeshift",
|
||||
"keywords": [
|
||||
"storybook"
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@storybook/core-webpack",
|
||||
"version": "8.4.0-beta.3",
|
||||
"version": "8.5.0-alpha.2",
|
||||
"description": "Storybook framework-agnostic API",
|
||||
"keywords": [
|
||||
"storybook"
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "create-storybook",
|
||||
"version": "8.4.0-beta.3",
|
||||
"version": "8.5.0-alpha.2",
|
||||
"description": "Initialize Storybook into your project",
|
||||
"homepage": "https://github.com/storybookjs/storybook/tree/next/code/lib/create-storybook",
|
||||
"bugs": {
|
||||
|
@ -25,7 +25,10 @@ program
|
||||
.option('--enable-crash-reports', 'Enable sending crash reports to telemetry data')
|
||||
.option('-f --force', 'Force add Storybook')
|
||||
.option('-s --skip-install', 'Skip installing deps')
|
||||
.option('--package-manager <npm|pnpm|yarn1|yarn2>', 'Force package manager for installing deps')
|
||||
.option(
|
||||
'--package-manager <npm|pnpm|yarn1|yarn2|bun>',
|
||||
'Force package manager for installing deps'
|
||||
)
|
||||
.option('--use-pnp', 'Enable pnp mode for Yarn 2+')
|
||||
.option('-p --parser <babel | babylon | flow | ts | tsx>', 'jscodeshift parser')
|
||||
.option('-t --type <type>', 'Add Storybook for a specific project type')
|
||||
|
@ -245,7 +245,7 @@ export async function baseGenerator(
|
||||
].filter(Boolean);
|
||||
|
||||
// TODO: migrate template stories in solid and qwik to use @storybook/test
|
||||
if (['solid', 'qwik'].includes(rendererId)) {
|
||||
if (['qwik'].includes(rendererId)) {
|
||||
addonPackages.push('@storybook/testing-library');
|
||||
} else {
|
||||
addonPackages.push('@storybook/test');
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@storybook/csf-plugin",
|
||||
"version": "8.4.0-beta.3",
|
||||
"version": "8.5.0-alpha.2",
|
||||
"description": "Enrich CSF files via static analysis",
|
||||
"keywords": [
|
||||
"storybook"
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@storybook/instrumenter",
|
||||
"version": "8.4.0-beta.3",
|
||||
"version": "8.5.0-alpha.2",
|
||||
"description": "",
|
||||
"keywords": [
|
||||
"storybook"
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@storybook/react-dom-shim",
|
||||
"version": "8.4.0-beta.3",
|
||||
"version": "8.5.0-alpha.2",
|
||||
"description": "",
|
||||
"keywords": [
|
||||
"storybook"
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@storybook/source-loader",
|
||||
"version": "8.4.0-beta.3",
|
||||
"version": "8.5.0-alpha.2",
|
||||
"description": "Source loader",
|
||||
"keywords": [
|
||||
"lib",
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user