DEV Community

Cover image for Write concise Custom Elements for React, Vue, Svelte, Solid, etc. Write once, use everywhere, type checked!
Joe Pea
Joe Pea

Posted on

Write concise Custom Elements for React, Vue, Svelte, Solid, etc. Write once, use everywhere, type checked!

I'm proud to release @lume/element v0.17.0.

This release adds support for Solid.js memos and effects for Custom Elements via decorator syntax.

Concisely write custom HTML elements, type checked in React, Vue, Svelte, Solid.js, React, Stencil, and more.

Here's a glance at what elements authored with @lume/element look like in JavaScript:

import {Element, element, numberAttribute, eventAttribute} from '@lume/element'
import {signal, memo, effect, startEffects, stopEffects} from 'classy-solid'

@element
class FurryDog extends Element {  
  @numberAttribute years = 7
  @eventAttribute onwoof = null

  @memo get dogYears() {
    return this.years * 7
  }

  @effect #log() {
    console.log('dog years:', this.dogYears)
    this.dispatchEvent(new Event('woof')) // bark any time age changes
  }

  template = () => <div>dog years: {this.dogYears}</div>

  css = `:host {color: cornflowerblue}`
}

const dog = document.createElement('furry-dog')
document.body.append(dog) // initially logs "dog years: 49"

dog.years = 8 // logs "dog years: 56"

// ...later, effects cleaned up when removed from DOM...
dog.remove()

// ...later, effects re-started if element reconnected...
document.body.append(dog)
Enter fullscreen mode Exit fullscreen mode

Use the custom element in HTML, or declarative framework templates.

HTML:

<furry-dog years="5" id="dog" onwoof="console.log('woof!')"></furry-dog>
<script>
  dog.years = 6
</script>
Enter fullscreen mode Exit fullscreen mode

React, Preact:

const [age, setAge] = useState(3)
return <furry-dog years={age} onwoof={() => console.log('woof!')}/>
Enter fullscreen mode Exit fullscreen mode

Solid.js JSX:

const [age, setAge] = createSignal(2)
return <furry-dog years={age()} on:woof={() => console.log('woof!')} />
Enter fullscreen mode Exit fullscreen mode

Vue:

<script setup>
  const age = ref(5)
</script>
<template>
  <furry-dog :years="age" @woof="console.log('woof!')" />
</template>
Enter fullscreen mode Exit fullscreen mode

Svelte:

<script>
  let age = $state(4);
</script>
<furry-dog years={age} onwoof={() => console.log('woof!')} />
Enter fullscreen mode Exit fullscreen mode

Type checking is available for all the above frameworks, including in the templates of the elements defined with @lume/element (templates are powered by (@ryansolid's) Solid.js). See the docs on how to connect your element definition to the type systems of each framework, and the various examples.

GitHub logo lume / element

Fast and simple custom elements.

@lume/element

Easily and concisely write Custom Elements with simple templates and reactivity.

Use the custom elements on their own in plain HTML or vanilla JavaScript, or in Vue, Svelte, Solid.js, Stencil.js, React, and Preact, with full type checking autocompletion, and intellisense in all the template systems of those frameworks, in any IDE that supports TypeScript such as VS Code.

Write your elements once, then use them in any app, with a complete developer experience no matter which base component system your app uses.

npm install @lume/element

💡Tip:

If you are new to Custom Elements, first learn about the basics of Custom Element APIs available natively in browsers. Lume Element simplifies the creation of Custom Elements compared to writing them with vanilla APIs, but sometimes vanilla APIs are all that is needed.

Live demos

  • Lume 3D HTML (The landing page, all of Lume's 3D elements, and the live code editors…

Top comments (0)