Add default argTypesEnhancers to presets

This commit is contained in:
Tom Coleman 2021-08-04 16:50:44 +10:00
parent ae3174ab2f
commit ee341ec5d2
7 changed files with 99 additions and 6 deletions

View File

@ -48,10 +48,12 @@
"@storybook/addons": "6.4.0-alpha.19",
"@storybook/api": "6.4.0-alpha.19",
"@storybook/client-api": "6.4.0-alpha.19",
"@storybook/client-logger": "6.4.0-alpha.19",
"@storybook/components": "6.4.0-alpha.19",
"@storybook/node-logger": "6.4.0-alpha.19",
"@storybook/theming": "6.4.0-alpha.19",
"core-js": "^3.8.2",
"lodash": "^4.17.20",
"ts-dedent": "^2.0.0"
},
"peerDependencies": {

View File

@ -5,4 +5,8 @@ function managerEntries(entry = [], options) {
return [...entry, require.resolve('./dist/esm/register')];
}
module.exports = { managerEntries };
function config(entry = []) {
return [...entry, require.resolve('./dist/esm/inferControls')];
}
module.exports = { managerEntries, config };

View File

@ -0,0 +1,78 @@
import mapValues from 'lodash/mapValues';
import { ArgType } from '@storybook/addons';
import { logger } from '@storybook/client-logger';
import {
SBEnumType,
ArgTypesEnhancer,
filterArgTypes,
combineParameters,
} from '@storybook/client-api';
type ControlsMatchers = {
date: RegExp;
color: RegExp;
};
const inferControl = (argType: ArgType, name: string, matchers: ControlsMatchers): any => {
const { type, options } = argType;
if (!type && !options) {
return undefined;
}
// args that end with background or color e.g. iconColor
if (matchers.color && matchers.color.test(name)) {
const controlType = argType.type.name;
if (controlType === 'string') {
return { control: { type: 'color' } };
}
logger.warn(
`Addon controls: Control of type color only supports string, received "${controlType}" instead`
);
}
// args that end with date e.g. purchaseDate
if (matchers.date && matchers.date.test(name)) {
return { control: { type: 'date' } };
}
switch (type.name) {
case 'array':
return { control: { type: 'object' } };
case 'boolean':
return { control: { type: 'boolean' } };
case 'string':
return { control: { type: 'text' } };
case 'number':
return { control: { type: 'number' } };
case 'enum': {
const { value } = type as SBEnumType;
return { control: { type: value?.length <= 5 ? 'radio' : 'select' }, options: value };
}
case 'function':
case 'symbol':
case 'void':
return null;
default:
return { control: { type: options ? 'select' : 'object' } };
}
};
const inferControls: ArgTypesEnhancer = (context) => {
const {
argTypes,
parameters: { __isArgsStory, controls: { include = null, exclude = null, matchers = {} } = {} },
} = context;
if (!__isArgsStory) return argTypes;
const filteredArgTypes = filterArgTypes(argTypes, include, exclude);
const withControls = mapValues(filteredArgTypes, (argType, name) => {
return argType?.type && inferControl(argType, name, matchers);
});
return combineParameters(withControls, filteredArgTypes);
};
export const argTypesEnhancers = [inferControls];

View File

@ -3,7 +3,11 @@ import { ArgTypesEnhancer, combineParameters } from '@storybook/client-api';
import { normalizeArgTypes } from './normalizeArgTypes';
export const enhanceArgTypes: ArgTypesEnhancer = (context) => {
const { component, argTypes: userArgTypes = {}, docs = {} } = context.parameters;
const {
component,
argTypes: userArgTypes,
parameters: { docs = {} },
} = context;
const { extractArgTypes } = docs;
const normalizedArgTypes = normalizeArgTypes(userArgTypes);

View File

@ -41,10 +41,9 @@ const inferType = (value: any, name: string, visited: Set<any>): SBType => {
};
export const inferArgTypes: ArgTypesEnhancer = (context) => {
const { id, parameters } = context;
const { argTypes: userArgTypes = {}, args = {} } = parameters;
if (!args) return userArgTypes;
const argTypes = mapValues(args, (arg, key) => ({
const { id, argTypes: userArgTypes = {}, initialArgs = {} } = context;
if (!initialArgs) return userArgTypes;
const argTypes = mapValues(initialArgs, (arg, key) => ({
type: inferType(arg, `${id}.${key}`, new Set()),
}));
return combineParameters(argTypes, userArgTypes);

View File

@ -62,3 +62,6 @@ export const features = async (existing: Record<string, boolean>) => ({
...existing,
postcss: true,
});
// TODO -- this feels like it should live in core-client or client-api
export const config = (entry: string[] = []) => [...entry, require.resolve('./inferArgTypes')];

View File

@ -0,0 +1,3 @@
import { inferArgTypes } from '@storybook/client-api/dist/esm/inferArgTypes';
export const argTypesEnhancers = [inferArgTypes];