Cleaning up Playground toolbar

This commit is contained in:
Ozzie Gooen 2022-05-30 16:29:46 -07:00
parent d6bc942265
commit 1213ca2bf0
2 changed files with 142 additions and 115 deletions

View File

@ -6,7 +6,7 @@ export const ErrorBox: React.FC<{
children: React.ReactNode; children: React.ReactNode;
}> = ({ heading = "Error", children }) => { }> = ({ heading = "Error", children }) => {
return ( return (
<div className="rounded-md bg-red-100 p-4 m-4"> <div className="rounded-md bg-red-100 p-4">
<div className="flex"> <div className="flex">
<div className="flex-shrink-0"> <div className="flex-shrink-0">
<XCircleIcon className="h-5 w-5 text-red-400" aria-hidden="true" /> <XCircleIcon className="h-5 w-5 text-red-400" aria-hidden="true" />

View File

@ -11,7 +11,10 @@ import { defaultBindings, environment } from "@quri/squiggle-lang";
import { Tab } from "@headlessui/react"; import { Tab } from "@headlessui/react";
import { CodeIcon } from "@heroicons/react/solid"; import { CodeIcon } from "@heroicons/react/solid";
import { CogIcon } from "@heroicons/react/solid"; import { CogIcon } from "@heroicons/react/solid";
import { ChartSquareBarIcon } from "@heroicons/react/solid";
import { CurrencyDollarIcon } from "@heroicons/react/solid";
import { Fragment } from "react"; import { Fragment } from "react";
import { ErrorBox } from "./ErrorBox";
interface ShowBoxProps { interface ShowBoxProps {
height: number; height: number;
@ -155,12 +158,21 @@ let SquigglePlayground: FC<PlaygroundProps> = ({
}; };
// className="text-gray-400 group-hover:text-gray-500 -ml-0.5 mr-2 h-4 w-4" // className="text-gray-400 group-hover:text-gray-500 -ml-0.5 mr-2 h-4 w-4"
let tab = (key) => { let tab = (key, iconName) => {
let iconStyle = (isSelected) => let iconStyle = (isSelected) =>
classNames( classNames(
"-ml-0.5 mr-2 h-4 w-4 ", "-ml-0.5 mr-2 h-4 w-4 ",
isSelected ? "text-teal-500" : "text-gray-500 group-hover:text-gray-900" isSelected ? "text-teal-500" : "text-gray-500 group-hover:text-gray-900"
); );
let icon = (selected) =>
({
code: <CodeIcon className={iconStyle(selected)} />,
cog: <CogIcon className={iconStyle(selected)} />,
squareBar: <ChartSquareBarIcon className={iconStyle(selected)} />,
dollar: <CurrencyDollarIcon className={iconStyle(selected)} />,
}[iconName]);
return ( return (
<Tab key={key} as={Fragment}> <Tab key={key} as={Fragment}>
{({ selected }) => ( {({ selected }) => (
@ -178,11 +190,7 @@ let SquigglePlayground: FC<PlaygroundProps> = ({
: "" : ""
)} )}
> >
{key === "Code" ? ( {icon(selected)}
<CodeIcon className={iconStyle(selected)} />
) : (
<CogIcon className={iconStyle(selected)} />
)}
<span <span
className={classNames( className={classNames(
"", "",
@ -202,128 +210,147 @@ let SquigglePlayground: FC<PlaygroundProps> = ({
return ( return (
<Tab.Group> <Tab.Group>
<div className="border border-slate-300 rounded-sm flex-col flex"> <div className=" flex-col flex">
<div className="border-b border-slate-300 rounded-tl-sm rounded-tr-sm p-2"> <div className="pb-4">
<Tab.List className="p-0.5 rounded-lg bg-slate-200 hover:bg-slate-300 inline-flex"> <Tab.List className="p-0.5 rounded-lg bg-slate-100 hover:bg-slate-200 inline-flex">
{tab("Code")} {tab("Code", "code")}
{tab("Settings")} {tab("Sampling Settings", "cog")}
</Tab.List> {tab("View Settings", "squareBar")}
{tab("Input Variables", "dollar")}
</Tab.List>
</div> </div>
<div className="flex" style={{ height: height + "px" }}> <div className="flex" style={{ height: height + "px" }}>
<div className="w-1/2"> <div className="w-1/2">
<Tab.Panels> <Tab.Panels>
<Tab.Panel> <Tab.Panel>
<CodeEditor <div className="border border-slate-200">
value={squiggleString} <CodeEditor
onChange={setSquiggleString} value={squiggleString}
oneLine={false} onChange={setSquiggleString}
showGutter={true} oneLine={false}
height={height - 1} showGutter={true}
/> height={height - 1}
/>
</div>
</Tab.Panel> </Tab.Panel>
<Tab.Panel> <Tab.Panel>
<> <form className="space-y-6 p-3">
<form className="space-y-6 p-3"> <InputItem label="Sample Count">
<InputItem label="Sample Count"> <>
<>
<input
type="number"
{...register("sampleCount")}
className={numberStyle}
/>
<p className="mt-2 text-sm text-gray-500">
How many samples to use for Monte Carlo simulations.
This can be overridden by specific programs.
</p>
</>
</InputItem>
<InputItem label="Coordinate Count (For PointSet Shapes)">
<>
<input
type="number"
{...register("xyPointLength")}
className={numberStyle}
/>
<p className="mt-2 text-sm text-gray-500">
When distributions are converted into PointSet shapes,
we need to know how many coordinates to use.
</p>
</>
</InputItem>
<InputItem label="Chart Height (in Pixels)">
<input <input
type="number" type="number"
{...register("chartHeight")} {...register("sampleCount")}
className={numberStyle} className={numberStyle}
/> />
</InputItem> <p className="mt-2 text-sm text-gray-500">
<InputItem label="Editor Width"> How many samples to use for Monte Carlo simulations.
This can be overridden by specific programs.
</p>
</>
</InputItem>
<InputItem label="Coordinate Count (For PointSet Shapes)">
<>
<input <input
type="range" type="number"
min="1" {...register("xyPointLength")}
max="100" className={numberStyle}
className="slider"
{...register("leftSizePercent")}
/> />
</InputItem> <p className="mt-2 text-sm text-gray-500">
<fieldset className="space-y-2"> When distributions are converted into PointSet shapes,
<div className="relative flex items-start"> we need to know how many coordinates to use.
<div className="flex items-center h-5"> </p>
<input </>
type="checkbox" </InputItem>
{...register("showTypes")} </form>
className="focus:ring-indigo-500 h-4 w-4 text-indigo-600 border-gray-300 rounded" </Tab.Panel>
/>
</div> <Tab.Panel>
<div className="ml-3 text-sm"> <form className="space-y-6 p-3">
<label className="font-medium text-gray-700"> <InputItem label="Chart Height (in Pixels)">
Type Names <input
</label> type="number"
</div> {...register("chartHeight")}
</div> className={numberStyle}
<div className="relative flex items-start"> />
<div className="flex items-center h-5"> </InputItem>
<input <InputItem label="Editor Width">
type="checkbox" <input
{...register("showControls")} type="range"
className="focus:ring-indigo-500 h-4 w-4 text-indigo-600 border-gray-300 rounded" min="1"
/> max="100"
</div> className="slider"
<div className="ml-3 text-sm"> {...register("leftSizePercent")}
<label className="font-medium text-gray-700"> />
X-Y Coordinate Scales </InputItem>
</label> <fieldset className="space-y-2">
</div> <div className="relative flex items-start">
</div> <div className="flex items-center h-5">
<div className="relative flex items-start"> <input
<div className="flex items-center h-5"> type="checkbox"
<input {...register("showTypes")}
type="checkbox" className="focus:ring-indigo-500 h-4 w-4 text-indigo-600 border-gray-300 rounded"
{...register("showSummary")}
className="focus:ring-indigo-500 h-4 w-4 text-indigo-600 border-gray-300 rounded"
/>
</div>
<div className="ml-3 text-sm">
<label className="font-medium text-gray-700">
Summary Statistics
</label>
</div>
</div>
</fieldset>
<InputItem label="Json Editor for imports">
<>
<JsonEditor
value={importString}
onChange={getChangeJson}
oneLine={false}
showGutter={true}
height={100}
/> />
{importsAreValid ? "Valid" : "Invalid"} </div>
</> <div className="ml-3 text-sm">
</InputItem> <label className="font-medium text-gray-700">
</form> Type Names
</> </label>
</div>
</div>
<div className="relative flex items-start">
<div className="flex items-center h-5">
<input
type="checkbox"
{...register("showControls")}
className="focus:ring-indigo-500 h-4 w-4 text-indigo-600 border-gray-300 rounded"
/>
</div>
<div className="ml-3 text-sm">
<label className="font-medium text-gray-700">
X-Y Coordinate Scales
</label>
</div>
</div>
<div className="relative flex items-start">
<div className="flex items-center h-5">
<input
type="checkbox"
{...register("showSummary")}
className="focus:ring-indigo-500 h-4 w-4 text-indigo-600 border-gray-300 rounded"
/>
</div>
<div className="ml-3 text-sm">
<label className="font-medium text-gray-700">
Summary Statistics
</label>
</div>
</div>
</fieldset>
</form>
</Tab.Panel>
<Tab.Panel>
<InputItem label="Json Editor for imports">
<>
<JsonEditor
value={importString}
onChange={getChangeJson}
oneLine={false}
showGutter={true}
height={100}
/>
{importsAreValid ? (
"Valid"
) : (
<div className="p-2">
<ErrorBox heading="Invalid JSON">
You must use valid json in this editor.
</ErrorBox>
</div>
)}
</>
</InputItem>
</Tab.Panel> </Tab.Panel>
</Tab.Panels> </Tab.Panels>
</div> </div>