<to-dos>
by WebComponents
HTML
<to-dos>
<to-do>Buy milk</to-do>
<to-do>Buy eggs</to-do>
</to-dos>
<script>
const createElement = (tag, props = {}) => Object.assign(document.createElement(tag), props)
customElements.define("to-dos", class extends HTMLElement {
constructor() {
super().attachShadow({ mode: "open" }).append(
createElement("style", {
textContent: `:host{font:20px arial}` +
`*:not(input){;padding:1em 0}` +
`::slotted(to-do) {display:block}` +
`::slotted(to-do)::before {content: "• "}`,
}),
createElement("b", { textContent: "Todo App" }),
createElement("br"),
(this.input = createElement("input", {
placeholder: "Add new todo",
onkeypress: (evt) => this[evt.key] && this[evt.key](), // execute this["Enter"]()
})),
(this.count = createElement("div")),
createElement("slot"), // display all <to-do> from lightDOM
) // append
let todosElement = this; // so everything in scope can directly call this Element
customElements.define("to-do", class extends HTMLElement {
connectedCallback() {
this.todoText = this.innerHTML;
todosElement.count.textContent = `Number of Todo items: ${todosElement.length}`;
this.append(" ", createElement("button", {
textContent: "remove",
onclick: _ => this.remove(),
}),
) // append
} // connectedCallback
}) // defined to-do
} // <to-dos> constructor
Enter() {
this.addTodo(this.input.value)
this.input.value = ""
console.log(this.length, this.todos);
}
addTodo(innerHTML) {
this.append(createElement("to-do", { innerHTML }))
}
get todos() {
return...