86 lines
2.5 KiB
TypeScript
86 lines
2.5 KiB
TypeScript
import React, { useMemo, type ComponentType } from "react";
|
|
import invariant from "tiny-invariant";
|
|
import {
|
|
createPaneFocusContextValue,
|
|
PaneFocusProvider,
|
|
PaneProvider,
|
|
type PaneContextValue,
|
|
} from "@/panels/pane-context";
|
|
import { getPanelRegistration } from "@/panels/panel-registry";
|
|
import { ensurePanelsRegistered } from "@/panels/register-panels";
|
|
import type { WorkspaceTabDescriptor } from "@/screens/workspace/workspace-tabs-types";
|
|
|
|
export interface WorkspacePaneContentModel {
|
|
key: string;
|
|
Component: ComponentType;
|
|
paneContextValue: PaneContextValue;
|
|
}
|
|
|
|
export interface BuildWorkspacePaneContentModelInput {
|
|
tab: WorkspaceTabDescriptor;
|
|
normalizedServerId: string;
|
|
normalizedWorkspaceId: string;
|
|
onOpenTab: (target: WorkspaceTabDescriptor["target"]) => void;
|
|
onCloseCurrentTab: () => void;
|
|
onRetargetCurrentTab: (target: WorkspaceTabDescriptor["target"]) => void;
|
|
onOpenWorkspaceFile: (filePath: string) => void;
|
|
}
|
|
|
|
export function buildWorkspacePaneContentModel({
|
|
tab,
|
|
normalizedServerId,
|
|
normalizedWorkspaceId,
|
|
onOpenTab,
|
|
onCloseCurrentTab,
|
|
onRetargetCurrentTab,
|
|
onOpenWorkspaceFile,
|
|
}: BuildWorkspacePaneContentModelInput): WorkspacePaneContentModel {
|
|
ensurePanelsRegistered();
|
|
const registration = getPanelRegistration(tab.kind);
|
|
invariant(registration, `No panel registration for kind: ${tab.kind}`);
|
|
return {
|
|
key: `${normalizedServerId}:${normalizedWorkspaceId}:${tab.tabId}:${tab.kind}`,
|
|
Component: registration.component,
|
|
paneContextValue: {
|
|
serverId: normalizedServerId,
|
|
workspaceId: normalizedWorkspaceId,
|
|
tabId: tab.tabId,
|
|
target: tab.target,
|
|
openTab: onOpenTab,
|
|
closeCurrentTab: onCloseCurrentTab,
|
|
retargetCurrentTab: onRetargetCurrentTab,
|
|
openFileInWorkspace: onOpenWorkspaceFile,
|
|
},
|
|
};
|
|
}
|
|
|
|
export interface WorkspacePaneContentProps {
|
|
content: WorkspacePaneContentModel;
|
|
isWorkspaceFocused: boolean;
|
|
isPaneFocused: boolean;
|
|
}
|
|
|
|
export function WorkspacePaneContent({
|
|
content,
|
|
isWorkspaceFocused,
|
|
isPaneFocused,
|
|
}: WorkspacePaneContentProps) {
|
|
const { Component, key, paneContextValue } = content;
|
|
const paneFocusValue = useMemo(
|
|
() =>
|
|
createPaneFocusContextValue({
|
|
isWorkspaceFocused,
|
|
isPaneFocused,
|
|
}),
|
|
[isPaneFocused, isWorkspaceFocused],
|
|
);
|
|
|
|
return (
|
|
<PaneProvider value={paneContextValue}>
|
|
<PaneFocusProvider value={paneFocusValue}>
|
|
<Component key={key} />
|
|
</PaneFocusProvider>
|
|
</PaneProvider>
|
|
);
|
|
}
|