Skip to content

Commit 4af2b03

Browse files
authored
fix: New comments are measured incorrectly (outline#8838)
* fix: New comments are measured incorrectly * Remove defaultRect so we can always return a DOMRect
1 parent c52d9a8 commit 4af2b03

3 files changed

Lines changed: 26 additions & 29 deletions

File tree

app/components/Fade.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@ import React from "react";
22
import styled from "styled-components";
33
import { fadeIn } from "~/styles/animations";
44

5+
/**
6+
* Fade in animation for a component.
7+
*
8+
* @param timing - The duration of the fade in animation, default is 250ms.
9+
*/
510
const Fade = styled.span<{ timing?: number | string }>`
611
animation: ${fadeIn} ${(props) => props.timing || "250ms"} ease-in-out;
712
`;
@@ -17,7 +22,6 @@ type Props = {
1722
*/
1823
export const ConditionalFade = ({ animate, children }: Props) => {
1924
const [isAnimated] = React.useState(animate);
20-
2125
return isAnimated ? <Fade>{children}</Fade> : <>{children}</>;
2226
};
2327

app/scenes/Document/components/CommentThread.tsx

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import { useDocumentContext } from "~/components/DocumentContext";
1616
import Facepile from "~/components/Facepile";
1717
import Fade from "~/components/Fade";
1818
import { ResizingHeightContainer } from "~/components/ResizingHeightContainer";
19+
import useBoolean from "~/hooks/useBoolean";
1920
import { useLocationSidebarContext } from "~/hooks/useLocationSidebarContext";
2021
import useOnClickOutside from "~/hooks/useOnClickOutside";
2122
import usePersistedState from "~/hooks/usePersistedState";
@@ -63,7 +64,7 @@ function CommentThread({
6364
const history = useHistory();
6465
const location = useLocation();
6566
const sidebarContext = useLocationSidebarContext();
66-
const [autoFocus, setAutoFocus] = React.useState(thread.isNew);
67+
const [autoFocus, setAutoFocusOn, setAutoFocusOff] = useBoolean(thread.isNew);
6768

6869
const can = usePolicy(document);
6970

@@ -156,9 +157,9 @@ function CommentThread({
156157

157158
React.useEffect(() => {
158159
if (!focused && autoFocus) {
159-
setAutoFocus(false);
160+
setAutoFocusOff();
160161
}
161-
}, [focused, autoFocus]);
162+
}, [focused, autoFocus, setAutoFocusOff]);
162163

163164
React.useEffect(() => {
164165
if (focused) {
@@ -273,7 +274,7 @@ function CommentThread({
273274
)}
274275
</ResizingHeightContainer>
275276
{!focused && !recessed && !draft && canReply && (
276-
<Reply onClick={() => setAutoFocus(true)}>{t("Reply")}</Reply>
277+
<Reply onClick={setAutoFocusOn}>{t("Reply")}</Reply>
277278
)}
278279
</Thread>
279280
);

shared/hooks/useComponentSize.ts

Lines changed: 16 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,5 @@
11
import { useState, useLayoutEffect } from "react";
22

3-
const defaultRect = {
4-
top: 0,
5-
left: 0,
6-
bottom: 0,
7-
right: 0,
8-
x: 0,
9-
y: 0,
10-
width: 0,
11-
height: 0,
12-
};
13-
143
/**
154
* A hook that returns the size of an element or ref.
165
*
@@ -19,19 +8,11 @@ const defaultRect = {
198
*/
209
export function useComponentSize(
2110
input: HTMLElement | null | React.RefObject<HTMLElement | null>
22-
): DOMRect | typeof defaultRect {
11+
) {
2312
const element = input instanceof HTMLElement ? input : input?.current;
24-
const [size, setSize] = useState(() => element?.getBoundingClientRect());
25-
26-
useLayoutEffect(() => {
27-
const sizeObserver = new ResizeObserver(() => {
28-
element?.dispatchEvent(new CustomEvent("resize"));
29-
});
30-
if (element) {
31-
sizeObserver.observe(element);
32-
}
33-
return () => sizeObserver.disconnect();
34-
}, [element]);
13+
const [size, setSize] = useState<DOMRect | undefined>(
14+
() => element?.getBoundingClientRect() || new DOMRect()
15+
);
3516

3617
useLayoutEffect(() => {
3718
const handleResize = () => {
@@ -55,6 +36,7 @@ export function useComponentSize(
5536
window.addEventListener("click", handleResize);
5637
window.addEventListener("resize", handleResize);
5738
element?.addEventListener("resize", handleResize);
39+
handleResize();
5840

5941
return () => {
6042
window.removeEventListener("click", handleResize);
@@ -63,5 +45,15 @@ export function useComponentSize(
6345
};
6446
});
6547

66-
return size ?? defaultRect;
48+
useLayoutEffect(() => {
49+
const sizeObserver = new ResizeObserver(() => {
50+
element?.dispatchEvent(new CustomEvent("resize"));
51+
});
52+
if (element) {
53+
sizeObserver.observe(element);
54+
}
55+
return () => sizeObserver.disconnect();
56+
}, [element]);
57+
58+
return size ?? new DOMRect();
6759
}

0 commit comments

Comments
 (0)