Skip to content

Instantly share code, notes, and snippets.

@gburning
Created April 18, 2021 14:30
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save gburning/7727cb834760460a796fbf103b89986e to your computer and use it in GitHub Desktop.
Save gburning/7727cb834760460a796fbf103b89986e to your computer and use it in GitHub Desktop.
Storybook - manual mapping of Vue props to argTypes
// This is a super basic way of mapping Vue props to argTypes in cases
// where Storybook (or rather vue-docgen-api) fails.
// See https://github.com/storybookjs/storybook/issues/11774
const toType = ({}).toString.call(obj).match(/\s([a-zA-Z]+)/)[1].toLowerCase()
const controlTypeMappings = {
String: 'text',
Boolean: 'boolean',
Array: 'object',
Object: 'object',
Number: 'number'
}
const getPropControlType = ({ type = null }) => {
if (!Array.isArray(type)) {
return controlTypeMappings[type.name]
}
return 'text'
}
const getPropTypeSummary = ({ type = null }) => {
if (!type) {
return null
}
if (Array.isArray(type)) {
const typeNames = type.map(t => t.name.toLowerCase())
return typeNames.join('|')
}
return type.name.toLowerCase()
}
/**
* Get default value for table
* @todo Would kind of like to write out `null` but Storybook doesn't, so...
*/
const getPropDefaultValueSummary = prop => {
if (Object.prototype.hasOwnProperty.call(prop, 'default')) {
switch (toType(prop.default)) {
case 'function':
return JSON.stringify(prop.default())
case 'string':
return `'${prop.default}'`
default:
return prop.default
}
}
return null
}
/**
* Extract information about props as closely as possible to what vue-docgen-api
* and the Storybook backend would do if props were defined normally.
* @note This is a workaround. It will not be perfect. Define props normally were possible.
* @see https://github.com/storybookjs/storybook/blob/master/addons/docs/src/frameworks/vue/extractArgTypes.ts
* @see https://github.com/storybookjs/storybook/blob/master/addons/docs/src/lib/docgen/createPropDef.ts
*/
export const mapPropToArgType = (prop = {}, argType = {}) => {
const newArgType = {
...argType,
control: {
type: getPropControlType(prop),
...argType.control
},
type: {
required: !!prop.required,
summary: getPropTypeSummary(prop),
...argType.type
},
table: {
category: 'props',
...argType.table
}
}
const defaultValueSummary = getPropDefaultValueSummary(prop)
if (defaultValueSummary !== null) {
newArgType.table.defaultValue = {
summary: defaultValueSummary,
...argType?.table?.defaultValue
}
}
return newArgType
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment