Skip to content

Commit

Permalink
feat(console): Add SandpackConsole component (#546)
Browse files Browse the repository at this point in the history
  • Loading branch information
danilowoz authored Aug 30, 2022
1 parent ebbf863 commit 9987ec5
Show file tree
Hide file tree
Showing 45 changed files with 1,435 additions and 181 deletions.
1 change: 1 addition & 0 deletions plugins/docusaurus/src/theme/CodeBlock/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ const RenderSandpack = (props) => {
: { [file]: children }
: undefined
}
options={{ showConsoleButton: true }}
template={template}
theme={theme}
/>
Expand Down
12 changes: 11 additions & 1 deletion sandpack-react/src/Playground.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
SandpackPreview,
SandpackLayout,
SandpackFileExplorer,
SandpackConsole,
} from "./";

export default {
Expand All @@ -19,7 +20,12 @@ export default {

export const Main = (): JSX.Element => {
const [config, setConfig] = useState({
Components: { Preview: true, Editor: true, FileExplorer: true },
Components: {
Preview: true,
Editor: true,
FileExplorer: true,
Console: true,
},
Options: {
showTabs: true,
showLineNumbers: true,
Expand All @@ -30,6 +36,7 @@ export const Main = (): JSX.Element => {
showReadOnly: true,
showNavigator: true,
showRefreshButton: true,
consoleShowHeader: true,
},
Template: "react" as const,
Theme: "auto",
Expand Down Expand Up @@ -142,6 +149,9 @@ export const Main = (): JSX.Element => {
showRefreshButton={config.Options?.showRefreshButton}
/>
)}
{config.Components.Console && (
<SandpackConsole showHeader={config.Options.consoleShowHeader} />
)}
</SandpackLayout>
</SandpackProvider>
</div>
Expand Down
27 changes: 11 additions & 16 deletions sandpack-react/src/common/Layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import * as React from "react";
import { useCombinedRefs } from "../components/CodeEditor/utils";
import { useSandpack } from "../hooks/useSandpack";
import { css, THEME_PREFIX } from "../styles";
import { absoluteClassName } from "../styles/shared";
import { classNames } from "../utils/classNames";

import { stackClassName } from ".";
Expand All @@ -24,21 +23,11 @@ export const layoutClassName = css({
display: "flex",
flexWrap: "wrap",
alignItems: "stretch",
background: "$colors$surface1",
borderRadius: "$border$radius",
overflow: "hidden",

"> *:not(:first-child)": {
borderLeft: "1px solid $colors$surface2",
borderTop: "1px solid $colors$surface2",
marginLeft: "-1px",
marginTop: "-1px",
position: "relative",
},

[`> *:first-child .${absoluteClassName}`]: {
borderRight: "1px solid $colors$surface2",
},
position: "relative",
backgroundColor: "$colors$surface2",
gap: 1,

[`> .${stackClassName}`]: {
flexGrow: 1,
Expand All @@ -54,10 +43,16 @@ export const layoutClassName = css({

"@media screen and (max-width: 768px)": {
height: "auto",
minWidth:
"100% !important;" /* triggers the layout break at the 768px breakpoint, not when the component is less then 700px */,

/* triggers the layout break at the 768px breakpoint, not when the component is less then 700px */
minWidth: "100% !important;",
},
},

[`> .${THEME_PREFIX}-file-explorer`]: {
flex: 0.2,
minWidth: 200,
},
});

/**
Expand Down
3 changes: 3 additions & 0 deletions sandpack-react/src/common/Stack.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ export const stackClassName = css({
flexDirection: "column",
width: "100%",
position: "relative",
backgroundColor: "$colors$surface1",
transition: "height $transitions$default",
gap: 1, // border between components
});

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import * as React from "react";

import * as mocks from "./languages-mocks";
import { SandpackProvider } from "../../contexts/sandpackContext";

import * as mocks from "./languages-mocks";

import { CodeEditor } from "./index";

export default {
Expand Down
5 changes: 5 additions & 0 deletions sandpack-react/src/components/CodeEditor/styles.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { css } from "../../styles";
import { buttonClassName } from "../../styles/shared";

import { styleTokens } from "./utils";

Expand Down Expand Up @@ -56,4 +57,8 @@ export const readOnlyClassName = css({
backgroundColor: "$colors$surface2",
borderRadius: "99999px",
padding: "calc($space$1 / 2) $space$2",

[`& + .${buttonClassName}`]: {
right: "calc($space$11 * 2)",
},
});
34 changes: 34 additions & 0 deletions sandpack-react/src/components/Console/Button.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { useClasser } from "@code-hike/classer";
import React from "react";

import { CleanIcon } from "../../icons";
import { css } from "../../styles";
import {
buttonClassName,
iconStandaloneClassName,
actionButtonClassName,
} from "../../styles/shared";
import { classNames } from "../../utils/classNames";

export const Button: React.FC<{ onClick: () => void }> = ({ onClick }) => {
const c = useClasser("sp");

return (
<button
className={classNames(
c("button", "icon-standalone"),
buttonClassName,
iconStandaloneClassName,
actionButtonClassName,
css({
position: "absolute",
bottom: "$space$2",
right: "$space$2",
})
)}
onClick={onClick}
>
<CleanIcon />
</button>
);
};
132 changes: 132 additions & 0 deletions sandpack-react/src/components/Console/Console.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
import React from "react";

import { SandpackCodeEditor, SandpackPreview } from "..";
import { SandpackProvider, SandpackLayout, Sandpack } from "../..";

import { SandpackConsole } from "./SandpackConsole";

export default {
title: "components/Console",
};

/* eslint-disable-next-line @typescript-eslint/no-explicit-any,@typescript-eslint/no-explicit-any */
const files = (full: boolean): any => ({
"/App.js": `export default function App() {
return (
<>
<p>Primitives</p>
<button onClick={() => console.log("Lorem ipsum")}>string</button>
<button onClick={() => console.log(123)}>number</button>
<button onClick={() => console.log(true)}>boolean</button>
<button onClick={() => console.log(undefined)}>undefined</button>
<button onClick={() => console.log(null)}>null</button>
${
full
? `<p>Others</p>
<button onClick={() => console.log(new Date())}>Date</button>
<button onClick={() => console.log(NaN)}>NaN</button>
<button onClick={() => console.log(new RegExp("//"))}>Regex</button>
<button onClick={() => console.log(new Error("Foo"))}>Error</button>
<button onClick={() => console.log(document.querySelector("button"))}>Log a node</button>
<button onClick={() => console.log(document.querySelectorAll("button"))}>Log nodes</button>
<button onClick={() => console.log(document.querySelector("body"))}>Log body</button>
<button onClick={() => console.log(()=>{}, function foo(){})}>Log function</button>
<button onClick={() => console.log(window)}>Log window</button>
<button onClick={() => console.log({ foo: [] })}>Log object</button>
<button onClick={() => console.log({foo: [], baz: () => {}})}>Log object II</button>
<button onClick={() => console.log(["foo", 123, [], ["foo2"], () => {}])}>Multiples types</button>
<button onClick={() => {
console.log("foo", "baz")
console.error("foo", "baz")
}}>
Multiples logs
</button>
<button onClick={() => console.error({ foo: [] })}>Log error</button>
<button onClick={() => console.warn({ foo: [] })}>Log warning</button>
<button onClick={() => console.info({ foo: [] })}>Log info</button>
<button onClick={() => console.clear()}>Console.clear</button>`
: ""
}
</>
);
}
`,
});

export const Main: React.FC = () => {
const [showHeader, setShowHeader] = React.useState(true);
const [showSyntaxErrors, setShowSyntaxErrors] = React.useState(true);

return (
<SandpackProvider files={files(true)} template="react">
<SandpackLayout>
<SandpackCodeEditor />
<SandpackPreview />
</SandpackLayout>

<SandpackLayout style={{ marginTop: 12 }}>
<SandpackConsole
showHeader={showHeader}
showSyntaxError={showSyntaxErrors}
/>
</SandpackLayout>

<br />

<label>
<input
checked={showHeader}
onChange={({ target }): void => setShowHeader(target.checked)}
type="checkbox"
/>
Show header
</label>

<label>
<input
checked={showSyntaxErrors}
onChange={({ target }): void => setShowSyntaxErrors(target.checked)}
type="checkbox"
/>
Show syntax errors
</label>
</SandpackProvider>
);
};

export const Preset: React.FC = () => {
return (
<div style={{ width: "auto" }}>
<Sandpack template="react" />

<br />

<Sandpack
files={files(false)}
options={{ showConsoleButton: true, showConsole: true }}
template="react"
/>

<br />

<Sandpack
files={files(false)}
options={{ showConsoleButton: false, showConsole: true }}
template="react"
/>

<br />

<Sandpack
files={files(false)}
options={{ showConsoleButton: true, showConsole: false }}
template="react"
/>
</div>
);
};
37 changes: 37 additions & 0 deletions sandpack-react/src/components/Console/Header.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import React from "react";

import { ConsoleIcon } from "../../icons";
import { css } from "../../styles";
import { classNames } from "../../utils/classNames";

export const Header: React.FC = () => {
return (
<div
className={classNames(
css({
borderBottom: "1px solid $colors$surface2",
padding: "$space$3 $space$2",
})
)}
>
<p
className={classNames(
css({
lineHeight: 1,
margin: 0,
color: "$colors$base",
fontSize: "$font$size",

display: "flex",
alignItems: "center",

gap: "$space$2",
})
)}
>
<ConsoleIcon />
Console
</p>
</div>
);
};
Loading

0 comments on commit 9987ec5

Please sign in to comment.