diff --git a/CHANGELOG.prerelease.md b/CHANGELOG.prerelease.md index 53ddf862c349..18b151809ed3 100644 --- a/CHANGELOG.prerelease.md +++ b/CHANGELOG.prerelease.md @@ -1,3 +1,12 @@ +## 7.2.2-alpha.1 + +- CSF-Tools: Remove prettier from printConfig - [#23766](https://github.com/storybookjs/storybook/pull/23766), thanks [@kasperpeulen](https://github.com/kasperpeulen)! +- UI: Improve Link component - [#23767](https://github.com/storybookjs/storybook/pull/23767), thanks [@cdedreuille](https://github.com/cdedreuille)! +- UI: Improve new `Button` component - [#23765](https://github.com/storybookjs/storybook/pull/23765), thanks [@cdedreuille](https://github.com/cdedreuille)! +- UI: Update Button types to allow for no children on iconOnly buttons - [#23735](https://github.com/storybookjs/storybook/pull/23735), thanks [@cdedreuille](https://github.com/cdedreuille)! +- UI: Upgrade Icon component - [#23680](https://github.com/storybookjs/storybook/pull/23680), thanks [@cdedreuille](https://github.com/cdedreuille)! +- WebpackBuilder: Remove need for `react` as peerDependency - [#23496](https://github.com/storybookjs/storybook/pull/23496), thanks [@ndelangen](https://github.com/ndelangen)! + ## 7.2.2-alpha.0 - Indexer: Introduce new experimental `indexer` API - #23691, thanks [@JReinhold](https://github.com/jreinhold)! diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index d0ddac9871db..77e1f6fc0955 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,6 +1,7 @@ # Getting started -- Ensure you have node version 16 installed (suggestion: v16.5). +Storybook is developed against a specific node version. We recommend using [Volta](https://volta.sh/) as it will automatically install the correct node and yarn version when you first use the repo. If you chose not to use Volta please ensure you you have node version 16 installed (suggestion: v16.5) + - Ensure if you are using Windows to use the Windows Subsystem for Linux (WSL). - Run `yarn start` in the root directory to run a basic test Storybook "sandbox". @@ -31,4 +32,4 @@ yarn task --task dev --template --start-from=publish # Contributing to Storybook -For further advice on how to contribute, please refer to our [NEW contributing guide on the Storybook website](https://storybook.js.org/docs/next/react/contribute/how-to-contribute). +For further advice on how to contribute, please refer to our [NEW contributing guide on the Storybook website](https://storybook.js.org/docs/react/contribute/how-to-contribute). diff --git a/RELEASES.md b/RELEASES.md deleted file mode 100644 index 88557cf2fbeb..000000000000 --- a/RELEASES.md +++ /dev/null @@ -1,117 +0,0 @@ -# Release Process - -A Storybook release process based on [Semver](http://semver.org/). In short: - -1. Merge all PRs into `next`, which is the default branch. Cherry-pick bugfix PRs into `main`, which is the stable release. - -2. Every week: release patch releases off `main` to the NPM tag `latest`, and alpha releases off `next` to the NPM tag `next` (as e.g. `4.1.0-alpha.0`). - -3. Every month or two, merge `next` into `main` and release a minor/major version according to `semver`. We set minor release dates as soon as we have feature clarity and manage to those dates: - - Date should be a Monday so if we slip we don't get pushed into the weekend - - T-3wk: - - Draft announcement and socialize - - Announce dates in #maintenance so people can react - - T-1wk: - - If you want your feature in the release, it should already be released on next by this time - - Create release branch and only cherrypick bugfixes - - Set up launch plan - -## Motivation - -During the Storybook 3.x transition we've undergone a series of growing pains as -we've opened up the development process. We've had questions about: - -1. how to adhere to semver? -2. how to do marketing releases (while adhering to semver)? -3. how to introduce significant new features (e.g. vue support, story hierarchy)? -4. how to converge on key design decisions (e.g. new addons API)? -5. how to schedule releases? -6. how to maintain quality/stability through the process? -7. how to pay down tech debt as we go? - -This process attempts to address all these concerns in one shot. - -## Semver - -[Semver](http://semver.org/) dictates three types of release: - -1. MAJOR version when you make incompatible API changes, -2. MINOR version when you add functionality in a backwards-compatible manner, and -3. PATCH version when you make backwards-compatible bug fixes. - -We'll do our best to adhere to Semver, but won't be religious about it. In -particular, we may occasionally release small bits of new functionality in PATCH -releases. We'll try our best to restrict breaking changes to MAJOR releases. - -## PATCH releases - -Every bugfix should go out as soon as we've verified the fix, and based on the -current rate of contribution, we should be issuing PATCH releases weekly. -Eventually, we'll automate the process so that a release will go out every time a PR is -merged into `main`, and we've already laid most of the groundwork for this. - -## MINOR releases - -Every new feature, particularly significant ones (e.g. Vue support, deep -hierarchy for stories) deserves more attention: - -1. They should be well-tested by the community before we release. -2. They often have architectural implications for the entire Storybook ecosystem, so should be discussed thoroughly before release. Doing `alpha` releases allow us to test in the community without necessarily achieving agreement. -3. They often deserve proper marketing treatment (blog posts, release announcement, podcast, etc.) - -Therefore we release `alpha` versions continuously on the NPM `next` tag to allow people to test out features as soon as they are ready. - -In general, we should release 2-3 headline features per minor release for -marketing purposes. Each headline feature should get its own blog post on the -Storybook medium publication, and the release itself should also get a blog -post. - -## MAJOR releases - -We should avoid major releases, but won't hold ourselves back on this. Making storybook better is the prime directive, and if we have to make breaking changes to do it, we will. That said, MAJOR releases -should have killer features that reward users for upgrading, and should not be -used to scratch our own architectural itches -- unless those itches are really -killing development in some meaningful way. - -## Blocking bugs - -Most PATCH releases come from community members, who generously fix problems as -they come up. However, there are also bugs that never get picked up and just sit -there gathering upvotes and "me too" comments. We need a way to make sure that -these bugs get addressed. - -For every non-PATCH release, we nominate a small number of bugs that must be -addressed before a release can go out by adding them to the milestone. For example, here's a list of blocking bugs [for the 6.5 milestone](https://github.com/storybookjs/storybook/milestone/75). - -Adding bugs to the milestone helps people looking for good ways to contribute, -or to understand what is blocking the release so they can actually do something -about it. Discussion about which bugs are critical happens in the [`#maintenance` channel](https://discord.com/channels/486522875931656193/490070912448724992) in our Discord Server - -If you're experiencing a bug, the best way to make sure that it gets attention -is to upvote it by adding a "thumbs-up" reaction in Github. This way important -bugs quickly bubble to the top [with a -search](https://github.com/storybookjs/storybook/issues?utf8=%E2%9C%93&q=is%3Aissue%20is%3Aopen%20sort%3Areactions-%2B1-desc%20label%3Abug). - -The best way to make sure a bug gets addressed quickly is to fix -it yourself and issue a PR. If the fix is good, we'll try to release it quickly -in a patch release. - -## Decision-making - -- For PATCH changes, all discussion can occur in issue/PR comments (and random slack chat as needed). -- For MINOR feature changes, there are multiple stages of discussion: - - The feature may be discussed in an issue before it is implemented (ex: ) - - Once it's implemented, the discussion may occur on the PR (ex: ) - - If people disagree on an implementation and it can't be resolved in discussion, they may issue alternative PR's with different ideas - - Ultimately the maintainers will reach a consensus before merging the changes. There is no set process for this, but we're all adults. - - Since MINOR features are released in alpha before they are fully released, new issues may be created by end users, etc. -- For MAJOR infrastructural changes, the discussion may take place over time, in gists, issues, slack discussions, etc. - - Once the breaking changes have been reduced to an actual implementation, it looks pretty much like a feature release (only with higher stakes and probably a longer stabilization process). - -## FAQ's - -#### How does my PR get merged? - -- For PATCH PR's, any maintainer can review, test, approve, and merge it. -- For MINOR/MAJOR PR's, once a maintainer reviews, tests, and approves it, they should clear it with the other maintainers before merging it into the release branch. -- Once a release date has been set and we cut off merging, we'll create a temporary branch to hold that release so that it doesn't block merging to `next`. diff --git a/code/addons/a11y/src/components/VisionSimulator.tsx b/code/addons/a11y/src/components/VisionSimulator.tsx index b66f8eef297d..b43756897364 100644 --- a/code/addons/a11y/src/components/VisionSimulator.tsx +++ b/code/addons/a11y/src/components/VisionSimulator.tsx @@ -1,7 +1,8 @@ import type { ReactNode } from 'react'; import React, { useState } from 'react'; import { Global, styled } from '@storybook/theming'; -import { Icons, IconButton, WithTooltip, TooltipLinkList } from '@storybook/components'; +import { IconButton, WithTooltip, TooltipLinkList } from '@storybook/components'; +import { Icon } from '@storybook/components/experimental'; import { Filters } from './ColorFilters'; @@ -144,7 +145,7 @@ export const VisionSimulator = () => { onDoubleClick={() => setFilter(null)} > - + diff --git a/code/addons/backgrounds/src/containers/BackgroundSelector.tsx b/code/addons/backgrounds/src/containers/BackgroundSelector.tsx index 078a2752a5e3..d44d7f58ab6b 100644 --- a/code/addons/backgrounds/src/containers/BackgroundSelector.tsx +++ b/code/addons/backgrounds/src/containers/BackgroundSelector.tsx @@ -4,7 +4,8 @@ import memoize from 'memoizerific'; import { useParameter, useGlobals } from '@storybook/manager-api'; import { logger } from '@storybook/client-logger'; -import { Icons, IconButton, WithTooltip, TooltipLinkList } from '@storybook/components'; +import { IconButton, WithTooltip, TooltipLinkList } from '@storybook/components'; +import { Icon } from '@storybook/components/experimental'; import { PARAM_KEY as BACKGROUNDS_PARAM_KEY } from '../constants'; import { ColorIcon } from '../components/ColorIcon'; @@ -140,7 +141,7 @@ export const BackgroundSelector: FC = memo(function BackgroundSelector() { title="Change the background of the preview" active={selectedBackgroundColor !== 'transparent' || isTooltipVisible} > - + diff --git a/code/addons/backgrounds/src/containers/GridSelector.tsx b/code/addons/backgrounds/src/containers/GridSelector.tsx index 80d6477884b4..b860209ae0ae 100644 --- a/code/addons/backgrounds/src/containers/GridSelector.tsx +++ b/code/addons/backgrounds/src/containers/GridSelector.tsx @@ -2,7 +2,8 @@ import type { FC } from 'react'; import React, { memo } from 'react'; import { useGlobals, useParameter } from '@storybook/manager-api'; -import { Icons, IconButton } from '@storybook/components'; +import { IconButton } from '@storybook/components'; +import { Icon } from '@storybook/components/experimental'; import { PARAM_KEY as BACKGROUNDS_PARAM_KEY } from '../constants'; @@ -30,7 +31,7 @@ export const GridSelector: FC = memo(function GridSelector() { }) } > - + ); }); diff --git a/code/addons/interactions/src/components/Interaction.tsx b/code/addons/interactions/src/components/Interaction.tsx index bacaea0fe358..c0bf532d9072 100644 --- a/code/addons/interactions/src/components/Interaction.tsx +++ b/code/addons/interactions/src/components/Interaction.tsx @@ -1,5 +1,6 @@ import * as React from 'react'; -import { IconButton, Icons, TooltipNote, WithTooltip } from '@storybook/components'; +import { IconButton, TooltipNote, WithTooltip } from '@storybook/components'; +import { Icon } from '@storybook/components/experimental'; import { type Call, CallStates, type ControlStates } from '@storybook/instrumenter'; import { styled, typography } from '@storybook/theming'; import { transparentize } from 'polished'; @@ -174,7 +175,7 @@ export const Interaction = ({ tooltip={} > - + )} diff --git a/code/addons/interactions/src/components/Subnav.tsx b/code/addons/interactions/src/components/Subnav.tsx index 3d2e5c41d1a3..de78bf2c94b6 100644 --- a/code/addons/interactions/src/components/Subnav.tsx +++ b/code/addons/interactions/src/components/Subnav.tsx @@ -3,13 +3,13 @@ import React from 'react'; import { Button, IconButton, - Icons, Separator, P, TooltipNote, WithTooltip, Bar, } from '@storybook/components'; +import { Icon } from '@storybook/components/experimental'; import type { Call, ControlStates } from '@storybook/instrumenter'; import { CallStates } from '@storybook/instrumenter'; import { styled } from '@storybook/theming'; @@ -135,7 +135,7 @@ export const Subnav: React.FC = ({ onClick={controls.start} disabled={!controlStates.start} > - + @@ -146,7 +146,7 @@ export const Subnav: React.FC = ({ onClick={controls.back} disabled={!controlStates.back} > - + @@ -157,7 +157,7 @@ export const Subnav: React.FC = ({ onClick={controls.next} disabled={!controlStates.next} > - + @@ -168,13 +168,13 @@ export const Subnav: React.FC = ({ onClick={controls.end} disabled={!controlStates.end} > - + }> - + diff --git a/code/addons/measure/src/Tool.tsx b/code/addons/measure/src/Tool.tsx index 2e68078aa06b..bb78447f8527 100644 --- a/code/addons/measure/src/Tool.tsx +++ b/code/addons/measure/src/Tool.tsx @@ -1,6 +1,7 @@ import React, { useCallback, useEffect } from 'react'; import { useGlobals, useStorybookApi } from '@storybook/manager-api'; -import { Icons, IconButton } from '@storybook/components'; +import { IconButton } from '@storybook/components'; +import { Icon } from '@storybook/components/experimental'; import { TOOL_ID, ADDON_ID } from './constants'; export const Tool = () => { @@ -33,7 +34,7 @@ export const Tool = () => { title="Enable measure" onClick={toggleMeasure} > - + ); }; diff --git a/code/addons/outline/src/OutlineSelector.tsx b/code/addons/outline/src/OutlineSelector.tsx index 93bdf321df07..63c826044ef5 100644 --- a/code/addons/outline/src/OutlineSelector.tsx +++ b/code/addons/outline/src/OutlineSelector.tsx @@ -1,6 +1,7 @@ import React, { memo, useCallback, useEffect } from 'react'; import { useGlobals, useStorybookApi } from '@storybook/manager-api'; -import { Icons, IconButton } from '@storybook/components'; +import { IconButton } from '@storybook/components'; +import { Icon } from '@storybook/components/experimental'; import { ADDON_ID, PARAM_KEY } from './constants'; export const OutlineSelector = memo(function OutlineSelector() { @@ -34,7 +35,7 @@ export const OutlineSelector = memo(function OutlineSelector() { title="Apply outlines to the preview" onClick={toggleOutline} > - + ); }); diff --git a/code/addons/themes/src/theme-switcher.tsx b/code/addons/themes/src/theme-switcher.tsx index 3658a3ef78cc..b950f780c1d5 100644 --- a/code/addons/themes/src/theme-switcher.tsx +++ b/code/addons/themes/src/theme-switcher.tsx @@ -1,8 +1,8 @@ import React, { Fragment, useMemo } from 'react'; import { useAddonState, useChannel, useGlobals, useParameter } from '@storybook/manager-api'; import { styled } from '@storybook/theming'; -import { Icons, IconButton, WithTooltip, TooltipLinkList } from '@storybook/components'; - +import { IconButton, WithTooltip, TooltipLinkList } from '@storybook/components'; +import { Icon } from '@storybook/components/experimental'; import type { ThemeAddonState, ThemeParameters } from './constants'; import { PARAM_KEY, @@ -74,7 +74,7 @@ export const ThemeSwitcher = () => { }} > - + {label && {label}} diff --git a/code/addons/viewport/src/Tool.tsx b/code/addons/viewport/src/Tool.tsx index df65988e5097..e62ce3543eb3 100644 --- a/code/addons/viewport/src/Tool.tsx +++ b/code/addons/viewport/src/Tool.tsx @@ -4,8 +4,8 @@ import memoize from 'memoizerific'; import { styled, Global, type Theme, withTheme } from '@storybook/theming'; -import { Icons, IconButton, WithTooltip, TooltipLinkList } from '@storybook/components'; - +import { IconButton, WithTooltip, TooltipLinkList } from '@storybook/components'; +import { Icon } from '@storybook/components/experimental'; import { useStorybookApi, useParameter, useAddonState } from '@storybook/manager-api'; import { registerShortcuts } from './shortcuts'; import { PARAM_KEY, ADDON_ID } from './constants'; @@ -188,7 +188,7 @@ export const ViewportTool: FC = memo( setState({ ...state, selected: responsiveViewport.id }); }} > - + {styles ? ( {isRotated ? `${item.title} (L)` : `${item.title} (P)`} @@ -234,7 +234,7 @@ export const ViewportTool: FC = memo( setState({ ...state, isRotated: !isRotated }); }} > - + {styles.height.replace('px', '')} diff --git a/code/builders/builder-webpack5/package.json b/code/builders/builder-webpack5/package.json index 340ae06c38f9..1af2435ef428 100644 --- a/code/builders/builder-webpack5/package.json +++ b/code/builders/builder-webpack5/package.json @@ -55,23 +55,15 @@ "prep": "../../../scripts/prepare/bundle.ts" }, "dependencies": { - "@babel/core": "^7.22.9", - "@storybook/addons": "workspace:*", + "@babel/core": "^7.22.0", "@storybook/channels": "workspace:*", - "@storybook/client-api": "workspace:*", "@storybook/client-logger": "workspace:*", - "@storybook/components": "workspace:*", "@storybook/core-common": "workspace:*", "@storybook/core-events": "workspace:*", "@storybook/core-webpack": "workspace:*", - "@storybook/global": "^5.0.0", - "@storybook/manager-api": "workspace:*", "@storybook/node-logger": "workspace:*", "@storybook/preview": "workspace:*", "@storybook/preview-api": "workspace:*", - "@storybook/router": "workspace:*", - "@storybook/store": "workspace:*", - "@storybook/theming": "workspace:*", "@swc/core": "^1.3.49", "@types/node": "^16.0.0", "@types/semver": "^7.3.4", @@ -109,10 +101,6 @@ "slash": "^5.0.0", "typescript": "~4.9.3" }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" - }, "peerDependenciesMeta": { "typescript": { "optional": true diff --git a/code/builders/builder-webpack5/src/preview/iframe-webpack.config.ts b/code/builders/builder-webpack5/src/preview/iframe-webpack.config.ts index c99a1df1da81..704d8fe2b98b 100644 --- a/code/builders/builder-webpack5/src/preview/iframe-webpack.config.ts +++ b/code/builders/builder-webpack5/src/preview/iframe-webpack.config.ts @@ -36,19 +36,29 @@ const storybookPaths: Record = { `@storybook/components` )}/dist/experimental`, ...[ - // these packages are not pre-bundled because of react dependencies + // these packages are not pre-bundled because of react dependencies. + // these are not dependencies of the builder anymore, thus resolving them can fail. + // we should remove the aliases in 8.0, I'm not sure why they are here in the first place. 'components', 'global', 'manager-api', 'router', 'theming', - ].reduce( - (acc, sbPackage) => ({ - ...acc, - [`@storybook/${sbPackage}`]: getAbsolutePath(`@storybook/${sbPackage}`), - }), - {} - ), + ].reduce((acc, sbPackage) => { + let packagePath; + try { + packagePath = getAbsolutePath(`@storybook/${sbPackage}`); + } catch (e) { + // ignore + } + if (packagePath) { + return { + ...acc, + [`@storybook/${sbPackage}`]: getAbsolutePath(`@storybook/${sbPackage}`), + }; + } + return acc; + }, {}), // deprecated, remove in 8.0 [`@storybook/api`]: getAbsolutePath(`@storybook/manager-api`), }; diff --git a/code/lib/csf-tools/package.json b/code/lib/csf-tools/package.json index 5f3a85b926d5..7ab953b8d7d8 100644 --- a/code/lib/csf-tools/package.json +++ b/code/lib/csf-tools/package.json @@ -48,7 +48,6 @@ "@storybook/csf": "^0.1.0", "@storybook/types": "workspace:*", "fs-extra": "^11.1.0", - "prettier": "^2.8.0", "recast": "^0.23.1", "ts-dedent": "^2.0.0" }, diff --git a/code/lib/csf-tools/src/ConfigFile.test.ts b/code/lib/csf-tools/src/ConfigFile.test.ts index e72d7813dd80..10b2c5e8d025 100644 --- a/code/lib/csf-tools/src/ConfigFile.test.ts +++ b/code/lib/csf-tools/src/ConfigFile.test.ts @@ -235,9 +235,8 @@ describe('ConfigFile', () => { export const addons = []; export const core = { - builder: 'webpack5', + builder: "webpack5" }; - `); }); it('missing field', () => { @@ -252,9 +251,8 @@ describe('ConfigFile', () => { ).toMatchInlineSnapshot(` export const core = { foo: 'bar', - builder: 'webpack5', + builder: 'webpack5' }; - `); }); it('found scalar', () => { @@ -266,10 +264,7 @@ describe('ConfigFile', () => { export const core = { builder: 'webpack4' }; ` ) - ).toMatchInlineSnapshot(` - export const core = { builder: 'webpack5' }; - - `); + ).toMatchInlineSnapshot(`export const core = { builder: 'webpack5' };`); }); it('found top-level scalar', () => { expect( @@ -280,10 +275,7 @@ describe('ConfigFile', () => { export const foo = 'bar'; ` ) - ).toMatchInlineSnapshot(` - export const foo = 'baz'; - - `); + ).toMatchInlineSnapshot(`export const foo = 'baz';`); }); it('found object', () => { expect( @@ -295,12 +287,9 @@ describe('ConfigFile', () => { ` ) ).toMatchInlineSnapshot(` - export const core = { - builder: { - name: 'webpack5', - }, - }; - + export const core = { builder: { + name: 'webpack5' + } }; `); }); it('variable export', () => { @@ -316,7 +305,6 @@ describe('ConfigFile', () => { ).toMatchInlineSnapshot(` const coreVar = { builder: 'webpack5' }; export const core = coreVar; - `); }); }); @@ -336,10 +324,9 @@ describe('ConfigFile', () => { addons: [], core: { - builder: 'webpack5', - }, + builder: "webpack5" + } }; - `); }); it('missing field', () => { @@ -352,13 +339,10 @@ describe('ConfigFile', () => { ` ) ).toMatchInlineSnapshot(` - module.exports = { - core: { - foo: 'bar', - builder: 'webpack5', - }, - }; - + module.exports = { core: { + foo: 'bar', + builder: 'webpack5' + }}; `); }); it('found scalar', () => { @@ -370,10 +354,7 @@ describe('ConfigFile', () => { module.exports = { core: { builder: 'webpack4' } }; ` ) - ).toMatchInlineSnapshot(` - module.exports = { core: { builder: 'webpack5' } }; - - `); + ).toMatchInlineSnapshot(`module.exports = { core: { builder: 'webpack5' } };`); }); }); @@ -392,10 +373,9 @@ describe('ConfigFile', () => { addons: [], core: { - builder: 'webpack5', - }, + builder: "webpack5" + } }; - `); }); it('missing field', () => { @@ -408,13 +388,10 @@ describe('ConfigFile', () => { ` ) ).toMatchInlineSnapshot(` - export default { - core: { - foo: 'bar', - builder: 'webpack5', - }, - }; - + export default { core: { + foo: 'bar', + builder: 'webpack5' + }}; `); }); it('found scalar', () => { @@ -426,10 +403,7 @@ describe('ConfigFile', () => { export default { core: { builder: 'webpack4' } }; ` ) - ).toMatchInlineSnapshot(` - export default { core: { builder: 'webpack5' } }; - - `); + ).toMatchInlineSnapshot(`export default { core: { builder: 'webpack5' } };`); }); }); @@ -437,31 +411,28 @@ describe('ConfigFile', () => { it('no quotes', () => { expect(setField(['foo', 'bar'], 'baz', '')).toMatchInlineSnapshot(` export const foo = { - bar: 'baz', + bar: "baz" }; - `); }); it('more single quotes', () => { expect(setField(['foo', 'bar'], 'baz', `export const stories = ['a', 'b', "c"]`)) .toMatchInlineSnapshot(` - export const stories = ['a', 'b', 'c']; + export const stories = ['a', 'b', "c"] export const foo = { - bar: 'baz', + bar: 'baz' }; - `); }); it('more double quotes', () => { expect(setField(['foo', 'bar'], 'baz', `export const stories = ['a', "b", "c"]`)) .toMatchInlineSnapshot(` - export const stories = ['a', 'b', 'c']; + export const stories = ['a', "b", "c"] export const foo = { - bar: 'baz', + bar: "baz" }; - `); }); }); @@ -480,9 +451,8 @@ describe('ConfigFile', () => { ).toMatchInlineSnapshot(` export default { core: { builder: 'webpack5' }, - addons: ['docs'], + addons: ['docs'] }; - `); }); it('found scalar', () => { @@ -505,10 +475,7 @@ describe('ConfigFile', () => { export default { addons: ['a11y', 'viewport'] }; ` ) - ).toMatchInlineSnapshot(` - export default { addons: ['a11y', 'viewport', 'docs'] }; - - `); + ).toMatchInlineSnapshot(`export default { addons: ['a11y', 'viewport', 'docs'] };`); }); it('array of complex values', () => { @@ -520,10 +487,9 @@ describe('ConfigFile', () => { export default { addons: [require.resolve('a11y'), someVariable] }; ` ) - ).toMatchInlineSnapshot(` - export default { addons: [require.resolve('a11y'), someVariable, 'docs'] }; - - `); + ).toMatchInlineSnapshot( + `export default { addons: [require.resolve('a11y'), someVariable, 'docs'] };` + ); }); }); @@ -537,10 +503,7 @@ describe('ConfigFile', () => { export const addons = []; ` ) - ).toMatchInlineSnapshot(` - export const addons = []; - - `); + ).toMatchInlineSnapshot(`export const addons = [];`); }); it('missing field', () => { expect( @@ -550,10 +513,7 @@ describe('ConfigFile', () => { export const core = { foo: 'bar' }; ` ) - ).toMatchInlineSnapshot(` - export const core = { foo: 'bar' }; - - `); + ).toMatchInlineSnapshot(`export const core = { foo: 'bar' };`); }); it('found scalar', () => { expect( @@ -563,10 +523,7 @@ describe('ConfigFile', () => { export const core = { builder: 'webpack4' }; ` ) - ).toMatchInlineSnapshot(` - export const core = {}; - - `); + ).toMatchInlineSnapshot(`export const core = {};`); }); it('found object', () => { expect( @@ -576,10 +533,7 @@ describe('ConfigFile', () => { export const core = { builder: { name: 'webpack4' } }; ` ) - ).toMatchInlineSnapshot(` - export const core = {}; - - `); + ).toMatchInlineSnapshot(`export const core = {};`); }); it('nested object', () => { expect( @@ -589,10 +543,7 @@ describe('ConfigFile', () => { export const core = { builder: { name: 'webpack4' } }; ` ) - ).toMatchInlineSnapshot(` - export const core = { builder: {} }; - - `); + ).toMatchInlineSnapshot(`export const core = { builder: {} };`); }); it('string literal key', () => { expect( @@ -602,10 +553,7 @@ describe('ConfigFile', () => { export const core = { 'builder': 'webpack4' }; ` ) - ).toMatchInlineSnapshot(` - export const core = {}; - - `); + ).toMatchInlineSnapshot(`export const core = {};`); }); it('variable export', () => { expect( @@ -619,7 +567,6 @@ describe('ConfigFile', () => { ).toMatchInlineSnapshot(` const coreVar = {}; export const core = coreVar; - `); }); it('root export variable', () => { @@ -632,10 +579,7 @@ describe('ConfigFile', () => { export const addons = []; ` ) - ).toMatchInlineSnapshot(` - export const addons = []; - - `); + ).toMatchInlineSnapshot(`export const addons = [];`); }); }); @@ -648,10 +592,7 @@ describe('ConfigFile', () => { module.exports = { addons: [] }; ` ) - ).toMatchInlineSnapshot(` - module.exports = { addons: [] }; - - `); + ).toMatchInlineSnapshot(`module.exports = { addons: [] };`); }); it('missing field', () => { expect( @@ -661,10 +602,7 @@ describe('ConfigFile', () => { module.exports = { core: { foo: 'bar' }}; ` ) - ).toMatchInlineSnapshot(` - module.exports = { core: { foo: 'bar' } }; - - `); + ).toMatchInlineSnapshot(`module.exports = { core: { foo: 'bar' }};`); }); it('found scalar', () => { expect( @@ -674,10 +612,7 @@ describe('ConfigFile', () => { module.exports = { core: { builder: 'webpack4' } }; ` ) - ).toMatchInlineSnapshot(` - module.exports = { core: {} }; - - `); + ).toMatchInlineSnapshot(`module.exports = { core: {} };`); }); it('nested scalar', () => { expect( @@ -687,10 +622,7 @@ describe('ConfigFile', () => { module.exports = { core: { builder: { name: 'webpack4' } } }; ` ) - ).toMatchInlineSnapshot(` - module.exports = { core: { builder: {} } }; - - `); + ).toMatchInlineSnapshot(`module.exports = { core: { builder: {} } };`); }); it('string literal key', () => { expect( @@ -700,10 +632,7 @@ describe('ConfigFile', () => { module.exports = { 'core': { 'builder': 'webpack4' } }; ` ) - ).toMatchInlineSnapshot(` - module.exports = { core: {} }; - - `); + ).toMatchInlineSnapshot(`module.exports = { 'core': {} };`); }); it('root property', () => { expect( @@ -715,9 +644,8 @@ describe('ConfigFile', () => { ) ).toMatchInlineSnapshot(` module.exports = { - addons: [], + addons: [] }; - `); }); }); @@ -731,10 +659,7 @@ describe('ConfigFile', () => { export default { addons: [] }; ` ) - ).toMatchInlineSnapshot(` - export default { addons: [] }; - - `); + ).toMatchInlineSnapshot(`export default { addons: [] };`); }); it('missing field', () => { expect( @@ -744,10 +669,7 @@ describe('ConfigFile', () => { export default { core: { foo: 'bar' }}; ` ) - ).toMatchInlineSnapshot(` - export default { core: { foo: 'bar' } }; - - `); + ).toMatchInlineSnapshot(`export default { core: { foo: 'bar' }};`); }); it('found scalar', () => { expect( @@ -757,10 +679,7 @@ describe('ConfigFile', () => { export default { core: { builder: 'webpack4' } }; ` ) - ).toMatchInlineSnapshot(` - export default { core: {} }; - - `); + ).toMatchInlineSnapshot(`export default { core: {} };`); }); it('nested scalar', () => { expect( @@ -770,10 +689,7 @@ describe('ConfigFile', () => { export default { core: { builder: { name: 'webpack4' } } }; ` ) - ).toMatchInlineSnapshot(` - export default { core: { builder: {} } }; - - `); + ).toMatchInlineSnapshot(`export default { core: { builder: {} } };`); }); it('string literal key', () => { expect( @@ -783,10 +699,7 @@ describe('ConfigFile', () => { export default { 'core': { 'builder': 'webpack4' } }; ` ) - ).toMatchInlineSnapshot(` - export default { core: {} }; - - `); + ).toMatchInlineSnapshot(`export default { 'core': {} };`); }); it('root property', () => { expect( @@ -798,9 +711,8 @@ describe('ConfigFile', () => { ) ).toMatchInlineSnapshot(` export default { - addons: [], + addons: [] }; - `); }); }); @@ -809,31 +721,28 @@ describe('ConfigFile', () => { it('no quotes', () => { expect(setField(['foo', 'bar'], 'baz', '')).toMatchInlineSnapshot(` export const foo = { - bar: 'baz', + bar: "baz" }; - `); }); it('more single quotes', () => { expect(setField(['foo', 'bar'], 'baz', `export const stories = ['a', 'b', "c"]`)) .toMatchInlineSnapshot(` - export const stories = ['a', 'b', 'c']; + export const stories = ['a', 'b', "c"] export const foo = { - bar: 'baz', + bar: 'baz' }; - `); }); it('more double quotes', () => { expect(setField(['foo', 'bar'], 'baz', `export const stories = ['a', "b", "c"]`)) .toMatchInlineSnapshot(` - export const stories = ['a', 'b', 'c']; + export const stories = ['a', "b", "c"] export const foo = { - bar: 'baz', + bar: "baz" }; - `); }); }); diff --git a/code/lib/csf-tools/src/ConfigFile.ts b/code/lib/csf-tools/src/ConfigFile.ts index 684e195919a8..e31750a2fed6 100644 --- a/code/lib/csf-tools/src/ConfigFile.ts +++ b/code/lib/csf-tools/src/ConfigFile.ts @@ -6,10 +6,8 @@ import * as t from '@babel/types'; import * as generate from '@babel/generator'; import * as traverse from '@babel/traverse'; -import * as recast from 'recast'; -import prettier from 'prettier'; - import type { Options } from 'recast'; +import * as recast from 'recast'; import { babelParse } from './babelParse'; const logger = console; @@ -718,27 +716,11 @@ export const loadConfig = (code: string, fileName?: string) => { }; export const formatConfig = (config: ConfigFile) => { - const { code } = generate.default(config._ast, {}); - return code; + return printConfig(config).code; }; export const printConfig = (config: ConfigFile, options: Options = {}) => { - const result = recast.print(config._ast, options); - const prettierConfig = prettier.resolveConfig.sync('.'); - - if (prettierConfig) { - let pretty: string; - try { - pretty = prettier.format(result.code, { - ...prettierConfig, - filepath: config.fileName ?? 'main.ts', - }); - } catch (_) { - pretty = result.code; - } - return { ...result, code: pretty }; - } - return result; + return recast.print(config._ast, options); }; export const readConfig = async (fileName: string) => { diff --git a/code/lib/types/README.md b/code/lib/types/README.md index 3fc5cbe80885..1035e9e1b693 100644 --- a/code/lib/types/README.md +++ b/code/lib/types/README.md @@ -3,6 +3,6 @@ Storybook types exports only typescript types for storybook usage. It exports typescript enums, which do have a runtime implementation. -But it should not export any implementation such as classes, method, function or constants. +But it should not export any implementation such as classes, methods, functions or constants. It also has no dependencies, all the types it exports are bundled in. diff --git a/code/package.json b/code/package.json index 7fd9c897bb52..2013de5f4248 100644 --- a/code/package.json +++ b/code/package.json @@ -326,5 +326,6 @@ "Dependency Upgrades" ] ] - } + }, + "deferredNextVersion": "7.2.2-alpha.1" } diff --git a/code/ui/blocks/src/blocks/mdx.tsx b/code/ui/blocks/src/blocks/mdx.tsx index 3c1c69f87fc2..eae97528ecb4 100644 --- a/code/ui/blocks/src/blocks/mdx.tsx +++ b/code/ui/blocks/src/blocks/mdx.tsx @@ -1,7 +1,8 @@ import type { FC, MouseEvent, PropsWithChildren, SyntheticEvent } from 'react'; import React, { useContext } from 'react'; import { NAVIGATE_URL } from '@storybook/core-events'; -import { Code, components, Icons, nameSpaceClassNames } from '@storybook/components'; +import { Code, components, nameSpaceClassNames } from '@storybook/components'; +import { Icon } from '@storybook/components/experimental'; import { global } from '@storybook/global'; import { styled } from '@storybook/theming'; import { Source } from '../components'; @@ -190,7 +191,7 @@ const HeaderWithOcticonAnchor: FC - + {children} diff --git a/code/ui/blocks/src/components/ArgsTable/ArgsTable.tsx b/code/ui/blocks/src/components/ArgsTable/ArgsTable.tsx index 74c849f9597b..a528c292e25c 100644 --- a/code/ui/blocks/src/components/ArgsTable/ArgsTable.tsx +++ b/code/ui/blocks/src/components/ArgsTable/ArgsTable.tsx @@ -5,8 +5,8 @@ import { styled } from '@storybook/theming'; import { transparentize } from 'polished'; import { includeConditionalArg } from '@storybook/csf'; import { once } from '@storybook/client-logger'; -import { IconButton, Icons, ResetWrapper } from '@storybook/components'; -import { Link } from '@storybook/components/experimental'; +import { IconButton, ResetWrapper } from '@storybook/components'; +import { Icon, Link } from '@storybook/components/experimental'; import { ArgRow } from './ArgRow'; import { SectionRow } from './SectionRow'; @@ -380,7 +380,7 @@ export const ArgsTable: FC = (props) => { Control{' '} {!isLoading && resetArgs && ( resetArgs()} title="Reset controls"> - + )} diff --git a/code/ui/blocks/src/components/ArgsTable/Empty.tsx b/code/ui/blocks/src/components/ArgsTable/Empty.tsx index 7962d475acf8..ea8e3c2f17fc 100644 --- a/code/ui/blocks/src/components/ArgsTable/Empty.tsx +++ b/code/ui/blocks/src/components/ArgsTable/Empty.tsx @@ -1,7 +1,7 @@ import type { FC } from 'react'; import React, { useEffect, useState } from 'react'; import { styled } from '@storybook/theming'; -import { Icon, Link } from '@storybook/components/experimental'; +import { Link } from '@storybook/components/experimental'; interface EmptyProps { inAddonPanel?: boolean; @@ -53,16 +53,6 @@ const Divider = styled.div(({ theme }) => ({ backgroundColor: theme.appBorderColor, })); -const VideoIcon = styled.div(({ theme }) => ({ - width: 22, - height: 16, - borderRadius: theme.appBorderRadius, - border: `1px solid ${theme.color.secondary}`, - display: 'flex', - alignItems: 'center', - justifyContent: 'center', -})); - export const Empty: FC = ({ inAddonPanel }) => { const [isLoading, setIsLoading] = useState(true); @@ -95,16 +85,7 @@ export const Empty: FC = ({ inAddonPanel }) => { {inAddonPanel && ( <> - - - - } - withArrow - > + Watch 5m video diff --git a/code/ui/blocks/src/components/Toolbar.tsx b/code/ui/blocks/src/components/Toolbar.tsx index 392cd7a8a769..b454dce0478c 100644 --- a/code/ui/blocks/src/components/Toolbar.tsx +++ b/code/ui/blocks/src/components/Toolbar.tsx @@ -1,7 +1,8 @@ import type { FC, MouseEvent } from 'react'; import React, { Fragment } from 'react'; import { styled } from '@storybook/theming'; -import { FlexBar, Icons, IconButton, IconButtonSkeleton } from '@storybook/components'; +import { FlexBar, IconButton, IconButtonSkeleton } from '@storybook/components'; +import { Icon } from '@storybook/components/experimental'; interface ZoomProps { zoom: (val: number) => void; @@ -33,7 +34,7 @@ const Zoom: FC = ({ zoom, resetZoom }) => ( }} title="Zoom in" > - + = ({ zoom, resetZoom }) => ( }} title="Zoom out" > - + = ({ zoom, resetZoom }) => ( }} title="Reset zoom" > - + ); diff --git a/code/ui/blocks/src/controls/Object.tsx b/code/ui/blocks/src/controls/Object.tsx index 11c51f8f6392..8cd8c8bb7bea 100644 --- a/code/ui/blocks/src/controls/Object.tsx +++ b/code/ui/blocks/src/controls/Object.tsx @@ -4,6 +4,7 @@ import type { ComponentProps, SyntheticEvent, FC, FocusEvent } from 'react'; import React, { useCallback, useMemo, useState, useEffect, useRef } from 'react'; import { styled, useTheme, type Theme } from '@storybook/theming'; import { Form, Icons, type IconsProps, IconButton } from '@storybook/components'; +import { Icon } from '@storybook/components/experimental'; import { JsonTree, getObjectType } from './react-editable-json-tree'; import { getControlId, getControlSetterButtonId } from './helpers'; import type { ControlProps, ObjectValue, ObjectConfig } from './types'; @@ -294,7 +295,7 @@ export const ObjectControl: FC = ({ name, value, onChange }) => { setShowRaw((v) => !v); }} > - + {showRaw ? : } RAW )} diff --git a/code/ui/blocks/src/controls/options/Select.tsx b/code/ui/blocks/src/controls/options/Select.tsx index f033c131bd71..43c47cfc3405 100644 --- a/code/ui/blocks/src/controls/options/Select.tsx +++ b/code/ui/blocks/src/controls/options/Select.tsx @@ -3,8 +3,7 @@ import React from 'react'; import { styled } from '@storybook/theming'; import type { CSSObject } from '@storybook/theming'; import { logger } from '@storybook/client-logger'; -import { Icons } from '@storybook/components'; - +import { Icon } from '@storybook/components/experimental'; import type { ControlProps, OptionsSelection, NormalizedOptionsConfig } from '../types'; import { selectedKey, selectedKeys, selectedValues } from './helpers'; @@ -73,21 +72,17 @@ const SelectWrapper = styled.span(({ theme }) => ({ position: 'relative', verticalAlign: 'top', width: '100%', +})); - svg: { - position: 'absolute', - zIndex: 1, - pointerEvents: 'none', - height: '12px', - marginTop: '-6px', - right: '12px', - top: '50%', - fill: theme.textMutedColor, - - path: { - fill: theme.textMutedColor, - }, - }, +const SelectChevronDown = styled.div(({ theme }) => ({ + position: 'absolute', + zIndex: 1, + pointerEvents: 'none', + height: '12px', + marginTop: '-6px', + right: '12px', + top: '50%', + color: theme.textMutedColor, })); type SelectConfig = NormalizedOptionsConfig & { isMulti: boolean }; @@ -104,7 +99,9 @@ const SingleSelect: FC = ({ name, value, options, onChange }) => { return ( - + + +