From adf647483c2ec6fe72c9e40b34a2b5e5fd26a518 Mon Sep 17 00:00:00 2001 From: 1ilit <1ilit@proton.me> Date: Sat, 12 Apr 2025 20:50:47 +0400 Subject: [PATCH] Switch to monaco-editor from codemirror (#403) * switch to monaco-editor * fix styles --- package-lock.json | 302 +++----------------- package.json | 6 +- src/components/CodeEditor/index.jsx | 47 +++ src/components/CodeEditor/setUpDBML.js | 152 ++++++++++ src/components/CodeEditor/styles.css | 4 + src/components/EditorHeader/Modal/Code.jsx | 52 ---- src/components/EditorHeader/Modal/Modal.jsx | 20 +- src/utils/modalData.js | 1 + 8 files changed, 259 insertions(+), 325 deletions(-) create mode 100644 src/components/CodeEditor/index.jsx create mode 100644 src/components/CodeEditor/setUpDBML.js create mode 100644 src/components/CodeEditor/styles.css delete mode 100644 src/components/EditorHeader/Modal/Code.jsx diff --git a/package-lock.json b/package-lock.json index 44fa7ff..bd145e4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,14 +8,10 @@ "name": "client-vite", "version": "0.0.0", "dependencies": { - "@codemirror/lang-json": "^6.0.1", - "@codemirror/lang-sql": "^6.6.3", "@dbml/core": "^3.9.7-alpha.0", "@douyinfe/semi-ui": "^2.77.1", "@lexical/react": "^0.12.5", - "@uiw/codemirror-theme-github": "^4.21.25", - "@uiw/codemirror-theme-vscode": "^4.21.25", - "@uiw/react-codemirror": "^4.21.25", + "@monaco-editor/react": "^4.7.0", "@vercel/analytics": "^1.2.2", "@vercel/speed-insights": "^1.2.0", "axios": "^1.8.2", @@ -378,115 +374,6 @@ "node": ">=6.9.0" } }, - "node_modules/@codemirror/autocomplete": { - "version": "6.16.0", - "resolved": "https://registry.npmjs.org/@codemirror/autocomplete/-/autocomplete-6.16.0.tgz", - "integrity": "sha512-P/LeCTtZHRTCU4xQsa89vSKWecYv1ZqwzOd5topheGRf+qtacFgBeIMQi3eL8Kt/BUNvxUWkx+5qP2jlGoARrg==", - "dependencies": { - "@codemirror/language": "^6.0.0", - "@codemirror/state": "^6.0.0", - "@codemirror/view": "^6.17.0", - "@lezer/common": "^1.0.0" - }, - "peerDependencies": { - "@codemirror/language": "^6.0.0", - "@codemirror/state": "^6.0.0", - "@codemirror/view": "^6.0.0", - "@lezer/common": "^1.0.0" - } - }, - "node_modules/@codemirror/commands": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/@codemirror/commands/-/commands-6.4.0.tgz", - "integrity": "sha512-HB3utD5GxCvEhSyj5EuG9KpuQQhFpxalh3lwrspyL/GeSNDe4c6JDxVzL12SJ+7gUknHjZzmq7OPCb9QPgiRmQ==", - "dependencies": { - "@codemirror/language": "^6.0.0", - "@codemirror/state": "^6.4.0", - "@codemirror/view": "^6.0.0", - "@lezer/common": "^1.1.0" - } - }, - "node_modules/@codemirror/lang-json": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/@codemirror/lang-json/-/lang-json-6.0.1.tgz", - "integrity": "sha512-+T1flHdgpqDDlJZ2Lkil/rLiRy684WMLc74xUnjJH48GQdfJo/pudlTRreZmKwzP8/tGdKf83wlbAdOCzlJOGQ==", - "dependencies": { - "@codemirror/language": "^6.0.0", - "@lezer/json": "^1.0.0" - } - }, - "node_modules/@codemirror/lang-sql": { - "version": "6.6.3", - "resolved": "https://registry.npmjs.org/@codemirror/lang-sql/-/lang-sql-6.6.3.tgz", - "integrity": "sha512-fo5i3OD/7TmmqMtKycC4OaqfPsRxk0sKOb35g8cOtyUyyI2hfP2qXkDc7Asb6h7BiJK+MU/DYVPnQm6iNB5ZTw==", - "dependencies": { - "@codemirror/autocomplete": "^6.0.0", - "@codemirror/language": "^6.0.0", - "@codemirror/state": "^6.0.0", - "@lezer/common": "^1.2.0", - "@lezer/highlight": "^1.0.0", - "@lezer/lr": "^1.0.0" - } - }, - "node_modules/@codemirror/language": { - "version": "6.10.1", - "resolved": "https://registry.npmjs.org/@codemirror/language/-/language-6.10.1.tgz", - "integrity": "sha512-5GrXzrhq6k+gL5fjkAwt90nYDmjlzTIJV8THnxNFtNKWotMIlzzN+CpqxqwXOECnUdOndmSeWntVrVcv5axWRQ==", - "dependencies": { - "@codemirror/state": "^6.0.0", - "@codemirror/view": "^6.23.0", - "@lezer/common": "^1.1.0", - "@lezer/highlight": "^1.0.0", - "@lezer/lr": "^1.0.0", - "style-mod": "^4.0.0" - } - }, - "node_modules/@codemirror/lint": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@codemirror/lint/-/lint-6.5.0.tgz", - "integrity": "sha512-+5YyicIaaAZKU8K43IQi8TBy6mF6giGeWAH7N96Z5LC30Wm5JMjqxOYIE9mxwMG1NbhT2mA3l9hA4uuKUM3E5g==", - "dependencies": { - "@codemirror/state": "^6.0.0", - "@codemirror/view": "^6.0.0", - "crelt": "^1.0.5" - } - }, - "node_modules/@codemirror/search": { - "version": "6.5.6", - "resolved": "https://registry.npmjs.org/@codemirror/search/-/search-6.5.6.tgz", - "integrity": "sha512-rpMgcsh7o0GuCDUXKPvww+muLA1pDJaFrpq/CCHtpQJYz8xopu4D1hPcKRoDD0YlF8gZaqTNIRa4VRBWyhyy7Q==", - "dependencies": { - "@codemirror/state": "^6.0.0", - "@codemirror/view": "^6.0.0", - "crelt": "^1.0.5" - } - }, - "node_modules/@codemirror/state": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/@codemirror/state/-/state-6.4.1.tgz", - "integrity": "sha512-QkEyUiLhsJoZkbumGZlswmAhA7CBU02Wrz7zvH4SrcifbsqwlXShVXg65f3v/ts57W3dqyamEriMhij1Z3Zz4A==" - }, - "node_modules/@codemirror/theme-one-dark": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/@codemirror/theme-one-dark/-/theme-one-dark-6.1.2.tgz", - "integrity": "sha512-F+sH0X16j/qFLMAfbciKTxVOwkdAS336b7AXTKOZhy8BR3eH/RelsnLgLFINrpST63mmN2OuwUt0W2ndUgYwUA==", - "dependencies": { - "@codemirror/language": "^6.0.0", - "@codemirror/state": "^6.0.0", - "@codemirror/view": "^6.0.0", - "@lezer/highlight": "^1.0.0" - } - }, - "node_modules/@codemirror/view": { - "version": "6.26.3", - "resolved": "https://registry.npmjs.org/@codemirror/view/-/view-6.26.3.tgz", - "integrity": "sha512-gmqxkPALZjkgSxIeeweY/wGQXBfwTUaLs8h7OKtSwfbj9Ct3L11lD+u1sS7XHppxFQoMDiMDp07P9f3I2jWOHw==", - "dependencies": { - "@codemirror/state": "^6.4.0", - "style-mod": "^4.1.0", - "w3c-keyname": "^2.2.4" - } - }, "node_modules/@dbml/core": { "version": "3.9.7-alpha.0", "resolved": "https://registry.npmjs.org/@dbml/core/-/core-3.9.7-alpha.0.tgz", @@ -1516,37 +1403,6 @@ "yjs": ">=13.5.22" } }, - "node_modules/@lezer/common": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@lezer/common/-/common-1.2.1.tgz", - "integrity": "sha512-yemX0ZD2xS/73llMZIK6KplkjIjf2EvAHcinDi/TfJ9hS25G0388+ClHt6/3but0oOxinTcQHJLDXh6w1crzFQ==" - }, - "node_modules/@lezer/highlight": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@lezer/highlight/-/highlight-1.2.0.tgz", - "integrity": "sha512-WrS5Mw51sGrpqjlh3d4/fOwpEV2Hd3YOkp9DBt4k8XZQcoTHZFB7sx030A6OcahF4J1nDQAa3jXlTVVYH50IFA==", - "dependencies": { - "@lezer/common": "^1.0.0" - } - }, - "node_modules/@lezer/json": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@lezer/json/-/json-1.0.2.tgz", - "integrity": "sha512-xHT2P4S5eeCYECyKNPhr4cbEL9tc8w83SPwRC373o9uEdrvGKTZoJVAGxpOsZckMlEh9W23Pc72ew918RWQOBQ==", - "dependencies": { - "@lezer/common": "^1.2.0", - "@lezer/highlight": "^1.0.0", - "@lezer/lr": "^1.0.0" - } - }, - "node_modules/@lezer/lr": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@lezer/lr/-/lr-1.4.0.tgz", - "integrity": "sha512-Wst46p51km8gH0ZUmeNrtpRYmdlRHUpN1DQd3GFAyKANi8WVz8c2jHYTf1CVScFaCjQw1iO3ZZdqGDxQPRErTg==", - "dependencies": { - "@lezer/common": "^1.0.0" - } - }, "node_modules/@mdx-js/mdx": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/@mdx-js/mdx/-/mdx-3.1.0.tgz", @@ -1583,6 +1439,29 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/@monaco-editor/loader": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@monaco-editor/loader/-/loader-1.5.0.tgz", + "integrity": "sha512-hKoGSM+7aAc7eRTRjpqAZucPmoNOC4UUbknb/VNoTkEIkCPhqV8LfbsgM1webRM7S/z21eHEx9Fkwx8Z/C/+Xw==", + "license": "MIT", + "dependencies": { + "state-local": "^1.0.6" + } + }, + "node_modules/@monaco-editor/react": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/@monaco-editor/react/-/react-4.7.0.tgz", + "integrity": "sha512-cyzXQCtO47ydzxpQtCGSQGOC8Gk3ZUeBXFAxD+CWXYFo5OqZyZUonFl0DwUlTyAfRHntBfw2p3w4s9R6oe1eCA==", + "license": "MIT", + "dependencies": { + "@monaco-editor/loader": "^1.5.0" + }, + "peerDependencies": { + "monaco-editor": ">= 0.25.0 < 1", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -2643,97 +2522,6 @@ "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", "license": "MIT" }, - "node_modules/@uiw/codemirror-extensions-basic-setup": { - "version": "4.21.25", - "resolved": "https://registry.npmjs.org/@uiw/codemirror-extensions-basic-setup/-/codemirror-extensions-basic-setup-4.21.25.tgz", - "integrity": "sha512-eeUKlmEE8aSoSgelS8OR2elcPGntpRo669XinAqPCLa0eKorT2B0d3ts+AE+njAeGk744tiyAEbHb2n+6OQmJw==", - "dependencies": { - "@codemirror/autocomplete": "^6.0.0", - "@codemirror/commands": "^6.0.0", - "@codemirror/language": "^6.0.0", - "@codemirror/lint": "^6.0.0", - "@codemirror/search": "^6.0.0", - "@codemirror/state": "^6.0.0", - "@codemirror/view": "^6.0.0" - }, - "funding": { - "url": "https://jaywcjlove.github.io/#/sponsor" - }, - "peerDependencies": { - "@codemirror/autocomplete": ">=6.0.0", - "@codemirror/commands": ">=6.0.0", - "@codemirror/language": ">=6.0.0", - "@codemirror/lint": ">=6.0.0", - "@codemirror/search": ">=6.0.0", - "@codemirror/state": ">=6.0.0", - "@codemirror/view": ">=6.0.0" - } - }, - "node_modules/@uiw/codemirror-theme-github": { - "version": "4.21.25", - "resolved": "https://registry.npmjs.org/@uiw/codemirror-theme-github/-/codemirror-theme-github-4.21.25.tgz", - "integrity": "sha512-RDS9s/Lbi1uIvupIXNiREFMryZjd7X4xRMKzmf6NfZuXWVdDATTA1b5smzxXldJgl8bY4QoOevczRncFTVRfGA==", - "dependencies": { - "@uiw/codemirror-themes": "4.21.25" - }, - "funding": { - "url": "https://jaywcjlove.github.io/#/sponsor" - } - }, - "node_modules/@uiw/codemirror-theme-vscode": { - "version": "4.21.25", - "resolved": "https://registry.npmjs.org/@uiw/codemirror-theme-vscode/-/codemirror-theme-vscode-4.21.25.tgz", - "integrity": "sha512-1gubCz7kHE5XH3H1IUTSrnyK/G3dQRmOIgPFsefE9e+TizhBJnkbKSDSfRfpm5l7jl1G7v/as0HQvN3cYg/Rkg==", - "dependencies": { - "@uiw/codemirror-themes": "4.21.25" - }, - "funding": { - "url": "https://jaywcjlove.github.io/#/sponsor" - } - }, - "node_modules/@uiw/codemirror-themes": { - "version": "4.21.25", - "resolved": "https://registry.npmjs.org/@uiw/codemirror-themes/-/codemirror-themes-4.21.25.tgz", - "integrity": "sha512-C3t/voELxQj0eaVhrlgzaOnSALNf8bOcRbL5xN9r2+RkdsbFOmvNl3VVhlxEB7PSGc1jUZwVO4wQsB2AP178ag==", - "dependencies": { - "@codemirror/language": "^6.0.0", - "@codemirror/state": "^6.0.0", - "@codemirror/view": "^6.0.0" - }, - "funding": { - "url": "https://jaywcjlove.github.io/#/sponsor" - }, - "peerDependencies": { - "@codemirror/language": ">=6.0.0", - "@codemirror/state": ">=6.0.0", - "@codemirror/view": ">=6.0.0" - } - }, - "node_modules/@uiw/react-codemirror": { - "version": "4.21.25", - "resolved": "https://registry.npmjs.org/@uiw/react-codemirror/-/react-codemirror-4.21.25.tgz", - "integrity": "sha512-mBrCoiffQ+hbTqV1JoixFEcH7BHXkS3PjTyNH7dE8Gzf3GSBRazhtSM5HrAFIiQ5FIRGFs8Gznc4UAdhtevMmw==", - "dependencies": { - "@babel/runtime": "^7.18.6", - "@codemirror/commands": "^6.1.0", - "@codemirror/state": "^6.1.1", - "@codemirror/theme-one-dark": "^6.0.0", - "@uiw/codemirror-extensions-basic-setup": "4.21.25", - "codemirror": "^6.0.0" - }, - "funding": { - "url": "https://jaywcjlove.github.io/#/sponsor" - }, - "peerDependencies": { - "@babel/runtime": ">=7.11.0", - "@codemirror/state": ">=6.0.0", - "@codemirror/theme-one-dark": ">=6.0.0", - "@codemirror/view": ">=6.0.0", - "codemirror": ">=6.0.0", - "react": ">=16.8.0", - "react-dom": ">=16.8.0" - } - }, "node_modules/@ungap/structured-clone": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", @@ -3280,20 +3068,6 @@ "node": ">=6" } }, - "node_modules/codemirror": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/codemirror/-/codemirror-6.0.1.tgz", - "integrity": "sha512-J8j+nZ+CdWmIeFIGXEFbFPtpiYacFMDR8GlHK3IyHQJMCaVRfGx9NT+Hxivv1ckLWPvNdZqndbr/7lVhrf/Svg==", - "dependencies": { - "@codemirror/autocomplete": "^6.0.0", - "@codemirror/commands": "^6.0.0", - "@codemirror/language": "^6.0.0", - "@codemirror/lint": "^6.0.0", - "@codemirror/search": "^6.0.0", - "@codemirror/state": "^6.0.0", - "@codemirror/view": "^6.0.0" - } - }, "node_modules/collapse-white-space": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/collapse-white-space/-/collapse-white-space-2.1.0.tgz", @@ -3373,11 +3147,6 @@ "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", "license": "MIT" }, - "node_modules/crelt": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/crelt/-/crelt-1.0.6.tgz", - "integrity": "sha512-VQ2MBenTq1fWZUH9DJNGti7kKv6EeAuYr3cLwxUWhIu1baTaXh4Ib5W2CqHVqib4/MqbYGJqiL3Zb8GJZr3l4g==" - }, "node_modules/cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -6775,6 +6544,13 @@ "node": "*" } }, + "node_modules/monaco-editor": { + "version": "0.52.2", + "resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.52.2.tgz", + "integrity": "sha512-GEQWEZmfkOGLdd3XK8ryrfWz3AIP8YymVXiPHEdewrUq7mh0qrKrfHLNCXcbB6sTnMLnOZ3ztSiKcciFUkIJwQ==", + "license": "MIT", + "peer": true + }, "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -7960,6 +7736,12 @@ "node": ">=0.1.14" } }, + "node_modules/state-local": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/state-local/-/state-local-1.0.7.tgz", + "integrity": "sha512-HTEHMNieakEnoe33shBYcZ7NX83ACUjCu8c40iOGEZsngj9zRnkqS9j1pqQPXwobB0ZcVTk27REb7COQ0UR59w==", + "license": "MIT" + }, "node_modules/string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", @@ -8072,11 +7854,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/style-mod": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/style-mod/-/style-mod-4.1.2.tgz", - "integrity": "sha512-wnD1HyVqpJUI2+eKZ+eo1UwghftP6yuFheBqqe+bWCotBjC2K1YnteJILRMs3SM4V/0dLEW1SC27MWP5y+mwmw==" - }, "node_modules/style-to-js": { "version": "1.1.16", "resolved": "https://registry.npmjs.org/style-to-js/-/style-to-js-1.1.16.tgz", @@ -8607,11 +8384,6 @@ "node": ">=0.10.0" } }, - "node_modules/w3c-keyname": { - "version": "2.2.8", - "resolved": "https://registry.npmjs.org/w3c-keyname/-/w3c-keyname-2.2.8.tgz", - "integrity": "sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==" - }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", diff --git a/package.json b/package.json index a7c1250..3465c7e 100644 --- a/package.json +++ b/package.json @@ -10,14 +10,10 @@ "preview": "vite preview" }, "dependencies": { - "@codemirror/lang-json": "^6.0.1", - "@codemirror/lang-sql": "^6.6.3", "@dbml/core": "^3.9.7-alpha.0", "@douyinfe/semi-ui": "^2.77.1", "@lexical/react": "^0.12.5", - "@uiw/codemirror-theme-github": "^4.21.25", - "@uiw/codemirror-theme-vscode": "^4.21.25", - "@uiw/react-codemirror": "^4.21.25", + "@monaco-editor/react": "^4.7.0", "@vercel/analytics": "^1.2.2", "@vercel/speed-insights": "^1.2.0", "axios": "^1.8.2", diff --git a/src/components/CodeEditor/index.jsx b/src/components/CodeEditor/index.jsx new file mode 100644 index 0000000..2bed794 --- /dev/null +++ b/src/components/CodeEditor/index.jsx @@ -0,0 +1,47 @@ +import { Editor } from "@monaco-editor/react"; +import { useDiagram, useSettings } from "../../hooks"; +import { Button, Toast } from "@douyinfe/semi-ui"; +import { useTranslation } from "react-i18next"; +import { IconCopy } from "@douyinfe/semi-icons"; +import { setUpDBML } from "./setUpDBML"; +import "./styles.css"; + +export default function CodeEditor({ showCopyButton, ...props }) { + const { settings } = useSettings(); + const { database } = useDiagram(); + const { t } = useTranslation(); + + const copyCode = () => { + navigator.clipboard + .writeText(props.value) + .then(() => Toast.success(t("copied_to_clipboard"))) + .catch((e) => { + console.log(e); + }); + }; + + const handleEditorMount = (editor, monaco) => { + setUpDBML(monaco, database); + + setTimeout(() => { + editor.getAction("editor.action.formatDocument").run(); + }, 300); + }; + + return ( +
+ + {showCopyButton && ( +
+ ); +} diff --git a/src/components/CodeEditor/setUpDBML.js b/src/components/CodeEditor/setUpDBML.js new file mode 100644 index 0000000..4a486a3 --- /dev/null +++ b/src/components/CodeEditor/setUpDBML.js @@ -0,0 +1,152 @@ +import { dbToTypes } from "../../data/datatypes"; + +export function setUpDBML(monaco, database) { + monaco.languages.register({ id: "dbml" }); + + console.log(Object.keys(dbToTypes[database])); + + monaco.languages.setMonarchTokensProvider("dbml", { + defaultToken: "", + tokenPostfix: ".dbml", + ignoreCase: true, + + keywords: [ + "table", + "tablegroup", + "project", + "enum", + "ref", + "as", + "indexes", + "index", + "note", + "delete", + "update", + "pk", + "increment", + "not", + "null", + "unique", + "default", + ], + + typeKeywords: Object.keys(dbToTypes[database]), + + operators: [ + "=", + ">", + "<", + "!", + "~", + "?", + ":", + "==", + "<=", + ">=", + "!=", + "&&", + "||", + "++", + "--", + "+", + "-", + "*", + "/", + "&", + "|", + "^", + ], + + symbols: /[=>](?!@symbols)/, "@brackets"], + [ + /@symbols/, + { + cases: { + "@operators": "operator", + "@default": "", + }, + }, + ], + [/\d*\.\d+([eE][-+]?\d+)?/, "number.float"], + [/0[xX][0-9a-fA-F]+/, "number.hex"], + [/\d+/, "number"], + [/[;,.]/, "delimiter"], + [/"([^"\\]|\\.)*$/, "string.invalid"], + [/'([^'\\]|\\.)*$/, "string.invalid"], + [/"/, { token: "string.quote", bracket: "@open", next: "@dqstring" }], + [/'/, { token: "string.quote", bracket: "@open", next: "@sqstring" }], + ], + + dqstring: [ + [/[^\\"]+/, "string"], + [/@escapes/, "string.escape"], + [/\\./, "string.escape.invalid"], + [/"/, { token: "string.quote", bracket: "@close", next: "@pop" }], + ], + + sqstring: [ + [/[^\\']+/, "string"], + [/@escapes/, "string.escape"], + [/\\./, "string.escape.invalid"], + [/'/, { token: "string.quote", bracket: "@close", next: "@pop" }], + ], + + comment: [ + [/[^\\/*]+/, "comment"], + [/\/\*/, "comment", "@push"], + ["\\*/", "comment", "@pop"], + [/[\\/*]/, "comment"], + ], + + whitespace: [ + [/[ \t\r\n]+/, "white"], + [/\/\*/, "comment", "@comment"], + [/\/\/.*$/, "comment"], + ], + }, + }); + + monaco.languages.setLanguageConfiguration("dbml", { + comments: { + lineComment: "//", + blockComment: ["/*", "*/"], + }, + brackets: [ + ["{", "}"], + ["[", "]"], + ["(", ")"], + ], + autoClosingPairs: [ + { open: "{", close: "}" }, + { open: "[", close: "]" }, + { open: "(", close: ")" }, + { open: '"', close: '"' }, + { open: "'", close: "'" }, + ], + surroundingPairs: [ + { open: "{", close: "}" }, + { open: "[", close: "]" }, + { open: "(", close: ")" }, + { open: '"', close: '"' }, + { open: "'", close: "'" }, + ], + }); +} diff --git a/src/components/CodeEditor/styles.css b/src/components/CodeEditor/styles.css new file mode 100644 index 0000000..e48b1cd --- /dev/null +++ b/src/components/CodeEditor/styles.css @@ -0,0 +1,4 @@ +.monaco-editor, +.monaco-editor > .overflow-guard { + border-radius: 6px; +} diff --git a/src/components/EditorHeader/Modal/Code.jsx b/src/components/EditorHeader/Modal/Code.jsx deleted file mode 100644 index 8b291a7..0000000 --- a/src/components/EditorHeader/Modal/Code.jsx +++ /dev/null @@ -1,52 +0,0 @@ -import { useState } from "react"; -import { sql } from "@codemirror/lang-sql"; -import { json } from "@codemirror/lang-json"; -import { vscodeDark } from "@uiw/codemirror-theme-vscode"; -import { githubLight } from "@uiw/codemirror-theme-github"; -import { useSettings } from "../../../hooks"; -import { useTranslation } from "react-i18next"; -import CodeMirror from "@uiw/react-codemirror"; - -const languageExtension = { - sql: [sql()], - json: [json()], -}; - -export default function Code({ value, language }) { - const { t } = useTranslation(); - const { settings } = useSettings(); - const [copied, setCopied] = useState(false); - - const copyCode = () => { - navigator.clipboard - .writeText(value) - .then(() => { - setCopied(true); - setTimeout(() => { - setCopied(false); - }, 2000); - }) - .catch((e) => { - console.log(e); - }); - }; - - return ( -
- - -
- ); -} diff --git a/src/components/EditorHeader/Modal/Modal.jsx b/src/components/EditorHeader/Modal/Modal.jsx index 0e5ceec..812b07b 100644 --- a/src/components/EditorHeader/Modal/Modal.jsx +++ b/src/components/EditorHeader/Modal/Modal.jsx @@ -34,12 +34,19 @@ import ImportSource from "./ImportSource"; import SetTableWidth from "./SetTableWidth"; import Language from "./Language"; import Share from "./Share"; -import Code from "./Code"; +import CodeEditor from "../../CodeEditor"; import { useTranslation } from "react-i18next"; import { importSQL } from "../../../utils/importSQL"; import { databases } from "../../../data/databases"; import { isRtl } from "../../../i18n/utils/rtl"; +const extensionToLanguage = { + md: "markdown", + sql: "sql", + dbml: "dbml", + json: "json", +}; + export default function Modal({ modal, setModal, @@ -52,7 +59,8 @@ export default function Modal({ importFrom, }) { const { t, i18n } = useTranslation(); - const { tables, setTables, setRelationships, database, setDatabase } = useDiagram(); + const { tables, setTables, setRelationships, database, setDatabase } = + useDiagram(); const { setNotes } = useNotes(); const { setAreas } = useAreas(); const { setTypes } = useTypes(); @@ -307,7 +315,13 @@ export default function Modal({ {modal === MODAL.IMG ? ( Diagram ) : ( - + )}
{t("filename")}:
{ switch (modal) { case MODAL.LANGUAGE: case MODAL.OPEN: + case MODAL.CODE: case MODAL.NEW: return 740; default: