fix: text inputs debounce
This commit is contained in:
parent
879f206d8f
commit
10f9a5adb1
@ -32,6 +32,7 @@
|
||||
"react-router-dom": "^6.6.2",
|
||||
"react-scripts": "5.0.1",
|
||||
"typescript": "^4.4.2",
|
||||
"use-debounce": "^9.0.4",
|
||||
"web-vitals": "^2.1.0",
|
||||
"zustand": "^4.3.8"
|
||||
},
|
||||
|
@ -10,6 +10,7 @@ import {
|
||||
useTheme,
|
||||
useMediaQuery,
|
||||
} from "@mui/material";
|
||||
import { useDebouncedCallback } from "use-debounce";
|
||||
|
||||
import { questionStore, updateQuestionsList } from "@root/questions";
|
||||
|
||||
@ -42,6 +43,17 @@ export const AnswerItem = ({
|
||||
const { listQuestions } = questionStore();
|
||||
const theme = useTheme();
|
||||
const isMobile = useMediaQuery(theme.breakpoints.down(790));
|
||||
const debounced = useDebouncedCallback((value) => {
|
||||
const answerNew = variants.slice();
|
||||
answerNew[index].answer = value;
|
||||
|
||||
updateQuestionsList(quizId, totalIndex, {
|
||||
content: {
|
||||
...listQuestions[quizId][totalIndex].content,
|
||||
variants: answerNew,
|
||||
},
|
||||
});
|
||||
}, 1000);
|
||||
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
const [anchorEl, setAnchorEl] = useState<HTMLButtonElement | null>(null);
|
||||
@ -55,18 +67,6 @@ export const AnswerItem = ({
|
||||
setIsOpen(false);
|
||||
};
|
||||
|
||||
const onChangeText = (event: ChangeEvent<HTMLInputElement>) => {
|
||||
const answerNew = variants.slice();
|
||||
answerNew[index].answer = event.target.value;
|
||||
|
||||
updateQuestionsList(quizId, totalIndex, {
|
||||
content: {
|
||||
...listQuestions[quizId][totalIndex].content,
|
||||
variants: answerNew,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
const addNewAnswer = () => {
|
||||
const answerNew = variants.slice();
|
||||
answerNew.push({ answer: "", hints: "" });
|
||||
@ -114,12 +114,12 @@ export const AnswerItem = ({
|
||||
sx={{ padding: isMobile ? " 15px 0 20px 0" : "0 0 20px 0" }}
|
||||
>
|
||||
<TextField
|
||||
value={variant.answer}
|
||||
defaultValue={variant.answer}
|
||||
fullWidth
|
||||
focused={false}
|
||||
placeholder={"Добавьте ответ"}
|
||||
multiline={listQuestions[quizId][totalIndex].content.largeCheck}
|
||||
onChange={onChangeText}
|
||||
onChange={({ target }) => debounced(target.value)}
|
||||
onKeyDown={(event: KeyboardEvent<HTMLInputElement>) => {
|
||||
if (
|
||||
event.code === "Enter" &&
|
||||
|
@ -6,6 +6,7 @@ import {
|
||||
useMediaQuery,
|
||||
useTheme,
|
||||
} from "@mui/material";
|
||||
import { useDebouncedCallback } from "use-debounce";
|
||||
import CustomCheckbox from "@ui_kit/CustomCheckbox";
|
||||
import CustomTextField from "@ui_kit/CustomTextField";
|
||||
import InfoIcon from "../../../assets/icons/InfoIcon";
|
||||
@ -20,6 +21,11 @@ export default function SettingsData({ totalIndex }: SettingsDataProps) {
|
||||
const { listQuestions } = questionStore();
|
||||
const theme = useTheme();
|
||||
const isWrappColumn = useMediaQuery(theme.breakpoints.down(980));
|
||||
const debounced = useDebouncedCallback((value) => {
|
||||
let clonContent = listQuestions[quizId][totalIndex].content;
|
||||
clonContent.innerName = value;
|
||||
updateQuestionsList(quizId, totalIndex, { content: clonContent });
|
||||
}, 1000);
|
||||
|
||||
return (
|
||||
<Box
|
||||
@ -98,11 +104,7 @@ export default function SettingsData({ totalIndex }: SettingsDataProps) {
|
||||
<CustomTextField
|
||||
placeholder={"Развёрнутое описание вопроса"}
|
||||
text={listQuestions[quizId][totalIndex].content.innerName}
|
||||
onChange={({ target }) => {
|
||||
let clonContent = listQuestions[quizId][totalIndex].content;
|
||||
clonContent.innerName = target.value;
|
||||
updateQuestionsList(quizId, totalIndex, { content: clonContent });
|
||||
}}
|
||||
onChange={({ target }) => debounced(target.value)}
|
||||
/>
|
||||
)}
|
||||
</Box>
|
||||
|
@ -12,10 +12,17 @@ import {
|
||||
useMediaQuery,
|
||||
useTheme,
|
||||
} from "@mui/material";
|
||||
import { useDebouncedCallback } from "use-debounce";
|
||||
import TypeQuestions from "../TypeQuestions";
|
||||
import SwitchQuestionsPage from "../SwitchQuestionsPage";
|
||||
|
||||
import { questionStore, updateQuestionsList, createQuestion, copyQuestion, removeQuestion } from "@root/questions";
|
||||
import {
|
||||
questionStore,
|
||||
updateQuestionsList,
|
||||
createQuestion,
|
||||
copyQuestion,
|
||||
removeQuestion,
|
||||
} from "@root/questions";
|
||||
|
||||
import ExpandMoreIcon from "@mui/icons-material/ExpandMore";
|
||||
import ExpandLessIcon from "@mui/icons-material/ExpandLess";
|
||||
@ -49,39 +56,102 @@ interface Props {
|
||||
const IconAndrom = (isExpanded: boolean, switchState: string) => {
|
||||
switch (switchState) {
|
||||
case "variant":
|
||||
return <Answer color={isExpanded ? "#9A9AAF" : "white"} sx={{ height: "22px", width: "20px" }} />;
|
||||
return (
|
||||
<Answer
|
||||
color={isExpanded ? "#9A9AAF" : "white"}
|
||||
sx={{ height: "22px", width: "20px" }}
|
||||
/>
|
||||
);
|
||||
case "images":
|
||||
return <OptionsPict color={isExpanded ? "#9A9AAF" : "white"} sx={{ height: "22px", width: "20px" }} />;
|
||||
return (
|
||||
<OptionsPict
|
||||
color={isExpanded ? "#9A9AAF" : "white"}
|
||||
sx={{ height: "22px", width: "20px" }}
|
||||
/>
|
||||
);
|
||||
case "varimg":
|
||||
return <OptionsAndPict color={isExpanded ? "#9A9AAF" : "white"} sx={{ height: "22px", width: "20px" }} />;
|
||||
return (
|
||||
<OptionsAndPict
|
||||
color={isExpanded ? "#9A9AAF" : "white"}
|
||||
sx={{ height: "22px", width: "20px" }}
|
||||
/>
|
||||
);
|
||||
case "emoji":
|
||||
return <Emoji color={isExpanded ? "#9A9AAF" : "white"} sx={{ height: "22px", width: "20px" }} />;
|
||||
return (
|
||||
<Emoji
|
||||
color={isExpanded ? "#9A9AAF" : "white"}
|
||||
sx={{ height: "22px", width: "20px" }}
|
||||
/>
|
||||
);
|
||||
case "text":
|
||||
return <Input color={isExpanded ? "#9A9AAF" : "white"} sx={{ height: "22px", width: "20px" }} />;
|
||||
return (
|
||||
<Input
|
||||
color={isExpanded ? "#9A9AAF" : "white"}
|
||||
sx={{ height: "22px", width: "20px" }}
|
||||
/>
|
||||
);
|
||||
case "select":
|
||||
return <DropDown color={isExpanded ? "#9A9AAF" : "white"} sx={{ height: "22px", width: "20px" }} />;
|
||||
return (
|
||||
<DropDown
|
||||
color={isExpanded ? "#9A9AAF" : "white"}
|
||||
sx={{ height: "22px", width: "20px" }}
|
||||
/>
|
||||
);
|
||||
case "date":
|
||||
return <Date color={isExpanded ? "#9A9AAF" : "white"} sx={{ height: "22px", width: "20px" }} />;
|
||||
return (
|
||||
<Date
|
||||
color={isExpanded ? "#9A9AAF" : "white"}
|
||||
sx={{ height: "22px", width: "20px" }}
|
||||
/>
|
||||
);
|
||||
case "number":
|
||||
return <Slider color={isExpanded ? "#9A9AAF" : "white"} sx={{ height: "22px", width: "20px" }} />;
|
||||
return (
|
||||
<Slider
|
||||
color={isExpanded ? "#9A9AAF" : "white"}
|
||||
sx={{ height: "22px", width: "20px" }}
|
||||
/>
|
||||
);
|
||||
case "file":
|
||||
return <Download color={isExpanded ? "#9A9AAF" : "white"} sx={{ height: "22px", width: "20px" }} />;
|
||||
return (
|
||||
<Download
|
||||
color={isExpanded ? "#9A9AAF" : "white"}
|
||||
sx={{ height: "22px", width: "20px" }}
|
||||
/>
|
||||
);
|
||||
case "page":
|
||||
return <Page color={isExpanded ? "#9A9AAF" : "white"} sx={{ height: "22px", width: "20px" }} />;
|
||||
return (
|
||||
<Page
|
||||
color={isExpanded ? "#9A9AAF" : "white"}
|
||||
sx={{ height: "22px", width: "20px" }}
|
||||
/>
|
||||
);
|
||||
case "rating":
|
||||
return <RatingIcon color={isExpanded ? "#9A9AAF" : "white"} sx={{ height: "22px", width: "20px" }} />;
|
||||
return (
|
||||
<RatingIcon
|
||||
color={isExpanded ? "#9A9AAF" : "white"}
|
||||
sx={{ height: "22px", width: "20px" }}
|
||||
/>
|
||||
);
|
||||
default:
|
||||
return <></>;
|
||||
}
|
||||
};
|
||||
export default function QuestionsPageCard({ totalIndex, draggableProps, isDragging }: Props) {
|
||||
export default function QuestionsPageCard({
|
||||
totalIndex,
|
||||
draggableProps,
|
||||
isDragging,
|
||||
}: Props) {
|
||||
const [plusVisible, setPlusVisible] = useState<boolean>(false);
|
||||
const quizId = Number(useParams().quizId);
|
||||
const theme = useTheme();
|
||||
const isTablet = useMediaQuery(theme.breakpoints.down(1000));
|
||||
const isMobile = useMediaQuery(theme.breakpoints.down(790));
|
||||
const { listQuestions } = questionStore();
|
||||
const { type: switchState, expanded: isExpanded } = listQuestions[quizId][totalIndex];
|
||||
const { type: switchState, expanded: isExpanded } =
|
||||
listQuestions[quizId][totalIndex];
|
||||
const debounced = useDebouncedCallback((title) => {
|
||||
updateQuestionsList(quizId, totalIndex, { title });
|
||||
}, 1000);
|
||||
|
||||
return (
|
||||
<>
|
||||
@ -106,24 +176,29 @@ export default function QuestionsPageCard({ totalIndex, draggableProps, isDraggi
|
||||
>
|
||||
<FormControl
|
||||
variant="standard"
|
||||
sx={{ p: 0, maxWidth: isTablet ? (isMobile ? "100%" : "640px") : "100%", width: "100%" }}
|
||||
sx={{
|
||||
p: 0,
|
||||
maxWidth: isTablet ? (isMobile ? "100%" : "640px") : "100%",
|
||||
width: "100%",
|
||||
}}
|
||||
>
|
||||
<TextField
|
||||
value={listQuestions[quizId][totalIndex].title}
|
||||
defaultValue={listQuestions[quizId][totalIndex].title}
|
||||
placeholder={"Заголовок вопроса"}
|
||||
onChange={(e) => {
|
||||
updateQuestionsList(quizId, totalIndex, {
|
||||
title: e.target.value,
|
||||
});
|
||||
console.log(listQuestions[quizId][totalIndex].title);
|
||||
}}
|
||||
onChange={({ target }) => debounced(target.value)}
|
||||
InputProps={{
|
||||
startAdornment: <InputAdornment position="start">{IconAndrom(isExpanded, switchState)}</InputAdornment>,
|
||||
startAdornment: (
|
||||
<InputAdornment position="start">
|
||||
{IconAndrom(isExpanded, switchState)}
|
||||
</InputAdornment>
|
||||
),
|
||||
}}
|
||||
sx={{
|
||||
"& .MuiInputBase-root": {
|
||||
color: isExpanded ? "#9A9AAF" : "white",
|
||||
backgroundColor: isExpanded ? theme.palette.background.default : "transparent",
|
||||
backgroundColor: isExpanded
|
||||
? theme.palette.background.default
|
||||
: "transparent",
|
||||
height: "48px",
|
||||
borderRadius: "10px",
|
||||
".MuiOutlinedInput-notchedOutline": {
|
||||
@ -141,17 +216,45 @@ export default function QuestionsPageCard({ totalIndex, draggableProps, isDraggi
|
||||
}}
|
||||
/>
|
||||
</FormControl>
|
||||
<Box sx={{ display: "flex", alignItems: "center", width: isMobile ? "100%" : "auto", position: "relative" }}>
|
||||
<Box sx={{ display: "flex", alignItems: "center", marginLeft: isMobile ? "auto" : "0px" }}>
|
||||
<IconButton onClick={() => updateQuestionsList(quizId, totalIndex, { expanded: !isExpanded })}>
|
||||
{isExpanded ? <ExpandMoreIcon /> : <ExpandLessIcon fill="#7E2AEA" />}
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
width: isMobile ? "100%" : "auto",
|
||||
position: "relative",
|
||||
}}
|
||||
>
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
marginLeft: isMobile ? "auto" : "0px",
|
||||
}}
|
||||
>
|
||||
<IconButton
|
||||
onClick={() =>
|
||||
updateQuestionsList(quizId, totalIndex, {
|
||||
expanded: !isExpanded,
|
||||
})
|
||||
}
|
||||
>
|
||||
{isExpanded ? (
|
||||
<ExpandMoreIcon />
|
||||
) : (
|
||||
<ExpandLessIcon fill="#7E2AEA" />
|
||||
)}
|
||||
</IconButton>
|
||||
{isExpanded ? (
|
||||
<></>
|
||||
) : (
|
||||
<Box sx={{ display: "flex", borderRight: "solid 1px white" }}>
|
||||
<FormControlLabel
|
||||
control={<Checkbox icon={<HideIcon color={"#7E2AEA"} />} checkedIcon={<CrossedEyeIcon />} />}
|
||||
control={
|
||||
<Checkbox
|
||||
icon={<HideIcon color={"#7E2AEA"} />}
|
||||
checkedIcon={<CrossedEyeIcon />}
|
||||
/>
|
||||
}
|
||||
label={""}
|
||||
sx={{
|
||||
color: theme.palette.grey2.main,
|
||||
@ -164,7 +267,11 @@ export default function QuestionsPageCard({ totalIndex, draggableProps, isDraggi
|
||||
<CopyIcon color={"white"} />
|
||||
</IconButton>
|
||||
<IconButton
|
||||
sx={{ cursor: "pointer", borderRadius: "6px", padding: "2px" }}
|
||||
sx={{
|
||||
cursor: "pointer",
|
||||
borderRadius: "6px",
|
||||
padding: "2px",
|
||||
}}
|
||||
onClick={() => removeQuestion(quizId, totalIndex)}
|
||||
>
|
||||
<DeleteIcon color={"white"} />
|
||||
@ -231,7 +338,8 @@ export default function QuestionsPageCard({ totalIndex, draggableProps, isDraggi
|
||||
backgroundPosition: "bottom",
|
||||
backgroundRepeat: "repeat-x",
|
||||
backgroundSize: "20px 1px",
|
||||
backgroundImage: "radial-gradient(circle, #7E2AEA 6px, #F2F3F7 1px)",
|
||||
backgroundImage:
|
||||
"radial-gradient(circle, #7E2AEA 6px, #F2F3F7 1px)",
|
||||
}}
|
||||
/>
|
||||
<PlusIcon />
|
||||
|
@ -2,6 +2,7 @@ import { useParams } from "react-router-dom";
|
||||
import { Box, Typography, useMediaQuery, useTheme } from "@mui/material";
|
||||
import CustomCheckbox from "@ui_kit/CustomCheckbox";
|
||||
import CustomTextField from "@ui_kit/CustomTextField";
|
||||
import { useDebouncedCallback } from "use-debounce";
|
||||
|
||||
import { questionStore, updateQuestionsList } from "@root/questions";
|
||||
|
||||
@ -18,6 +19,16 @@ export default function SettingDropDown({ totalIndex }: SettingDropDownProps) {
|
||||
const theme = useTheme();
|
||||
const isTablet = useMediaQuery(theme.breakpoints.down(1000));
|
||||
const isMobile = useMediaQuery(theme.breakpoints.down(790));
|
||||
const debounced = useDebouncedCallback((value) => {
|
||||
let clonContent = listQuestions[quizId][totalIndex].content;
|
||||
clonContent.innerName = value;
|
||||
updateQuestionsList(quizId, totalIndex, { content: clonContent });
|
||||
}, 1000);
|
||||
const debounceAnswer = useDebouncedCallback((value) => {
|
||||
const clonContent = listQuestions[quizId][totalIndex].content;
|
||||
clonContent.default = value;
|
||||
updateQuestionsList(quizId, totalIndex, { content: clonContent });
|
||||
}, 1000);
|
||||
|
||||
return (
|
||||
<>
|
||||
@ -30,8 +41,15 @@ export default function SettingDropDown({ totalIndex }: SettingDropDownProps) {
|
||||
flexDirection: isMobile ? "column" : null,
|
||||
}}
|
||||
>
|
||||
<Box sx={{ padding: isMobile ? "20px 20px 0px 20px" : "20px 20px 20px 20px", width: "100%" }}>
|
||||
<Typography sx={{ marginBottom: "15px" }}>Настройки ответов</Typography>
|
||||
<Box
|
||||
sx={{
|
||||
padding: isMobile ? "20px 20px 0px 20px" : "20px 20px 20px 20px",
|
||||
width: "100%",
|
||||
}}
|
||||
>
|
||||
<Typography sx={{ marginBottom: "15px" }}>
|
||||
Настройки ответов
|
||||
</Typography>
|
||||
<CustomCheckbox
|
||||
label={"Можно несколько"}
|
||||
checked={listQuestions[quizId][totalIndex].content.multi}
|
||||
@ -45,21 +63,21 @@ export default function SettingDropDown({ totalIndex }: SettingDropDownProps) {
|
||||
}
|
||||
/>
|
||||
<Box sx={{ display: isMobile ? "none" : "block" }}>
|
||||
<Typography sx={{ marginBottom: "15px" }}>Текст в выпадающем списке</Typography>
|
||||
<Typography sx={{ marginBottom: "15px" }}>
|
||||
Текст в выпадающем списке
|
||||
</Typography>
|
||||
<CustomTextField
|
||||
sx={{ maxWidth: "360px" }}
|
||||
placeholder={"Выберите вариант"}
|
||||
text={listQuestions[quizId][totalIndex].content.default}
|
||||
onChange={({ target }) => {
|
||||
const clonContent = listQuestions[quizId][totalIndex].content;
|
||||
clonContent.default = target.value;
|
||||
updateQuestionsList(quizId, totalIndex, { content: clonContent });
|
||||
}}
|
||||
onChange={({ target }) => debounceAnswer(target.value)}
|
||||
/>
|
||||
</Box>
|
||||
</Box>
|
||||
<Box sx={{ padding: "20px", width: "100%" }}>
|
||||
<Typography sx={{ marginBottom: "15px" }}>Настройки вопросов</Typography>
|
||||
<Typography sx={{ marginBottom: "15px" }}>
|
||||
Настройки вопросов
|
||||
</Typography>
|
||||
<CustomCheckbox
|
||||
label={"Необязательный вопрос"}
|
||||
checked={!listQuestions[quizId][totalIndex].required}
|
||||
@ -69,7 +87,9 @@ export default function SettingDropDown({ totalIndex }: SettingDropDownProps) {
|
||||
});
|
||||
}}
|
||||
/>
|
||||
<Box sx={{ position: "relative", display: "flex", alignItems: "center" }}>
|
||||
<Box
|
||||
sx={{ position: "relative", display: "flex", alignItems: "center" }}
|
||||
>
|
||||
<CustomCheckbox
|
||||
label={"Внутреннее название вопроса"}
|
||||
checked={listQuestions[quizId][totalIndex].content.innerNameCheck}
|
||||
@ -87,33 +107,34 @@ export default function SettingDropDown({ totalIndex }: SettingDropDownProps) {
|
||||
}}
|
||||
/>
|
||||
<InfoIcon
|
||||
sx={{ position: isMobile ? "absolute" : null, display: "block", right: isMobile ? "30px" : null }}
|
||||
sx={{
|
||||
position: isMobile ? "absolute" : null,
|
||||
display: "block",
|
||||
right: isMobile ? "30px" : null,
|
||||
}}
|
||||
/>
|
||||
</Box>
|
||||
<Box sx={{ width: "85%", pt: "20px", display: isMobile ? "block" : "none" }}>
|
||||
<Typography sx={{ marginBottom: "15px" }}>Текст в выпадающем списке</Typography>
|
||||
<Box
|
||||
sx={{
|
||||
width: "85%",
|
||||
pt: "20px",
|
||||
display: isMobile ? "block" : "none",
|
||||
}}
|
||||
>
|
||||
<Typography sx={{ marginBottom: "15px" }}>
|
||||
Текст в выпадающем списке
|
||||
</Typography>
|
||||
<CustomTextField
|
||||
sx={{}}
|
||||
placeholder={"Выберите вариант"}
|
||||
text={listQuestions[quizId][totalIndex].content.default}
|
||||
onChange={({ target }) => {
|
||||
const clonContent = listQuestions[quizId][totalIndex].content;
|
||||
clonContent.default = target.value;
|
||||
updateQuestionsList(quizId, totalIndex, { content: clonContent });
|
||||
}}
|
||||
onChange={({ target }) => debounceAnswer(target.value)}
|
||||
/>
|
||||
</Box>
|
||||
{listQuestions[quizId][totalIndex].content.innerNameCheck && (
|
||||
<CustomTextField
|
||||
placeholder={"Развёрнутое описание вопроса"}
|
||||
text={listQuestions[quizId][totalIndex].content.innerName}
|
||||
onChange={({ target }) => {
|
||||
let clonContent = listQuestions[quizId][totalIndex].content;
|
||||
clonContent.innerName = target.value;
|
||||
updateQuestionsList(quizId, totalIndex, {
|
||||
content: clonContent,
|
||||
});
|
||||
}}
|
||||
onChange={({ target }) => debounced(target.value)}
|
||||
/>
|
||||
)}
|
||||
</Box>
|
||||
|
@ -6,6 +6,7 @@ import {
|
||||
useMediaQuery,
|
||||
useTheme,
|
||||
} from "@mui/material";
|
||||
import { useDebouncedCallback } from "use-debounce";
|
||||
import CustomCheckbox from "@ui_kit/CustomCheckbox";
|
||||
import CustomTextField from "@ui_kit/CustomTextField";
|
||||
import InfoIcon from "../../../assets/icons/InfoIcon";
|
||||
@ -21,6 +22,11 @@ export default function SettingEmoji({ totalIndex }: SettingEmojiProps) {
|
||||
const theme = useTheme();
|
||||
const isWrappColumn = useMediaQuery(theme.breakpoints.down(980));
|
||||
const isMobile = useMediaQuery(theme.breakpoints.down(790));
|
||||
const debounced = useDebouncedCallback((value) => {
|
||||
let clonContent = listQuestions[quizId][totalIndex].content;
|
||||
clonContent.innerName = value;
|
||||
updateQuestionsList(quizId, totalIndex, { content: clonContent });
|
||||
}, 1000);
|
||||
|
||||
return (
|
||||
<Box
|
||||
@ -98,11 +104,7 @@ export default function SettingEmoji({ totalIndex }: SettingEmojiProps) {
|
||||
<CustomTextField
|
||||
placeholder={"Развёрнутое описание вопроса"}
|
||||
text={listQuestions[quizId][totalIndex].content.innerName}
|
||||
onChange={({ target }) => {
|
||||
let clonContent = listQuestions[quizId][totalIndex].content;
|
||||
clonContent.innerName = target.value;
|
||||
updateQuestionsList(quizId, totalIndex, { content: clonContent });
|
||||
}}
|
||||
onChange={({ target }) => debounced(target.value)}
|
||||
/>
|
||||
)}
|
||||
</Box>
|
||||
|
@ -6,6 +6,7 @@ import {
|
||||
useMediaQuery,
|
||||
useTheme,
|
||||
} from "@mui/material";
|
||||
import { useDebouncedCallback } from "use-debounce";
|
||||
import CustomCheckbox from "@ui_kit/CustomCheckbox";
|
||||
import CustomTextField from "@ui_kit/CustomTextField";
|
||||
import InfoIcon from "../../../assets/icons/InfoIcon";
|
||||
@ -24,6 +25,21 @@ export default function SettingOptionsAndPict({
|
||||
const theme = useTheme();
|
||||
const isWrappColumn = useMediaQuery(theme.breakpoints.down(980));
|
||||
const isMobile = useMediaQuery(theme.breakpoints.down(680));
|
||||
const debounced = useDebouncedCallback((replText) => {
|
||||
updateQuestionsList(quizId, totalIndex, {
|
||||
content: {
|
||||
...listQuestions[quizId][totalIndex].content,
|
||||
replText,
|
||||
},
|
||||
});
|
||||
}, 1000);
|
||||
const debounceDescription = useDebouncedCallback((value) => {
|
||||
let clonContent = listQuestions[quizId][totalIndex].content;
|
||||
clonContent.innerName = value;
|
||||
updateQuestionsList(quizId, totalIndex, {
|
||||
content: clonContent,
|
||||
});
|
||||
}, 1000);
|
||||
|
||||
return (
|
||||
<>
|
||||
@ -60,14 +76,7 @@ export default function SettingOptionsAndPict({
|
||||
sx={{ maxWidth: "330px", width: "100%" }}
|
||||
placeholder={"Пример текста"}
|
||||
text={listQuestions[quizId][totalIndex].content.replText}
|
||||
onChange={({ target }) => {
|
||||
updateQuestionsList(quizId, totalIndex, {
|
||||
content: {
|
||||
...listQuestions[quizId][totalIndex].content,
|
||||
replText: target.value,
|
||||
},
|
||||
});
|
||||
}}
|
||||
onChange={({ target }) => debounced(target.value)}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
@ -123,13 +132,7 @@ export default function SettingOptionsAndPict({
|
||||
<CustomTextField
|
||||
placeholder={"Развёрнутое описание вопроса"}
|
||||
text={listQuestions[quizId][totalIndex].content.innerName}
|
||||
onChange={({ target }) => {
|
||||
let clonContent = listQuestions[quizId][totalIndex].content;
|
||||
clonContent.innerName = target.value;
|
||||
updateQuestionsList(quizId, totalIndex, {
|
||||
content: clonContent,
|
||||
});
|
||||
}}
|
||||
onChange={({ target }) => debounceDescription(target.value)}
|
||||
/>
|
||||
)}
|
||||
{isWrappColumn && (
|
||||
@ -141,14 +144,7 @@ export default function SettingOptionsAndPict({
|
||||
sx={{ maxWidth: "330px", width: "100%" }}
|
||||
placeholder={"Пример текста"}
|
||||
text={listQuestions[quizId][totalIndex].content.replText}
|
||||
onChange={({ target }) => {
|
||||
updateQuestionsList(quizId, totalIndex, {
|
||||
content: {
|
||||
...listQuestions[quizId][totalIndex].content,
|
||||
replText: target.value,
|
||||
},
|
||||
});
|
||||
}}
|
||||
onChange={({ target }) => debounced(target.value)}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
|
@ -10,6 +10,7 @@ import {
|
||||
} from "@mui/material";
|
||||
import CustomCheckbox from "@ui_kit/CustomCheckbox";
|
||||
import CustomTextField from "@ui_kit/CustomTextField";
|
||||
import { useDebouncedCallback } from "use-debounce";
|
||||
|
||||
import { questionStore, updateQuestionsList } from "@root/questions";
|
||||
|
||||
@ -85,6 +86,13 @@ export default function SettingOpytionsPict({
|
||||
const theme = useTheme();
|
||||
const isTablet = useMediaQuery(theme.breakpoints.down(1000));
|
||||
const isMobile = useMediaQuery(theme.breakpoints.down(790));
|
||||
const debounced = useDebouncedCallback((value) => {
|
||||
let clonContent = listQuestions[quizId][totalIndex].content;
|
||||
clonContent.innerName = value;
|
||||
updateQuestionsList(quizId, totalIndex, {
|
||||
content: clonContent,
|
||||
});
|
||||
}, 1000);
|
||||
|
||||
useEffect(() => {
|
||||
if (!listQuestions[quizId][totalIndex].content.xy) {
|
||||
@ -254,13 +262,7 @@ export default function SettingOpytionsPict({
|
||||
<CustomTextField
|
||||
placeholder={"Внутреннее описание вопроса"}
|
||||
text={listQuestions[quizId][totalIndex].content.innerName}
|
||||
onChange={({ target }) => {
|
||||
let clonContent = listQuestions[quizId][totalIndex].content;
|
||||
clonContent.innerName = target.value;
|
||||
updateQuestionsList(quizId, totalIndex, {
|
||||
content: clonContent,
|
||||
});
|
||||
}}
|
||||
onChange={({ target }) => debounced(target.value)}
|
||||
/>
|
||||
)}
|
||||
</Box>
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { useState } from "react";
|
||||
import { useParams } from "react-router-dom";
|
||||
import { Box, Typography, Tooltip, useTheme } from "@mui/material";
|
||||
import { useDebouncedCallback } from "use-debounce";
|
||||
|
||||
import CustomTextField from "@ui_kit/CustomTextField";
|
||||
import ButtonsOptions from "../ButtonsOptions";
|
||||
@ -10,8 +11,6 @@ import { questionStore, updateQuestionsList } from "@root/questions";
|
||||
|
||||
import InfoIcon from "../../../assets/icons/InfoIcon";
|
||||
|
||||
import type { ChangeEvent } from "react";
|
||||
|
||||
interface Props {
|
||||
totalIndex: number;
|
||||
}
|
||||
@ -20,6 +19,11 @@ export default function OwnTextField({ totalIndex }: Props) {
|
||||
const quizId = Number(useParams().quizId);
|
||||
const { listQuestions } = questionStore();
|
||||
const theme = useTheme();
|
||||
const debounced = useDebouncedCallback((value) => {
|
||||
const clonContent = listQuestions[quizId][totalIndex].content;
|
||||
clonContent.placeholder = value;
|
||||
updateQuestionsList(quizId, totalIndex, { content: clonContent });
|
||||
}, 1000);
|
||||
|
||||
const SSHC = (data: string) => {
|
||||
setSwitchState(data);
|
||||
@ -40,11 +44,7 @@ export default function OwnTextField({ totalIndex }: Props) {
|
||||
<CustomTextField
|
||||
placeholder={"Пример ответа"}
|
||||
text={listQuestions[quizId][totalIndex].content.placeholder}
|
||||
onChange={({ target }: ChangeEvent<HTMLInputElement>) => {
|
||||
const clonContent = listQuestions[quizId][totalIndex].content;
|
||||
clonContent.placeholder = target.value;
|
||||
updateQuestionsList(quizId, totalIndex, { content: clonContent });
|
||||
}}
|
||||
onChange={({ target }) => debounced(target.value)}
|
||||
/>
|
||||
<Box sx={{ display: "flex", alignItems: "center", gap: "12px" }}>
|
||||
<Typography
|
||||
|
@ -10,6 +10,7 @@ import {
|
||||
useMediaQuery,
|
||||
useTheme,
|
||||
} from "@mui/material";
|
||||
import { useDebouncedCallback } from "use-debounce";
|
||||
import CustomCheckbox from "@ui_kit/CustomCheckbox";
|
||||
import CustomTextField from "@ui_kit/CustomTextField";
|
||||
|
||||
@ -42,6 +43,11 @@ export default function SettingTextField({
|
||||
const theme = useTheme();
|
||||
const isWrapperColumn = useMediaQuery(theme.breakpoints.down(980));
|
||||
const isMobile = useMediaQuery(theme.breakpoints.down(790));
|
||||
const debounced = useDebouncedCallback((value) => {
|
||||
let clonContent = listQuestions[quizId][totalIndex].content;
|
||||
clonContent.innerName = value;
|
||||
updateQuestionsList(quizId, totalIndex, { content: clonContent });
|
||||
}, 1000);
|
||||
|
||||
return (
|
||||
<Box
|
||||
@ -138,11 +144,7 @@ export default function SettingTextField({
|
||||
<CustomTextField
|
||||
placeholder={"Развёрнутое описание вопроса"}
|
||||
text={listQuestions[quizId][totalIndex].content.innerName}
|
||||
onChange={({ target }) => {
|
||||
let clonContent = listQuestions[quizId][totalIndex].content;
|
||||
clonContent.innerName = target.value;
|
||||
updateQuestionsList(quizId, totalIndex, { content: clonContent });
|
||||
}}
|
||||
onChange={({ target }) => debounced(target.value)}
|
||||
/>
|
||||
)}
|
||||
</Box>
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { useState } from "react";
|
||||
import { useParams } from "react-router-dom";
|
||||
import { Box, Typography, useMediaQuery, useTheme } from "@mui/material";
|
||||
import { useDebouncedCallback } from "use-debounce";
|
||||
import ButtonsOptions from "../ButtonsOptions";
|
||||
import CustomTextField from "@ui_kit/CustomTextField";
|
||||
import AddImage from "../../../assets/icons/questionsPage/addImage";
|
||||
@ -26,6 +27,11 @@ export default function PageOptions({ disableInput, totalIndex }: Props) {
|
||||
const theme = useTheme();
|
||||
const isTablet = useMediaQuery(theme.breakpoints.down(980));
|
||||
const isMobile = useMediaQuery(theme.breakpoints.down(780));
|
||||
const debounced = useDebouncedCallback((value) => {
|
||||
const clonContent = listQuestions[quizId][totalIndex].content;
|
||||
clonContent.text = value;
|
||||
updateQuestionsList(quizId, totalIndex, { content: clonContent });
|
||||
}, 1000);
|
||||
|
||||
const SSHC = (data: string) => {
|
||||
setSwitchState(data);
|
||||
@ -47,15 +53,16 @@ export default function PageOptions({ disableInput, totalIndex }: Props) {
|
||||
<CustomTextField
|
||||
placeholder={"Можно добавить текст"}
|
||||
text={listQuestions[quizId][totalIndex].content.text}
|
||||
onChange={({ target }) => {
|
||||
const clonContent = listQuestions[quizId][totalIndex].content;
|
||||
clonContent.text = target.value;
|
||||
updateQuestionsList(quizId, totalIndex, { content: clonContent });
|
||||
}}
|
||||
onChange={({ target }) => debounced(target.value)}
|
||||
/>
|
||||
</Box>
|
||||
<Box
|
||||
sx={{ display: "flex", alignItems: "center", gap: "12px", justifyContent: isMobile ? "space-between" : null }}
|
||||
sx={{
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
gap: "12px",
|
||||
justifyContent: isMobile ? "space-between" : null,
|
||||
}}
|
||||
>
|
||||
<Box
|
||||
onClick={() => setOpenImageModal(true)}
|
||||
@ -129,7 +136,11 @@ export default function PageOptions({ disableInput, totalIndex }: Props) {
|
||||
/>
|
||||
</Box>
|
||||
</Box>
|
||||
<ButtonsOptions switchState={switchState} SSHC={SSHC} totalIndex={totalIndex} />
|
||||
<ButtonsOptions
|
||||
switchState={switchState}
|
||||
SSHC={SSHC}
|
||||
totalIndex={totalIndex}
|
||||
/>
|
||||
<SwitchPageOptions switchState={switchState} totalIndex={totalIndex} />
|
||||
</>
|
||||
);
|
||||
|
@ -2,6 +2,7 @@ import { useParams } from "react-router-dom";
|
||||
import { Box, Typography, Tooltip } from "@mui/material";
|
||||
import CustomCheckbox from "@ui_kit/CustomCheckbox";
|
||||
import CustomTextField from "@ui_kit/CustomTextField";
|
||||
import { useDebouncedCallback } from "use-debounce";
|
||||
|
||||
import { questionStore, updateQuestionsList } from "@root/questions";
|
||||
|
||||
@ -16,6 +17,13 @@ export default function SettingPageOptions({
|
||||
}: SettingPageOptionsProps) {
|
||||
const quizId = Number(useParams().quizId);
|
||||
const { listQuestions } = questionStore();
|
||||
const debounced = useDebouncedCallback((value) => {
|
||||
let clonContent = listQuestions[quizId][totalIndex].content;
|
||||
clonContent.innerName = value;
|
||||
updateQuestionsList(quizId, totalIndex, {
|
||||
content: clonContent,
|
||||
});
|
||||
}, 1000);
|
||||
|
||||
return (
|
||||
<Box sx={{ display: "flex", flexDirection: "column", padding: "20px" }}>
|
||||
@ -47,13 +55,7 @@ export default function SettingPageOptions({
|
||||
<CustomTextField
|
||||
placeholder={"Внутреннее описание вопроса"}
|
||||
text={listQuestions[quizId][totalIndex].content.innerName}
|
||||
onChange={({ target }) => {
|
||||
let clonContent = listQuestions[quizId][totalIndex].content;
|
||||
clonContent.innerName = target.value;
|
||||
updateQuestionsList(quizId, totalIndex, {
|
||||
content: clonContent,
|
||||
});
|
||||
}}
|
||||
onChange={({ target }) => debounced(target.value)}
|
||||
/>
|
||||
)}
|
||||
</Box>
|
||||
|
@ -1,9 +1,20 @@
|
||||
import { Box, Button, IconButton, Typography, useMediaQuery, useTheme } from "@mui/material";
|
||||
import {
|
||||
Box,
|
||||
Button,
|
||||
IconButton,
|
||||
Typography,
|
||||
useMediaQuery,
|
||||
useTheme,
|
||||
} from "@mui/material";
|
||||
import AddPlus from "../../assets/icons/questionsPage/addPlus";
|
||||
import ArrowLeft from "../../assets/icons/questionsPage/arrowLeft";
|
||||
import { quizStore } from "@root/quizes";
|
||||
import { useParams } from "react-router-dom";
|
||||
import { questionStore, createQuestion, updateQuestionsList } from "@root/questions";
|
||||
import {
|
||||
questionStore,
|
||||
createQuestion,
|
||||
updateQuestionsList,
|
||||
} from "@root/questions";
|
||||
import { DraggableList } from "./DraggableList";
|
||||
|
||||
export default function QuestionsPage() {
|
||||
@ -72,7 +83,10 @@ export default function QuestionsPage() {
|
||||
<AddPlus />
|
||||
</IconButton>
|
||||
<Box sx={{ display: "flex", gap: "8px" }}>
|
||||
<Button variant="outlined" sx={{ padding: "10px 20px", borderRadius: "8px", height: "44px" }}>
|
||||
<Button
|
||||
variant="outlined"
|
||||
sx={{ padding: "10px 20px", borderRadius: "8px", height: "44px" }}
|
||||
>
|
||||
<ArrowLeft />
|
||||
</Button>
|
||||
<Button
|
||||
|
@ -8,6 +8,7 @@ import {
|
||||
useMediaQuery,
|
||||
useTheme,
|
||||
} from "@mui/material";
|
||||
import { useDebouncedCallback } from "use-debounce";
|
||||
|
||||
import CustomCheckbox from "@ui_kit/CustomCheckbox";
|
||||
import CustomTextField from "@ui_kit/CustomTextField";
|
||||
@ -34,6 +35,11 @@ export default function SettingSlider({ totalIndex }: SettingSliderProps) {
|
||||
const isMobile = useMediaQuery(theme.breakpoints.down(790));
|
||||
const isWrappColumn = useMediaQuery(theme.breakpoints.down(980));
|
||||
const { listQuestions } = questionStore();
|
||||
const debounced = useDebouncedCallback((value) => {
|
||||
let clonContent = listQuestions[quizId][totalIndex].content;
|
||||
clonContent.innerName = value;
|
||||
updateQuestionsList(quizId, totalIndex, { content: clonContent });
|
||||
}, 1000);
|
||||
|
||||
const buttonRatingForm: ButtonRatingFrom[] = [
|
||||
{ name: "star", icon: <StarIconMini color={theme.palette.grey3.main} /> },
|
||||
@ -160,11 +166,7 @@ export default function SettingSlider({ totalIndex }: SettingSliderProps) {
|
||||
<CustomTextField
|
||||
placeholder={"Развёрнутое описание вопроса"}
|
||||
text={listQuestions[quizId][totalIndex].content.innerName}
|
||||
onChange={({ target }) => {
|
||||
let clonContent = listQuestions[quizId][totalIndex].content;
|
||||
clonContent.innerName = target.value;
|
||||
updateQuestionsList(quizId, totalIndex, { content: clonContent });
|
||||
}}
|
||||
onChange={({ target }) => debounced(target.value)}
|
||||
/>
|
||||
)}
|
||||
</Box>
|
||||
|
@ -6,6 +6,7 @@ import {
|
||||
useMediaQuery,
|
||||
useTheme,
|
||||
} from "@mui/material";
|
||||
import { useDebouncedCallback } from "use-debounce";
|
||||
import CustomCheckbox from "@ui_kit/CustomCheckbox";
|
||||
import CustomTextField from "@ui_kit/CustomTextField";
|
||||
import InfoIcon from "../../../assets/icons/InfoIcon";
|
||||
@ -21,6 +22,11 @@ export default function SettingSlider({ totalIndex }: SettingSliderProps) {
|
||||
const theme = useTheme();
|
||||
const isWrappColumn = useMediaQuery(theme.breakpoints.down(980));
|
||||
const isMobile = useMediaQuery(theme.breakpoints.down(790));
|
||||
const debounced = useDebouncedCallback((value) => {
|
||||
let clonContent = listQuestions[quizId][totalIndex].content;
|
||||
clonContent.innerName = value;
|
||||
updateQuestionsList(quizId, totalIndex, { content: clonContent });
|
||||
}, 1000);
|
||||
|
||||
return (
|
||||
<Box
|
||||
@ -81,11 +87,7 @@ export default function SettingSlider({ totalIndex }: SettingSliderProps) {
|
||||
<CustomTextField
|
||||
placeholder={"Развёрнутое описание вопроса"}
|
||||
text={listQuestions[quizId][totalIndex].content.innerName}
|
||||
onChange={({ target }) => {
|
||||
let clonContent = listQuestions[quizId][totalIndex].content;
|
||||
clonContent.innerName = target.value;
|
||||
updateQuestionsList(quizId, totalIndex, { content: clonContent });
|
||||
}}
|
||||
onChange={({ target }) => debounced(target.value)}
|
||||
/>
|
||||
)}
|
||||
</Box>
|
||||
|
@ -2,6 +2,7 @@ import { useParams } from "react-router-dom";
|
||||
import { Box, Typography, Tooltip } from "@mui/material";
|
||||
import CustomCheckbox from "@ui_kit/CustomCheckbox";
|
||||
import CustomTextField from "@ui_kit/CustomTextField";
|
||||
import { useDebouncedCallback } from "use-debounce";
|
||||
|
||||
import { questionStore, updateQuestionsList } from "@root/questions";
|
||||
|
||||
@ -14,6 +15,11 @@ type SettingsUploadProps = {
|
||||
export default function SettingsUpload({ totalIndex }: SettingsUploadProps) {
|
||||
const quizId = Number(useParams().quizId);
|
||||
const { listQuestions } = questionStore();
|
||||
const debounced = useDebouncedCallback((value) => {
|
||||
let clonContent = listQuestions[quizId][totalIndex].content;
|
||||
clonContent.innerName = value;
|
||||
updateQuestionsList(quizId, totalIndex, { content: clonContent });
|
||||
}, 1000);
|
||||
|
||||
return (
|
||||
<Box sx={{ display: "flex", flexDirection: "column", padding: "20px" }}>
|
||||
@ -64,11 +70,7 @@ export default function SettingsUpload({ totalIndex }: SettingsUploadProps) {
|
||||
<CustomTextField
|
||||
placeholder={"Развёрнутое описание вопроса"}
|
||||
text={listQuestions[quizId][totalIndex].content.innerName}
|
||||
onChange={({ target }) => {
|
||||
let clonContent = listQuestions[quizId][totalIndex].content;
|
||||
clonContent.innerName = target.value;
|
||||
updateQuestionsList(quizId, totalIndex, { content: clonContent });
|
||||
}}
|
||||
onChange={({ target }) => debounced(target.value)}
|
||||
/>
|
||||
)}
|
||||
</Box>
|
||||
|
@ -6,6 +6,7 @@ import {
|
||||
useMediaQuery,
|
||||
useTheme,
|
||||
} from "@mui/material";
|
||||
import { useDebouncedCallback } from "use-debounce";
|
||||
import CustomCheckbox from "@ui_kit/CustomCheckbox";
|
||||
import InfoIcon from "../../../assets/icons/InfoIcon";
|
||||
import CustomTextField from "@ui_kit/CustomTextField";
|
||||
@ -21,6 +22,11 @@ export default function ResponseSettings({ totalIndex }: Props) {
|
||||
const theme = useTheme();
|
||||
const isTablet = useMediaQuery(theme.breakpoints.down(900));
|
||||
const isMobile = useMediaQuery(theme.breakpoints.down(790));
|
||||
const debounced = useDebouncedCallback((value) => {
|
||||
let clonContent = listQuestions[quizId][totalIndex].content;
|
||||
clonContent.innerName = value;
|
||||
updateQuestionsList(quizId, totalIndex, { content: clonContent });
|
||||
}, 1000);
|
||||
|
||||
return (
|
||||
<Box
|
||||
@ -107,11 +113,7 @@ export default function ResponseSettings({ totalIndex }: Props) {
|
||||
<CustomTextField
|
||||
placeholder={"Развёрнутое описание вопроса"}
|
||||
text={listQuestions[quizId][totalIndex].content.innerName}
|
||||
onChange={({ target }) => {
|
||||
let clonContent = listQuestions[quizId][totalIndex].content;
|
||||
clonContent.innerName = target.value;
|
||||
updateQuestionsList(quizId, totalIndex, { content: clonContent });
|
||||
}}
|
||||
onChange={({ target }) => debounced(target.value)}
|
||||
/>
|
||||
)}
|
||||
</Box>
|
||||
|
@ -1,8 +1,9 @@
|
||||
import { useState } from "react";
|
||||
import { Box, ButtonBase, Typography } from "@mui/material";
|
||||
import { useParams } from "react-router-dom";
|
||||
import SelectableButton from "@ui_kit/SelectableButton";
|
||||
import CustomTextField from "@ui_kit/CustomTextField";
|
||||
import { useState } from "react";
|
||||
import { useDebouncedCallback } from "use-debounce";
|
||||
import UploadIcon from "../../assets/icons/UploadIcon";
|
||||
import UploadBox from "@ui_kit/UploadBox";
|
||||
import { questionStore, updateQuestionsList } from "@root/questions";
|
||||
@ -19,6 +20,11 @@ export default function HelpQuestions({ totalIndex }: HelpQuestionsProps) {
|
||||
const [backgroundType, setBackgroundType] = useState<BackgroundType>("text");
|
||||
const quizId = Number(useParams().quizId);
|
||||
const { listQuestions } = questionStore();
|
||||
const debounced = useDebouncedCallback((value) => {
|
||||
let clonContent = listQuestions[quizId][totalIndex].content;
|
||||
clonContent.hint.text = value;
|
||||
updateQuestionsList(quizId, totalIndex, { content: clonContent });
|
||||
}, 1000);
|
||||
|
||||
const videoHC = (url: string) => {
|
||||
const clonContent = listQuestions[quizId][totalIndex].content;
|
||||
@ -62,11 +68,7 @@ export default function HelpQuestions({ totalIndex }: HelpQuestionsProps) {
|
||||
<CustomTextField
|
||||
placeholder={"Текст консультанта"}
|
||||
text={listQuestions[quizId][totalIndex].content.hint.text}
|
||||
onChange={({ target }) => {
|
||||
let clonContent = listQuestions[quizId][totalIndex].content;
|
||||
clonContent.hint.text = target.value;
|
||||
updateQuestionsList(quizId, totalIndex, { content: clonContent });
|
||||
}}
|
||||
onChange={({ target }) => debounced(target.value)}
|
||||
/>
|
||||
</>
|
||||
) : (
|
||||
|
@ -9186,6 +9186,11 @@ url-parse@^1.5.3:
|
||||
querystringify "^2.1.1"
|
||||
requires-port "^1.0.0"
|
||||
|
||||
use-debounce@^9.0.4:
|
||||
version "9.0.4"
|
||||
resolved "https://registry.yarnpkg.com/use-debounce/-/use-debounce-9.0.4.tgz#51d25d856fbdfeb537553972ce3943b897f1ac85"
|
||||
integrity sha512-6X8H/mikbrt0XE8e+JXRtZ8yYVvKkdYRfmIhWZYsP8rcNs9hk3APV8Ua2mFkKRLcJKVdnX2/Vwrmg2GWKUQEaQ==
|
||||
|
||||
use-memo-one@^1.1.1:
|
||||
version "1.1.3"
|
||||
resolved "https://registry.yarnpkg.com/use-memo-one/-/use-memo-one-1.1.3.tgz#2fd2e43a2169eabc7496960ace8c79efef975e99"
|
||||
|
Loading…
Reference in New Issue
Block a user