Skip to content

Commit

Permalink
Add Web-Components to Examples (#2195)
Browse files Browse the repository at this point in the history
  • Loading branch information
flashdesignory authored Oct 23, 2023
1 parent 1916c93 commit 95ade96
Show file tree
Hide file tree
Showing 78 changed files with 5,453 additions and 0 deletions.
4 changes: 4 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -231,3 +231,7 @@ jobs:
env:
- CYPRESS_framework=lit
<<: *defaults
- stage: test
env:
- CYPRESS_framework=web-components
<<: *defaults
2 changes: 2 additions & 0 deletions examples/web-components/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
.DS_Store
/node_modules
147 changes: 147 additions & 0 deletions examples/web-components/dist/components/todo-app/todo-app.component.js
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;
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;
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;
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;
Loading

0 comments on commit 95ade96

Please sign in to comment.