From 9208330038470997328a4c6b3363eb487bf496d5 Mon Sep 17 00:00:00 2001 From: Vyacheslav Matyukhin Date: Sun, 26 Jun 2022 21:15:09 +0300 Subject: [PATCH] playground: manual play mode --- .../src/components/SquiggleChart.tsx | 104 +++++++++-------- .../src/components/SquigglePlayground.tsx | 109 +++++++++++++++--- .../components/src/components/ui/Toggle.tsx | 34 ++++++ 3 files changed, 180 insertions(+), 67 deletions(-) create mode 100644 packages/components/src/components/ui/Toggle.tsx diff --git a/packages/components/src/components/SquiggleChart.tsx b/packages/components/src/components/SquiggleChart.tsx index 9e352a62..bfb69a4e 100644 --- a/packages/components/src/components/SquiggleChart.tsx +++ b/packages/components/src/components/SquiggleChart.tsx @@ -48,57 +48,59 @@ export interface SquiggleChartProps { const defaultOnChange = () => {}; -export const SquiggleChart: React.FC = ({ - code = "", - environment, - onChange = defaultOnChange, // defaultOnChange must be constant, don't move its definition here - height = 200, - bindings = defaultBindings, - jsImports = defaultImports, - showSummary = false, - width, - showTypes = false, - showControls = false, - logX = false, - expY = false, - diagramStart = 0, - diagramStop = 10, - diagramCount = 100, -}) => { - const result = useSquiggle({ - code, - bindings, +export const SquiggleChart: React.FC = React.memo( + ({ + code = "", environment, - jsImports, - onChange, - }); + onChange = defaultOnChange, // defaultOnChange must be constant, don't move its definition here + height = 200, + bindings = defaultBindings, + jsImports = defaultImports, + showSummary = false, + width, + showTypes = false, + showControls = false, + logX = false, + expY = false, + diagramStart = 0, + diagramStop = 10, + diagramCount = 100, + }) => { + const result = useSquiggle({ + code, + bindings, + environment, + jsImports, + onChange, + }); - if (result.tag !== "Ok") { - return ; + if (result.tag !== "Ok") { + return ; + } + + let distributionPlotSettings = { + showControls, + showSummary, + logX, + expY, + }; + + let chartSettings = { + start: diagramStart, + stop: diagramStop, + count: diagramCount, + }; + + return ( + + ); } - - let distributionPlotSettings = { - showControls, - showSummary, - logX, - expY, - }; - - let chartSettings = { - start: diagramStart, - stop: diagramStop, - count: diagramCount, - }; - - return ( - - ); -}; +); diff --git a/packages/components/src/components/SquigglePlayground.tsx b/packages/components/src/components/SquigglePlayground.tsx index 4b01a344..74f48455 100644 --- a/packages/components/src/components/SquigglePlayground.tsx +++ b/packages/components/src/components/SquigglePlayground.tsx @@ -1,4 +1,4 @@ -import React, { FC, Fragment, useState, useEffect } from "react"; +import React, { FC, Fragment, useState, useEffect, useMemo } from "react"; import { Path, useForm, UseFormRegister, useWatch } from "react-hook-form"; import * as yup from "yup"; import { useMaybeControlledValue } from "../lib/hooks"; @@ -6,10 +6,14 @@ import { yupResolver } from "@hookform/resolvers/yup"; import { Tab } from "@headlessui/react"; import { ChartSquareBarIcon, + CheckCircleIcon, CodeIcon, CogIcon, CurrencyDollarIcon, EyeIcon, + PauseIcon, + PlayIcon, + RefreshIcon, } from "@heroicons/react/solid"; import clsx from "clsx"; @@ -20,6 +24,7 @@ import { CodeEditor } from "./CodeEditor"; import { JsonEditor } from "./JsonEditor"; import { ErrorAlert, SuccessAlert } from "./Alert"; import { SquiggleContainer } from "./SquiggleContainer"; +import { Toggle } from "./ui/Toggle"; interface PlaygroundProps { /** The initial squiggle string to put in the playground */ @@ -110,7 +115,7 @@ type StyledTabProps = { const StyledTab: React.FC = ({ name, icon: Icon }) => { return ( - + {({ selected }) => ( + )} + + + ); +}; + export const SquigglePlayground: FC = ({ defaultCode = "", height = 500, @@ -225,7 +277,14 @@ export const SquigglePlayground: FC = ({ const [importString, setImportString] = useState("{}"); const [imports, setImports] = useState({}); const [importsAreValid, setImportsAreValid] = useState(true); - const { register, control } = useForm({ + + const [renderedCode, setRenderedCode] = useState(""); // used only if autoplay is false + + const { + register, + control, + setValue: setFormValue, + } = useForm({ resolver: yupResolver(schema), defaultValues: { sampleCount: 1000, @@ -242,6 +301,7 @@ export const SquigglePlayground: FC = ({ diagramStart: 0, diagramStop: 10, diagramCount: 20, + autoplay: true, }, }); const vars = useWatch({ @@ -252,10 +312,14 @@ export const SquigglePlayground: FC = ({ onSettingsChange?.(vars); }, [vars, onSettingsChange]); - const env: environment = { - sampleCount: Number(vars.sampleCount), - xyPointLength: Number(vars.xyPointLength), - }; + const env: environment = useMemo( + () => ({ + sampleCount: Number(vars.sampleCount), + xyPointLength: Number(vars.xyPointLength), + }), + [vars.sampleCount, vars.xyPointLength] + ); + const getChangeJson = (r: string) => { setImportString(r); try { @@ -418,7 +482,7 @@ export const SquigglePlayground: FC = ({ const squiggleChart = ( = ({
- - + + + + + + + { + setRenderedCode(code); + }} + onAutoplayChange={(newValue) => { + if (!newValue) setRenderedCode(code); + setFormValue("autoplay", newValue); + }} /> - - - - +
{vars.showEditor ? withEditor : withoutEditor}
diff --git a/packages/components/src/components/ui/Toggle.tsx b/packages/components/src/components/ui/Toggle.tsx new file mode 100644 index 00000000..1b96db77 --- /dev/null +++ b/packages/components/src/components/ui/Toggle.tsx @@ -0,0 +1,34 @@ +import clsx from "clsx"; +import React from "react"; + +type IconType = (props: React.ComponentProps<"svg">) => JSX.Element; + +type Props = { + status: boolean; + onChange: (status: boolean) => void; + texts: [string, string]; + icons: [IconType, IconType]; +}; + +export const Toggle: React.FC = ({ + texts: [onText, offText], + icons: [OnIcon, OffIcon], + status, + onChange, +}) => { + const CurrentIcon = status ? OnIcon : OffIcon; + return ( + + ); +};