mirror of
https://github.com/storybookjs/storybook.git
synced 2025-04-15 00:05:35 +08:00
Merge branch '16052-index-server-story-sort' into 16047-add-hmr-to-story-index
This commit is contained in:
commit
a384035d78
@ -55,12 +55,12 @@
|
||||
"js-string-escape": "^1.0.1",
|
||||
"lodash": "^4.17.20",
|
||||
"prettier": "^2.2.1",
|
||||
"regenerator-runtime": "^0.13.7"
|
||||
"regenerator-runtime": "^0.13.7",
|
||||
"ts-dedent": "^2.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/fs-extra": "^9.0.6",
|
||||
"js-yaml": "^3.14.1",
|
||||
"ts-dedent": "^2.0.0"
|
||||
"js-yaml": "^3.14.1"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
|
@ -2,6 +2,7 @@ import dedent from 'ts-dedent';
|
||||
import { getStorySortParameter } from './getStorySortParameter';
|
||||
|
||||
describe('getStorySortParameter', () => {
|
||||
describe('supported', () => {
|
||||
it('no parameters', () => {
|
||||
expect(
|
||||
getStorySortParameter(dedent`
|
||||
@ -10,14 +11,6 @@ describe('getStorySortParameter', () => {
|
||||
).toBeUndefined();
|
||||
});
|
||||
|
||||
it('invalid parameters', () => {
|
||||
expect(
|
||||
getStorySortParameter(dedent`
|
||||
export const parameters = [];
|
||||
`)
|
||||
).toBeUndefined();
|
||||
});
|
||||
|
||||
it('no storySort parameter', () => {
|
||||
expect(
|
||||
getStorySortParameter(dedent`
|
||||
@ -134,10 +127,26 @@ describe('getStorySortParameter', () => {
|
||||
}
|
||||
`);
|
||||
});
|
||||
});
|
||||
|
||||
// unsupported
|
||||
// eslint-disable-next-line jest/no-disabled-tests
|
||||
it.skip('parameters var', () => {
|
||||
describe('unsupported', () => {
|
||||
it('invalid parameters', () => {
|
||||
expect(() =>
|
||||
getStorySortParameter(dedent`
|
||||
export const parameters = [];
|
||||
`)
|
||||
).toThrowErrorMatchingInlineSnapshot(`
|
||||
"Unexpected 'parameters'. Parameter 'options.storySort' should be defined inline e.g.:
|
||||
|
||||
export const parameters = {
|
||||
options: {
|
||||
storySort: <array | object | function>
|
||||
}
|
||||
}"
|
||||
`);
|
||||
});
|
||||
|
||||
it('parameters var', () => {
|
||||
expect(
|
||||
getStorySortParameter(dedent`
|
||||
const parameters = {
|
||||
@ -151,6 +160,57 @@ describe('getStorySortParameter', () => {
|
||||
};
|
||||
export { parameters };
|
||||
`)
|
||||
).toMatchInlineSnapshot(`undefined`);
|
||||
).toBeUndefined();
|
||||
});
|
||||
|
||||
it('options var', () => {
|
||||
expect(() =>
|
||||
getStorySortParameter(dedent`
|
||||
const options = {
|
||||
storySort: {
|
||||
method: "",
|
||||
order: [],
|
||||
locales: "",
|
||||
},
|
||||
};
|
||||
export const parameters = {
|
||||
options,
|
||||
};
|
||||
`)
|
||||
).toThrowErrorMatchingInlineSnapshot(`
|
||||
"Unexpected 'options'. Parameter 'options.storySort' should be defined inline e.g.:
|
||||
|
||||
export const parameters = {
|
||||
options: {
|
||||
storySort: <array | object | function>
|
||||
}
|
||||
}"
|
||||
`);
|
||||
});
|
||||
|
||||
it('storySort var', () => {
|
||||
expect(() =>
|
||||
getStorySortParameter(dedent`
|
||||
const storySort = {
|
||||
method: "",
|
||||
order: [],
|
||||
locales: "",
|
||||
};
|
||||
export const parameters = {
|
||||
options: {
|
||||
storySort,
|
||||
},
|
||||
};
|
||||
`)
|
||||
).toThrowErrorMatchingInlineSnapshot(`
|
||||
"Unexpected 'storySort'. Parameter 'options.storySort' should be defined inline e.g.:
|
||||
|
||||
export const parameters = {
|
||||
options: {
|
||||
storySort: <array | object | function>
|
||||
}
|
||||
}"
|
||||
`);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -1,8 +1,11 @@
|
||||
import * as t from '@babel/types';
|
||||
import traverse from '@babel/traverse';
|
||||
import generate from '@babel/generator';
|
||||
import dedent from 'ts-dedent';
|
||||
import { babelParse } from './babelParse';
|
||||
|
||||
const logger = console;
|
||||
|
||||
const getValue = (obj: t.ObjectExpression, key: string) => {
|
||||
let value: t.Expression;
|
||||
obj.properties.forEach((p: t.ObjectProperty) => {
|
||||
@ -34,6 +37,23 @@ const parseValue = (expr: t.Expression): any => {
|
||||
throw new Error(`Unknown node type ${expr}`);
|
||||
};
|
||||
|
||||
const unsupported = (unexpectedVar: string, isError: boolean) => {
|
||||
const message = dedent`
|
||||
Unexpected '${unexpectedVar}'. Parameter 'options.storySort' should be defined inline e.g.:
|
||||
|
||||
export const parameters = {
|
||||
options: {
|
||||
storySort: <array | object | function>
|
||||
}
|
||||
}
|
||||
`;
|
||||
if (isError) {
|
||||
throw new Error(message);
|
||||
} else {
|
||||
logger.info(message);
|
||||
}
|
||||
};
|
||||
|
||||
export const getStorySortParameter = (previewCode: string) => {
|
||||
let storySort: t.Expression;
|
||||
const ast = babelParse(previewCode);
|
||||
@ -50,11 +70,23 @@ export const getStorySortParameter = (previewCode: string) => {
|
||||
: decl.init;
|
||||
if (t.isObjectExpression(paramsObject)) {
|
||||
const options = getValue(paramsObject, 'options');
|
||||
if (options && t.isObjectExpression(options)) {
|
||||
if (options) {
|
||||
if (t.isObjectExpression(options)) {
|
||||
storySort = getValue(options, 'storySort');
|
||||
} else {
|
||||
unsupported('options', true);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
unsupported('parameters', true);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
} else {
|
||||
node.specifiers.forEach((spec) => {
|
||||
if (t.isIdentifier(spec.exported) && spec.exported.name === 'parameters') {
|
||||
unsupported('parameters', false);
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -82,5 +114,9 @@ export const getStorySortParameter = (previewCode: string) => {
|
||||
return eval(wrapper);
|
||||
}
|
||||
|
||||
if (t.isLiteral(storySort) || t.isArrayExpression(storySort) || t.isObjectExpression(storySort)) {
|
||||
return parseValue(storySort);
|
||||
}
|
||||
|
||||
return unsupported('storySort', true);
|
||||
};
|
||||
|
@ -9,7 +9,7 @@ export const storySort = (options: StorySortObjectParameter = {}): StorySortComp
|
||||
// If the two stories have the same story kind, then use the default
|
||||
// ordering, which is the order they are defined in the story file.
|
||||
// only when includeNames is falsy
|
||||
if (a[1].kind === b[1].kind && !options.includeNames) {
|
||||
if (a[1].title === b[1].title && !options.includeNames) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -17,9 +17,9 @@ export const storySort = (options: StorySortObjectParameter = {}): StorySortComp
|
||||
const method = options.method || 'configure';
|
||||
let order = options.order || [];
|
||||
|
||||
// Examine each part of the story kind in turn.
|
||||
const storyKindA = a[1].kind.trim().split(STORY_KIND_PATH_SEPARATOR);
|
||||
const storyKindB = b[1].kind.trim().split(STORY_KIND_PATH_SEPARATOR);
|
||||
// Examine each part of the story title in turn.
|
||||
const storyKindA = a[1].title.trim().split(STORY_KIND_PATH_SEPARATOR);
|
||||
const storyKindB = b[1].title.trim().split(STORY_KIND_PATH_SEPARATOR);
|
||||
if (options.includeNames) {
|
||||
storyKindA.push(a[1].name);
|
||||
storyKindB.push(b[1].name);
|
||||
@ -35,7 +35,7 @@ export const storySort = (options: StorySortObjectParameter = {}): StorySortComp
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Compare the next part of the story kind.
|
||||
// Compare the next part of the story title.
|
||||
const nameA = storyKindA[depth];
|
||||
const nameB = storyKindB[depth];
|
||||
if (nameA !== nameB) {
|
||||
@ -86,7 +86,7 @@ export const storySort = (options: StorySortObjectParameter = {}): StorySortComp
|
||||
depth += 1;
|
||||
}
|
||||
|
||||
// Identical story kinds. The shortcut at the start of this function prevents
|
||||
// Identical story titles. The shortcut at the start of this function prevents
|
||||
// this from ever being used.
|
||||
/* istanbul ignore next */
|
||||
return 0;
|
||||
|
Loading…
x
Reference in New Issue
Block a user