Create web component util

This commit is contained in:
Antoine Bartuccio 2024-10-16 13:33:02 +02:00
parent 645b8a543e
commit 677ff51ea5
2 changed files with 34 additions and 15 deletions

View File

@ -1,6 +1,7 @@
// biome-ignore lint/correctness/noUndeclaredDependencies: shipped by easymde // biome-ignore lint/correctness/noUndeclaredDependencies: shipped by easymde
import "codemirror/lib/codemirror.css"; import "codemirror/lib/codemirror.css";
import "easymde/src/css/easymde.css"; import "easymde/src/css/easymde.css";
import { InheritedComponent } from "#core:utils/web-components";
// biome-ignore lint/correctness/noUndeclaredDependencies: Imported by EasyMDE // biome-ignore lint/correctness/noUndeclaredDependencies: Imported by EasyMDE
import type CodeMirror from "codemirror"; import type CodeMirror from "codemirror";
// biome-ignore lint/style/useNamingConvention: This is how they called their namespace // biome-ignore lint/style/useNamingConvention: This is how they called their namespace
@ -182,23 +183,10 @@ const loadEasyMde = (textarea: HTMLTextAreaElement) => {
} }
}; };
class MarkdownInput extends HTMLElement { class MarkdownInput extends InheritedComponent<"textarea"> {
widget: HTMLTextAreaElement;
constructor() { constructor() {
super(); super("textarea");
this.widget = document.createElement("textarea");
const attributes: Attr[] = []; // We need to make a copy to delete while iterating
for (const attr of this.attributes) {
attributes.push(attr);
}
for (const attr of attributes) {
this.removeAttributeNode(attr);
this.widget.setAttributeNode(attr);
}
this.appendChild(this.widget);
window.addEventListener("DOMContentLoaded", () => loadEasyMde(this.widget)); window.addEventListener("DOMContentLoaded", () => loadEasyMde(this.widget));
} }
} }

View File

@ -0,0 +1,31 @@
/**
* Safari doesn't support inheriting from HTML tags on web components
* The technique is to:
* create a new web component
* create the desired type inside
* pass all attributes to the child component
* store is at as a widget inside the parent
*
* To use this, you must use the tag name twice, once for creating the class
* and the second time while calling super to pass it to the constructor
**/
export class InheritedComponent<
K extends keyof HTMLElementTagNameMap,
> extends HTMLElement {
widget: HTMLElementTagNameMap[K];
constructor(tagName: K) {
super();
this.widget = document.createElement(tagName);
const attributes: Attr[] = []; // We need to make a copy to delete while iterating
for (const attr of this.attributes) {
attributes.push(attr);
}
for (const attr of attributes) {
this.removeAttributeNode(attr);
this.widget.setAttributeNode(attr);
}
this.appendChild(this.widget);
}
}