Skip to content

Commit bb287e0

Browse files
committed
Auto-expand and auto-scroll explorer
1 parent ea2f68a commit bb287e0

File tree

7 files changed

+187
-14
lines changed

7 files changed

+187
-14
lines changed

packages/webdoc-default-template/src/app/components/Explorer/ExplorerItem.js

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1-
import {useExplorerCategoryStyles, useExplorerStyles} from "./useExplorerStyles";
1+
import {useExplorerCategoryStyles, useExplorerPrimaryItemStyles, useExplorerStyles} from "./useExplorerStyles";
22
import ExplorerCategoryItem from "./ExplorerCategoryItem";
33
import Link from "@material-ui/core/Link";
44
import React from "react";
55
import TreeItem from "@material-ui/lab/TreeItem";
6+
import {isSamePage} from "./helpers";
67

78
export default function ExplorerItem(props) {
89
if (!props.data.$nodeId) {
@@ -11,6 +12,7 @@ export default function ExplorerItem(props) {
1112

1213
const classesItem = useExplorerStyles();
1314
const classesCategory = useExplorerCategoryStyles();
15+
const classesPrimaryItem = useExplorerPrimaryItemStyles();
1416
const targetChildren = [];
1517

1618
let i = 0;
@@ -24,6 +26,11 @@ export default function ExplorerItem(props) {
2426

2527
const classes = i > 0 ? classesCategory : classesItem;
2628
const nodeId = props.data.$nodeId;
29+
const primary = props.data.page && isSamePage(props.data);
30+
31+
if (primary) {
32+
console.log(props.data);
33+
}
2734

2835
const toggle = React.useCallback(
2936
() => props.toggle(nodeId),
@@ -36,6 +43,7 @@ export default function ExplorerItem(props) {
3643

3744
return (
3845
<TreeItem
46+
id={props.data.$nodeId}
3947
className="explorer-tree__target"
4048
classes={{
4149
label: classes.label,
@@ -47,7 +55,7 @@ export default function ExplorerItem(props) {
4755
label={
4856
props.data.page ?
4957
(
50-
<Link classes={{root: classes.labelLinks}}
58+
<Link classes={{root: primary ? classesPrimaryItem.labelLinks : classes.labelLinks}}
5159
href={props.data.page}
5260
underline="hover"
5361
>
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
export function isSamePage(data) {
2+
const path = `${window.location.pathname}.html`;
3+
4+
if (data.page.startsWith("/") && data.page === path) {
5+
return true;
6+
} else if (!data.page.startsWith("/") && path.includes(`/${data.page}`)) {
7+
return true;
8+
}
9+
10+
return false;
11+
}

packages/webdoc-default-template/src/app/components/Explorer/index.js

Lines changed: 58 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,19 +8,36 @@ import React from "react";
88
import TreeView from "@material-ui/lab/TreeView";
99
import {connect} from "react-redux";
1010
import cuid from "cuid";
11+
import {isSamePage} from "./helpers";
1112
import store from "../../store";
1213
import {useExplorerStyles} from "./useExplorerStyles";
1314

1415
let fetched = false;
1516

16-
function makeIds(data) {
17+
function makeIds(data, collector) {
1718
data.$nodeId = cuid();
1819

20+
let shouldBeExpanded = false;
21+
22+
if (data.page) {
23+
shouldBeExpanded = isSamePage(data);
24+
}
25+
1926
if (data.children) {
2027
for (const [, value] of Object.entries(data.children)) {
21-
makeIds(value);
28+
const childExpanded = makeIds(value, collector);
29+
30+
if (childExpanded) {
31+
collector.add(data.$nodeId);
32+
shouldBeExpanded = true;
33+
}
2234
}
2335
}
36+
if (shouldBeExpanded) {
37+
collector.add(data.$nodeId);
38+
}
39+
40+
return shouldBeExpanded;
2441
}
2542

2643
export default connect(({
@@ -35,6 +52,14 @@ export default connect(({
3552
value: isOpen,
3653
}),
3754
expandedItems: Array.from(expandedItems),
55+
setAutoScrollTo: (value) => store.dispatch({
56+
type: "setAutoScrollTo",
57+
value,
58+
}),
59+
setExpandedItems: (value) => store.dispatch({
60+
type: "setExpandedItems",
61+
value,
62+
}),
3863
toggleItem: (nodeId, optValue) => store.dispatch({
3964
type: "toggleItem",
4065
nodeId,
@@ -44,9 +69,12 @@ export default connect(({
4469
isOpen,
4570
setOpen,
4671
expandedItems,
72+
setExpandedItems,
4773
toggleItem,
74+
rootRef,
4875
}) {
4976
const [data, setData] = React.useState(null);
77+
const [autoScrollTo, setAutoScrollTo] = React.useState(null);
5078
const {root} = useExplorerStyles();
5179
const toggleOpen = React.useCallback(() => setOpen(!isOpen), [isOpen]);
5280
const children = [];
@@ -57,8 +85,12 @@ export default connect(({
5785
.then((response) => {
5886
if (response.ok) {
5987
response.json().then((idata) => {
60-
makeIds(idata);
88+
const defaultExpanded = new Set();
89+
90+
makeIds(idata, defaultExpanded);
6191
setData(idata || {});
92+
setAutoScrollTo(defaultExpanded.values().next().value);
93+
setExpandedItems(defaultExpanded);
6294
});
6395
} else {
6496
throw new Error("Can't fetch reference.json");
@@ -87,6 +119,29 @@ export default connect(({
87119
children.push(<span key={++i}>Loading...</span>);
88120
}
89121

122+
React.useEffect(
123+
() => {
124+
setTimeout(
125+
() => {
126+
const scrollEl = rootRef.current.querySelector(".MuiTreeView-root");
127+
const toEl = document.getElementById(autoScrollTo);
128+
129+
if (scrollEl && toEl) {
130+
const rect = toEl.getBoundingClientRect();
131+
132+
scrollEl.scrollTo({
133+
left: rect.left,
134+
top: rect.top - 124,
135+
behavior: "smooth",
136+
});
137+
}
138+
},
139+
400,
140+
);
141+
},
142+
[autoScrollTo],
143+
);
144+
90145
return (
91146
<div className="explorer" style={{
92147
transition: "margin-left 200ms, width 200ms",

packages/webdoc-default-template/src/app/components/Explorer/useExplorerStyles.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,3 +34,10 @@ export const useExplorerCategoryStyles = makeStyles({
3434
fontWeight: "bold !important",
3535
},
3636
});
37+
38+
export const useExplorerPrimaryItemStyles = makeStyles({
39+
labelLinks: {
40+
...itemStyle.labelLinks,
41+
color: "#0066CD !important",
42+
},
43+
});

packages/webdoc-default-template/src/app/index.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ window.onload = function() {
2424
ReactDOM.render(
2525
(
2626
<Provider store={store}>
27-
<Explorer />
27+
<Explorer rootRef={{current: explorerRoot}} />
2828
</Provider>
2929
),
3030
explorerRoot,
@@ -44,7 +44,6 @@ function wakeAccordions() {
4444
const btn = accordion.querySelector(".accordion__toggle");
4545

4646
btn.onclick = () => {
47-
console.log("WTF");
4847
accordion.classList.toggle("accordion-active");
4948
};
5049
},

packages/webdoc-default-template/src/app/store.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,11 @@ function globalReducer(state = {}, action) {
2626
query: action.value,
2727
};
2828
}
29+
case "setExpandedItems":
30+
return {
31+
...state,
32+
expandedItems: new Set(action.value),
33+
};
2934
case "toggleItem": {
3035
const expandedItems = new Set(state.expandedItems);
3136

0 commit comments

Comments
 (0)