-
Notifications
You must be signed in to change notification settings - Fork 7.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Beta] Add console to sandboxes (#4672)
* added code for sandpack console * add log * added console for older bundle * Revert "[beta] Sandpack - new bundler (#4458)" This reverts commit 3ab1245. * adds proper console and removes new bundle * modify styles * remove unwanted code * nit * fix types (#4677) * update console * little nits * remove unwanted code changes * update bundler URL * use `message.firstLoad` for clearing console * use `refresh` event to clear logs as well (used when going away and coming back to sandpack) * remove padding for code blocks inside console * small UI revamps * change p to div since the sandpack comes inside the p, add try catch and a try catch for the catch again * tweaks * Fixes * Reset unrelated changes * tweaks * fix * fixes * oops * Fix * fix Co-authored-by: Danilo Woznica <danilowoz@gmail.com> Co-authored-by: Dan Abramov <dan.abramov@gmail.com>
- Loading branch information
1 parent
e4d807d
commit 6d96542
Showing
3 changed files
with
163 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,154 @@ | ||
/* | ||
* Copyright (c) Facebook, Inc. and its affiliates. | ||
*/ | ||
import cn from 'classnames'; | ||
import * as React from 'react'; | ||
import {IconChevron} from 'components/Icon/IconChevron'; | ||
|
||
import {SandpackCodeViewer, useSandpack} from '@codesandbox/sandpack-react'; | ||
import type {SandpackMessageConsoleMethods} from '@codesandbox/sandpack-client'; | ||
|
||
const getType = ( | ||
message: SandpackMessageConsoleMethods | ||
): 'info' | 'warning' | 'error' => { | ||
if (message === 'log' || message === 'info') { | ||
return 'info'; | ||
} | ||
|
||
if (message === 'warn') { | ||
return 'warning'; | ||
} | ||
|
||
return 'error'; | ||
}; | ||
|
||
type ConsoleData = Array<{ | ||
data: Array<string | Record<string, string>>; | ||
id: string; | ||
method: SandpackMessageConsoleMethods; | ||
}>; | ||
|
||
const MAX_MESSAGE_COUNT = 100; | ||
|
||
export const SandpackConsole = () => { | ||
const {listen} = useSandpack(); | ||
const [logs, setLogs] = React.useState<ConsoleData>([]); | ||
const wrapperRef = React.useRef<HTMLDivElement>(null); | ||
|
||
React.useEffect(() => { | ||
const unsubscribe = listen((message) => { | ||
if ( | ||
(message.type === 'start' && message.firstLoad) || | ||
message.type === 'refresh' | ||
) { | ||
setLogs([]); | ||
} | ||
if (message.type === 'console' && message.codesandbox) { | ||
setLogs((prev) => { | ||
const messages = [...prev, ...message.log]; | ||
messages.slice(Math.max(0, messages.length - MAX_MESSAGE_COUNT)); | ||
|
||
return messages.filter(({method}) => method === 'log'); | ||
}); | ||
} | ||
}); | ||
|
||
return unsubscribe; | ||
}, [listen]); | ||
|
||
const [isExpanded, setIsExpanded] = React.useState(false); | ||
|
||
React.useEffect(() => { | ||
if (wrapperRef.current) { | ||
wrapperRef.current.scrollTop = wrapperRef.current.scrollHeight; | ||
} | ||
}, [logs]); | ||
|
||
if (logs.length === 0) { | ||
return null; | ||
} | ||
|
||
return ( | ||
<div className="absolute dark:border-gray-700 bg-white dark:bg-gray-95 border-t bottom-0 w-full dark:text-white"> | ||
<div className="flex justify-between"> | ||
<button | ||
className="flex items-center p-1" | ||
onClick={() => setIsExpanded(!isExpanded)}> | ||
<IconChevron displayDirection={isExpanded ? 'down' : 'right'} /> | ||
<span className="pl-1 text-sm">Console ({logs.length})</span> | ||
</button> | ||
<button | ||
className="p-1" | ||
onClick={() => { | ||
setLogs([]); | ||
setIsExpanded(false); | ||
}}> | ||
<svg | ||
viewBox="0 0 24 24" | ||
width="18" | ||
height="18" | ||
stroke="currentColor" | ||
strokeWidth="2" | ||
fill="none" | ||
strokeLinecap="round" | ||
strokeLinejoin="round"> | ||
<circle cx="12" cy="12" r="10"></circle> | ||
<line x1="4.93" y1="4.93" x2="19.07" y2="19.07"></line> | ||
</svg> | ||
</button> | ||
</div> | ||
{isExpanded && ( | ||
<div className="w-full h-full border-y bg-white dark:border-gray-700 dark:bg-gray-95 min-h-[28px] console"> | ||
<div className="max-h-52 h-auto overflow-auto" ref={wrapperRef}> | ||
{logs.map(({data, id, method}) => { | ||
return ( | ||
<div | ||
key={id} | ||
className={cn( | ||
'last:border-none border-b dark:border-gray-700 text-md p-1 pl-2 leading-6 font-mono', | ||
`console-${getType(method)}` | ||
)}> | ||
<span className={cn('console-message')}> | ||
{data.map((msg, index) => { | ||
if (typeof msg === 'string') { | ||
return <span key={`${msg}-${index}`}>{msg}</span>; | ||
} | ||
|
||
let children; | ||
if (msg != null && typeof msg['@t'] === 'string') { | ||
// CodeSandbox wraps custom types | ||
children = msg['@t']; | ||
} else { | ||
try { | ||
children = JSON.stringify(msg, null, 2); | ||
} catch (error) { | ||
try { | ||
children = Object.prototype.toString.call(msg); | ||
} catch (err) { | ||
children = '[' + typeof msg + ']'; | ||
} | ||
} | ||
} | ||
|
||
return ( | ||
<span | ||
className={cn('console-span')} | ||
key={`${msg}-${index}`}> | ||
<SandpackCodeViewer | ||
initMode="user-visible" | ||
// fileType="js" | ||
code={children} | ||
/> | ||
</span> | ||
); | ||
})} | ||
</span> | ||
</div> | ||
); | ||
})} | ||
</div> | ||
</div> | ||
)} | ||
</div> | ||
); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters