Use auto height
optics/use-auto-heightFreeUtility
Hook utility: use-auto-height
See it running
Open the demo on optics
optics.agusmayol.com.ar/components/use-auto-heightInstall it
npx shadcn@latest add https://optics.agusmayol.com.ar/r/use-auto-height.jsonSource
1"use client";2import * as React from "react";34export function useAutoHeight(5 deps = [],6 options = {7 includeParentBox: true,8 includeSelfBox: false,9 },10) {11 const ref = React.useRef(null);12 const roRef = React.useRef(null);13 const [height, setHeight] = React.useState(0);1415 const measure = React.useCallback(() => {16 const el = ref.current;17 if (!el) return 0;1819 const base = el.getBoundingClientRect().height || 0;2021 let extra = 0;2223 if (options.includeParentBox && el.parentElement) {24 const cs = getComputedStyle(el.parentElement);25 const paddingY =26 (parseFloat(cs.paddingTop || "0") || 0) +27 (parseFloat(cs.paddingBottom || "0") || 0);28 const borderY =29 (parseFloat(cs.borderTopWidth || "0") || 0) +30 (parseFloat(cs.borderBottomWidth || "0") || 0);31 const isBorderBox = cs.boxSizing === "border-box";32 if (isBorderBox) {33 extra += paddingY + borderY;34 }35 }3637 if (options.includeSelfBox) {38 const cs = getComputedStyle(el);39 const paddingY =40 (parseFloat(cs.paddingTop || "0") || 0) +41 (parseFloat(cs.paddingBottom || "0") || 0);42 const borderY =43 (parseFloat(cs.borderTopWidth || "0") || 0) +44 (parseFloat(cs.borderBottomWidth || "0") || 0);45 const isBorderBox = cs.boxSizing === "border-box";46 if (isBorderBox) {47 extra += paddingY + borderY;48 }49 }5051 const dpr =52 typeof window !== "undefined" ? window.devicePixelRatio || 1 : 1;53 const total = Math.ceil((base + extra) * dpr) / dpr;5455 return total;56 }, [options.includeParentBox, options.includeSelfBox]);5758 React.useLayoutEffect(() => {59 const el = ref.current;60 if (!el) return;6162 setHeight(measure());6364 if (roRef.current) {65 roRef.current.disconnect();66 roRef.current = null;67 }6869 const ro = new ResizeObserver(() => {70 const next = measure();71 requestAnimationFrame(() => setHeight(next));72 });7374 ro.observe(el);75 if (options.includeParentBox && el.parentElement) {76 ro.observe(el.parentElement);77 }7879 roRef.current = ro;8081 return () => {82 ro.disconnect();83 roRef.current = null;84 };85 // eslint-disable-next-line react-hooks/exhaustive-deps86 }, deps);8788 React.useLayoutEffect(() => {89 if (height === 0) {90 const next = measure();91 if (next !== 0) setHeight(next);92 }93 }, [height, measure]);9495 return {96 ref,97 height,98 };99}
Files it writes
More from optics
All 79 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Cursor Rule: Back Endcursor-rule-back-end | optics | Utilities | Free | no deps | |
| Cursor Rule: Bulk Processingcursor-rule-bulk-processing | optics | Utilities | Free | no deps | |
| Cursor Rule: Commits Conventioncursor-rule-commits-convention | optics | Utilities | Free | no deps | |
| Cursor Rule: Front Endcursor-rule-front-end | optics | Utilities | Free | no deps | |
| Cursor Rule: Generalcursor-rule-general | optics | Utilities | Free | no deps | |
| Cursor Rule: React Optimizationcursor-rule-react-optimization | optics | Utilities | Free | no deps | |
| Cursor Rule: Web Interface Guidelinescursor-rule-web-interface-guidelines | optics | Utilities | Free | no deps | |
| Get strict contextget-strict-context | optics | Utilities | Free | no deps |
