useElementSize
function useElementSize<E extends HTMLElement>(
options?: ElementSizeOptions<E>
): ElementSizeImplementation<E>;
The useElementSize
hook can be used to track size changes for a specific
element using the Resize Observer API.
Example Usage
import { useElementSize } from "@react-md/core/useElementSize";
function Example() {
const { height, width, elementRef } = useElementSize();
return <div ref={elementRef}>{`height: ${height}, width: ${width}`}</div>;
}
Parameters
options
(optional) - An object with the following definition:
export interface ElementSizeOptions<E extends HTMLElement> {
/** @defaultValue `{ height: 0, width: 0 }` */
defaultValue?: UseStateInitializer<ElementSize>;
/**
* An optional ref to merge with the ref returned by this hook.
*/
ref?: Ref<E>;
/**
* Set this to `true` to prevent observing the element's size changes. This is
* equivalent to not attaching the returned ref to any element.
*
* @defaultValue `false`
*/
disabled?: boolean;
/**
* Set this to `true` if the {@link onUpdate} should not be fired for height
* changes.
*
* @defaultValue `false`
*/
disableHeight?: boolean;
/**
* Set this to `true` if the {@link onUpdate} should not be fired for width
* changes.
*
* @defaultValue `false`
*/
disableWidth?: boolean;
}
defaultValue
This prop can be used to define a default value for the first render if the size can be guessed. This is mostly useful for server-side-rendering.
The default value can be static or using an initializer function to handle client side values.
const ssr = useSsr();
const { height, width, elementRef } = useElementSize({
defaultValue: () => {
if (ssr) {
return { height: 128, width: 64 };
}
// some sort of known client calculation
return {
height: window.innerHeight / 8,
width: window.innerWidth / 12,
};
},
});
Returns
export interface ElementSizeImplementation<E extends HTMLElement> {
height: number;
width: number;
elementRef: RefCallback<E>;
/**
* This will be `true` once the resize observer's callback is triggered at
* least once.
*
* This was added so that generating custom properties that have a reasonable
* default value set in css don't cause major layout shifts when a default
* value cannot be provided.
*/
observedOnce: boolean;
}
observedOnce
The observedOnce
flag can be used to ensure some value is only calculated once
the Resize Observer has been initialized.
const { height, width, observedOnce } = useElementSize();
useCSSVariables(
useMemo(() => {
if (!observedOnce) {
return [];
}
// something that uses the element's height, width, or both
return [{ var: "--something", value: (height / width) * 0.5 }];
}, [height, width, observedOnce])
);