diff --git a/custom-elements-manifest.config.js b/custom-elements-manifest.config.js index cbb1a81aa..b82161e0f 100644 --- a/custom-elements-manifest.config.js +++ b/custom-elements-manifest.config.js @@ -1,10 +1,18 @@ import fs from 'fs'; +import { generateCustomData } from 'cem-plugin-vs-code-custom-data-generator'; +import commandLineArgs from 'command-line-args'; import { parse } from 'comment-parser'; import { pascalCase } from 'pascal-case'; const packageData = JSON.parse(fs.readFileSync('./package.json', 'utf8')); const { name, description, version, author, homepage, license } = packageData; +const { outdir } = commandLineArgs([ + { name: 'litelement', type: String }, + { name: 'analyze', defaultOption: true }, + { name: 'outdir', type: String } +]); + function noDash(string) { return string.replace(/^\s?-/, '').trim(); } @@ -148,6 +156,11 @@ export default { } }); } - } + }, + // Generate custom VS Code data + generateCustomData({ + outdir, + cssFileName: null + }) ] }; diff --git a/docs/getting-started/usage.md b/docs/getting-started/usage.md index 4d408446b..a16a6b7e2 100644 --- a/docs/getting-started/usage.md +++ b/docs/getting-started/usage.md @@ -153,7 +153,7 @@ A clever way to use this method is to hide the `` with `opacity: 0` and ad ### VS Code -Shoelace ships with a file called `vscode.html-custom-data.json` that can be used to describe its components to Visual Studio Code. This enables code completion for Shoelace components (also known as "code hinting" or "IntelliSense"). To enable it, you need to tell VS Code where the file is. +Shoelace ships with a file called `vscode.html-custom-data.json` that can be used to describe custom elements and CSS custom properties to Visual Studio Code. This enables code completion for Shoelace components (also known as "code hinting" or "IntelliSense"). To enable it, you need to tell VS Code where the file is. 1. [Install Shoelace locally](/getting-started/installation#local-installation) 2. Create a folder called `.vscode` at the root of your project @@ -162,7 +162,8 @@ Shoelace ships with a file called `vscode.html-custom-data.json` that can be use ```js { - "html.customData": ["./node_modules/@shoelace-style/shoelace/dist/vscode.html-custom-data.json"] + "html.customData": ["./node_modules/@shoelace-style/shoelace/dist/vscode.html-custom-data.json"], + "css.customData": ["./node_modules/@shoelace-style/shoelace/dist/vscode.css-custom-data.json"] } ``` diff --git a/package-lock.json b/package-lock.json index a9b5bbe5f..f7a79d3ad 100644 --- a/package-lock.json +++ b/package-lock.json @@ -31,6 +31,7 @@ "@web/test-runner-playwright": "^0.9.0", "bootstrap-icons": "^1.10.2", "browser-sync": "^2.27.10", + "cem-plugin-vs-code-custom-data-generator": "^1.0.1", "chalk": "^5.1.2", "command-line-args": "^5.2.1", "comment-parser": "^1.3.1", @@ -3619,6 +3620,15 @@ "upper-case-first": "^2.0.2" } }, + "node_modules/cem-plugin-vs-code-custom-data-generator": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cem-plugin-vs-code-custom-data-generator/-/cem-plugin-vs-code-custom-data-generator-1.0.1.tgz", + "integrity": "sha512-D01fe+FyZ53n+qVPEokt0GQnZL5YNhxQqPJP1JVQdWYEn7Tr6/jywgldTPB573BAsnuV18fbvuBNEfalAyujdQ==", + "dev": true, + "dependencies": { + "prettier": "^2.7.1" + } + }, "node_modules/chai-a11y-axe": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/chai-a11y-axe/-/chai-a11y-axe-1.4.0.tgz", @@ -17803,6 +17813,15 @@ "upper-case-first": "^2.0.2" } }, + "cem-plugin-vs-code-custom-data-generator": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cem-plugin-vs-code-custom-data-generator/-/cem-plugin-vs-code-custom-data-generator-1.0.1.tgz", + "integrity": "sha512-D01fe+FyZ53n+qVPEokt0GQnZL5YNhxQqPJP1JVQdWYEn7Tr6/jywgldTPB573BAsnuV18fbvuBNEfalAyujdQ==", + "dev": true, + "requires": { + "prettier": "^2.7.1" + } + }, "chai-a11y-axe": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/chai-a11y-axe/-/chai-a11y-axe-1.4.0.tgz", diff --git a/package.json b/package.json index fd99a19b4..83e42bc53 100644 --- a/package.json +++ b/package.json @@ -78,6 +78,7 @@ "@web/test-runner-playwright": "^0.9.0", "bootstrap-icons": "^1.10.2", "browser-sync": "^2.27.10", + "cem-plugin-vs-code-custom-data-generator": "^1.1.0", "chalk": "^5.1.2", "command-line-args": "^5.2.1", "comment-parser": "^1.3.1", diff --git a/scripts/build.js b/scripts/build.js index 4e74c7c2f..199030957 100644 --- a/scripts/build.js +++ b/scripts/build.js @@ -28,7 +28,6 @@ fs.mkdirSync(outdir, { recursive: true }); execSync(`node scripts/make-metadata.js --outdir "${outdir}"`, { stdio: 'inherit' }); execSync(`node scripts/make-search.js --outdir "${outdir}"`, { stdio: 'inherit' }); execSync(`node scripts/make-react.js --outdir "${outdir}"`, { stdio: 'inherit' }); - execSync(`node scripts/make-vscode-data.js --outdir "${outdir}"`, { stdio: 'inherit' }); execSync(`node scripts/make-web-types.js --outdir "${outdir}"`, { stdio: 'inherit' }); execSync(`node scripts/make-themes.js --outdir "${outdir}"`, { stdio: 'inherit' }); execSync(`node scripts/make-icons.js --outdir "${outdir}"`, { stdio: 'inherit' }); diff --git a/scripts/make-vscode-data.js b/scripts/make-vscode-data.js deleted file mode 100644 index 2bfa1d9ed..000000000 --- a/scripts/make-vscode-data.js +++ /dev/null @@ -1,58 +0,0 @@ -// -// This script generates vscode.html-custom-data.json (for IntelliSense). -// -// You must generate dist/custom-elements.json before running this script. -// -import commandLineArgs from 'command-line-args'; -import fs from 'fs'; -import path from 'path'; -import { getAllComponents } from './shared.js'; - -const { outdir } = commandLineArgs({ name: 'outdir', type: String }); -const metadata = JSON.parse(fs.readFileSync(path.join(outdir, 'custom-elements.json'), 'utf8')); - -console.log('Generating custom data for VS Code'); - -const components = getAllComponents(metadata); -const vscode = { tags: [] }; - -components.map(component => { - const name = component.tagName; - const attributes = component.attributes?.map(attr => { - const type = attr.type?.text; - let values = []; - - if (type) { - type.split('|').map(val => { - val = val.trim(); - - // Only accept values that are strings and numbers - const isString = val.startsWith(`'`); - const isNumber = Number(val).toString() === val; - - if (isString) { - // Remove quotes - val = val.replace(/^'/, '').replace(/'$/, ''); - } - - if (isNumber || isString) { - values.push({ name: val }); - } - }); - } - - if (values.length === 0) { - values = undefined; - } - - return { - name: attr.name, - description: attr.description, - values - }; - }); - - vscode.tags.push({ name, attributes }); -}); - -fs.writeFileSync(path.join(outdir, 'vscode.html-custom-data.json'), JSON.stringify(vscode, null, 2), 'utf8');