Compare commits

...

1 Commits

Author SHA1 Message Date
Tom Moor 7932ed7090 Combine useComponentSize hooks, possible fix for #8337 2025-02-04 20:55:07 -05:00
8 changed files with 19 additions and 47 deletions
+1 -1
View File
@@ -6,12 +6,12 @@ import * as React from "react";
import { mergeRefs } from "react-merge-refs";
import styled from "styled-components";
import breakpoint from "styled-components-breakpoint";
import { useComponentSize } from "@shared/hooks/useComponentSize";
import { depths, s } from "@shared/styles";
import { supportsPassiveListener } from "@shared/utils/browser";
import Button from "~/components/Button";
import Fade from "~/components/Fade";
import Flex from "~/components/Flex";
import useComponentSize from "~/hooks/useComponentSize";
import useEventListener from "~/hooks/useEventListener";
import useMobile from "~/hooks/useMobile";
import useStores from "~/hooks/useStores";
+1 -1
View File
@@ -1,7 +1,7 @@
import { m, TargetAndTransition } from "framer-motion";
import * as React from "react";
import { mergeRefs } from "react-merge-refs";
import useComponentSize from "~/hooks/useComponentSize";
import { useComponentSize } from "@shared/hooks/useComponentSize";
type Props = {
/** The children to render */
+3 -3
View File
@@ -6,10 +6,10 @@ import styled, { css } from "styled-components";
import { isCode } from "@shared/editor/lib/isCode";
import { findParentNode } from "@shared/editor/queries/findParentNode";
import { EditorStyleHelper } from "@shared/editor/styles/EditorStyleHelper";
import { useComponentSize } from "@shared/hooks/useComponentSize";
import { depths, s } from "@shared/styles";
import { HEADER_HEIGHT } from "~/components/Header";
import { Portal } from "~/components/Portal";
import useComponentSize from "~/hooks/useComponentSize";
import useEventListener from "~/hooks/useEventListener";
import useMobile from "~/hooks/useMobile";
import useWindowSize from "~/hooks/useWindowSize";
@@ -184,10 +184,10 @@ function usePosition({
// of the selection still
const offset = left - (centerOfSelection - menuWidth / 2);
return {
left: Math.round(left - offsetParent.left),
left: Math.max(margin, Math.round(left - offsetParent.left)),
top: Math.round(top - offsetParent.top),
offset: Math.round(offset),
maxWidth: Math.min(window.innerWidth - margin * 2, offsetParent.width),
maxWidth: Math.min(window.innerWidth, offsetParent.width) - margin * 2,
blockSelection: codeBlock || isColSelection || isRowSelection,
visible: true,
};
-35
View File
@@ -1,35 +0,0 @@
import { useState, useLayoutEffect } from "react";
export default function useComponentSize(
ref: React.RefObject<HTMLElement | null>
): {
width: number;
height: number;
} {
const [size, setSize] = useState({ width: 0, height: 0 });
useLayoutEffect(() => {
const sizeObserver = new ResizeObserver((entries) => {
entries.forEach(({ target }) => {
if (
size.width !== target.clientWidth ||
size.height !== target.clientHeight
) {
setSize({ width: target.clientWidth, height: target.clientHeight });
}
});
});
if (ref.current) {
setSize({
width: ref.current?.clientWidth,
height: ref.current?.clientHeight,
});
sizeObserver.observe(ref.current);
}
return () => sizeObserver.disconnect();
}, [ref, size.height, size.width]);
return size;
}
+1 -1
View File
@@ -12,6 +12,7 @@ import { useTranslation } from "react-i18next";
import { Link } from "react-router-dom";
import styled, { useTheme } from "styled-components";
import Icon from "@shared/components/Icon";
import { useComponentSize } from "@shared/hooks/useComponentSize";
import { NavigationNode } from "@shared/types";
import { altDisplay, metaDisplay } from "@shared/utils/keyboard";
import { Theme } from "~/stores/UiStore";
@@ -31,7 +32,6 @@ import { publishDocument } from "~/actions/definitions/documents";
import { navigateToTemplateSettings } from "~/actions/definitions/navigation";
import { restoreRevision } from "~/actions/definitions/revisions";
import useActionContext from "~/hooks/useActionContext";
import useComponentSize from "~/hooks/useComponentSize";
import useCurrentTeam from "~/hooks/useCurrentTeam";
import useCurrentUser from "~/hooks/useCurrentUser";
import useEditingFocus from "~/hooks/useEditingFocus";
@@ -1,5 +1,5 @@
import * as React from "react";
import useComponentSize from "@shared/hooks/useComponentSize";
import { useComponentSize } from "@shared/hooks/useComponentSize";
export const MeasuredContainer = <T extends React.ElementType>({
as: As,
+1 -1
View File
@@ -1,5 +1,5 @@
import * as React from "react";
import useComponentSize from "../../hooks/useComponentSize";
import { useComponentSize } from "../../hooks/useComponentSize";
import Frame from "../components/Frame";
import { EmbedProps as Props } from ".";
+11 -4
View File
@@ -1,4 +1,4 @@
import { useState, useEffect } from "react";
import { useState, useLayoutEffect, useEffect } from "react";
const defaultRect = {
top: 0,
@@ -11,12 +11,19 @@ const defaultRect = {
height: 0,
};
export default function useComponentSize(
element: HTMLElement | null
/**
* A hook that returns the size of an element or ref.
*
* @param input The element or ref to observe
* @returns The size and position of the element
*/
export function useComponentSize(
input: HTMLElement | null | React.RefObject<HTMLElement | null>
): DOMRect | typeof defaultRect {
const element = input instanceof HTMLElement ? input : input?.current;
const [size, setSize] = useState(() => element?.getBoundingClientRect());
useEffect(() => {
useLayoutEffect(() => {
const sizeObserver = new ResizeObserver(() => {
element?.dispatchEvent(new CustomEvent("resize"));
});