svelte_webcomponents
v1.1.0
Published
Boilerplate for developing web components in svelte, using nested components, passing props, sass and jest setup, eslint and style-lint etc
Downloads
6
Readme
About 📚
A ready to use project template to build custom elements (web components) with Svelte 3 with support and examples for web components, jest, sass, nested components with props, eslinting, stylelinting, Github actions and custom events from shadow-DOM to real-DOM etc.
Installation 🚀
Run below command inside the working folder
$ git clone https://github.com/tal1992/svelte-webcomponents.git
** or **
$ npx degit tal1992/svelte-webcomponents
Installation and build 📌
📦 $ npm install
🔨 developer mode -> $ npm run dev
🔨 production mode -> $ npm run build
Using web-components in HTML 📌
<component-name propOne="Lorem" propTwo="Ipsum"></component-name>
Using web-components as a widget 📌
function addScript(src) {
var s = document.createElement("script");
s.setAttribute("src", src);
document.querySelector("body").appendChild(s);
}
//replace the url with your hosted path of bundle.js
addScript("https://loremipsumdolarsir/build/bundle.js", "", "");
Now that your bundle.js file is included in the html , we can use the web components.
let foo = document.createElement('component-foo');
let header = document.getElementByTagName('header');
foo.setAttribute('propOne', "lorem");
foo.setAttribute('propTwo', "Ipsum");
// please replace header with the element where you want to add your custom element.
header.parentNode.replaceChild(foo, header);
Nested Custom Elements 📌
Register your custom-element inside App.svelte
App.svelte
import foo from './foo.svelte';
import bar from './bar.svelte';
No need to import the custom element inside parent declared component, use custom tag names while nesting.
Parent.svelte
<svelte:options tag="component-parent"></svelte:options>
<div class="parent">
<component-foo name="John" background="orange"></component-foo>
<component-bar name="Doe" background="lightgreen"></component-bar>
</div>
Writing SCSS inside svelte 📌
This template comes with in-built support for scss.
foo.svelte
<style lang="scss">
h2 {
padding: 20px;
}
</style>
Test cases 📌
Write test cases inside __tests __ folder
Note : Dont treat webcomponents as a special case for testing, they should be tested as normal svelte components.
import { render } from "@testing-library/svelte";
import App from "../src/App.svelte";
describe("App component", () => {
test("should render component correctly", () => {
const { container } = render(App);
expect(container).toContainHTML("<body><div><h1>Hello from svelte</h1></div></body>");
});
});
Use normal component name and not the webcomponent name in the test case.
$ npm run test
ESLINT 📌
$ npm run lintjs
Style lint 📌
$ npm run lintcss
Event propagation from Shadow DOM to Real DOM 📌
Foo.svelte (web component)
<script>
import { get_current_component } from "svelte/internal";
const thisComponent = get_current_component();
const dispatchEvent = (name, detail) => {
thisComponent.dispatchEvent(new CustomEvent(name, {
detail,
composed: true, // propagate to the Real DOM, handled in index.html
}));
};
function handleClick(event) {
event.preventDefault();
dispatchEvent("customclick", name)
}
</script>
<svelte:options tag="component-foo"></svelte:options>
<button on:click={event => handleClick(event)}>Click me</button>
Inside Real DOM
<script>
window.onload = function () {
let myelem = document.querySelectorAll('component-foo');
myelem.forEach(function (elem) {
elem.addEventListener('customclick', (e) => {
alert(e.detail + ' clicked');
});
});
};
</script>