Skip to content

Commit

Permalink
refactor: resizer and draggable components (#2731)
Browse files Browse the repository at this point in the history
* refactor: useDraggable hook

* refactor: resizer component and its hook

* refactor: lefting resizer state up and remove key

* refactor: create HOC for the resizer component

* refactor: resizer component and remove div resizer
  • Loading branch information
hamed-musallam authored Nov 6, 2023
1 parent b8c8e48 commit 565fb92
Show file tree
Hide file tree
Showing 10 changed files with 209 additions and 334 deletions.
23 changes: 8 additions & 15 deletions src/component/1d/integral/IntegralResizable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,8 @@ import { Integral } from 'nmr-processing';

import { useChartData } from '../../context/ChartContext';
import { useDispatch } from '../../context/DispatchContext';
import { useGlobal } from '../../context/GlobalContext';
import { useScaleChecked } from '../../context/ScaleContext';
import Resizer from '../../elements/resizer/Resizer';
import { ResizerWithScale } from '../../elements/ResizerWithScale';
import { HighlightEventSource, useHighlight } from '../../highlight/index';
import { useResizerStatus } from '../../hooks/useResizerStatus';

Expand Down Expand Up @@ -52,10 +51,9 @@ function IntegralResizable({
integralFormat,
}: IntegralResizableProps) {
const { height, margin } = useChartData();
const { viewerRef } = useGlobal();
const { scaleX } = useScaleChecked();
const dispatch = useDispatch();
const { id, integral } = integralData;
const { id, integral, to, from } = integralData;
const highlight = useHighlight([id], {
type: HighlightEventSource.INTEGRAL,
extra: { id },
Expand All @@ -74,25 +72,20 @@ function IntegralResizable({
});
}

const from = integralData.from ? scaleX()(integralData.from) : 0;
const to = integralData.to ? scaleX()(integralData.to) : 0;

const bottom = height - margin.bottom;

const isResizeingActive = useResizerStatus('integral');
const isResizingActive = useResizerStatus('integral');

return (
<g
onMouseEnter={() => highlight.show()}
onMouseLeave={() => highlight.hide()}
>
<Resizer
tag="svg"
initialPosition={{ x1: to, x2: from }}
<ResizerWithScale
from={from}
to={to}
onEnd={handleOnStopResizing}
parentElement={viewerRef}
key={`${id}_${to}_${from}`}
disabled={!isResizeingActive}
disabled={!isResizingActive}
>
{({ x1, x2 }, isActive) => {
const width = x2 - x1;
Expand All @@ -119,7 +112,7 @@ function IntegralResizable({
</g>
);
}}
</Resizer>
</ResizerWithScale>
</g>
);
}
Expand Down
21 changes: 8 additions & 13 deletions src/component/1d/multiAnalysis/AnalysisRange.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,9 @@
import { css } from '@emotion/react';
import { useCallback } from 'react';

import { useGlobal } from '../../context/GlobalContext';
import { usePreferences } from '../../context/PreferencesContext';
import { useScaleChecked } from '../../context/ScaleContext';
import Resizer from '../../elements/resizer/Resizer';
import { ResizerWithScale } from '../../elements/ResizerWithScale';
import { useHighlight } from '../../highlight';
import { useResizerStatus } from '../../hooks/useResizerStatus';

Expand Down Expand Up @@ -55,7 +54,6 @@ function AnalysisRange({
});
const { scaleX } = useScaleChecked();
const { dispatch } = usePreferences();
const { viewerRef } = useGlobal();

const resizeEndHandler = useCallback(
(resized) => {
Expand All @@ -71,18 +69,15 @@ function AnalysisRange({
[activeTab, columnKey, dispatch, scaleX],
);

const from = scaleX()(rangeData.from);
const to = scaleX()(rangeData.to);
const isResizeingActive = useResizerStatus('multipleSpectraAnalysis');
const { from, to } = rangeData;
const isResizingActive = useResizerStatus('multipleSpectraAnalysis');
return (
<g {...highlight.onHover} {...highlight.onHover}>
<Resizer
tag="svg"
<ResizerWithScale
onEnd={resizeEndHandler}
initialPosition={{ x2: from, x1: to }}
parentElement={viewerRef}
key={`${columnKey}_${to}_${from}`}
disabled={!isResizeingActive}
from={from}
to={to}
disabled={!isResizingActive}
>
{({ x1, x2 }, isActive) => (
<g
Expand Down Expand Up @@ -114,7 +109,7 @@ function AnalysisRange({
</text>
</g>
)}
</Resizer>
</ResizerWithScale>
</g>
);
}
Expand Down
29 changes: 11 additions & 18 deletions src/component/1d/ranges/Range.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,13 @@ import {
} from '../../assignment/AssignmentsContext';
import { filterForIDsWithAssignment } from '../../assignment/utilities/filterForIDsWithAssignment';
import { useDispatch } from '../../context/DispatchContext';
import { useGlobal } from '../../context/GlobalContext';
import { useScaleChecked } from '../../context/ScaleContext';
import Resizer from '../../elements/resizer/Resizer';
import { ResizerWithScale } from '../../elements/ResizerWithScale';
import { HighlightEventSource, useHighlight } from '../../highlight';
import { useResizerStatus } from '../../hooks/useResizerStatus';
import { options } from '../../toolbar/ToolTypes';
import { IntegralIndicator } from '../integral/IntegralIndicator';
import { MultiplicityTree } from '../multiplicityTree/MultiplicityTree';
import { useScaleX } from '../utilities/scale';

import { AssignmentActionsButtons } from './AssignmentActionsButtons';

Expand Down Expand Up @@ -46,8 +45,7 @@ function Range({
selectedTool,
relativeFormat,
}: RangeProps) {
const { viewerRef } = useGlobal();
const { id, integration, signals, diaIDs } = range;
const { id, integration, signals, diaIDs, from, to } = range;
const assignmentData = useAssignmentData();
const assignmentRange = useAssignment(id);
const highlightRange = useHighlight(
Expand All @@ -60,7 +58,7 @@ function Range({
{ type: HighlightEventSource.RANGE, extra: { id } },
);

const { scaleX } = useScaleChecked();
const scaleX = useScaleX();
const dispatch = useDispatch();

const isBlockedByEditing =
Expand Down Expand Up @@ -105,15 +103,12 @@ function Range({
}
}

const from = scaleX()(range.from);
const to = scaleX()(range.to);

const isNotSignal = !checkRangeKind(range);
const isHighlighted =
isBlockedByEditing || highlightRange.isActive || assignmentRange.isActive;

const isAssigned = isRangeAssigned(range);
const isResizeingActive = useResizerStatus('rangePicking');
const isResizingActive = useResizerStatus('rangePicking');

return (
<g
Expand All @@ -124,13 +119,11 @@ function Range({
onMouseLeave={mouseLeaveHandler}
{...(!assignmentRange.isActive && { css: style })}
>
<Resizer
tag="svg"
initialPosition={{ x1: to, x2: from }}
<ResizerWithScale
from={from}
to={to}
onEnd={handleOnStopResizing}
parentElement={viewerRef}
key={`${id}_${to}_${from}`}
disabled={!isResizeingActive}
disabled={!isResizingActive}
>
{({ x1, x2 }, isActive) => {
const width = x2 - x1;
Expand Down Expand Up @@ -161,14 +154,14 @@ function Range({
</g>
);
}}
</Resizer>
</ResizerWithScale>

{showMultiplicityTrees && (
<MultiplicityTree range={range} onUnlink={unAssignHandler} />
)}
<AssignmentActionsButtons
isActive={!!(assignmentRange.isActive || diaIDs)}
x={from - 16}
x={scaleX()(from) - 16}
onAssign={assignHandler}
onUnAssign={() => unAssignHandler()}
/>
Expand Down
41 changes: 41 additions & 0 deletions src/component/elements/ResizerWithScale.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { useEffect, useState } from 'react';

import { useScaleX } from '../1d/utilities/scale';
import { useGlobal } from '../context/GlobalContext';

import SVGResizer, { ResizerProps } from './resizer/SVGResizer';

interface ResizerWithScaleProps {
disabled: boolean;
from: number;
to: number;
onEnd: ResizerProps['onEnd'];
children: ResizerProps['children'];
}

export function ResizerWithScale(props: ResizerWithScaleProps) {
const { from, to, onEnd, disabled, children } = props;
const { viewerRef } = useGlobal();
const scaleX = useScaleX();
const x2 = scaleX()(from);
const x1 = scaleX()(to);
const [position, setPosition] = useState({ x1, x2 });

useEffect(() => {
const x2 = scaleX()(from);
const x1 = scaleX()(to);
setPosition({ x1, x2 });
}, [from, scaleX, to]);

return (
<SVGResizer
position={position}
onEnd={onEnd}
parentElement={viewerRef}
disabled={disabled}
onMove={(p) => setPosition(p)}
>
{children}
</SVGResizer>
);
}
53 changes: 21 additions & 32 deletions src/component/elements/draggable/SVGDraggable.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useEffect, ReactFragment } from 'react';
import { ReactFragment } from 'react';

import useDraggable, { Position } from './useDraggable';

Expand All @@ -13,7 +13,7 @@ type PositionChangeHandler = (data: Position) => void;

export interface DraggableProps {
children?: ChildType | ((x1: number, x2: number) => ChildType);
initialPosition?: Position;
position?: Position;
width: number;
height: number;
onStart?: PositionChangeHandler;
Expand All @@ -26,7 +26,7 @@ export interface DraggableProps {
export default function SVGDraggable(props: DraggableProps) {
const {
children,
initialPosition = { x: 0, y: 0 },
position: cPosition = { x: 0, y: 0 },
width,
height,
onStart,
Expand All @@ -36,43 +36,32 @@ export default function SVGDraggable(props: DraggableProps) {
dragHandleClassName,
} = props;

const {
position: {
value: { x, y },
action,
const { onPointerDown } = useDraggable({
position: cPosition,
onChange: (dragEvent) => {
const { action, position } = dragEvent;
switch (action) {
case 'start':
onStart?.(position);
break;
case 'move':
onMove?.(position);
break;
case 'end':
onEnd?.(position);
break;
default:
break;
}
},
onPointerDown,
} = useDraggable({
position: initialPosition,
parentElement,
dragHandleClassName,
});

useEffect(() => {
const position: Position = {
x,
y,
};

switch (action) {
case 'start':
onStart?.(position);
break;
case 'move':
onMove?.(position);
break;
case 'end':
onEnd?.(position);
break;
default:
break;
}
}, [action, onEnd, onMove, onStart, x, y]);

return (
<g
style={{
transform: `translate(${x}px,${y}px)`,
transform: `translate(${cPosition.x}px,${cPosition.y}px)`,
}}
onPointerDown={onPointerDown}
>
Expand Down
Loading

0 comments on commit 565fb92

Please sign in to comment.