chore(right_pane): basic collapse support

This commit is contained in:
Elian Doran 2025-12-18 14:42:21 +02:00
parent b5bfb02d96
commit 682c61305c
No known key found for this signature in database
3 changed files with 63 additions and 8 deletions

View File

@ -13,5 +13,9 @@ body.experimental-feature-new-layout #right-pane {
&:last-of-type {
border-bottom: 0;
}
&.collapsed .card-header > .bx {
transform: rotate(-90deg);
}
}
}

View File

@ -2,7 +2,8 @@
import "./RightPanelContainer.css";
import Split from "@triliumnext/split.js";
import { useEffect } from "preact/hooks";
import { createContext } from "preact";
import { useEffect, useRef } from "preact/hooks";
import options from "../../services/options";
import { DEFAULT_GUTTER_SIZE } from "../../services/resizer";
@ -10,6 +11,11 @@ import HighlightsList from "./HighlightsList";
import TableOfContents from "./TableOfContents";
const MIN_WIDTH_PERCENT = 5;
const COLLAPSED_SIZE = 32;
export const RightPanelContext = createContext({
setExpanded(cardEl: HTMLElement, expanded: boolean) {}
});
export default function RightPanelContainer() {
// Split between right pane and the content pane.
@ -32,19 +38,46 @@ export default function RightPanelContainer() {
];
// Split between items.
const innerSplitRef = useRef<Split.Instance>(null);
useEffect(() => {
const rightPaneContainer = document.getElementById("right-pane");
const elements = Array.from(rightPaneContainer?.children ?? []) as HTMLElement[];
console.log("Got ", elements);
const splitInstance = Split(elements, {
direction: "vertical"
direction: "vertical",
minSize: COLLAPSED_SIZE,
gutterSize: 1
});
innerSplitRef.current = splitInstance;
return () => splitInstance.destroy();
}, [ items ]);
return (
<div id="right-pane">
{items}
<RightPanelContext.Provider value={{
setExpanded(cardEl, expanded) {
const splitInstance = innerSplitRef.current;
if (!splitInstance) return;
const rightPaneEl = document.getElementById("right-pane");
const children = Array.from(rightPaneEl?.querySelectorAll(":scope > .card") ?? []);
const pos = children.indexOf(cardEl);
if (pos === -1) return;
const sizes = splitInstance.getSizes();
if (!expanded) {
const sizeBeforeCollapse = sizes[pos];
sizes[pos] = 0;
const itemToExpand = pos > 0 ? pos - 1 : pos + 1;
if (sizes[itemToExpand] > COLLAPSED_SIZE) {
sizes[itemToExpand] += sizeBeforeCollapse;
}
}
console.log("Set sizes to ", sizes);
splitInstance.setSizes(sizes);
},
}}>
{items}
</RightPanelContext.Provider>
</div>
);
}

View File

@ -1,6 +1,10 @@
import { useContext, useRef } from "preact/hooks";
import { ParentComponent } from "../react/react_utils";
import clsx from "clsx";
import { ComponentChildren } from "preact";
import { useContext, useRef, useState } from "preact/hooks";
import Icon from "../react/Icon";
import { ParentComponent } from "../react/react_utils";
import { RightPanelContext } from "./RightPanelContainer";
interface RightPanelWidgetProps {
title: string;
@ -9,6 +13,8 @@ interface RightPanelWidgetProps {
}
export default function RightPanelWidget({ title, buttons, children }: RightPanelWidgetProps) {
const rightPanelContext = useContext(RightPanelContext);
const [ expanded, setExpanded ] = useState(true);
const containerRef = useRef<HTMLDivElement>(null);
const parentComponent = useContext(ParentComponent);
@ -17,15 +23,27 @@ export default function RightPanelWidget({ title, buttons, children }: RightPane
}
return (
<div ref={containerRef} class="card widget" style={{contain: "none"}}>
<div
ref={containerRef}
class={clsx("card widget", !expanded && "collapsed")}
>
<div class="card-header">
<Icon
icon="bx bx-chevron-down"
onClick={() => {
if (containerRef.current) {
rightPanelContext.setExpanded(containerRef.current, !expanded);
}
setExpanded(!expanded);
}}
/>
<div class="card-header-title">{title}</div>
<div class="card-header-buttons">{buttons}</div>
</div>
<div id={parentComponent?.componentId} class="body-wrapper">
<div class="card-body">
{children}
{expanded && children}
</div>
</div>
</div>