mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
Expanding parent nodes when scrolling along child ones
Signed-off-by: Alex Andreev <alex.andreev.email@gmail.com>
This commit is contained in:
parent
d0e25e90b0
commit
09a009049f
@ -306,6 +306,7 @@
|
||||
"concurrently": "^5.2.0",
|
||||
"css-element-queries": "^1.2.3",
|
||||
"css-loader": "^3.5.3",
|
||||
"deepdash-es": "^5.3.5",
|
||||
"dompurify": "^2.0.11",
|
||||
"electron": "^9.4.0",
|
||||
"electron-builder": "^22.7.0",
|
||||
|
||||
@ -29,6 +29,7 @@ export function ScrollSpy(props: Props) {
|
||||
|
||||
sections.forEach(section => {
|
||||
const id = section.getAttribute("id");
|
||||
const parentId = section.parentElement.id;
|
||||
const name = section.querySelector("h1, h2, h3, h4, h5, h6").textContent;
|
||||
const selected = id === activeElementId;
|
||||
|
||||
@ -38,6 +39,7 @@ export function ScrollSpy(props: Props) {
|
||||
|
||||
children.push({
|
||||
id,
|
||||
parentId,
|
||||
name,
|
||||
selected,
|
||||
children: getNavigation(section)
|
||||
@ -56,6 +58,9 @@ export function ScrollSpy(props: Props) {
|
||||
const observeSections = () => {
|
||||
const options: IntersectionObserverInit = {
|
||||
threshold: [0],
|
||||
// Shrinking root area from the bottom
|
||||
// Allows to fire observer event only if target scrolled up to top of the page)
|
||||
// https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API#creating_an_intersection_observer
|
||||
rootMargin: "0px 0px -85%",
|
||||
};
|
||||
|
||||
|
||||
@ -1,14 +1,15 @@
|
||||
import "./tree-view.scss";
|
||||
|
||||
import React from "react";
|
||||
import React, { useEffect, useRef } from "react";
|
||||
import { Icon } from "../icon";
|
||||
import TreeView from "@material-ui/lab/TreeView";
|
||||
import TreeItem from "@material-ui/lab/TreeItem";
|
||||
import { cssNames } from "../../utils";
|
||||
import flattenDeep from "lodash/flattenDeep";
|
||||
import findDeep from "deepdash-es/findDeep";
|
||||
|
||||
export interface NavigationTree {
|
||||
id: string;
|
||||
parentId: string;
|
||||
name: string;
|
||||
selected?: boolean;
|
||||
children?: NavigationTree[];
|
||||
@ -18,14 +19,49 @@ interface Props {
|
||||
data: NavigationTree[]
|
||||
}
|
||||
|
||||
const scrollToItem = (id: string) => {
|
||||
const element = document.getElementById(id);
|
||||
|
||||
element?.scrollIntoView();
|
||||
};
|
||||
|
||||
const getSelectedNode = (data: NavigationTree[]) => {
|
||||
return findDeep(data, (value, key) => key === "selected" && value === true)?.parent;
|
||||
};
|
||||
|
||||
export function RecursiveTreeView({ data }: Props) {
|
||||
const [expanded, setExpanded] = React.useState<string[]>([]);
|
||||
const prevData = useRef<NavigationTree[]>(data);
|
||||
|
||||
const handleToggle = (event: React.ChangeEvent<{}>, nodeIds: string[]) => {
|
||||
setExpanded(nodeIds);
|
||||
};
|
||||
|
||||
const expandTopLevelNodes = () => {
|
||||
setExpanded(data.map(node => node.id));
|
||||
};
|
||||
|
||||
const expandParentNode = () => {
|
||||
const node = getSelectedNode(data) as any as NavigationTree;
|
||||
const id = node?.parentId;
|
||||
|
||||
if (id && !expanded.includes(id)) {
|
||||
setExpanded([...expanded, id]);
|
||||
}
|
||||
};
|
||||
|
||||
const onLabelClick = (event: React.MouseEvent, nodeId: string) => {
|
||||
event.preventDefault();
|
||||
scrollToItem(nodeId);
|
||||
};
|
||||
|
||||
const renderTree = (nodes: NavigationTree[]) => {
|
||||
return nodes.map(node => (
|
||||
<TreeItem
|
||||
key={node.id}
|
||||
nodeId={node.id}
|
||||
label={node.name}
|
||||
onLabelClick={() => scrollToItem(node.id)}
|
||||
onLabelClick={(event) => onLabelClick(event, node.id)}
|
||||
className={cssNames({selected: node.selected})}
|
||||
>
|
||||
{Array.isArray(node.children) ? node.children.map((node) => renderTree([node])) : null}
|
||||
@ -33,17 +69,14 @@ export function RecursiveTreeView({ data }: Props) {
|
||||
));
|
||||
};
|
||||
|
||||
const scrollToItem = (id: string) => {
|
||||
const element = document.getElementById(id);
|
||||
|
||||
element?.scrollIntoView();
|
||||
};
|
||||
|
||||
const getAllNodeIds = (nodes: NavigationTree[]): string[] => {
|
||||
return flattenDeep(nodes.map(node => {
|
||||
return [node.id, ...node.children.map(item => getAllNodeIds([item]))];
|
||||
}));
|
||||
};
|
||||
useEffect(() => {
|
||||
if (!prevData.current.length) {
|
||||
expandTopLevelNodes();
|
||||
} else {
|
||||
expandParentNode();
|
||||
}
|
||||
prevData.current = data;
|
||||
}, [data]);
|
||||
|
||||
if (!data.length) {
|
||||
return null;
|
||||
@ -52,7 +85,8 @@ export function RecursiveTreeView({ data }: Props) {
|
||||
return (
|
||||
<TreeView
|
||||
className="TreeView"
|
||||
defaultExpanded={getAllNodeIds(data)}
|
||||
expanded={expanded}
|
||||
onNodeToggle={handleToggle}
|
||||
defaultCollapseIcon={<Icon material="expand_more"/>}
|
||||
defaultExpandIcon={<Icon material="chevron_right" />}
|
||||
>
|
||||
|
||||
12
yarn.lock
12
yarn.lock
@ -4381,6 +4381,13 @@ deep-is@^0.1.3, deep-is@~0.1.3:
|
||||
resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34"
|
||||
integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=
|
||||
|
||||
deepdash-es@^5.3.5:
|
||||
version "5.3.5"
|
||||
resolved "https://registry.yarnpkg.com/deepdash-es/-/deepdash-es-5.3.5.tgz#1217365f6508bb47f1f90def6b4f1c4b5f4ff6eb"
|
||||
integrity sha512-bezxT+LqAu1Ly8I2LAEFle3fdEAc/bHld9cMAbgYzY+69+P9qTkGtNvC2ZQJEP4C1C2Fx9gVn/TCoQlAivWPDA==
|
||||
dependencies:
|
||||
lodash-es "^4.17.15"
|
||||
|
||||
deepmerge@^4.2.2:
|
||||
version "4.2.2"
|
||||
resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.2.2.tgz#44d2ea3679b8f4d4ffba33f03d865fc1e7bf4955"
|
||||
@ -8637,6 +8644,11 @@ lockfile@^1.0.4:
|
||||
dependencies:
|
||||
signal-exit "^3.0.2"
|
||||
|
||||
lodash-es@^4.17.15:
|
||||
version "4.17.21"
|
||||
resolved "https://registry.yarnpkg.com/lodash-es/-/lodash-es-4.17.21.tgz#43e626c46e6591b7750beb2b50117390c609e3ee"
|
||||
integrity sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==
|
||||
|
||||
lodash._baseuniq@~4.6.0:
|
||||
version "4.6.0"
|
||||
resolved "https://registry.yarnpkg.com/lodash._baseuniq/-/lodash._baseuniq-4.6.0.tgz#0ebb44e456814af7905c6212fa2c9b2d51b841e8"
|
||||
|
||||
Loading…
Reference in New Issue
Block a user