Skip to content

Commit

Permalink
Collapse and Expand DevTools Tree Nodes (#2679)
Browse files Browse the repository at this point in the history
  • Loading branch information
noi5e authored and thegreatercurve committed Nov 25, 2022
1 parent f7e2415 commit f101757
Show file tree
Hide file tree
Showing 7 changed files with 109 additions and 33 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
.chevron-button {
background: #222;
border: none;
color: #fff;
cursor: pointer;
margin: 0;
padding: 0;
text-decoration: none;
}
26 changes: 26 additions & 0 deletions packages/lexical-devtools/src/panel/components/Chevron/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
import './index.css';

import * as React from 'react';

function Chevron({
handleClick,
isExpanded,
}: {
handleClick: React.MouseEventHandler;
isExpanded: boolean;
}): JSX.Element {
return (
<button className="chevron-button" onClick={handleClick}>
{isExpanded ? <>&#x25BC;</> : <>&#9654;</>}
</button>
);
}

export default Chevron;
18 changes: 18 additions & 0 deletions packages/lexical-devtools/src/panel/components/TreeNode/index.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
.indentation {
background: #222;
border: none;
color: #222;
margin: 0;
padding: 0;
text-decoration: none;
user-select: none;
}

.tree-node {
padding-left: 1em;
width: 100%;
}

.tree-node-wrapper {
width: 100%;
}
51 changes: 35 additions & 16 deletions packages/lexical-devtools/src/panel/components/TreeNode/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,33 +5,52 @@
* LICENSE file in the root directory of this source tree.
*
*/
import './index.css';

import {DevToolsNode} from 'packages/lexical-devtools/types';
import * as React from 'react';
import {useState} from 'react';

import Chevron from '../Chevron';

function TreeNode({
lexicalKey,
__text,
__type,
children,
}: {
children: Array<DevToolsNode>;
lexicalKey: string;
__text?: string;
__type: string;
}): JSX.Element {
depth,
lexicalKey,
}: DevToolsNode): JSX.Element {
const [isExpanded, setIsExpanded] = useState(true);

const handleChevronClick = () => {
setIsExpanded(!isExpanded);
};

const nodeString = ` (${lexicalKey}) ${__type} ${
__text ? '"' + __text + '"' : ''
}`;
const childNodes =
children.length > 0 ? (
<>
{children.map((child) => (
<TreeNode {...child} />
))}
</>
) : (
''
);

return (
<li key={lexicalKey}>
({lexicalKey}) {__type} {__text ? '"' + __text + '"' : ''}
<div className="tree-node" key={lexicalKey}>
{children.length > 0 ? (
<ul>
{children.map((child) => (
<TreeNode {...child} />
))}
</ul>
<Chevron handleClick={handleChevronClick} isExpanded={isExpanded} />
) : (
''
<button className="indentation">&#9654;</button>
)}
</li>
{nodeString}
{<br />}
{isExpanded ? childNodes : ''}
</div>
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,10 @@
color: #fff;
margin: 0;
padding: 1em;
font-size: 1em;
font-size: 1.2em;
overflow: auto;
text-align: left;
-moz-osx-font-smoothing: grayscale;
font-weight: 400;
}

.tree-view-output ul li {
font-family: monospace;
padding-left: 0.5em;
--indentation-size: 1em;
}
27 changes: 17 additions & 10 deletions packages/lexical-devtools/src/panel/components/TreeView/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,29 +19,36 @@ function TreeView({
viewClassName: string;
nodeMap: DevToolsTree;
}): JSX.Element {
const depthFirstSearch = (node: DevToolsNode): DevToolsNode => {
// takes flat JSON structure, nests child comments inside parents
const depthFirstSearch = (
map: DevToolsTree = nodeMap,
nodeKey = 'root',
depth = 0,
): DevToolsNode => {
const node = map[nodeKey];
const children: Array<DevToolsNode> = [];

if (Object.prototype.hasOwnProperty.call(node, '__children')) {
node.__children.forEach((childKey: string) => {
const child = nodeMap[childKey];
children.push(depthFirstSearch(child));
children.push(depthFirstSearch(map, childKey, depth + 1));
});
}

return {...node, __type: node.__type, children, lexicalKey: node.__key};
return {
...node,
__type: node.__type,
children,
depth,
lexicalKey: node.__key,
};
};

const generateTree = (map: DevToolsTree): JSX.Element => {
const root = depthFirstSearch(map.root);
const root = depthFirstSearch(nodeMap, 'root', 0);
return <TreeNode {...root} />;
};

return (
<div className={viewClassName}>
<ul>{generateTree(nodeMap)}</ul>
</div>
);
return <div className={viewClassName}>{generateTree(nodeMap)}</div>;
}

export default TreeView;
3 changes: 2 additions & 1 deletion packages/lexical-devtools/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,9 @@ export interface DevToolsTree {
export interface DevToolsNode {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
[x: string]: any;
children: Array<DevToolsNode>;
__text?: string;
__type: string;
children: Array<DevToolsNode>;
depth: number;
lexicalKey: string;
}

0 comments on commit f101757

Please sign in to comment.