Merge branch 'next' into 10723-update-cli-template-stories

This commit is contained in:
Michael Shilman 2020-07-15 15:03:31 +08:00
commit b101f9e15d
33 changed files with 542 additions and 463 deletions

View File

@ -52,9 +52,9 @@ const useArgs = (storyId: string, storyStore: StoryStore): [Args, (args: Args) =
const { args: initialArgs } = story;
const [args, setArgs] = useState(initialArgs);
useEffect(() => {
const cb = (changedId: string, newArgs: Args) => {
if (changedId === storyId) {
setArgs(newArgs);
const cb = (changed: { storyId: string; args: Args }) => {
if (changed.storyId === storyId) {
setArgs(changed.args);
}
};
storyStore._channel.on(Events.STORY_ARGS_UPDATED, cb);

View File

@ -24,7 +24,7 @@ type BabelParams = {
function createBabelOptions({ babelOptions, mdxBabelOptions, configureJSX }: BabelParams) {
const babelPlugins = mdxBabelOptions?.plugins || babelOptions?.plugins || [];
const jsxPlugin = [
'@babel/plugin-transform-react-jsx',
require.resolve('@babel/plugin-transform-react-jsx'),
{ pragma: 'React.createElement', pragmaFrag: 'React.Fragment' },
];
const plugins = configureJSX ? [...babelPlugins, jsxPlugin] : babelPlugins;

View File

@ -0,0 +1,16 @@
describe('addon-viewport', () => {
before(() => {
cy.visitStorybook();
});
it('should have viewport button in the toolbar', () => {
cy.navigateToStory('button', 'Text');
// Click on viewport button and select small mobile
cy.get('[title="Change the size of the preview"]').click();
cy.get('#mobile1').click();
// Check that Welcome story is still displayed
cy.getStoryElement().should('contain.text', 'Button');
});
});

View File

@ -186,10 +186,18 @@ module.exports = {
// Make whatever fine-grained changes you need
config.module.rules.push({
test: /\.scss$/,
use: ['style-loader', 'css-loader', 'sass-loader'],
include: path.resolve(__dirname, '../'),
});
test: /.scss$/,
loader: [
'style-loader',
{
loader: 'css-loader',
options: {
modules: true, // to support files with '.module.scss' extenstions.
},
},
'sass-loader',
],
})
// Return the altered config
return config;

View File

@ -34,6 +34,7 @@ module.exports = {
reactDocgen: 'react-docgen-typescript',
reactDocgenTypescriptOptions: {
shouldExtractLiteralValuesFromEnum: true,
shouldRemoveUndefinedFromOptional: true,
propFilter: (prop) => (prop.parent ? !/node_modules/.test(prop.parent.fileName) : true),
},
},

View File

@ -4,7 +4,7 @@ import PropTypes from 'prop-types';
import { useArgs } from '@storybook/client-api';
// eslint-disable-next-line react/prop-types
const ArgUpdater = ({ args, updateArgs }) => {
const ArgUpdater = ({ args, updateArgs, resetArgs }) => {
const [argsInput, updateArgsInput] = useState(JSON.stringify(args));
return (
@ -20,6 +20,9 @@ const ArgUpdater = ({ args, updateArgs }) => {
<textarea value={argsInput} onChange={(e) => updateArgsInput(e.target.value)} />
<br />
<button type="submit">Change</button>
<button type="button" onClick={() => resetArgs()}>
Reset all
</button>
</form>
</div>
);
@ -29,12 +32,12 @@ export default {
title: 'Core/Args',
decorators: [
(story) => {
const [args, updateArgs] = useArgs();
const [args, updateArgs, resetArgs] = useArgs();
return (
<>
{story()}
<ArgUpdater args={args} updateArgs={updateArgs} />
<ArgUpdater args={args} updateArgs={updateArgs} resetArgs={resetArgs} />
</>
);
},
@ -50,7 +53,7 @@ export const PassedToStory = (inputArgs) => {
);
};
PassedToStory.argTypes = { name: { defaultValue: 'initial' } };
PassedToStory.argTypes = { name: { defaultValue: 'initial', control: 'text' } };
PassedToStory.propTypes = {
args: PropTypes.shape({}).isRequired,

View File

@ -5,6 +5,7 @@ import {
STORY_RENDERED,
DOCS_RENDERED,
UPDATE_STORY_ARGS,
RESET_STORY_ARGS,
UPDATE_GLOBALS,
} from '@storybook/core-events';
import { addons } from './index';
@ -402,7 +403,7 @@ export function useParameter<S>(parameterKey: string, defaultValue?: S): S | und
}
/* Returns current value of story args */
export function useArgs(): [Args, (newArgs: Args) => void] {
export function useArgs(): [Args, (newArgs: Args) => void, (argNames?: [string]) => void] {
const channel = addons.getChannel();
const { id: storyId, args } = useStoryContext();
@ -411,7 +412,12 @@ export function useArgs(): [Args, (newArgs: Args) => void] {
[channel, storyId]
);
return [args, updateArgs];
const resetArgs = useCallback(
(argNames?: [string]) => channel.emit(RESET_STORY_ARGS, { storyId, argNames }),
[channel, storyId]
);
return [args, updateArgs, resetArgs];
}
/* Returns current value of global args */

View File

@ -428,13 +428,17 @@ export function useAddonState<S>(addonId: string, defaultState?: S) {
return useSharedState<S>(addonId, defaultState);
}
export function useArgs(): [Args, (newArgs: Args) => void] {
const { getCurrentStoryData, updateStoryArgs } = useStorybookApi();
export function useArgs(): [Args, (newArgs: Args) => void, (argNames?: [string]) => void] {
const { getCurrentStoryData, updateStoryArgs, resetStoryArgs } = useStorybookApi();
const data = getCurrentStoryData();
const args = isStory(data) ? data.args : {};
return [args, (newArgs: Args) => updateStoryArgs(data as Story, newArgs)];
return [
args,
(newArgs: Args) => updateStoryArgs(data as Story, newArgs),
(argNames?: [string]) => resetStoryArgs(data as Story, argNames),
];
}
export function useGlobals(): [Args, (newGlobals: Args) => void] {

View File

@ -2,6 +2,7 @@ import { DOCS_MODE } from 'global';
import { toId, sanitize } from '@storybook/csf';
import {
UPDATE_STORY_ARGS,
RESET_STORY_ARGS,
STORY_ARGS_UPDATED,
STORY_CHANGED,
SELECT_STORY,
@ -61,6 +62,7 @@ export interface SubAPI {
) => Story['parameters'] | any;
getCurrentParameter<S>(parameterName?: ParameterName): S;
updateStoryArgs(story: Story, newArgs: Args): void;
resetStoryArgs: (story: Story, argNames?: [string]) => void;
findLeafStoryId(StoriesHash: StoriesHash, storyId: StoryId): StoryId;
}
@ -314,6 +316,16 @@ export const init: ModuleFn = ({
},
});
},
resetStoryArgs: (story, argNames?: [string]) => {
const { id: storyId, refId } = story;
fullAPI.emit(RESET_STORY_ARGS, {
storyId,
argNames,
options: {
target: refId ? `storybook-ref-${refId}` : 'storybook-preview-iframe',
},
});
},
};
const initModule = () => {

View File

@ -1,6 +1,7 @@
import {
STORY_ARGS_UPDATED,
UPDATE_STORY_ARGS,
RESET_STORY_ARGS,
SET_STORIES,
CURRENT_STORY_WAS_SET,
} from '@storybook/core-events';
@ -467,6 +468,66 @@ describe('stories API', () => {
},
});
});
it('resetStoryArgs emits RESET_STORY_ARGS to the local frame and does not change anything', () => {
const navigate = jest.fn();
const emit = jest.fn();
const on = jest.fn();
const store = createMockStore();
const {
api: { setStories, resetStoryArgs },
init,
} = initStories({ store, navigate, provider, fullAPI: { emit, on } });
setStories({
'a--1': { kind: 'a', name: '1', parameters, path: 'a--1', id: 'a--1', args: { a: 'b' } },
'b--1': { kind: 'b', name: '1', parameters, path: 'b--1', id: 'b--1', args: { x: 'y' } },
});
init();
resetStoryArgs({ id: 'a--1' }, ['foo']);
expect(emit).toHaveBeenCalledWith(RESET_STORY_ARGS, {
storyId: 'a--1',
argNames: ['foo'],
options: {
target: 'storybook-preview-iframe',
},
});
const { storiesHash: changedStoriesHash } = store.getState();
expect(changedStoriesHash['a--1'].args).toEqual({ a: 'b' });
expect(changedStoriesHash['b--1'].args).toEqual({ x: 'y' });
});
it('resetStoryArgs emits RESET_STORY_ARGS to the right frame', () => {
const navigate = jest.fn();
const emit = jest.fn();
const on = jest.fn();
const store = createMockStore();
const {
api: { setStories, resetStoryArgs },
init,
} = initStories({ store, navigate, provider, fullAPI: { emit, on } });
setStories({
'a--1': { kind: 'a', name: '1', parameters, path: 'a--1', id: 'a--1', args: { a: 'b' } },
'b--1': { kind: 'b', name: '1', parameters, path: 'b--1', id: 'b--1', args: { x: 'y' } },
});
init();
resetStoryArgs({ id: 'a--1', refId: 'refId' }, ['foo']);
expect(emit).toHaveBeenCalledWith(RESET_STORY_ARGS, {
storyId: 'a--1',
argNames: ['foo'],
options: {
target: 'storybook-ref-refId',
},
});
});
});
describe('jumpToStory', () => {

View File

@ -32,10 +32,10 @@
"versions.json"
],
"scripts": {
"prepare": "node ../../scripts/prepare.js && node -r esm ./scripts/generate-app-versions.js",
"prepare": "node ../../scripts/prepare.js && node -r esm ./scripts/generate-sb-packages-versions.js",
"test": "cd test && ./run_tests.sh",
"test-yarn-2": "cd test && ./run_tests_yarn_2.sh",
"postversion": "node -r esm ./scripts/generate-app-versions.js"
"postversion": "node -r esm ./scripts/generate-sb-packages-versions.js"
},
"dependencies": {
"@babel/core": "^7.9.6",
@ -63,32 +63,6 @@
"update-notifier": "^4.0.0"
},
"devDependencies": {
"@storybook/addon-actions": "6.0.0-rc.3",
"@storybook/addon-docs": "6.0.0-rc.3",
"@storybook/addon-essentials": "6.0.0-rc.3",
"@storybook/addon-graphql": "6.0.0-rc.3",
"@storybook/addon-knobs": "6.0.0-rc.3",
"@storybook/addon-links": "6.0.0-rc.3",
"@storybook/addon-storyshots": "6.0.0-rc.3",
"@storybook/addons": "6.0.0-rc.3",
"@storybook/angular": "6.0.0-rc.3",
"@storybook/channel-postmessage": "6.0.0-rc.3",
"@storybook/channel-websocket": "6.0.0-rc.3",
"@storybook/channels": "6.0.0-rc.3",
"@storybook/ember": "6.0.0-rc.3",
"@storybook/html": "6.0.0-rc.3",
"@storybook/marionette": "6.0.0-rc.3",
"@storybook/marko": "6.0.0-rc.3",
"@storybook/mithril": "6.0.0-rc.3",
"@storybook/preact": "6.0.0-rc.3",
"@storybook/rax": "6.0.0-rc.3",
"@storybook/react": "6.0.0-rc.3",
"@storybook/react-native": "6.0.0-alpha.0",
"@storybook/riot": "6.0.0-rc.3",
"@storybook/svelte": "6.0.0-rc.3",
"@storybook/ui": "6.0.0-rc.3",
"@storybook/vue": "6.0.0-rc.3",
"@storybook/web-components": "6.0.0-rc.3",
"@types/cross-spawn": "^6.0.1",
"@types/inquirer": "^6.5.0",
"@types/puppeteer-core": "^2.0.0",

View File

@ -1,37 +0,0 @@
import fs from 'fs-extra';
import path from 'path';
import { parse } from 'json5';
const logger = console;
const appsFolder = path.join(__dirname, '..', '..', '..', 'app');
const run = async () => {
const apps = await fs.readdir(appsFolder);
const versions = await Promise.all(
apps.map(async (appName) => {
const { name, version } = parse(
await fs.readFile(path.join(appsFolder, appName, 'package.json'))
);
return {
name,
version,
};
})
);
await fs.writeFile(
path.join(__dirname, '..', 'versions.json'),
JSON.stringify(
versions.reduce((acc, { name, version }) => ({ ...acc, [name]: version }), {}),
null,
2
)
);
};
run().catch((e) => {
logger.error(e);
process.exit(1);
});

View File

@ -0,0 +1,41 @@
import { writeJson, readJson } from 'fs-extra';
import path from 'path';
import globby from 'globby';
const rootDirectory = path.join(__dirname, '..', '..', '..');
const logger = console;
const run = async () => {
const storybookPackagesPaths = await globby(
`${rootDirectory}/@(app|addons|lib)/**/package.json`,
{
ignore: '**/node_modules/**/*',
}
);
const packageToVersionMap = (
await Promise.all(
storybookPackagesPaths.map(async (storybookPackagePath) => {
const { name, version } = await readJson(storybookPackagePath);
return {
name,
version,
};
})
)
)
// Remove non-`@storybook/XXX` package (like: `cli-sb`, `cli-storybook`)
.filter(({ name }) => /@storybook/.test(name))
// As some previous steps are asynchronous order is not always the same so sort them to avoid that
.sort((package1, package2) => package1.name.localeCompare(package2.name))
.reduce((acc, { name, version }) => ({ ...acc, [name]: version }), {});
await writeJson(path.join(__dirname, '..', 'versions.json'), packageToVersionMap, { spaces: 2 });
};
run().catch((e) => {
logger.error(e);
process.exit(1);
});

View File

@ -17,7 +17,7 @@ const logger = console;
program
.command('init')
.description('Initialize Storybook into your project.')
.option('-f --force', 'Force add storybook')
.option('-f --force', 'Force add Storybook')
.option('-s --skip-install', 'Skip installing deps')
.option('-N --use-npm', 'Use npm to install deps')
.option('-p --parser <babel | babylon | flow | ts | tsx>', 'jscodeshift parser')
@ -35,7 +35,7 @@ program
program
.command('upgrade')
.description('Upgrade your storybook packages to the latest')
.description('Upgrade your Storybook packages to the latest')
.option('-N --use-npm', 'Use NPM to build the Storybook server')
.option('-n --dry-run', 'Only check for upgrades, do not install')
.option('-p --prerelease', 'Upgrade to the pre-release packages')
@ -60,7 +60,7 @@ program
program
.command('migrate [migration]')
.description('Run a storybook codemod migration on your source files')
.description('Run a Storybook codemod migration on your source files')
.option('-l --list', 'List available migrations')
.option('-g --glob <glob>', 'Glob for files upon which to apply the migration', '**/*.js')
.option('-p --parser <babel | babylon | flow | ts | tsx>', 'jscodeshift parser')

View File

@ -49,11 +49,15 @@ export async function baseGenerator(
'@storybook/addon-essentials',
];
const yarn2Dependencies =
packageManager.type === 'yarn2' ? ['@storybook/addon-docs', '@mdx-js/react'] : [];
const packages = [
`@storybook/${framework}`,
...addons,
...extraPackages,
...extraAddons,
...yarn2Dependencies,
// ⚠️ Some addons have peer deps that must be added too, like '@storybook/addon-docs' => 'react-is'
'react-is',
].filter(Boolean);

View File

@ -70,7 +70,7 @@ const installStorybook = (projectType: ProjectType, options: CommandOptions): Pr
packageManager.installDependencies();
}
logger.log('\nTo run your storybook, type:\n');
logger.log('\nTo run your Storybook, type:\n');
codeLog([packageManager.getRunStorybookCommand()]);
logger.log('\nFor more information visit:', chalk.cyan('https://storybook.js.org'));
@ -85,7 +85,7 @@ const installStorybook = (projectType: ProjectType, options: CommandOptions): Pr
switch (projectType) {
case ProjectType.ALREADY_HAS_STORYBOOK:
logger.log();
paddedLog('There seems to be a storybook already available in this project.');
paddedLog('There seems to be a Storybook already available in this project.');
paddedLog('Apply following command to force:\n');
codeLog(['sb init [options] -f']);
@ -96,17 +96,17 @@ const installStorybook = (projectType: ProjectType, options: CommandOptions): Pr
case ProjectType.UPDATE_PACKAGE_ORGANIZATIONS:
return updateOrganisationsGenerator(packageManager, options.parser, npmOptions)
.then(() => null) // commmandLog doesn't like to see output
.then(commandLog('Upgrading your project to the new storybook packages.'))
.then(commandLog('Upgrading your project to the new Storybook packages.'))
.then(end);
case ProjectType.REACT_SCRIPTS:
return reactScriptsGenerator(packageManager, npmOptions, generatorOptions)
.then(commandLog('Adding storybook support to your "Create React App" based project'))
.then(commandLog('Adding Storybook support to your "Create React App" based project'))
.then(end);
case ProjectType.REACT:
return reactGenerator(packageManager, npmOptions, generatorOptions)
.then(commandLog('Adding storybook support to your "React" app'))
.then(commandLog('Adding Storybook support to your "React" app'))
.then(end);
case ProjectType.REACT_NATIVE: {
@ -117,7 +117,7 @@ const installStorybook = (projectType: ProjectType, options: CommandOptions): Pr
type: 'confirm',
name: 'server',
message:
'Do you want to install dependencies necessary to run storybook server? You can manually do it later by install @storybook/react-native-server',
'Do you want to install dependencies necessary to run Storybook server? You can manually do it later by install @storybook/react-native-server',
default: false,
},
]) as Promise<{ server: boolean }>)
@ -125,11 +125,11 @@ const installStorybook = (projectType: ProjectType, options: CommandOptions): Pr
.then(({ server }) =>
reactNativeGenerator(packageManager, npmOptions, server, generatorOptions)
)
.then(commandLog('Adding storybook support to your "React Native" app'))
.then(commandLog('Adding Storybook support to your "React Native" app'))
.then(end)
.then(() => {
logger.log(chalk.red('NOTE: installation is not 100% automated.'));
logger.log(`To quickly run storybook, replace contents of your app entry with:\n`);
logger.log(`To quickly run Storybook, replace contents of your app entry with:\n`);
codeLog(["export default from './storybook';"]);
logger.log('\n For more in depth setup instructions, see:\n');
logger.log(chalk.cyan(REACT_NATIVE_DISCUSSION));
@ -139,82 +139,82 @@ const installStorybook = (projectType: ProjectType, options: CommandOptions): Pr
case ProjectType.METEOR:
return meteorGenerator(packageManager, npmOptions, generatorOptions)
.then(commandLog('Adding storybook support to your "Meteor" app'))
.then(commandLog('Adding Storybook support to your "Meteor" app'))
.then(end);
case ProjectType.WEBPACK_REACT:
return webpackReactGenerator(packageManager, npmOptions, generatorOptions)
.then(commandLog('Adding storybook support to your "Webpack React" app'))
.then(commandLog('Adding Storybook support to your "Webpack React" app'))
.then(end);
case ProjectType.REACT_PROJECT:
return reactGenerator(packageManager, npmOptions, generatorOptions)
.then(commandLog('Adding storybook support to your "React" library'))
.then(commandLog('Adding Storybook support to your "React" library'))
.then(end);
case ProjectType.SFC_VUE:
return sfcVueGenerator(packageManager, npmOptions, generatorOptions)
.then(commandLog('Adding storybook support to your "Single File Components Vue" app'))
.then(commandLog('Adding Storybook support to your "Single File Components Vue" app'))
.then(end);
case ProjectType.VUE:
return vueGenerator(packageManager, npmOptions, generatorOptions)
.then(commandLog('Adding storybook support to your "Vue" app'))
.then(commandLog('Adding Storybook support to your "Vue" app'))
.then(end);
case ProjectType.ANGULAR:
return angularGenerator(packageManager, npmOptions, generatorOptions)
.then(commandLog('Adding storybook support to your "Angular" app'))
.then(commandLog('Adding Storybook support to your "Angular" app'))
.then(end);
case ProjectType.EMBER:
return emberGenerator(packageManager, npmOptions, generatorOptions)
.then(commandLog('Adding storybook support to your "Ember" app'))
.then(commandLog('Adding Storybook support to your "Ember" app'))
.then(end);
case ProjectType.MITHRIL:
return mithrilGenerator(packageManager, npmOptions, generatorOptions)
.then(commandLog('Adding storybook support to your "Mithril" app'))
.then(commandLog('Adding Storybook support to your "Mithril" app'))
.then(end);
case ProjectType.MARIONETTE:
return marionetteGenerator(packageManager, npmOptions, generatorOptions)
.then(commandLog('Adding storybook support to your "Marionette.js" app'))
.then(commandLog('Adding Storybook support to your "Marionette.js" app'))
.then(end);
case ProjectType.MARKO:
return markoGenerator(packageManager, npmOptions, generatorOptions)
.then(commandLog('Adding storybook support to your "Marko" app'))
.then(commandLog('Adding Storybook support to your "Marko" app'))
.then(end);
case ProjectType.HTML:
return htmlGenerator(packageManager, npmOptions, generatorOptions)
.then(commandLog('Adding storybook support to your "HTML" app'))
.then(commandLog('Adding Storybook support to your "HTML" app'))
.then(end);
case ProjectType.WEB_COMPONENTS:
return webComponentsGenerator(packageManager, npmOptions, generatorOptions)
.then(commandLog('Adding storybook support to your "web components" app'))
.then(commandLog('Adding Storybook support to your "web components" app'))
.then(end);
case ProjectType.RIOT:
return riotGenerator(packageManager, npmOptions, generatorOptions)
.then(commandLog('Adding storybook support to your "riot.js" app'))
.then(commandLog('Adding Storybook support to your "riot.js" app'))
.then(end);
case ProjectType.PREACT:
return preactGenerator(packageManager, npmOptions, generatorOptions)
.then(commandLog('Adding storybook support to your "Preact" app'))
.then(commandLog('Adding Storybook support to your "Preact" app'))
.then(end);
case ProjectType.SVELTE:
return svelteGenerator(packageManager, npmOptions, generatorOptions)
.then(commandLog('Adding storybook support to your "Svelte" app'))
.then(commandLog('Adding Storybook support to your "Svelte" app'))
.then(end);
case ProjectType.RAX:
return raxGenerator(packageManager, npmOptions, generatorOptions)
.then(commandLog('Adding storybook support to your "Rax" app'))
.then(commandLog('Adding Storybook support to your "Rax" app'))
.then(end);
default:
@ -263,7 +263,7 @@ const projectTypeInquirer = async (options: { yes?: boolean }) => {
};
export default function (options: CommandOptions, pkg: IPackage): Promise<void> {
const welcomeMessage = 'sb init - the simplest way to add a storybook to your project.';
const welcomeMessage = 'sb init - the simplest way to add a Storybook to your project.';
logger.log(chalk.inverse(`\n ${welcomeMessage} \n`));
// Update notify code.

View File

@ -7,10 +7,10 @@ import { readPackageJson, writePackageJson } from './PackageJsonHelper';
const logger = console;
// Cannot be `import` as it's not under TS root dir
const { storybookCLIVersion, devDependencies } = require('../../package.json');
const storybookPackagesVersions = require('../../versions.json');
export abstract class JsPackageManager {
public abstract type: 'npm' | 'yarn' | 'yarn2';
public abstract readonly type: 'npm' | 'yarn1' | 'yarn2';
public abstract initPackageJson(): void;
@ -138,10 +138,9 @@ export abstract class JsPackageManager {
public async getVersion(packageName: string, constraint?: string): Promise<string> {
let current;
if (packageName === '@storybook/cli') {
current = storybookCLIVersion;
} else if (/storybook/.test(packageName)) {
current = devDependencies[packageName];
if (/@storybook/.test(packageName)) {
current = storybookPackagesVersions[packageName];
}
let latest;

View File

@ -7,6 +7,10 @@ describe('NPM Proxy', () => {
npmProxy = new NPMProxy();
});
it('type should be npm', () => {
expect(npmProxy.type).toEqual('npm');
});
describe('initPackageJson', () => {
it('should run `npm init -y`', () => {
const executeCommandSpy = jest.spyOn(npmProxy, 'executeCommand').mockReturnValue('');
@ -78,4 +82,39 @@ describe('NPM Proxy', () => {
await expect(npmProxy.latestVersion('@storybook/addons')).rejects.toThrow();
});
});
describe('getVersion', () => {
it('with a Storybook package listed in versions.json it returns the version', async () => {
// eslint-disable-next-line global-require
const storybookAngularVersion = require('../../versions.json')['@storybook/angular'];
const executeCommandSpy = jest.spyOn(npmProxy, 'executeCommand').mockReturnValue('"5.3.19"');
const version = await npmProxy.getVersion('@storybook/angular');
expect(executeCommandSpy).toHaveBeenCalledWith('npm', [
'info',
'@storybook/angular',
'version',
'--json',
]);
expect(version).toEqual(`^${storybookAngularVersion}`);
});
it('with a Storybook package not listed in versions.json it returns the latest version', async () => {
const packageVersion = '5.3.19';
const executeCommandSpy = jest
.spyOn(npmProxy, 'executeCommand')
.mockReturnValue(`"${packageVersion}"`);
const version = await npmProxy.getVersion('@storybook/react-native');
expect(executeCommandSpy).toHaveBeenCalledWith('npm', [
'info',
'@storybook/react-native',
'version',
'--json',
]);
expect(version).toEqual(`^${packageVersion}`);
});
});
});

View File

@ -1,7 +1,7 @@
import { JsPackageManager } from './JsPackageManager';
export class NPMProxy extends JsPackageManager {
type: 'npm';
readonly type = 'npm';
initPackageJson() {
return this.executeCommand('npm', ['init', '-y']);

View File

@ -7,6 +7,10 @@ describe('Yarn 1 Proxy', () => {
yarn1Proxy = new Yarn1Proxy();
});
it('type should be yarn1', () => {
expect(yarn1Proxy.type).toEqual('yarn1');
});
describe('initPackageJson', () => {
it('should run `yarn init -y`', () => {
const executeCommandSpy = jest.spyOn(yarn1Proxy, 'executeCommand').mockReturnValue('');

View File

@ -1,7 +1,7 @@
import { JsPackageManager } from './JsPackageManager';
export class Yarn1Proxy extends JsPackageManager {
type: 'yarn';
readonly type = 'yarn1';
initPackageJson() {
return this.executeCommand('yarn', ['init', '-y']);

View File

@ -7,6 +7,10 @@ describe('Yarn 1 Proxy', () => {
yarn2Proxy = new Yarn2Proxy();
});
it('type should be yarn2', () => {
expect(yarn2Proxy.type).toEqual('yarn2');
});
describe('initPackageJson', () => {
it('should run `yarn init`', () => {
const executeCommandSpy = jest.spyOn(yarn2Proxy, 'executeCommand').mockReturnValue('');

View File

@ -1,7 +1,7 @@
import { JsPackageManager } from './JsPackageManager';
export class Yarn2Proxy extends JsPackageManager {
type: 'yarn2';
readonly type = 'yarn2';
initPackageJson() {
return this.executeCommand('yarn', ['init']);

View File

@ -1,17 +1,55 @@
{
"@storybook/addon-a11y": "6.0.0-rc.3",
"@storybook/addon-actions": "6.0.0-rc.3",
"@storybook/addon-backgrounds": "6.0.0-rc.3",
"@storybook/addon-controls": "6.0.0-rc.3",
"@storybook/addon-cssresources": "6.0.0-rc.3",
"@storybook/addon-design-assets": "6.0.0-rc.3",
"@storybook/addon-docs": "6.0.0-rc.3",
"@storybook/addon-essentials": "6.0.0-rc.3",
"@storybook/addon-events": "6.0.0-rc.3",
"@storybook/addon-google-analytics": "6.0.0-rc.3",
"@storybook/addon-graphql": "6.0.0-rc.3",
"@storybook/addon-jest": "6.0.0-rc.3",
"@storybook/addon-knobs": "6.0.0-rc.3",
"@storybook/addon-links": "6.0.0-rc.3",
"@storybook/addon-queryparams": "6.0.0-rc.3",
"@storybook/addon-storyshots": "6.0.0-rc.3",
"@storybook/addon-storyshots-puppeteer": "6.0.0-rc.3",
"@storybook/addon-storysource": "6.0.0-rc.3",
"@storybook/addon-toolbars": "6.0.0-rc.3",
"@storybook/addon-viewport": "6.0.0-rc.3",
"@storybook/addons": "6.0.0-rc.3",
"@storybook/angular": "6.0.0-rc.3",
"@storybook/api": "6.0.0-rc.3",
"@storybook/aurelia": "6.0.0-rc.3",
"@storybook/channel-postmessage": "6.0.0-rc.3",
"@storybook/channel-websocket": "6.0.0-rc.3",
"@storybook/channels": "6.0.0-rc.3",
"@storybook/cli": "6.0.0-rc.3",
"@storybook/client-api": "6.0.0-rc.3",
"@storybook/client-logger": "6.0.0-rc.3",
"@storybook/codemod": "6.0.0-rc.3",
"@storybook/components": "6.0.0-rc.3",
"@storybook/core": "6.0.0-rc.3",
"@storybook/core-events": "6.0.0-rc.3",
"@storybook/ember": "6.0.0-rc.3",
"@storybook/html": "6.0.0-rc.3",
"@storybook/marionette": "6.0.0-rc.3",
"@storybook/marko": "6.0.0-rc.3",
"@storybook/mithril": "6.0.0-rc.3",
"@storybook/node-logger": "6.0.0-rc.3",
"@storybook/postinstall": "6.0.0-rc.3",
"@storybook/preact": "6.0.0-rc.3",
"@storybook/rax": "6.0.0-rc.3",
"@storybook/react": "6.0.0-rc.3",
"@storybook/riot": "6.0.0-rc.3",
"@storybook/router": "6.0.0-rc.3",
"@storybook/server": "6.0.0-rc.3",
"@storybook/source-loader": "6.0.0-rc.3",
"@storybook/svelte": "6.0.0-rc.3",
"@storybook/theming": "6.0.0-rc.3",
"@storybook/ui": "6.0.0-rc.3",
"@storybook/vue": "6.0.0-rc.3",
"@storybook/web-components": "6.0.0-rc.3"
}
}

View File

@ -2,6 +2,7 @@ import {
FORCE_RE_RENDER,
STORY_RENDERED,
UPDATE_STORY_ARGS,
RESET_STORY_ARGS,
UPDATE_GLOBALS,
} from '@storybook/core-events';
import addons from '@storybook/addons';
@ -528,6 +529,26 @@ describe('Preview hooks', () => {
{ id: '1', args: {} }
);
});
it('will emit RESET_STORY_ARGS when called', () => {
run(
() => {},
[
(storyFn) => {
useArgs()[2](['a']);
expect(mockChannel.emit).toHaveBeenCalledWith(RESET_STORY_ARGS, {
storyId: '1',
argNames: ['a'],
});
useArgs()[2]();
expect(mockChannel.emit).toHaveBeenCalledWith(RESET_STORY_ARGS, {
storyId: '1',
});
return storyFn();
},
],
{ id: '1', args: {} }
);
});
});
describe('useGlobals', () => {

View File

@ -243,6 +243,62 @@ describe('preview.story_store', () => {
})
);
});
it('resetStoryArgs resets a single arg', () => {
const store = new StoryStore({ channel });
addStoryToStore(store, 'a', '1', () => 0);
expect(store.getRawStory('a', '1').args).toEqual({});
store.updateStoryArgs('a--1', { foo: 'bar', bar: 'baz' });
expect(store.getRawStory('a', '1').args).toEqual({ foo: 'bar', bar: 'baz' });
store.resetStoryArgs('a--1', ['foo']);
expect(store.getRawStory('a', '1').args).toEqual({ bar: 'baz' });
});
it('resetStoryArgs resets all args', () => {
const store = new StoryStore({ channel });
addStoryToStore(store, 'a', '1', () => 0);
expect(store.getRawStory('a', '1').args).toEqual({});
store.updateStoryArgs('a--1', { foo: 'bar', bar: 'baz' });
expect(store.getRawStory('a', '1').args).toEqual({ foo: 'bar', bar: 'baz' });
store.resetStoryArgs('a--1');
expect(store.getRawStory('a', '1').args).toEqual({});
});
it('resetStoryArgs emits STORY_ARGS_UPDATED', () => {
const onArgsChangedChannel = jest.fn();
const testChannel = mockChannel();
testChannel.on(Events.STORY_ARGS_UPDATED, onArgsChangedChannel);
const store = new StoryStore({ channel: testChannel });
addStoryToStore(store, 'a', '1', () => 0);
store.updateStoryArgs('a--1', { foo: 'bar' });
expect(onArgsChangedChannel).toHaveBeenCalledWith({ storyId: 'a--1', args: { foo: 'bar' } });
store.resetStoryArgs('a--1');
expect(onArgsChangedChannel).toHaveBeenCalledWith({
storyId: 'a--1',
args: {},
});
});
it('should reset if the RESET_STORY_ARGS event is received', () => {
const testChannel = mockChannel();
const store = new StoryStore({ channel: testChannel });
addStoryToStore(store, 'a', '1', () => 0);
store.updateStoryArgs('a--1', { foo: 'bar', bar: 'baz' });
testChannel.emit(Events.RESET_STORY_ARGS, { storyId: 'a--1', argNames: ['foo'] });
expect(store.getRawStory('a', '1').args).toEqual({ bar: 'baz' });
testChannel.emit(Events.RESET_STORY_ARGS, { storyId: 'a--1' });
expect(store.getRawStory('a', '1').args).toEqual({});
});
});
describe('globals', () => {

View File

@ -161,6 +161,12 @@ export default class StoryStore {
this.updateStoryArgs(storyId, updatedArgs)
);
this._channel.on(
Events.RESET_STORY_ARGS,
({ storyId, argNames }: { storyId: string; argNames?: string[] }) =>
this.resetStoryArgs(storyId, argNames)
);
this._channel.on(Events.UPDATE_GLOBALS, ({ globals }: { globals: Args }) =>
this.updateGlobals(globals)
);
@ -389,7 +395,7 @@ export default class StoryStore {
});
// Pull out parameters.args.$ || .argTypes.$.defaultValue into initialArgs
const initialArgs: Args = combinedParameters.args;
const passedArgs: Args = combinedParameters.args;
const defaultArgs: Args = Object.entries(
argTypes as Record<string, { defaultValue: any }>
).reduce((acc, [arg, { defaultValue }]) => {
@ -397,6 +403,7 @@ export default class StoryStore {
return acc;
}, {} as Args);
const initialArgs = { ...defaultArgs, ...passedArgs };
_stories[id] = {
...identification,
@ -406,7 +413,8 @@ export default class StoryStore {
storyFn,
parameters: { ...storyParameters, argTypes },
args: { ...defaultArgs, ...initialArgs },
args: initialArgs,
initialArgs,
};
}
@ -456,6 +464,19 @@ export default class StoryStore {
this._channel.emit(Events.STORY_ARGS_UPDATED, { storyId: id, args: this._stories[id].args });
}
resetStoryArgs(id: string, argNames?: string[]) {
if (!this._stories[id]) throw new Error(`No story for id ${id}`);
const { args, initialArgs } = this._stories[id];
this._stories[id].args = { ...args }; // Make a copy to avoid problems
(argNames || Object.keys(args)).forEach((name) => {
// We overwrite like this to ensure we can reset to falsey values
this._stories[id].args[name] = initialArgs[name];
});
this._channel.emit(Events.STORY_ARGS_UPDATED, { storyId: id, args: this._stories[id].args });
}
fromId = (id: string): PublishedStoreItem | null => {
try {
const data = this._stories[id as string];

View File

@ -54,6 +54,7 @@ export type StoreItem = StoryIdentifier & {
storyFn: StoryFn<any>;
hooks: HooksContext;
args: Args;
initialArgs: Args;
};
export type PublishedStoreItem = StoreItem & {

View File

@ -19,6 +19,8 @@ enum events {
UPDATE_STORY_ARGS = 'updateStoryArgs',
// The values of a stories args just changed
STORY_ARGS_UPDATED = 'storyArgsUpdated',
// Reset either a single arg of a story all args of a story
RESET_STORY_ARGS = 'resetStoryArgs',
// As above
UPDATE_GLOBALS = 'updateGlobals',
GLOBALS_UPDATED = 'globalsUpdated',
@ -53,6 +55,7 @@ export const {
STORY_THREW_EXCEPTION,
UPDATE_STORY_ARGS,
STORY_ARGS_UPDATED,
RESET_STORY_ARGS,
UPDATE_GLOBALS,
GLOBALS_UPDATED,
REGISTER_SUBSCRIPTION,

View File

@ -1,5 +1,5 @@
import { StoriesHash } from '@storybook/api';
import { collapseDocsOnlyStories, collapseAllStories } from './sidebar';
import { collapseDocsOnlyStories, collapseAllStories } from './State';
type Item = StoriesHash[keyof StoriesHash];

View File

@ -1,8 +1,127 @@
import { DOCS_MODE } from 'global';
import rfdc from 'rfdc';
import React, { useMemo, useState, useEffect } from 'react';
import { isRoot } from '@storybook/api';
import { isRoot as isRootFn, Story, StoriesHash } from '@storybook/api';
import { toFiltered, getMains, getParents } from './utils';
import { BooleanSet, FilteredType, Item, DataSet } from '../RefHelpers';
export type ItemType = StoriesHash[keyof StoriesHash];
export const collapseAllStories = (stories: StoriesHash) => {
// keep track of component IDs that have been rewritten to the ID of their first leaf child
const componentIdToLeafId: Record<string, string> = {};
// 1) remove all leaves
const leavesRemoved = Object.values(stories).filter(
(item) => !(item.isLeaf && stories[item.parent].isComponent)
);
// 2) make all components leaves and rewrite their ID's to the first leaf child
const componentsFlattened = leavesRemoved.map((item) => {
const { id, isComponent, isRoot, children, ...rest } = item;
// this is a folder, so just leave it alone
if (!isComponent) {
return item;
}
const nonLeafChildren: string[] = [];
const leafChildren: string[] = [];
children.forEach((child) =>
(stories[child].isLeaf ? leafChildren : nonLeafChildren).push(child)
);
if (leafChildren.length === 0) {
return item; // pass through, we'll handle you later
}
const leafId = leafChildren[0];
const component = {
...rest,
id: leafId,
kind: (stories[leafId] as Story).kind,
isRoot: false,
isLeaf: true,
isComponent: true,
children: [] as string[],
};
componentIdToLeafId[id] = leafId;
// this is a component, so it should not have any non-leaf children
if (nonLeafChildren.length !== 0) {
throw new Error(
`Unexpected '${item.id}': ${JSON.stringify({ isComponent, nonLeafChildren })}`
);
}
return component;
});
// 3) rewrite all the children as needed
const childrenRewritten = componentsFlattened.map((item) => {
if (item.isLeaf) {
return item;
}
const { children, ...rest } = item;
const rewritten = children.map((child) => componentIdToLeafId[child] || child);
return { children: rewritten, ...rest };
});
const result = {} as StoriesHash;
childrenRewritten.forEach((item) => {
result[item.id] = item as Item;
});
return result;
};
export const collapseDocsOnlyStories = (storiesHash: StoriesHash) => {
// keep track of component IDs that have been rewritten to the ID of their first leaf child
const componentIdToLeafId: Record<string, string> = {};
const docsOnlyStoriesRemoved = Object.values(storiesHash).filter((item) => {
if (item.isLeaf && item.parameters && item.parameters.docsOnly) {
componentIdToLeafId[item.parent] = item.id;
return false; // filter it out
}
return true;
});
const docsOnlyComponentsCollapsed = docsOnlyStoriesRemoved.map((item) => {
// collapse docs-only components
const { isComponent, children, id } = item;
if (isComponent && children.length === 1) {
const leafId = componentIdToLeafId[id];
if (leafId) {
const collapsed = {
...item,
id: leafId,
isLeaf: true,
children: [] as string[],
};
return collapsed;
}
}
// update groups
if (children) {
const rewritten = children.map((child) => componentIdToLeafId[child] || child);
return { ...item, children: rewritten };
}
// pass through stories unmodified
return item;
});
const result = {} as StoriesHash;
docsOnlyComponentsCollapsed.forEach((item) => {
result[item.id] = item as Item;
});
return result;
};
const clone = rfdc({ circles: true });
export const ExpanderContext = React.createContext<{
setExpanded: React.Dispatch<React.SetStateAction<Record<string, boolean>>>;
expandedSet: BooleanSet;
@ -75,7 +194,14 @@ const useFiltered = (dataset: DataSet, filter: string, parents: Item[], storyId:
);
};
export const useDataset = (dataset: DataSet = {}, filter: string, storyId: string) => {
export const useDataset = (storiesHash: DataSet = {}, filter: string, storyId: string) => {
const dataset = useMemo(() => {
// protect against mutation
const copy = clone(storiesHash);
return DOCS_MODE ? collapseAllStories(copy) : collapseDocsOnlyStories(copy);
}, [DOCS_MODE, storiesHash]);
const emptyInitial = useMemo(
() => ({
filtered: {},
@ -110,7 +236,7 @@ export const useDataset = (dataset: DataSet = {}, filter: string, storyId: strin
const topLevel = useMemo(
() =>
Object.values(filteredSet).filter(
(i) => (i.depth === 0 && !isRoot(i)) || (!isRoot(i) && isRoot(filteredSet[i.parent]))
(i) => (i.depth === 0 && !isRootFn(i)) || (!isRootFn(i) && isRootFn(filteredSet[i.parent]))
),
[filteredSet]
);
@ -127,7 +253,7 @@ export const useDataset = (dataset: DataSet = {}, filter: string, storyId: strin
() =>
getMains(filteredSet).reduce(
(acc, item) => {
return isRoot(item)
return isRootFn(item)
? { ...acc, roots: [...acc.roots, item] }
: { ...acc, others: [...acc.others, item] };
},

View File

@ -1,129 +1,12 @@
import { DOCS_MODE } from 'global';
import React, { FunctionComponent, useMemo } from 'react';
import rfdc from 'rfdc';
import React, { FunctionComponent } from 'react';
import { Consumer, Combo, StoriesHash, Story } from '@storybook/api';
import { Consumer, Combo, StoriesHash } from '@storybook/api';
import SidebarComponent from '../components/sidebar/Sidebar';
import { useMenu } from './menu';
export type Item = StoriesHash[keyof StoriesHash];
export const collapseAllStories = (stories: StoriesHash) => {
// keep track of component IDs that have been rewritten to the ID of their first leaf child
const componentIdToLeafId: Record<string, string> = {};
// 1) remove all leaves
const leavesRemoved = Object.values(stories).filter(
(item) => !(item.isLeaf && stories[item.parent].isComponent)
);
// 2) make all components leaves and rewrite their ID's to the first leaf child
const componentsFlattened = leavesRemoved.map((item) => {
const { id, isComponent, isRoot, children, ...rest } = item;
// this is a folder, so just leave it alone
if (!isComponent) {
return item;
}
const nonLeafChildren: string[] = [];
const leafChildren: string[] = [];
children.forEach((child) =>
(stories[child].isLeaf ? leafChildren : nonLeafChildren).push(child)
);
if (leafChildren.length === 0) {
return item; // pass through, we'll handle you later
}
const leafId = leafChildren[0];
const component = {
...rest,
id: leafId,
kind: (stories[leafId] as Story).kind,
isRoot: false,
isLeaf: true,
isComponent: true,
children: [] as string[],
};
componentIdToLeafId[id] = leafId;
// this is a component, so it should not have any non-leaf children
if (nonLeafChildren.length !== 0) {
throw new Error(
`Unexpected '${item.id}': ${JSON.stringify({ isComponent, nonLeafChildren })}`
);
}
return component;
});
// 3) rewrite all the children as needed
const childrenRewritten = componentsFlattened.map((item) => {
if (item.isLeaf) {
return item;
}
const { children, ...rest } = item;
const rewritten = children.map((child) => componentIdToLeafId[child] || child);
return { children: rewritten, ...rest };
});
const result = {} as StoriesHash;
childrenRewritten.forEach((item) => {
result[item.id] = item as Item;
});
return result;
};
export const collapseDocsOnlyStories = (storiesHash: StoriesHash) => {
// keep track of component IDs that have been rewritten to the ID of their first leaf child
const componentIdToLeafId: Record<string, string> = {};
const docsOnlyStoriesRemoved = Object.values(storiesHash).filter((item) => {
if (item.isLeaf && item.parameters && item.parameters.docsOnly) {
componentIdToLeafId[item.parent] = item.id;
return false; // filter it out
}
return true;
});
const docsOnlyComponentsCollapsed = docsOnlyStoriesRemoved.map((item) => {
// collapse docs-only components
const { isComponent, children, id } = item;
if (isComponent && children.length === 1) {
const leafId = componentIdToLeafId[id];
if (leafId) {
const collapsed = {
...item,
id: leafId,
isLeaf: true,
children: [] as string[],
};
return collapsed;
}
}
// update groups
if (children) {
const rewritten = children.map((child) => componentIdToLeafId[child] || child);
return { ...item, children: rewritten };
}
// pass through stories unmodified
return item;
});
const result = {} as StoriesHash;
docsOnlyComponentsCollapsed.forEach((item) => {
result[item.id] = item as Item;
});
return result;
};
const clone = rfdc({ circles: true });
const Sidebar: FunctionComponent<{}> = React.memo(() => {
const mapper = ({ state, api }: Combo) => {
const {
@ -137,19 +20,12 @@ const Sidebar: FunctionComponent<{}> = React.memo(() => {
refs,
} = state;
const stories = useMemo(() => {
// protect against mutation
const copy = clone(storiesHash);
return DOCS_MODE ? collapseAllStories(copy) : collapseDocsOnlyStories(copy);
}, [DOCS_MODE, storiesHash]);
const menu = useMenu(api, isFullscreen, showPanel, showNav, enableShortcuts);
return {
title: name,
url,
stories,
stories: storiesHash,
storiesFailed,
storiesConfigured,
refs,

216
yarn.lock
View File

@ -2003,20 +2003,6 @@
resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.7.4.tgz#19bf0f5af19149111c40d98bb0cf82119f5d9eeb"
integrity sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw==
"@emotion/native@^10.0.14":
version "10.0.27"
resolved "https://registry.yarnpkg.com/@emotion/native/-/native-10.0.27.tgz#67c2c0ceeeed873c849c611d9a6497a006d43a8f"
integrity sha512-3qxR2XFizGfABKKbX9kAYc0PHhKuCEuyxshoq3TaMEbi9asWHdQVChg32ULpblm4XAf9oxaitAU7J9SfdwFxtw==
dependencies:
"@emotion/primitives-core" "10.0.27"
"@emotion/primitives-core@10.0.27":
version "10.0.27"
resolved "https://registry.yarnpkg.com/@emotion/primitives-core/-/primitives-core-10.0.27.tgz#7a5fae07fe06a046ced597f5c0048f22d5c45842"
integrity sha512-fRBEDNPSFFOrBJ0OcheuElayrNTNdLF9DzMxtL0sFgsCFvvadlzwJHhJMSwEJuxwARm9GhVLr1p8G8JGkK98lQ==
dependencies:
css-to-react-native "^2.2.1"
"@emotion/serialize@^0.11.15", "@emotion/serialize@^0.11.16":
version "0.11.16"
resolved "https://registry.yarnpkg.com/@emotion/serialize/-/serialize-0.11.16.tgz#dee05f9e96ad2fb25a5206b6d759b2d1ed3379ad"
@ -3785,7 +3771,7 @@
"@parcel/utils" "^1.11.0"
physical-cpu-count "^2.0.0"
"@reach/router@^1.2.1", "@reach/router@^1.3.3":
"@reach/router@^1.3.3":
version "1.3.3"
resolved "https://registry.yarnpkg.com/@reach/router/-/router-1.3.3.tgz#58162860dce6c9449d49be86b0561b5ef46d80db"
integrity sha512-gOIAiFhWdiVGSVjukKeNKkCRBLmnORoTPyBihI/jLunICPgxdP30DroAvPQuf1eVfQbfGJQDJkwhJXsNPMnVWw==
@ -3875,110 +3861,6 @@
resolved "https://registry.yarnpkg.com/@soda/get-current-script/-/get-current-script-1.0.0.tgz#623aa40623550e3b94767cffeb096a6fb597ed09"
integrity sha512-9GvTek+7cVw7r+L7TNGOG1astZJWXz2h5q4BqMXl28KN+24iSCm1xo+RhZOZvwdT3bzNe9hD7riJc/lBoO7mgg==
"@storybook/addons@6.0.0-alpha.0":
version "6.0.0-alpha.0"
resolved "https://registry.yarnpkg.com/@storybook/addons/-/addons-6.0.0-alpha.0.tgz#f4416a8c9c081961e5950a7962d7a5102138717e"
integrity sha512-CrPvlo7pW44t7f/YWoEXMRgafvBKAcDYw9/sbBlltu88nKMHU28qjLf95HiTXtiE6P9AqdkRdVkQtyVWhnqKQA==
dependencies:
"@storybook/api" "6.0.0-alpha.0"
"@storybook/channels" "6.0.0-alpha.0"
"@storybook/client-logger" "6.0.0-alpha.0"
"@storybook/core-events" "6.0.0-alpha.0"
core-js "^3.0.1"
global "^4.3.2"
util-deprecate "^1.0.2"
"@storybook/api@6.0.0-alpha.0":
version "6.0.0-alpha.0"
resolved "https://registry.yarnpkg.com/@storybook/api/-/api-6.0.0-alpha.0.tgz#9b612f8c41fb8b1f9bbd3c990b5a1b3beb0eb82a"
integrity sha512-aKYxx39jfakMfYB0FJkFqlqig8Ph/y3K4QaUgmYbL9CSuouvvfBDGh1onhp2mwZpqohrAKl9UAeNZp9HDM0dug==
dependencies:
"@reach/router" "^1.2.1"
"@storybook/channels" "6.0.0-alpha.0"
"@storybook/client-logger" "6.0.0-alpha.0"
"@storybook/core-events" "6.0.0-alpha.0"
"@storybook/csf" "0.0.1"
"@storybook/router" "6.0.0-alpha.0"
"@storybook/theming" "6.0.0-alpha.0"
"@types/reach__router" "^1.2.3"
core-js "^3.0.1"
fast-deep-equal "^2.0.1"
global "^4.3.2"
lodash "^4.17.15"
memoizerific "^1.11.3"
prop-types "^15.6.2"
react "^16.8.3"
semver "^6.0.0"
shallow-equal "^1.1.0"
store2 "^2.7.1"
telejson "^3.2.0"
util-deprecate "^1.0.2"
"@storybook/channel-postmessage@6.0.0-alpha.0":
version "6.0.0-alpha.0"
resolved "https://registry.yarnpkg.com/@storybook/channel-postmessage/-/channel-postmessage-6.0.0-alpha.0.tgz#dec7245e9be7b1303c8bd60e664134a56639ae54"
integrity sha512-OX3Ho/MbQ1+wVPh/9gAATf4LxoFN6k62GtmB5qcpkpJkSUhs5AQQPVG70kHpb7eCaRmV6a90b67tiLDRWNyzow==
dependencies:
"@storybook/channels" "6.0.0-alpha.0"
"@storybook/client-logger" "6.0.0-alpha.0"
core-js "^3.0.1"
global "^4.3.2"
telejson "^3.2.0"
"@storybook/channel-websocket@6.0.0-alpha.0":
version "6.0.0-alpha.0"
resolved "https://registry.yarnpkg.com/@storybook/channel-websocket/-/channel-websocket-6.0.0-alpha.0.tgz#81d10287250b76b0ab5856cb96c4827714f31875"
integrity sha512-bbTeYoRTXPjh/eybeOtBrnFGKE2YUmu7S2sCLzvyDbbQCLYuE/qlhFBX23d/xJSzZZz4pCkj687E15MOIXQ3eA==
dependencies:
"@storybook/channels" "6.0.0-alpha.0"
core-js "^3.0.1"
global "^4.3.2"
json-fn "^1.1.1"
"@storybook/channels@6.0.0-alpha.0":
version "6.0.0-alpha.0"
resolved "https://registry.yarnpkg.com/@storybook/channels/-/channels-6.0.0-alpha.0.tgz#c86e3bdff2e98444a0e9938a1a4abec503221af4"
integrity sha512-0Va1Cajk2X9tQVJKizdDFLKgBJmYakd3ykV1rIYdlPHi+5DndQQ3EqxKrLGE6nQLcKVoxM84Sq8nCLyC891+mw==
dependencies:
core-js "^3.0.1"
"@storybook/client-api@6.0.0-alpha.0":
version "6.0.0-alpha.0"
resolved "https://registry.yarnpkg.com/@storybook/client-api/-/client-api-6.0.0-alpha.0.tgz#9a6766a9878ee1f41b35debd93d480fef50506c2"
integrity sha512-G24H5mFxxptS0G2UwNNxPlV8RM+h6vUxQTmXUtqQoangJPQ/IUm+Ts9QgqDiyHEks9pwYEpSGMAdycZf0IUhJA==
dependencies:
"@storybook/addons" "6.0.0-alpha.0"
"@storybook/channel-postmessage" "6.0.0-alpha.0"
"@storybook/channels" "6.0.0-alpha.0"
"@storybook/client-logger" "6.0.0-alpha.0"
"@storybook/core-events" "6.0.0-alpha.0"
"@storybook/csf" "0.0.1"
"@types/webpack-env" "^1.15.0"
core-js "^3.0.1"
eventemitter3 "^4.0.0"
global "^4.3.2"
is-plain-object "^3.0.0"
lodash "^4.17.15"
memoizerific "^1.11.3"
qs "^6.6.0"
stable "^0.1.8"
ts-dedent "^1.1.0"
util-deprecate "^1.0.2"
"@storybook/client-logger@6.0.0-alpha.0":
version "6.0.0-alpha.0"
resolved "https://registry.yarnpkg.com/@storybook/client-logger/-/client-logger-6.0.0-alpha.0.tgz#c8dd075d5a4a78158f6acb8ace14cf0492f2af16"
integrity sha512-qiML4TiQCFosvxlVGqDbqSy2MA7DuBPclbocliaXEnYAlHzHy5LaQ7OK2SZzigMuim7LOr/eNmqaLAIDVfAjTg==
dependencies:
core-js "^3.0.1"
"@storybook/core-events@6.0.0-alpha.0":
version "6.0.0-alpha.0"
resolved "https://registry.yarnpkg.com/@storybook/core-events/-/core-events-6.0.0-alpha.0.tgz#a35d2f96f6d38aba080d7f5f1ec67799325728de"
integrity sha512-BvJvokog7ezWg0rMIYYUA1d1Bi14hy8iZeQyD0s/Q17EMjqZb1ATQ1cPr9lVJ0CpyYOYRJp8IPbvGDnMFkm8YA==
dependencies:
core-js "^3.0.1"
"@storybook/csf@0.0.1":
version "0.0.1"
resolved "https://registry.yarnpkg.com/@storybook/csf/-/csf-0.0.1.tgz#95901507dc02f0bc6f9ac8ee1983e2fc5bb98ce6"
@ -4055,37 +3937,6 @@
resolved "https://registry.yarnpkg.com/@storybook/preset-scss/-/preset-scss-1.0.2.tgz#6c993b972c6f599237082b55e12c875f0f66ab06"
integrity sha512-Kq+Y3H7qRBxocLW57V9HtQhrw9ZzmTodFCjf+OelMh1k6SZ7/FvJHb7mtWofafHcqq1tSQlNIgYMtHRDJ64WVg==
"@storybook/react-native@6.0.0-alpha.0":
version "6.0.0-alpha.0"
resolved "https://registry.yarnpkg.com/@storybook/react-native/-/react-native-6.0.0-alpha.0.tgz#e05090a351d41da756fb0cf9a637a05be15babb4"
integrity sha512-36lg/YqDTB2AZquRj4xVORVzNPE+A9E0WysJUn6If2yP3LCQ9y0mMucArKxJinYnW6A6UZptw18gZqOmkYatFg==
dependencies:
"@emotion/core" "^10.0.20"
"@emotion/native" "^10.0.14"
"@storybook/addons" "6.0.0-alpha.0"
"@storybook/channel-websocket" "6.0.0-alpha.0"
"@storybook/channels" "6.0.0-alpha.0"
"@storybook/client-api" "6.0.0-alpha.0"
"@storybook/core-events" "6.0.0-alpha.0"
core-js "^3.0.1"
emotion-theming "^10.0.19"
react-native-swipe-gestures "^1.0.4"
"@storybook/router@6.0.0-alpha.0":
version "6.0.0-alpha.0"
resolved "https://registry.yarnpkg.com/@storybook/router/-/router-6.0.0-alpha.0.tgz#c2b9da6c7eba0dccf32228a72e23ecf8875aacac"
integrity sha512-jpFaJu8SFiHqTqG5bSab7qOMRcAZb5htFjD6zSTb/1a3km9yLJQqYA0Jk0rFBrc89lwd/ngYVBOuOrn/XJRwoA==
dependencies:
"@reach/router" "^1.2.1"
"@storybook/csf" "0.0.1"
"@types/reach__router" "^1.2.3"
core-js "^3.0.1"
global "^4.3.2"
lodash "^4.17.15"
memoizerific "^1.11.3"
qs "^6.6.0"
util-deprecate "^1.0.2"
"@storybook/semver@^7.3.2":
version "7.3.2"
resolved "https://registry.yarnpkg.com/@storybook/semver/-/semver-7.3.2.tgz#f3b9c44a1c9a0b933c04e66d0048fcf2fa10dac0"
@ -4094,25 +3945,6 @@
core-js "^3.6.5"
find-up "^4.1.0"
"@storybook/theming@6.0.0-alpha.0":
version "6.0.0-alpha.0"
resolved "https://registry.yarnpkg.com/@storybook/theming/-/theming-6.0.0-alpha.0.tgz#0a9580cecb1c9609e070c8db7737bd121faf56c3"
integrity sha512-XFFpbX2ls1AvbesF64y1q53kMMZYTd/U5EluFmqDsAvoqXVXXKbh8wcguxnMlEHYvgXoDKmzCww+IpmVbAyYcA==
dependencies:
"@emotion/core" "^10.0.20"
"@emotion/is-prop-valid" "^0.8.6"
"@emotion/styled" "^10.0.17"
"@storybook/client-logger" "6.0.0-alpha.0"
core-js "^3.0.1"
deep-object-diff "^1.1.0"
emotion-theming "^10.0.19"
global "^4.3.2"
memoizerific "^1.11.3"
polished "^3.3.1"
prop-types "^15.7.2"
resolve-from "^5.0.0"
ts-dedent "^1.1.0"
"@stroncium/procfs@^1.0.0":
version "1.2.1"
resolved "https://registry.yarnpkg.com/@stroncium/procfs/-/procfs-1.2.1.tgz#6b9be6fd20fb0a4c20e99a8695e083c699bb2b45"
@ -4833,7 +4665,7 @@
resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.3.tgz#7ee330ba7caafb98090bece86a5ee44115904c2c"
integrity sha512-ewFXqrQHlFsgc09MK5jP5iR7vumV/BYayNC6PgJO2LPe8vrnNFyjQjSppfEngITi0qvfKtzFvgKymGheFM9UOA==
"@types/reach__router@^1.2.3", "@types/reach__router@^1.3.5":
"@types/reach__router@^1.3.5":
version "1.3.5"
resolved "https://registry.yarnpkg.com/@types/reach__router/-/reach__router-1.3.5.tgz#14e1e981cccd3a5e50dc9e969a72de0b9d472f6d"
integrity sha512-h0NbqXN/tJuBY/xggZSej1SKQEstbHO7J/omt1tYoFGmj3YXOodZKbbqD4mNDh7zvEGYd7YFrac1LTtAr3xsYQ==
@ -5034,7 +4866,7 @@
resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-7.0.4.tgz#00a5749810b4ad80bff73a61f9cc9d0d521feb3c"
integrity sha512-WGZCqBZZ0mXN2RxvLHL6/7RCu+OWs28jgQMP04LWfpyJlQUMTR6YU9CNJAKDgbw+EV/u687INXuLUc7FuML/4g==
"@types/webpack-env@^1.15.0", "@types/webpack-env@^1.15.1", "@types/webpack-env@^1.15.2":
"@types/webpack-env@^1.15.1", "@types/webpack-env@^1.15.2":
version "1.15.2"
resolved "https://registry.yarnpkg.com/@types/webpack-env/-/webpack-env-1.15.2.tgz#927997342bb9f4a5185a86e6579a0a18afc33b0a"
integrity sha512-67ZgZpAlhIICIdfQrB5fnDvaKFcDxpKibxznfYRVAT4mQE41Dido/3Ty+E3xGBmTogc5+0Qb8tWhna+5B8z1iQ==
@ -11341,7 +11173,7 @@ css-selector-tokenizer@^0.7.0, css-selector-tokenizer@^0.7.1:
fastparse "^1.1.2"
regexpu-core "^4.6.0"
css-to-react-native@^2.2.1, css-to-react-native@^2.2.2:
css-to-react-native@^2.2.2:
version "2.3.2"
resolved "https://registry.yarnpkg.com/css-to-react-native/-/css-to-react-native-2.3.2.tgz#e75e2f8f7aa385b4c3611c52b074b70a002f2e7d"
integrity sha512-VOFaeZA053BqvvvqIA8c9n0+9vFppVBAHCp6JgFTtTMU3Mzi+XnelJ9XC9ul3BqFzZyQ5N+H0SnwsWT2Ebchxw==
@ -14484,11 +14316,6 @@ fast-deep-equal@^1.0.0:
resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz#c053477817c86b51daa853c81e059b733d023614"
integrity sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ=
fast-deep-equal@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz#7b05218ddf9667bf7f370bf7fdb2cb15fdd0aa49"
integrity sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=
fast-deep-equal@^3.1.1:
version "3.1.1"
resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz#545145077c501491e33b15ec408c294376e94ae4"
@ -17646,7 +17473,7 @@ is-fullwidth-code-point@^3.0.0:
resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d"
integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==
is-function@^1.0.1, is-function@^1.0.2:
is-function@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/is-function/-/is-function-1.0.2.tgz#4f097f30abf6efadac9833b17ca5dc03f8144e08"
integrity sha512-lw7DUp0aWXYg+CBCN+JKkcE0Q2RayZnSvnZBlwgxHBQhqt5pZNVy4Ri7H9GmmXkdu7LUthszM+Tor1u/2iBcpQ==
@ -19919,11 +19746,6 @@ json-buffer@3.0.0:
resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.0.tgz#5b1f397afc75d677bde8bcfc0e47e1f9a3d9a898"
integrity sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=
json-fn@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/json-fn/-/json-fn-1.1.1.tgz#4293c9198a482d6697d334a6e32cd0d221121e80"
integrity sha1-QpPJGYpILWaX0zSm4yzQ0iESHoA=
json-parse-better-errors@^1.0.0, json-parse-better-errors@^1.0.1, json-parse-better-errors@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9"
@ -24463,7 +24285,7 @@ pnp-webpack-plugin@1.6.4, pnp-webpack-plugin@^1.6.4:
dependencies:
ts-pnp "^1.1.6"
polished@^3.3.1, polished@^3.4.4:
polished@^3.4.4:
version "3.6.3"
resolved "https://registry.yarnpkg.com/polished/-/polished-3.6.3.tgz#68f4fe7ffad46530733029b939dd12978200cb59"
integrity sha512-QJ0q0b6gX1+0OJtPMfgVJxV0vg5XTa4im+Rca989dAtmsd/fEky3X+0A+V+OUXq1nyiDGplJwqD853dTS0gkPg==
@ -26721,11 +26543,6 @@ react-moment-proptypes@^1.7.0:
dependencies:
moment ">=1.6.0"
react-native-swipe-gestures@^1.0.4:
version "1.0.5"
resolved "https://registry.yarnpkg.com/react-native-swipe-gestures/-/react-native-swipe-gestures-1.0.5.tgz#a172cb0f3e7478ccd681fd36b8bfbcdd098bde7c"
integrity sha512-Ns7Bn9H/Tyw278+5SQx9oAblDZ7JixyzeOczcBK8dipQk2pD7Djkcfnf1nB/8RErAmMLL9iXgW0QHqiII8AhKw==
react-popper-tooltip@^2.11.0, react-popper-tooltip@^2.11.1:
version "2.11.1"
resolved "https://registry.yarnpkg.com/react-popper-tooltip/-/react-popper-tooltip-2.11.1.tgz#3c4bdfd8bc10d1c2b9a162e859bab8958f5b2644"
@ -28866,11 +28683,6 @@ shallow-copy@~0.0.1:
resolved "https://registry.yarnpkg.com/shallow-copy/-/shallow-copy-0.0.1.tgz#415f42702d73d810330292cc5ee86eae1a11a170"
integrity sha1-QV9CcC1z2BAzApLMXuhurhoRoXA=
shallow-equal@^1.1.0:
version "1.2.1"
resolved "https://registry.yarnpkg.com/shallow-equal/-/shallow-equal-1.2.1.tgz#4c16abfa56043aa20d050324efa68940b0da79da"
integrity sha512-S4vJDjHHMBaiZuT9NPb616CSmLf618jawtv3sufLl6ivK8WocjAo58cXwbRV1cgqxH0Qbv+iUt6m05eqEa2IRA==
shallowequal@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/shallowequal/-/shallowequal-1.1.0.tgz#188d521de95b9087404fd4dcb68b13df0ae4e7f8"
@ -30414,20 +30226,6 @@ teeny-request@6.0.1:
stream-events "^1.0.5"
uuid "^3.3.2"
telejson@^3.2.0:
version "3.3.0"
resolved "https://registry.yarnpkg.com/telejson/-/telejson-3.3.0.tgz#6d814f3c0d254d5c4770085aad063e266b56ad03"
integrity sha512-er08AylQ+LEbDLp1GRezORZu5wKOHaBczF6oYJtgC3Idv10qZ8A3p6ffT+J5BzDKkV9MqBvu8HAKiIIOp6KJ2w==
dependencies:
"@types/is-function" "^1.0.0"
global "^4.4.0"
is-function "^1.0.1"
is-regex "^1.0.4"
is-symbol "^1.0.3"
isobject "^4.0.0"
lodash "^4.17.15"
memoizerific "^1.11.3"
telejson@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/telejson/-/telejson-4.0.0.tgz#91ac1747f1efbc88a58e4344fbd8fe438695f77e"
@ -31130,7 +30928,7 @@ tryer@^1.0.1:
resolved "https://registry.yarnpkg.com/tryer/-/tryer-1.0.1.tgz#f2c85406800b9b0f74c9f7465b81eaad241252f8"
integrity sha512-c3zayb8/kWWpycWYg87P71E1S1ZL6b6IJxfb5fvsUgsf0S2MVGaDhDXXjDMpdCpfWXqptc+4mXwmiy1ypXqRAA==
ts-dedent@^1.1.0, ts-dedent@^1.1.1:
ts-dedent@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/ts-dedent/-/ts-dedent-1.1.1.tgz#68fad040d7dbd53a90f545b450702340e17d18f3"
integrity sha512-UGTRZu1evMw4uTPyYF66/KFd22XiU+jMaIuHrkIHQ2GivAXVlLV0v/vHrpOuTRf9BmpNHi/SO7Vd0rLu0y57jg==