Workspaces

This commit is contained in:
2026-02-22 00:05:29 +00:00
parent 9e9acd9631
commit 23b369c7e1
101 changed files with 701 additions and 512 deletions
@@ -6,7 +6,7 @@ type AppPickerProps = {
};
export const AppPicker = ({ registry, onSelect }: AppPickerProps) => {
const entries = Object.entries(registry).filter(([, entry]) => !entry.widget && entry.availableOnPanel !== false);
const entries = Object.entries(registry).filter(([, entry]) => entry.availableOnPanel !== false);
return (
<div className="flex flex-wrap gap-1.5 max-w-md">
@@ -3,11 +3,12 @@ import type { LayoutNode, AppRegistry, PanelComponents } from './types';
import { updateSizes } from './layout-utils';
import { WorkspaceProvider } from './WorkspaceContext';
import { WorkspaceRenderer } from './WorkspaceRenderer';
import { useAppRegistry } from 'officerdev';
type WorkspaceLayoutProps = {
layout: LayoutNode;
onLayoutChange: (layout: LayoutNode) => void;
registry: AppRegistry;
registry?: AppRegistry;
components?: PanelComponents;
workspaceId?: string;
cwd?: string;
@@ -15,7 +16,10 @@ type WorkspaceLayoutProps = {
const noop = () => {};
export const WorkspaceLayout = ({ layout, onLayoutChange, registry, components, workspaceId, cwd }: WorkspaceLayoutProps) => {
export const WorkspaceLayout = ({ layout, onLayoutChange, registry: registryProp, components, workspaceId, cwd }: WorkspaceLayoutProps) => {
const { registry: globalRegistry } = useAppRegistry();
const registry = registryProp ?? globalRegistry;
const handleResized = useCallback(
(groupId: string, sizes: number[]) => {
onLayoutChange(updateSizes(layout, groupId, sizes));
@@ -1,25 +1,26 @@
import { useState, useCallback, useEffect } from 'react';
import { flushSync } from 'react-dom';
import { ResizablePanel, ResizablePanelGroup, ResizableHandle } from '../ui/resizable';
import type { LayoutNode, AppRegistry, WorkspaceState, EphemeralPanels } from './types';
import type { LayoutNode, WorkspaceState, EphemeralPanels } from './types';
import type { DropPosition } from './layout-utils';
import { splitPanel, removePanel, setApp, updateSizes, swapPanels, movePanel, countPanels } from './layout-utils';
import { WorkspaceProvider } from './WorkspaceContext';
import { WorkspaceRenderer } from './WorkspaceRenderer';
import { useAppRegistry } from 'officerdev';
type WorkspaceViewProps = {
workspace: WorkspaceState;
registry: AppRegistry;
cwd?: string;
ephemeral?: EphemeralPanels | null;
};
const noop = () => {};
export const WorkspaceView = ({ workspace, registry, cwd = '~', ephemeral }: WorkspaceViewProps) => {
if (!workspace.isLoaded) return null;
export const WorkspaceView = ({ workspace, cwd = '~', ephemeral }: WorkspaceViewProps) => {
const { registry } = useAppRegistry();
const { value: layout, setValue: onLayoutChange } = workspace;
const layout = workspace.value;
const onLayoutChange = workspace.setValue;
const [swapSourceId, setSwapSourceId] = useState<string | null>(null);
const [dragSourceId, setDragSourceId] = useState<string | null>(null);
const [maximizedPanelId, setMaximizedPanelId] = useState<string | null>(null);
@@ -105,6 +106,8 @@ export const WorkspaceView = ({ workspace, registry, cwd = '~', ephemeral }: Wor
return () => window.removeEventListener('keydown', onKeyDown);
}, [swapSourceId, dragSourceId, maximizedPanelId, setMaximizedAnimated]);
if (!workspace.isLoaded) return null;
const baseRenderer = (
<WorkspaceRenderer
layout={layout}
@@ -53,7 +53,6 @@ export type AppRegistryEntry = {
provider?: ComponentType<{ panelId: string; children: ReactNode }>;
transparent?: boolean;
fixedHeight?: number;
widget?: boolean;
availableOnPanel?: boolean;
};