Skip to content

Commit 50234cb

Browse files
committed
Fix deprecated use of MutableRefObject() in a browser context
1 parent 12a1f52 commit 50234cb

File tree

1 file changed

+44
-25
lines changed

1 file changed

+44
-25
lines changed

src/components/ui/coaching-sessions/coaching-notes/floating-toolbar.tsx

Lines changed: 44 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,17 @@
1-
import { useEffect, useState, useRef, useCallback, startTransition } from "react";
1+
import {
2+
useEffect,
3+
useState,
4+
useRef,
5+
useCallback,
6+
startTransition,
7+
RefObject,
8+
} from "react";
29
import { SimpleToolbar } from "./simple-toolbar";
3-
import { TOOLBAR_HEIGHT_PX, TOOLBAR_SHOW_THRESHOLD, TOOLBAR_HIDE_THRESHOLD } from "./constants";
10+
import {
11+
TOOLBAR_HEIGHT_PX,
12+
TOOLBAR_SHOW_THRESHOLD,
13+
TOOLBAR_HIDE_THRESHOLD,
14+
} from "./constants";
415

516
interface FloatingToolbarProps {
617
/** Editor container ref for scroll detection */
@@ -29,24 +40,26 @@ export const FloatingToolbar: React.FC<FloatingToolbarProps> = ({
2940
headerHeight,
3041
onOriginalToolbarVisibilityChange
3142
);
32-
43+
3344
const { floatingRef, styles } = useToolbarPositioning(editorRef, isVisible);
34-
45+
3546
useScrollEventManagement(editorRef, checkVisibility);
36-
47+
3748
return renderFloatingToolbar(floatingRef, isVisible, styles, editorRef);
3849
};
3950

4051
/** Cancels any pending debounced visibility update */
41-
const cancelDebouncedUpdate = (timerRef: React.MutableRefObject<NodeJS.Timeout | null>) => {
52+
const cancelDebouncedUpdate = (
53+
timerRef: RefObject<NodeJS.Timeout | null>
54+
) => {
4255
if (timerRef.current) {
4356
clearTimeout(timerRef.current);
4457
}
4558
};
4659

4760
/** Schedules a debounced visibility update after 10ms delay */
4861
const scheduleDebouncedUpdate = (
49-
timerRef: React.MutableRefObject<NodeJS.Timeout | null>,
62+
timerRef: React.RefObject<NodeJS.Timeout | null>,
5063
editorRef: React.RefObject<HTMLDivElement>,
5164
toolbarRef: React.RefObject<HTMLDivElement>,
5265
headerHeight: number,
@@ -146,10 +159,10 @@ const useScrollEventManagement = (
146159
useEffect(() => {
147160
// Initial visibility check
148161
onScroll();
149-
162+
150163
// Setup scroll listeners on window and scrollable parents
151164
const cleanup = setupAllScrollListeners(editorRef, onScroll);
152-
165+
153166
return cleanup;
154167
}, [editorRef, onScroll]);
155168
};
@@ -168,7 +181,7 @@ const calculateTransitionPoint = (
168181
editorTop: number,
169182
threshold: number
170183
): number => {
171-
return editorTop + (TOOLBAR_HEIGHT_PX * threshold);
184+
return editorTop + TOOLBAR_HEIGHT_PX * threshold;
172185
};
173186

174187
/** Checks if threshold point has crossed below the header */
@@ -198,12 +211,15 @@ const calculateToolbarVisibility = (
198211
const editorRect = editorRef.current.getBoundingClientRect();
199212
const threshold = selectThresholdForTransition(currentlyVisible);
200213
const thresholdPosition = calculateTransitionPoint(editorRect.top, threshold);
201-
const thresholdCrossed = hasThresholdCrossedHeader(thresholdPosition, headerHeight);
214+
const thresholdCrossed = hasThresholdCrossedHeader(
215+
thresholdPosition,
216+
headerHeight
217+
);
202218
const editorVisible = isEditorInViewport(editorRect);
203219

204220
return {
205221
shouldShow: thresholdCrossed && editorVisible,
206-
editorVisible
222+
editorVisible,
207223
};
208224
};
209225

@@ -225,14 +241,14 @@ const updateVisibilityState = (
225241

226242
const getDefaultStyles = () => ({
227243
left: "auto",
228-
right: "auto",
244+
right: "auto",
229245
width: "auto",
230246
minWidth: "auto",
231247
});
232248

233249
const calculateFloatingPosition = (editorElement: HTMLElement) => {
234250
const editorRect = editorElement.getBoundingClientRect();
235-
251+
236252
return {
237253
left: `${editorRect.left + 16}px`, // 1rem margin
238254
right: "auto",
@@ -241,45 +257,48 @@ const calculateFloatingPosition = (editorElement: HTMLElement) => {
241257
};
242258
};
243259

244-
/**
260+
/**
245261
* Sets up scroll listeners on window and all scrollable parent elements.
246262
* Tracks scroll events to update toolbar visibility when editor position changes.
247263
*/
248264
const setupAllScrollListeners = (
249265
editorRef: React.RefObject<HTMLDivElement>,
250266
onScroll: () => void
251267
): (() => void) => {
252-
const listeners: Array<{ element: Element | Window; handler: () => void }> = [];
253-
268+
const listeners: Array<{ element: Element | Window; handler: () => void }> =
269+
[];
270+
254271
// Window scroll and resize handlers
255272
const handleScroll = () => onScroll();
256273
const handleResize = () => onScroll();
257-
274+
258275
window.addEventListener("scroll", handleScroll, { passive: true });
259276
window.addEventListener("resize", handleResize, { passive: true });
260-
277+
261278
listeners.push(
262279
{ element: window, handler: handleScroll },
263280
{ element: window, handler: handleResize }
264281
);
265-
282+
266283
// Traverse up DOM tree to find scrollable containers
267284
let currentElement = editorRef.current?.parentElement;
268-
285+
269286
while (currentElement) {
270287
if (isScrollableElement(currentElement)) {
271288
const elementHandler = () => onScroll();
272-
currentElement.addEventListener("scroll", elementHandler, { passive: true });
289+
currentElement.addEventListener("scroll", elementHandler, {
290+
passive: true,
291+
});
273292
listeners.push({ element: currentElement, handler: elementHandler });
274293
}
275294
currentElement = currentElement.parentElement;
276295
}
277-
296+
278297
// Cleanup function removes all listeners
279298
return () => {
280299
window.removeEventListener("scroll", handleScroll);
281300
window.removeEventListener("resize", handleResize);
282-
301+
283302
listeners.forEach(({ element, handler }) => {
284303
if (element !== window) {
285304
element.removeEventListener("scroll", handler);
@@ -318,4 +337,4 @@ const renderFloatingToolbar = (
318337
<SimpleToolbar />
319338
</div>
320339
</div>
321-
);
340+
);

0 commit comments

Comments
 (0)