basex-lsp/webapp/static/clients/codemirror/list.js
2025-10-06 10:49:43 +01:00

80 lines
No EOL
2.8 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 shad = this.#shadow;
this.#data.forEach((item, index) => {
const listItem = document.createElement('li');
listItem.innerHTML = `<a href="#"><i class='codicon codicon-${this.#iconKinds[item.kind]}'></i>
<span>${item.name} - ${item.detail}</span></a>`;
listItem.addEventListener('click', function (e) {
shad.querySelectorAll('li.selected').forEach(item => { item.className = ''; });
e.currentTarget.className = 'selected';
console.log('Item clicked:', item, listItem);
// 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 = `
@import url("../codicon@0.0.40/codicon.css");
ul { list-style-type: none; padding: 0; margin: 0; }
li { padding: 1px; border-bottom: 1px solid #ccc; cursor: pointer; }
li :not(.selected) :hover { background: #ccc; }
.selected { background: lightgreen;}
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);