[playground] TabbedWindowItem lifting tabs state up
- List local state in TabbedWindowItem to Editor/index
jacdebug committed
Nov 25, 2022 at 09:00 UTC
b932ce19a712223a0a1961ccf0f26bf2b1775a70
3 files changed
+57
-13
compiler/forget/packages/playground/components/Editor/Output.tsx
+6
-2
@@ -17,7 +17,7 @@ import prettierParserBabel from "prettier/parser-babel";
17
import { memo, useMemo } from "react";
18
import compileOldArchitecture from "../../lib/compilerDriver";
19
import type { Store } from "../../lib/stores";
20
-import TabbedWindow from "../TabbedWindow";
20
+import TabbedWindow, { TabTypes } from "../TabbedWindow";
21
import { monacoOptions } from "./monacoOptions";
22
const {
23
parseFunctions,
@@ -38,6 +38,8 @@ export default MemoizedOutput;
38
type Props = {
39
store: Store;
40
updateDiagnostics: (newDiags: Diagnostic[]) => void;
41
+ tabsOpen: Map<TabTypes, boolean>;
42
+ setTabsOpen: (newTab: Map<TabTypes, boolean>) => void;
43
};
44
45
type CompilerOutput = {
@@ -118,7 +120,7 @@ function compile(source: string): CompilerOutput | CompilerError {
120
}
121
122
// TODO(gsn: Update diagnostics ƒrom HIR output
121
-function Output({ store }: Props) {
123
+function Output({ store, setTabsOpen, tabsOpen }: Props) {
124
const compilerOutput = useMemo(() => compile(store.source), [store.source]);
125
const { outputs: oldCompilerOutputs } = useMemo(
126
() => compileOldArchitecture(store.source, store.compilerFlags),
@@ -139,6 +141,8 @@ function Output({ store }: Props) {
141
return (
142
<TabbedWindow
143
defaultTab="HIR"
144
+ setTabsOpen={setTabsOpen}
145
+ tabsOpen={tabsOpen}
146
tabs={{
147
HIR: (
148
<TextTabContent output={compilerOutput.hirOutput}></TextTabContent>
compiler/forget/packages/playground/components/Editor/index.tsx
+8
-1
@@ -21,6 +21,7 @@ import {
21
type Store,
22
} from "../../lib/stores";
23
import { useStore, useStoreDispatch } from "../StoreContext";
24
+import { TabTypes } from "../TabbedWindow";
25
import Input from "./Input";
26
import Output from "./Output";
27
@@ -41,6 +42,7 @@ export default function Editor() {
42
(newDiags: Diagnostic[]) => setDiagnostics(newDiags),
43
[setDiagnostics]
44
);
45
+ const [tabsOpen, setTabsOpen] = useState<Map<TabTypes, boolean>>(new Map());
46
47
/**
48
* Initialize store from encoded data or fallback to the default store.
@@ -90,7 +92,12 @@ export default function Editor() {
92
hidden: !showOutputOnMobile,
93
})}
94
>
93
- <Output store={deferredStore} updateDiagnostics={updateDiagnostics} />
95
+ <Output
96
+ tabsOpen={tabsOpen}
97
+ setTabsOpen={setTabsOpen}
98
+ store={deferredStore}
99
+ updateDiagnostics={updateDiagnostics}
100
+ />
101
</div>
102
</div>
103
<button
compiler/forget/packages/playground/components/TabbedWindow.tsx
+43
-10
@@ -6,16 +6,39 @@
6
*/
7
8
import clsx from "clsx";
9
-import React, { useState } from "react";
9
+import React, { useCallback, useState } from "react";
10
+
11
+export type TabTypes =
12
+ | "HIR"
13
+ | "SSA"
14
+ | "EliminateRedundantPhi"
15
+ | "InferReferenceEffects"
16
+ | "InferMutableRanges"
17
+ | "LeaveSSA"
18
+ | "JS"
19
+ | "SourceMap"
20
+ | "OldArchitecture";
21
+
22
+type TabsRecord = Record<TabTypes, React.ReactNode>;
23
24
export default function TabbedWindow(props: {
25
defaultTab: string | null;
13
- tabs: { [name: string]: React.ReactNode };
26
+ tabs: TabsRecord;
27
+ tabsOpen: Map<TabTypes, boolean>;
28
+ setTabsOpen: (newTab: Map<TabTypes, boolean>) => void;
29
}): React.ReactElement {
30
return (
31
<div className="flex flex-row h-full">
32
{Object.keys(props.tabs).map((name, index, all) => {
18
- return <TabbedWindowItem name={name} key={index} tabs={props.tabs} />;
33
+ return (
34
+ <TabbedWindowItem
35
+ name={name as TabTypes}
36
+ key={index}
37
+ tabs={props.tabs}
38
+ tabsOpen={props.tabsOpen}
39
+ setTabsOpen={props.setTabsOpen}
40
+ />
41
+ );
42
})}
43
</div>
44
);
@@ -24,19 +47,29 @@ export default function TabbedWindow(props: {
47
function TabbedWindowItem({
48
name,
49
tabs,
50
+ tabsOpen,
51
+ setTabsOpen,
52
}: {
28
- name: string;
29
- tabs: { [name: string]: React.ReactNode };
53
+ name: TabTypes;
54
+ tabs: TabsRecord;
55
+ tabsOpen: Map<TabTypes, boolean>;
56
+ setTabsOpen: (newTab: Map<TabTypes, boolean>) => void;
57
}): React.ReactElement {
31
- const [isShow, setIsShow] = useState<boolean>(false);
58
+ const isShow = tabsOpen.get(name) ?? false;
59
+
60
+ const toggleTabs = useCallback(() => {
61
+ const nextState = new Map(tabsOpen);
62
+ nextState.set(name, !isShow);
63
+ setTabsOpen(nextState);
64
+ }, [tabsOpen, name, isShow, setTabsOpen]);
65
66
return (
67
<div key={name} className="flex flex-row">
68
{isShow ? (
69
<div style={{ minWidth: 500 }}>
70
<h2
38
- onClick={() => setIsShow(!isShow)}
39
- className="p-4 border-b cursor-pointer border-grey-200"
71
+ onClick={toggleTabs}
72
+ className="p-4 duration-150 ease-in border-b cursor-pointer border-grey-200 text-secondary hover:text-link"
73
>
74
- {name}
75
</h2>
@@ -46,8 +79,8 @@ function TabbedWindowItem({
79
<div className="relative items-center h-full px-4 py-8 align-middle border-r border-grey-200">
80
<button
81
style={{ transform: "rotate(90deg) translate(-50%)" }}
49
- onClick={() => setIsShow(!isShow)}
50
- className="flex-grow-0 w-5 transition-colors duration-150 ease-in"
82
+ onClick={toggleTabs}
83
+ className="flex-grow-0 w-5 transition-colors duration-150 ease-in text-secondary hover:text-link"
84
>
85
{`+${name}`}
86
</button>