/* Define the web component for settable list https://stackoverflow.com/questions/50404970/web-components-pass-data-to-and-from */ class JsonListComponent extends HTMLElement { #shadow; #data; #selected; constructor() { super(); this.#shadow = this.attachShadow({ mode: "open" }); this.#data = []; this.render(); } setData(newData, append = false) { if (!Array.isArray(newData)) { console.warn("Invalid format, expected an array."); return; } this.#data = append ? this.#data.concat(newData) : structuredClone(newData); this.render(); } set data(value) { this.setData(value, false); } get data() { return this.#data; } /* Render the list items using the fetched JSON data */ render() { const list = document.createElement('ul'); this.#data.forEach(item => { const listItem = document.createElement('li'); listItem.textContent = `${item.name} - ${item.description}`; // Adding a click event listener for user interaction listItem.addEventListener('click', () => { console.log('Item clicked:', item); // You can dispatch a custom event here if needed. this.dispatchEvent(new CustomEvent('itemSelected', { detail: item, bubbles: true, composed: true })); }); list.appendChild(listItem); }); this.#shadow.innerHTML = ''; const style = document.createElement('style'); style.textContent = ` ul { list-style-type: none; padding: 0; margin: 0; } li { padding: 10px; border-bottom: 1px solid #ccc; cursor: pointer; } li:hover { background: #f0f0f0; } `; this.#shadow.appendChild(style); this.#shadow.appendChild(list); } /* Render an error message if JSON fetching fails */ renderError(error) { this.#shadow.innerHTML = `
Error loading data: ${error.message}
`; } } /* Define the new custom element */ customElements.define('json-list', JsonListComponent);