mirror of
https://github.com/Frooodle/Stirling-PDF.git
synced 2025-09-08 17:51:20 +02:00
utils/clickHandlers
This commit is contained in:
parent
4e703bef34
commit
90451f7172
@ -5,6 +5,7 @@ import { Tooltip } from './Tooltip';
|
|||||||
import AppsIcon from '@mui/icons-material/AppsRounded';
|
import AppsIcon from '@mui/icons-material/AppsRounded';
|
||||||
import { useToolWorkflow } from '../../contexts/ToolWorkflowContext';
|
import { useToolWorkflow } from '../../contexts/ToolWorkflowContext';
|
||||||
import { useSidebarNavigation } from '../../hooks/useSidebarNavigation';
|
import { useSidebarNavigation } from '../../hooks/useSidebarNavigation';
|
||||||
|
import { handleUnlessSpecialClick } from '../../utils/clickHandlers';
|
||||||
|
|
||||||
interface AllToolsNavButtonProps {
|
interface AllToolsNavButtonProps {
|
||||||
activeButton: string;
|
activeButton: string;
|
||||||
@ -29,14 +30,7 @@ const AllToolsNavButton: React.FC<AllToolsNavButtonProps> = ({ activeButton, set
|
|||||||
const navProps = getHomeNavigation();
|
const navProps = getHomeNavigation();
|
||||||
|
|
||||||
const handleNavClick = (e: React.MouseEvent) => {
|
const handleNavClick = (e: React.MouseEvent) => {
|
||||||
// Check if it's a special click (middle click, ctrl+click, etc.)
|
handleUnlessSpecialClick(e, handleClick);
|
||||||
if (e.metaKey || e.ctrlKey || e.shiftKey || e.button === 1) {
|
|
||||||
return; // Let browser handle it via href
|
|
||||||
}
|
|
||||||
|
|
||||||
// For regular clicks, prevent default and use SPA navigation
|
|
||||||
e.preventDefault();
|
|
||||||
handleClick();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const iconNode = (
|
const iconNode = (
|
||||||
|
@ -8,6 +8,7 @@ import { useIsOverflowing } from '../../hooks/useIsOverflowing';
|
|||||||
import { useFilesModalContext } from '../../contexts/FilesModalContext';
|
import { useFilesModalContext } from '../../contexts/FilesModalContext';
|
||||||
import { useToolWorkflow } from '../../contexts/ToolWorkflowContext';
|
import { useToolWorkflow } from '../../contexts/ToolWorkflowContext';
|
||||||
import { useSidebarNavigation } from '../../hooks/useSidebarNavigation';
|
import { useSidebarNavigation } from '../../hooks/useSidebarNavigation';
|
||||||
|
import { handleUnlessSpecialClick } from '../../utils/clickHandlers';
|
||||||
import { ButtonConfig } from '../../types/sidebar';
|
import { ButtonConfig } from '../../types/sidebar';
|
||||||
import './quickAccessBar/QuickAccessBar.css';
|
import './quickAccessBar/QuickAccessBar.css';
|
||||||
import AllToolsNavButton from './AllToolsNavButton';
|
import AllToolsNavButton from './AllToolsNavButton';
|
||||||
@ -50,14 +51,10 @@ const QuickAccessBar = forwardRef<HTMLDivElement>(({
|
|||||||
|
|
||||||
const handleClick = (e?: React.MouseEvent) => {
|
const handleClick = (e?: React.MouseEvent) => {
|
||||||
if (navProps && e) {
|
if (navProps && e) {
|
||||||
// Check if it's a special click (middle click, ctrl+click, etc.)
|
handleUnlessSpecialClick(e, config.onClick);
|
||||||
if (e.metaKey || e.ctrlKey || e.shiftKey || e.button === 1) {
|
} else {
|
||||||
return; // Let browser handle it via href
|
config.onClick();
|
||||||
}
|
|
||||||
// For regular clicks, prevent default and use SPA navigation
|
|
||||||
e.preventDefault();
|
|
||||||
}
|
}
|
||||||
config.onClick();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Render with URL navigation if available, otherwise regular div
|
// Render with URL navigation if available, otherwise regular div
|
||||||
|
@ -17,6 +17,7 @@ import { ActionIcon } from '@mantine/core';
|
|||||||
import ArrowBackRoundedIcon from '@mui/icons-material/ArrowBackRounded';
|
import ArrowBackRoundedIcon from '@mui/icons-material/ArrowBackRounded';
|
||||||
import { useToolWorkflow } from '../../../contexts/ToolWorkflowContext';
|
import { useToolWorkflow } from '../../../contexts/ToolWorkflowContext';
|
||||||
import { useSidebarNavigation } from '../../../hooks/useSidebarNavigation';
|
import { useSidebarNavigation } from '../../../hooks/useSidebarNavigation';
|
||||||
|
import { handleUnlessSpecialClick } from '../../../utils/clickHandlers';
|
||||||
import FitText from '../FitText';
|
import FitText from '../FitText';
|
||||||
import { Tooltip } from '../Tooltip';
|
import { Tooltip } from '../Tooltip';
|
||||||
|
|
||||||
@ -147,15 +148,10 @@ const ActiveToolButton: React.FC<ActiveToolButtonProps> = ({ activeButton, setAc
|
|||||||
component="a"
|
component="a"
|
||||||
href={getHomeNavigation().href}
|
href={getHomeNavigation().href}
|
||||||
onClick={(e: React.MouseEvent) => {
|
onClick={(e: React.MouseEvent) => {
|
||||||
// Check if it's a special click (middle click, ctrl+click, etc.)
|
handleUnlessSpecialClick(e, () => {
|
||||||
if (e.metaKey || e.ctrlKey || e.shiftKey || e.button === 1) {
|
setActiveButton('tools');
|
||||||
return; // Let browser handle it via href
|
handleBackToTools();
|
||||||
}
|
});
|
||||||
|
|
||||||
// For regular clicks, prevent default and use SPA navigation
|
|
||||||
e.preventDefault();
|
|
||||||
setActiveButton('tools');
|
|
||||||
handleBackToTools();
|
|
||||||
}}
|
}}
|
||||||
size={'xl'}
|
size={'xl'}
|
||||||
variant="subtle"
|
variant="subtle"
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import { Button, Anchor } from "@mantine/core";
|
import { Button } from "@mantine/core";
|
||||||
import { Tooltip } from "../../shared/Tooltip";
|
import { Tooltip } from "../../shared/Tooltip";
|
||||||
import { ToolRegistryEntry } from "../../../data/toolsTaxonomy";
|
import { ToolRegistryEntry } from "../../../data/toolsTaxonomy";
|
||||||
import { useToolNavigation } from "../../../hooks/useToolNavigation";
|
import { useToolNavigation } from "../../../hooks/useToolNavigation";
|
||||||
|
import { handleUnlessSpecialClick } from "../../../utils/clickHandlers";
|
||||||
import FitText from "../../shared/FitText";
|
import FitText from "../../shared/FitText";
|
||||||
|
|
||||||
interface ToolButtonProps {
|
interface ToolButtonProps {
|
||||||
@ -49,14 +50,7 @@ const ToolButton: React.FC<ToolButtonProps> = ({ id, tool, isSelected, onSelect
|
|||||||
);
|
);
|
||||||
|
|
||||||
const handleExternalClick = (e: React.MouseEvent) => {
|
const handleExternalClick = (e: React.MouseEvent) => {
|
||||||
// Check if it's a special click (ctrl+click, etc.)
|
handleUnlessSpecialClick(e, () => handleClick(id));
|
||||||
if (e.metaKey || e.ctrlKey || e.shiftKey) {
|
|
||||||
return; // Let browser handle it via href
|
|
||||||
}
|
|
||||||
|
|
||||||
// For regular clicks, prevent default and use window.open
|
|
||||||
e.preventDefault();
|
|
||||||
handleClick(id);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const buttonElement = navProps ? (
|
const buttonElement = navProps ? (
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import { useCallback } from 'react';
|
import { useCallback } from 'react';
|
||||||
import { useToolNavigation } from './useToolNavigation';
|
import { useToolNavigation } from './useToolNavigation';
|
||||||
import { useToolManagement } from './useToolManagement';
|
import { useToolManagement } from './useToolManagement';
|
||||||
|
import { handleUnlessSpecialClick } from '../utils/clickHandlers';
|
||||||
|
|
||||||
export interface SidebarNavigationProps {
|
export interface SidebarNavigationProps {
|
||||||
/** Full URL for the navigation (for href attribute) */
|
/** Full URL for the navigation (for href attribute) */
|
||||||
@ -21,8 +22,9 @@ export function useSidebarNavigation(): {
|
|||||||
const { getSelectedTool } = useToolManagement();
|
const { getSelectedTool } = useToolManagement();
|
||||||
|
|
||||||
const defaultNavClick = useCallback((e: React.MouseEvent) => {
|
const defaultNavClick = useCallback((e: React.MouseEvent) => {
|
||||||
if (e.metaKey || e.ctrlKey || e.shiftKey) return;
|
handleUnlessSpecialClick(e, () => {
|
||||||
e.preventDefault();
|
// SPA navigation will be handled by the calling component
|
||||||
|
});
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const getHomeNavigation = useCallback((): SidebarNavigationProps => {
|
const getHomeNavigation = useCallback((): SidebarNavigationProps => {
|
||||||
|
@ -2,6 +2,7 @@ import { useCallback } from 'react';
|
|||||||
import { ToolId } from '../types/toolId';
|
import { ToolId } from '../types/toolId';
|
||||||
import { ToolRegistryEntry, getToolUrlPath } from '../data/toolsTaxonomy';
|
import { ToolRegistryEntry, getToolUrlPath } from '../data/toolsTaxonomy';
|
||||||
import { useToolWorkflow } from '../contexts/ToolWorkflowContext';
|
import { useToolWorkflow } from '../contexts/ToolWorkflowContext';
|
||||||
|
import { handleUnlessSpecialClick } from '../utils/clickHandlers';
|
||||||
|
|
||||||
export interface ToolNavigationProps {
|
export interface ToolNavigationProps {
|
||||||
/** Full URL for the tool (for href attribute) */
|
/** Full URL for the tool (for href attribute) */
|
||||||
@ -26,20 +27,16 @@ export function useToolNavigation(): {
|
|||||||
|
|
||||||
// Click handler that maintains SPA behavior
|
// Click handler that maintains SPA behavior
|
||||||
const onClick = (e: React.MouseEvent) => {
|
const onClick = (e: React.MouseEvent) => {
|
||||||
// Check if it's a special click (ctrl+click, etc.)
|
handleUnlessSpecialClick(e, () => {
|
||||||
if (e.metaKey || e.ctrlKey || e.shiftKey) {
|
// Handle external links normally
|
||||||
return; // Let browser handle it via href
|
if (tool.link) {
|
||||||
}
|
window.open(tool.link, '_blank', 'noopener,noreferrer');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Handle external links normally
|
// Use SPA navigation for internal tools
|
||||||
if (tool.link) {
|
handleToolSelect(toolId);
|
||||||
window.open(tool.link, '_blank', 'noopener,noreferrer');
|
});
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// For regular clicks, prevent default and use SPA navigation
|
|
||||||
e.preventDefault();
|
|
||||||
handleToolSelect(toolId);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return { href, onClick };
|
return { href, onClick };
|
||||||
|
31
frontend/src/utils/clickHandlers.ts
Normal file
31
frontend/src/utils/clickHandlers.ts
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
/**
|
||||||
|
* Utility functions for handling click events in navigation components
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines if a click event is a "special" click that should use browser's default navigation
|
||||||
|
* instead of SPA navigation. Special clicks include:
|
||||||
|
* - Ctrl+click (or Cmd+click on Mac)
|
||||||
|
* - Shift+click
|
||||||
|
* - Middle mouse button click
|
||||||
|
*/
|
||||||
|
export function isSpecialClick(e: React.MouseEvent): boolean {
|
||||||
|
return e.metaKey || e.ctrlKey || e.shiftKey || e.button === 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles a click event for SPA navigation, but allows special clicks to use browser defaults
|
||||||
|
*
|
||||||
|
* @param e - The click event
|
||||||
|
* @param handleClick - Function to execute for regular clicks (SPA navigation)
|
||||||
|
* @returns true if the event was handled as a special click, false if it was handled as regular click
|
||||||
|
*/
|
||||||
|
export function handleUnlessSpecialClick(e: React.MouseEvent, handleClick: () => void): boolean {
|
||||||
|
if (isSpecialClick(e)) {
|
||||||
|
return true; // Let browser handle via href
|
||||||
|
}
|
||||||
|
|
||||||
|
e.preventDefault();
|
||||||
|
handleClick();
|
||||||
|
return false;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user