Skip to content

Commit 98412f1

Browse files
authored
fix(drawing): reposition toolbar on drawing (#657)
* fix(drawing): reposition toolbar above highest staged annotation
1 parent 2f4a9e1 commit 98412f1

File tree

3 files changed

+45
-16
lines changed

3 files changed

+45
-16
lines changed

src/components/Popups/PopupDrawingToolbar.tsx

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ import PopupBase from './PopupBase';
99
import { Options, PopupReference, Rect } from './Popper';
1010
import './PopupDrawingToolbar.scss';
1111

12+
export type PopupBaseRef = PopupBase;
13+
1214
export type Props = {
1315
canComment: boolean;
1416
canRedo: boolean;
@@ -38,28 +40,21 @@ const options: Partial<Options> = {
3840
{
3941
name: 'preventOverflow',
4042
options: {
41-
padding: 5,
43+
altAxis: true,
44+
padding: 50,
4245
},
4346
},
4447
],
4548
placement: 'top',
4649
};
4750

48-
const PopupDrawingToolbar = ({
49-
canComment,
50-
canRedo,
51-
canUndo,
52-
className,
53-
onDelete,
54-
onRedo,
55-
onReply,
56-
onUndo,
57-
reference,
58-
}: Props): JSX.Element => {
51+
const PopupDrawingToolbar = (props: Props, ref: React.Ref<PopupBaseRef>): JSX.Element => {
52+
const { canComment, canRedo, canUndo, className, onDelete, onRedo, onReply, onUndo, reference } = props;
5953
const intl = useIntl();
6054

6155
return (
6256
<PopupBase
57+
ref={ref}
6358
className={classNames(className, 'ba-PopupDrawingToolbar')}
6459
data-resin-component="popupDrawingToolbar"
6560
options={options}
@@ -111,4 +106,4 @@ const PopupDrawingToolbar = ({
111106
);
112107
};
113108

114-
export default PopupDrawingToolbar;
109+
export default React.forwardRef(PopupDrawingToolbar);

src/drawing/DrawingAnnotations.tsx

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
import React from 'react';
1+
import * as React from 'react';
22
import classNames from 'classnames';
33
import DecoratedDrawingPath from './DecoratedDrawingPath';
44
import DrawingList from './DrawingList';
55
import DrawingCreator from './DrawingCreator';
66
import DrawingPathGroup from './DrawingPathGroup';
77
import DrawingSVG, { DrawingSVGRef } from './DrawingSVG';
88
import DrawingSVGGroup from './DrawingSVGGroup';
9-
import PopupDrawingToolbar from '../components/Popups/PopupDrawingToolbar';
9+
import PopupDrawingToolbar, { PopupBaseRef } from '../components/Popups/PopupDrawingToolbar';
1010
import { AnnotationDrawing, PathGroup } from '../@types';
1111
import { CreatorItemDrawing, CreatorStatus } from '../store';
1212
import './DrawingAnnotations.scss';
@@ -56,6 +56,7 @@ const DrawingAnnotations = (props: Props): JSX.Element => {
5656
const hasDrawnPathGroups = drawnPathGroups.length > 0;
5757
const hasStashedPathGroups = stashedPathGroups.length > 0;
5858
const hasPathGroups = hasDrawnPathGroups || hasStashedPathGroups;
59+
const popupDrawingToolbarRef = React.useRef<PopupBaseRef>(null);
5960
const stagedGroupRef = React.useRef<SVGGElement>(null);
6061
const { current: drawingSVGGroup } = stagedGroupRef;
6162

@@ -87,6 +88,12 @@ const DrawingAnnotations = (props: Props): JSX.Element => {
8788
const handleUndo = (): void => {
8889
undoDrawingPathGroup();
8990
};
91+
React.useEffect(() => {
92+
const { current: popup } = popupDrawingToolbarRef;
93+
if (popup?.popper && drawnPathGroups.length) {
94+
popup.popper.update();
95+
}
96+
}, [drawnPathGroups]);
9097

9198
return (
9299
<>
@@ -131,6 +138,7 @@ const DrawingAnnotations = (props: Props): JSX.Element => {
131138

132139
{isCreating && hasPathGroups && drawingSVGGroup && canShowPopupToolbar && (
133140
<PopupDrawingToolbar
141+
ref={popupDrawingToolbarRef}
134142
canComment={hasDrawnPathGroups}
135143
canRedo={hasStashedPathGroups}
136144
canUndo={hasDrawnPathGroups}

src/drawing/__tests__/DrawingAnnotations-test.tsx

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React from 'react';
1+
import * as React from 'react';
22
import { act } from 'react-dom/test-utils';
33
import { mount, ReactWrapper } from 'enzyme';
44
import DrawingAnnotations, { Props } from '../DrawingAnnotations';
@@ -11,6 +11,7 @@ import { annotations } from '../__mocks__/drawingData';
1111
import { CreatorStatus } from '../../store';
1212

1313
jest.mock('../DrawingList');
14+
jest.mock('../../components/Popups/PopupDrawingToolbar');
1415

1516
describe('DrawingAnnotations', () => {
1617
const getDefaults = (): Props => ({
@@ -239,4 +240,29 @@ describe('DrawingAnnotations', () => {
239240
},
240241
);
241242
});
243+
244+
describe('state changes', () => {
245+
test.each`
246+
basePathGroups | nextPathGroups | expected
247+
${[]} | ${[]} | ${0}
248+
${[]} | ${pathGroups} | ${1}
249+
${pathGroups} | ${pathGroups} | ${1}
250+
`(
251+
'should call update $expected times if basePathGroups.length is $basePathGroups.length and nextPathGroups.length is $nextPathGroups.length',
252+
({ basePathGroups, nextPathGroups, expected }) => {
253+
const popupRef = { popper: { update: jest.fn() } };
254+
jest.spyOn(React, 'useRef').mockImplementation(() => ({ current: popupRef }));
255+
256+
const wrapper = getWrapper({
257+
canShowPopupToolbar: true,
258+
drawnPathGroups: basePathGroups,
259+
isCreating: true,
260+
});
261+
262+
wrapper.setProps({ drawnPathGroups: nextPathGroups });
263+
264+
expect(popupRef.popper.update).toHaveBeenCalledTimes(expected);
265+
},
266+
);
267+
});
242268
});

0 commit comments

Comments
 (0)