This component no longer exists. It was in cubby-ui’s manifest when we first indexed it and is not there now — the registry served its inventory on 2026-08-10 and this item was not on it. The install command below will fail. It is kept here because a tutorial somewhere still tells people to run it.
useAnimatedHeight
cubby-ui/use-animated-heightRemovedHook
A custom React hook for animated height.
Install it
npx shadcn@latest add https://cubby-ui.dev/r/use-animated-height.jsonSource
1import { useCallback, useEffect, useRef } from "react";23const MIN_FADE_DURATION = 0.15;4const MAX_FADE_DURATION = 0.27;56/**7 * Tracks the inner element's height and writes it onto the outer element, plus8 * a size-adaptive `--fade-duration`.9 *10 * `onResize` runs after each write with the measured height and the outer11 * element. Consumers driving their own height animation use it to retarget when12 * content resizes mid-flight. It's held in a ref, so passing an inline function13 * won't tear down and rebuild the observer on every render. Pass a stable14 * callback if it reads state: the ref syncs in a passive effect (after paint)15 * while the observer fires before it, so an inline closure can be a render late.16 */17export function useAnimatedHeight(18 onResize?: (height: number, outer: HTMLElement) => void,19) {20 const outerRef = useRef<HTMLDivElement>(null);21 const observerRef = useRef<ResizeObserver | null>(null);22 const previousHeight = useRef(0);2324 // Held in a ref rather than `useEffectEvent`: the observer is attached from a25 // callback ref, and an effect event closed over inside that `useCallback`26 // trips the React Compiler's memoization check (it wants the event in the27 // deps, which effect events must never go in). Refs are recognized as stable,28 // so this keeps the observer from rebuilding on every render.29 const onResizeRef = useRef(onResize);30 useEffect(() => {31 onResizeRef.current = onResize;32 }, [onResize]);3334 const innerRef = useCallback((node: HTMLDivElement | null) => {35 if (observerRef.current) {36 observerRef.current.disconnect();37 observerRef.current = null;38 }3940 if (!node) return;4142 const observer = new ResizeObserver((entries) => {43 const outer = outerRef.current;44 if (!outer) return;45 // Use the layout border-box height, not `getBoundingClientRect`. The46 // bounding rect includes ancestor transforms (e.g. a parent popover's47 // open-time `scale-95` → `scale-100`), which previously caused this48 // hook to write the *scaled* height onto the outer element on first49 // observation — under-sizing the container until a later layout50 // change happened to trigger another ResizeObserver tick.51 const entry = entries[0];52 const height =53 entry.borderBoxSize?.[0]?.blockSize ??54 (entry.target as HTMLElement).offsetHeight;55 if (height > 0) {56// … truncated
