Skip to content

Instantly share code, notes, and snippets.

@Blquinn
Created February 15, 2023 14:55
Show Gist options
  • Save Blquinn/a4eb878ab2209391c28f508adeaf3b86 to your computer and use it in GitHub Desktop.
Save Blquinn/a4eb878ab2209391c28f508adeaf3b86 to your computer and use it in GitHub Desktop.
Solid-js tree store
import { render } from "solid-js/web";
import { createSignal, For, Show } from "solid-js";
import { createStore } from "solid-js/store";
const [state, setState] = createStore<TreeNode[]>([
{
value: "foo",
children: [
{ value: "bar", children: [] },
{ value: "baz", children: [{ value: "quux", children: [] }] },
],
},
{
value: "foo2",
children: [
{ value: "bar", children: [] },
{ value: "baz", children: [{ value: "quux", children: [] }] },
],
},
]);
interface TreeNode {
value: string;
selected?: boolean;
children: TreeNode[];
}
interface TreeProps {
nodes: TreeNode[];
basePath: string;
index: number[];
}
function* intersperse<T, R>(a: Array<T>, delim: R): Generator<T | R> {
let first = true;
for (const x of a) {
if (!first) yield delim;
first = false;
yield x;
}
}
const path = (basePath: string, value: string) => basePath + "/" + value;
const index = (baseIndex: number[], index: number) => [...baseIndex, index];
const treePath = (index: number[]): Array<number | "children"> =>
[...intersperse(index, "children")] as Array<number | "children">;
function Tree(props: TreeProps) {
const onClick = (node: TreeNode, idx: number) => {
const p = path(props.basePath, node.value);
const i = index(props.index, idx);
const tp = treePath(i);
console.log(p, i, tp);
let ss: any = setState;
ss(...tp, "selected", (s: any) => !!!s);
};
return (
<ul>
<For each={props.nodes}>
{(node, i) => (
<li>
<button onClick={() => onClick(node, i())}>
{path(props.basePath, node.value)}
{node.selected ? " selected" : ""}
</button>
<Tree
nodes={node.children}
basePath={path(props.basePath, node.value)}
index={[...props.index, i()]}
/>
</li>
)}
</For>
</ul>
);
}
render(
() => <Tree nodes={state} basePath="" index={[]} />,
document.getElementById("app")!
);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment