mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
Introducting ScrollSpy component
Signed-off-by: Alex Andreev <alex.andreev.email@gmail.com>
This commit is contained in:
parent
f4764c757f
commit
90a1101a0f
@ -38,9 +38,9 @@ export class Preferences extends React.Component {
|
|||||||
contentGaps={false}
|
contentGaps={false}
|
||||||
header={header}
|
header={header}
|
||||||
>
|
>
|
||||||
<section>
|
<section id="application">
|
||||||
<h1>Application</h1>
|
<h1>Application</h1>
|
||||||
<section>
|
<section id="appearance">
|
||||||
<h2>Appearance</h2>
|
<h2>Appearance</h2>
|
||||||
<SubTitle title="Theme"/>
|
<SubTitle title="Theme"/>
|
||||||
<Select
|
<Select
|
||||||
|
|||||||
@ -5,6 +5,7 @@ import { observer } from "mobx-react";
|
|||||||
import { autobind, cssNames, IClassName } from "../../utils";
|
import { autobind, cssNames, IClassName } from "../../utils";
|
||||||
import { Icon } from "../icon";
|
import { Icon } from "../icon";
|
||||||
import { navigation } from "../../navigation";
|
import { navigation } from "../../navigation";
|
||||||
|
import { ScrollSpy } from "../scroll-spy/scroll-spy";
|
||||||
|
|
||||||
export interface PageLayoutProps extends React.DOMAttributes<any> {
|
export interface PageLayoutProps extends React.DOMAttributes<any> {
|
||||||
className?: IClassName;
|
className?: IClassName;
|
||||||
@ -63,33 +64,35 @@ export class PageLayout extends React.Component<PageLayoutProps> {
|
|||||||
const className = cssNames("PageLayout", { showOnTop, showNavigation }, this.props.className);
|
const className = cssNames("PageLayout", { showOnTop, showNavigation }, this.props.className);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div {...elemProps} className={className}>
|
<ScrollSpy render={navigation => (
|
||||||
<div className={cssNames("header flex gaps align-center", headerClass)}>
|
<div {...elemProps} className={className}>
|
||||||
{header}
|
<div className={cssNames("header flex gaps align-center", headerClass)}>
|
||||||
{provideBackButtonNavigation && (
|
{header}
|
||||||
<Icon
|
{provideBackButtonNavigation && (
|
||||||
big material="close"
|
<Icon
|
||||||
className="back box right"
|
big material="close"
|
||||||
onClick={this.back}
|
className="back box right"
|
||||||
/>
|
onClick={this.back}
|
||||||
)}
|
/>
|
||||||
</div>
|
|
||||||
<div className="content-scrollable-area">
|
|
||||||
<div className="content-wrapper">
|
|
||||||
{ showNavigation && (
|
|
||||||
<div className="content-navigation">
|
|
||||||
<ul>
|
|
||||||
<li>Section 1</li>
|
|
||||||
<li>Section 2</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
)}
|
)}
|
||||||
<div className={cssNames("content", contentGaps && "flex column gaps", contentClass)}>
|
</div>
|
||||||
{children}
|
<div className="content-scrollable-area">
|
||||||
|
<div className="content-wrapper">
|
||||||
|
{ showNavigation && (
|
||||||
|
<div className="content-navigation">
|
||||||
|
<ul>
|
||||||
|
<li>Section 1</li>
|
||||||
|
<li>Section 2</li>
|
||||||
|
<li>{navigation.toString()}</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
<div className={cssNames("content", contentGaps && "flex column gaps", contentClass)}>
|
||||||
|
{children}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
)} />);
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
59
src/renderer/components/scroll-spy/scroll-spy.tsx
Normal file
59
src/renderer/components/scroll-spy/scroll-spy.tsx
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
import React, { useEffect } from "react";
|
||||||
|
|
||||||
|
interface Props extends React.DOMAttributes<any> {
|
||||||
|
render: (data: any) => any
|
||||||
|
}
|
||||||
|
|
||||||
|
export function ScrollSpy(props: Props) {
|
||||||
|
let navigationData: any = {};
|
||||||
|
|
||||||
|
const updateNavigation = () => {
|
||||||
|
const firstSection = document.querySelector("section");
|
||||||
|
|
||||||
|
if (!firstSection) {
|
||||||
|
throw new Error("No <section/> tag founded! Content should be placed inside <section></section> elements to activate navigation.");
|
||||||
|
}
|
||||||
|
|
||||||
|
navigationData = {
|
||||||
|
id: "root",
|
||||||
|
name: "Parent",
|
||||||
|
children: getNavigation(firstSection.parentElement)
|
||||||
|
};
|
||||||
|
|
||||||
|
console.log(navigationData);
|
||||||
|
};
|
||||||
|
|
||||||
|
const getNavigation = (element: Element) => {
|
||||||
|
const sections = element.querySelectorAll(":scope > section"); // Searching only direct children of an element. Impossible without :scope
|
||||||
|
const children: any = [];
|
||||||
|
|
||||||
|
sections.forEach(section => {
|
||||||
|
const id = section.getAttribute("id");
|
||||||
|
const name = section.querySelector(":first-child").textContent;
|
||||||
|
|
||||||
|
if (!name || !id) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
children.push({
|
||||||
|
id,
|
||||||
|
name,
|
||||||
|
children: getNavigation(section)
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
return children;
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
updateNavigation();
|
||||||
|
// element.current.addEventListener("scroll", updateActive);
|
||||||
|
// TODO: Attach on dom change event
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="ScrollSpy">
|
||||||
|
{props.render(navigationData)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user