diff --git a/src/App.tsx b/src/App.tsx index 2b2668e..9982d81 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -12,7 +12,7 @@ function App() {
}/> -
}/> + }/> }/> diff --git a/src/assets/icons/input/receipt.png b/src/assets/icons/input/receipt.png new file mode 100644 index 0000000..0f7c554 Binary files /dev/null and b/src/assets/icons/input/receipt.png differ diff --git a/src/components/drop-down-list/DropDownList.tsx b/src/components/drop-down-list/DropDownList.tsx index b79097b..690dcfa 100644 --- a/src/components/drop-down-list/DropDownList.tsx +++ b/src/components/drop-down-list/DropDownList.tsx @@ -1,15 +1,16 @@ import React from "react"; import { cn } from "../../lib/cn"; import { checkMark, chevroneDropDownList } from "../../assets/icons/input"; +import { useClickOutside } from "../../hooks/useClickOutside"; -export interface DropDownListItem{ +export interface DropDownListItem { text: string; value: string; } interface DropDownListProps { disabled?: boolean; - className?: string; + className?: string; onChange: (state: string) => void; defaultState?: DropDownListItem; items: DropDownListItem[]; @@ -20,52 +21,67 @@ export const DropDownList: React.FC = ({ className = "", onChange, defaultState, - items = [{text: "", value: ""}], + items = [{ text: "", value: "" }], }) => { if (items.length == 0) - items.push({text: "", value: ""}); + items.push({ text: "", value: "" }); const [value, setValue] = React.useState(defaultState != undefined ? defaultState : items[0]); const [active, setActive] = React.useState(false); React.useEffect(() => onChange(value.value), [value]); + const ref = React.useRef(null); + + useClickOutside(ref, () => { + setActive(false); + }); + + return (
+ )} + ref={ref} + >
setActive(!active)}> + onClick={() => { + setActive(!active); + } + }> {value.text}
+ className={cn(" absolute right-[16px] h-[24px] w-[24px] top-[8.5px] rotate-0 transition-all duration-300 pointer-events-none", + active && " rotate-180" + )} /> -
+
{items.map((v, i) =>
{ setValue(v); @@ -73,8 +89,8 @@ export const DropDownList: React.FC = ({ }}> {v.text} - {v.text == value.text && - + {v.text == value.text && + }
)} diff --git a/src/hooks/useClickOutside.ts b/src/hooks/useClickOutside.ts new file mode 100644 index 0000000..fb27289 --- /dev/null +++ b/src/hooks/useClickOutside.ts @@ -0,0 +1,18 @@ +import React from "react"; + +export const useClickOutside = (ref: React.RefObject, onClickOutside: () => void) => { + React.useEffect(() => { + const handleClickOutside = (event: MouseEvent | TouchEvent) => { + if (ref.current && !ref.current.contains(event.target)) { + onClickOutside(); + } + } + + document.addEventListener("mousedown", handleClickOutside); + document.addEventListener("touchstart", handleClickOutside); + return () => { + document.removeEventListener("mousedown", handleClickOutside); + document.removeEventListener("touchstart", handleClickOutside); + } + }, [ref, onClickOutside]); +} \ No newline at end of file diff --git a/src/views/problem/codeeditor/CodeEditor.tsx b/src/views/problem/codeeditor/CodeEditor.tsx index eb53729..94974cd 100644 --- a/src/views/problem/codeeditor/CodeEditor.tsx +++ b/src/views/problem/codeeditor/CodeEditor.tsx @@ -10,6 +10,8 @@ const languageMap: Record = { java: "java", python: "python", pascal: "pascal", + kotlin: "kotlin", + csharp: "csharp" }; const CodeEditor: React.FC = () => { @@ -22,8 +24,10 @@ const CodeEditor: React.FC = () => { { value: "c", text: "C" }, { value: "cpp", text: "C++" }, { value: "java", text: "Java" }, - { value: "python", text: "Python" }, + { value: "python", text: "Python" }, { value: "pascal", text: "Pascal" }, + { value: "kotlin", text: "Kotlin" }, + { value: "csharp", text: "C#" }, ]; const handleFileUpload = (e: React.ChangeEvent) => { @@ -70,7 +74,7 @@ const CodeEditor: React.FC = () => { return (
{/* Панель выбора языка и загрузки файла */} -
+
{ setLanguage(v) }} /> diff --git a/src/views/problem/statement/Statement.tsx b/src/views/problem/statement/Statement.tsx new file mode 100644 index 0000000..e69de29