aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlonkaars <l.leblansch@gmail.com>2021-03-27 09:52:07 +0100
committerlonkaars <l.leblansch@gmail.com>2021-03-27 09:52:07 +0100
commitfee0469e1265122eafcdae6cd92c8c9e1b250826 (patch)
treef5db0373444da61c2d9490fdb139e24bc9e80ea7
parentf129069cbfcd29f3fd9ba0c8f4ca3b0167489e03 (diff)
foldable chapters :tada:
-rw-r--r--components/chapters.tsx34
-rw-r--r--components/navbar.tsx9
-rw-r--r--styles/navbar.css34
3 files changed, 54 insertions, 23 deletions
diff --git a/components/chapters.tsx b/components/chapters.tsx
index e90f91c..27116ee 100644
--- a/components/chapters.tsx
+++ b/components/chapters.tsx
@@ -1,9 +1,8 @@
-import { ReactNode, useState } from 'react';
+import { ReactNode, useState, CSSProperties } from 'react';
import { NavbarItem } from '../components/navbar';
import RemoveRoundedIcon from '@material-ui/icons/RemoveRounded';
-import KeyboardArrowRightRoundedIcon from '@material-ui/icons/KeyboardArrowRightRounded';
import KeyboardArrowDownRoundedIcon from '@material-ui/icons/KeyboardArrowDownRounded';
interface chapter {
@@ -19,17 +18,30 @@ function NavbarChapter(props: {
}) {
var [ collapsed, setCollapsed ] = useState(true);
- var icon = props.chapter.children?.length > 0 ?
- collapsed ? <KeyboardArrowDownRoundedIcon/> : <KeyboardArrowRightRoundedIcon/> :
- <RemoveRoundedIcon/>
+ var icon = <div className={ "collapseIcon" + (collapsed ? "" : " collapsed") }>
+ {
+ props.chapter.children?.length > 0 ?
+ <KeyboardArrowDownRoundedIcon/> :
+ <RemoveRoundedIcon/>
+ }
+ </div>
- var classes: Array<string> = [];
- classes.push("chapter")
- classes.push(`indentLevel${props.level}`)
+ var classes = [
+ "chapter",
+ `indentLevel${props.level}`
+ ]
+ !collapsed && classes.push("childrenCollapsed");
- return <NavbarItem icon={icon} classList={classes} title={props.chapter.name} style={{
- marginLeft: 12 * props.level
- }}>
+ var outercss = /* { "--children-height": 0 + "px" } */ {} as CSSProperties;
+
+ return <NavbarItem
+ icon={icon}
+ classList={classes}
+ title={props.chapter.name}
+ onIconClick={() => props.chapter.children?.length > 0 && setCollapsed(!collapsed)}
+ style={{
+ marginLeft: 12 * props.level,
+ }} outerStyle={outercss}>
{props.children}
</NavbarItem>
}
diff --git a/components/navbar.tsx b/components/navbar.tsx
index cbbd164..9183b3b 100644
--- a/components/navbar.tsx
+++ b/components/navbar.tsx
@@ -11,14 +11,17 @@ export function NavbarItem(props: {
children?: ReactNode;
classList?: Array<string>;
style?: CSSProperties;
+ outerStyle?: CSSProperties;
+ onIconClick?: () => void;
+ onClick?: () => void;
}) {
var classes = props.classList || [];
classes.push("navbarItem");
props.active && classes.push("active");
- return <a href={props.href} className={classes.join(" ")}>
+ return <a href={props.href} className={classes.join(" ")} style={props.outerStyle}>
<div className="inner" style={props.style}>
- {props.icon}
- <span>{props.title}</span>
+ <div className="icon" onClick={props.onIconClick}>{props.icon}</div>
+ <span className="title" onClick={props.onClick}>{props.title}</span>
</div>
{props.children}
</a>
diff --git a/styles/navbar.css b/styles/navbar.css
index 97986e9..bfd48c5 100644
--- a/styles/navbar.css
+++ b/styles/navbar.css
@@ -16,6 +16,22 @@
display: block;
}
+.navbarItem .icon { display: inline-block; }
+
+.navbarItem .icon .collapseIcon {
+ transform: rotate(0deg);
+ transition-property: transform;
+ transition-duration: .3s;
+}
+.navbarItem .icon .collapseIcon.collapsed {
+ transform: rotate(-90deg);
+}
+
+.navbarItem .icon,
+.navbarItem .title {
+ cursor: pointer;
+}
+
.navbarItem.indentLevel0 { margin-bottom: 12px; }
.navbarItem.active .inner,
@@ -27,12 +43,12 @@
.navbarItem.chapter .inner {
background-color: transparent;
color: var(--fg);
- /* box-shadow: inset 0 0 0 1px #ff00ff; */
+
padding: 4px 0;
overflow: visible;
}
-.navbarItem span {
+.navbarItem .title {
vertical-align: top;
margin-left: 8px;
margin-top: 3px;
@@ -42,9 +58,7 @@
white-space: nowrap;
width: calc(100% - 32px);
}
-.navbarItem.chapter span {
- margin-top: 1px;
-}
+.navbarItem.chapter .title { margin-top: 1px; }
.navbarItem.chapter .chapterChildren {
transition-property: height;
@@ -52,11 +66,13 @@
overflow: hidden;
}
-.navbarItem.chapter .chapterChildren.collapsed {
- height: 0;
-}
-.navbarItem .inner {
+.navbarItem.chapter.childrenCollapsed > .chapterChildren { height: 0; }
+.navbarItem.chapter > .chapterChildren { height: var(--children-height); }
+
+.navbarItem .inner,
+.navbarItem .icon,
+.navbarItem .icon .collapseIcon {
height: 24px;
}