Skip to content

Commit 1234dec

Browse files
committed
chore: un-generic panel display components
1 parent 271e868 commit 1234dec

File tree

14 files changed

+180
-189
lines changed

14 files changed

+180
-189
lines changed

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,8 @@
6060
"use-deep-compare-effect": "^1.8.1",
6161
"use-keyboard-shortcuts": "^2.2.2",
6262
"visjs-network": "^4.24.11",
63-
"yaml": "^2.0.1"
63+
"yaml": "^2.0.1",
64+
"zod": "^4.2.1"
6465
},
6566
"devDependencies": {
6667
"@eslint/js": "^9.18.0",

src/components/FullPlayground.tsx

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,6 @@ import { ShareLoader } from "./ShareLoader";
7777
import { ValidateButton } from "./ValidationButton";
7878
import { Panel, useSummaryStyles } from "./panels/base/common";
7979
import { ReflexedPanelDisplay } from "./panels/base/reflexed";
80-
import { PlaygroundPanelLocation } from "./panels/panels";
8180
import { ProblemsPanel, ProblemsSummary } from "./panels/problems";
8281
import { TerminalPanel, TerminalSummary } from "./panels/terminal";
8382
import { ValidationPanel, ValidationSummary } from "./panels/validation";
@@ -1104,31 +1103,31 @@ const TabLabelWithCount = (props: {
11041103
);
11051104
};
11061105

1107-
const panels: Panel<PlaygroundPanelLocation>[] = [
1106+
const panels: Panel[] = [
11081107
{
11091108
id: "problems",
1110-
summary: ProblemsSummary,
1111-
content: ProblemsPanel,
1109+
Summary: ProblemsSummary,
1110+
Content: ProblemsPanel,
11121111
},
11131112
{
11141113
id: "watches",
1115-
summary: WatchesSummary,
1116-
content: WatchesPanel,
1114+
Summary: WatchesSummary,
1115+
Content: WatchesPanel,
11171116
},
11181117
{
11191118
id: "visualizer",
1120-
summary: VisualizerSummary,
1121-
content: VisualizerPanel,
1119+
Summary: VisualizerSummary,
1120+
Content: VisualizerPanel,
11221121
},
11231122
{
11241123
id: "validation",
1125-
summary: ValidationSummary,
1126-
content: ValidationPanel,
1124+
Summary: ValidationSummary,
1125+
Content: ValidationPanel,
11271126
},
11281127
{
11291128
id: "terminal",
1130-
summary: TerminalSummary,
1131-
content: TerminalPanel,
1129+
Summary: TerminalSummary,
1130+
Content: TerminalPanel,
11321131
},
11331132
];
11341133

src/components/panels/base/common.tsx

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
1+
import { type ReactNode } from 'react'
12
import { createStyles, makeStyles, Theme } from "@material-ui/core/styles";
23
import "react-reflex/styles.css";
34
import { DataStore } from "../../../services/datastore";
45
import { Services } from "../../../services/services";
6+
import { ReflexedPanelLocation } from '../types';
57

68
/**
79
* Panel defines a single panel found in the panel display component.
810
*/
9-
export interface Panel<L extends string> {
11+
export interface Panel {
1012
/**
1113
* id is the unique ID for the panel. Must be stable across loads.
1214
*/
@@ -15,29 +17,29 @@ export interface Panel<L extends string> {
1517
/**
1618
* summary is the React tag to render for displaying the summary of the panel.
1719
*/
18-
summary: (props: PanelSummaryProps<L>) => JSX.Element;
20+
Summary: (props: PanelSummaryProps) => ReactNode;
1921

2022
/**
2123
* content is the React tag to render for displaying the contents of the panel.
2224
*/
23-
content: (props: PanelProps<L>) => JSX.Element;
25+
Content: (props: PanelProps) => ReactNode;
2426
}
2527

2628
/**
2729
* PanelProps are the props passed to all panels content tags.
2830
*/
29-
export interface PanelProps<L extends string> {
31+
export interface PanelProps {
3032
datastore: DataStore;
3133
services: Services;
32-
location: L;
34+
location: ReflexedPanelLocation;
3335
}
3436

3537
/**
3638
* PanelSummaryProps are the props passed to all panel summary tags.
3739
*/
38-
export interface PanelSummaryProps<L extends string> {
40+
export interface PanelSummaryProps {
3941
services: Services;
40-
location: L;
42+
location: ReflexedPanelLocation;
4143
}
4244

4345
/**

src/components/panels/base/components.tsx

Lines changed: 19 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,16 @@ import { DataStore } from "../../../services/datastore";
1313
import { Services } from "../../../services/services";
1414
import { Panel, useSummaryStyles } from "./common";
1515
import { LocationData, PanelsCoordinator } from "./coordinator";
16+
import { ReflexedPanelLocation } from "../types";
1617

1718
export const SUMMARY_BAR_HEIGHT = 48; // Pixels
1819

1920
/**
2021
* PanelSummaryBar is the summary bar displayed when a panel display is closed.
2122
*/
22-
export function PanelSummaryBar<L extends string>(props: {
23-
location: L;
24-
coordinator: PanelsCoordinator<L>;
23+
export function PanelSummaryBar(props: {
24+
location: ReflexedPanelLocation;
25+
coordinator: PanelsCoordinator;
2526
services: Services;
2627
disabled?: boolean | undefined;
2728
overrideSummaryDisplay?: ReactNode;
@@ -45,10 +46,10 @@ export function PanelSummaryBar<L extends string>(props: {
4546
>
4647
{props.overrideSummaryDisplay !== undefined &&
4748
props.overrideSummaryDisplay}
48-
{panels.map((panel: Panel<L>) => {
49+
{panels.map((panel: Panel) => {
4950
// NOTE: Using this as a tag here is important for React's state system. Otherwise,
5051
// it'll run hooks outside of the normal flow, which breaks things.
51-
const Summary = panel.summary;
52+
const Summary = panel.Summary;
5253
return (
5354
<Button
5455
key={panel.id}
@@ -114,23 +115,22 @@ const TOOLBAR_HEIGHT = 48; // Pixels
114115
/**
115116
* PanelDisplay displays the panels in a specific location.
116117
*/
117-
export function PanelDisplay<L extends string>(
118+
export function PanelDisplay(
118119
props: {
119-
location: L;
120-
coordinator: PanelsCoordinator<L>;
120+
location: ReflexedPanelLocation;
121+
coordinator: PanelsCoordinator;
121122
datastore: DataStore;
122123
services: Services;
123-
} & {
124124
dimensions?: { width: number; height: number };
125-
},
125+
}
126126
) {
127127
const classes = useStyles();
128128
const coordinator = props.coordinator;
129129

130130
const currentTabName = coordinator.getActivePanel(props.location)?.id || "";
131131

132132
const handleChangeTab = useCallback(
133-
(_event: React.ChangeEvent<object>, selectedPanelId: string) => {
133+
(_event: object, selectedPanelId: string) => {
134134
coordinator.setActivePanel(selectedPanelId, props.location);
135135
},
136136
[coordinator, props.location],
@@ -159,14 +159,13 @@ export function PanelDisplay<L extends string>(
159159
aria-label="Tabs"
160160
variant="fullWidth"
161161
>
162-
{panels.map((panel: Panel<L>) => {
162+
{panels.map(({id, Summary }: Panel) => {
163163
// NOTE: Using this as a tag here is important for React's state system. Otherwise,
164164
// it'll run hooks outside of the normal flow, which breaks things.
165-
const Summary = panel.summary;
166165
return (
167166
<Tab
168-
key={`tab-${panel.id}`}
169-
value={panel.id}
167+
key={id}
168+
value={id}
170169
label={<Summary {...props} />}
171170
/>
172171
);
@@ -175,7 +174,7 @@ export function PanelDisplay<L extends string>(
175174

176175
<span>
177176
{currentTabName &&
178-
coordinator.listLocations().map((locData: LocationData<L>) => {
177+
coordinator.listLocations().map((locData: LocationData) => {
179178
if (locData.location === props.location) {
180179
return <div key={locData.location} />;
181180
}
@@ -215,27 +214,26 @@ export function PanelDisplay<L extends string>(
215214
</Toolbar>
216215
</AppBar>
217216

218-
{panels.map((panel: Panel<L>) => {
217+
{panels.map(({id, Content }: Panel) => {
219218
// NOTE: Using this as a tag here is important for React's state system. Otherwise,
220219
// it'll run hooks outside of the normal flow, which breaks things.
221-
const Content = panel.content;
222220
const height =
223221
(props.dimensions?.height ?? 0 >= 48)
224222
? (props.dimensions?.height ?? 0) - 48
225223
: "auto";
226224

227225
return (
228226
<TabPanel
229-
key={`panel-${panel.id}`}
230-
index={panel.id}
227+
key={id}
228+
index={id}
231229
value={currentTabName}
232230
style={{
233231
overflow: "auto",
234232
height: height || "auto",
235233
position: "relative",
236234
}}
237235
>
238-
{currentTabName === panel.id && <Content {...contentProps} />}
236+
{currentTabName === id && <Content {...contentProps} />}
239237
</TabPanel>
240238
);
241239
})}

0 commit comments

Comments
 (0)