UNPKG

@vant/cli

Version:

Vant CLI is a tool for building vue component library. You can quickly build a full-featured Vue component library with vant-cli.

162 lines (161 loc) 5.94 kB
import { formatType, removeVersion, toKebabCase } from './utils.js'; function formatComponentName(name, tagPrefix) { return tagPrefix + toKebabCase(name); } /** * format arguments of events * input = value: { foo: foo or 1, bar: bar or 2 }, value2: { one: 1 and 1, two: 2 and 2 }, foo: bar * output = [{ name: 'value', type: '{ foo: foo or 1, bar: bar or 2 }' }, { name: 'value2', type: '{ one: 1 and 1, two: 2 and 2 }'}, { name: 'foo', type: 'bar' }] */ function formatArguments(input) { if (input === '-') return []; const args = []; const items = []; input = formatType(input); while (input.length > 0) { if (/(?!_)\w/.test(input[0])) { const val = input.match(/(\w|\s|\||\[|\]|>|<)+/)[0] || ''; input = input.substring(val.length); items.push(val); } else if (input[0] === '{') { const val = input.match(/\{[^}]+\}/)[0] || ''; input = input.substring(val.length); items.push(val); } else if ([':', ',', '_', ' '].includes(input[0])) { input = input.substring(1); } else { const matched = input.match(/( |'|\||\w)+/); if ((matched === null || matched === void 0 ? void 0 : matched.length) && matched[0]) { const val = matched[0]; input = input.substring(val.length); items.push(val); } else { input = ''; } } } for (let i = 0; i < items.length; i += 2) { args.push({ name: items[i], type: items[i + 1], }); } return args; } function getNameFromTableTitle(tableTitle, tagPrefix) { tableTitle = tableTitle.trim(); if (tableTitle.includes(' ')) { return formatComponentName(tableTitle, tagPrefix).split(' ')[0]; } } function findTag(vueTags, name) { const matched = vueTags.find((item) => item.name === name); if (matched) { return matched; } const newTag = { name, }; vueTags.push(newTag); return newTag; } export function formatter(vueTags, articles, tagPrefix = '') { if (!articles.length) { return; } const mainTitle = articles[0].content; const defaultName = mainTitle ? formatComponentName(mainTitle.split(' ')[0], tagPrefix) : ''; const tables = articles.filter((article) => article.type === 'table'); tables.forEach((item) => { const { table } = item; const prevIndex = articles.indexOf(item) - 1; const prevArticle = articles[prevIndex]; if (!prevArticle || !prevArticle.content || !table || !table.body) { return; } const tableTitle = prevArticle.content; if (tableTitle.includes('Props')) { const name = getNameFromTableTitle(tableTitle, tagPrefix) || defaultName; const tag = findTag(vueTags, name); table.body.forEach((line) => { const [_name, desc, _type, defaultVal] = line; const name = removeVersion(_name); const type = formatType(_type); if (!tag.attributes) { tag.attributes = []; } const attribute = { name, default: defaultVal, description: desc, value: { type, kind: 'expression', }, }; if (name === 'v-model') { const modelValue = 'modelValue'; // add `modelValue` tag.attributes.push({ ...attribute, name: modelValue }); if (type === 'boolean') { // fix: warning `is not a valid value for v-model` in JetBrains IDE // ref: https://github.com/JetBrains/web-types/issues/79#issuecomment-2045153333 attribute.value = { ...attribute.value, type: type + ' ' }; } if (!tag.events) { tag.events = []; } tag.events.push({ name: `update:${modelValue}`, description: `${desc}\n\nEmitted when the value of \`${modelValue}\` prop changes.`, arguments: [ { name: modelValue, type, }, ], }); } tag.attributes.push(attribute); }); return; } if (tableTitle.includes('Events')) { const name = getNameFromTableTitle(tableTitle, tagPrefix) || defaultName; const tag = findTag(vueTags, name); const events = []; table.body.forEach((line) => { const [name, desc, args] = line; events.push({ name: removeVersion(name), description: desc, arguments: formatArguments(args), }); }); // for higher priority tag.events = events.concat(tag.events || []); return; } if (tableTitle.includes('Slots')) { const name = getNameFromTableTitle(tableTitle, tagPrefix) || defaultName; const tag = findTag(vueTags, name); table.body.forEach((line) => { const [name, desc] = line; if (!tag.slots) { tag.slots = []; } tag.slots.push({ name: removeVersion(name), description: desc, }); }); } }); }