feat(playground): add settings button and group IR
fix
MODIFY
website/playground/src/App.tsx
website/playground/src/App.tsx
@@ -3,8 +3,7 @@ import { useEffect, useState, useRef } from "react";
import { LoadingState, RomeOutput } from "./types";
import { defaultRomeConfig } from "./types";
import { usePlaygroundState, useWindowSize } from "./utils";
-import DesktopPlayground from "./DesktopPlayground";
-import { MobilePlayground } from "./MobilePlayground";
+import Playground from "./Playground";
function App() {
const [loadingState, setLoadingState] = useState(LoadingState.Loading);
@@ -105,18 +104,8 @@ function App() {
</div>
);
default:
- if (width && width < 480) {
return (
- <MobilePlayground
- setPlaygroundState={setPlaygroundState}
- playgroundState={playgroundState}
- prettierOutput={prettierOutput}
- romeOutput={romeOutput}
- />
- );
- }
- return (
- <DesktopPlayground
+ <Playground
setPlaygroundState={setPlaygroundState}
playgroundState={playgroundState}
prettierOutput={prettierOutput}

DELETE
website/playground/src/MobilePlayground.tsx
-import { useCallback, useMemo } from "react";
-import { Tab, TabList, TabPanel, Tabs } from "react-tabs";
-import CodeMirror from "@uiw/react-codemirror";
-import type { ViewUpdate } from "@codemirror/view";
-import { javascript } from "@codemirror/lang-javascript";
-import { PlaygroundProps } from "./types";
-import { SettingsMenu } from "./SettingsMenu";
-import TreeView from "./TreeView";
-import MermaidGraph from "./MermaidGraph";
-
-export function MobilePlayground({
- setPlaygroundState,
- playgroundState: { code, ...settings },
- prettierOutput,
- romeOutput: {
- cst,
- ast,
- formatted_code,
- formatter_ir,
- errors,
- control_flow_graph,
- },
-}: PlaygroundProps) {
- const { isJsx, isTypeScript } = settings;
-
- const onUpdate = useCallback((viewUpdate: ViewUpdate) => {
- const cursorPosition = viewUpdate.state.selection.ranges[0]?.from ?? 0;
- setPlaygroundState((state) =>
- state.cursorPosition !== cursorPosition
- ? {
- ...state,
- cursorPosition,
- }
- : state,
- );
- }, []);
- const onChange = useCallback((value) => {
- setPlaygroundState((state) => ({ ...state, code: value }));
- }, []);
-
- const extensions = useMemo(
- () => [
- javascript({
- jsx: isJsx,
- typescript: isTypeScript,
- }),
- ],
- [isJsx, isTypeScript],
- );
-
- return (
- <div className="p-1">
- <h1 className="p-3 text-xl pb-5">Rome Playground</h1>
- <Tabs>
- <TabList>
- <Tab selectedClassName="bg-slate-300">Input</Tab>
- <Tab selectedClassName="bg-slate-300">Settings</Tab>
- <Tab selectedClassName="bg-slate-300">Formatter Output</Tab>
- <Tab selectedClassName="bg-slate-300">CST</Tab>
- <Tab selectedClassName="bg-slate-300">AST</Tab>
- <Tab selectedClassName="bg-slate-300">Rome IR</Tab>
- <Tab selectedClassName="bg-slate-300">Prettier IR</Tab>
- <Tab disabled={errors === ""} selectedClassName="bg-slate-300">
- Errors
- </Tab>
- <Tab
- disabled={control_flow_graph === ""}
- selectedClassName="bg-slate-300"
- >
- Control Flow Graph
- </Tab>
- </TabList>
- <TabPanel>
- <CodeMirror
- value={code}
- extensions={extensions}
- placeholder="Enter your code here"
- onUpdate={onUpdate}
- onChange={onChange}
- style={{
- fontSize: 12,
- height: "100vh",
- fontFamily:
- "ui-monospace,SFMono-Regular,SF Mono,Consolas,Liberation Mono,Menlo,monospace",
- }}
- />
- </TabPanel>
- <TabPanel>
- <SettingsMenu
- setPlaygroundState={setPlaygroundState}
- settings={settings}
- />
- </TabPanel>
- <TabPanel>
- <h1>Rome</h1>
- <CodeMirror
- value={formatted_code}
- extensions={extensions}
- placeholder="Rome Output"
- readOnly={true}
- style={{
- fontSize: 12,
- height: "40vh",
- overflowY: "scroll",
- fontFamily:
- "ui-monospace,SFMono-Regular,SF Mono,Consolas,Liberation Mono,Menlo,monospace",
- }}
- />
- <h1>Prettier</h1>
- <CodeMirror
- value={prettierOutput.code}
- extensions={extensions}
- readOnly={true}
- placeholder="Prettier Output"
- style={{
- fontSize: 12,
- height: "50vh",
- overflowY: "scroll",
- fontFamily:
- "ui-monospace,SFMono-Regular,SF Mono,Consolas,Liberation Mono,Menlo,monospace",
- }}
- />
- </TabPanel>
- <TabPanel>
- <TreeView tree={cst} />
- </TabPanel>
- <TabPanel>
- <TreeView tree={ast} />
- </TabPanel>
- <TabPanel>
- <pre className="h-screen overflow-y-scroll">{formatter_ir}</pre>
- </TabPanel>
- <TabPanel>
- <pre className="h-screen overflow-y-scroll">{prettierOutput.ir}</pre>
- </TabPanel>
- <TabPanel>
- <pre className="h-screen overflow-y-scroll whitespace-pre-wrap text-red-500 text-xs">
- {errors}
- </pre>
- </TabPanel>
- <TabPanel>
- <MermaidGraph graph={control_flow_graph} />
- </TabPanel>
- </Tabs>
- </div>
- );
-}

RENAME
website/playground/src/DesktopPlayground.tsx
website/playground/src/Playground.tsx
@@ -7,14 +7,21 @@ import { javascript } from "@codemirror/lang-javascript";
import { Tab, TabList, TabPanel, Tabs } from "react-tabs";
import { SettingsMenu } from "./SettingsMenu";
import TreeView from "./TreeView";
-import { useCallback, useEffect, useMemo, useRef, useState } from "react";
+import React, {
+ useCallback,
+ useEffect,
+ useMemo,
+ useRef,
+ useState,
+} from "react";
import MermaidGraph from "./MermaidGraph";
import { EditorSelection } from "@codemirror/state";
+import { useWindowSize } from "./utils";
const romeAstCodeMirrorExtension = [romeAst()];
const romeFormatterIrCodeMirrorExtension = [RomeFormatterIr()];
-export default function DesktopPlayground({
+export default function Playground({
setPlaygroundState,
playgroundState: { code, ...settings },
prettierOutput,
@@ -108,33 +115,77 @@ export default function DesktopPlayground({
setPlaygroundState((state) => ({ ...state, code: value }));
}, []);
+ const [isSettingsVisible, setSettingVisible] = useState(false);
+
+ const { width } = useWindowSize();
+ const isMd = width && width > 768;
+
+ const chevronSvg = (
+ <svg
+ xmlns="http://www.w3.org/2000/svg"
+ width="18"
+ height="18"
+ viewBox="0 0 24 24"
+ stroke-width="2"
+ stroke="currentColor"
+ fill="none"
+ stroke-linecap="round"
+ stroke-linejoin="round"
+ className="inline transition-all ml-1 group-aria-pressed:rotate-180"
+ >
+ <path stroke="none" d="M0 0h24v24H0z" fill="none" />
+ <polyline points="6 9 12 15 18 9" />
+ </svg>
+ );
+
return (
<div className="divide-y divide-slate-300 h-screen flex flex-col">
- <h1 className="p-4 text-xl">Rome Playground</h1>
+ <div className="p-4 flex justify-between">
+ <h1 className="text-xl">Rome Playground</h1>
+ {/* rome-ignore lint(a11y/useKeyWithClickEvents) lint: because of issue#3644 */}
+ <button
+ aria-label="Open or Close Settings Menu"
+ aria-pressed={isSettingsVisible}
+ onClick={() => setSettingVisible(!isSettingsVisible)}
+ className="text-base text-slate-700 font-medium hover:text-slate-800 group p-1"
+ >
+ Settings
+ {chevronSvg}
+ </button>
+ </div>
+ {isSettingsVisible && (
<SettingsMenu
settings={settings}
setPlaygroundState={setPlaygroundState}
/>
- <div className="box-border flex divide-x divide-slate-300 flex-1 overflow-auto">
+ )}
+ <div
+ className={`box-border divide-x divide-slate-300 flex-1 overflow-auto ${
+ isSettingsVisible ? "hidden md:flex" : "flex"
+ }`}
+ >
+ <div className="p-5 w-1/2 hidden md:block">
<CodeMirror
value={code}
- className="h-full overflow-y-hidden w-1/2 p-5 h-full"
+ className="h-full overflow-y-hidden w-full"
height="100%"
extensions={extensions}
placeholder="Enter your code here"
onUpdate={onUpdate}
onChange={onChange}
/>
+ </div>
+
<Tabs
- className="w-1/2 p-5 flex flex-col"
+ className="p-5 flex flex-col w-full md:w-1/2"
selectedTabPanelClassName="flex-1 react-tabs__tab-panel--selected overflow-y-auto"
>
<TabList>
+ {!isMd && <Tab selectedClassName="bg-slate-300">Code</Tab>}
<Tab selectedClassName="bg-slate-300">Formatter</Tab>
<Tab selectedClassName="bg-slate-300">CST</Tab>
<Tab selectedClassName="bg-slate-300">AST</Tab>
- <Tab selectedClassName="bg-slate-300">Rome IR</Tab>
- <Tab selectedClassName="bg-slate-300">Prettier IR</Tab>
+ <Tab selectedClassName="bg-slate-300">IR</Tab>
<Tab disabled={errors === ""} selectedClassName="bg-slate-300">
Diagnostics
</Tab>
@@ -145,6 +196,19 @@ export default function DesktopPlayground({
Control Flow Graph
</Tab>
</TabList>
+ {!isMd && (
+ <TabPanel>
+ <CodeMirror
+ value={code}
+ className="h-full overflow-y-hidden w-full"
+ height="100%"
+ extensions={extensions}
+ placeholder="Enter your code here"
+ onUpdate={onUpdate}
+ onChange={onChange}
+ />
+ </TabPanel>
+ )}
<TabPanel>
<div className="h-1/2 flex flex-col pb-4">
<h1 className="text-lg font-medium pb-2">Rome</h1>
@@ -183,6 +247,8 @@ export default function DesktopPlayground({
/>
</TabPanel>
<TabPanel>
+ <div className="h-1/2 flex flex-col pb-4">
+ <h1 className="text-lg font-medium pb-2">Rome</h1>
<CodeMirror
value={formatter_ir}
extensions={romeFormatterIrCodeMirrorExtension}
@@ -190,8 +256,9 @@ export default function DesktopPlayground({
height="100%"
readOnly={true}
/>
- </TabPanel>
- <TabPanel>
+ </div>
+ <div className="h-1/2 flex flex-col">
+ <h1 className="text-lg font-medium pb-2">Prettier</h1>
<CodeMirror
value={prettierOutput.ir}
extensions={romeFormatterIrCodeMirrorExtension}
@@ -199,6 +266,7 @@ export default function DesktopPlayground({
height="100%"
readOnly={true}
/>
+ </div>
</TabPanel>
<TabPanel>
<div
@@ -212,6 +280,11 @@ export default function DesktopPlayground({
</TabPanel>
</Tabs>
</div>
+ <div className={`${isSettingsVisible ? "block md:hidden" : "hidden"}`}>
+ <p className="text-center my-4 text-sm text-slate-600">
+ Press Settings to see Code and its Outputs
+ </p>
+ </div>
</div>
);

MODIFY
website/playground/src/SettingsMenu.tsx
website/playground/src/SettingsMenu.tsx
@@ -31,7 +31,7 @@ export function SettingsMenu({
}: Props) {
return (
<div>
- <div className="flex flex-col sm:flex-row">
+ <div className="flex flex-col md:flex-row">
<LineWidthInput
lineWidth={lineWidth}
setLineWidth={createSetter(setPlaygroundState, "lineWidth")}
@@ -43,7 +43,7 @@ export function SettingsMenu({
setIndentStyle={createSetter(setPlaygroundState, "indentStyle")}
/>
</div>
- <div className="flex flex-col sm:flex-row">
+ <div className="flex flex-col md:flex-row">
<QuoteStyleSelect
quoteStyle={quoteStyle}
setQuoteStyle={createSetter(setPlaygroundState, "quoteStyle")}
@@ -68,7 +68,7 @@ export function SettingsMenu({
setSourceType={createSetter(setPlaygroundState, "sourceType")}
/>
</div>
- <div className="flex flex-col sm:flex-row">
+ <div className="flex flex-col md:flex-row">
<NurseryRules
setEnabledNurseryRules={createSetter(
setPlaygroundState,

feat(playground): add settings button and group IR (#3559)

fix https://github.com/rome/tools/issues/2620