Skip to content

Commit

Permalink
fix: position of form incase of zooming/in out
Browse files Browse the repository at this point in the history
  • Loading branch information
LinaYahya committed Jul 24, 2024
1 parent 4925ac2 commit 834a82b
Show file tree
Hide file tree
Showing 2 changed files with 121 additions and 131 deletions.
113 changes: 62 additions & 51 deletions src/modules/builder/configuration/AddLabelsStep/AddLabelForm.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import React, { useContext } from 'react';
import { useControls } from 'react-zoom-pan-pinch';

import { CloseRounded } from '@mui/icons-material';
import CheckIcon from '@mui/icons-material/Check';
Expand Down Expand Up @@ -28,76 +29,86 @@ const AddLabelForm = ({
const theme = useTheme();
const { deleteLabel } = useContext(LabelsContext);

const { instance } = useControls();

const { scale } = instance.transformState;
return (
<Stack
sx={{
position: 'absolute',
zIndex: 500,
top: position.y,
left: position.x,
background: 'black',
padding: 1,
}}
gap={1}
>
<Box sx={{ position: 'relative' }}>
<IconButton
color="primary"
sx={{
position: 'absolute',
top: -26,
right: -8,
padding: '2px',
borderRadius: '50%',
color: 'white',
background: 'black',
'&:hover': {
background: 'black',
color: 'white',
},
}}
onClick={onClose}
>
<CloseRounded />
</IconButton>
<Box
display="flex"
alignItems="center"
sx={{ border: `1px solid ${theme.palette.primary.main}` }}
>
<TextField
autoFocus
size="small"
value={value}
onChange={onChange}
sx={{
background: 'white',
opacity: 1,
border: 0,
width: '15ch',
}}
multiline
/>
<Box
sx={{
background: 'black',
padding: 1,
transformOrigin: 'top left',
transform: `translate(0px, 0px) scale(${1 / scale})`, // keeping the form size the same despite zooming in/out
}}
>
<Box sx={{ position: 'relative' }}>
<IconButton
onClick={onSubmit}
color="primary"
sx={{
background: theme.palette.primary.main,
borderRadius: 0,
position: 'absolute',
top: -26,
right: -8,
padding: '2px',
borderRadius: '50%',
color: 'white',
background: 'black',
'&:hover': {
background: 'black',
color: 'white',
},
}}
onClick={onClose}
>
<CheckIcon sx={{ color: 'white' }} />
<CloseRounded />
</IconButton>
{labelToDelete && (
<Box
display="flex"
alignItems="center"
sx={{ border: `1px solid ${theme.palette.primary.main}` }}
>
<TextField
autoFocus
size="small"
value={value}
onChange={onChange}
sx={{
background: 'white',
opacity: 1,
border: 0,
width: '15ch',
}}
multiline
/>
<IconButton
onClick={() => {
deleteLabel(labelToDelete.id);
onClose();
onClick={onSubmit}
sx={{
background: theme.palette.primary.main,
borderRadius: 0,
}}
sx={{ borderRadius: 0 }}
>
<DeleteIcon color="primary" sx={{ color: 'white' }} />
<CheckIcon sx={{ color: 'white' }} />
</IconButton>
)}
{labelToDelete && (
<IconButton
onClick={() => {
deleteLabel(labelToDelete.id);
onClose();
}}
sx={{ borderRadius: 0 }}
>
<DeleteIcon color="primary" sx={{ color: 'white' }} />
</IconButton>
)}
</Box>
</Box>
</Box>
</Stack>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
import { useContext, useState } from 'react';
import {
TransformComponent,
TransformWrapper,
useControls,
} from 'react-zoom-pan-pinch';
import { TransformComponent, TransformWrapper } from 'react-zoom-pan-pinch';

import { Alert, Box, styled } from '@mui/material';

Expand All @@ -12,7 +8,7 @@ import { PermissionLevel } from '@graasp/sdk';

import { v4 } from 'uuid';

import { Label, Position } from '@/@types';
import { Label } from '@/@types';
import {
ADD_LABEL_FRAME_HEIGHT,
ADD_LABEL_FRAME_WIDTH,
Expand Down Expand Up @@ -40,32 +36,58 @@ const Container = styled('div')(() => ({
left: '0px',
}));

type Props = {
setFormPosition: (p: Position) => void;
setContent: (s: string) => void;
setLabelToEdit: (l: Label | null) => void;
};
const AddLabelWithinFrame = ({
setFormPosition,
setContent,
setLabelToEdit,
}: Props): JSX.Element => {
const { labels, isDragging, setOpenForm } = useContext(LabelsContext);
const AddLabelWithinFrame = (): JSX.Element => {
const { labels, isDragging, setOpenForm, saveLabelsChanges, openForm } =
useContext(LabelsContext);

const { permission } = useLocalContext();
const [content, setContent] = useState('');
const [labelToEdit, setLabelToEdit] = useState<Label | null>(null);
const [formPosition, setFormPosition] = useState({
y: 0,
x: 0,
});

const handleFormInputChange = (
event: React.ChangeEvent<HTMLInputElement>,
): void => {
setContent(event.target.value);
};

const { instance } = useControls();
const handleShowLabelForm = (show: boolean): void => {
setOpenForm(show);
setContent('');
setLabelToEdit(null);
};

const { scale, positionX, positionY } = instance.transformState;
const handleFormSubmit = (): void => {
if (labelToEdit) {
const newLabel = {
...labelToEdit,
content,
};
saveLabelsChanges(newLabel);
} else {
const id = v4();
const p = {
y: formPosition.y,
x: formPosition.x,
};
const newLabel = { ...p, id, content };
saveLabelsChanges(newLabel);
}
handleShowLabelForm(false);
};

const showLabelForm = (
event: React.MouseEvent<HTMLImageElement, MouseEvent>,
): void => {
if (!isDragging) {
const { offsetX, offsetY } = event.nativeEvent;
setFormPosition({
y: offsetY * scale + positionY,
x: offsetX * scale + positionX,
y: offsetY,
x: offsetX,
});

setOpenForm(true);
setLabelToEdit(null);
setContent('');
Expand All @@ -76,8 +98,8 @@ const AddLabelWithinFrame = ({
setLabelToEdit(label);
const { x, y, content: c } = label;
setFormPosition({
y: y * scale + positionY,
x: x * scale + positionX,
y,
x,
});

setOpenForm(true);
Expand All @@ -91,6 +113,16 @@ const AddLabelWithinFrame = ({
width: ADD_LABEL_FRAME_WIDTH,
}}
>
{permission === PermissionLevel.Admin && openForm && !isDragging && (
<AddLabelForm
value={content}
position={formPosition}
onChange={handleFormInputChange}
onSubmit={handleFormSubmit}
onClose={() => setOpenForm(false)}
labelToDelete={labelToEdit}
/>
)}
<ImageFrame />
<Container onClick={showLabelForm} sx={{ cursor: 'crosshair' }}>
{labels.map((ele) => (
Expand All @@ -108,64 +140,15 @@ const AddLabelWithinFrame = ({
const AddLabelWithinFrameWrapper = (): JSX.Element => {
const { t } = useAppTranslation();

const { isDragging, openForm, setOpenForm, saveLabelsChanges, labels } =
useContext(LabelsContext);
const { isDragging, openForm, labels } = useContext(LabelsContext);
const disabled = isDragging || openForm;

const { permission } = useLocalContext();
const [content, setContent] = useState('');
const [labelToEdit, setLabelToEdit] = useState<Label | null>(null);
const [formPosition, setFormPosition] = useState({
y: 0,
x: 0,
});

const handleFormInputChange = (
event: React.ChangeEvent<HTMLInputElement>,
): void => {
setContent(event.target.value);
};

const handleShowLabelForm = (show: boolean): void => {
setOpenForm(show);
setContent('');
setLabelToEdit(null);
};

const handleFormSubmit = (): void => {
if (labelToEdit) {
const newLabel = {
...labelToEdit,
content,
};
saveLabelsChanges(newLabel);
} else {
const id = v4();
const p = {
y: formPosition.y,
x: formPosition.x,
};
const newLabel = { ...p, id, content };
saveLabelsChanges(newLabel);
}
handleShowLabelForm(false);
};

return (
<Box sx={{ position: 'relative' }}>
{labels.length === 0 && (
<Alert severity="info">{t(APP.START_ADDING_LABEL_HELPER_TEXT)}</Alert>
)}
{permission === PermissionLevel.Admin && openForm && !isDragging && (
<AddLabelForm
value={content}
position={formPosition}
onChange={handleFormInputChange}
onSubmit={handleFormSubmit}
onClose={() => setOpenForm(false)}
labelToDelete={labelToEdit}
/>
)}

<TransformContainer
doubleClick={{ disabled: true }}
centerOnInit
Expand All @@ -182,11 +165,7 @@ const AddLabelWithinFrameWrapper = (): JSX.Element => {
maxHeight: '100%',
}}
>
<AddLabelWithinFrame
setContent={setContent}
setFormPosition={setFormPosition}
setLabelToEdit={setLabelToEdit}
/>
<AddLabelWithinFrame />
</TransformComponent>
</TransformContainer>
</Box>
Expand Down

0 comments on commit 834a82b

Please sign in to comment.