feat: new SliderOptions logic

This commit is contained in:
IlyaDoronin 2023-12-19 14:23:09 +03:00
parent 2828a5ebe2
commit 860c883037
3 changed files with 72 additions and 45 deletions

@ -1,4 +1,4 @@
import { useState } from "react"; import { useEffect, useState } from "react";
import { Box, Typography, useMediaQuery, useTheme } from "@mui/material"; import { Box, Typography, useMediaQuery, useTheme } from "@mui/material";
import ButtonsOptions from "../ButtonsOptions"; import ButtonsOptions from "../ButtonsOptions";
import CustomNumberField from "@ui_kit/CustomNumberField"; import CustomNumberField from "@ui_kit/CustomNumberField";
@ -16,6 +16,22 @@ export default function SliderOptions({ question }: Props) {
const isMobile = useMediaQuery(theme.breakpoints.down(790)); const isMobile = useMediaQuery(theme.breakpoints.down(790));
const [switchState, setSwitchState] = useState("setting"); const [switchState, setSwitchState] = useState("setting");
const [stepError, setStepError] = useState(""); const [stepError, setStepError] = useState("");
const [startError, setStartError] = useState<boolean>(false);
useEffect(() => {
const min = Number(question.content.range.split("—")[0]);
const max = Number(question.content.range.split("—")[1]);
const start = Number(question.content.start);
console.log(min, max, start);
if (start < min || start > max) {
setStartError(true);
}
if (start >= min && start <= max) {
setStartError(false);
}
}, [question.content.range, question.content.start]);
const SSHC = (data: string) => { const SSHC = (data: string) => {
setSwitchState(data); setSwitchState(data);
@ -44,10 +60,19 @@ export default function SliderOptions({ question }: Props) {
marginRight: isMobile ? "10px" : "0px", marginRight: isMobile ? "10px" : "0px",
}} }}
> >
<Typography sx={{ fontWeight: "500", fontSize: "18px", color: "#4D4D4D" }}> <Typography
sx={{ fontWeight: "500", fontSize: "18px", color: "#4D4D4D" }}
>
Выбор значения из диапазона Выбор значения из диапазона
</Typography> </Typography>
<Box sx={{ width: "100%", display: "flex", alignItems: "center", gap: isMobile ? "9px" : "20px" }}> <Box
sx={{
width: "100%",
display: "flex",
alignItems: "center",
gap: isMobile ? "9px" : "20px",
}}
>
<CustomNumberField <CustomNumberField
sx={{ maxWidth: "310px", width: "100%" }} sx={{ maxWidth: "310px", width: "100%" }}
placeholder={"0"} placeholder={"0"}
@ -58,11 +83,12 @@ export default function SliderOptions({ question }: Props) {
updateQuestion(question.id, (question) => { updateQuestion(question.id, (question) => {
if (question.type !== "number") return; if (question.type !== "number") return;
question.content.range = `${target.value}${question.content.range.split("—")[1]}`; question.content.range = `${target.value}${
question.content.range.split("—")[1]
}`;
}); });
}} }}
onBlur={({ target }) => { onBlur={({ target }) => {
const start = question.content.start;
const min = Number(target.value); const min = Number(target.value);
const max = Number(question.content.range.split("—")[1]); const max = Number(question.content.range.split("—")[1]);
@ -70,15 +96,9 @@ export default function SliderOptions({ question }: Props) {
updateQuestion(question.id, (question) => { updateQuestion(question.id, (question) => {
if (question.type !== "number") return; if (question.type !== "number") return;
question.content.range = `${max - 1 >= 0 ? max - 1 : 0}${question.content.range.split("—")[1]}`; question.content.range = `${max - 1 >= 0 ? max - 1 : 0}${
}); question.content.range.split("—")[1]
} }`;
if (start < min) {
updateQuestion(question.id, (question) => {
if (question.type !== "number") return;
question.content.start = min;
}); });
} }
}} }}
@ -94,11 +114,12 @@ export default function SliderOptions({ question }: Props) {
updateQuestion(question.id, (question) => { updateQuestion(question.id, (question) => {
if (question.type !== "number") return; if (question.type !== "number") return;
question.content.range = `${question.content.range.split("—")[0]}${target.value}`; question.content.range = `${
question.content.range.split("—")[0]
}${target.value}`;
}); });
}} }}
onBlur={({ target }) => { onBlur={({ target }) => {
const start = question.content.start;
const step = question.content.step; const step = question.content.step;
const min = Number(question.content.range.split("—")[0]); const min = Number(question.content.range.split("—")[0]);
const max = Number(target.value); const max = Number(target.value);
@ -108,15 +129,9 @@ export default function SliderOptions({ question }: Props) {
updateQuestion(question.id, (question) => { updateQuestion(question.id, (question) => {
if (question.type !== "number") return; if (question.type !== "number") return;
question.content.range = `${min}${min + 1 >= 100 ? 100 : min + 1}`; question.content.range = `${min}${
}); min + 1 >= 100 ? 100 : min + 1
} }`;
if (start > max) {
updateQuestion(question.id, (question) => {
if (question.type !== "number") return;
question.content.start = max;
}); });
} }
@ -128,7 +143,11 @@ export default function SliderOptions({ question }: Props) {
}); });
if (range % step) { if (range % step) {
setStepError(`Шаг должен делить без остатка диапазон ${max} - ${min} = ${max - min}`); setStepError(
`Шаг должен делить без остатка диапазон ${max} - ${min} = ${
max - min
}`
);
} else { } else {
setStepError(""); setStepError("");
} }
@ -147,7 +166,14 @@ export default function SliderOptions({ question }: Props) {
}} }}
> >
<Box sx={{ width: "100%" }}> <Box sx={{ width: "100%" }}>
<Typography sx={{ fontWeight: "500", fontSize: "18px", color: "#4D4D4D", mb: isMobile ? "10px" : "14px" }}> <Typography
sx={{
fontWeight: "500",
fontSize: "18px",
color: "#4D4D4D",
mb: isMobile ? "10px" : "14px",
}}
>
Начальное значение Начальное значение
</Typography> </Typography>
<CustomNumberField <CustomNumberField
@ -156,6 +182,7 @@ export default function SliderOptions({ question }: Props) {
min={Number(question.content.range.split("—")[0])} min={Number(question.content.range.split("—")[0])}
max={Number(question.content.range.split("—")[1])} max={Number(question.content.range.split("—")[1])}
value={String(question.content.start)} value={String(question.content.start)}
emptyError={startError}
onChange={({ target }) => { onChange={({ target }) => {
updateQuestion(question.id, (question) => { updateQuestion(question.id, (question) => {
if (question.type !== "number") return; if (question.type !== "number") return;
@ -205,7 +232,11 @@ export default function SliderOptions({ question }: Props) {
} }
if (range % step) { if (range % step) {
setStepError(`Шаг должен делить без остатка диапазон ${max} - ${min} = ${max - min}`); setStepError(
`Шаг должен делить без остатка диапазон ${max} - ${min} = ${
max - min
}`
);
} else { } else {
setStepError(""); setStepError("");
} }
@ -214,7 +245,11 @@ export default function SliderOptions({ question }: Props) {
</Box> </Box>
</Box> </Box>
</Box> </Box>
<ButtonsOptions switchState={switchState} SSHC={SSHC} question={question} /> <ButtonsOptions
switchState={switchState}
SSHC={SSHC}
question={question}
/>
<SwitchSlider switchState={switchState} question={question} /> <SwitchSlider switchState={switchState} question={question} />
</> </>
); );

@ -9,6 +9,7 @@ interface CustomNumberFieldProps {
onKeyDown?: (event: KeyboardEvent<HTMLInputElement>) => void; onKeyDown?: (event: KeyboardEvent<HTMLInputElement>) => void;
onBlur?: (event: FocusEvent<HTMLInputElement>) => void; onBlur?: (event: FocusEvent<HTMLInputElement>) => void;
error?: string; error?: string;
emptyError?: boolean;
value: string; value: string;
sx?: SxProps<Theme>; sx?: SxProps<Theme>;
min?: number; min?: number;
@ -20,6 +21,7 @@ export default function CustomNumberField({
value, value,
sx, sx,
error, error,
emptyError,
onChange, onChange,
onKeyDown, onKeyDown,
onBlur, onBlur,
@ -34,32 +36,20 @@ export default function CustomNumberField({
inputValue.match(/^\d*$/) || inputValue.match(/^\d*$/) ||
(inputValue[0] === "-" && inputValue.slice(1).match(/^\d*$/)) (inputValue[0] === "-" && inputValue.slice(1).match(/^\d*$/))
) { ) {
console.log("inputValue", inputValue);
onChange?.({ ...event, target: { ...event.target, value: inputValue } }); onChange?.({ ...event, target: { ...event.target, value: inputValue } });
} }
}; };
const onInputBlur = (event: FocusEvent<HTMLInputElement>) => {
const inputValue = event.target.value;
if (Number(inputValue) < min) {
onChange?.({ ...event, target: { ...event.target, value: String(min) } });
}
if (Number(inputValue) > max) {
onChange?.({ ...event, target: { ...event.target, value: String(max) } });
}
onBlur?.(event);
};
return ( return (
<CustomTextField <CustomTextField
placeholder={placeholder} placeholder={placeholder}
sx={sx} sx={sx}
error={error} error={error}
emptyError={emptyError}
onChange={onInputChange} onChange={onInputChange}
onKeyDown={onKeyDown} onKeyDown={onKeyDown}
onBlur={onInputBlur} onBlur={onBlur}
value={value} value={value}
/> />
); );

@ -7,6 +7,7 @@ interface CustomTextFieldProps {
placeholder: string; placeholder: string;
value?: string; value?: string;
error?: string; error?: string;
emptyError?: boolean;
onChange?: (event: ChangeEvent<HTMLInputElement>) => void; onChange?: (event: ChangeEvent<HTMLInputElement>) => void;
onKeyDown?: (event: KeyboardEvent<HTMLInputElement>) => void; onKeyDown?: (event: KeyboardEvent<HTMLInputElement>) => void;
onBlur?: (event: FocusEvent<HTMLInputElement>) => void; onBlur?: (event: FocusEvent<HTMLInputElement>) => void;
@ -25,6 +26,7 @@ export default function CustomTextField({
text, text,
sx, sx,
error, error,
emptyError,
InputProps, InputProps,
maxLength = 200, maxLength = 200,
}: CustomTextFieldProps) { }: CustomTextFieldProps) {
@ -62,7 +64,7 @@ export default function CustomTextField({
value={inputValue} value={inputValue}
placeholder={placeholder} placeholder={placeholder}
onChange={handleInputChange} onChange={handleInputChange}
error={!!error} error={!!error || emptyError}
label={error} label={error}
onFocus={handleInputFocus} onFocus={handleInputFocus}
onBlur={handleInputBlur} onBlur={handleInputBlur}