diff --git a/packages/vue/.gitignore b/packages/vue/.gitignore new file mode 100644 index 00000000000..de980e10dc2 --- /dev/null +++ b/packages/vue/.gitignore @@ -0,0 +1 @@ +/web-types.json diff --git a/packages/vue/package.json b/packages/vue/package.json index 6247565aec1..9eb44918c32 100644 --- a/packages/vue/package.json +++ b/packages/vue/package.json @@ -5,11 +5,12 @@ "scripts": { "lint": "echo add linter", "test": "jest", - "build": "npm run clean && npm run copy && npm run copy.overlays && npm run compile && npm run bundle", + "build": "npm run clean && npm run copy && npm run copy.overlays && npm run compile && npm run build.web-types && npm run bundle", "bundle": "rollup --config rollup.config.js", "clean": "rimraf dist dist-transpiled", "compile": "npm run tsc", "tsc": "tsc -p .", + "build.web-types": "node ./scripts/build-web-types.js", "copy": "node ./scripts/copy-css.js", "copy.overlays": "node ./scripts/copy-overlays.js" }, @@ -56,5 +57,6 @@ "dependencies": { "@ionic/core": "5.4.1", "ionicons": "^5.1.2" - } + }, + "web-types": "./web-types.json" } diff --git a/packages/vue/scripts/build-web-types.js b/packages/vue/scripts/build-web-types.js new file mode 100644 index 00000000000..7d55c4d67e1 --- /dev/null +++ b/packages/vue/scripts/build-web-types.js @@ -0,0 +1,83 @@ +const fs = require("fs") + +// Web-types build require docs to be built first +const docs = require("../../../docs/core.json") + +const components = [] + +function toCamelCase(name) { + return name.split("-").map(n => n[0].toUpperCase() + n.substr(1)).join("") +} + +for (const component of docs.components) { + if (!component.usage.vue) continue + const attributes = [] + const slots = [] + const events = [] + const componentName = toCamelCase(component.tag) + const docUrl = "https://ionicframework.com/docs/api/" + component.tag.substr(4) + + for (const prop of component.props || []) { + attributes.push({ + name: prop.attr || prop.name, + description: prop.docs, + required: prop.required, + default: prop.default, + value: { + kind: "expression", + type: prop.type + } + }) + } + + for (const event of component.events || []) { + let eventName = event.event; + if (eventName.toLowerCase().startsWith(componentName.toLowerCase())) { + eventName = "on" + eventName.substr(componentName.length); + } + events.push({ + name: eventName, + description: event.docs, + arguments: [{ + name: "detail", + type: event.detail + }] + }) + } + + for (const slot of component.slots || []) { + slots.push({ + name: slot.name === "" ? "default" : slot.name, + description: slot.docs + }) + } + + components.push({ + name: componentName, + "doc-url": docUrl, + description: component.docs, + source: { + module: "@ionic/core/" + component.filePath.replace("./src/", "dist/types/").replace(".tsx", ".d.ts"), + symbol: componentName.substr(3) + }, + attributes, + slots, + events + }) +} + +const webTypes = { + $schema: "http://json.schemastore.org/web-types", + framework: "vue", + name: "@ionic/vue", + version: require("../package.json").version, + contributions: { + html: { + "types-syntax": "typescript", + "description-markup": "markdown", + tags: components + } + } +} + +fs.writeFileSync("web-types.json", JSON.stringify(webTypes, null, 2))