mirror of
https://github.com/storybookjs/storybook.git
synced 2025-04-01 05:05:25 +08:00
Merge remote-tracking branch 'origin/next' into jeppe/fix-svelte-in-docs
This commit is contained in:
commit
ce95c52e32
@ -1,5 +1,12 @@
|
||||
version: 2.1
|
||||
|
||||
parameters:
|
||||
workflow:
|
||||
description: Which workflow to run
|
||||
type: enum
|
||||
enum: ['tests', 'daily-tests']
|
||||
default: 'tests'
|
||||
|
||||
executors:
|
||||
sb_node_16_classic:
|
||||
parameters:
|
||||
@ -169,7 +176,7 @@ jobs:
|
||||
destination: sb-bench.tar.gz
|
||||
react-vite-bench:
|
||||
executor:
|
||||
class: medium
|
||||
class: large
|
||||
name: sb_playwright
|
||||
working_directory: /tmp/storybook
|
||||
steps:
|
||||
@ -246,12 +253,12 @@ jobs:
|
||||
name: Test
|
||||
command: |
|
||||
cd scripts
|
||||
yarn test --coverage --runInBand --ci
|
||||
yarn test --coverage --ci
|
||||
- store_test_results:
|
||||
path: scripts/junit.xml
|
||||
unit-tests:
|
||||
executor:
|
||||
class: medium+
|
||||
class: xlarge
|
||||
name: sb_node_16_browsers
|
||||
steps:
|
||||
- git-shallow-clone/checkout_advanced:
|
||||
@ -262,7 +269,7 @@ jobs:
|
||||
name: Test
|
||||
command: |
|
||||
cd code
|
||||
yarn test --coverage --runInBand --ci
|
||||
yarn test --coverage --ci
|
||||
- store_test_results:
|
||||
path: code/junit.xml
|
||||
- persist_to_workspace:
|
||||
@ -302,10 +309,18 @@ jobs:
|
||||
path: test-results
|
||||
## new workflow
|
||||
create-sandboxes:
|
||||
parameters:
|
||||
parallelism:
|
||||
type: integer
|
||||
default: 9
|
||||
cadence:
|
||||
type: enum
|
||||
enum: [ "ci", "daily", "weekly" ]
|
||||
default: "ci"
|
||||
executor:
|
||||
class: medium
|
||||
name: sb_node_16_browsers
|
||||
parallelism: 9
|
||||
parallelism: << parameters.parallelism >>
|
||||
steps:
|
||||
- git-shallow-clone/checkout_advanced:
|
||||
clone_options: '--depth 1 --verbose'
|
||||
@ -313,7 +328,7 @@ jobs:
|
||||
at: .
|
||||
- run:
|
||||
name: Creating Sandboxes
|
||||
command: yarn task --task sandbox --template $(yarn get-template ci create) --no-link --start-from=never --junit
|
||||
command: yarn task --task sandbox --template $(yarn get-template << parameters.cadence >> create) --no-link --start-from=never --junit
|
||||
- persist_to_workspace:
|
||||
root: .
|
||||
paths:
|
||||
@ -321,10 +336,18 @@ jobs:
|
||||
- store_test_results:
|
||||
path: test-results
|
||||
smoke-test-sandboxes:
|
||||
parameters:
|
||||
parallelism:
|
||||
type: integer
|
||||
default: 9
|
||||
cadence:
|
||||
type: enum
|
||||
enum: [ "ci", "daily", "weekly" ]
|
||||
default: "ci"
|
||||
executor:
|
||||
class: medium
|
||||
name: sb_node_16_browsers
|
||||
parallelism: 9
|
||||
parallelism: << parameters.parallelism >>
|
||||
steps:
|
||||
- git-shallow-clone/checkout_advanced:
|
||||
clone_options: '--depth 1 --verbose'
|
||||
@ -332,14 +355,22 @@ jobs:
|
||||
at: .
|
||||
- run:
|
||||
name: Smoke Testing Sandboxes
|
||||
command: yarn task --task smoke-test --template $(yarn get-template ci smoke-test) --no-link --start-from=never --junit
|
||||
command: yarn task --task smoke-test --template $(yarn get-template << parameters.cadence >> smoke-test) --no-link --start-from=never --junit
|
||||
- store_test_results:
|
||||
path: test-results
|
||||
build-sandboxes:
|
||||
parameters:
|
||||
parallelism:
|
||||
type: integer
|
||||
default: 9
|
||||
cadence:
|
||||
type: enum
|
||||
enum: [ "ci", "daily", "weekly" ]
|
||||
default: "ci"
|
||||
executor:
|
||||
class: medium+
|
||||
name: sb_node_16_browsers
|
||||
parallelism: 9
|
||||
parallelism: << parameters.parallelism >>
|
||||
steps:
|
||||
- git-shallow-clone/checkout_advanced:
|
||||
clone_options: '--depth 1 --verbose'
|
||||
@ -347,7 +378,7 @@ jobs:
|
||||
at: .
|
||||
- run:
|
||||
name: Building Sandboxes
|
||||
command: yarn task --task build --template $(yarn get-template ci build) --no-link --start-from=never --junit
|
||||
command: yarn task --task build --template $(yarn get-template << parameters.cadence >> build) --no-link --start-from=never --junit
|
||||
- store_test_results:
|
||||
path: test-results
|
||||
- persist_to_workspace:
|
||||
@ -355,10 +386,18 @@ jobs:
|
||||
paths:
|
||||
- sandbox/*/storybook-static
|
||||
test-runner-sandboxes:
|
||||
parameters:
|
||||
parallelism:
|
||||
type: integer
|
||||
default: 9
|
||||
cadence:
|
||||
type: enum
|
||||
enum: [ "ci", "daily", "weekly" ]
|
||||
default: "ci"
|
||||
executor:
|
||||
class: medium
|
||||
name: sb_playwright
|
||||
parallelism: 9
|
||||
parallelism: << parameters.parallelism >>
|
||||
steps:
|
||||
- git-shallow-clone/checkout_advanced:
|
||||
clone_options: '--depth 1 --verbose'
|
||||
@ -366,29 +405,44 @@ jobs:
|
||||
at: .
|
||||
- run:
|
||||
name: Running Test Runner
|
||||
command: yarn task --task test-runner --template $(yarn get-template ci test-runner) --no-link --start-from=never --junit
|
||||
command: yarn task --task test-runner --template $(yarn get-template << parameters.cadence >> test-runner) --no-link --start-from=never --junit
|
||||
- store_test_results:
|
||||
path: test-results
|
||||
chromatic-sandboxes:
|
||||
parameters:
|
||||
parallelism:
|
||||
type: integer
|
||||
default: 9
|
||||
cadence:
|
||||
type: enum
|
||||
enum: ["ci", "daily", "weekly"]
|
||||
default: "ci"
|
||||
executor:
|
||||
class: medium
|
||||
name: sb_node_16_browsers
|
||||
parallelism: 9
|
||||
parallelism: << parameters.parallelism >>
|
||||
steps:
|
||||
- git-shallow-clone/checkout_advanced:
|
||||
clone_options: '--depth 1 --verbose'
|
||||
- checkout
|
||||
- attach_workspace:
|
||||
at: .
|
||||
- run:
|
||||
name: Running Chromatic
|
||||
command: yarn task --task chromatic --template $(yarn get-template ci chromatic) --no-link --start-from=never --junit
|
||||
command: yarn task --task chromatic --template $(yarn get-template << parameters.cadence >> chromatic) --no-link --start-from=never --junit
|
||||
- store_test_results:
|
||||
path: test-results
|
||||
e2e-sandboxes:
|
||||
parameters:
|
||||
parallelism:
|
||||
type: integer
|
||||
default: 9
|
||||
cadence:
|
||||
type: enum
|
||||
enum: ["ci", "daily", "weekly"]
|
||||
default: "ci"
|
||||
executor:
|
||||
class: medium
|
||||
name: sb_playwright
|
||||
parallelism: 9
|
||||
parallelism: << parameters.parallelism >>
|
||||
steps:
|
||||
- git-shallow-clone/checkout_advanced:
|
||||
clone_options: '--depth 1 --verbose'
|
||||
@ -396,7 +450,7 @@ jobs:
|
||||
at: .
|
||||
- run:
|
||||
name: Running E2E Tests
|
||||
command: yarn task --task e2e-tests --template $(yarn get-template ci e2e-tests) --no-link --start-from=never --junit
|
||||
command: yarn task --task e2e-tests --template $(yarn get-template << parameters.cadence >> e2e-tests) --no-link --start-from=never --junit
|
||||
- store_test_results:
|
||||
path: test-results
|
||||
- store_artifacts: # this is where playwright puts more complex stuff
|
||||
@ -404,7 +458,45 @@ jobs:
|
||||
destination: playwright
|
||||
|
||||
workflows:
|
||||
daily-tests:
|
||||
when:
|
||||
equal: [ daily-tests, << pipeline.parameters.workflow >> ]
|
||||
jobs:
|
||||
- build
|
||||
- publish:
|
||||
requires:
|
||||
- build
|
||||
- create-sandboxes:
|
||||
parallelism: 24
|
||||
cadence: "daily"
|
||||
requires:
|
||||
- publish
|
||||
# - smoke-test-sandboxes: # disabled for now
|
||||
# requires:
|
||||
# - create-sandboxes
|
||||
- build-sandboxes:
|
||||
parallelism: 24
|
||||
cadence: "daily"
|
||||
requires:
|
||||
- create-sandboxes
|
||||
- test-runner-sandboxes:
|
||||
parallelism: 24
|
||||
cadence: "daily"
|
||||
requires:
|
||||
- build-sandboxes
|
||||
- chromatic-sandboxes:
|
||||
parallelism: 24
|
||||
cadence: "daily"
|
||||
requires:
|
||||
- build-sandboxes
|
||||
- e2e-sandboxes:
|
||||
parallelism: 24
|
||||
cadence: "daily"
|
||||
requires:
|
||||
- build-sandboxes
|
||||
test:
|
||||
when:
|
||||
equal: [ tests, << pipeline.parameters.workflow >> ]
|
||||
jobs:
|
||||
- build
|
||||
- lint:
|
||||
|
@ -1,8 +0,0 @@
|
||||
{
|
||||
"printWidth": 100,
|
||||
"tabWidth": 2,
|
||||
"bracketSpacing": true,
|
||||
"trailingComma": "es5",
|
||||
"singleQuote": true,
|
||||
"arrowParens": "always"
|
||||
}
|
@ -40,7 +40,7 @@
|
||||
"./react": {
|
||||
"require": "./dist/react/index.js",
|
||||
"import": "./dist/react/index.mjs",
|
||||
"types": "./dist/react.d.ts"
|
||||
"types": "./dist/react/index.d.ts"
|
||||
},
|
||||
"./register": {
|
||||
"require": "./dist/manager.js",
|
||||
|
@ -41,7 +41,7 @@
|
||||
"./preview": {
|
||||
"require": "./dist/preset/preview.js",
|
||||
"import": "./dist/preset/preview.mjs",
|
||||
"types": "./dist/preview.d.ts"
|
||||
"types": "./dist/preset/preview.d.ts"
|
||||
},
|
||||
"./register": {
|
||||
"require": "./dist/manager.js",
|
||||
|
@ -32,7 +32,7 @@ window.__STORYBOOK_CLIENT_API__ = new ClientApi({ storyStore: preview.storyStore
|
||||
|
||||
preview.initialize({ importFn, getProjectAnnotations });
|
||||
|
||||
if (module.hot) {
|
||||
if (import.meta.webpackHot) {
|
||||
import.meta.webpackHot.accept('./{{storiesFilename}}', () => {
|
||||
// importFn has changed so we need to patch the new one in
|
||||
preview.onStoriesChanged({ importFn });
|
||||
|
61
code/lib/cli/src/automigrate/fixes/docsPage-automatic.ts
Normal file
61
code/lib/cli/src/automigrate/fixes/docsPage-automatic.ts
Normal file
@ -0,0 +1,61 @@
|
||||
import chalk from 'chalk';
|
||||
import { dedent } from 'ts-dedent';
|
||||
|
||||
import type { ConfigFile } from '@storybook/csf-tools';
|
||||
import { readConfig, writeConfig } from '@storybook/csf-tools';
|
||||
import { getStorybookInfo } from '@storybook/core-common';
|
||||
|
||||
import type { Fix } from '../types';
|
||||
|
||||
const logger = console;
|
||||
|
||||
interface DocsPageAutomaticFrameworkRunOptions {
|
||||
main: ConfigFile;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the docs.docsPage option to automatic if it isn't already set
|
||||
*/
|
||||
export const docsPageAutomatic: Fix<DocsPageAutomaticFrameworkRunOptions> = {
|
||||
id: 'docsPageAutomatic',
|
||||
|
||||
async check({ packageManager }) {
|
||||
const packageJson = packageManager.retrievePackageJson();
|
||||
|
||||
const { mainConfig } = getStorybookInfo(packageJson);
|
||||
|
||||
if (!mainConfig) {
|
||||
logger.warn('Unable to find storybook main.js config, skipping');
|
||||
return null;
|
||||
}
|
||||
|
||||
const main = await readConfig(mainConfig);
|
||||
const docs = main.getFieldValue(['docs']);
|
||||
|
||||
return docs?.docsPage === undefined ? { main } : null;
|
||||
},
|
||||
|
||||
prompt() {
|
||||
const docsPageAutomaticFormatted = chalk.cyan(`docs: { docsPage: 'automatic' }`);
|
||||
|
||||
return dedent`
|
||||
We've detected that your main.js configuration file has not configured docsPage. In 6.x we
|
||||
we defaulted to having a docsPage for every story, in 7.x you need to opt in per-component.
|
||||
However, we can set the \`docs.docsPage\` to 'automatic' to approximate the old behaviour:
|
||||
|
||||
${docsPageAutomaticFormatted}
|
||||
|
||||
More info: ${chalk.yellow(
|
||||
'https://github.com/storybookjs/storybook/blob/next/MIGRATION.md#docs-page'
|
||||
)}
|
||||
`;
|
||||
},
|
||||
|
||||
async run({ result: { main }, dryRun }) {
|
||||
logger.info(`✅ Setting 'docs.docsPage' to 'automatic' in main.js`);
|
||||
if (!dryRun) {
|
||||
main.setFieldValue(['docsPage', 'docs'], 'automatic');
|
||||
await writeConfig(main);
|
||||
}
|
||||
},
|
||||
};
|
@ -12,6 +12,7 @@ import { sbScripts } from './sb-scripts';
|
||||
import { newFrameworks } from './new-frameworks';
|
||||
import { removedGlobalClientAPIs } from './remove-global-client-apis';
|
||||
import { mdx1to2 } from './mdx-1-to-2';
|
||||
import { docsPageAutomatic } from './docsPage-automatic';
|
||||
|
||||
export * from '../types';
|
||||
|
||||
@ -28,4 +29,5 @@ export const fixes: Fix[] = [
|
||||
newFrameworks,
|
||||
removedGlobalClientAPIs,
|
||||
mdx1to2,
|
||||
docsPageAutomatic,
|
||||
];
|
||||
|
@ -191,12 +191,12 @@ export class StoryStoreFacade<TFramework extends AnyFramework> {
|
||||
|
||||
// NOTE: this logic is equivalent to the `extractStories` function of `StoryIndexGenerator`
|
||||
const docsOptions = (global.DOCS_OPTIONS || {}) as DocsOptions;
|
||||
const docsPageOptedIn =
|
||||
docsOptions.docsPage === 'automatic' ||
|
||||
(docsOptions.docsPage && componentTags.includes('docsPage'));
|
||||
if (docsOptions.enabled && storyExports.length) {
|
||||
// We will use tags soon and this crappy filename test will go away
|
||||
if (
|
||||
fileName.match(/\.mdx$/) ||
|
||||
(docsOptions.docsPage && componentTags.includes('docsPage'))
|
||||
) {
|
||||
if (fileName.match(/\.mdx$/) || docsPageOptedIn) {
|
||||
const name = docsOptions.defaultName;
|
||||
const docsId = toId(componentId || title, name);
|
||||
this.entries[docsId] = {
|
||||
|
@ -11,4 +11,6 @@ export {
|
||||
setGlobalRender,
|
||||
} from './ClientApi';
|
||||
|
||||
export * from '@storybook/store';
|
||||
|
||||
export * from './queryparams';
|
||||
|
@ -46,7 +46,7 @@
|
||||
"globby": "^11.0.2",
|
||||
"jscodeshift": "^0.13.1",
|
||||
"lodash": "^4.17.21",
|
||||
"prettier": ">=2.2.1 <=2.3.0",
|
||||
"prettier": ">=2.2.1 <=3.0.0",
|
||||
"recast": "^0.19.0",
|
||||
"util": "^0.12.4"
|
||||
},
|
||||
|
@ -1295,6 +1295,50 @@ describe('start', () => {
|
||||
`);
|
||||
});
|
||||
});
|
||||
describe('when docsOptions.docsPage = automatic', () => {
|
||||
beforeEach(() => {
|
||||
global.DOCS_OPTIONS = { enabled: true, docsPage: 'automatic', defaultName: 'Docs' };
|
||||
});
|
||||
|
||||
it('adds stories for each component with docsPage tag', async () => {
|
||||
const renderToDOM = jest.fn();
|
||||
|
||||
const { configure, clientApi } = start(renderToDOM);
|
||||
configure('test', () => {
|
||||
(clientApi as any).addParameters({
|
||||
docs: { renderer: () => ({ render: jest.fn((_, _2, _3, d) => d()) }) },
|
||||
});
|
||||
clientApi
|
||||
.storiesOf('Component A', { id: 'file1' } as NodeModule)
|
||||
.add('Story One', jest.fn())
|
||||
.add('Story Two', jest.fn());
|
||||
|
||||
clientApi
|
||||
.storiesOf('Component B', { id: 'file2' } as NodeModule)
|
||||
.addParameters({ tags: ['docsPage'] })
|
||||
.add('Story Three', jest.fn());
|
||||
|
||||
return [componentCExports];
|
||||
});
|
||||
|
||||
await waitForRender();
|
||||
const setIndexData = mockChannel.emit.mock.calls.find(
|
||||
(call: [string, any]) => call[0] === SET_INDEX
|
||||
)[1];
|
||||
expect(Object.keys(setIndexData.entries)).toMatchInlineSnapshot(`
|
||||
Array [
|
||||
"component-a--docs",
|
||||
"component-a--story-one",
|
||||
"component-a--story-two",
|
||||
"component-b--docs",
|
||||
"component-b--story-three",
|
||||
"component-c--docs",
|
||||
"component-c--story-one",
|
||||
"component-c--story-two",
|
||||
]
|
||||
`);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('auto-title', () => {
|
||||
|
@ -441,6 +441,39 @@ describe('StoryIndexGenerator', () => {
|
||||
`);
|
||||
});
|
||||
|
||||
it('generates an entry for every CSF file when docsOptions.docsPage = automatic', async () => {
|
||||
const specifier: CoreCommon_NormalizedStoriesSpecifier = normalizeStoriesEntry(
|
||||
'./src/**/*.stories.(ts|js|jsx)',
|
||||
options
|
||||
);
|
||||
|
||||
const generator = new StoryIndexGenerator([specifier], {
|
||||
...docsPageOptions,
|
||||
docs: {
|
||||
...docsPageOptions.docs,
|
||||
docsPage: 'automatic',
|
||||
},
|
||||
});
|
||||
await generator.initialize();
|
||||
|
||||
expect(Object.keys((await generator.getIndex()).entries)).toMatchInlineSnapshot(`
|
||||
Array [
|
||||
"a--docs",
|
||||
"a--story-one",
|
||||
"b--docs",
|
||||
"b--story-one",
|
||||
"d--docs",
|
||||
"d--story-one",
|
||||
"first-nested-deeply-f--docs",
|
||||
"first-nested-deeply-f--story-one",
|
||||
"nested-button--docs",
|
||||
"nested-button--story-one",
|
||||
"second-nested-g--docs",
|
||||
"second-nested-g--story-one",
|
||||
]
|
||||
`);
|
||||
});
|
||||
|
||||
it('does not generate a docs page entry if there is a standalone entry with the same name', async () => {
|
||||
const csfSpecifier: CoreCommon_NormalizedStoriesSpecifier = normalizeStoriesEntry(
|
||||
'./src/A.stories.js',
|
||||
|
@ -224,12 +224,12 @@ export class StoryIndexGenerator {
|
||||
});
|
||||
|
||||
if (this.options.docs.enabled && csf.stories.length) {
|
||||
const { docsPage } = this.options.docs;
|
||||
const docsPageOptedIn =
|
||||
docsPage === 'automatic' || (docsPage && componentTags.includes('docsPage'));
|
||||
// We always add a template for *.stories.mdx, but only if docs page is enabled for
|
||||
// regular CSF files
|
||||
if (
|
||||
storyIndexer.addDocsTemplate ||
|
||||
(this.options.docs.docsPage && componentTags.includes('docsPage'))
|
||||
) {
|
||||
if (storyIndexer.addDocsTemplate || docsPageOptedIn) {
|
||||
const name = this.options.docs.defaultName;
|
||||
const id = toId(csf.meta.title, name);
|
||||
entries.unshift({
|
||||
|
@ -1,3 +1,5 @@
|
||||
/// <reference types="@types/jest" />;
|
||||
|
||||
import { dedent } from 'ts-dedent';
|
||||
import { formatConfig, loadConfig } from './ConfigFile';
|
||||
|
||||
@ -83,6 +85,7 @@ describe('ConfigFile', () => {
|
||||
).toEqual('webpack5');
|
||||
});
|
||||
});
|
||||
|
||||
describe('module exports', () => {
|
||||
it('missing export', () => {
|
||||
expect(
|
||||
@ -142,6 +145,66 @@ describe('ConfigFile', () => {
|
||||
).toEqual([{ directory: '../src', titlePrefix: 'Demo' }]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('default export', () => {
|
||||
it('missing export', () => {
|
||||
expect(
|
||||
getField(
|
||||
['core', 'builder'],
|
||||
dedent`
|
||||
export default { foo: { builder: 'webpack5' } }
|
||||
`
|
||||
)
|
||||
).toBeUndefined();
|
||||
});
|
||||
it('found scalar', () => {
|
||||
expect(
|
||||
getField(
|
||||
['core', 'builder'],
|
||||
dedent`
|
||||
export default { core: { builder: 'webpack5' } }
|
||||
`
|
||||
)
|
||||
).toEqual('webpack5');
|
||||
});
|
||||
it('variable ref export', () => {
|
||||
expect(
|
||||
getField(
|
||||
['core', 'builder'],
|
||||
dedent`
|
||||
const core = { builder: 'webpack5' };
|
||||
export default { core };
|
||||
`
|
||||
)
|
||||
).toEqual('webpack5');
|
||||
});
|
||||
it('variable rename', () => {
|
||||
expect(
|
||||
getField(
|
||||
['core', 'builder'],
|
||||
dedent`
|
||||
const coreVar = { builder: 'webpack5' };
|
||||
export default { core: coreVar };
|
||||
`
|
||||
)
|
||||
).toEqual('webpack5');
|
||||
});
|
||||
it('variable exports', () => {
|
||||
expect(
|
||||
getField(
|
||||
['stories'],
|
||||
dedent`
|
||||
import type { StorybookConfig } from '@storybook/react-webpack5';
|
||||
|
||||
const config: StorybookConfig = {
|
||||
stories: [{ directory: '../src', titlePrefix: 'Demo' }],
|
||||
}
|
||||
export default config;
|
||||
`
|
||||
)
|
||||
).toEqual([{ directory: '../src', titlePrefix: 'Demo' }]);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('setField', () => {
|
||||
@ -228,6 +291,7 @@ describe('ConfigFile', () => {
|
||||
`);
|
||||
});
|
||||
});
|
||||
|
||||
describe('module exports', () => {
|
||||
it('missing export', () => {
|
||||
expect(
|
||||
@ -283,6 +347,63 @@ describe('ConfigFile', () => {
|
||||
`);
|
||||
});
|
||||
});
|
||||
|
||||
describe('default export', () => {
|
||||
it('missing export', () => {
|
||||
expect(
|
||||
setField(
|
||||
['core', 'builder'],
|
||||
'webpack5',
|
||||
dedent`
|
||||
export default { addons: [] };
|
||||
`
|
||||
)
|
||||
).toMatchInlineSnapshot(`
|
||||
export default {
|
||||
addons: [],
|
||||
core: {
|
||||
builder: "webpack5"
|
||||
}
|
||||
};
|
||||
`);
|
||||
});
|
||||
it('missing field', () => {
|
||||
expect(
|
||||
setField(
|
||||
['core', 'builder'],
|
||||
'webpack5',
|
||||
dedent`
|
||||
export default { core: { foo: 'bar' }};
|
||||
`
|
||||
)
|
||||
).toMatchInlineSnapshot(`
|
||||
export default {
|
||||
core: {
|
||||
foo: 'bar',
|
||||
builder: 'webpack5'
|
||||
}
|
||||
};
|
||||
`);
|
||||
});
|
||||
it('found scalar', () => {
|
||||
expect(
|
||||
setField(
|
||||
['core', 'builder'],
|
||||
'webpack5',
|
||||
dedent`
|
||||
export default { core: { builder: 'webpack4' } };
|
||||
`
|
||||
)
|
||||
).toMatchInlineSnapshot(`
|
||||
export default {
|
||||
core: {
|
||||
builder: 'webpack5'
|
||||
}
|
||||
};
|
||||
`);
|
||||
});
|
||||
});
|
||||
|
||||
describe('quotes', () => {
|
||||
it('no quotes', () => {
|
||||
expect(setField(['foo', 'bar'], 'baz', '')).toMatchInlineSnapshot(`
|
||||
|
@ -108,6 +108,30 @@ export class ConfigFile {
|
||||
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
||||
const self = this;
|
||||
traverse.default(this._ast, {
|
||||
ExportDefaultDeclaration: {
|
||||
enter({ node, parent }) {
|
||||
const decl =
|
||||
t.isIdentifier(node.declaration) && t.isProgram(parent)
|
||||
? _findVarInitialization(node.declaration.name, parent)
|
||||
: node.declaration;
|
||||
|
||||
if (t.isObjectExpression(decl)) {
|
||||
self._exportsObject = decl;
|
||||
decl.properties.forEach((p: t.ObjectProperty) => {
|
||||
const exportName = propKey(p);
|
||||
if (exportName) {
|
||||
let exportVal = p.value;
|
||||
if (t.isIdentifier(exportVal)) {
|
||||
exportVal = _findVarInitialization(exportVal.name, parent as t.Program);
|
||||
}
|
||||
self._exports[exportName] = exportVal as t.Expression;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
logger.warn(`Unexpected ${JSON.stringify(node)}`);
|
||||
}
|
||||
},
|
||||
},
|
||||
ExportNamedDeclaration: {
|
||||
enter({ node, parent }) {
|
||||
if (t.isVariableDeclaration(node.declaration)) {
|
||||
|
@ -47,7 +47,7 @@
|
||||
"@storybook/types": "7.0.0-alpha.47",
|
||||
"estraverse": "^5.2.0",
|
||||
"lodash": "^4.17.21",
|
||||
"prettier": ">=2.2.1 <=2.3.0"
|
||||
"prettier": ">=2.2.1 <=3.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"jest-specific-snapshot": "^4.0.0",
|
||||
|
@ -1,6 +1,37 @@
|
||||
import { SHARED_STATE_CHANGED, SHARED_STATE_SET } from '@storybook/core-events';
|
||||
|
||||
import { addons, useMemo, useState, useEffect, useChannel } from '@storybook/addons';
|
||||
import {
|
||||
addons,
|
||||
HooksContext,
|
||||
applyHooks,
|
||||
useMemo,
|
||||
useCallback,
|
||||
useRef,
|
||||
useState,
|
||||
useReducer,
|
||||
useEffect,
|
||||
useChannel,
|
||||
useStoryContext,
|
||||
useParameter,
|
||||
useArgs,
|
||||
useGlobals,
|
||||
} from '@storybook/addons';
|
||||
|
||||
export {
|
||||
HooksContext,
|
||||
applyHooks,
|
||||
useMemo,
|
||||
useCallback,
|
||||
useRef,
|
||||
useState,
|
||||
useReducer,
|
||||
useEffect,
|
||||
useChannel,
|
||||
useStoryContext,
|
||||
useParameter,
|
||||
useArgs,
|
||||
useGlobals,
|
||||
};
|
||||
|
||||
export function useSharedState<S>(sharedId: string, defaultState?: S): [S, (s: S) => void] {
|
||||
const channel = addons.getChannel();
|
||||
|
50
code/lib/telemetry/src/get-framework-info.ts
Normal file
50
code/lib/telemetry/src/get-framework-info.ts
Normal file
@ -0,0 +1,50 @@
|
||||
import type { PackageJson, StorybookConfig } from '@storybook/types';
|
||||
import { getActualPackageJson } from './package-json';
|
||||
|
||||
const knownRenderers = [
|
||||
'html',
|
||||
'react',
|
||||
'svelte',
|
||||
'vue3',
|
||||
'preact',
|
||||
'server',
|
||||
'vue',
|
||||
'web-components',
|
||||
'angular',
|
||||
'ember',
|
||||
];
|
||||
|
||||
const knownBuilders = ['builder-webpack5', 'builder-vite'];
|
||||
|
||||
function findMatchingPackage(packageJson: PackageJson, suffixes: string[]) {
|
||||
const { name = '', version, dependencies, devDependencies, peerDependencies } = packageJson;
|
||||
|
||||
const allDependencies = {
|
||||
// We include the framework itself because it may be a renderer too (e.g. angular)
|
||||
[name]: version,
|
||||
...dependencies,
|
||||
...devDependencies,
|
||||
...peerDependencies,
|
||||
};
|
||||
|
||||
return suffixes.map((suffix) => `@storybook/${suffix}`).find((pkg) => allDependencies[pkg]);
|
||||
}
|
||||
|
||||
export async function getFrameworkInfo(mainConfig: StorybookConfig) {
|
||||
const { framework: frameworkInput } = mainConfig;
|
||||
|
||||
if (!frameworkInput) return {};
|
||||
|
||||
const framework = typeof frameworkInput === 'string' ? { name: frameworkInput } : frameworkInput;
|
||||
|
||||
const frameworkPackageJson = await getActualPackageJson(framework.name);
|
||||
|
||||
const builder = findMatchingPackage(frameworkPackageJson, knownBuilders);
|
||||
const renderer = findMatchingPackage(frameworkPackageJson, knownRenderers);
|
||||
|
||||
return {
|
||||
framework,
|
||||
builder,
|
||||
renderer,
|
||||
};
|
||||
}
|
@ -9,8 +9,7 @@ export const getActualPackageVersions = async (packages: Record<string, Partial<
|
||||
|
||||
export const getActualPackageVersion = async (packageName: string) => {
|
||||
try {
|
||||
// eslint-disable-next-line import/no-dynamic-require,global-require
|
||||
const packageJson = require(path.join(packageName, 'package.json'));
|
||||
const packageJson = await getActualPackageJson(packageName);
|
||||
return {
|
||||
name: packageName,
|
||||
version: packageJson.version,
|
||||
@ -19,3 +18,9 @@ export const getActualPackageVersion = async (packageName: string) => {
|
||||
return { name: packageName, version: null };
|
||||
}
|
||||
};
|
||||
|
||||
export const getActualPackageJson = async (packageName: string) => {
|
||||
// eslint-disable-next-line import/no-dynamic-require,global-require
|
||||
const packageJson = require(path.join(packageName, 'package.json'));
|
||||
return packageJson;
|
||||
};
|
@ -12,7 +12,7 @@ const mainJsMock: StorybookConfig = {
|
||||
stories: [],
|
||||
};
|
||||
|
||||
jest.mock('./package-versions', () => {
|
||||
jest.mock('./package-json', () => {
|
||||
const getActualPackageVersion = jest.fn((name) =>
|
||||
Promise.resolve({
|
||||
name,
|
||||
@ -24,9 +24,17 @@ jest.mock('./package-versions', () => {
|
||||
Promise.all(Object.keys(packages).map(getActualPackageVersion))
|
||||
);
|
||||
|
||||
const getActualPackageJson = jest.fn((name) => ({
|
||||
dependencies: {
|
||||
'@storybook/react': 'x.x.x',
|
||||
'@storybook/builder-vite': 'x.x.x',
|
||||
},
|
||||
}));
|
||||
|
||||
return {
|
||||
getActualPackageVersions,
|
||||
getActualPackageVersion,
|
||||
getActualPackageJson,
|
||||
};
|
||||
});
|
||||
|
||||
@ -96,40 +104,39 @@ describe('sanitizeAddonName', () => {
|
||||
describe('await computeStorybookMetadata', () => {
|
||||
test('should return frameworkOptions from mainjs', async () => {
|
||||
const reactResult = await computeStorybookMetadata({
|
||||
packageJson: {
|
||||
...packageJsonMock,
|
||||
devDependencies: {
|
||||
'@storybook/react': 'x.x.x',
|
||||
},
|
||||
},
|
||||
packageJson: packageJsonMock,
|
||||
mainConfig: {
|
||||
...mainJsMock,
|
||||
reactOptions: {
|
||||
fastRefresh: false,
|
||||
framework: {
|
||||
name: '@storybook/react-vite',
|
||||
options: {
|
||||
fastRefresh: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
expect(reactResult.framework).toEqual({ name: 'react', options: { fastRefresh: false } });
|
||||
expect(reactResult.framework).toEqual({
|
||||
name: '@storybook/react-vite',
|
||||
options: { fastRefresh: false },
|
||||
});
|
||||
|
||||
const angularResult = await computeStorybookMetadata({
|
||||
packageJson: {
|
||||
...packageJsonMock,
|
||||
devDependencies: {
|
||||
'@storybook/angular': 'x.x.x',
|
||||
},
|
||||
},
|
||||
packageJson: packageJsonMock,
|
||||
mainConfig: {
|
||||
...mainJsMock,
|
||||
angularOptions: {
|
||||
enableIvy: true,
|
||||
enableNgcc: true,
|
||||
framework: {
|
||||
name: '@storybook/angular',
|
||||
options: {
|
||||
enableIvy: true,
|
||||
enableNgcc: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
expect(angularResult.framework).toEqual({
|
||||
name: 'angular',
|
||||
name: '@storybook/angular',
|
||||
options: { enableIvy: true, enableNgcc: true },
|
||||
});
|
||||
});
|
||||
@ -196,40 +203,20 @@ describe('await computeStorybookMetadata', () => {
|
||||
expect(result.features).toEqual(features);
|
||||
});
|
||||
|
||||
test('should handle different types of builders', async () => {
|
||||
const simpleBuilder = 'webpack4';
|
||||
const complexBuilder = {
|
||||
name: 'webpack5',
|
||||
options: {
|
||||
lazyCompilation: true,
|
||||
},
|
||||
};
|
||||
test('should infer builder and renderer from framework package.json', async () => {
|
||||
expect(
|
||||
(
|
||||
await computeStorybookMetadata({
|
||||
packageJson: packageJsonMock,
|
||||
mainConfig: {
|
||||
...mainJsMock,
|
||||
core: {
|
||||
builder: complexBuilder,
|
||||
},
|
||||
},
|
||||
})
|
||||
).builder
|
||||
).toEqual(complexBuilder);
|
||||
expect(
|
||||
(
|
||||
await computeStorybookMetadata({
|
||||
packageJson: packageJsonMock,
|
||||
mainConfig: {
|
||||
...mainJsMock,
|
||||
core: {
|
||||
builder: simpleBuilder,
|
||||
},
|
||||
},
|
||||
})
|
||||
).builder
|
||||
).toEqual({ name: simpleBuilder });
|
||||
await computeStorybookMetadata({
|
||||
packageJson: packageJsonMock,
|
||||
mainConfig: {
|
||||
...mainJsMock,
|
||||
framework: '@storybook/react-vite',
|
||||
},
|
||||
})
|
||||
).toMatchObject({
|
||||
framework: { name: '@storybook/react-vite' },
|
||||
renderer: '@storybook/react',
|
||||
builder: '@storybook/builder-vite',
|
||||
});
|
||||
});
|
||||
|
||||
test('should return the number of refs', async () => {
|
||||
|
@ -9,9 +9,10 @@ import {
|
||||
import type { StorybookConfig, PackageJson } from '@storybook/types';
|
||||
|
||||
import type { StorybookMetadata, Dependency, StorybookAddon } from './types';
|
||||
import { getActualPackageVersion, getActualPackageVersions } from './package-versions';
|
||||
import { getActualPackageVersion, getActualPackageVersions } from './package-json';
|
||||
import { getMonorepoType } from './get-monorepo-type';
|
||||
import { cleanPaths } from './sanitize';
|
||||
import { getFrameworkInfo } from './get-framework-info';
|
||||
|
||||
export const metaFrameworks = {
|
||||
next: 'Next',
|
||||
@ -23,31 +24,6 @@ export const metaFrameworks = {
|
||||
'@sveltejs/kit': 'svelte-kit',
|
||||
} as Record<string, string>;
|
||||
|
||||
// @TODO: This should be removed in 7.0 as the framework.options field in main.js will replace this
|
||||
const getFrameworkOptions = (mainConfig: any) => {
|
||||
const possibleOptions = [
|
||||
'angular',
|
||||
'ember',
|
||||
'html',
|
||||
'preact',
|
||||
'react',
|
||||
'server',
|
||||
'svelte',
|
||||
'vue',
|
||||
'vue3',
|
||||
'webComponents',
|
||||
].map((opt) => `${opt}Options`);
|
||||
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
for (const opt of possibleOptions) {
|
||||
if (opt in mainConfig) {
|
||||
return mainConfig[opt] as any;
|
||||
}
|
||||
}
|
||||
|
||||
return undefined;
|
||||
};
|
||||
|
||||
export const sanitizeAddonName = (name: string) => {
|
||||
return cleanPaths(name)
|
||||
.replace(/\/dist\/.*/, '')
|
||||
@ -68,7 +44,6 @@ export const computeStorybookMetadata = async ({
|
||||
}): Promise<StorybookMetadata> => {
|
||||
const metadata: Partial<StorybookMetadata> = {
|
||||
generatedAt: new Date().getTime(),
|
||||
builder: { name: 'webpack5' },
|
||||
hasCustomBabel: false,
|
||||
hasCustomWebpack: false,
|
||||
hasStaticDirs: false,
|
||||
@ -118,14 +93,7 @@ export const computeStorybookMetadata = async ({
|
||||
metadata.typescriptOptions = mainConfig.typescript;
|
||||
}
|
||||
|
||||
if (mainConfig.core?.builder) {
|
||||
const { builder } = mainConfig.core;
|
||||
|
||||
metadata.builder = {
|
||||
name: typeof builder === 'string' ? builder : builder.name,
|
||||
options: typeof builder === 'string' ? undefined : builder?.options ?? undefined,
|
||||
};
|
||||
}
|
||||
const frameworkInfo = await getFrameworkInfo(mainConfig);
|
||||
|
||||
if (mainConfig.refs) {
|
||||
metadata.refCount = Object.keys(mainConfig.refs).length;
|
||||
@ -181,22 +149,16 @@ export const computeStorybookMetadata = async ({
|
||||
|
||||
const hasStorybookEslint = !!allDependencies['eslint-plugin-storybook'];
|
||||
|
||||
// FIXME: resolve framework/renderer split in 7.0
|
||||
// OR should be getting this from mainConfig instead?
|
||||
const storybookInfo = getStorybookInfo(packageJson);
|
||||
|
||||
const storybookVersion =
|
||||
storybookPackages[storybookInfo.frameworkPackage]?.version || storybookInfo.version;
|
||||
|
||||
return {
|
||||
...metadata,
|
||||
...frameworkInfo,
|
||||
storybookVersion,
|
||||
language,
|
||||
storybookPackages,
|
||||
framework: {
|
||||
name: storybookInfo.framework,
|
||||
options: getFrameworkOptions(mainConfig),
|
||||
},
|
||||
addons,
|
||||
hasStorybookEslint,
|
||||
};
|
||||
|
@ -17,14 +17,12 @@ export type StorybookMetadata = {
|
||||
storybookVersion: string;
|
||||
generatedAt?: number;
|
||||
language: 'typescript' | 'javascript';
|
||||
framework: {
|
||||
framework?: {
|
||||
name: string;
|
||||
options?: any;
|
||||
};
|
||||
builder?: {
|
||||
name: string;
|
||||
options?: Record<string, any>;
|
||||
};
|
||||
builder?: string;
|
||||
renderer?: string;
|
||||
monorepo?: MonorepoType;
|
||||
packageManager?: {
|
||||
type: PM;
|
||||
|
@ -296,9 +296,10 @@ export type DocsOptions = {
|
||||
*/
|
||||
defaultName?: string;
|
||||
/**
|
||||
* Should we generate a docs entry per CSF file?
|
||||
* Should we generate a docs entry per CSF file with the `docsPage` tag?
|
||||
* Set to 'automatic' to generate an entry irrespective of tag.
|
||||
*/
|
||||
docsPage?: boolean;
|
||||
docsPage?: boolean | 'automatic';
|
||||
/**
|
||||
* Only show doc entries in the side bar (usually set with the `--docs` CLI flag)
|
||||
*/
|
||||
|
@ -1,3 +1,5 @@
|
||||
import { parameters as docsParams } from './docs/config';
|
||||
|
||||
export { renderToDOM, render } from './render';
|
||||
|
||||
export const parameters = { framework: 'preact' as const };
|
||||
export const parameters = { framework: 'preact' as const, ...docsParams };
|
||||
|
5
code/renderers/preact/src/docs/config.ts
Normal file
5
code/renderers/preact/src/docs/config.ts
Normal file
@ -0,0 +1,5 @@
|
||||
export const parameters = {
|
||||
docs: {
|
||||
inlineStories: true,
|
||||
},
|
||||
};
|
@ -36,6 +36,7 @@ const config: StorybookConfig = {
|
||||
viteFinal: (vite) => ({
|
||||
...vite,
|
||||
plugins: [...(vite.plugins || []), csfPlugin({})],
|
||||
optimizeDeps: { ...vite.optimizeDeps, force: true },
|
||||
}),
|
||||
};
|
||||
|
||||
|
@ -11,6 +11,12 @@ import {
|
||||
useTheme,
|
||||
} from '@storybook/theming';
|
||||
import { Symbols } from '@storybook/components';
|
||||
import type { PreviewWeb } from '@storybook/preview-web';
|
||||
import { DocsContext } from '@storybook/preview-web';
|
||||
import type { ReactFramework } from '@storybook/react';
|
||||
import type { Channel } from '@storybook/channels';
|
||||
|
||||
import { DocsContainer } from '../blocks/src/blocks/DocsContainer';
|
||||
|
||||
const { document } = global;
|
||||
|
||||
@ -86,7 +92,49 @@ const ThemedSetRoot = () => {
|
||||
return null;
|
||||
};
|
||||
|
||||
// eslint-disable-next-line no-underscore-dangle
|
||||
const preview = (window as any).__STORYBOOK_PREVIEW__ as PreviewWeb<ReactFramework>;
|
||||
const channel = (window as any).__STORYBOOK_ADDONS_CHANNEL__ as Channel;
|
||||
export const loaders = [
|
||||
async () => ({ globalValue: 1 }),
|
||||
|
||||
async ({ parameters: { relativeCsfPaths } }) => {
|
||||
if (!relativeCsfPaths) return {};
|
||||
|
||||
const csfFiles = await Promise.all(
|
||||
(relativeCsfPaths as string[]).map(async (relativePath) => {
|
||||
const webpackPath = `./ui/blocks/src/${relativePath.replace(/^..\//, '')}.tsx`;
|
||||
const entry = preview.storyStore.storyIndex!.importPathToEntry(webpackPath);
|
||||
|
||||
if (!entry) {
|
||||
throw new Error(`Couldn't find story file at ${webpackPath} (passed as ${relativePath})`);
|
||||
}
|
||||
|
||||
return preview.storyStore.loadCSFFileByStoryId(entry.id);
|
||||
})
|
||||
);
|
||||
|
||||
return {
|
||||
docsContext: new DocsContext(
|
||||
channel,
|
||||
preview.storyStore,
|
||||
preview.renderStoryToElement.bind(preview),
|
||||
csfFiles,
|
||||
false
|
||||
),
|
||||
};
|
||||
},
|
||||
];
|
||||
|
||||
export const decorators = [
|
||||
(Story, { loaded: { docsContext } }) =>
|
||||
docsContext ? (
|
||||
<DocsContainer context={docsContext}>
|
||||
<Story />
|
||||
</DocsContainer>
|
||||
) : (
|
||||
<Story />
|
||||
),
|
||||
(StoryFn, { globals, parameters, playFunction }) => {
|
||||
const defaultTheme = isChromatic() && !playFunction ? 'stacked' : 'light';
|
||||
const theme = globals.theme || parameters.theme || defaultTheme;
|
||||
@ -242,7 +290,5 @@ export const globalTypes = {
|
||||
},
|
||||
};
|
||||
|
||||
export const loaders = [async () => ({ globalValue: 1 })];
|
||||
|
||||
export const argTypes = { color: { control: 'color' } };
|
||||
export const args = { color: 'red' };
|
20
code/ui/blocks/src/blocks/Story.stories.tsx
Normal file
20
code/ui/blocks/src/blocks/Story.stories.tsx
Normal file
@ -0,0 +1,20 @@
|
||||
import type { Meta, StoryObj } from '@storybook/react';
|
||||
|
||||
import { Story as StoryComponent } from './Story';
|
||||
import * as BooleanStories from '../controls/Boolean.stories';
|
||||
|
||||
const meta: Meta<typeof StoryComponent> = {
|
||||
component: StoryComponent,
|
||||
parameters: {
|
||||
relativeCsfPaths: ['../controls/Boolean.stories'],
|
||||
},
|
||||
};
|
||||
export default meta;
|
||||
|
||||
type Story = StoryObj<typeof meta>;
|
||||
|
||||
export const BasicOf: Story = {
|
||||
args: {
|
||||
of: BooleanStories.Undefined,
|
||||
},
|
||||
};
|
@ -6428,7 +6428,7 @@ __metadata:
|
||||
jest-specific-snapshot: ^4.0.0
|
||||
jscodeshift: ^0.13.1
|
||||
lodash: ^4.17.21
|
||||
prettier: ">=2.2.1 <=2.3.0"
|
||||
prettier: ">=2.2.1 <=3.0.0"
|
||||
recast: ^0.19.0
|
||||
typescript: ~4.6.3
|
||||
util: ^0.12.4
|
||||
@ -7724,7 +7724,7 @@ __metadata:
|
||||
estraverse: ^5.2.0
|
||||
jest-specific-snapshot: ^4.0.0
|
||||
lodash: ^4.17.21
|
||||
prettier: ">=2.2.1 <=2.3.0"
|
||||
prettier: ">=2.2.1 <=3.0.0"
|
||||
typescript: ~4.6.3
|
||||
peerDependencies:
|
||||
react: ^16.8.0 || ^17.0.0 || ^18.0.0
|
||||
@ -28674,7 +28674,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"prettier@npm:2.7.1, prettier@npm:>=2.5, prettier@npm:^1.18.2 || ^2.0.0":
|
||||
"prettier@npm:2.7.1, prettier@npm:>=2.2.1 <=3.0.0, prettier@npm:>=2.5, prettier@npm:^1.18.2 || ^2.0.0":
|
||||
version: 2.7.1
|
||||
resolution: "prettier@npm:2.7.1"
|
||||
bin:
|
||||
@ -28683,15 +28683,6 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"prettier@npm:>=2.2.1 <=2.3.0":
|
||||
version: 2.3.0
|
||||
resolution: "prettier@npm:2.3.0"
|
||||
bin:
|
||||
prettier: bin-prettier.js
|
||||
checksum: b9f434af2f25a37aad0b133894827e980885eb8bf317444c9dde0401ed2c7f463f9996d691f5ee5a0a4450ab46a894cd6557516b561e2522821522ce1f4c6668
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"pretty-bytes@npm:^5.3.0":
|
||||
version: 5.6.0
|
||||
resolution: "pretty-bytes@npm:5.6.0"
|
||||
|
@ -1,8 +0,0 @@
|
||||
{
|
||||
"printWidth": 100,
|
||||
"tabWidth": 2,
|
||||
"bracketSpacing": true,
|
||||
"trailingComma": "es5",
|
||||
"singleQuote": true,
|
||||
"arrowParens": "always"
|
||||
}
|
@ -147,7 +147,7 @@
|
||||
"npmlog": "^5.0.1",
|
||||
"nx": "14.6.1",
|
||||
"p-limit": "^3.1.0",
|
||||
"prettier": ">=2.2.1 <=2.3.0",
|
||||
"prettier": ">=2.2.1 <=3.0.0",
|
||||
"pretty-hrtime": "^1.0.0",
|
||||
"process": "^0.11.10",
|
||||
"prompts": "^2.4.0",
|
||||
|
@ -3,10 +3,4 @@ const base = require('@storybook/linter-config/prettier.config');
|
||||
module.exports = {
|
||||
...base,
|
||||
arrowParens: 'always',
|
||||
overrides: [
|
||||
{
|
||||
files: '*.html',
|
||||
options: { parser: 'babel' },
|
||||
},
|
||||
],
|
||||
};
|
||||
|
@ -3431,7 +3431,7 @@ __metadata:
|
||||
npmlog: ^5.0.1
|
||||
nx: 14.6.1
|
||||
p-limit: ^3.1.0
|
||||
prettier: ">=2.2.1 <=2.3.0"
|
||||
prettier: ">=2.2.1 <=3.0.0"
|
||||
pretty-hrtime: ^1.0.0
|
||||
process: ^0.11.10
|
||||
prompts: ^2.4.0
|
||||
@ -15669,12 +15669,12 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"prettier@npm:>=2.2.1 <=2.3.0":
|
||||
version: 2.3.0
|
||||
resolution: "prettier@npm:2.3.0"
|
||||
"prettier@npm:>=2.2.1 <=3.0.0":
|
||||
version: 2.7.1
|
||||
resolution: "prettier@npm:2.7.1"
|
||||
bin:
|
||||
prettier: bin-prettier.js
|
||||
checksum: b9f434af2f25a37aad0b133894827e980885eb8bf317444c9dde0401ed2c7f463f9996d691f5ee5a0a4450ab46a894cd6557516b561e2522821522ce1f4c6668
|
||||
checksum: 359d2b7ecf36bd52924a48331cae506d335f18637fde6c686212f952b9ce678ce9f554a80571049b36ec2897a8a6c40094b776dea371cc5c04c481cf5b78504b
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user