Skip to content

Instantly share code, notes, and snippets.

@educastellano
Last active April 30, 2025 10:16
Show Gist options
  • Save educastellano/d9756d8e21c18cb409f9198b705b39a2 to your computer and use it in GitHub Desktop.
Save educastellano/d9756d8e21c18cb409f9198b705b39a2 to your computer and use it in GitHub Desktop.
create webcomponents with support for className, htmlFor, etc.
function MyComponent () {
return (
<div className="MyComponent">
<img
is="my-image"
className="MyComponent__image"
src="image.png"
/>
</div>
)
}
function createReactCompatibleClass (BaseElement) {
const attrs = [['className', 'class'], ['htmlFor', 'html']]
return class extends BaseElement {
static get observedAttributes () {
return attrs.flat().map((attr) => attr.toLowerCase())
}
attributeChangedCallback (name, oldValue, newValue) {
super.attributeChangedCallback?.(name, oldValue, newValue)
if (newValue !== oldValue) {
const pair = attrs.find((p) => p[0].toLowerCase() === name.toLowerCase() || p[1].toLowerCase() === name.toLowerCase())
if (pair) {
this[pair[0]] = newValue
}
}
}
connectedCallback () {
super.connectedCallback?.()
for (const pair of attrs) {
const value = this.getAttribute(pair[0].toLowerCase()) || this.getAttribute(pair[1].toLowerCase())
if (value) {
this[pair[0]] = value
}
}
}
}
}
class MyImageElement extends createReactCompatibleClass(HTMLImageElement) {}
window.customElements.define('my-image', MyImageElement, { extends: 'img' })
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment