Skip to main content

useBoundingRectangle

Description#

This hook saves and returns the last known bounding box (position and dimensions) of a DOM element. It also updates on resize events.

Usage#

This hook is useful when interacting with popovers, that need an anchor element, which is expected to remount while the popover is open (e.g.: eva-suite-ui DateRangePicker).

import moment from 'moment';import { useState } from 'react';import { useBoundingRectangle } from '@springtree/eva-suite-react-hooks';import { Box, Grid, DatePickerField, DateRangePicker } from '@springtree/eva-suite-ui';
const Example = () => {  const [startDate, setStartDate] = useState<string | undefined>();  const [endDate, setEndDate] = useState<string | undefined>();  const [anchorEl, setAnchorEl] = useState<HTMLDivElement | null>(null);  const [openPopover, setOpenPopover] = useState(false);  const [focusedInput, setFocusedInput] = useState<'startDate' | 'endDate'>('startDate');  const anchorElBoundingRectangle = useBoundingRectangle(anchorEl);
  return (    <Box>      <Grid container spacing={2}>        <Grid item md={6}>          <DatePickerField            fullWidth            label="Start date"            value={startDate ? startDate : ''}            clear={() => setStartDate(undefined)}            onChange={(event) => setStartDate(event.target.value)}            handleClick={e => {              setOpenPopover(true);              setAnchorEl(e.currentTarget);              setFocusedInput('startDate');            }}          />        </Grid>        <Grid item md={6}>          <DatePickerField            fullWidth            label="End date"            value={endDate ? endDate : ''}            clear={() => setEndDate(undefined)}            onChange={event => setEndDate(event.target.value)}            handleClick={(event) => {              setAnchorEl(event.currentTarget);              setOpenPopover(true);              setFocusedInput('endDate');            }}          />        </Grid>      </Grid>      <DateRangePicker        minimumNights={0}        numberOfMonths={2}        open={openPopover}        anchorEl={anchorEl}        setOpen={setOpenPopover}        focusedInput={focusedInput}        id="date-range-picker-absolute"        endDate={endDate ? moment(endDate) : null}        startDate={startDate ? moment(startDate) : null}        absolutePosition={{ top: anchorElBoundingRectangle.top, left: anchorElBoundingRectangle.left }}        onFocusChange={(arg) => {          if (arg !== null) {            setFocusedInput(arg);          }        }}        onDatesChange={({ startDate: changedStartDate, endDate: changedEndDate }) => {          if (changedStartDate) {            setStartDate(moment(changedStartDate).format('YYYY-MM-DD'));          }          if (changedEndDate) {            setEndDate(moment(changedEndDate).format('YYYY-MM-DD'));            setOpenPopover(false);          }        }}      />      <pre>{JSON.stringify({ startDate, endDate }, null, 2)}</pre>    </Box>  );};
export default Example;

References#