mirror of
https://github.com/zadam/trilium.git
synced 2026-05-07 04:47:40 +02:00
client: create a fluid wrapper component
This commit is contained in:
41
apps/client/src/widgets/react/FluidWrapper.tsx
Normal file
41
apps/client/src/widgets/react/FluidWrapper.tsx
Normal file
@@ -0,0 +1,41 @@
|
||||
import clsx from "clsx";
|
||||
import { ComponentChildren } from "preact";
|
||||
import { useEffect, useMemo, useRef, useState } from "preact/hooks";
|
||||
|
||||
interface FluidWrapperParams {
|
||||
className?: string;
|
||||
breakpoints: {[key: string]: number};
|
||||
children: ComponentChildren;
|
||||
}
|
||||
|
||||
export function FluidWrapper({className, breakpoints, children}: FluidWrapperParams) {
|
||||
const ref = useRef<HTMLDivElement>(null);
|
||||
const sortedBreakpoints = useMemo(() => {
|
||||
return Object.entries(breakpoints).sort(([, a], [, b]) => a - b)
|
||||
}, [breakpoints]);
|
||||
const [activeBreakpoint, setActiveBreakpoint] = useState<string | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
const el = ref.current;
|
||||
if (!el) return;
|
||||
|
||||
const onWidthChanged = (width: number) => {
|
||||
let match = sortedBreakpoints[0]?.[0] ?? null;
|
||||
for (const [name, min] of sortedBreakpoints) {
|
||||
if (width >= min) match = name;
|
||||
else break;
|
||||
}
|
||||
setActiveBreakpoint(match);
|
||||
};
|
||||
|
||||
const observer = new ResizeObserver(([entry]) => onWidthChanged(entry.contentRect.width));
|
||||
observer.observe(el);
|
||||
onWidthChanged(el.getBoundingClientRect().width);
|
||||
|
||||
return () => observer.disconnect();
|
||||
}, [sortedBreakpoints]);
|
||||
|
||||
return <div ref={ref} className={clsx("fluid-container", className, activeBreakpoint)}>
|
||||
{children}
|
||||
</div>
|
||||
}
|
||||
Reference in New Issue
Block a user