mirror of
https://github.com/zadam/trilium.git
synced 2025-12-20 06:14:28 +01:00
chore(toc): reintroduce basic collapse support
This commit is contained in:
parent
87a98201b4
commit
73f1b91d34
@ -1,8 +1,16 @@
|
||||
interface IconProps {
|
||||
import clsx from "clsx";
|
||||
import { HTMLAttributes } from "preact";
|
||||
|
||||
interface IconProps extends Pick<HTMLAttributes<HTMLSpanElement>, "className" | "onClick"> {
|
||||
icon?: string;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
export default function Icon({ icon, className }: IconProps) {
|
||||
return <span class={`${icon ?? "bx bx-empty"} ${className ?? ""}`}></span>
|
||||
}
|
||||
export default function Icon({ icon, className, ...restProps }: IconProps) {
|
||||
return (
|
||||
<span
|
||||
class={clsx(icon ?? "bx bx-empty", className)}
|
||||
{...restProps}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
82
apps/client/src/widgets/sidebar/TableOfContents.css
Normal file
82
apps/client/src/widgets/sidebar/TableOfContents.css
Normal file
@ -0,0 +1,82 @@
|
||||
.toc ol {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
padding-inline-start: 0px;
|
||||
transition: max-height 0.3s ease;
|
||||
}
|
||||
|
||||
.toc li.collapsed + ol {
|
||||
display:none;
|
||||
}
|
||||
|
||||
.toc li + ol:before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
height: 100%;
|
||||
border-inline-start: 1px solid var(--main-border-color);
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.toc li {
|
||||
display: flex;
|
||||
position: relative;
|
||||
list-style: none;
|
||||
align-items: center;
|
||||
padding-inline-start: 7px;
|
||||
cursor: pointer;
|
||||
text-align: justify;
|
||||
word-wrap: break-word;
|
||||
hyphens: auto;
|
||||
}
|
||||
|
||||
.toc > ol {
|
||||
--toc-depth-level: 1;
|
||||
}
|
||||
.toc > ol > ol {
|
||||
--toc-depth-level: 2;
|
||||
}
|
||||
.toc > ol > ol > ol {
|
||||
--toc-depth-level: 3;
|
||||
}
|
||||
.toc > ol > ol > ol > ol {
|
||||
--toc-depth-level: 4;
|
||||
}
|
||||
.toc > ol > ol > ol > ol > ol {
|
||||
--toc-depth-level: 5;
|
||||
}
|
||||
|
||||
.toc > ol ol::before {
|
||||
inset-inline-start: calc((var(--toc-depth-level) - 2) * 20px + 14px);
|
||||
}
|
||||
|
||||
.toc li {
|
||||
padding-inline-start: calc((var(--toc-depth-level) - 1) * 20px + 4px);
|
||||
}
|
||||
|
||||
.toc li .collapse-button {
|
||||
display: flex;
|
||||
position: relative;
|
||||
width: 21px;
|
||||
height: 21px;
|
||||
flex-shrink: 0;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
transition: transform 0.3s ease;
|
||||
}
|
||||
|
||||
.toc li.collapsed .collapse-button {
|
||||
transform: rotate(-90deg);
|
||||
}
|
||||
|
||||
.toc li .item-content {
|
||||
margin-inline-start: 25px;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.toc li .collapse-button + .item-content {
|
||||
margin-inline-start: 4px;
|
||||
}
|
||||
|
||||
.toc li:hover {
|
||||
font-weight: bold;
|
||||
}
|
||||
@ -1,8 +1,12 @@
|
||||
import "./TableOfContents.css";
|
||||
|
||||
import { CKTextEditor, ModelElement } from "@triliumnext/ckeditor5";
|
||||
import clsx from "clsx";
|
||||
import { useEffect, useState } from "preact/hooks";
|
||||
|
||||
import { t } from "../../services/i18n";
|
||||
import { useActiveNoteContext, useIsNoteReadOnly, useNoteProperty, useTextEditor } from "../react/hooks";
|
||||
import Icon from "../react/Icon";
|
||||
import RightPanelWidget from "./RightPanelWidget";
|
||||
|
||||
interface RawHeading {
|
||||
@ -66,19 +70,35 @@ function AbstractTableOfContents({ headings }: {
|
||||
headings: RawHeading[];
|
||||
}) {
|
||||
const nestedHeadings = buildHeadingTree(headings);
|
||||
return nestedHeadings.map(heading => <TableOfContentsHeading heading={heading} />);
|
||||
return (
|
||||
<span className="toc">
|
||||
<ol>
|
||||
{nestedHeadings.map(heading => <TableOfContentsHeading heading={heading} />)}
|
||||
</ol>
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
function TableOfContentsHeading({ heading }: { heading: HeadingsWithNesting }) {
|
||||
const [ collapsed, setCollapsed ] = useState(false);
|
||||
return (
|
||||
<li>
|
||||
<span className="title">{heading.text}</span>
|
||||
<>
|
||||
<li className={clsx(collapsed && "collapsed")}>
|
||||
{heading.children.length > 0 && (
|
||||
<Icon
|
||||
className="collapse-button"
|
||||
icon="bx bx-chevron-down"
|
||||
onClick={() => setCollapsed(!collapsed)}
|
||||
/>
|
||||
)}
|
||||
<span className="item-content">{heading.text}</span>
|
||||
</li>
|
||||
{heading.children && (
|
||||
<ul>
|
||||
<ol>
|
||||
{heading.children.map(heading => <TableOfContentsHeading heading={heading} />)}
|
||||
</ul>
|
||||
</ol>
|
||||
)}
|
||||
</li>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user