diff --git a/src/containers/JsonEditor/ErrorContainer.tsx b/src/containers/JsonEditor/ErrorContainer.tsx new file mode 100644 index 0000000..adbead1 --- /dev/null +++ b/src/containers/JsonEditor/ErrorContainer.tsx @@ -0,0 +1,79 @@ +import React from "react"; +import styled from "styled-components"; +import { + MdExpandMore, + MdExpandLess, + MdReportGmailerrorred, +} from "react-icons/md"; + +export type Error = { + message: string; + isExpanded: boolean; +}; + +interface ErrorContainerProps { + error: Error; + setError: React.Dispatch>; +} + +const StyledErrorWrapper = styled.div``; + +const StyledErrorHeader = styled.a` + display: flex; + justify-content: space-between; + align-items: center; + background: ${({ theme }) => theme.BLACK_DARK}; + padding: 6px 12px; + color: ${({ theme }) => theme.DANGER}; + font-size: 22px; + cursor: pointer; + + &:hover { + color: ${({ theme }) => theme.DANGER}; + } +`; + +const StyledTitle = styled.span` + display: flex; + justify-content: center; + align-items: center; + font-weight: 600; + gap: 10px; +`; + +const StyledError = styled.pre` + color: ${({ theme }) => theme.DANGER}; + border: 1px solid ${({ theme }) => theme.SILVER_DARK}; + border-left: none; + border-right: none; + font-size: 12px; + padding: 12px; + margin: 0; + word-wrap: break-word; + white-space: pre-line; +`; + +export const ErrorContainer: React.FC = ({ + error, + setError, +}) => { + return ( + + + setError((err: Error) => ({ ...err, isExpanded: !err.isExpanded })) + } + > + + Error + + {error.isExpanded ? ( + + ) : ( + + )} + + {error.isExpanded && {error.message}} + + ); +}; diff --git a/src/containers/JsonEditor/index.tsx b/src/containers/JsonEditor/index.tsx index 22f47e1..21a97f0 100644 --- a/src/containers/JsonEditor/index.tsx +++ b/src/containers/JsonEditor/index.tsx @@ -6,11 +6,7 @@ import { useLocalStorage } from "usehooks-ts"; import { defaultConfig } from "src/constants/data"; import parseJson from "parse-json"; import styled from "styled-components"; -import { - MdExpandMore, - MdExpandLess, - MdReportGmailerrorred, -} from "react-icons/md"; +import { Error, ErrorContainer } from "./ErrorContainer"; const StyledEditorWrapper = styled.div` display: flex; @@ -20,43 +16,6 @@ const StyledEditorWrapper = styled.div` user-select: none; `; -const StyledErrorWrapper = styled.div``; - -const StyledErrorHeader = styled.a` - display: flex; - justify-content: space-between; - align-items: center; - background: ${({ theme }) => theme.BLACK_DARK}; - padding: 6px 12px; - color: ${({ theme }) => theme.DANGER}; - font-size: 22px; - cursor: pointer; - - &:hover { - color: ${({ theme }) => theme.DANGER}; - } -`; - -const StyledTitle = styled.span` - display: flex; - justify-content: center; - align-items: center; - font-weight: 600; - gap: 10px; -`; - -const StyledError = styled.pre` - color: ${({ theme }) => theme.DANGER}; - border: 1px solid ${({ theme }) => theme.SILVER_DARK}; - border-left: none; - border-right: none; - font-size: 12px; - padding: 12px; - margin: 0; - word-wrap: break-word; - white-space: pre-line; -`; - const AceEditor: ComponentType = dynamic( async () => { const Ace = require("react-ace").default; @@ -69,6 +28,34 @@ const AceEditor: ComponentType = dynamic( } ); +function isJson( + value: string, + setState: React.Dispatch> +) { + value = typeof value !== "string" ? JSON.stringify(value) : value; + + try { + value = parseJson(value); + setState((err) => ({ + ...err, + message: "", + })); + } catch (e: any) { + setState((err) => ({ + ...err, + message: e.message, + })); + + return false; + } + + if (typeof value === "object" && value !== null) { + return true; + } + + return false; +} + const JsonEditor: React.FC<{ json: string; setJson: React.Dispatch>; @@ -84,31 +71,6 @@ const JsonEditor: React.FC<{ JSON.stringify(JSON.parse(json), null, 2) ); - function isJson(value: string) { - value = typeof value !== "string" ? JSON.stringify(value) : value; - - try { - value = parseJson(value); - setError((err) => ({ - ...err, - message: "", - })); - } catch (e: any) { - setError((err) => ({ - ...err, - message: e.message, - })); - - return false; - } - - if (typeof value === "object" && value !== null) { - return true; - } - - return false; - } - React.useEffect(() => { const resizeObserver = new ResizeObserver((observed) => { const width = observed[0].contentRect.width; @@ -133,7 +95,7 @@ const JsonEditor: React.FC<{ React.useEffect(() => { const formatTimer = setTimeout(() => { - if (!isJson(value)) return; + if (!isJson(value, setError)) return; if (config.autoformat) { setValue(JSON.stringify(JSON.parse(value), null, 2)); @@ -149,26 +111,7 @@ const JsonEditor: React.FC<{ return ( - {error.message && ( - - - setError((err) => ({ ...err, isExpanded: !err.isExpanded })) - } - > - - Error - - {error.isExpanded ? ( - - ) : ( - - )} - - {error.isExpanded && {error.message}} - - )} - + {error.message && } >; }> = ({ json }) => { const pageLoaded = useLoading(); - const canvasRef = React.useRef(null); const wrapperRef = React.useRef(null); const [config] = useLocalStorage("config", defaultConfig); + const { nodes, edges } = getEdgeNodes(json, config.expand); + React.useEffect(() => { if (wrapperRef.current) wrapperRef.current?.resetTransform(); }, [json, wrapperRef]); - const { nodes, edges } = getEdgeNodes(json, config.expand); - const zoomIn = (scale: number) => { if ( wrapperRef.current?.state.scale && diff --git a/src/pages/editor/index.tsx b/src/pages/editor/index.tsx index 58f09aa..9c8e0e6 100644 --- a/src/pages/editor/index.tsx +++ b/src/pages/editor/index.tsx @@ -129,7 +129,6 @@ const Editor: React.FC = () => { React.useEffect(() => { const jsonStored = localStorage.getItem("json"); - if (jsonStored) setJson(jsonStored); }, []);