index.tsx 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. import React from "react";
  2. import Editor, { loader } from "@monaco-editor/react";
  3. import { Loading } from "src/components/Loading";
  4. import useConfig from "src/hooks/store/useConfig";
  5. import useGraph from "src/hooks/store/useGraph";
  6. import useStored from "src/hooks/store/useStored";
  7. import { parser } from "src/utils/jsonParser";
  8. import styled from "styled-components";
  9. loader.config({
  10. paths: {
  11. vs: "https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.34.0/min/vs",
  12. },
  13. });
  14. const editorOptions = {
  15. formatOnPaste: true,
  16. minimap: {
  17. enabled: false,
  18. },
  19. };
  20. const StyledWrapper = styled.div`
  21. display: grid;
  22. height: calc(100vh - 36px);
  23. grid-template-columns: 100%;
  24. grid-template-rows: minmax(0, 1fr);
  25. `;
  26. export const MonacoEditor = ({
  27. setHasError,
  28. }: {
  29. setHasError: (value: boolean) => void;
  30. }) => {
  31. const json = useConfig(state => state.json);
  32. const expand = useConfig(state => state.expand);
  33. const setJson = useConfig(state => state.setJson);
  34. const setGraphValue = useGraph(state => state.setGraphValue);
  35. const [value, setValue] = React.useState<string | undefined>("");
  36. const lightmode = useStored(state => (state.lightmode ? "light" : "vs-dark"));
  37. React.useEffect(() => {
  38. const { nodes, edges } = parser(json, expand);
  39. setGraphValue("nodes", nodes);
  40. setGraphValue("edges", edges);
  41. setValue(json);
  42. }, [expand, json, setGraphValue]);
  43. React.useEffect(() => {
  44. const formatTimer = setTimeout(() => {
  45. try {
  46. if (!value) {
  47. setHasError(false);
  48. return setJson("{}");
  49. }
  50. const parsedJSON = JSON.stringify(JSON.parse(value), null, 2);
  51. setJson(parsedJSON);
  52. setHasError(false);
  53. } catch (jsonError: any) {
  54. setHasError(true);
  55. }
  56. }, 1200);
  57. return () => clearTimeout(formatTimer);
  58. }, [value, setJson, setHasError]);
  59. return (
  60. <StyledWrapper>
  61. <Editor
  62. height="100%"
  63. defaultLanguage="json"
  64. value={value}
  65. theme={lightmode}
  66. options={editorOptions}
  67. onChange={setValue}
  68. loading={<Loading message="Loading Editor..." />}
  69. />
  70. </StyledWrapper>
  71. );
  72. };