From 3ad837891d584135874ee5655cb069f1b39c645f Mon Sep 17 00:00:00 2001 From: EthanHealy01 Date: Fri, 10 Oct 2025 15:04:53 +0100 Subject: [PATCH] change expand and collapse icon and fix tooltip bug --- frontend/src/components/shared/Tooltip.tsx | 29 +++++++++++++------ .../tools/FullscreenToolSurface.tsx | 10 ++++--- frontend/src/components/tools/ToolPanel.tsx | 25 +++++----------- 3 files changed, 34 insertions(+), 30 deletions(-) diff --git a/frontend/src/components/shared/Tooltip.tsx b/frontend/src/components/shared/Tooltip.tsx index b5cbab947..775cbbee1 100644 --- a/frontend/src/components/shared/Tooltip.tsx +++ b/frontend/src/components/shared/Tooltip.tsx @@ -29,6 +29,10 @@ export interface TooltipProps { pinOnClick?: boolean; /** If true, clicking outside also closes when not pinned (default true) */ closeOnOutside?: boolean; + /** If true, tooltip interaction is disabled entirely */ + disabled?: boolean; + /** If false, tooltip will not open on focus (hover only) */ + openOnFocus?: boolean; } export const Tooltip: React.FC = ({ @@ -49,6 +53,8 @@ export const Tooltip: React.FC = ({ containerStyle = {}, pinOnClick = false, closeOnOutside = true, + disabled = false, + openOnFocus = true, }) => { const [internalOpen, setInternalOpen] = useState(false); const [isPinned, setIsPinned] = useState(false); @@ -69,7 +75,7 @@ export const Tooltip: React.FC = ({ const sidebarContext = sidebarTooltip ? useSidebarContext() : null; const isControlled = controlledOpen !== undefined; - const open = isControlled ? !!controlledOpen : internalOpen; + const open = (isControlled ? !!controlledOpen : internalOpen) && !disabled; const setOpen = useCallback( (newOpen: boolean) => { @@ -149,15 +155,16 @@ export const Tooltip: React.FC = ({ // === Trigger handlers === const openWithDelay = useCallback(() => { clearTimers(); + if (disabled) return; openTimeoutRef.current = setTimeout(() => setOpen(true), Math.max(0, delay || 0)); - }, [clearTimers, setOpen, delay]); + }, [clearTimers, setOpen, delay, disabled]); const handlePointerEnter = useCallback( (e: React.PointerEvent) => { - if (!isPinned) openWithDelay(); + if (!isPinned && !disabled) openWithDelay(); (children.props as any)?.onPointerEnter?.(e); }, - [isPinned, openWithDelay, children.props] + [isPinned, openWithDelay, children.props, disabled] ); const handlePointerLeave = useCallback( @@ -220,10 +227,10 @@ export const Tooltip: React.FC = ({ // Keyboard / focus accessibility const handleFocus = useCallback( (e: React.FocusEvent) => { - if (!isPinned) openWithDelay(); + if (!isPinned && !disabled && openOnFocus) openWithDelay(); (children.props as any)?.onFocus?.(e); }, - [isPinned, openWithDelay, children.props] + [isPinned, openWithDelay, children.props, disabled, openOnFocus] ); const handleBlur = useCallback( @@ -346,9 +353,13 @@ export const Tooltip: React.FC = ({ return ( <> {childWithHandlers} - {portalTarget && document.body.contains(portalTarget) - ? tooltipElement && createPortal(tooltipElement, portalTarget) - : tooltipElement} + {(() => { + const defaultTarget = typeof document !== 'undefined' ? document.body : null; + const target = portalTarget ?? defaultTarget; + return tooltipElement && target + ? createPortal(tooltipElement, target) + : tooltipElement; + })()} ); }; diff --git a/frontend/src/components/tools/FullscreenToolSurface.tsx b/frontend/src/components/tools/FullscreenToolSurface.tsx index 1f0f9d95b..69b3c205d 100644 --- a/frontend/src/components/tools/FullscreenToolSurface.tsx +++ b/frontend/src/components/tools/FullscreenToolSurface.tsx @@ -1,6 +1,6 @@ import { useState, useRef } from 'react'; -import { ActionIcon, ScrollArea, Switch, Tooltip, useMantineColorScheme } from '@mantine/core'; -import ViewSidebarRoundedIcon from '@mui/icons-material/ViewSidebarRounded'; +import { ActionIcon, ScrollArea, Switch, useMantineColorScheme } from '@mantine/core'; +import DoubleArrowIcon from '@mui/icons-material/DoubleArrow'; import { useTranslation } from 'react-i18next'; import ToolSearch from './toolPicker/ToolSearch'; import FullscreenToolList from './FullscreenToolList'; @@ -8,8 +8,10 @@ import { ToolRegistryEntry } from '../../data/toolsTaxonomy'; import { ToolId } from '../../types/toolId'; import { useFocusTrap } from '../../hooks/useFocusTrap'; import { BASE_PATH } from '../../constants/app'; +import { Tooltip } from '../shared/Tooltip'; import './ToolPanel.css'; import { ToolPanelGeometry } from '../../hooks/tools/useToolPanelGeometry'; +import { Z_INDEX_OVER_FULLSCREEN_SURFACE } from '../../styles/zIndex'; interface FullscreenToolSurfaceProps { searchQuery: string; @@ -103,7 +105,7 @@ const FullscreenToolSurface = ({ {brandAltText}
- + - +
diff --git a/frontend/src/components/tools/ToolPanel.tsx b/frontend/src/components/tools/ToolPanel.tsx index 6e54199a5..88089df5d 100644 --- a/frontend/src/components/tools/ToolPanel.tsx +++ b/frontend/src/components/tools/ToolPanel.tsx @@ -7,18 +7,17 @@ import ToolRenderer from './ToolRenderer'; import ToolSearch from './toolPicker/ToolSearch'; import { useSidebarContext } from "../../contexts/SidebarContext"; import rainbowStyles from '../../styles/rainbow.module.css'; -import { ActionIcon, ScrollArea, Tooltip } from '@mantine/core'; +import { ActionIcon, ScrollArea } from '@mantine/core'; import { ToolId } from '../../types/toolId'; import { useMediaQuery } from '@mantine/hooks'; -import ViewSidebarRoundedIcon from '@mui/icons-material/ViewSidebarRounded'; -import DashboardCustomizeRoundedIcon from '@mui/icons-material/DashboardCustomizeRounded'; +import DoubleArrowIcon from '@mui/icons-material/DoubleArrow'; import { useTranslation } from 'react-i18next'; import FullscreenToolSurface from './FullscreenToolSurface'; import { useToolPanelGeometry } from '../../hooks/tools/useToolPanelGeometry'; import { useLocalStorageState } from '../../hooks/tools/useJsonLocalStorageState'; import { useRightRail } from '../../contexts/RightRailContext'; +import { Tooltip } from '../shared/Tooltip'; import './ToolPanel.css'; -import { Z_INDEX_OVER_FULLSCREEN_SURFACE } from '../../styles/zIndex'; // No props needed - component uses context @@ -138,14 +137,10 @@ export default function ToolPanel() { /> {!isMobile && leftPanelView === 'toolPicker' && ( - {isFullscreenMode ? ( - - ) : ( - - )} + )}