Files
rodydavis b9e42c3ef4
Build and Deploy / build-and-deploy (push) Has been cancelled
fix(lit-components): fix rendering and interaction issues in force-graph, html-table, and draggable-dom
- lit-force-graph: Refactored for instance reuse, better lifecycle management, and added dynamic imports for AR/VR modes.
- lit-html-table: Improved visual design, readability of headers, and fixed reactivity in editable mode.
- lit-draggable-dom: Fixed clipping issues by switching to relative/absolute positioning and resolved a panning speed bug caused by CSS variable inheritance.
2026-05-17 00:41:14 -07:00

138 lines
2.5 KiB
TypeScript

import { css, html, LitElement, TemplateResult } from "lit";
import { customElement, property, state } from "lit/decorators";
/**
* Tree view styles
*/
export const styles = css`
ul.tree {
width: 100%;
height: 100%;
overflow-x: scroll;
white-space: nowrap;
}
ul.tree,
ul.tree ul {
list-style: none;
margin: 0;
padding: 0;
}
ul.tree ul {
margin-left: 10px;
}
ul.tree li {
margin: 0;
padding: 0 7px;
line-height: 20px;
color: #369;
font-weight: bold;
border-left: 1px solid rgb(100, 100, 100);
}
ul.tree li:last-child {
border-left: none;
}
ul.tree li:before {
position: relative;
top: -0.3em;
height: 1em;
width: 12px;
color: white;
border-bottom: 1px solid rgb(100, 100, 100);
content: "";
display: inline-block;
left: -7px;
}
ul.tree li:last-child:before {
border-left: 1px solid rgb(100, 100, 100);
}
`;
/**
* A tree view component.
*/
@customElement("tree-view")
export class TreeView extends LitElement {
@property({ type: Object })
tree: Tree = {
children: [],
};
@state()
selectedNode: BaseTreeNode | null = null;
static get styles() {
return [styles];
}
render() {
return template({
tree: this.tree,
onSelect: (node) => {
this.selectedNode = node;
},
onUpdate: () => {
this.requestUpdate();
},
});
}
}
/**
* Tree view
*/
export declare interface Tree {
children: BaseTreeNode[];
}
/**
* Base tree node
*/
export declare interface BaseTreeNode {
id: string;
name: string;
children: BaseTreeNode[];
collapsed: boolean;
}
interface TemplateProps {
tree: Tree;
onSelect: (node: BaseTreeNode) => void;
onUpdate: () => void;
}
/**
* Build a tree view
*
* @param props Tree view properties
*/
export function template(props: TemplateProps): TemplateResult {
return html`
<ul class="tree">
${props.tree.children.map((node) => buildNode(node, props))}
</ul>
`;
}
function buildNode(node: BaseTreeNode, props: TemplateProps): TemplateResult {
return html`
<li
@click=${() => {
props.onSelect(node);
}}
@dblclick=${() => {
node.collapsed = !node.collapsed;
props.onUpdate();
}}
>
${node.name}
${node.collapsed || node.children.length === 0
? html``
: html`
<ul class="nested">
${node.children.map((n) => buildNode(n, props))}
</ul>
`}
</li>
`;
}