From dc47595b8469deaba3f85b2223580b652433c0ac Mon Sep 17 00:00:00 2001 From: Anthony ramos roncal Date: Sun, 16 Mar 2025 17:07:55 -0500 Subject: [PATCH] feature: Add code mirror in input --- deno.json | 16 ++- deno.lock | 282 +++++++++++++++++++++++++++++++++++++++ src/utils/CodeEditor.tsx | 85 ++++++++++++ src/utils/input.tsx | 39 ++++-- 4 files changed, 411 insertions(+), 11 deletions(-) create mode 100644 src/utils/CodeEditor.tsx diff --git a/deno.json b/deno.json index 80b0911..8bf08f3 100644 --- a/deno.json +++ b/deno.json @@ -5,6 +5,11 @@ "preview": "deno run -A --node-modules-dir npm:vite preview", "serve": "deno run --allow-net --allow-read jsr:@std/http@1/file-server dist/" }, + "permissions": { + "net": true, + "read": true, + "write": true + }, "compilerOptions": { "lib": ["ES2020", "DOM", "DOM.Iterable", "deno.ns"], "jsx": "react-jsx", @@ -23,6 +28,15 @@ "react-router-dom": "npm:react-router-dom@^6.28.0", "react-syntax-highlighter": "npm:react-syntax-highlighter@^15.6.1", "tailwindcss": "npm:tailwindcss@^3.4.14", - "vite": "npm:vite@^5.4.9" + "vite": "npm:vite@^5.4.9", + "@uiw/react-codemirror": "npm:@uiw/react-codemirror@latest", + "@codemirror/lang-javascript": "npm:@codemirror/lang-javascript@latest", + "@codemirror/lang-python": "npm:@codemirror/lang-python@latest", + "@codemirror/lang-cpp": "npm:@codemirror/lang-cpp@latest", + "@codemirror/lang-java": "npm:@codemirror/lang-java@latest", + "@codemirror/lang-rust": "npm:@codemirror/lang-rust@latest", + "@codemirror/lang-go": "npm:@codemirror/lang-go@latest", + "@codemirror/lang-sql": "npm:@codemirror/lang-sql@latest", + "@uiw/codemirror-theme-github": "npm:@uiw/codemirror-theme-github@latest" } } diff --git a/deno.lock b/deno.lock index ae4e85e..37edcb8 100644 --- a/deno.lock +++ b/deno.lock @@ -13,10 +13,24 @@ "jsr:@std/io@0.224": "0.224.9", "jsr:@std/media-types@1": "1.0.3", "jsr:@std/path@1": "1.0.8", + "npm:@codemirror/lang-cpp@*": "6.0.2", + "npm:@codemirror/lang-cpp@latest": "6.0.2", + "npm:@codemirror/lang-go@latest": "6.0.1", + "npm:@codemirror/lang-java@latest": "6.0.1", + "npm:@codemirror/lang-javascript@*": "6.2.3", + "npm:@codemirror/lang-javascript@latest": "6.2.3", + "npm:@codemirror/lang-python@*": "6.1.7", + "npm:@codemirror/lang-python@latest": "6.1.7", + "npm:@codemirror/lang-rust@latest": "6.0.1", + "npm:@codemirror/lang-sql@latest": "6.8.0", "npm:@deno/vite-plugin@1": "1.0.0_vite@5.4.10", "npm:@types/node@*": "22.5.4", "npm:@types/react-dom@^18.3.1": "18.3.1", "npm:@types/react@^18.3.11": "18.3.12", + "npm:@uiw/codemirror-theme-github@*": "4.23.10", + "npm:@uiw/codemirror-theme-github@latest": "4.23.10", + "npm:@uiw/react-codemirror@*": "4.23.10_@babel+runtime@7.26.0_@codemirror+state@6.5.2_@codemirror+theme-one-dark@6.1.2_@codemirror+view@6.36.4_codemirror@6.0.1_react@18.3.1_react-dom@18.3.1__react@18.3.1_@codemirror+commands@6.8.0", + "npm:@uiw/react-codemirror@latest": "4.23.10_@babel+runtime@7.26.0_@codemirror+state@6.5.2_@codemirror+theme-one-dark@6.1.2_@codemirror+view@6.36.4_codemirror@6.0.1_react@18.3.1_react-dom@18.3.1__react@18.3.1_@codemirror+commands@6.8.0", "npm:@vitejs/plugin-react-swc@^3.7.1": "3.7.1_vite@5.4.10", "npm:autoprefixer@^10.4.20": "10.4.20_postcss@8.4.47", "npm:path-to-regexp@6.2.1": "6.2.1", @@ -87,6 +101,138 @@ "regenerator-runtime" ] }, + "@codemirror/autocomplete@6.18.6": { + "integrity": "sha512-PHHBXFomUs5DF+9tCOM/UoW6XQ4R44lLNNhRaW9PKPTU0D7lIjRg3ElxaJnTwsl/oHiR93WSXDBrekhoUGCPtg==", + "dependencies": [ + "@codemirror/language", + "@codemirror/state", + "@codemirror/view", + "@lezer/common" + ] + }, + "@codemirror/commands@6.8.0": { + "integrity": "sha512-q8VPEFaEP4ikSlt6ZxjB3zW72+7osfAYW9i8Zu943uqbKuz6utc1+F170hyLUCUltXORjQXRyYQNfkckzA/bPQ==", + "dependencies": [ + "@codemirror/language", + "@codemirror/state", + "@codemirror/view", + "@lezer/common" + ] + }, + "@codemirror/lang-cpp@6.0.2": { + "integrity": "sha512-6oYEYUKHvrnacXxWxYa6t4puTlbN3dgV662BDfSH8+MfjQjVmP697/KYTDOqpxgerkvoNm7q5wlFMBeX8ZMocg==", + "dependencies": [ + "@codemirror/language", + "@lezer/cpp" + ] + }, + "@codemirror/lang-go@6.0.1": { + "integrity": "sha512-7fNvbyNylvqCphW9HD6WFnRpcDjr+KXX/FgqXy5H5ZS0eC5edDljukm/yNgYkwTsgp2busdod50AOTIy6Jikfg==", + "dependencies": [ + "@codemirror/autocomplete", + "@codemirror/language", + "@codemirror/state", + "@lezer/common", + "@lezer/go" + ] + }, + "@codemirror/lang-java@6.0.1": { + "integrity": "sha512-OOnmhH67h97jHzCuFaIEspbmsT98fNdhVhmA3zCxW0cn7l8rChDhZtwiwJ/JOKXgfm4J+ELxQihxaI7bj7mJRg==", + "dependencies": [ + "@codemirror/language", + "@lezer/java" + ] + }, + "@codemirror/lang-javascript@6.2.3": { + "integrity": "sha512-8PR3vIWg7pSu7ur8A07pGiYHgy3hHj+mRYRCSG8q+mPIrl0F02rgpGv+DsQTHRTc30rydOsf5PZ7yjKFg2Ackw==", + "dependencies": [ + "@codemirror/autocomplete", + "@codemirror/language", + "@codemirror/lint", + "@codemirror/state", + "@codemirror/view", + "@lezer/common", + "@lezer/javascript" + ] + }, + "@codemirror/lang-python@6.1.7": { + "integrity": "sha512-mZnFTsL4lW5p9ch8uKNKeRU3xGGxr1QpESLilfON2E3fQzOa/OygEMkaDvERvXDJWJA9U9oN/D4w0ZuUzNO4+g==", + "dependencies": [ + "@codemirror/autocomplete", + "@codemirror/language", + "@codemirror/state", + "@lezer/common", + "@lezer/python" + ] + }, + "@codemirror/lang-rust@6.0.1": { + "integrity": "sha512-344EMWFBzWArHWdZn/NcgkwMvZIWUR1GEBdwG8FEp++6o6vT6KL9V7vGs2ONsKxxFUPXKI0SPcWhyYyl2zPYxQ==", + "dependencies": [ + "@codemirror/language", + "@lezer/rust" + ] + }, + "@codemirror/lang-sql@6.8.0": { + "integrity": "sha512-aGLmY4OwGqN3TdSx3h6QeA1NrvaYtF7kkoWR/+W7/JzB0gQtJ+VJxewlnE3+VImhA4WVlhmkJr109PefOOhjLg==", + "dependencies": [ + "@codemirror/autocomplete", + "@codemirror/language", + "@codemirror/state", + "@lezer/common", + "@lezer/highlight", + "@lezer/lr" + ] + }, + "@codemirror/language@6.11.0": { + "integrity": "sha512-A7+f++LodNNc1wGgoRDTt78cOwWm9KVezApgjOMp1W4hM0898nsqBXwF+sbePE7ZRcjN7Sa1Z5m2oN27XkmEjQ==", + "dependencies": [ + "@codemirror/state", + "@codemirror/view", + "@lezer/common", + "@lezer/highlight", + "@lezer/lr", + "style-mod" + ] + }, + "@codemirror/lint@6.8.4": { + "integrity": "sha512-u4q7PnZlJUojeRe8FJa/njJcMctISGgPQ4PnWsd9268R4ZTtU+tfFYmwkBvgcrK2+QQ8tYFVALVb5fVJykKc5A==", + "dependencies": [ + "@codemirror/state", + "@codemirror/view", + "crelt" + ] + }, + "@codemirror/search@6.5.10": { + "integrity": "sha512-RMdPdmsrUf53pb2VwflKGHEe1XVM07hI7vV2ntgw1dmqhimpatSJKva4VA9h4TLUDOD4EIF02201oZurpnEFsg==", + "dependencies": [ + "@codemirror/state", + "@codemirror/view", + "crelt" + ] + }, + "@codemirror/state@6.5.2": { + "integrity": "sha512-FVqsPqtPWKVVL3dPSxy8wEF/ymIEuVzF1PK3VbUgrxXpJUSHQWWZz4JMToquRxnkw+36LTamCZG2iua2Ptq0fA==", + "dependencies": [ + "@marijn/find-cluster-break" + ] + }, + "@codemirror/theme-one-dark@6.1.2": { + "integrity": "sha512-F+sH0X16j/qFLMAfbciKTxVOwkdAS336b7AXTKOZhy8BR3eH/RelsnLgLFINrpST63mmN2OuwUt0W2ndUgYwUA==", + "dependencies": [ + "@codemirror/language", + "@codemirror/state", + "@codemirror/view", + "@lezer/highlight" + ] + }, + "@codemirror/view@6.36.4": { + "integrity": "sha512-ZQ0V5ovw/miKEXTvjgzRyjnrk9TwriUB1k4R5p7uNnHR9Hus+D1SXHGdJshijEzPFjU25xea/7nhIeSqYFKdbA==", + "dependencies": [ + "@codemirror/state", + "style-mod", + "w3c-keyname" + ] + }, "@deno/vite-plugin@1.0.0_vite@5.4.10": { "integrity": "sha512-Q9UeWqs3s7B5lqzu1Z5QrzYAzqTj3+F9YW17tWobGRbT2G40ihwis6zK/+QgMgcG4fm3IqdIfXmpQYhkZpdMfw==", "dependencies": [ @@ -197,6 +343,72 @@ "@jridgewell/sourcemap-codec" ] }, + "@lezer/common@1.2.3": { + "integrity": "sha512-w7ojc8ejBqr2REPsWxJjrMFsA/ysDCFICn8zEOR9mrqzOu2amhITYuLD8ag6XZf0CFXDrhKqw7+tW8cX66NaDA==" + }, + "@lezer/cpp@1.1.3": { + "integrity": "sha512-ykYvuFQKGsRi6IcE+/hCSGUhb/I4WPjd3ELhEblm2wS2cOznDFzO+ubK2c+ioysOnlZ3EduV+MVQFCPzAIoY3w==", + "dependencies": [ + "@lezer/common", + "@lezer/highlight", + "@lezer/lr" + ] + }, + "@lezer/go@1.0.0": { + "integrity": "sha512-co9JfT3QqX1YkrMmourYw2Z8meGC50Ko4d54QEcQbEYpvdUvN4yb0NBZdn/9ertgvjsySxHsKzH3lbm3vqJ4Jw==", + "dependencies": [ + "@lezer/common", + "@lezer/highlight", + "@lezer/lr" + ] + }, + "@lezer/highlight@1.2.1": { + "integrity": "sha512-Z5duk4RN/3zuVO7Jq0pGLJ3qynpxUVsh7IbUbGj88+uV2ApSAn6kWg2au3iJb+0Zi7kKtqffIESgNcRXWZWmSA==", + "dependencies": [ + "@lezer/common" + ] + }, + "@lezer/java@1.1.3": { + "integrity": "sha512-yHquUfujwg6Yu4Fd1GNHCvidIvJwi/1Xu2DaKl/pfWIA2c1oXkVvawH3NyXhCaFx4OdlYBVX5wvz2f7Aoa/4Xw==", + "dependencies": [ + "@lezer/common", + "@lezer/highlight", + "@lezer/lr" + ] + }, + "@lezer/javascript@1.4.21": { + "integrity": "sha512-lL+1fcuxWYPURMM/oFZLEDm0XuLN128QPV+VuGtKpeaOGdcl9F2LYC3nh1S9LkPqx9M0mndZFdXCipNAZpzIkQ==", + "dependencies": [ + "@lezer/common", + "@lezer/highlight", + "@lezer/lr" + ] + }, + "@lezer/lr@1.4.2": { + "integrity": "sha512-pu0K1jCIdnQ12aWNaAVU5bzi7Bd1w54J3ECgANPmYLtQKP0HBj2cE/5coBD66MT10xbtIuUr7tg0Shbsvk0mDA==", + "dependencies": [ + "@lezer/common" + ] + }, + "@lezer/python@1.1.16": { + "integrity": "sha512-ievIWylIZA5rNgAyHgA06/Y76vMUISKaYL9WrtjU8rCTTEzyZYo2jz9ER2YBdnN6dxCyS7eaK4HJCzamoAMKZw==", + "dependencies": [ + "@lezer/common", + "@lezer/highlight", + "@lezer/lr" + ] + }, + "@lezer/rust@1.0.2": { + "integrity": "sha512-Lz5sIPBdF2FUXcWeCu1//ojFAZqzTQNRga0aYv6dYXqJqPfMdCAI0NzajWUd4Xijj1IKJLtjoXRPMvTKWBcqKg==", + "dependencies": [ + "@lezer/common", + "@lezer/highlight", + "@lezer/lr" + ] + }, + "@marijn/find-cluster-break@1.0.2": { + "integrity": "sha512-l0h88YhZFyKdXIFNfSWpyjStDjGHwZ/U7iobcK1cQQD8sejsONdQtTVU+1wVN1PBw40PiiHB1vA5S7VTfQiP9g==" + }, "@nodelib/fs.scandir@2.1.5": { "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", "dependencies": [ @@ -364,6 +576,46 @@ "@types/unist@2.0.11": { "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==" }, + "@uiw/codemirror-extensions-basic-setup@4.23.10_@codemirror+autocomplete@6.18.6_@codemirror+commands@6.8.0_@codemirror+language@6.11.0_@codemirror+lint@6.8.4_@codemirror+search@6.5.10_@codemirror+state@6.5.2_@codemirror+view@6.36.4": { + "integrity": "sha512-zpbmSeNs3OU/f/Eyd6brFnjsBUYwv2mFjWxlAsIRSwTlW+skIT60rQHFBSfsj/5UVSxSLWVeUYczN7AyXvgTGQ==", + "dependencies": [ + "@codemirror/autocomplete", + "@codemirror/commands", + "@codemirror/language", + "@codemirror/lint", + "@codemirror/search", + "@codemirror/state", + "@codemirror/view" + ] + }, + "@uiw/codemirror-theme-github@4.23.10": { + "integrity": "sha512-jTg2sHAcU1d+8x0O+EBDI71rtJ8PWKIW8gzy+SW4wShQTAdsqGHk5y1ynt3KIeoaUkqngLqAK4SkhPaUKlqZqg==", + "dependencies": [ + "@uiw/codemirror-themes" + ] + }, + "@uiw/codemirror-themes@4.23.10_@codemirror+language@6.11.0_@codemirror+state@6.5.2_@codemirror+view@6.36.4": { + "integrity": "sha512-dU0UgEEgEXCAYpxuVDQ6fovE82XsqgHZckTJOH6Bs8xCi3Z7dwBKO4pXuiA8qGDwTOXOMjSzfi+pRViDm7OfWw==", + "dependencies": [ + "@codemirror/language", + "@codemirror/state", + "@codemirror/view" + ] + }, + "@uiw/react-codemirror@4.23.10_@babel+runtime@7.26.0_@codemirror+state@6.5.2_@codemirror+theme-one-dark@6.1.2_@codemirror+view@6.36.4_codemirror@6.0.1_react@18.3.1_react-dom@18.3.1__react@18.3.1_@codemirror+commands@6.8.0": { + "integrity": "sha512-AbN4eVHOL4ckRuIXpZxkzEqL/1ChVA+BSdEnAKjIB68pLQvKsVoYbiFP8zkXkYc4+Fcgq5KbAjvYqdo4ewemKw==", + "dependencies": [ + "@babel/runtime", + "@codemirror/commands", + "@codemirror/state", + "@codemirror/theme-one-dark", + "@codemirror/view", + "@uiw/codemirror-extensions-basic-setup", + "codemirror", + "react", + "react-dom" + ] + }, "@vitejs/plugin-react-swc@3.7.1_vite@5.4.10": { "integrity": "sha512-vgWOY0i1EROUK0Ctg1hwhtC3SdcDjZcdit4Ups4aPkDcB1jYhmo+RMYWY87cmXMhvtD5uf8lV89j2w16vkdSVg==", "dependencies": [ @@ -466,6 +718,18 @@ "readdirp" ] }, + "codemirror@6.0.1": { + "integrity": "sha512-J8j+nZ+CdWmIeFIGXEFbFPtpiYacFMDR8GlHK3IyHQJMCaVRfGx9NT+Hxivv1ckLWPvNdZqndbr/7lVhrf/Svg==", + "dependencies": [ + "@codemirror/autocomplete", + "@codemirror/commands", + "@codemirror/language", + "@codemirror/lint", + "@codemirror/search", + "@codemirror/state", + "@codemirror/view" + ] + }, "color-convert@2.0.1": { "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dependencies": [ @@ -481,6 +745,9 @@ "commander@4.1.1": { "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==" }, + "crelt@1.0.6": { + "integrity": "sha512-VQ2MBenTq1fWZUH9DJNGti7kKv6EeAuYr3cLwxUWhIu1baTaXh4Ib5W2CqHVqib4/MqbYGJqiL3Zb8GJZr3l4g==" + }, "cross-spawn@7.0.5": { "integrity": "sha512-ZVJrKKYunU38/76t0RMOulHOnUcbU9GbpWKAOZ0mhjr7CX6FVrH+4FrAapSOekrgFQ3f/8gwMEuIft0aKq6Hug==", "dependencies": [ @@ -1033,6 +1300,9 @@ "ansi-regex@6.1.0" ] }, + "style-mod@4.1.2": { + "integrity": "sha512-wnD1HyVqpJUI2+eKZ+eo1UwghftP6yuFheBqqe+bWCotBjC2K1YnteJILRMs3SM4V/0dLEW1SC27MWP5y+mwmw==" + }, "sucrase@3.35.0": { "integrity": "sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==", "dependencies": [ @@ -1119,6 +1389,9 @@ "rollup" ] }, + "w3c-keyname@2.2.8": { + "integrity": "sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==" + }, "which@2.0.2": { "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dependencies": [ @@ -1381,9 +1654,18 @@ }, "workspace": { "dependencies": [ + "npm:@codemirror/lang-cpp@latest", + "npm:@codemirror/lang-go@latest", + "npm:@codemirror/lang-java@latest", + "npm:@codemirror/lang-javascript@latest", + "npm:@codemirror/lang-python@latest", + "npm:@codemirror/lang-rust@latest", + "npm:@codemirror/lang-sql@latest", "npm:@deno/vite-plugin@1", "npm:@types/react-dom@^18.3.1", "npm:@types/react@^18.3.11", + "npm:@uiw/codemirror-theme-github@latest", + "npm:@uiw/react-codemirror@latest", "npm:@vitejs/plugin-react-swc@^3.7.1", "npm:autoprefixer@^10.4.20", "npm:postcss@^8.4.47", diff --git a/src/utils/CodeEditor.tsx b/src/utils/CodeEditor.tsx new file mode 100644 index 0000000..cb1289a --- /dev/null +++ b/src/utils/CodeEditor.tsx @@ -0,0 +1,85 @@ +// CodeEditor.tsx +import { useState } from "react"; +import CodeMirror from "@uiw/react-codemirror"; +import { javascript } from "@codemirror/lang-javascript"; +import { python } from "@codemirror/lang-python"; +import { cpp } from "@codemirror/lang-cpp"; +import { java } from "@codemirror/lang-java"; +import { rust } from "@codemirror/lang-rust"; +import { go } from "@codemirror/lang-go"; +import { sql } from "@codemirror/lang-sql"; +import { githubLight } from "@uiw/codemirror-theme-github"; +import { text } from "stream/consumers"; + +const languages = { + javascript: javascript(), + python: python(), + cpp: cpp(), + java: java(), + rust: rust(), + go: go(), + sql: sql(), +}; + +interface CodeEditorProps { + language?: keyof typeof languages; + code: string; + onLanguageChange?: (lang: keyof typeof languages) => void; + onCodeChange?: (code: string) => void; + readOnly? : boolean; +} + +export const CodeEditor = ({ + language = "cpp", + code, + onLanguageChange, + onCodeChange, + readOnly = false +}: CodeEditorProps) => { + return ( +
+ {/* Selector de lenguaje */} + {!readOnly && ( + + )} + + {/* Contenedor con scroll */} +
+ +
+
+ ); +}; \ No newline at end of file diff --git a/src/utils/input.tsx b/src/utils/input.tsx index 626d7e6..5e6e0c4 100644 --- a/src/utils/input.tsx +++ b/src/utils/input.tsx @@ -1,7 +1,30 @@ import { useEffect, useState } from "react"; import { Link, useParams } from "react-router-dom"; +import CodeMirror from "@uiw/react-codemirror"; +import { javascript } from "@codemirror/lang-javascript"; +import { python } from "@codemirror/lang-python"; +import { cpp } from "@codemirror/lang-cpp"; +import { java } from "@codemirror/lang-java"; +import { rust } from "@codemirror/lang-rust"; +import { go } from "@codemirror/lang-go"; +import { sql } from "@codemirror/lang-sql"; +import { githubLight } from "@uiw/codemirror-theme-github"; +import { CodeEditor } from "./CodeEditor.tsx"; + + +const languages = { + javascript: javascript(), + python: python(), + cpp: cpp(), + java: java(), + rust: rust(), + go: go(), + sql: sql(), +}; const input = () => { + const [language, setLanguage] = useState("python"); + const { pt } = useParams(); const [dato, setDato] = useState({ name: '', @@ -32,6 +55,7 @@ const input = () => { useEffect(() => { }, [dato]); return ( +

@@ -84,16 +108,11 @@ const input = () => { />

-

- Codigo -

-