Open History to see the last commit
1import { useLayoutEffect, useRef, useState } from "react";
2
3import { observeResize } from "~/lib/observeResize";
4
5// The folds clip with `max-h-44`, which is 11rem.
6const FOLDED_HEIGHT_REM = 11;
7
8/**
9 * Put `ref` on the unclipped content inside a fold. `tallEnough` is true when that content is at
10 * least twice the folded height, so opening a fold always at least doubles what was on screen.
11 */
12export function useTallEnoughToFold(enabled = true) {
13 const ref = useRef<HTMLDivElement>(null);
14 const [tallEnough, setTallEnough] = useState(false);
15 // oxlint-disable-next-line t3code/no-unreasoned-state-sync -- the fold depends on the rendered height, which only the DOM knows
16 useLayoutEffect(() => {
17 const content = ref.current;
18 if (!enabled || !content) return;
19 const measure = () => {
20 const remPx = Number.parseFloat(getComputedStyle(document.documentElement).fontSize) || 16;
21 setTallEnough(content.offsetHeight >= FOLDED_HEIGHT_REM * 2 * remPx);
22 };
23 // Measured here too: waiting for the observer would paint one unfolded frame.
24 measure();
25 return observeResize(content, measure);
26 }, [enabled]);
27 return { ref, tallEnough: enabled && tallEnough };
28}