Skip to content

added code for sandpack console #4672

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 30 commits into from
Jun 10, 2022
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
6f53fe2
added code for sandpack console
harish-sethuraman May 22, 2022
8efd337
add log
harish-sethuraman May 22, 2022
d26bf0a
added console for older bundle
harish-sethuraman May 22, 2022
68afb83
Revert "[beta] Sandpack - new bundler (#4458)"
harish-sethuraman May 22, 2022
e9c61b8
adds proper console and removes new bundle
harish-sethuraman May 22, 2022
f992e96
modify styles
harish-sethuraman May 22, 2022
8ab57d8
remove unwanted code
harish-sethuraman May 22, 2022
63a812a
nit
harish-sethuraman May 22, 2022
66eeacb
fix types (#4677)
danilowoz May 24, 2022
878755c
update console
harish-sethuraman May 24, 2022
894325c
Merge branch 'main' into try-sandpack-console
gaearon May 24, 2022
877b36a
little nits
harish-sethuraman May 25, 2022
6d2f067
remove unwanted code changes
harish-sethuraman May 25, 2022
abee2a6
update bundler URL
harish-sethuraman May 31, 2022
0f75b8e
use `message.firstLoad` for clearing console
harish-sethuraman Jun 1, 2022
f2a5fd9
use `refresh` event to clear logs as well (used when going away and c…
harish-sethuraman Jun 1, 2022
da01af3
remove padding for code blocks inside console
harish-sethuraman Jun 3, 2022
038b353
Merge branch 'main' into try-sandpack-console
harish-sethuraman Jun 3, 2022
6fbd737
small UI revamps
harish-sethuraman Jun 6, 2022
094b646
change p to div since the sandpack comes inside the p, add try catch …
harish-sethuraman Jun 6, 2022
a8fa116
tweaks
gaearon Jun 10, 2022
05db819
Fixes
gaearon Jun 10, 2022
dbf4b33
Merge branch 'main' into try-sandpack-console
gaearon Jun 10, 2022
48a0667
Reset unrelated changes
gaearon Jun 10, 2022
1a98616
tweaks
gaearon Jun 10, 2022
086b30b
fix
gaearon Jun 10, 2022
a1fc684
fixes
gaearon Jun 10, 2022
0344610
oops
gaearon Jun 10, 2022
eaa0a10
Fix
gaearon Jun 10, 2022
665e455
fix
gaearon Jun 10, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .nvmrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
12.22.0
12.16.1
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
diff --git a/node_modules/@codesandbox/sandpack-client/dist/types/types.d.ts b/node_modules/@codesandbox/sandpack-client/dist/types/types.d.ts
index a18cc43..8b85844 100644
--- a/node_modules/@codesandbox/sandpack-client/dist/types/types.d.ts
+++ b/node_modules/@codesandbox/sandpack-client/dist/types/types.d.ts
@@ -88,6 +88,7 @@ export interface SandpackErrorMessage {
export interface BaseSandpackMessage {
type: string;
$id?: number;
+ status?: ClientStatus
codesandbox?: boolean;
}
export declare type SandpackMessage = BaseSandpackMessage & ({
@@ -152,4 +153,22 @@ export declare type SandpackMessage = BaseSandpackMessage & ({
} | {
type: "activate-react-devtools";
uid?: string;
+} | {
+ type: "console",
+ log: Array<
+ {
+ method: 'log'
+ | 'debug'
+ | 'info'
+ | 'warn'
+ | 'error'
+ | 'table'
+ | 'clear'
+ | 'time'
+ | 'timeEnd'
+ | 'count'
+ | 'assert',
+ id: string,
+ data: string[]
+ }>,
});
145 changes: 145 additions & 0 deletions beta/src/components/MDX/Sandpack/Console.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
import cn from 'classnames';
import * as React from 'react';
import {IconChevron} from 'components/Icon/IconChevron';

import {SandpackCodeViewer, useSandpack} from '@codesandbox/sandpack-react';

const getType = (message: Methods): '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: Methods;
}>;

type Methods =
| 'log'
| 'debug'
| 'info'
| 'warn'
| 'error'
| 'table'
| 'clear'
| 'time'
| 'timeEnd'
| 'count'
| 'assert';

const MAX_MESSAGE_COUNT = 100;

export const SandpackConsole: React.FC<{clientId?: string}> = ({clientId}) => {
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') {
setLogs([]);
}
// there is no such type as console in Sandpack
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;
});
}
});

return unsubscribe;
}, [listen]);

const [showConsole, toggleConsole] = React.useState(false);

React.useEffect(() => {
if (wrapperRef.current) {
wrapperRef.current.scrollTop = wrapperRef.current.scrollHeight;
}
}, [logs]);

return (
<div
className={cn(
'absolute dark:border-gray-700 dark:bg-gray-95 border-t bottom-0 w-full',
!!!logs.length && 'cursor-not-allowed'
)}>
<div className="flex justify-between h-8 items-center">
<div onClick={() => !!logs.length && toggleConsole(!showConsole)}>
<IconChevron displayDirection={showConsole ? 'down' : 'right'} />
</div>
<p className="p-1 text-md">console ({logs.length})</p>
<button
className={cn('p-1', !!!logs.length && 'cursor-not-allowed')}
onClick={() => {
setLogs([]);
toggleConsole(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>
{showConsole && (
<div className="w-full h-full border-y dark:border-gray-700 dark:bg-gray-95 dark:text-white">
<div className={cn('console-scroll')} ref={wrapperRef}>
{logs.map(({data, id, method}) => {
return (
<p
key={id}
className={cn(
'border-y border dark:border-gray-700 text-md p-1 pl-2',
`console-${getType(method)}`
)}>
<span className={cn('console-message')}>
{data.map((msg, index) => {
if (typeof msg === 'string') {
return <span key={`${msg}-${index}`}>{msg}</span>;
}

console.log('console', console);

const children = JSON.stringify(msg);

return (
<span
className={cn('console-span')}
key={`${msg}-${index}`}>
<SandpackCodeViewer
initMode="user-visible"
// fileType="js"
code={children}
/>
</span>
);
})}
</span>
</p>
);
})}
</div>
</div>
)}
</div>
);
};
16 changes: 11 additions & 5 deletions beta/src/components/MDX/Sandpack/CustomPreset.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
SandpackThemeProvider,
SandpackReactDevTools,
} from '@codesandbox/sandpack-react';
import {SandpackConsole} from './Console';
import scrollIntoView from 'scroll-into-view-if-needed';
import cn from 'classnames';

Expand All @@ -23,10 +24,12 @@ import {useSandpackLint} from './utils';
export function CustomPreset({
isSingleFile,
showDevTools,
showConsole,
onDevToolsLoad,
devToolsLoaded,
}: {
isSingleFile: boolean;
showConsole: boolean;
showDevTools: boolean;
devToolsLoaded: boolean;
onDevToolsLoad: () => void;
Expand Down Expand Up @@ -66,11 +69,14 @@ export function CustomPreset({
showRunButton={false}
extensions={[onLint]}
/>
<Preview
className="order-last xl:order-2"
isExpanded={isExpanded}
lintErrors={lintErrors}
/>
<div className="sp-stack h-full">
<Preview
className="h-full"
isExpanded={isExpanded}
lintErrors={lintErrors}
/>
{showConsole && <SandpackConsole />}
</div>
{isExpandable && (
<button
translate="yes"
Expand Down
15 changes: 10 additions & 5 deletions beta/src/components/MDX/Sandpack/SandpackRoot.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

import * as React from 'react';
import {SandpackProvider} from '@codesandbox/sandpack-react';
import {SandpackLogLevel} from '@codesandbox/sandpack-client';
import {CustomPreset} from './CustomPreset';
import {createFileMap} from './utils';

Expand All @@ -15,6 +14,7 @@ type SandpackProps = {
autorun?: boolean;
setup?: SandpackSetup;
showDevTools?: boolean;
showConsole?: boolean;
};

const sandboxStyle = `
Expand Down Expand Up @@ -64,7 +64,13 @@ ul {
`.trim();

function SandpackRoot(props: SandpackProps) {
let {children, setup, autorun = true, showDevTools = false} = props;
let {
children,
setup,
autorun = true,
showDevTools = false,
showConsole = true,
} = props;
const [devToolsLoaded, setDevToolsLoaded] = React.useState(false);
let codeSnippets = React.Children.toArray(children) as React.ReactElement[];
let isSingleFile = true;
Expand All @@ -83,12 +89,11 @@ function SandpackRoot(props: SandpackProps) {
customSetup={{...setup, files: files}}
autorun={autorun}
initMode="user-visible"
initModeObserverOptions={{rootMargin: '1400px 0px'}}
bundlerURL="https://22530bfe.sandpack-bundler.pages.dev"
logLevel={SandpackLogLevel.None}>
initModeObserverOptions={{rootMargin: '1400px 0px'}}>
<CustomPreset
isSingleFile={isSingleFile}
showDevTools={showDevTools}
showConsole={showConsole}
onDevToolsLoad={() => setDevToolsLoaded(true)}
devToolsLoaded={devToolsLoaded}
/>
Expand Down
100 changes: 100 additions & 0 deletions beta/src/pages/apis/usecontext.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,104 @@
---
title: useContext
---
<Sandpack>


```js
console.log('strek')

import { createContext, useContext, useState } from 'react';

const ThemeContext = createContext(null);

export default function MyApp() {
const [theme, setTheme] = useState('light');
return (
<ThemeContext.Provider value={theme}>
<Form />
<label>
<input
type="checkbox"
checked={theme === 'dark'}
onChange={(e) => {
setTheme(e.target.checked ? 'dark' : 'light')
}}
/>
Use dark mode
</label>
</ThemeContext.Provider>
)
}

function Form({ children }) {
return (
<Panel title="Welcome">
<Button>Sign up</Button>
<Button>Log in</Button>
</Panel>
);
}

function Panel({ title, children }) {
const theme = useContext(ThemeContext);
const className = 'panel-' + theme;
return (
<section className={className}>
<h1>{title}</h1>
{children}
</section>
)
}

function Button({ children }) {
const theme = useContext(ThemeContext);
const className = 'button-' + theme;
return (
<button className={className}>
{children}
</button>
);
}
```

```css
.panel-light,
.panel-dark {
border: 1px solid black;
border-radius: 4px;
padding: 20px;
margin-bottom: 10px;
}
.panel-light {
color: #222;
background: #fff;
}

.panel-dark {
color: #fff;
background: rgb(23, 32, 42);
}

.button-light,
.button-dark {
border: 1px solid #777;
padding: 5px;
margin-right: 10px;
margin-top: 10px;
}

.button-dark {
background: #222;
color: #fff;
}

.button-light {
background: #fff;
color: #222;
}
```

</Sandpack>
<Intro>

`useContext` is a React Hook that lets you read and subscribe to [context](/learn/passing-data-deeply-with-context) from your component.
Expand Down Expand Up @@ -183,7 +280,10 @@ In this example, the `MyApp` component holds a state variable which is then pass

<Sandpack>


```js
console.log('strek')

import { createContext, useContext, useState } from 'react';

const ThemeContext = createContext(null);
Expand Down
Loading