If youβre using web-components or if you like the project, please β this repository to show your support! π€©
The world's most easiest, ready to use template for web-components.
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.
Run below command inside the working folder
$ git clone https://github.com/tal1992/svelte-webcomponents.git ** or ** $ npx degit tal1992/svelte-webcomponents π¦ $ npm install π¨ developer mode -> $ npm run dev π¨ production mode -> $ npm run build <component-name propOne="Lorem" propTwo="Ipsum"></component-name>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); 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.
<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> <style lang="scss"> h2 { padding: 20px; } </style>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$ npm run lintjs$ npm run lintcssFoo.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>