From ec613f8d32a71caf54312083d48c2287a9ae6a54 Mon Sep 17 00:00:00 2001 From: Cory LaViska Date: Wed, 24 Jan 2024 13:31:42 -0500 Subject: [PATCH] backport 1797 --- cspell.json | 1 + custom-elements-manifest.config.js | 7 +++++ docs/pages/frameworks/vue.md | 41 ++++++++++------------------ package-lock.json | 43 ++++++++++++++++++++++++++++++ package.json | 2 ++ 5 files changed, 67 insertions(+), 27 deletions(-) diff --git a/cspell.json b/cspell.json index 8d1293a94..ccaf8e4f9 100644 --- a/cspell.json +++ b/cspell.json @@ -173,6 +173,7 @@ "valpha", "valuenow", "valuetext", + "Vuejs", "WCAG", "webawesome", "WEBP", diff --git a/custom-elements-manifest.config.js b/custom-elements-manifest.config.js index 303f036ed..5f1d028b0 100644 --- a/custom-elements-manifest.config.js +++ b/custom-elements-manifest.config.js @@ -1,6 +1,7 @@ import * as path from 'path'; import { customElementJetBrainsPlugin } from 'custom-element-jet-brains-integration'; import { customElementVsCodePlugin } from 'custom-element-vs-code-integration'; +import { customElementVuejsPlugin } from 'custom-element-vuejs-integration'; import { parse } from 'comment-parser'; import { pascalCase } from 'pascal-case'; import commandLineArgs from 'command-line-args'; @@ -218,6 +219,12 @@ export default { url: `https://shoelace.style/components/${tag.replace('wa-', '')}` }; } + }), + + customElementVuejsPlugin({ + outdir: './dist/types/vue', + fileName: 'index.d.ts', + componentTypePath: (_, tag) => `../../components/${tag.replace('wa-', '')}/${tag.replace('wa-', '')}.component.js` }) ] }; diff --git a/docs/pages/frameworks/vue.md b/docs/pages/frameworks/vue.md index 3348eb7d3..56daf4908 100644 --- a/docs/pages/frameworks/vue.md +++ b/docs/pages/frameworks/vue.md @@ -35,35 +35,22 @@ If you'd rather not use the CDN for assets, you can create a build task that cop ## Configuration -You'll need to tell Vue to ignore Web Awesome components. This is pretty easy because they all start with `sl-`. - -```js -import { fileURLToPath, URL } from 'url'; - -import { defineConfig } from 'vite'; -import vue from '@vitejs/plugin-vue'; - -// https://vitejs.dev/config/ -export default defineConfig({ - plugins: [ - vue({ - template: { - compilerOptions: { - isCustomElement: tag => tag.startsWith('wa-') - } - } - }) - ], - resolve: { - alias: { - '@': fileURLToPath(new URL('./src', import.meta.url)) - } - } -}); -``` +If you haven't configured your Vue.js project to work with custom elements/web components, follow [the instructions here](https://vuejs.org/guide/extras/web-components.html#using-custom-elements-in-vue) based on your project type to ensure your project will not throw an error when it encounters a custom element. Now you can start using Web Awesome components in your app! +## Types + +Once you have configured your application for custom elements, you should be able to use Shoelace in your application without it causing any errors. Unfortunately, this doesn't register the custom elements to behave like components built using Vue. To provide autocomplete information and type safety for your components, you can import the Shoelace Vue types into your `tsconfig.json` to get better integration in your standard Vue and JSX templates. + +```json +{ + "compilerOptions": { + "types": ["@shoelace-style/shoelace/dist/types/vue"] + } +} +``` + ## Usage ### QR code generator example @@ -126,7 +113,7 @@ Are you using Web Awesome with Vue? [Help us improve this page!](https://github. ### Slots -To use Web Awesome components with slots, follow the Vue documentation on using [slots with custom elements](https://vuejs.org/guide/extras/web-components.html#building-custom-elements-with-vue). +Slots in Web Awesome (and web components in general) are functionally the same as basic slots in Vue. Slots can be assigned to elements using the `slot` attribute followed by the name of the slot it is being assigned to. Here is an example: diff --git a/package-lock.json b/package-lock.json index 41b00ad1e..24beeadba 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7,6 +7,7 @@ "": { "name": "@shoelace-style/shoelace", "version": "2.8.0", + "hasInstallScript": true, "license": "MIT", "dependencies": { "@ctrl/tinycolor": "^4.0.2", @@ -39,6 +40,7 @@ "cspell": "^6.18.1", "custom-element-jet-brains-integration": "^1.4.0", "custom-element-vs-code-integration": "^1.2.1", + "custom-element-vuejs-integration": "^1.0.0", "del": "^7.1.0", "download": "^8.0.0", "esbuild": "^0.19.4", @@ -6760,6 +6762,30 @@ "url": "https://github.com/prettier/prettier?sponsor=1" } }, + "node_modules/custom-element-vuejs-integration": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/custom-element-vuejs-integration/-/custom-element-vuejs-integration-1.0.1.tgz", + "integrity": "sha512-whoB5DqPNIxaltlvTuOXrP543o5dHKV1ae3a3qFHwKKKwDSCU9vtTOIZpZ4NdRmBPDbaCOgQvYxCJmjdDXrC+g==", + "dev": true, + "dependencies": { + "prettier": "^2.7.1" + } + }, + "node_modules/custom-element-vuejs-integration/node_modules/prettier": { + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", + "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", + "dev": true, + "bin": { + "prettier": "bin-prettier.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, "node_modules/custom-elements-manifest": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/custom-elements-manifest/-/custom-elements-manifest-1.0.0.tgz", @@ -23702,6 +23728,23 @@ } } }, + "custom-element-vuejs-integration": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/custom-element-vuejs-integration/-/custom-element-vuejs-integration-1.0.1.tgz", + "integrity": "sha512-whoB5DqPNIxaltlvTuOXrP543o5dHKV1ae3a3qFHwKKKwDSCU9vtTOIZpZ4NdRmBPDbaCOgQvYxCJmjdDXrC+g==", + "dev": true, + "requires": { + "prettier": "^2.7.1" + }, + "dependencies": { + "prettier": { + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", + "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", + "dev": true + } + } + }, "custom-elements-manifest": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/custom-elements-manifest/-/custom-elements-manifest-1.0.0.tgz", diff --git a/package.json b/package.json index db5fdd43d..86c336f90 100644 --- a/package.json +++ b/package.json @@ -45,6 +45,7 @@ "start": "node scripts/build.js --serve", "build": "node scripts/build.js", "verify": "npm run prettier:check && npm run lint && npm run build && npm run test", + "postinstall": "npx playwright install", "prepublishOnly": "npm run verify", "prettier": "prettier --write --log-level warn .", "prettier:check": "prettier --check --log-level warn .", @@ -92,6 +93,7 @@ "cspell": "^6.18.1", "custom-element-jet-brains-integration": "^1.4.0", "custom-element-vs-code-integration": "^1.2.1", + "custom-element-vuejs-integration": "^1.0.0", "del": "^7.1.0", "download": "^8.0.0", "esbuild": "^0.19.4",