Left menu and chip links (#12294)
Small optimization for faster loading (gaining ~80ms - average time of a click) It might seem a little over-engineered but there are a lot of edge cases and I couldn't find a simpler solution I also tried to tackle Link Chips but it's more complex so this will be for another PR
This commit is contained in:
@ -0,0 +1,71 @@
|
||||
import { isNavigationModifierPressed } from '@ui/utilities/navigation/isNavigationModifierPressed';
|
||||
import { TriggerEventType } from '@ui/utilities/navigation/types/trigger-event.type';
|
||||
import { MouseEvent } from 'react';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
type UseMouseDownNavigationProps = {
|
||||
to?: string;
|
||||
onClick?: (event: MouseEvent<HTMLElement>) => void;
|
||||
disabled?: boolean;
|
||||
onBeforeNavigation?: () => void;
|
||||
triggerEvent?: TriggerEventType;
|
||||
stopPropagation?: boolean;
|
||||
};
|
||||
|
||||
export const useMouseDownNavigation = ({
|
||||
to,
|
||||
onClick,
|
||||
disabled = false,
|
||||
onBeforeNavigation,
|
||||
triggerEvent = 'MOUSE_DOWN',
|
||||
}: UseMouseDownNavigationProps) => {
|
||||
const navigate = useNavigate();
|
||||
|
||||
const handleClick = (event: MouseEvent<HTMLElement>) => {
|
||||
if (disabled) return;
|
||||
|
||||
// For modifier keys, let the default browser behavior handle it
|
||||
if (isNavigationModifierPressed(event)) {
|
||||
onBeforeNavigation?.();
|
||||
if (isDefined(onClick) && !isDefined(to)) {
|
||||
onClick(event);
|
||||
}
|
||||
// Don't prevent default for modifier keys to allow browser navigation
|
||||
return;
|
||||
}
|
||||
|
||||
if (triggerEvent === 'CLICK') {
|
||||
onBeforeNavigation?.();
|
||||
if (isDefined(onClick)) {
|
||||
onClick(event);
|
||||
} else if (isDefined(to)) {
|
||||
navigate(to);
|
||||
}
|
||||
}
|
||||
|
||||
// For regular clicks, prevent default to avoid double navigation
|
||||
event.preventDefault();
|
||||
};
|
||||
|
||||
const handleMouseDown = (event: MouseEvent<HTMLElement>) => {
|
||||
if (disabled || triggerEvent === 'CLICK') return;
|
||||
|
||||
if (isNavigationModifierPressed(event)) {
|
||||
return;
|
||||
}
|
||||
|
||||
onBeforeNavigation?.();
|
||||
|
||||
if (isDefined(onClick)) {
|
||||
onClick(event);
|
||||
} else if (isDefined(to)) {
|
||||
navigate(to);
|
||||
}
|
||||
};
|
||||
|
||||
return {
|
||||
onClick: handleClick,
|
||||
onMouseDown: handleMouseDown,
|
||||
};
|
||||
};
|
||||
@ -0,0 +1,16 @@
|
||||
type LimitedMouseEvent = Pick<
|
||||
MouseEvent,
|
||||
'button' | 'metaKey' | 'altKey' | 'ctrlKey' | 'shiftKey'
|
||||
>;
|
||||
|
||||
export const isNavigationModifierPressed = ({
|
||||
altKey,
|
||||
ctrlKey,
|
||||
shiftKey,
|
||||
metaKey,
|
||||
button,
|
||||
}: LimitedMouseEvent) => {
|
||||
const pressedKey = [altKey, ctrlKey, shiftKey, metaKey].some((key) => key);
|
||||
const isLeftClick = button === 0;
|
||||
return pressedKey || !isLeftClick;
|
||||
};
|
||||
@ -0,0 +1 @@
|
||||
export type TriggerEventType = 'MOUSE_DOWN' | 'CLICK';
|
||||
Reference in New Issue
Block a user