mirror of
https://github.com/fluxerapp/fluxer
synced 2026-10-18 05:25:40 +09:00
refactor: remove dead code (#3337)
This commit is contained in:
1 parent
a19002652b
commit
93d1f8af46
1527 files changed
+21170
-73846
No files matched your search
@@ -10,8 +10,6 @@ export type ResizeEdge =
|
||||
| 'top-right'
|
||||
| 'bottom-left'
|
||||
| 'bottom-right';
|
||||
|
||||
export const ALL_CORNERS: ReadonlyArray<Corner> = ['top-left', 'top-right', 'bottom-right', 'bottom-left'];
|
||||
export const ALL_RESIZE_EDGES: ReadonlyArray<ResizeEdge> = [
|
||||
'top',
|
||||
'bottom',
|
||||
@@ -23,7 +21,7 @@ export const ALL_RESIZE_EDGES: ReadonlyArray<ResizeEdge> = [
|
||||
'bottom-right',
|
||||
];
|
||||
|
||||
export interface Size {
|
||||
interface Size {
|
||||
width: number;
|
||||
height: number;
|
||||
}
|
||||
@@ -64,7 +62,7 @@ export interface FlingOptions {
|
||||
axisVelocityFloor: number;
|
||||
}
|
||||
|
||||
export const DEFAULT_FLING_OPTIONS: FlingOptions = {
|
||||
const DEFAULT_FLING_OPTIONS: FlingOptions = {
|
||||
lookaheadSeconds: 0.2,
|
||||
strongVelocity: 550,
|
||||
axisVelocityFloor: 180,
|
||||
@@ -85,12 +83,12 @@ export function getPaneHeight(width: number, aspectRatio: number): number {
|
||||
return Math.round(width / aspectRatio);
|
||||
}
|
||||
|
||||
export interface WidthRange {
|
||||
interface WidthRange {
|
||||
min: number;
|
||||
max: number;
|
||||
}
|
||||
|
||||
export function getEffectiveWidthRange(geometry: FloatingPaneGeometry): WidthRange {
|
||||
function getEffectiveWidthRange(geometry: FloatingPaneGeometry): WidthRange {
|
||||
const {viewport, edgePadding, topInset, aspectRatio, minWidth, maxWidth} = geometry;
|
||||
const availableWidth = Math.max(0, viewport.width - edgePadding * 2);
|
||||
const availableHeight = Math.max(0, viewport.height - edgePadding * 2 - topInset);
|
||||
@@ -117,7 +115,7 @@ export function getDragBounds(geometry: FloatingPaneGeometry, width: number): Dr
|
||||
return {minX, maxX, minY, maxY};
|
||||
}
|
||||
|
||||
export function clampPoint(point: Point, bounds: DragBounds): Point {
|
||||
function clampPoint(point: Point, bounds: DragBounds): Point {
|
||||
return {
|
||||
x: clamp(point.x, bounds.minX, bounds.maxX),
|
||||
y: clamp(point.y, bounds.minY, bounds.maxY),
|
||||
@@ -137,7 +135,7 @@ export function getCornerPoint(corner: Corner, bounds: DragBounds): Point {
|
||||
}
|
||||
}
|
||||
|
||||
export function snapPointToCorner(point: Point, bounds: DragBounds): Corner {
|
||||
function snapPointToCorner(point: Point, bounds: DragBounds): Corner {
|
||||
const midX = (bounds.minX + bounds.maxX) / 2;
|
||||
const midY = (bounds.minY + bounds.maxY) / 2;
|
||||
const isRight = point.x >= midX;
|
||||
@@ -215,22 +213,3 @@ export function computeResize(
|
||||
const offset = clampPoint({x: paneStartX + offsetXDelta, y: paneStartY + offsetYDelta}, bounds);
|
||||
return {width: nextWidth, offset};
|
||||
}
|
||||
|
||||
export interface GeometryReconcileInput {
|
||||
corner: Corner;
|
||||
width: number;
|
||||
geometry: FloatingPaneGeometry;
|
||||
}
|
||||
|
||||
export interface GeometryReconcileOutput {
|
||||
corner: Corner;
|
||||
width: number;
|
||||
offset: Point;
|
||||
}
|
||||
|
||||
export function reconcileToGeometry({corner, width, geometry}: GeometryReconcileInput): GeometryReconcileOutput {
|
||||
const nextWidth = clampWidth(width, geometry);
|
||||
const bounds = getDragBounds(geometry, nextWidth);
|
||||
const offset = getCornerPoint(corner, bounds);
|
||||
return {corner, width: nextWidth, offset};
|
||||
}
|
||||
@@ -74,30 +74,3 @@
|
||||
bottom: 0;
|
||||
cursor: se-resize;
|
||||
}
|
||||
|
||||
.cornerVisualHint {
|
||||
position: absolute;
|
||||
right: 0.25rem;
|
||||
bottom: 0.25rem;
|
||||
width: 0.625rem;
|
||||
height: 0.625rem;
|
||||
pointer-events: none;
|
||||
opacity: 0;
|
||||
transition: opacity 150ms ease;
|
||||
background: linear-gradient(
|
||||
135deg,
|
||||
transparent 0%,
|
||||
transparent 50%,
|
||||
var(--floating-pane-resize-hint-color, rgba(255, 255, 255, 0.75)) 50%,
|
||||
var(--floating-pane-resize-hint-color, rgba(255, 255, 255, 0.75)) 60%,
|
||||
transparent 60%,
|
||||
transparent 70%,
|
||||
var(--floating-pane-resize-hint-color, rgba(255, 255, 255, 0.55)) 70%,
|
||||
var(--floating-pane-resize-hint-color, rgba(255, 255, 255, 0.55)) 80%,
|
||||
transparent 80%
|
||||
);
|
||||
}
|
||||
|
||||
.cornerVisualHintVisible {
|
||||
opacity: 1;
|
||||
}
|
||||
@@ -3,35 +3,17 @@
|
||||
export type {
|
||||
Corner,
|
||||
DragBounds,
|
||||
FlingOptions,
|
||||
FloatingPaneGeometry,
|
||||
Point,
|
||||
ResizeEdge,
|
||||
ResizeResult,
|
||||
ResizeStart,
|
||||
Size,
|
||||
WidthRange,
|
||||
} from '@app/features/ui/floating_pane/FloatingPaneMath';
|
||||
export {
|
||||
ALL_CORNERS,
|
||||
ALL_RESIZE_EDGES,
|
||||
clampPoint,
|
||||
clampWidth,
|
||||
computeResize,
|
||||
DEFAULT_FLING_OPTIONS,
|
||||
getCornerPoint,
|
||||
getDragBounds,
|
||||
getEffectiveWidthRange,
|
||||
getPaneHeight,
|
||||
pickCornerForFling,
|
||||
reconcileToGeometry,
|
||||
snapPointToCorner,
|
||||
} from '@app/features/ui/floating_pane/FloatingPaneMath';
|
||||
export type {FloatingPaneResizeHandlesProps} from '@app/features/ui/floating_pane/FloatingPaneResizeHandles';
|
||||
export {FloatingPaneResizeHandles} from '@app/features/ui/floating_pane/FloatingPaneResizeHandles';
|
||||
export type {
|
||||
FloatingPanePointerHandlers,
|
||||
FloatingPaneResult,
|
||||
UseFloatingPaneOptions,
|
||||
} from '@app/features/ui/floating_pane/useFloatingPane';
|
||||
export {useFloatingPane} from '@app/features/ui/floating_pane/useFloatingPane';
|
||||
@@ -1,394 +0,0 @@
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
import {
|
||||
type Corner,
|
||||
clampPoint,
|
||||
clampWidth,
|
||||
computeResize,
|
||||
type FloatingPaneGeometry,
|
||||
getCornerPoint,
|
||||
getDragBounds,
|
||||
getPaneHeight,
|
||||
pickCornerForFling,
|
||||
type ResizeEdge,
|
||||
type ResizeStart,
|
||||
reconcileToGeometry,
|
||||
} from '@app/features/ui/floating_pane/FloatingPaneMath';
|
||||
import {appZoomLayoutPx} from '@app/features/ui/utils/AppZoomUtils';
|
||||
import {canUseWindowFocusedHoverControls} from '@app/features/ui/utils/WindowFocusInteractionGuard';
|
||||
import type React from 'react';
|
||||
import {useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState} from 'react';
|
||||
|
||||
const DRAG_ACTIVATION_DISTANCE_SQ = 9;
|
||||
|
||||
export interface UseFloatingPaneOptions {
|
||||
geometry: FloatingPaneGeometry;
|
||||
initialCorner: Corner;
|
||||
initialWidth: number;
|
||||
onCornerChange?: (corner: Corner) => void;
|
||||
onWidthChange?: (width: number) => void;
|
||||
requireFocusedWindow?: boolean;
|
||||
useFlingForCornerPick?: boolean;
|
||||
}
|
||||
|
||||
export interface FloatingPanePointerHandlers {
|
||||
onPointerDown: (event: React.PointerEvent<HTMLElement>) => void;
|
||||
}
|
||||
|
||||
export interface FloatingPaneResult {
|
||||
width: number;
|
||||
height: number;
|
||||
offset: {x: number; y: number};
|
||||
corner: Corner;
|
||||
isDragging: boolean;
|
||||
isResizing: boolean;
|
||||
hasPositioned: boolean;
|
||||
dragHandlers: FloatingPanePointerHandlers;
|
||||
createResizeHandler: (edge: ResizeEdge) => (event: React.PointerEvent<HTMLElement>) => void;
|
||||
suppressNextClick: boolean;
|
||||
consumeClickSuppression: () => boolean;
|
||||
}
|
||||
|
||||
interface DragInternalState {
|
||||
pointerId: number;
|
||||
startClientX: number;
|
||||
startClientY: number;
|
||||
startOffsetX: number;
|
||||
startOffsetY: number;
|
||||
startTimestamp: number;
|
||||
lastClientX: number;
|
||||
lastClientY: number;
|
||||
lastTimestamp: number;
|
||||
velocityX: number;
|
||||
velocityY: number;
|
||||
dragActivated: boolean;
|
||||
}
|
||||
|
||||
interface ResizeInternalState extends ResizeStart {
|
||||
pointerId: number;
|
||||
}
|
||||
|
||||
export function useFloatingPane(options: UseFloatingPaneOptions): FloatingPaneResult {
|
||||
const {
|
||||
geometry,
|
||||
initialCorner,
|
||||
initialWidth,
|
||||
onCornerChange,
|
||||
onWidthChange,
|
||||
requireFocusedWindow = true,
|
||||
useFlingForCornerPick = false,
|
||||
} = options;
|
||||
const geometryRef = useRef(geometry);
|
||||
useEffect(() => {
|
||||
geometryRef.current = geometry;
|
||||
}, [geometry]);
|
||||
const [corner, setCorner] = useState<Corner>(initialCorner);
|
||||
const hasMeasuredViewport = geometry.viewport.width > 0 && geometry.viewport.height > 0;
|
||||
const [width, setWidth] = useState(() => (hasMeasuredViewport ? clampWidth(initialWidth, geometry) : initialWidth));
|
||||
const [offset, setOffset] = useState(() =>
|
||||
hasMeasuredViewport
|
||||
? getCornerPoint(initialCorner, getDragBounds(geometry, clampWidth(initialWidth, geometry)))
|
||||
: {x: 0, y: 0},
|
||||
);
|
||||
const [isDragging, setIsDragging] = useState(false);
|
||||
const [isResizing, setIsResizing] = useState(false);
|
||||
const [hasPositioned, setHasPositioned] = useState(hasMeasuredViewport);
|
||||
const cornerRef = useRef(corner);
|
||||
const widthRef = useRef(width);
|
||||
const offsetRef = useRef(offset);
|
||||
const dragStateRef = useRef<DragInternalState | null>(null);
|
||||
const resizeStateRef = useRef<ResizeInternalState | null>(null);
|
||||
const dragListenersRef = useRef<{move: (event: PointerEvent) => void; up: (event: PointerEvent) => void} | null>(
|
||||
null,
|
||||
);
|
||||
const resizeListenersRef = useRef<{move: (event: PointerEvent) => void; up: (event: PointerEvent) => void} | null>(
|
||||
null,
|
||||
);
|
||||
const resizeFrameRef = useRef<number | null>(null);
|
||||
const pendingResizeMoveRef = useRef<{pointerId: number; clientX: number; clientY: number} | null>(null);
|
||||
const suppressClickRef = useRef(false);
|
||||
useEffect(() => {
|
||||
cornerRef.current = corner;
|
||||
}, [corner]);
|
||||
useEffect(() => {
|
||||
widthRef.current = width;
|
||||
}, [width]);
|
||||
useEffect(() => {
|
||||
offsetRef.current = offset;
|
||||
}, [offset]);
|
||||
const commitCorner = useCallback(
|
||||
(nextCorner: Corner) => {
|
||||
cornerRef.current = nextCorner;
|
||||
setCorner((previous) => (previous === nextCorner ? previous : nextCorner));
|
||||
onCornerChange?.(nextCorner);
|
||||
},
|
||||
[onCornerChange],
|
||||
);
|
||||
const updateWidthSilently = useCallback((nextWidth: number) => {
|
||||
widthRef.current = nextWidth;
|
||||
setWidth((previous) => (Math.abs(previous - nextWidth) < 0.5 ? previous : nextWidth));
|
||||
}, []);
|
||||
const commitWidth = useCallback(
|
||||
(nextWidth: number) => {
|
||||
updateWidthSilently(nextWidth);
|
||||
onWidthChange?.(nextWidth);
|
||||
},
|
||||
[onWidthChange, updateWidthSilently],
|
||||
);
|
||||
const updateOffsetSilently = useCallback((next: {x: number; y: number}) => {
|
||||
offsetRef.current = next;
|
||||
setOffset((previous) =>
|
||||
Math.abs(previous.x - next.x) < 0.5 && Math.abs(previous.y - next.y) < 0.5 ? previous : next,
|
||||
);
|
||||
}, []);
|
||||
useLayoutEffect(() => {
|
||||
if (dragStateRef.current || resizeStateRef.current) return;
|
||||
if (geometry.viewport.width <= 0 || geometry.viewport.height <= 0) return;
|
||||
const reconciled = reconcileToGeometry({
|
||||
corner: cornerRef.current,
|
||||
width: widthRef.current,
|
||||
geometry,
|
||||
});
|
||||
if (Math.abs(reconciled.width - widthRef.current) >= 0.5) {
|
||||
commitWidth(reconciled.width);
|
||||
}
|
||||
updateOffsetSilently(reconciled.offset);
|
||||
setHasPositioned(true);
|
||||
}, [
|
||||
commitWidth,
|
||||
geometry,
|
||||
geometry.aspectRatio,
|
||||
geometry.edgePadding,
|
||||
geometry.maxWidth,
|
||||
geometry.minWidth,
|
||||
geometry.topInset,
|
||||
geometry.viewport.height,
|
||||
geometry.viewport.width,
|
||||
updateOffsetSilently,
|
||||
]);
|
||||
const cancelPendingResizeFrame = useCallback(() => {
|
||||
if (resizeFrameRef.current !== null) {
|
||||
cancelAnimationFrame(resizeFrameRef.current);
|
||||
resizeFrameRef.current = null;
|
||||
}
|
||||
}, []);
|
||||
const flushResizeFrame = useCallback(() => {
|
||||
resizeFrameRef.current = null;
|
||||
const pendingMove = pendingResizeMoveRef.current;
|
||||
pendingResizeMoveRef.current = null;
|
||||
const state = resizeStateRef.current;
|
||||
if (!state || !pendingMove || state.pointerId !== pendingMove.pointerId) return;
|
||||
const pointerX = appZoomLayoutPx(pendingMove.clientX);
|
||||
const pointerY = appZoomLayoutPx(pendingMove.clientY);
|
||||
const result = computeResize(state, pointerX, pointerY, geometryRef.current);
|
||||
updateWidthSilently(result.width);
|
||||
updateOffsetSilently(result.offset);
|
||||
}, [updateOffsetSilently, updateWidthSilently]);
|
||||
const cleanupResizeListeners = useCallback(() => {
|
||||
const listeners = resizeListenersRef.current;
|
||||
if (!listeners) return;
|
||||
window.removeEventListener('pointermove', listeners.move);
|
||||
window.removeEventListener('pointerup', listeners.up);
|
||||
window.removeEventListener('pointercancel', listeners.up);
|
||||
resizeListenersRef.current = null;
|
||||
pendingResizeMoveRef.current = null;
|
||||
cancelPendingResizeFrame();
|
||||
}, [cancelPendingResizeFrame]);
|
||||
const handleResizeMove = useCallback(
|
||||
(event: PointerEvent) => {
|
||||
const state = resizeStateRef.current;
|
||||
if (!state || state.pointerId !== event.pointerId) return;
|
||||
event.preventDefault();
|
||||
pendingResizeMoveRef.current = {pointerId: event.pointerId, clientX: event.clientX, clientY: event.clientY};
|
||||
if (resizeFrameRef.current !== null) return;
|
||||
resizeFrameRef.current = requestAnimationFrame(flushResizeFrame);
|
||||
},
|
||||
[flushResizeFrame],
|
||||
);
|
||||
const handleResizeUp = useCallback(
|
||||
(event: PointerEvent) => {
|
||||
const state = resizeStateRef.current;
|
||||
if (!state || state.pointerId !== event.pointerId) return;
|
||||
event.preventDefault();
|
||||
if (resizeFrameRef.current !== null) {
|
||||
cancelPendingResizeFrame();
|
||||
flushResizeFrame();
|
||||
}
|
||||
cleanupResizeListeners();
|
||||
resizeStateRef.current = null;
|
||||
setIsResizing(false);
|
||||
const reconcileGeometry = geometryRef.current;
|
||||
const bounds = getDragBounds(reconcileGeometry, widthRef.current);
|
||||
const snappedOffset = clampPoint(offsetRef.current, bounds);
|
||||
const nextCorner: Corner = (() => {
|
||||
const midX = (bounds.minX + bounds.maxX) / 2;
|
||||
const midY = (bounds.minY + bounds.maxY) / 2;
|
||||
const isRight = snappedOffset.x >= midX;
|
||||
const isBottom = snappedOffset.y >= midY;
|
||||
return `${isBottom ? 'bottom' : 'top'}-${isRight ? 'right' : 'left'}` as Corner;
|
||||
})();
|
||||
commitCorner(nextCorner);
|
||||
commitWidth(widthRef.current);
|
||||
updateOffsetSilently(getCornerPoint(nextCorner, bounds));
|
||||
},
|
||||
[
|
||||
cancelPendingResizeFrame,
|
||||
cleanupResizeListeners,
|
||||
commitCorner,
|
||||
commitWidth,
|
||||
flushResizeFrame,
|
||||
updateOffsetSilently,
|
||||
],
|
||||
);
|
||||
const createResizeHandler = useCallback(
|
||||
(edge: ResizeEdge) => (event: React.PointerEvent<HTMLElement>) => {
|
||||
if (event.button !== 0) return;
|
||||
if (requireFocusedWindow && !canUseWindowFocusedHoverControls()) return;
|
||||
if (dragStateRef.current) return;
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
const startWidth = clampWidth(widthRef.current, geometryRef.current);
|
||||
const start: ResizeInternalState = {
|
||||
pointerId: event.pointerId,
|
||||
edge,
|
||||
startWidth,
|
||||
pointerStartX: appZoomLayoutPx(event.clientX),
|
||||
pointerStartY: appZoomLayoutPx(event.clientY),
|
||||
paneStartX: offsetRef.current.x,
|
||||
paneStartY: offsetRef.current.y,
|
||||
};
|
||||
resizeStateRef.current = start;
|
||||
const listeners = {move: handleResizeMove, up: handleResizeUp};
|
||||
resizeListenersRef.current = listeners;
|
||||
setIsResizing(true);
|
||||
window.addEventListener('pointermove', listeners.move);
|
||||
window.addEventListener('pointerup', listeners.up);
|
||||
window.addEventListener('pointercancel', listeners.up);
|
||||
},
|
||||
[handleResizeMove, handleResizeUp, requireFocusedWindow],
|
||||
);
|
||||
const cleanupDragListeners = useCallback(() => {
|
||||
const listeners = dragListenersRef.current;
|
||||
if (!listeners) return;
|
||||
window.removeEventListener('pointermove', listeners.move);
|
||||
window.removeEventListener('pointerup', listeners.up);
|
||||
window.removeEventListener('pointercancel', listeners.up);
|
||||
dragListenersRef.current = null;
|
||||
}, []);
|
||||
const handleDragMove = useCallback(
|
||||
(event: PointerEvent) => {
|
||||
const state = dragStateRef.current;
|
||||
if (!state || state.pointerId !== event.pointerId) return;
|
||||
const deltaX = appZoomLayoutPx(event.clientX - state.startClientX);
|
||||
const deltaY = appZoomLayoutPx(event.clientY - state.startClientY);
|
||||
if (!state.dragActivated) {
|
||||
if (deltaX * deltaX + deltaY * deltaY < DRAG_ACTIVATION_DISTANCE_SQ) return;
|
||||
state.dragActivated = true;
|
||||
suppressClickRef.current = true;
|
||||
setIsDragging(true);
|
||||
}
|
||||
const now = event.timeStamp;
|
||||
const dt = now - state.lastTimestamp;
|
||||
if (dt > 0) {
|
||||
const dx = event.clientX - state.lastClientX;
|
||||
const dy = event.clientY - state.lastClientY;
|
||||
state.velocityX = (dx / dt) * 1000;
|
||||
state.velocityY = (dy / dt) * 1000;
|
||||
}
|
||||
state.lastClientX = event.clientX;
|
||||
state.lastClientY = event.clientY;
|
||||
state.lastTimestamp = now;
|
||||
const nextOffset = clampPoint(
|
||||
{x: state.startOffsetX + deltaX, y: state.startOffsetY + deltaY},
|
||||
getDragBounds(geometryRef.current, widthRef.current),
|
||||
);
|
||||
updateOffsetSilently(nextOffset);
|
||||
},
|
||||
[updateOffsetSilently],
|
||||
);
|
||||
const handleDragUp = useCallback(
|
||||
(event: PointerEvent) => {
|
||||
const state = dragStateRef.current;
|
||||
if (!state || state.pointerId !== event.pointerId) return;
|
||||
dragStateRef.current = null;
|
||||
cleanupDragListeners();
|
||||
if (!state.dragActivated) {
|
||||
setIsDragging(false);
|
||||
return;
|
||||
}
|
||||
const bounds = getDragBounds(geometryRef.current, widthRef.current);
|
||||
const nextCorner = useFlingForCornerPick
|
||||
? pickCornerForFling(offsetRef.current, {x: state.velocityX, y: state.velocityY}, bounds)
|
||||
: (() => {
|
||||
const midX = (bounds.minX + bounds.maxX) / 2;
|
||||
const midY = (bounds.minY + bounds.maxY) / 2;
|
||||
const isRight = offsetRef.current.x >= midX;
|
||||
const isBottom = offsetRef.current.y >= midY;
|
||||
return `${isBottom ? 'bottom' : 'top'}-${isRight ? 'right' : 'left'}` as Corner;
|
||||
})();
|
||||
commitCorner(nextCorner);
|
||||
updateOffsetSilently(getCornerPoint(nextCorner, bounds));
|
||||
setIsDragging(false);
|
||||
},
|
||||
[cleanupDragListeners, commitCorner, updateOffsetSilently, useFlingForCornerPick],
|
||||
);
|
||||
const beginDrag = useCallback(
|
||||
(event: React.PointerEvent<HTMLElement>) => {
|
||||
if (event.button !== 0) return;
|
||||
if (requireFocusedWindow && !canUseWindowFocusedHoverControls()) return;
|
||||
if (resizeStateRef.current) return;
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
try {
|
||||
event.currentTarget.setPointerCapture(event.pointerId);
|
||||
} catch {}
|
||||
const now = event.timeStamp;
|
||||
dragStateRef.current = {
|
||||
pointerId: event.pointerId,
|
||||
startClientX: event.clientX,
|
||||
startClientY: event.clientY,
|
||||
startOffsetX: offsetRef.current.x,
|
||||
startOffsetY: offsetRef.current.y,
|
||||
startTimestamp: now,
|
||||
lastClientX: event.clientX,
|
||||
lastClientY: event.clientY,
|
||||
lastTimestamp: now,
|
||||
velocityX: 0,
|
||||
velocityY: 0,
|
||||
dragActivated: false,
|
||||
};
|
||||
const listeners = {move: handleDragMove, up: handleDragUp};
|
||||
dragListenersRef.current = listeners;
|
||||
window.addEventListener('pointermove', listeners.move);
|
||||
window.addEventListener('pointerup', listeners.up);
|
||||
window.addEventListener('pointercancel', listeners.up);
|
||||
},
|
||||
[handleDragMove, handleDragUp, requireFocusedWindow],
|
||||
);
|
||||
useEffect(() => {
|
||||
return () => {
|
||||
cleanupDragListeners();
|
||||
cleanupResizeListeners();
|
||||
};
|
||||
}, [cleanupDragListeners, cleanupResizeListeners]);
|
||||
const consumeClickSuppression = useCallback(() => {
|
||||
if (!suppressClickRef.current) return false;
|
||||
suppressClickRef.current = false;
|
||||
return true;
|
||||
}, []);
|
||||
const height = useMemo(() => getPaneHeight(width, geometry.aspectRatio), [width, geometry.aspectRatio]);
|
||||
const dragHandlers = useMemo<FloatingPanePointerHandlers>(() => ({onPointerDown: beginDrag}), [beginDrag]);
|
||||
return {
|
||||
width,
|
||||
height,
|
||||
offset,
|
||||
corner,
|
||||
isDragging,
|
||||
isResizing,
|
||||
hasPositioned,
|
||||
dragHandlers,
|
||||
createResizeHandler,
|
||||
suppressNextClick: suppressClickRef.current,
|
||||
consumeClickSuppression,
|
||||
};
|
||||
}
|
||||
Reference in new issue
Block a user