diff --git a/packages/next-sandbox/src/highlighted-json.tsx b/packages/next-sandbox/src/highlighted-json.tsx new file mode 100644 index 0000000..cc2674f --- /dev/null +++ b/packages/next-sandbox/src/highlighted-json.tsx @@ -0,0 +1,49 @@ +import React from 'react'; + +function syntaxHighlightReact(jsonStr: string) { + if (!jsonStr) return null; + + const regex = + /("(\\u[a-zA-Z0-9]{4}|\\[^u]|[^\\"])*"(\s*:)?|\b(true|false|null)\b|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?)/g; + let lastIndex = 0; + const tokens = []; + let match; + let key = 0; + + while ((match = regex.exec(jsonStr)) !== null) { + if (match.index > lastIndex) { + tokens.push(jsonStr.slice(lastIndex, match.index)); + } + const token = match[0]; + let cls = 'number'; + if (/^"/.test(token)) { + cls = /:$/.test(token) ? 'key' : 'string'; + } else if (/true|false/.test(token)) { + cls = 'boolean'; + } else if (/null/.test(token)) { + cls = 'null'; + } + tokens.push( + + {token} + , + ); + lastIndex = regex.lastIndex; + } + + if (lastIndex < jsonStr.length) { + tokens.push(jsonStr.slice(lastIndex)); + } + + return tokens; +} + +interface HighlightedJSONProps { + jsonStr: string; +} + +export default function HighlightedJSON({ jsonStr }: HighlightedJSONProps) { + const tokens = syntaxHighlightReact(jsonStr); + + return
{tokens}
; +} diff --git a/packages/next-sandbox/src/log-drawer.tsx b/packages/next-sandbox/src/log-drawer.tsx index 9a36876..032ae19 100644 --- a/packages/next-sandbox/src/log-drawer.tsx +++ b/packages/next-sandbox/src/log-drawer.tsx @@ -5,6 +5,7 @@ import React from 'react'; import { useSandbox } from './sandbox-context'; import LoaderIcon from './icons/loader-icon'; import PlayIcon from './icons/play-icon'; +import HighlightedJSON from './highlighted-json'; interface LogDrawerProps { open: boolean; @@ -56,12 +57,13 @@ export default function LogDrawer({ ) : ( [...currentRecords].reverse().map((record, idx) => (
-
-                        {record.output}
-                      
+ {record.status === 'success' ? ( + + ) : ( +
+                          {record.output}
+                        
+ )}

{new Date(record.timestamp).toLocaleTimeString() ?? diff --git a/packages/next-sandbox/src/style.css b/packages/next-sandbox/src/style.css index 8ccad0a..d3563a4 100644 --- a/packages/next-sandbox/src/style.css +++ b/packages/next-sandbox/src/style.css @@ -271,7 +271,23 @@ overflow-x: auto; } -.log-content[data-error-message='true'] { +.log-content .string { + color: var(--color-success); +} +.log-content .number { + color: darkorange; +} +.log-content .boolean { + color: var(--color-blue); +} +.log-content .null { + color: rgb(195, 120, 215); +} +.log-content .key { + color: var(--color-danger); +} + +.log-error { color: var(--color-danger); }