diff --git a/packages/vant-cli/src/compiler/web-types/formatter.ts b/packages/vant-cli/src/compiler/web-types/formatter.ts index c358c1725..5169af8b0 100644 --- a/packages/vant-cli/src/compiler/web-types/formatter.ts +++ b/packages/vant-cli/src/compiler/web-types/formatter.ts @@ -1,7 +1,7 @@ /* eslint-disable no-continue */ import { Articles } from './parser.js'; import { formatType, removeVersion, toKebabCase } from './utils.js'; -import { VueEventArgument, VueTag } from './type.js'; +import { VueAttribute, VueEvent, VueEventArgument, VueTag } from './type.js'; function formatComponentName(name: string, tagPrefix: string) { return tagPrefix + toKebabCase(name); @@ -105,21 +105,52 @@ export function formatter( const tag = findTag(vueTags, name); table.body.forEach((line) => { - const [name, desc, type, defaultVal] = line; + const [_name, desc, _type, defaultVal] = line; + const name = removeVersion(_name); + const type = formatType(_type); if (!tag.attributes) { tag.attributes = []; } - tag.attributes.push({ - name: removeVersion(name), + const attribute: VueAttribute = { + name, default: defaultVal, description: desc, value: { - type: formatType(type), + 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; } @@ -127,20 +158,21 @@ export function formatter( if (tableTitle.includes('Events')) { const name = getNameFromTableTitle(tableTitle, tagPrefix) || defaultName; const tag = findTag(vueTags, name); + const events: VueEvent[] = []; table.body.forEach((line) => { const [name, desc, args] = line; - if (!tag.events) { - tag.events = []; - } - - tag.events.push({ + events.push({ name: removeVersion(name), description: desc, arguments: formatArguments(args), }); }); + + // for higher priority + tag.events = events.concat(tag.events || []); + return; } diff --git a/packages/vant-cli/src/compiler/web-types/index.ts b/packages/vant-cli/src/compiler/web-types/index.ts index 4baff4bd7..25c234a85 100644 --- a/packages/vant-cli/src/compiler/web-types/index.ts +++ b/packages/vant-cli/src/compiler/web-types/index.ts @@ -17,6 +17,7 @@ async function readMarkdown(options: Options) { const mds = await glob(normalizePath(`${options.path}/**/*.md`)); return mds .filter((md) => options.test.test(md)) + .sort((a, b) => a.localeCompare(b)) // keep order .map((path) => fse.readFileSync(path, 'utf-8')); } diff --git a/packages/vant-cli/src/compiler/web-types/parser.ts b/packages/vant-cli/src/compiler/web-types/parser.ts index cfd73705c..3ef8c2c4e 100644 --- a/packages/vant-cli/src/compiler/web-types/parser.ts +++ b/packages/vant-cli/src/compiler/web-types/parser.ts @@ -1,5 +1,5 @@ /* eslint-disable no-cond-assign */ -const TITLE_REG = /^(#+)\s+([^\n]*)/; +const TITLE_REG = /^(#+)\s+([^\r\n]*)/; const TABLE_REG = /^\|.+\r?\n\|\s*-+/; const TD_REG = /\s*`[^`]+`\s*|([^|`]+)/g; const TABLE_SPLIT_LINE_REG = /^\|\s*-/;