mirror of
https://github.com/storybookjs/storybook.git
synced 2025-04-03 05:04:51 +08:00
74 lines
2.1 KiB
TypeScript
74 lines
2.1 KiB
TypeScript
import mapValues from 'lodash/mapValues';
|
|
import { ArgType } from '@storybook/addons';
|
|
import { logger } from '@storybook/client-logger';
|
|
|
|
import { SBEnumType, ArgTypesEnhancer } from './types';
|
|
import { combineParameters } from './parameters';
|
|
import { filterArgTypes } from './filterArgTypes';
|
|
|
|
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 = typeof argType.type.value;
|
|
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' } };
|
|
}
|
|
};
|
|
|
|
export const inferControls: ArgTypesEnhancer = (context) => {
|
|
const {
|
|
__isArgsStory,
|
|
argTypes,
|
|
controls: { include = null, exclude = null, matchers = {} } = {},
|
|
} = context.parameters;
|
|
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);
|
|
};
|