Skip to content

Commit

Permalink
feat(components): Tree renders as nodes and edges
Browse files Browse the repository at this point in the history
This uses fancy html+css border tricks to draw the edges.

Note that tailwind supports 'first(-child)' and 'last(-child)'
modifiers, but not 'only(-child)'. Thus we use CSS to style the borders
in most cases, but use TypeScript to emit different DOM nodes if a tree
has only one child.
  • Loading branch information
brprice committed Oct 28, 2021
1 parent 80ef4aa commit 8f0f7ad
Showing 1 changed file with 32 additions and 15 deletions.
47 changes: 32 additions & 15 deletions packages/primer-components/src/Tree/Tree.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,22 +9,39 @@ export interface TreeI {
childTrees: TreeI[];
}

export const Tree = (tree: TreeI): JSX.Element => (
<ul className="ml-2 list-disc list-outside">
<li>{tree.label}</li>
<ChildTrees trees={tree.childTrees} />
const ulTop = "flex relative pt-3";
const ulul = ulTop + " before:border-l-2 before:border-solid before:h-3 \
before:left-1/2 before:absolute before:top-0 before:w-0";
const ulliTop = "float-left relative text-center pt-3";
const ulliOnly = "float-left relative text-center";
const ulli = "float-left relative text-center pt-3\
before:border-t-2 before:border-solid before:h-3 before:absolute \
before:right-1/2 before:w-1/2 before:top-0 \
after:border-t-2 after:border-l-2 after:border-solid after:h-3 after:absolute \
after:left-1/2 after:w-1/2 after:top-0 \
first:before:border-none last:after:border-t-0 \
";
const nod = "bg-blue-200 bg-opacity-50 mx-3 w-auto border-solid border-1";

export const Tree = (tree : TreeI): JSX.Element => (
<ul className={ulTop}>
<li className={ulliTop}>
<TreeHelper {...tree}/>
</li>
</ul>
);

function ChildTrees({ trees }: { trees: TreeI[] }): JSX.Element {
if (trees.length > 0) {
return (
<ul className="ml-2 list-disc list-outside">
{trees.map((t) => (
<Tree {...t} key={t.nodeId} />
))}
</ul>
);
function TreeHelper({label,childTrees}) {
let n = <span className={nod}>{label}</span>;
let s = <></>;
if(childTrees.length > 0) {
s = (<ul className={ulul}>
{childTrees.map((t)=>(
<li className={childTrees.length == 1?ulliOnly:ulli}>
<TreeHelper {...t}/>
</li>)
)}
</ul>);
}
return <></>;

return <>{n}{s}</>;
}

0 comments on commit 8f0f7ad

Please sign in to comment.