resizeable.tsx 982 B

123456789101112131415161718192021222324252627282930313233343536
  1. import React, {useCallback, useRef, useState} from 'react';
  2. import {useResizeObserver} from '@react-aria/utils';
  3. type Dimensions = {height: number; width: number};
  4. type Props = {
  5. children: (props: Dimensions) => React.ReactElement | null;
  6. className?: string;
  7. };
  8. /**
  9. * Watch and pass element dimensions into child render function.
  10. *
  11. * WARNING: be careful not to update the dimensions of child elements based on
  12. * this parent size as that could cause infinite render loops
  13. */
  14. export function Resizeable({children, className}: Props) {
  15. const el = useRef<HTMLDivElement>(null);
  16. const [dimensions, setDimensions] = useState({height: 0, width: 0});
  17. const onResize = useCallback(() => {
  18. setDimensions({
  19. height: el.current?.clientHeight || 0,
  20. width: el.current?.clientWidth || 0,
  21. });
  22. }, [setDimensions]);
  23. useResizeObserver({ref: el, onResize});
  24. return (
  25. <div className={className} ref={el}>
  26. {children(dimensions)}
  27. </div>
  28. );
  29. }