-
Notifications
You must be signed in to change notification settings - Fork 13.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add Web-Components to Examples (#2195)
- Loading branch information
1 parent
1916c93
commit 95ade96
Showing
78 changed files
with
5,453 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
.DS_Store | ||
/node_modules |
147 changes: 147 additions & 0 deletions
147
examples/web-components/dist/components/todo-app/todo-app.component.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,147 @@ | ||
import template from "./todo-app.template.js"; | ||
import { useRouter } from "../../hooks/useRouter.js"; | ||
|
||
import globalStyles from "../../styles/global.constructable.js"; | ||
import appStyles from "../../styles/app.constructable.js"; | ||
import mainStyles from "../../styles/main.constructable.js"; | ||
class TodoApp extends HTMLElement { | ||
#isReady = false; | ||
#data = []; | ||
constructor() { | ||
super(); | ||
|
||
const node = document.importNode(template.content, true); | ||
this.topbar = node.querySelector("todo-topbar"); | ||
this.list = node.querySelector("todo-list"); | ||
this.bottombar = node.querySelector("todo-bottombar"); | ||
|
||
this.shadow = this.attachShadow({ mode: "open" }); | ||
this.htmlDirection = document.dir || "ltr"; | ||
this.setAttribute("dir", this.htmlDirection); | ||
this.shadow.adoptedStyleSheets = [globalStyles, appStyles, mainStyles]; | ||
this.shadow.append(node); | ||
|
||
this.addItem = this.addItem.bind(this); | ||
this.toggleItem = this.toggleItem.bind(this); | ||
this.removeItem = this.removeItem.bind(this); | ||
this.updateItem = this.updateItem.bind(this); | ||
this.toggleItems = this.toggleItems.bind(this); | ||
this.clearCompletedItems = this.clearCompletedItems.bind(this); | ||
this.routeChange = this.routeChange.bind(this); | ||
|
||
this.router = useRouter(); | ||
} | ||
|
||
get isReady() { | ||
return this.#isReady; | ||
} | ||
|
||
getInstance() { | ||
return this; | ||
} | ||
|
||
addItem(event) { | ||
const { detail: item } = event; | ||
|
||
this.#data.push(item); | ||
this.list.addItem(item); | ||
|
||
this.update("add-item", item.id); | ||
} | ||
|
||
toggleItem(event) { | ||
this.#data.forEach((entry) => { | ||
if (entry.id === event.detail.id) | ||
entry.completed = event.detail.completed; | ||
}); | ||
|
||
this.update("toggle-item", event.detail.id); | ||
} | ||
|
||
removeItem(event) { | ||
this.#data.forEach((entry, index) => { | ||
if (entry.id === event.detail.id) | ||
this.#data.splice(index, 1); | ||
}); | ||
|
||
this.update("remove-item", event.detail.id); | ||
} | ||
|
||
updateItem(event) { | ||
this.#data.forEach((entry) => { | ||
if (entry.id === event.detail.id) | ||
entry.title = event.detail.title; | ||
}); | ||
|
||
this.update("update-item", event.detail.id); | ||
} | ||
|
||
toggleItems(event) { | ||
this.list.toggleItems(event.detail.completed); | ||
} | ||
|
||
clearCompletedItems() { | ||
this.list.removeCompletedItems(); | ||
} | ||
|
||
update(type = "", id = "") { | ||
const totalItems = this.#data.length; | ||
const activeItems = this.#data.filter((entry) => !entry.completed).length; | ||
const completedItems = totalItems - activeItems; | ||
|
||
this.list.setAttribute("total-items", totalItems); | ||
this.list.updateElements(type, id); | ||
|
||
this.topbar.setAttribute("total-items", totalItems); | ||
this.topbar.setAttribute("active-items", activeItems); | ||
this.topbar.setAttribute("completed-items", completedItems); | ||
|
||
this.bottombar.setAttribute("total-items", totalItems); | ||
this.bottombar.setAttribute("active-items", activeItems); | ||
} | ||
|
||
addListeners() { | ||
this.topbar.addEventListener("toggle-all", this.toggleItems); | ||
this.topbar.addEventListener("add-item", this.addItem); | ||
|
||
this.list.listNode.addEventListener("toggle-item", this.toggleItem); | ||
this.list.listNode.addEventListener("remove-item", this.removeItem); | ||
this.list.listNode.addEventListener("update-item", this.updateItem); | ||
|
||
this.bottombar.addEventListener("clear-completed-items", this.clearCompletedItems); | ||
} | ||
|
||
removeListeners() { | ||
this.topbar.removeEventListener("toggle-all", this.toggleItems); | ||
this.topbar.removeEventListener("add-item", this.addItem); | ||
|
||
this.list.listNode.removeEventListener("toggle-item", this.toggleItem); | ||
this.list.listNode.removeEventListener("remove-item", this.removeItem); | ||
this.list.listNode.removeEventListener("update-item", this.updateItem); | ||
|
||
this.bottombar.removeEventListener("clear-completed-items", this.clearCompletedItems); | ||
} | ||
|
||
routeChange(route) { | ||
const routeName = route.split("/")[1] || "all"; | ||
this.list.updateRoute(routeName); | ||
this.bottombar.updateRoute(routeName); | ||
this.topbar.updateRoute(routeName); | ||
} | ||
|
||
connectedCallback() { | ||
this.update("connected"); | ||
this.addListeners(); | ||
this.router.initRouter(this.routeChange); | ||
this.#isReady = true; | ||
} | ||
|
||
disconnectedCallback() { | ||
this.removeListeners(); | ||
this.#isReady = false; | ||
} | ||
} | ||
|
||
customElements.define("todo-app", TodoApp); | ||
|
||
export default TodoApp; |
14 changes: 14 additions & 0 deletions
14
examples/web-components/dist/components/todo-app/todo-app.template.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
const template = document.createElement("template"); | ||
|
||
template.id = "todo-app-template"; | ||
template.innerHTML = ` | ||
<section class="app"> | ||
<todo-topbar></todo-topbar> | ||
<main class="main"> | ||
<todo-list></todo-list> | ||
</main> | ||
<todo-bottombar></todo-bottombar> | ||
</section> | ||
`; | ||
|
||
export default template; |
80 changes: 80 additions & 0 deletions
80
examples/web-components/dist/components/todo-bottombar/todo-bottombar.component.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
import template from "./todo-bottombar.template.js"; | ||
|
||
import globalStyles from "../../styles/global.constructable.js"; | ||
import bottombarStyles from "../../styles/bottombar.constructable.js"; | ||
|
||
class TodoBottombar extends HTMLElement { | ||
static get observedAttributes() { | ||
return ["total-items", "active-items"]; | ||
} | ||
|
||
constructor() { | ||
super(); | ||
|
||
const node = document.importNode(template.content, true); | ||
this.element = node.querySelector(".bottombar"); | ||
this.clearCompletedButton = node.querySelector(".clear-completed-button"); | ||
this.todoStatus = node.querySelector(".todo-status"); | ||
this.filterLinks = node.querySelectorAll(".filter-link"); | ||
|
||
this.shadow = this.attachShadow({ mode: "open" }); | ||
this.htmlDirection = document.dir || "ltr"; | ||
this.setAttribute("dir", this.htmlDirection); | ||
this.shadow.adoptedStyleSheets = [globalStyles, bottombarStyles]; | ||
this.shadow.append(node); | ||
|
||
this.clearCompletedItems = this.clearCompletedItems.bind(this); | ||
} | ||
|
||
updateDisplay() { | ||
if (parseInt(this["total-items"]) !== 0) | ||
this.element.style.display = "block"; | ||
else | ||
this.element.style.display = "none"; | ||
|
||
this.todoStatus.textContent = `${this["active-items"]} ${this["active-items"] === "1" ? "item" : "items"} left!`; | ||
} | ||
|
||
updateRoute(route) { | ||
this.filterLinks.forEach((link) => { | ||
if (link.dataset.route === route) | ||
link.classList.add("selected"); | ||
else | ||
link.classList.remove("selected"); | ||
}); | ||
} | ||
|
||
clearCompletedItems() { | ||
this.dispatchEvent(new CustomEvent("clear-completed-items")); | ||
} | ||
|
||
addListeners() { | ||
this.clearCompletedButton.addEventListener("click", this.clearCompletedItems); | ||
} | ||
|
||
removeListeners() { | ||
this.clearCompletedButton.removeEventListener("click", this.clearCompletedItems); | ||
} | ||
|
||
attributeChangedCallback(property, oldValue, newValue) { | ||
if (oldValue === newValue) | ||
return; | ||
this[property] = newValue; | ||
|
||
if (this.isConnected) | ||
this.updateDisplay(); | ||
} | ||
|
||
connectedCallback() { | ||
this.updateDisplay(); | ||
this.addListeners(); | ||
} | ||
|
||
disconnectedCallback() { | ||
this.removeListeners(); | ||
} | ||
} | ||
|
||
customElements.define("todo-bottombar", TodoBottombar); | ||
|
||
export default TodoBottombar; |
22 changes: 22 additions & 0 deletions
22
examples/web-components/dist/components/todo-bottombar/todo-bottombar.template.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
const template = document.createElement("template"); | ||
|
||
template.id = "todo-bottombar-template"; | ||
template.innerHTML = ` | ||
<footer class="bottombar" style="display:none"> | ||
<div class="todo-status"><span class="todo-count">0</span> item left</div> | ||
<ul class="filter-list"> | ||
<li class="filter-item"> | ||
<a id="filter-link-all" class="filter-link selected" href="#/" data-route="all">All</a> | ||
</li> | ||
<li class="filter-item"> | ||
<a id="filter-link-active" class="filter-link" href="#/active" data-route="active">Active</a> | ||
</li> | ||
<li class="filter-item"> | ||
<a id="filter-link-completed" class="filter-link" href="#/completed" data-route="completed">Completed</a> | ||
</li> | ||
</ul> | ||
<button id="clear-completed" class="clear-completed-button">Clear completed</button> | ||
</footer> | ||
`; | ||
|
||
export default template; |
Oops, something went wrong.