Changing styles of Playground

This commit is contained in:
Ozzie Gooen 2022-04-14 20:16:15 -04:00
parent 478bbf5740
commit e7d5fb4ad8
8 changed files with 152 additions and 95 deletions

View File

@ -3,6 +3,7 @@
"version": "0.1.8", "version": "0.1.8",
"dependencies": { "dependencies": {
"@quri/squiggle-lang": "0.2.2", "@quri/squiggle-lang": "0.2.2",
"@react-hook/size": "^2.1.2",
"@testing-library/jest-dom": "^5.16.4", "@testing-library/jest-dom": "^5.16.4",
"@testing-library/react": "^13.0.1", "@testing-library/react": "^13.0.1",
"@testing-library/user-event": "^14.0.4", "@testing-library/user-event": "^14.0.4",
@ -11,6 +12,7 @@
"@types/node": "^17.0.23", "@types/node": "^17.0.23",
"@types/react": "^18.0.3", "@types/react": "^18.0.3",
"@types/react-dom": "^18.0.0", "@types/react-dom": "^18.0.0",
"@types/styled-components": "^5.1.25",
"antd": "^4.19.3", "antd": "^4.19.3",
"cross-env": "^7.0.3", "cross-env": "^7.0.3",
"lodash": "^4.17.21", "lodash": "^4.17.21",

View File

@ -10,12 +10,16 @@ interface CodeEditorProps {
onChange: (value: string) => void; onChange: (value: string) => void;
oneLine?: boolean; oneLine?: boolean;
width?: number; width?: number;
height: number;
showGutter?: boolean;
} }
export let CodeEditor: FC<CodeEditorProps> = ({ export let CodeEditor: FC<CodeEditorProps> = ({
value, value,
onChange, onChange,
oneLine = false, oneLine = false,
showGutter = false,
height,
}: CodeEditorProps) => { }: CodeEditorProps) => {
let lineCount = value.split("\n").length; let lineCount = value.split("\n").length;
let id = _.uniqueId(); let id = _.uniqueId();
@ -25,9 +29,10 @@ export let CodeEditor: FC<CodeEditorProps> = ({
mode="golang" mode="golang"
theme="github" theme="github"
width={"100%"} width={"100%"}
minLines={oneLine ? lineCount : 15} height={String(height) + "px"}
maxLines={oneLine ? lineCount : 15} minLines={oneLine ? lineCount : undefined}
showGutter={false} maxLines={oneLine ? lineCount : undefined}
showGutter={showGutter}
highlightActiveLine={false} highlightActiveLine={false}
showPrintMargin={false} showPrintMargin={false}
onChange={onChange} onChange={onChange}

View File

@ -27,7 +27,7 @@ export const DistributionChart: React.FC<DistributionChartProps> = ({
return ( return (
<SquiggleVegaChart <SquiggleVegaChart
data={{ con: shape.value.continuous, dis: shape.value.discrete }} data={{ con: shape.value.continuous, dis: shape.value.discrete }}
width={width} width={width - 20}
height={height} height={height}
actions={false} actions={false}
/> />

View File

@ -10,6 +10,7 @@ import type { samplingParams, exportEnv } from "@quri/squiggle-lang";
import { NumberShower } from "./NumberShower"; import { NumberShower } from "./NumberShower";
import { DistributionChart } from "./DistributionChart"; import { DistributionChart } from "./DistributionChart";
import { ErrorBox } from "./ErrorBox"; import { ErrorBox } from "./ErrorBox";
import useSize from "@react-hook/size";
export interface SquiggleChartProps { export interface SquiggleChartProps {
/** The input string for squiggle */ /** The input string for squiggle */
@ -43,12 +44,17 @@ export interface SquiggleItemProps {
} }
const ShowBox = styled.div` const ShowBox = styled.div`
border: 1px solid #ddd; background: white;
border: 1px solid #eee;
border-radius: 2px;
margin-bottom: 0.4em;
`; `;
const ShowBoxHeading = styled.div` const ShowBoxHeading = styled.div`
border-bottom: 1px solid #ddd; border-bottom: 1px solid #eee;
padding: 0.4em 0.8em; padding-left: 0.8em;
padding-right: 0.8em;
padding-top: 0.1em;
`; `;
const ShowBoxPadding = styled.div` const ShowBoxPadding = styled.div`
@ -83,7 +89,14 @@ const SquiggleItem: React.FC<SquiggleItemProps> = ({
} else if (expression.tag === "distribution") { } else if (expression.tag === "distribution") {
let distType = expression.value.type(); let distType = expression.value.type();
return ( return (
<Box heading={`Distribution (${distType}${distType === "Symbolic" ? ": " + expression.value.toString() : ""})`}> <Box heading={`Distribution (${distType})`}>
{distType === "Symbolic" ? (
<>
<div>{expression.value.toString()}</div>
</>
) : (
<></>
)}
<DistributionChart <DistributionChart
distribution={expression.value} distribution={expression.value}
height={height} height={height}
@ -92,7 +105,7 @@ const SquiggleItem: React.FC<SquiggleItemProps> = ({
</Box> </Box>
); );
} else if (expression.tag === "string") { } else if (expression.tag === "string") {
return <Box heading="String">({expression.value})</Box>; return <Box heading="String">{`"${expression.value}"`}</Box>;
} else if (expression.tag === "boolean") { } else if (expression.tag === "boolean") {
return ( return (
<Box heading="Boolean"> <Box heading="Boolean">
@ -128,27 +141,33 @@ export const SquiggleChart: React.FC<SquiggleChartProps> = ({
outputXYPoints = 1000, outputXYPoints = 1000,
environment = [], environment = [],
onEnvChange = () => {}, onEnvChange = () => {},
width = 500,
height = 60, height = 60,
}: SquiggleChartProps) => { }: SquiggleChartProps) => {
const target = React.useRef(null);
const [width] = useSize(target);
let samplingInputs: samplingParams = { let samplingInputs: samplingParams = {
sampleCount: sampleCount, sampleCount: sampleCount,
xyPointLength: outputXYPoints, xyPointLength: outputXYPoints,
}; };
let expressionResult = run(squiggleString, samplingInputs, environment); let expressionResult = run(squiggleString, samplingInputs, environment);
let internal = <></>;
if (expressionResult.tag === "Ok") { if (expressionResult.tag === "Ok") {
onEnvChange(environment); onEnvChange(environment);
let expression = expressionResult.value; let expression = expressionResult.value;
return ( internal = (
<SquiggleItem expression={expression} width={width} height={height} /> <SquiggleItem
expression={expression}
width={width - 20}
height={height}
/>
); );
} else { } else {
// At this point, we came across an error. What was our error? // At this point, we came across an error. What was our error?
return ( internal = (
<ErrorBox heading={"Parse Error"}> <ErrorBox heading={"Parse Error"}>
{errorValueToString(expressionResult.value)} {errorValueToString(expressionResult.value)}
</ErrorBox> </ErrorBox>
); );
} }
return <div ref={target}>{internal}</div>;
}; };

View File

@ -55,6 +55,8 @@ export let SquiggleEditor: React.FC<SquiggleEditorProps> = ({
value={expression} value={expression}
onChange={setExpression} onChange={setExpression}
oneLine={true} oneLine={true}
showGutter={false}
height={20}
/> />
</Input> </Input>
<SquiggleChart <SquiggleChart

View File

@ -3,7 +3,8 @@ import React, { FC, useState } from "react";
import ReactDOM from "react-dom"; import ReactDOM from "react-dom";
import { SquiggleChart } from "./SquiggleChart"; import { SquiggleChart } from "./SquiggleChart";
import CodeEditor from "./CodeEditor"; import CodeEditor from "./CodeEditor";
import { Form, Input, Card, Row, Col } from "antd"; import { Form, Input, Row, Col } from "antd";
import styled from "styled-components";
import "antd/dist/antd.css"; import "antd/dist/antd.css";
interface FieldFloatProps { interface FieldFloatProps {
@ -34,9 +35,38 @@ function FieldFloat(Props: FieldFloatProps) {
interface Props { interface Props {
initialSquiggleString?: string; initialSquiggleString?: string;
height?: number;
} }
let SquigglePlayground: FC<Props> = ({ initialSquiggleString = "" }: Props) => { interface Props2 {
height: number;
}
const ShowBox = styled.div<Props2>`
border: 1px solid #eee;
border-radius: 2px;
height: ${props => props.height};
`;
const MyComponent = styled.div`
color: ${props => props.theme.colors.main};
`;
interface TitleProps {
readonly maxHeight: number;
}
const Display = styled.div<TitleProps>`
background: #f6f6f6;
border-left: 1px solid #eee;
height: 100vh;
padding: 3px;
overflow-y: auto;
max-height: ${props => props.maxHeight}px;
`;
let SquigglePlayground: FC<Props> = ({ initialSquiggleString = "", height = 300 }: Props) => {
let [squiggleString, setSquiggleString] = useState(initialSquiggleString); let [squiggleString, setSquiggleString] = useState(initialSquiggleString);
let [sampleCount, setSampleCount] = useState(1000); let [sampleCount, setSampleCount] = useState(1000);
let [outputXYPoints, setOutputXYPoints] = useState(1000); let [outputXYPoints, setOutputXYPoints] = useState(1000);
@ -44,81 +74,34 @@ let SquigglePlayground: FC<Props> = ({ initialSquiggleString = "" }: Props) => {
let [diagramStart, setDiagramStart] = useState(0); let [diagramStart, setDiagramStart] = useState(0);
let [diagramStop, setDiagramStop] = useState(10); let [diagramStop, setDiagramStop] = useState(10);
let [diagramCount, setDiagramCount] = useState(20); let [diagramCount, setDiagramCount] = useState(20);
var demoDist = (
<SquiggleChart
squiggleString={squiggleString}
sampleCount={sampleCount}
outputXYPoints={outputXYPoints}
diagramStart={diagramStart}
diagramStop={diagramStop}
diagramCount={diagramCount}
pointDistLength={pointDistLength}
height={150}
/>
);
return ( return (
<Row> <ShowBox height={height}>
<Col span={12}> <Row>
<Card title="Distribution Form"> <Col span={12}>
<Form> <CodeEditor
<Row gutter={16}> value={squiggleString}
<Col span={24}> onChange={setSquiggleString}
<CodeEditor oneLine={false}
value={squiggleString} showGutter={true}
onChange={setSquiggleString} height={height - 3}
oneLine={false} />
/> </Col>
</Col> <Col span={12}>
</Row> <Display maxHeight={height-3}>
<Row gutter={16}> <SquiggleChart
<Col span={12}> squiggleString={squiggleString}
<FieldFloat sampleCount={sampleCount}
value={sampleCount} outputXYPoints={outputXYPoints}
label="Sample Count" diagramStart={diagramStart}
onChange={setSampleCount} diagramStop={diagramStop}
/> diagramCount={diagramCount}
</Col> pointDistLength={pointDistLength}
<Col span={12}> height={150}
<FieldFloat />
value={outputXYPoints} </Display>
onChange={setOutputXYPoints} </Col>
label="Output XY-points" </Row>
/> </ShowBox>
</Col>
<Col span={12}>
<FieldFloat
value={pointDistLength}
onChange={setPointDistLength}
label="Downsample To"
/>
</Col>
<Col span={12}>
<FieldFloat
value={diagramStart}
onChange={setDiagramStart}
label="Diagram Start"
/>
</Col>
<Col span={12}>
<FieldFloat
value={diagramStop}
onChange={setDiagramStop}
label="Diagram Stop"
/>
</Col>
<Col span={12}>
<FieldFloat
value={diagramCount}
onChange={setDiagramCount}
label="Diagram Count"
/>
</Col>
</Row>
</Form>
</Card>
</Col>
<Col span={12}>{demoDist}</Col>
</Row>
); );
}; };
export default SquigglePlayground; export default SquigglePlayground;

View File

@ -1,5 +1,6 @@
import SquigglePlayground from "../components/SquigglePlayground"; import SquigglePlayground from "../components/SquigglePlayground";
import { Canvas, Meta, Story, Props } from "@storybook/addon-docs"; import { Canvas, Meta, Story, Props } from "@storybook/addon-docs";
import styled from "styled-components";
<Meta title="Squiggle/SquigglePlayground" component={SquigglePlayground} /> <Meta title="Squiggle/SquigglePlayground" component={SquigglePlayground} />
@ -15,6 +16,7 @@ including sampling settings, in squiggle.
name="Normal" name="Normal"
args={{ args={{
initialSquiggleString: "normal(5,2)", initialSquiggleString: "normal(5,2)",
height: 500,
}} }}
> >
{Template.bind({})} {Template.bind({})}

View File

@ -2197,6 +2197,11 @@
"@jridgewell/resolve-uri" "^3.0.3" "@jridgewell/resolve-uri" "^3.0.3"
"@jridgewell/sourcemap-codec" "^1.4.10" "@jridgewell/sourcemap-codec" "^1.4.10"
"@juggle/resize-observer@^3.3.1":
version "3.3.1"
resolved "https://registry.yarnpkg.com/@juggle/resize-observer/-/resize-observer-3.3.1.tgz#b50a781709c81e10701004214340f25475a171a0"
integrity sha512-zMM9Ds+SawiUkakS7y94Ymqx+S0ORzpG3frZirN3l+UlXUmSUR7hF4wxCVqW+ei94JzV5kt0uXBcoOEAuiydrw==
"@leichtgewicht/ip-codec@^2.0.1": "@leichtgewicht/ip-codec@^2.0.1":
version "2.0.3" version "2.0.3"
resolved "https://registry.yarnpkg.com/@leichtgewicht/ip-codec/-/ip-codec-2.0.3.tgz#0300943770e04231041a51bd39f0439b5c7ab4f0" resolved "https://registry.yarnpkg.com/@leichtgewicht/ip-codec/-/ip-codec-2.0.3.tgz#0300943770e04231041a51bd39f0439b5c7ab4f0"
@ -2321,6 +2326,35 @@
resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.11.5.tgz#db5a11bf66bdab39569719555b0f76e138d7bd64" resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.11.5.tgz#db5a11bf66bdab39569719555b0f76e138d7bd64"
integrity sha512-9X2obfABZuDVLCgPK9aX0a/x4jaOEweTTWE2+9sr0Qqqevj2Uv5XorvusThmc9XGYpS9yI+fhh8RTafBtGposw== integrity sha512-9X2obfABZuDVLCgPK9aX0a/x4jaOEweTTWE2+9sr0Qqqevj2Uv5XorvusThmc9XGYpS9yI+fhh8RTafBtGposw==
"@react-hook/latest@^1.0.2":
version "1.0.3"
resolved "https://registry.yarnpkg.com/@react-hook/latest/-/latest-1.0.3.tgz#c2d1d0b0af8b69ec6e2b3a2412ba0768ac82db80"
integrity sha512-dy6duzl+JnAZcDbNTfmaP3xHiKtbXYOaz3G51MGVljh548Y8MWzTr+PHLOfvpypEVW9zwvl+VyKjbWKEVbV1Rg==
"@react-hook/passive-layout-effect@^1.2.0":
version "1.2.1"
resolved "https://registry.yarnpkg.com/@react-hook/passive-layout-effect/-/passive-layout-effect-1.2.1.tgz#c06dac2d011f36d61259aa1c6df4f0d5e28bc55e"
integrity sha512-IwEphTD75liO8g+6taS+4oqz+nnroocNfWVHWz7j+N+ZO2vYrc6PV1q7GQhuahL0IOR7JccFTsFKQ/mb6iZWAg==
"@react-hook/resize-observer@^1.2.1":
version "1.2.5"
resolved "https://registry.yarnpkg.com/@react-hook/resize-observer/-/resize-observer-1.2.5.tgz#b59e2300de98bc6ddc6946942f21243cde10f984"
integrity sha512-qa0pPvRxq5VbdI8mMK2apPFsZOckhQ6D3Jc9yLuyHMNhui8yEih4qyFCZBDzzK3ymZS6LAltVSVg3l1Dg9vA0w==
dependencies:
"@juggle/resize-observer" "^3.3.1"
"@react-hook/latest" "^1.0.2"
"@react-hook/passive-layout-effect" "^1.2.0"
"@types/raf-schd" "^4.0.0"
raf-schd "^4.0.2"
"@react-hook/size@^2.1.2":
version "2.1.2"
resolved "https://registry.yarnpkg.com/@react-hook/size/-/size-2.1.2.tgz#87ed634ffb200f65d3e823501e5559aa3d584451"
integrity sha512-BmE5asyRDxSuQ9p14FUKJ0iBRgV9cROjqNG9jT/EjCM+xHha1HVqbPoT+14FQg1K7xIydabClCibUY4+1tw/iw==
dependencies:
"@react-hook/passive-layout-effect" "^1.2.0"
"@react-hook/resize-observer" "^1.2.1"
"@rollup/plugin-babel@^5.2.0": "@rollup/plugin-babel@^5.2.0":
version "5.3.1" version "5.3.1"
resolved "https://registry.yarnpkg.com/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz#04bc0608f4aa4b2e4b1aebf284344d0f68fda283" resolved "https://registry.yarnpkg.com/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz#04bc0608f4aa4b2e4b1aebf284344d0f68fda283"
@ -3980,6 +4014,11 @@
resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.7.tgz#63bb7d067db107cc1e457c303bc25d511febf6cb" resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.7.tgz#63bb7d067db107cc1e457c303bc25d511febf6cb"
integrity sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw== integrity sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==
"@types/raf-schd@^4.0.0":
version "4.0.1"
resolved "https://registry.yarnpkg.com/@types/raf-schd/-/raf-schd-4.0.1.tgz#1f9e03736f277fe9c7b82102bf18570a6ee19f82"
integrity sha512-Ha+EnKHFIh9EKW0/XZJPUd3EGDFisEvauaBd4VVCRPKeOqUxNEc9TodiY2Zhk33XCgzJucoFEcaoNcBAPHTQ2A==
"@types/range-parser@*": "@types/range-parser@*":
version "1.2.4" version "1.2.4"
resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.4.tgz#cd667bcfdd025213aafb7ca5915a932590acdcdc" resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.4.tgz#cd667bcfdd025213aafb7ca5915a932590acdcdc"
@ -4025,10 +4064,10 @@
dependencies: dependencies:
"@types/react" "*" "@types/react" "*"
"@types/react@*", "@types/react@^16.9.19", "@types/react@^18.0.1", "@types/react@^18.0.3": "@types/react@*", "@types/react@17.0.43", "@types/react@^16.9.19", "@types/react@^18.0.3":
version "18.0.3" version "17.0.43"
resolved "https://registry.yarnpkg.com/@types/react/-/react-18.0.3.tgz#baefa397561372015b9f8ba5bc83bc3f84ae8fcb" resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.43.tgz#4adc142887dd4a2601ce730bc56c3436fdb07a55"
integrity sha512-P8QUaMW4k+kH9aKNPl9b3XWcKMSSALYprLL8xpAMJOLUn3Pl6B+6nKC4F7dsk9oJPwkiRx+qlwhG/Zc1LxFVuQ== integrity sha512-8Q+LNpdxf057brvPu1lMtC5Vn7J119xrP1aq4qiaefNioQUYANF/CYeK4NsKorSZyUGJ66g0IM+4bbjwx45o2A==
dependencies: dependencies:
"@types/prop-types" "*" "@types/prop-types" "*"
"@types/scheduler" "*" "@types/scheduler" "*"
@ -4090,7 +4129,7 @@
resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.1.tgz#20f18294f797f2209b5f65c8e3b5c8e8261d127c" resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.1.tgz#20f18294f797f2209b5f65c8e3b5c8e8261d127c"
integrity sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw== integrity sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==
"@types/styled-components@^5.1.24": "@types/styled-components@^5.1.25":
version "5.1.25" version "5.1.25"
resolved "https://registry.yarnpkg.com/@types/styled-components/-/styled-components-5.1.25.tgz#0177c4ab5fa7c6ed0565d36f597393dae3f380ad" resolved "https://registry.yarnpkg.com/@types/styled-components/-/styled-components-5.1.25.tgz#0177c4ab5fa7c6ed0565d36f597393dae3f380ad"
integrity sha512-fgwl+0Pa8pdkwXRoVPP9JbqF0Ivo9llnmsm+7TCI330kbPIFd9qv1Lrhr37shf4tnxCOSu+/IgqM7uJXLWZZNQ== integrity sha512-fgwl+0Pa8pdkwXRoVPP9JbqF0Ivo9llnmsm+7TCI330kbPIFd9qv1Lrhr37shf4tnxCOSu+/IgqM7uJXLWZZNQ==
@ -13554,6 +13593,11 @@ quick-lru@^5.1.1:
resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-5.1.1.tgz#366493e6b3e42a3a6885e2e99d18f80fb7a8c932" resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-5.1.1.tgz#366493e6b3e42a3a6885e2e99d18f80fb7a8c932"
integrity sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA== integrity sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==
raf-schd@^4.0.2:
version "4.0.3"
resolved "https://registry.yarnpkg.com/raf-schd/-/raf-schd-4.0.3.tgz#5d6c34ef46f8b2a0e880a8fcdb743efc5bfdbc1a"
integrity sha512-tQkJl2GRWh83ui2DiPTJz9wEiMN20syf+5oKfB03yYP7ioZcJwsIK8FjrtLwH1m7C7e+Tt2yYBlrOpdT+dyeIQ==
raf@^3.4.1: raf@^3.4.1:
version "3.4.1" version "3.4.1"
resolved "https://registry.yarnpkg.com/raf/-/raf-3.4.1.tgz#0742e99a4a6552f445d73e3ee0328af0ff1ede39" resolved "https://registry.yarnpkg.com/raf/-/raf-3.4.1.tgz#0742e99a4a6552f445d73e3ee0328af0ff1ede39"