86 lines
No EOL
3.1 KiB
JavaScript
86 lines
No EOL
3.1 KiB
JavaScript
/* Define the web component for settable list
|
|
https://stackoverflow.com/questions/50404970/web-components-pass-data-to-and-from
|
|
https://www.w3schools.com/howto/howto_js_treeview.asp
|
|
*/
|
|
class ListComponent extends HTMLElement {
|
|
#shadow;
|
|
#data;
|
|
#iconKinds; //array from kind integer to codicon name
|
|
constructor() {
|
|
super();
|
|
this.#shadow = this.attachShadow({ mode: "open", delegatesFocus: true });
|
|
this.#data = [];
|
|
this.#iconKinds = [];
|
|
this.render();
|
|
}
|
|
|
|
setData(newData, icons, append = false) {
|
|
if (!Array.isArray(newData)) {
|
|
console.warn("Invalid format, expected an array.");
|
|
return;
|
|
}
|
|
this.#iconKinds = icons;
|
|
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 #data */
|
|
render() {
|
|
const list = document.createElement('ul');
|
|
list.style = "max-height:80cqh;overflow: auto;";
|
|
|
|
const select = e => {
|
|
if(e.type ==="keyup" && !(e.key==="Enter" )) return;
|
|
this.#shadow.querySelectorAll('li.selected').forEach(item => { item.className = ''; });
|
|
e.currentTarget.className = 'selected';
|
|
const i=e.currentTarget.getAttribute("data-index")
|
|
console.log('Item index clicked:', i,this.#data[i]);
|
|
// You can dispatch a custom event here if needed.
|
|
this.dispatchEvent(new CustomEvent('itemSelected', {
|
|
detail: this.#data[i],
|
|
bubbles: true,
|
|
composed: true
|
|
}));
|
|
};
|
|
this.#data.forEach((item, index) => {
|
|
const listItem = document.createElement('li');
|
|
listItem.setAttribute("tabindex", "0")
|
|
listItem.setAttribute("data-index", index)
|
|
listItem.innerHTML = `<i class='codicon codicon-${this.#iconKinds[item.kind]}'></i>
|
|
<span >${item.name} - ${item.detail}</span>`;
|
|
|
|
listItem.addEventListener('click', select);
|
|
listItem.addEventListener('keyup', select);
|
|
list.appendChild(listItem);
|
|
});
|
|
|
|
this.#shadow.innerHTML = '';
|
|
const style = document.createElement('style');
|
|
style.textContent = `
|
|
@import url("../codicon@0.0.40/codicon.css");
|
|
ul { list-style-type: none; padding:0;margin:0;max-height:80cqh;overflow: auto;
|
|
background-color: #f8f9fa;font-size: 80%;}
|
|
li { padding: 0 0 0 2px; border-bottom: 1px solid #ccc; cursor: pointer; width:100%; }
|
|
li:not(.selected) :hover { background-color: #ccc; }
|
|
.selected { background-color: #0d6efd;color: #ffff;}
|
|
i {vertical-align: middle;}
|
|
`;
|
|
this.#shadow.appendChild(style);
|
|
this.#shadow.appendChild(list);
|
|
}
|
|
|
|
/* Render an error message if JSON fetching fails */
|
|
renderError(error) {
|
|
this.#shadow.innerHTML = `<p>Error loading data: ${error.message}</p>`;
|
|
}
|
|
}
|
|
|
|
/* Define the new custom element */
|
|
customElements.define('json-list', ListComponent); |