class FileTree extends HTMLElement {
constructor() {
super();
this.fileStructure = {};
this.selectedFiles = [];
}
connectedCallback() {
this.render();
}
static get observedAttributes() {
return ['file-structure'];
}
attributeChangedCallback(name, oldValue, newValue) {
if (name === 'file-structure') {
this.fileStructure = JSON.parse(newValue);
this.render();
}
}
set fileStructure(value) {
this._fileStructure = value;
this.render();
}
get fileStructure() {
return this._fileStructure;
}
render() {
this.innerHTML = '';
const container = document.createElement('div');
container.className = 'file-tree';
this.appendChild(container);
if (this.fileStructure) {
this.renderDirectory(this.fileStructure, container, '');
}
}
renderDirectory(structure, container, path) {
Object.keys(structure).sort().forEach(key => {
const item = structure[key];
const fullPath = path ? `${path}/${item.name}` : item.name;
const itemElement = document.createElement('div');
itemElement.className = 'file-tree-item';
itemElement.dataset.path = fullPath;
if (item.type === 'directory') {
itemElement.classList.add('folder');
itemElement.innerHTML = `
${item.name}
`;
container.appendChild(itemElement);
const childrenContainer = document.createElement('div');
childrenContainer.className = 'file-tree-children';
container.appendChild(childrenContainer);
this.renderDirectory(item.children, childrenContainer, fullPath);
} else {
itemElement.classList.add('file');
itemElement.innerHTML = `
${item.name}
`;
container.appendChild(itemElement);
// Add to selected files list
this.selectedFiles.push({
path: fullPath,
selected: item.selected
});
}
// Add event listener for checkbox
const checkbox = itemElement.querySelector('input[type="checkbox"]');
checkbox.addEventListener('change', (e) => {
this.updateSelection(fullPath, e.target.checked, item.type === 'directory');
this.dispatchSelectionEvent();
});
});
feather.replace();
}
updateSelection(path, selected, isDirectory) {
// Update the selected files list
this.selectedFiles = this.selectedFiles.map(file => {
if (file.path.startsWith(path)) {
return { ...file, selected };
}
return file;
});
}
dispatchSelectionEvent() {
const event = new CustomEvent('selection-change', {
detail: this.selectedFiles
});
this.dispatchEvent(event);
}
}
customElements.define('file-tree', FileTree);