From c4e73af82b5a4fe01e77efaca75b2d94b8af1831 Mon Sep 17 00:00:00 2001 From: EthanHealy01 Date: Thu, 7 Aug 2025 13:56:35 +0100 Subject: [PATCH] final clean ups --- .../shared/{tooltip => }/Tooltip.tsx | 8 +- .../src/components/tools/shared/ToolStep.tsx | 3 +- frontend/src/hooks/useTooltipPosition.ts | 3 +- frontend/src/utils/domUtils.ts | 92 ------------------- frontend/src/utils/genericUtils.ts | 42 +++++++++ frontend/src/utils/sidebarUtils.ts | 50 ++++++++++ 6 files changed, 100 insertions(+), 98 deletions(-) rename frontend/src/components/shared/{tooltip => }/Tooltip.tsx (96%) delete mode 100644 frontend/src/utils/domUtils.ts create mode 100644 frontend/src/utils/genericUtils.ts create mode 100644 frontend/src/utils/sidebarUtils.ts diff --git a/frontend/src/components/shared/tooltip/Tooltip.tsx b/frontend/src/components/shared/Tooltip.tsx similarity index 96% rename from frontend/src/components/shared/tooltip/Tooltip.tsx rename to frontend/src/components/shared/Tooltip.tsx index 7f82f07c4..38060a300 100644 --- a/frontend/src/components/shared/tooltip/Tooltip.tsx +++ b/frontend/src/components/shared/Tooltip.tsx @@ -1,9 +1,9 @@ import React, { useState, useRef, useEffect } from 'react'; import { createPortal } from 'react-dom'; -import { isClickOutside, addEventListenerWithCleanup } from '../../../utils/domUtils'; -import { useTooltipPosition } from '../../../hooks/useTooltipPosition'; -import { TooltipContent, TooltipTip } from './TooltipContent'; -import styles from './Tooltip.module.css'; +import { isClickOutside, addEventListenerWithCleanup } from '../../utils/genericUtils'; +import { useTooltipPosition } from '../../hooks/useTooltipPosition'; +import { TooltipContent, TooltipTip } from './tooltip/TooltipContent'; +import styles from './tooltip/Tooltip.module.css' export interface TooltipProps { sidebarTooltip?: boolean; diff --git a/frontend/src/components/tools/shared/ToolStep.tsx b/frontend/src/components/tools/shared/ToolStep.tsx index f1eb9a2b1..5ae6aec9b 100644 --- a/frontend/src/components/tools/shared/ToolStep.tsx +++ b/frontend/src/components/tools/shared/ToolStep.tsx @@ -2,7 +2,8 @@ import React, { createContext, useContext, useMemo, useRef } from 'react'; import { Paper, Text, Stack, Box, Flex } from '@mantine/core'; import ExpandMoreIcon from '@mui/icons-material/ExpandMore'; import ChevronRightIcon from '@mui/icons-material/ChevronRight'; -import { Tooltip, TooltipTip } from '../../shared/tooltip/Tooltip'; +import { Tooltip } from '../../shared/Tooltip'; +import { TooltipTip } from '../../shared/tooltip/TooltipContent'; interface ToolStepContextType { visibleStepCount: number; diff --git a/frontend/src/hooks/useTooltipPosition.ts b/frontend/src/hooks/useTooltipPosition.ts index cd293ded4..680db614c 100644 --- a/frontend/src/hooks/useTooltipPosition.ts +++ b/frontend/src/hooks/useTooltipPosition.ts @@ -1,5 +1,6 @@ import { useState, useEffect, useMemo } from 'react'; -import { clamp, getSidebarRect } from '../utils/domUtils'; +import { clamp } from '../utils/genericUtils'; +import { getSidebarRect } from '../utils/sidebarUtils'; type Position = 'right' | 'left' | 'top' | 'bottom'; diff --git a/frontend/src/utils/domUtils.ts b/frontend/src/utils/domUtils.ts deleted file mode 100644 index 7ec180985..000000000 --- a/frontend/src/utils/domUtils.ts +++ /dev/null @@ -1,92 +0,0 @@ -/** - * DOM utility functions for common operations - */ - -/** - * Clamps a value between a minimum and maximum - * @param value - The value to clamp - * @param min - The minimum allowed value - * @param max - The maximum allowed value - * @returns The clamped value - */ -export function clamp(value: number, min: number, max: number): number { - return Math.min(Math.max(value, min), max); -} - -/** - * Safely adds an event listener with proper cleanup - * @param target - The target element or window/document - * @param event - The event type - * @param handler - The event handler function - * @param options - Event listener options - * @returns A cleanup function to remove the listener - */ -export function addEventListenerWithCleanup( - target: EventTarget, - event: string, - handler: EventListener, - options?: boolean | AddEventListenerOptions -): () => void { - target.addEventListener(event, handler, options); - return () => target.removeEventListener(event, handler, options); -} - -/** - * Checks if a click event occurred outside of a specified element - * @param event - The click event - * @param element - The element to check against - * @returns True if the click was outside the element - */ -export function isClickOutside(event: MouseEvent, element: HTMLElement | null): boolean { - return element ? !element.contains(event.target as Node) : true; -} - -/** - * Gets the All tools sidebar - * @returns Object containing the sidebar rect and whether it's the correct sidebar - */ -export function getSidebarRect(): { rect: DOMRect | null, isCorrectSidebar: boolean } { - // Find the rightmost sidebar - this will be the "All Tools" expanded panel - const allSidebars = []; - - // Find the QuickAccessBar (narrow left bar) - const quickAccessBar = document.querySelector('[data-sidebar="quick-access"]'); - if (quickAccessBar) { - const rect = quickAccessBar.getBoundingClientRect(); - if (rect.width > 0) { - allSidebars.push({ - element: 'QuickAccessBar', - selector: '[data-sidebar="quick-access"]', - rect - }); - } - } - - // Find the tool panel (the expanded "All Tools" panel) - const toolPanel = document.querySelector('[data-sidebar="tool-panel"]'); - if (toolPanel) { - const rect = toolPanel.getBoundingClientRect(); - if (rect.width > 0) { - allSidebars.push({ - element: 'ToolPanel', - selector: '[data-sidebar="tool-panel"]', - rect - }); - } - } - - // Use the rightmost sidebar (which should be the tool panel when expanded) - if (allSidebars.length > 0) { - const rightmostSidebar = allSidebars.reduce((rightmost, current) => { - return current.rect.right > rightmost.rect.right ? current : rightmost; - }); - - // Only consider it correct if we're using the ToolPanel (expanded All Tools sidebar) - const isCorrectSidebar = rightmostSidebar.element === 'ToolPanel'; - return { rect: rightmostSidebar.rect, isCorrectSidebar }; - } - - console.warn('⚠️ No sidebars found, using fallback positioning'); - // Final fallback - return { rect: new DOMRect(0, 0, 280, window.innerHeight), isCorrectSidebar: false }; -} \ No newline at end of file diff --git a/frontend/src/utils/genericUtils.ts b/frontend/src/utils/genericUtils.ts new file mode 100644 index 000000000..253346292 --- /dev/null +++ b/frontend/src/utils/genericUtils.ts @@ -0,0 +1,42 @@ +/** + * DOM utility functions for common operations + */ + +/** + * Clamps a value between a minimum and maximum + * @param value - The value to clamp + * @param min - The minimum allowed value + * @param max - The maximum allowed value + * @returns The clamped value + */ +export function clamp(value: number, min: number, max: number): number { + return Math.min(Math.max(value, min), max); +} + +/** + * Safely adds an event listener with proper cleanup + * @param target - The target element or window/document + * @param event - The event type + * @param handler - The event handler function + * @param options - Event listener options + * @returns A cleanup function to remove the listener + */ +export function addEventListenerWithCleanup( + target: EventTarget, + event: string, + handler: EventListener, + options?: boolean | AddEventListenerOptions +): () => void { + target.addEventListener(event, handler, options); + return () => target.removeEventListener(event, handler, options); +} + +/** + * Checks if a click event occurred outside of a specified element + * @param event - The click event + * @param element - The element to check against + * @returns True if the click was outside the element + */ +export function isClickOutside(event: MouseEvent, element: HTMLElement | null): boolean { + return element ? !element.contains(event.target as Node) : true; +} diff --git a/frontend/src/utils/sidebarUtils.ts b/frontend/src/utils/sidebarUtils.ts new file mode 100644 index 000000000..0c17b0876 --- /dev/null +++ b/frontend/src/utils/sidebarUtils.ts @@ -0,0 +1,50 @@ + +/** + * Gets the All tools sidebar + * @returns Object containing the sidebar rect and whether it's the correct sidebar + */ +export function getSidebarRect(): { rect: DOMRect | null, isCorrectSidebar: boolean } { + // Find the rightmost sidebar - this will be the "All Tools" expanded panel + const allSidebars = []; + + // Find the QuickAccessBar (narrow left bar) + const quickAccessBar = document.querySelector('[data-sidebar="quick-access"]'); + if (quickAccessBar) { + const rect = quickAccessBar.getBoundingClientRect(); + if (rect.width > 0) { + allSidebars.push({ + element: 'QuickAccessBar', + selector: '[data-sidebar="quick-access"]', + rect + }); + } + } + + // Find the tool panel (the expanded "All Tools" panel) + const toolPanel = document.querySelector('[data-sidebar="tool-panel"]'); + if (toolPanel) { + const rect = toolPanel.getBoundingClientRect(); + if (rect.width > 0) { + allSidebars.push({ + element: 'ToolPanel', + selector: '[data-sidebar="tool-panel"]', + rect + }); + } + } + + // Use the rightmost sidebar (which should be the tool panel when expanded) + if (allSidebars.length > 0) { + const rightmostSidebar = allSidebars.reduce((rightmost, current) => { + return current.rect.right > rightmost.rect.right ? current : rightmost; + }); + + // Only consider it correct if we're using the ToolPanel (expanded All Tools sidebar) + const isCorrectSidebar = rightmostSidebar.element === 'ToolPanel'; + return { rect: rightmostSidebar.rect, isCorrectSidebar }; + } + + console.warn('⚠️ No sidebars found, using fallback positioning'); + // Final fallback + return { rect: new DOMRect(0, 0, 280, window.innerHeight), isCorrectSidebar: false }; + } \ No newline at end of file