Skip to content

Commit

Permalink
feat: change style of label ections
Browse files Browse the repository at this point in the history
  • Loading branch information
LinaYahya committed Jul 19, 2024
1 parent 4226037 commit 3dd7a57
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 91 deletions.
51 changes: 40 additions & 11 deletions src/modules/builder/configuration/AddLabelsStep/AddLabelForm.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,21 @@
import React from 'react';
import React, { useContext } from 'react';
import { KeepScale } from 'react-zoom-pan-pinch';

import { CloseRounded } from '@mui/icons-material';
import { Box, Button, IconButton, Stack, TextField } from '@mui/material';
import AddIcon from '@mui/icons-material/Add';
import DeleteIcon from '@mui/icons-material/Delete';
import { Box, IconButton, Stack, TextField, useTheme } from '@mui/material';

import { Position } from '@/@types';
import { useAppTranslation } from '@/config/i18n';
import { APP } from '@/langs/constants';
import { Label, Position } from '@/@types';
import { LabelsContext } from '@/modules/context/LabelsContext';

type Props = {
position: Position;
value: string;
onChange: (event: React.ChangeEvent<HTMLInputElement>) => void;
onSubmit: () => void;
onClose: () => void;
labelToDelete?: Label | null;
};

const AddLabelForm = ({
Expand All @@ -22,8 +24,10 @@ const AddLabelForm = ({
onChange,
onSubmit,
onClose,
labelToDelete,
}: Props): JSX.Element => {
const { t } = useAppTranslation();
const theme = useTheme();
const { deleteLabel } = useContext(LabelsContext);

return (
<Stack
Expand All @@ -40,7 +44,6 @@ const AddLabelForm = ({
background: 'black',
opacity: '0.8',
padding: 8,
borderRadius: 4,
}}
>
<Box sx={{ position: 'relative' }}>
Expand All @@ -53,12 +56,16 @@ const AddLabelForm = ({
padding: '2px',
borderRadius: '50%',
background: 'black',
'&:hover': {
background: 'black',
color: 'white',
},
}}
onClick={onClose}
>
<CloseRounded />
</IconButton>
<Box display="flex" alignItems="center" gap={1}>
<Box display="flex" alignItems="center">
<TextField
autoFocus
size="small"
Expand All @@ -72,9 +79,31 @@ const AddLabelForm = ({
}}
multiline
/>
<Button size="small" variant="contained" onClick={onSubmit}>
{t(APP.ADD_LABEL)}
</Button>
<IconButton
onClick={onSubmit}
sx={{
background: theme.palette.primary.main,
borderRadius: 0,
outline: `1px solid ${theme.palette.primary.main}`,
}}
>
<AddIcon sx={{ color: 'white' }} />
</IconButton>
{labelToDelete && (
<IconButton
onClick={() => {
deleteLabel(labelToDelete.id);
onClose();
}}
sx={{
outline: `1px solid ${theme.palette.primary.main}`,
borderRadius: 0,
boxSizing: 'border-box',
}}
>
<DeleteIcon color="primary" sx={{ color: 'white' }} />
</IconButton>
)}
</Box>
</Box>
</KeepScale>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { PermissionLevel } from '@graasp/sdk';

import { v4 } from 'uuid';

import { Label } from '@/@types';
import {
ADD_LABEL_FRAME_HEIGHT,
ADD_LABEL_FRAME_WIDTH,
Expand Down Expand Up @@ -44,6 +45,7 @@ const AddLabelWithinFrame = (): JSX.Element => {
const { instance } = useControls();
const { permission } = useLocalContext();
const [content, setContent] = useState('');
const [labelToEdit, setLabelToEdit] = useState<Label | null>(null);
const [formPosition, setFormPosition] = useState({
y: 0,
x: 0,
Expand All @@ -58,29 +60,25 @@ const AddLabelWithinFrame = (): JSX.Element => {
};

const handleFormSubmit = (): void => {
const editingIndex = labels.findIndex(
({ y, x }) => y === formPosition.y && x === formPosition.x,
);
if (editingIndex > -1) {
const labelToEdit = labels[editingIndex];

if (labelToEdit) {
const newLabel = {
...labelToEdit,
content,
};
saveLabelsChanges(editingIndex, newLabel);
saveLabelsChanges(newLabel);
} else {
const id = v4();
const p = {
y: (formPosition.y - positionY) / scale,
x: (formPosition.x - positionX) / scale,
};
const newLabel = { ...p, id, content };
saveLabelsChanges(editingIndex, newLabel);
saveLabelsChanges(newLabel);
}

setOpenForm(false);
setContent('');
setLabelToEdit(null);
};

const showLabelForm = (
Expand All @@ -94,21 +92,21 @@ const AddLabelWithinFrame = (): JSX.Element => {
});

setOpenForm(true);
setLabelToEdit(null);
setContent('');
}
};

const showEditForm = (labelId: string): void => {
const ele = labels.find(({ id }) => id === labelId);
if (ele) {
const { x, y, content: c } = ele;
setFormPosition({
y: y * scale + positionY,
x: x * scale + positionX,
});
const showEditForm = (label: Label): void => {
setLabelToEdit(label);
const { x, y, content: c } = label;
setFormPosition({
y: y * scale + positionY,
x: x * scale + positionX,
});

setOpenForm(true);
setContent(c);
}
setOpenForm(true);
setContent(c);
};

return (
Expand All @@ -125,6 +123,7 @@ const AddLabelWithinFrame = (): JSX.Element => {
onChange={handleFormInputChange}
onSubmit={handleFormSubmit}
onClose={() => setOpenForm(false)}
labelToDelete={labelToEdit}
/>
)}
<ImageFrame />
Expand Down
80 changes: 21 additions & 59 deletions src/modules/builder/configuration/AddLabelsStep/DraggableLabel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,38 +2,35 @@ import { useContext, useState } from 'react';
import Draggable, { DraggableData, DraggableEvent } from 'react-draggable';
import { useControls } from 'react-zoom-pan-pinch';

import { Delete, Edit } from '@mui/icons-material';
import { Box, IconButton, styled } from '@mui/material';
import { Button, styled } from '@mui/material';

import { Label } from '@/@types';
import { buildLabelActionsID } from '@/config/selectors';
import { LabelsContext } from '@/modules/context/LabelsContext';

const StyledLabel = styled(Box)<{ labelId: string }>(({ theme, labelId }) => ({
const StyledLabel = styled(Button)(({ theme }) => ({
background: theme.palette.primary.main,
color: 'white',
textTransform: 'none',
borderRadius: theme.spacing(1),
userSelect: 'none',
padding: theme.spacing(0.5),
position: 'absolute',
cursor: 'grab',
maxWidth: '12ch',
'&:hover': {
[`#${buildLabelActionsID(labelId)}`]: {
display: 'inline-block',
},
background: theme.palette.primary.main,
},
zIndex: 5,
}));

type Props = {
showEditForm: (id: string) => void;
showEditForm: (l: Label) => void;
label: Label;
};

const DraggableLabel = ({ showEditForm, label }: Props): JSX.Element => {
const [position, setPosition] = useState({ x: label.x, y: label.y });
const { labels, saveLabelsChanges, deleteLabel, setIsDragging } =
const { saveLabelsChanges, setIsDragging, isDragging } =
useContext(LabelsContext);
const { instance } = useControls();
const { scale } = instance.transformState;
Expand All @@ -48,16 +45,12 @@ const DraggableLabel = ({ showEditForm, label }: Props): JSX.Element => {
e.stopPropagation();
e.preventDefault();

const labelInd = labels.findIndex(({ id }) => id === label.id);
if (labelInd > -1) {
const newLabel = { ...label, ...position };
saveLabelsChanges(labelInd, newLabel);

// Set a delay before enabling actions like opening a new form or applying zoom/move to the image frame
setTimeout(() => {
setIsDragging(false);
}, 2000);
}
const newLabel = { ...label, ...position };
// Set a delay before enabling actions like opening a new form or applying zoom/move to the image frame
setTimeout(() => {
setIsDragging(false);
}, 2000);
saveLabelsChanges(newLabel);
};
return (
<Draggable
Expand All @@ -67,47 +60,16 @@ const DraggableLabel = ({ showEditForm, label }: Props): JSX.Element => {
onStop={onStop}
scale={scale}
>
<StyledLabel labelId={label.id}>
<StyledLabel
onClick={(e) => {
if (!isDragging) {
e.stopPropagation();
e.preventDefault();
showEditForm(label);
}
}}
>
{label.content}
<Box
display="flex"
id={buildLabelActionsID(label.id)}
sx={{
position: 'absolute',
top: -24,
right: -10,
display: 'none',
width: 'max-content',
}}
>
<IconButton
sx={{
padding: '4px',
background: '#00000085',
borderRadius: '50%',
}}
onClick={(e) => {
e.stopPropagation();
showEditForm(label.id);
}}
>
<Edit sx={{ color: 'white' }} fontSize="small" />
</IconButton>

<IconButton
sx={{
padding: '4px',
background: '#00000085',
borderRadius: '50%',
}}
onClick={(e) => {
e.stopPropagation();
deleteLabel(label.id);
}}
>
<Delete sx={{ color: 'white' }} fontSize="small" />
</IconButton>
</Box>
</StyledLabel>
</Draggable>
);
Expand Down
5 changes: 3 additions & 2 deletions src/modules/context/LabelsContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ const defaultContextValue = {
export type SettingsContextType = {
labels: Label[];
deleteLabel: (lID: string) => void;
saveLabelsChanges: (idx: number, newLabel: Label) => void;
saveLabelsChanges: (newLabel: Label) => void;
isDragging: boolean;
setIsDragging: (b: boolean) => void;
openForm: boolean;
Expand Down Expand Up @@ -54,7 +54,8 @@ export const LabelsProvider = ({ children }: Props): JSX.Element => {
saveData(filteredLabels);
};

const saveLabelsChanges = (editingIndex: number, newLabel: Label): void => {
const saveLabelsChanges = (newLabel: Label): void => {
const editingIndex = labels.findIndex(({ id }) => id === newLabel.id);
if (editingIndex > -1) {
const newLabelGroups = [
...labels.slice(0, editingIndex),
Expand Down

0 comments on commit 3dd7a57

Please sign in to comment.