mirror of
				https://github.com/zadam/trilium.git
				synced 2025-10-31 02:16:05 +01:00 
			
		
		
		
	chore(react/ribbon): integrate expand/collapse button
This commit is contained in:
		| @@ -1,13 +1,14 @@ | ||||
| interface ActionButtonProps { | ||||
|     text: string; | ||||
|     icon: string; | ||||
|     className?: string; | ||||
|     onClick?: () => void; | ||||
| } | ||||
|  | ||||
| export default function ActionButton({ text, icon, onClick }: ActionButtonProps) { | ||||
| export default function ActionButton({ text, icon, className, onClick }: ActionButtonProps) { | ||||
|     return <button | ||||
|         class={`icon-action ${icon}`} | ||||
|         class={`icon-action ${icon} ${className ?? ""}`} | ||||
|         title={text} | ||||
|         onClick={onClick} | ||||
|         onClick={onClick}         | ||||
|     />; | ||||
| } | ||||
| @@ -11,8 +11,8 @@ import BasicWidget, { ReactWrappedWidget } from "../basic_widget"; | ||||
| import FNote from "../../entities/fnote"; | ||||
| import attributes from "../../services/attributes"; | ||||
| import FBlob from "../../entities/fblob"; | ||||
| import RawHtml from "./RawHtml"; | ||||
| import NoteContextAwareWidget from "../note_context_aware_widget"; | ||||
| import { VNode } from "preact"; | ||||
|  | ||||
| type TriliumEventHandler<T extends EventNames> = (data: EventData<T>) => void; | ||||
| const registeredHandlers: Map<Component, Map<EventNames, TriliumEventHandler<any>[]>> = new Map(); | ||||
| @@ -414,10 +414,10 @@ export function useNoteBlob(note: FNote | null | undefined): [ FBlob | null | un | ||||
|     return [ blob ] as const; | ||||
| } | ||||
|  | ||||
| export function useLegacyWidget(widgetFactory: () => BasicWidget, { noteContext, containerClassName }: { | ||||
| export function useLegacyWidget<T extends BasicWidget>(widgetFactory: () => T, { noteContext, containerClassName }: { | ||||
|     noteContext?: NoteContext; | ||||
|     containerClassName?: string; | ||||
| } = {}) { | ||||
| } = {}): [VNode, T] { | ||||
|     const ref = useRef<HTMLDivElement>(null); | ||||
|     const parentComponent = useContext(ParentComponent); | ||||
|  | ||||
| @@ -453,5 +453,5 @@ export function useLegacyWidget(widgetFactory: () => BasicWidget, { noteContext, | ||||
|         } | ||||
|     }, [ noteContext ]); | ||||
|  | ||||
|     return <div className={containerClassName} ref={ref} /> | ||||
|     return [ <div className={containerClassName} ref={ref} />, widget ] | ||||
| } | ||||
| @@ -1,16 +1,55 @@ | ||||
| import { TabContext } from "./ribbon-interface"; | ||||
| import NoteMapWidget from "../note_map"; | ||||
| import { useLegacyWidget } from "../react/hooks"; | ||||
| import ActionButton from "../react/ActionButton"; | ||||
| import { t } from "../../services/i18n"; | ||||
| import { useEffect, useRef, useState } from "preact/hooks"; | ||||
|  | ||||
| const SMALL_SIZE_HEIGHT = "300px"; | ||||
|  | ||||
| export default function NoteMapTab({ note, noteContext }: TabContext) { | ||||
|     const noteMapWidget = useLegacyWidget(() => new NoteMapWidget("ribbon"), { | ||||
|     const [ isExpanded, setExpanded ] = useState(false); | ||||
|     const [ height, setHeight ] = useState(SMALL_SIZE_HEIGHT); | ||||
|     const containerRef = useRef<HTMLDivElement>(null); | ||||
|  | ||||
|     const [ noteMapContainer, noteMapWidget ] = useLegacyWidget(() => new NoteMapWidget("ribbon"), { | ||||
|         noteContext, | ||||
|         containerClassName: "note-map-container" | ||||
|     }); | ||||
|  | ||||
|     useEffect(() => noteMapWidget.setDimensions(), [ height ]); | ||||
|  | ||||
|     function toggleExpanded(newValue: boolean) { | ||||
|         setExpanded(newValue); | ||||
|  | ||||
|         if (newValue && containerRef.current) { | ||||
|             const { top } = containerRef.current.getBoundingClientRect(); | ||||
|             const height = window.innerHeight - top; | ||||
|             setHeight(height + "px"); | ||||
|         } else { | ||||
|             setHeight(SMALL_SIZE_HEIGHT); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     return ( | ||||
|         <div className="note-map-ribbon-widget"> | ||||
|             {noteMapWidget} | ||||
|         <div className="note-map-ribbon-widget" style={{ height }} ref={containerRef}> | ||||
|             {noteMapContainer} | ||||
|  | ||||
|             {!isExpanded ? ( | ||||
|                 <ActionButton | ||||
|                     icon="bx bx-arrow-to-bottom" | ||||
|                     text={t("note_map.open_full")} | ||||
|                     className="open-full-button" | ||||
|                     onClick={() => toggleExpanded(true)} | ||||
|                 /> | ||||
|             ) : ( | ||||
|                 <ActionButton | ||||
|                     icon="bx bx-arrow-to-top" | ||||
|                     text={t("note_map.collapse")} | ||||
|                     className="collapse-button" | ||||
|                     onClick={() => toggleExpanded(false)} | ||||
|                 /> | ||||
|             )} | ||||
|         </div> | ||||
|     ); | ||||
| } | ||||
| @@ -253,7 +253,7 @@ | ||||
| } | ||||
|  | ||||
| .note-map-ribbon-widget .note-map-container { | ||||
|     height: 300px; | ||||
|     height: 100%; | ||||
| } | ||||
|  | ||||
| .note-map-ribbon-widget .open-full-button, .note-map-ribbon-widget .collapse-button { | ||||
|   | ||||
| @@ -2,14 +2,6 @@ import NoteContextAwareWidget from "../note_context_aware_widget.js"; | ||||
| import NoteMapWidget from "../note_map.js"; | ||||
| import { t } from "../../services/i18n.js"; | ||||
|  | ||||
| const TPL = /*html*/` | ||||
|  | ||||
|     <button class="bx bx-arrow-to-bottom icon-action open-full-button" title="${t("note_map.open_full")}"></button> | ||||
|     <button class="bx bx-arrow-to-top icon-action collapse-button" style="display: none;" title="${t("note_map.collapse")}"></button> | ||||
|  | ||||
|  | ||||
| </div>`; | ||||
|  | ||||
| export default class NoteMapRibbonWidget extends NoteContextAwareWidget { | ||||
|  | ||||
|     private openState!: "small" | "full"; | ||||
| @@ -50,37 +42,7 @@ export default class NoteMapRibbonWidget extends NoteContextAwareWidget { | ||||
|             this.noteMapWidget.setDimensions(); | ||||
|         }); | ||||
|  | ||||
|         const handleResize = () => { | ||||
|             if (!this.noteMapWidget.graph) { | ||||
|                 // no graph has been even rendered | ||||
|                 return; | ||||
|             } | ||||
|  | ||||
|             if (this.openState === "full") { | ||||
|                 this.setFullHeight(); | ||||
|             } else if (this.openState === "small") { | ||||
|                 this.setSmallSize(); | ||||
|             } | ||||
|         }; | ||||
|  | ||||
|         new ResizeObserver(handleResize).observe(this.$widget[0]); | ||||
|     } | ||||
|  | ||||
|     setSmallSize() { | ||||
|         const SMALL_SIZE_HEIGHT = 300; | ||||
|         const width = this.$widget.width() ?? 0; | ||||
|  | ||||
|         this.$widget.find(".note-map-container").height(SMALL_SIZE_HEIGHT).width(width); | ||||
|     } | ||||
|  | ||||
|     setFullHeight() { | ||||
|         const { top } = this.$widget[0].getBoundingClientRect(); | ||||
|  | ||||
|         const height = ($(window).height() ?? 0) - top; | ||||
|         const width = this.$widget.width() ?? 0; | ||||
|  | ||||
|         this.$widget.find(".note-map-container") | ||||
|             .height(height) | ||||
|             .width(width); | ||||
|     } | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user