diff --git a/src/utils/__tests__/propTypeInfo.js b/src/utils/__tests__/propTypeInfo.js index 99e9ac2a8..87f7f866e 100644 --- a/src/utils/__tests__/propTypeInfo.js +++ b/src/utils/__tests__/propTypeInfo.js @@ -1,6 +1,32 @@ -import { getNormalizedTypeName, getDefaultValue } from '../propTypeInfo'; +import { + getNormalizedTypeName, + getDefaultValue, + getTypeMeta, +} from '../propTypeInfo'; + +const createDocs = (type, { description, returnValue, params } = {}) => { + const docs = { + text: description, + }; + + switch (type) { + case 'func': + docs.tags = {}; + + if (returnValue) { + docs.tags.returns = returnValue; + } + + if (params) { + docs.tags.param = params; + } + break; + } + + return docs; +}; -const createPropType = (name, args, { isRequired = false } = {}) => { +const createPropType = (name, args, { isRequired = false, docs } = {}) => { const propType = [{ name: 'PropTypes' }, { name }]; if (args) { @@ -11,7 +37,7 @@ const createPropType = (name, args, { isRequired = false } = {}) => { propType.push({ name: 'isRequired' }); } - return { __reflect__: propType }; + return { __reflect__: propType, __docs__: createDocs(name, docs) }; }; describe('getNormalizedTypeName', () => { @@ -233,3 +259,48 @@ describe('getDefaultValue', () => { expect(getDefaultValue(component, 'gap')).toEqual('Grid.GAP.SMALL'); }); }); + +describe('getTypeMeta', () => { + [ + 'any', + 'array', + 'element', + 'elementType', + 'number', + 'node', + 'object', + 'string', + 'symbol', + ].forEach((type) => { + test(`returns null for ${type} types`, () => { + const propType = createPropType(type); + const component = { + propTypes: { + [type]: propType, + }, + }; + + expect(getTypeMeta(type, propType, { component })).toBeNull(); + }); + }); + + test('returns function information for func types', () => { + const propType = createPropType('func', undefined, { + docs: { + description: 'A click handler', + params: [{ description: '', name: 'event', type: 'Event' }], + }, + }); + + const component = { + propTypes: { + onClick: propType, + }, + }; + + expect(getTypeMeta('onClick', propType, { component })).toEqual({ + returnValue: { type: 'undefined' }, + params: [{ description: '', name: 'event', type: 'Event' }], + }); + }); +}); diff --git a/src/utils/propTypeInfo.js b/src/utils/propTypeInfo.js index 6441a16ba..e2151164b 100644 --- a/src/utils/propTypeInfo.js +++ b/src/utils/propTypeInfo.js @@ -92,6 +92,20 @@ export const getDefaultValue = (component, propTypeName) => { return defaultValue; }; +export const getTypeMeta = (name, propType, { component }) => { + const propTypeDocs = propType.__docs__; + + switch (getRawTypeName(propType)) { + case 'func': + return { + returnValue: propTypeDocs.tags?.returnValue ?? { type: 'undefined' }, + params: propTypeDocs.tags?.param, + }; + default: + return null; + } +}; + export const getPropTypeDefinition = (component, name, propType) => { const propDocs = propType.__docs__; const propMeta = propType.__reflect__;