diff --git a/src/examples/js/useMeasure/Resizable.jsx b/src/examples/js/useMeasure/Resizable.jsx new file mode 100644 index 0000000..c762ff5 --- /dev/null +++ b/src/examples/js/useMeasure/Resizable.jsx @@ -0,0 +1,20 @@ +import { useMeasure } from '../../../hooks/js/useMeasure.js'; + +const RESIZABLE_STYLE = { + resize: 'both', + overflow: 'auto', + padding: '20px', + border: '1px solid black' +}; + +export const Resizable = () => { + const [ref, size] = useMeasure(); + + return ( +
+

Resize this box!

+

Width: {size.width}px

+

Height: {size.height}px

+
+ ); +} \ No newline at end of file diff --git a/src/examples/ts/useMeasure/Resizable.tsx b/src/examples/ts/useMeasure/Resizable.tsx new file mode 100644 index 0000000..1bfc2cc --- /dev/null +++ b/src/examples/ts/useMeasure/Resizable.tsx @@ -0,0 +1,20 @@ +import { useMeasure } from '../../../hooks/ts/useMeasure.ts'; + +const RESIZABLE_STYLE = { + resize: 'both', + overflow: 'auto', + padding: '20px', + border: '1px solid black' +}; + +export const Resizable = () => { + const [ref, size] = useMeasure(); + + return ( +
+

Resize this box!

+

Width: {size.width}px

+

Height: {size.height}px

+
+ ); +} \ No newline at end of file diff --git a/src/hooks/js/useMeasure.js b/src/hooks/js/useMeasure.js new file mode 100644 index 0000000..4a7e602 --- /dev/null +++ b/src/hooks/js/useMeasure.js @@ -0,0 +1,28 @@ +import { useState, useEffect, useRef } from 'react' + +export const useMeasure = () => { + const [size, setSize] = useState({ width: 0, height: 0 }) + const elementRef = useRef(null) + + useEffect(() => { + const observer = new ResizeObserver((entries) => { + if (entries.length > 0) { + const entry = entries[0] + const { width, height } = entry.contentRect + setSize({ width, height }) + } + }) + + if (elementRef.current) { + observer.observe(elementRef.current) + } + + return () => { + if (elementRef.current) { + observer.unobserve(elementRef.current) + } + } + }, []) + + return [elementRef, size] +} \ No newline at end of file diff --git a/src/hooks/ts/useMeasure.ts b/src/hooks/ts/useMeasure.ts new file mode 100644 index 0000000..9c385bb --- /dev/null +++ b/src/hooks/ts/useMeasure.ts @@ -0,0 +1,33 @@ +import { useState, useEffect, useRef } from 'react' + +type Size = { + width: number + height: number +} + +export const useMeasure = () => { + const [size, setSize] = useState({ width: 0, height: 0 }) + const elementRef = useRef(null) + + useEffect(() => { + const observer = new ResizeObserver((entries: ResizeObserverEntry[]) => { + if (entries.length > 0) { + const entry = entries[0] + const { width, height } = entry.contentRect + setSize({ width, height }) + } + }) + + if (elementRef.current) { + observer.observe(elementRef.current) + } + + return () => { + if (elementRef.current) { + observer.unobserve(elementRef.current) + } + } + }, []) + + return [elementRef, size] as const +} \ No newline at end of file