Merge pull request #15 from amhsirak/develop
feat: primitive ui components
This commit is contained in:
40
src/components/atoms/AlertSnackbar.tsx
Normal file
40
src/components/atoms/AlertSnackbar.tsx
Normal file
@@ -0,0 +1,40 @@
|
||||
import * as React from 'react';
|
||||
import Snackbar from '@mui/material/Snackbar';
|
||||
import MuiAlert, { AlertProps } from '@mui/material/Alert';
|
||||
import { useGlobalInfoStore } from "../../context/globalInfo";
|
||||
|
||||
const Alert = React.forwardRef<HTMLDivElement, AlertProps>(function Alert(
|
||||
props,
|
||||
ref,
|
||||
) {
|
||||
return <MuiAlert elevation={6} ref={ref} variant="filled" {...props} />;
|
||||
});
|
||||
|
||||
export interface AlertSnackbarProps {
|
||||
severity: 'error' | 'warning' | 'info' | 'success',
|
||||
message: string,
|
||||
isOpen: boolean,
|
||||
};
|
||||
|
||||
export const AlertSnackbar = ({ severity, message, isOpen }: AlertSnackbarProps) => {
|
||||
const [open, setOpen] = React.useState(isOpen);
|
||||
|
||||
const { closeNotify } = useGlobalInfoStore();
|
||||
|
||||
const handleClose = (event?: React.SyntheticEvent | Event, reason?: string) => {
|
||||
if (reason === 'clickaway') {
|
||||
return;
|
||||
}
|
||||
|
||||
closeNotify();
|
||||
setOpen(false);
|
||||
};
|
||||
|
||||
return (
|
||||
<Snackbar anchorOrigin={{ vertical: 'top', horizontal: 'center' }} open={open} autoHideDuration={5000} onClose={handleClose}>
|
||||
<Alert onClose={handleClose} severity={severity} sx={{ width: '100%' }}>
|
||||
{message}
|
||||
</Alert>
|
||||
</Snackbar>
|
||||
);
|
||||
}
|
||||
25
src/components/atoms/Box.tsx
Normal file
25
src/components/atoms/Box.tsx
Normal file
@@ -0,0 +1,25 @@
|
||||
import * as React from 'react';
|
||||
import Box from '@mui/material/Box';
|
||||
|
||||
interface BoxProps {
|
||||
width: number | string,
|
||||
height: number | string,
|
||||
background: string,
|
||||
radius: string,
|
||||
children?: JSX.Element,
|
||||
};
|
||||
|
||||
export const SimpleBox = ({ width, height, background, radius, children }: BoxProps) => {
|
||||
return (
|
||||
<Box
|
||||
sx={{
|
||||
width: width,
|
||||
height: height,
|
||||
backgroundColor: background,
|
||||
borderRadius: radius,
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
29
src/components/atoms/DropdownMui.tsx
Normal file
29
src/components/atoms/DropdownMui.tsx
Normal file
@@ -0,0 +1,29 @@
|
||||
import React from 'react';
|
||||
import { FormControl, InputLabel, Select } from "@mui/material";
|
||||
import { SelectChangeEvent } from "@mui/material/Select/Select";
|
||||
|
||||
interface DropdownProps {
|
||||
id: string;
|
||||
label: string;
|
||||
value: string | undefined;
|
||||
handleSelect: (event: SelectChangeEvent) => void;
|
||||
children?: React.ReactNode;
|
||||
};
|
||||
|
||||
export const Dropdown = ({ id, label, value, handleSelect, children }: DropdownProps) => {
|
||||
return (
|
||||
<FormControl sx={{ minWidth: 120 }} size="small">
|
||||
<InputLabel id={id}>{label}</InputLabel>
|
||||
<Select
|
||||
labelId={id}
|
||||
name={id}
|
||||
value={value}
|
||||
label={label}
|
||||
onChange={handleSelect}
|
||||
size='small'
|
||||
>
|
||||
{children}
|
||||
</Select>
|
||||
</FormControl>
|
||||
);
|
||||
};
|
||||
44
src/components/atoms/GenericModal.tsx
Normal file
44
src/components/atoms/GenericModal.tsx
Normal file
@@ -0,0 +1,44 @@
|
||||
import React, { FC } from 'react';
|
||||
import { Modal, IconButton, Box } from '@mui/material';
|
||||
import { Clear } from "@mui/icons-material";
|
||||
|
||||
interface ModalProps {
|
||||
isOpen: boolean;
|
||||
onClose: () => void;
|
||||
children?: JSX.Element;
|
||||
modalStyle?: React.CSSProperties;
|
||||
canBeClosed?: boolean;
|
||||
}
|
||||
|
||||
export const GenericModal: FC<ModalProps> = (
|
||||
{ isOpen, onClose, children, modalStyle, canBeClosed = true }) => {
|
||||
|
||||
return (
|
||||
<Modal open={isOpen} onClose={canBeClosed ? onClose : () => { }} >
|
||||
<Box sx={modalStyle ? { ...modalStyle, boxShadow: 24, position: 'absolute', } : defaultModalStyle}>
|
||||
{canBeClosed ?
|
||||
<IconButton onClick={onClose} sx={{ float: "right" }}>
|
||||
<Clear sx={{ fontSize: 20 }} />
|
||||
</IconButton>
|
||||
: null
|
||||
}
|
||||
{children}
|
||||
</Box>
|
||||
</Modal>
|
||||
);
|
||||
};
|
||||
|
||||
const defaultModalStyle = {
|
||||
position: 'absolute',
|
||||
top: '50%',
|
||||
left: '50%',
|
||||
transform: 'translate(-50%, -50%)',
|
||||
width: 500,
|
||||
bgcolor: 'background.paper',
|
||||
boxShadow: 24,
|
||||
p: 4,
|
||||
height: '60%',
|
||||
display: 'block',
|
||||
overflow: 'scroll',
|
||||
padding: '5px 25px 10px 25px',
|
||||
};
|
||||
52
src/components/atoms/KeyValuePair.tsx
Normal file
52
src/components/atoms/KeyValuePair.tsx
Normal file
@@ -0,0 +1,52 @@
|
||||
import React, { forwardRef, useImperativeHandle } from "react";
|
||||
import { Box, TextField } from "@mui/material";
|
||||
|
||||
interface KeyValueFormProps {
|
||||
keyLabel?: string;
|
||||
valueLabel?: string;
|
||||
}
|
||||
|
||||
export const KeyValuePair = forwardRef(({ keyLabel, valueLabel }: KeyValueFormProps, ref) => {
|
||||
const [key, setKey] = React.useState<string>('');
|
||||
const [value, setValue] = React.useState<string | number>('');
|
||||
useImperativeHandle(ref, () => ({
|
||||
getKeyValuePair() {
|
||||
return { key, value };
|
||||
}
|
||||
}));
|
||||
return (
|
||||
<Box
|
||||
component="form"
|
||||
sx={{
|
||||
'& > :not(style)': { m: 1, width: '100px' },
|
||||
}}
|
||||
noValidate
|
||||
autoComplete="off"
|
||||
>
|
||||
<TextField
|
||||
id="outlined-name"
|
||||
label={keyLabel || "Key"}
|
||||
value={key}
|
||||
onChange={(event: React.ChangeEvent<HTMLInputElement>) => setKey(event.target.value)}
|
||||
size="small"
|
||||
required
|
||||
/>
|
||||
<TextField
|
||||
id="outlined-name"
|
||||
label={valueLabel || "Value"}
|
||||
value={value}
|
||||
onChange={(event: React.ChangeEvent<HTMLInputElement>) => {
|
||||
const num = Number(event.target.value);
|
||||
if (isNaN(num)) {
|
||||
setValue(event.target.value);
|
||||
}
|
||||
else {
|
||||
setValue(num);
|
||||
}
|
||||
}}
|
||||
size="small"
|
||||
required
|
||||
/>
|
||||
</Box>
|
||||
);
|
||||
});
|
||||
86
src/components/atoms/Loader.tsx
Normal file
86
src/components/atoms/Loader.tsx
Normal file
@@ -0,0 +1,86 @@
|
||||
import styled from "styled-components";
|
||||
import { Stack } from "@mui/material";
|
||||
|
||||
export const Loader = () => {
|
||||
return (
|
||||
<Stack direction="column" sx={{ margin: "30px 0px 291px 0px" }}>
|
||||
<StyledLoader />
|
||||
<StyledParagraph>
|
||||
Loading...
|
||||
</StyledParagraph>
|
||||
</Stack>
|
||||
);
|
||||
}
|
||||
|
||||
const StyledParagraph = styled.p`
|
||||
font-size: x-large;
|
||||
font-family: inherit;
|
||||
color: #1976d2;
|
||||
display: grid;
|
||||
justify-content: center;
|
||||
`;
|
||||
|
||||
const StyledLoader = styled.div`
|
||||
border-radius: 50%;
|
||||
color: #1976d2;
|
||||
font-size: 11px;
|
||||
text-indent: -99999em;
|
||||
margin: 55px auto;
|
||||
position: relative;
|
||||
width: 10em;
|
||||
height: 10em;
|
||||
box-shadow: inset 0 0 0 1em;
|
||||
-webkit-transform: translateZ(0);
|
||||
-ms-transform: translateZ(0);
|
||||
transform: translateZ(0);
|
||||
&:before {
|
||||
position: absolute;
|
||||
content: '';
|
||||
border-radius: 50%;
|
||||
width: 5.2em;
|
||||
height: 10.2em;
|
||||
background: #ffffff;
|
||||
border-radius: 10.2em 0 0 10.2em;
|
||||
top: -0.1em;
|
||||
left: -0.1em;
|
||||
-webkit-transform-origin: 5.1em 5.1em;
|
||||
transform-origin: 5.1em 5.1em;
|
||||
-webkit-animation: load2 2s infinite ease 1.5s;
|
||||
animation: load2 2s infinite ease 1.5s;
|
||||
}
|
||||
&:after {
|
||||
position: absolute;
|
||||
content: '';
|
||||
border-radius: 50%;
|
||||
width: 5.2em;
|
||||
height: 10.2em;
|
||||
background: #ffffff;
|
||||
border-radius: 0 10.2em 10.2em 0;
|
||||
top: -0.1em;
|
||||
left: 4.9em;
|
||||
-webkit-transform-origin: 0.1em 5.1em;
|
||||
transform-origin: 0.1em 5.1em;
|
||||
-webkit-animation: load2 2s infinite ease;
|
||||
animation: load2 2s infinite ease;
|
||||
}
|
||||
@-webkit-keyframes load2 {
|
||||
0% {
|
||||
-webkit-transform: rotate(0deg);
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
100% {
|
||||
-webkit-transform: rotate(360deg);
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
@keyframes load2 {
|
||||
0% {
|
||||
-webkit-transform: rotate(0deg);
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
100% {
|
||||
-webkit-transform: rotate(360deg);
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
`;
|
||||
42
src/components/atoms/PairDisplayDiv.tsx
Normal file
42
src/components/atoms/PairDisplayDiv.tsx
Normal file
@@ -0,0 +1,42 @@
|
||||
import React, { FC } from 'react';
|
||||
import Typography from '@mui/material/Typography';
|
||||
import { WhereWhatPair } from "@wbr-project/wbr-interpret";
|
||||
import styled from "styled-components";
|
||||
|
||||
interface PairDisplayDivProps {
|
||||
index: string;
|
||||
pair: WhereWhatPair;
|
||||
}
|
||||
|
||||
export const PairDisplayDiv: FC<PairDisplayDivProps> = ({ index, pair }) => {
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Typography sx={{ marginBottom: '10px', marginTop: '25px' }} id="pair-index" variant="h6" component="h2">
|
||||
{`Index: ${index}`}
|
||||
{pair.id ? `, Id: ${pair.id}` : ''}
|
||||
</Typography>
|
||||
<Typography id="where-title" variant="h6" component="h2">
|
||||
{"Where:"}
|
||||
</Typography>
|
||||
<DescriptionWrapper id="where-description">
|
||||
<pre>{JSON.stringify(pair?.where, undefined, 2)}</pre>
|
||||
</DescriptionWrapper>
|
||||
<Typography id="what-title" variant="h6" component="h2">
|
||||
{"What:"}
|
||||
</Typography>
|
||||
<DescriptionWrapper id="what-description">
|
||||
<pre>{JSON.stringify(pair?.what, undefined, 2)}</pre>
|
||||
</DescriptionWrapper>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
const DescriptionWrapper = styled.div`
|
||||
margin: 0;
|
||||
font-family: "Roboto","Helvetica","Arial",sans-serif;
|
||||
font-weight: 400;
|
||||
font-size: 1rem;
|
||||
line-height: 1.5;
|
||||
letter-spacing: 0.00938em;
|
||||
`;
|
||||
23
src/components/atoms/RecorderIcon.tsx
Normal file
23
src/components/atoms/RecorderIcon.tsx
Normal file
@@ -0,0 +1,23 @@
|
||||
import React from 'react';
|
||||
|
||||
export const RecordingIcon = () => {
|
||||
return (
|
||||
<svg style={{ height: '40px', marginLeft: '10px', }} viewBox="0 0 135 142.52057103247057">
|
||||
<g transform="translate(-21.574303538824683, -17.80925413300834) scale(1.7814908278702266)"
|
||||
className="css-1mun45u" fill="#111111">
|
||||
<g xmlns="http://www.w3.org/2000/svg" transform="translate(0,-952.36218)">
|
||||
<path
|
||||
style={{
|
||||
baselineShift: 'baseline',
|
||||
color: "white",
|
||||
direction: 'ltr',
|
||||
textIndent: 0,
|
||||
textTransform: 'none',
|
||||
}}
|
||||
fill="white"
|
||||
d="m82.048,962.36c-0.18271-0.003-0.35147-0.001-0.53125,0.0312-0.69633,0.12662-1.3353,0.54943-1.7812,1.1562l-0.03125-0.0312-0.03125,0.0625-18.031,22.125h-44.438c-2.809,0-5.0938,2.2847-5.0938,5.0938v35.531c0,2.8091,2.2847,5.125,5.0938,5.125h20.562l-1.3125,4.5938h-0.71875c-1.1137,0-2.0312,0.9175-2.0312,2.0312v2.2188c0,1.1137,0.91751,2.0625,2.0312,2.0625h19.938c1.1137,0,2.0312-0.9488,2.0312-2.0625v-2.2188c0-1.1137-0.91751-2.0312-2.0312-2.0312h-0.71875l-1.3438-4.5938h20.438c2.809,0,5.0938-2.3159,5.0938-5.125v-35.531c0-1.7706-0.90663-3.3369-2.2812-4.25l10.531-17.625,0.03125-0.0625c0.84234-1.2783,0.51486-3.0308-0.75-3.9062l-3.0312-2.0938c-0.48208-0.33338-1.0456-0.49073-1.5938-0.5zm-0.21875,1.6875c0.28723-0.0523,0.57635,0.0338,0.84375,0.21875l3.0312,2.0938c0.53421,0.36973,0.65504,1.0569,0.28125,1.5938a0.85008,0.85008,0,0,0,-0.03125,0.0312l-17.906,30.062-9.0938-6.3125,22.094-27.125a0.85008,0.85008,0,0,0,0.03125,-0.0625c0.18694-0.26873,0.46277-0.4477,0.75-0.5zm-64.625,23.344,43.062,0-2.3438,2.9062-40.688,0c-0.0312-0.002-0.06255-0.002-0.09375,0-0.0312-0.002-0.06255-0.002-0.09375,0-0.38644,0.0753-0.69183,0.45007-0.6875,0.84375v34.844c0.003,0.4514,0.42377,0.857,0.875,0.8437h56.781c0.44088,0,0.84048-0.4028,0.84375-0.8437v-34.844c-0.008-0.25538-0.13841-0.50419-0.34375-0.65625l1.5-2.5c0.87419,0.61342,1.4375,1.6512,1.4375,2.8125v35.531c0,1.8967-1.5096,3.4063-3.4062,3.4063h-56.844c-1.8966,0-3.4062-1.5096-3.4062-3.4063v-35.531c0-1.8966,1.5096-3.4062,3.4062-3.4062zm0.875,4.5938,38.469,0-1.0312,1.25,0,0.0312c-0.48971,0.60518-0.64056,1.3922-0.5,2.0312,0.14234,0.64722,0.49536,1.1659,0.84375,1.6562a0.85008,0.85008,0,0,0,0.1875,0.21875l1.2812,0.875c-1.0387,0.79518-2.0706,1.1661-3.2188,1.6562-1.4337,0.61212-3.0045,1.4512-4.3438,3.375-1.1451,1.6448-1.0525,3.5446-0.78125,5.3437,0.27121,1.7991,0.70152,3.5802,0.5625,5.2188a0.85008,0.85008,0,0,0,1.2188,0.8437c1.4928-0.7039,3.3085-0.9361,5.0938-1.3125s3.6049-0.9489,4.75-2.5937c1.34-1.9249,1.5559-3.6628,1.625-5.2188,0.05552-1.2502,0.05447-2.363,0.4375-3.625l1.2812,0.875c1.2744,0.8814,3.0499,0.4785,3.8438-0.8437l0.03125-0.031,1.125-1.9063a0.85008,0.85008,0,0,0,0.03125,-0.0312l0.03125-0.0312a0.85008,0.85008,0,0,0,0.09375,-0.21875l4.0625-6.8125v32.406h-55.094v-33.156zm39.812,1.0625,9.3125,6.4375-0.84375,1.4062a0.85008,0.85008,0,0,0,-0.03125,0c-0.33037,0.5726-0.86691,0.7168-1.4062,0.3438l-2.1875-1.5-0.1875-0.15625-0.65625-0.4375-1.8438-1.2812-0.84375-0.59375-0.0625-0.0312-1.9688-1.3438c-0.25075-0.36937-0.4494-0.7387-0.5-0.96875-0.0558-0.25371-0.0497-0.34572,0.15625-0.59375l1.0625-1.2812zm0.84375,5.9688,0.34375,0.25,1.8438,1.25,0.375,0.25c-0.60662,1.6994-0.69236,3.2017-0.75,4.5-0.0657,1.481-0.18871,2.7295-1.3125,4.3438-0.76502,1.0988-2.0465,1.5537-3.7188,1.9062-1.3283,0.2801-2.854,0.5618-4.3438,1.0625-0.0521-1.5631-0.29881-3.0716-0.5-4.4062-0.25388-1.6841-0.29624-3.0262,0.46875-4.125,1.1246-1.6154,2.2602-2.1673,3.625-2.75,1.1932-0.5094,2.5901-1.1274,3.9688-2.2813zm-30.5,2.5313c-1.6815,0-3.0625,1.4119-3.0625,3.0937s1.381,3.0313,3.0625,3.0313,3.0625-1.3495,3.0625-3.0313-1.381-3.0937-3.0625-3.0937zm0,1.7187c0.76283,0,1.375,0.612,1.375,1.375s-0.61217,1.3438-1.375,1.3438-1.3438-0.5808-1.3438-1.3438,0.58092-1.375,1.3438-1.375zm8,5.6563c-3.3379,0.1812-7.1915,2.4749-10.344,4.6875-3.1522,2.2126-5.5625,4.4062-5.5625,4.4062-0.3273,0.3027-0.36527,0.8915-0.0625,1.2188,0.30273,0.3272,0.89151,0.334,1.2188,0.031,0,0,2.3185-2.1046,5.375-4.25s6.8989-4.2667,9.4688-4.4063c1.6177-0.088,4.3314,1.0381,6.5312,2.25,2.1999,1.212,3.9375,2.4375,3.9375,2.4375,0.35264,0.3353,1.001,0.2728,1.2812-0.125,0.28024-0.3977,0.12188-1.0307-0.3125-1.25,0,0-1.7602-1.2941-4.0625-2.5625-2.3024-1.2684-5.0831-2.567-7.4688-2.4375zm3.2812,22.562,12.344,0,1.3438,4.5312-15,0,1.3125-4.5312zm-3.7812,6.25,19.938,0c0.20135,0,0.3125,0.1424,0.3125,0.3437v2.2188c0,0.2013-0.11115,0.3437-0.3125,0.3437h-19.938c-0.20135,0-0.34375-0.1424-0.34375-0.3437v-2.2188c0-0.2013,0.1424-0.3437,0.34375-0.3437z" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
36
src/components/atoms/buttons/AddButton.tsx
Normal file
36
src/components/atoms/buttons/AddButton.tsx
Normal file
@@ -0,0 +1,36 @@
|
||||
import { IconButton } from "@mui/material";
|
||||
import { Add } from "@mui/icons-material";
|
||||
import React, { FC } from "react";
|
||||
|
||||
interface AddButtonProps {
|
||||
handleClick: () => void;
|
||||
size?: "small" | "medium" | "large";
|
||||
title?: string;
|
||||
disabled?: boolean;
|
||||
hoverEffect?: boolean;
|
||||
style?: React.CSSProperties;
|
||||
}
|
||||
|
||||
export const AddButton: FC<AddButtonProps> = (
|
||||
{ handleClick,
|
||||
size,
|
||||
title,
|
||||
disabled = false,
|
||||
hoverEffect = true,
|
||||
style
|
||||
}) => {
|
||||
return (
|
||||
<IconButton
|
||||
aria-label="add"
|
||||
size={size || "small"}
|
||||
onClick={handleClick}
|
||||
disabled={disabled}
|
||||
sx={hoverEffect
|
||||
? { ...style, '&:hover': { background: 'rgba(0, 0, 0, 0.05)', color: 'rgba(0, 0, 0, 0.54)' } }
|
||||
: { ...style, '&:hover': { color: '#1976d2', backgroundColor: 'white' } }
|
||||
}
|
||||
>
|
||||
<Add /> {title}
|
||||
</IconButton>
|
||||
);
|
||||
};
|
||||
30
src/components/atoms/buttons/BreakpointButton.tsx
Normal file
30
src/components/atoms/buttons/BreakpointButton.tsx
Normal file
@@ -0,0 +1,30 @@
|
||||
import { IconButton } from "@mui/material";
|
||||
import { Circle } from "@mui/icons-material";
|
||||
|
||||
interface BreakpointButtonProps {
|
||||
handleClick: () => void;
|
||||
size?: "small" | "medium" | "large";
|
||||
changeColor?: boolean;
|
||||
}
|
||||
|
||||
export const BreakpointButton =
|
||||
({ handleClick, size, changeColor }: BreakpointButtonProps) => {
|
||||
return (
|
||||
<IconButton aria-label="add" size={size || "small"} onClick={handleClick}
|
||||
sx={{
|
||||
"&:hover": {
|
||||
background: 'transparent',
|
||||
}
|
||||
}}
|
||||
>
|
||||
<Circle sx={{
|
||||
fontSize: '1rem',
|
||||
marginLeft: '5px',
|
||||
color: changeColor ? 'red' : 'gray',
|
||||
"&:hover": {
|
||||
color: changeColor ? 'darkRed' : 'dimgray',
|
||||
}
|
||||
}} />
|
||||
</IconButton>
|
||||
);
|
||||
};
|
||||
17
src/components/atoms/buttons/ClearButton.tsx
Normal file
17
src/components/atoms/buttons/ClearButton.tsx
Normal file
@@ -0,0 +1,17 @@
|
||||
import { IconButton } from "@mui/material";
|
||||
import { Clear } from "@mui/icons-material";
|
||||
import React, { FC } from "react";
|
||||
|
||||
interface ClearButtonProps {
|
||||
handleClick: () => void;
|
||||
size?: "small" | "medium" | "large";
|
||||
}
|
||||
|
||||
export const ClearButton: FC<ClearButtonProps> = ({ handleClick, size }) => {
|
||||
return (
|
||||
<IconButton aria-label="add" size={size || "small"} onClick={handleClick}
|
||||
sx={{ color: 'inherit', '&:hover': { color: '#1976d2', backgroundColor: 'transparent' } }}>
|
||||
<Clear />
|
||||
</IconButton>
|
||||
);
|
||||
};
|
||||
17
src/components/atoms/buttons/EditButton.tsx
Normal file
17
src/components/atoms/buttons/EditButton.tsx
Normal file
@@ -0,0 +1,17 @@
|
||||
import { IconButton } from "@mui/material";
|
||||
import { Edit } from "@mui/icons-material";
|
||||
import React, { FC } from "react";
|
||||
|
||||
interface EditButtonProps {
|
||||
handleClick: () => void;
|
||||
size?: "small" | "medium" | "large";
|
||||
}
|
||||
|
||||
export const EditButton: FC<EditButtonProps> = ({ handleClick, size }) => {
|
||||
return (
|
||||
<IconButton aria-label="add" size={size || "small"} onClick={handleClick}
|
||||
sx={{ color: 'inherit', '&:hover': { color: '#1976d2', backgroundColor: 'transparent' } }}>
|
||||
<Edit />
|
||||
</IconButton>
|
||||
);
|
||||
};
|
||||
17
src/components/atoms/buttons/RemoveButton.tsx
Normal file
17
src/components/atoms/buttons/RemoveButton.tsx
Normal file
@@ -0,0 +1,17 @@
|
||||
import { IconButton } from "@mui/material";
|
||||
import { Remove } from "@mui/icons-material";
|
||||
import React, { FC } from "react";
|
||||
|
||||
interface RemoveButtonProps {
|
||||
handleClick: () => void;
|
||||
size?: "small" | "medium" | "large";
|
||||
}
|
||||
|
||||
export const RemoveButton: FC<RemoveButtonProps> = ({ handleClick, size }) => {
|
||||
return (
|
||||
<IconButton aria-label="add" size={size || "small"} onClick={handleClick}
|
||||
sx={{ '&:hover': { color: '#1976d2', backgroundColor: 'transparent' } }}>
|
||||
<Remove />
|
||||
</IconButton>
|
||||
);
|
||||
};
|
||||
@@ -1,22 +1,16 @@
|
||||
import React, {useCallback, useEffect, useRef} from 'react';
|
||||
import React, { useCallback, useEffect, useRef } from 'react';
|
||||
import { useSocketStore } from '../../context/socket';
|
||||
import { getMappedCoordinates } from "../../helpers/inputHelpers";
|
||||
import { useGlobalInfoStore } from "../../context/globalInfo";
|
||||
|
||||
interface CreateRefCallback {
|
||||
|
||||
(ref: React.RefObject<HTMLCanvasElement>): void;
|
||||
|
||||
}
|
||||
|
||||
interface CanvasProps {
|
||||
|
||||
width: number;
|
||||
|
||||
height: number;
|
||||
|
||||
onCreateRef: CreateRefCallback;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -40,7 +34,7 @@ const Canvas = ({ width, height, onCreateRef }: CanvasProps) => {
|
||||
};
|
||||
|
||||
const lastMousePosition = useRef<Coordinates>({ x: 0, y: 0 });
|
||||
//const lastWheelPosition = useRef<ScrollDeltas>({ deltaX: 0, deltaY: 0 });
|
||||
//const lastWheelPosition = useRef<ScrollDeltas>({ deltaX: 0, deltaY: 0 });
|
||||
|
||||
const onMouseEvent = useCallback((event: MouseEvent) => {
|
||||
if (socket) {
|
||||
@@ -57,12 +51,12 @@ const Canvas = ({ width, height, onCreateRef }: CanvasProps) => {
|
||||
case 'mousemove':
|
||||
const coordinates = getMappedCoordinates(event, canvasRef.current, width, height);
|
||||
if (lastMousePosition.current.x !== coordinates.x ||
|
||||
lastMousePosition.current.y !== coordinates.y) {
|
||||
lastMousePosition.current.y !== coordinates.y) {
|
||||
lastMousePosition.current = {
|
||||
x: coordinates.x,
|
||||
y: coordinates.y,
|
||||
};
|
||||
socket.emit('input:mousemove', {
|
||||
socket.emit('input:mousemove', {
|
||||
x: coordinates.x,
|
||||
y: coordinates.y,
|
||||
});
|
||||
@@ -122,21 +116,21 @@ const Canvas = ({ width, height, onCreateRef }: CanvasProps) => {
|
||||
}
|
||||
|
||||
};
|
||||
}else {
|
||||
} else {
|
||||
console.log('Canvas not initialized');
|
||||
}
|
||||
|
||||
}, [onMouseEvent]);
|
||||
|
||||
return (
|
||||
// <canvas tabIndex={0} ref={canvasRef} height={height} width={width} />
|
||||
<canvas
|
||||
tabIndex={0}
|
||||
ref={canvasRef}
|
||||
height={720}
|
||||
width={1280}
|
||||
style={{ width: '1280px', height: '720px' }} // Ensure dimensions are explicitly set
|
||||
/>
|
||||
// <canvas tabIndex={0} ref={canvasRef} height={height} width={width} />
|
||||
<canvas
|
||||
tabIndex={0}
|
||||
ref={canvasRef}
|
||||
height={720}
|
||||
width={1280}
|
||||
style={{ width: '1280px', height: '720px' }} // Ensure dimensions are explicitly set
|
||||
/>
|
||||
);
|
||||
|
||||
};
|
||||
|
||||
15
src/components/atoms/texts.tsx
Normal file
15
src/components/atoms/texts.tsx
Normal file
@@ -0,0 +1,15 @@
|
||||
import styled from "styled-components";
|
||||
|
||||
export const WarningText = styled.p`
|
||||
border: 1px solid orange;
|
||||
display: flex;
|
||||
margin: 10px;
|
||||
flex-direction: column;
|
||||
font-size: small;
|
||||
background: rgba(255,165,0,0.15);
|
||||
padding: 5px;
|
||||
font-family: "Roboto","Helvetica","Arial",sans-serif;
|
||||
font-weight: 400;
|
||||
line-height: 1.5;
|
||||
letter-spacing: 0.00938em;
|
||||
`
|
||||
Reference in New Issue
Block a user