useDomFullHeight.tsx 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. import { useEffect, useState } from 'react';
  2. import type { MutableRefObject } from 'react';
  3. type TargetValue<T> = T | undefined | null;
  4. type TargetType = HTMLElement | HTMLDivElement | Element | Window | Document;
  5. type BasicTarget<T extends TargetType = Element> =
  6. | TargetValue<T>
  7. | MutableRefObject<TargetValue<T>>;
  8. const getTargetElement = <T extends TargetType>(target: BasicTarget<T> | string) => {
  9. if (!target) {
  10. return null;
  11. }
  12. let targetElement: TargetValue<T> | Element;
  13. if (typeof target === 'string') {
  14. targetElement = document.querySelector(target);
  15. } else if ('current' in target) {
  16. targetElement = target.current;
  17. } else {
  18. targetElement = target;
  19. }
  20. return targetElement;
  21. };
  22. const useDomFullHeight = (target: BasicTarget | string, extraHeight: number = 0) => {
  23. const [state, setState] = useState(100);
  24. useEffect(() => {
  25. const el = getTargetElement(target);
  26. let resizeObserver: ResizeObserver | undefined;
  27. if (el) {
  28. resizeObserver = new ResizeObserver((entries) => {
  29. entries.forEach((entry) => {
  30. const bodyClient = document.body.getBoundingClientRect();
  31. const domClient = entry.target.getBoundingClientRect();
  32. console.log(domClient);
  33. if (domClient.y < 50) {
  34. setState(100);
  35. } else {
  36. setState(bodyClient.height - domClient.y - 24 - extraHeight);
  37. }
  38. });
  39. });
  40. resizeObserver.observe(el);
  41. }
  42. return () => {
  43. if (resizeObserver) {
  44. resizeObserver.disconnect();
  45. }
  46. };
  47. }, [target]);
  48. return {
  49. minHeight: state,
  50. };
  51. };
  52. export default useDomFullHeight;