@samitouri / QOS-React-2 / commits / c203d07d8c

[Playground] vertical tabs to see multiple stages same time

# Add vertical tabs to see multiple stages same time <img width="781" alt="image" src="https://user-images.githubusercontent.com/430289/203837762-ccf37491-2006-4512-8014-0b7893f3396f.png">

jacdebug committed Nov 24, 2022 at 17:25 UTC c203d07d8c3033a3b1d80958abe1329467979884
3 files changed +40 -37
compiler/forget/packages/playground/components/Editor/Output.tsx
-1
@@ -205,7 +205,6 @@ function TextTabContent({
205 return (
206 <div className="w-full h-full">
207 <MonacoEditor
208 - path={kind}
208 defaultLanguage="javascript"
209 value={output}
210 options={{
compiler/forget/packages/playground/components/Editor/index.tsx
+1 -1
@@ -86,7 +86,7 @@ export default function Editor() {
86 </div>
87 <div
88 style={{ width: isMobile ? "100%" : `${100 - inputWidthInPct}%` }}
89 - className={clsx("flex sm:flex flex-col sm:min-w-[300px]", {
89 + className={clsx("flex sm:flex sm:min-w-[300px]", {
90 hidden: !showOutputOnMobile,
91 })}
92 >
compiler/forget/packages/playground/components/TabbedWindow.tsx
+39 -35
@@ -12,43 +12,47 @@ export default function TabbedWindow(props: {
12 defaultTab: string | null;
13 tabs: { [name: string]: React.ReactNode };
14 }): React.ReactElement {
15 - let [selected, setSelected] = useState<string | null>(props.defaultTab);
16 - if (selected === null) {
17 - selected = Object.keys(props.tabs)[0];
18 - }
15 + return (
16 + <div className="flex flex-row h-full">
17 + {Object.keys(props.tabs).map((name, index, all) => {
18 + return <TabbedWindowItem name={name} key={index} tabs={props.tabs} />;
19 + })}
20 + </div>
21 + );
22 +}
23 +
24 +function TabbedWindowItem({
25 + name,
26 + tabs,
27 +}: {
28 + name: string;
29 + tabs: { [name: string]: React.ReactNode };
30 +}): React.ReactElement {
31 + const [isShow, setIsShow] = useState<boolean>(false);
32
33 return (
21 - <div className="flex flex-col w-full h-full">
22 - <div className="flex flex-none overflow-x-auto border-b border-gray-200 h-9 no-scrollbar">
23 - {Object.keys(props.tabs).map((name, index, all) => {
24 - const isFirst = index === 0;
25 - const isSelected = name === selected;
26 - return (
27 - <React.Fragment key={name}>
28 - {isFirst ? null : (
29 - <div className="w-[1px] h-[18px] self-center border-gray-200 border-l mx-1" />
30 - )}
31 - <div
32 - className={clsx(
33 - "h-full border-b-2 border-white px-4 py-0.5 flex items-center",
34 - {
35 - "border-link": isSelected,
36 - }
37 - )}
38 - >
39 - <button
40 - disabled={isSelected}
41 - onClick={() => setSelected(name)}
42 - className="transition-colors duration-150 ease-in"
43 - >
44 - {name}
45 - </button>
46 - </div>
47 - </React.Fragment>
48 - );
49 - })}
50 - </div>
51 - {props.tabs[selected]}
34 + <div key={name} className="flex flex-row">
35 + {isShow ? (
36 + <div style={{ minWidth: 500 }}>
37 + <h2
38 + onClick={() => setIsShow(!isShow)}
39 + className="p-4 border-b cursor-pointer border-grey-200"
40 + >
41 + - {name}
42 + </h2>
43 + {tabs[name]}
44 + </div>
45 + ) : (
46 + <div className="relative items-center h-full px-4 py-8 align-middle border-r border-grey-200">
47 + <button
48 + style={{ transform: "rotate(90deg) translate(-50%)" }}
49 + onClick={() => setIsShow(!isShow)}
50 + className="flex-grow-0 w-5 transition-colors duration-150 ease-in"
51 + >
52 + {`+${name}`}
53 + </button>
54 + </div>
55 + )}
56 </div>
57 );
58 }