Pre-built panel layout components and workspace management for the Panel Framework
npm install @principal-ade/panel-layouts> Pre-built panel layout components and workspace management for the Panel Framework
This package provides ready-to-use panel layout components, workspace presets, and persistence hooks that work with @principal-ade/panel-framework-core. Built on top of @principal-ade/panels, it adds workspace management, persistence, and pre-configured layouts from the electron-app.
While @principal-ade/panel-framework-core provides the foundation for how panels work (registration, lifecycle, events), this package handles how panels arrange on screen (layouts, resizing, workspaces).
This package = @principal-ade/panels (layout primitives) + persistence + workspace management + preset layouts
We re-export the core layout components from @principal-ade/panels for convenience:
- ConfigurablePanelLayout - Main layout component supporting 2 or 3 panel configurations
- TabGroup - Tab-based panel grouping
- PanelConfigurator - Interactive UI for configuring layouts
- AnimatedResizableLayout - Lower-level resizable layout primitive
- Types: PanelLayout, PanelSlot, PanelGroup, TabsConfig, TilesConfig
These components provide:
- Resizable panels with drag handles (powered by react-resizable-panels)
- Collapsible panels with animations
- Tab groups and tile arrangements
- Theme integration with @principal-ade/industry-theme
- 2-panel and 3-panel layout support
#### usePanelPersistence
NEW - Extracted from electron-app
Manages saving and loading panel sizes and collapsed states:
- Saves to user preferences (Electron) or localStorage (web)
- Supports both 2-panel and 3-panel layouts
- Debounced saving (500ms) to avoid excessive writes
- Handles collapse/expand animations
- Tracks last non-zero sizes for restoring after collapse
Source: /Users/griever/Developer/electron-app/src/renderer/hooks/usePanelPersistence.ts
#### useWorkspace
NEW - Convenience hook
Easy workspace management:
- Load and apply workspace presets
- Switch between workspaces
- Create custom workspaces
- React hooks API for workspace state
#### WorkspaceLayoutService
NEW - Extracted from electron-app
Manages workspace presets and configurations:
- CRUD operations for custom workspaces
- Built-in workspace presets (Feed View, Code Review, etc.)
- Per-repository workspace state tracking
- Workspace switching and persistence
Source: /Users/griever/Developer/electron-app/src/renderer/services/WorkspaceLayoutService.ts
NEW - Ready-to-use layout configurations
Ready-to-use React components wrapping ConfigurablePanelLayout with preset configurations:
#### FeedViewLayout
Three-panel layout optimized for repository exploration:
- Left Panel (20%): Projects, Stars, Social, Graphs
- Middle Panel (80%): Commits, README, Signals
- Right Panel: Collapsed by default
Source: /Users/griever/Developer/electron-app/src/renderer/principal-window/views/FeedView/FeedView.tsx
#### Other Workspace Presets (to be extracted from electron-app)
- ProjectManagementLayout - Project tracking and planning
- CodeReviewLayout - Git changes and diffs
- DocumentationLayout - README and markdown focus
- AgentWorkLayout - AI agent interaction
- QualityCheckLayout - Code quality metrics
- DrawingLayout - Excalidraw integration
- PrincipalOfficeLayout - Executive dashboard
``typescript
// Panel Layout Structure (from @principal-ade/panels)
interface PanelLayout {
left?: PanelSlot;
middle?: PanelSlot;
right?: PanelSlot;
}
// Panel Slot Configuration
type PanelSlot = string | null | PanelGroup;
interface PanelGroup {
type: 'tabs' | 'tiles';
panels: string[];
config?: TabsConfig | TilesConfig;
}
// Tabs Configuration
interface TabsConfig {
defaultActiveTab?: number;
tabPosition?: 'top' | 'bottom' | 'left' | 'right';
centered?: boolean;
activeTabIndex?: number;
onTabChange?: (index: number) => void;
}
// Tiles Configuration
interface TilesConfig {
direction?: 'horizontal' | 'vertical' | 'grid';
columns?: number;
rows?: number;
tileSizes?: number[];
}
`
`typescript
// Workspace Preset (NEW)
interface WorkspacePreset {
id: string;
name: string;
description?: string;
icon?: string;
layout: PanelLayout;
defaultSizes?: {
left?: number;
middle?: number;
right?: number;
};
collapsed?: {
left?: boolean;
right?: boolean;
};
}
// Panel Persistence Options (NEW)
interface PanelPersistenceOptions {
viewKey: string;
defaultSizes: PanelSizes | TwoPanelSizes;
collapsed: PanelCollapsed | { left?: boolean };
panelType: 'three-panel' | 'two-panel';
}
`
`typescript
import { PanelHarness, globalPanelRegistry } from '@principal-ade/panel-framework-core';
import {
FeedViewLayout,
usePanelPersistence,
WorkspaceLayoutService
} from '@principal-ade/panel-layouts';
// Register your panels
globalPanelRegistry.register({
metadata: { id: 'git-changes', name: 'Git Changes' },
component: GitChangesPanel,
});
function App() {
// Use persistence hook for saving layout state
const { sizes, collapsed, handleResize } = usePanelPersistence('my-app');
return (
collapsed={collapsed}
onResize={handleResize}
/>
);
}
`
`typescript
import { ConfigurablePanelLayout } from '@principal-ade/panel-layouts';
{ id: 'git-changes', content:
{ id: 'readme', content:
{ id: 'commits', content:
]}
layout={{
left: {
type: 'tabs',
panels: ['git-changes'],
config: { defaultActiveTab: 0, tabPosition: 'top' }
},
middle: {
type: 'tabs',
panels: ['readme', 'commits'],
config: { defaultActiveTab: 0 }
},
right: null
}}
defaultSizes={{ left: 30, middle: 70, right: 0 }}
collapsed={{ left: false, right: true }}
collapsiblePanels={{ left: true, right: false }}
showCollapseButtons={true}
onPanelResize={(sizes) => console.log('Resized:', sizes)}
/>
`
`typescript
import { WorkspaceLayoutService } from '@principal-ade/panel-layouts';
// Get built-in workspaces
const workspaces = WorkspaceLayoutService.getBuiltInWorkspaces();
// Apply a workspace
WorkspaceLayoutService.applyWorkspace('code-review', repositoryPath);
// Create custom workspace
WorkspaceLayoutService.createCustomWorkspace({
id: 'my-workflow',
name: 'My Custom Workflow',
layout: { / ... / },
defaultSizes: { left: 25, middle: 50, right: 25 }
});
`
``
@principal-ade/panel-layouts/
āāā src/
ā āāā index.ts # Main entry - re-exports from @principal-ade/panels + our code
ā āāā layouts/
ā ā āāā FeedViewLayout.tsx # Pre-built feed view
ā ā āāā ProjectManagementLayout.tsx # Project management preset
ā ā āāā CodeReviewLayout.tsx # Code review preset
ā ā āāā DocumentationLayout.tsx # Documentation preset
ā ā āāā index.ts
ā āāā hooks/
ā ā āāā usePanelPersistence.ts # Layout state persistence (extracted)
ā ā āāā useWorkspace.ts # Workspace management hook
ā ā āāā index.ts
ā āāā services/
ā ā āāā WorkspaceLayoutService.ts # Workspace CRUD operations (extracted)
ā ā āāā index.ts
ā āāā types/
ā āāā workspace.types.ts # Workspace types
ā āāā persistence.types.ts # Persistence types
ā āāā index.ts
āāā package.json
āāā tsconfig.json
āāā vite.config.ts
āāā README.md
āāā LICENSE
Note: We don't duplicate ConfigurablePanelLayout, TabGroup, etc. - we re-export them from @principal-ade/panels.
`json`
{
"peerDependencies": {
"@principal-ade/panel-framework-core": "^0.1.0",
"react": ">=18.0.0",
"react-dom": ">=18.0.0"
},
"dependencies": {
"@principal-ade/panels": "^1.0.39",
"@principal-ade/industry-theme": "^0.1.2",
"react-resizable-panels": "^3.0.0"
}
}
Architecture:
- We depend on @principal-ade/panels for layout primitives (ConfigurablePanelLayout, TabGroup, etc.)@principal-ade/panels
- depends on react-resizable-panels for resizing functionality@principal-ade/panels
- We re-export components from for convenience
- We add our own persistence, workspace management, and preset layouts on top
) rather than reinventing the wheel. This allows us to:
- Focus on high-value features (workspaces, persistence)
- Get resizing, animations, and theming for free
- Maintain compatibility with existing electron-app code$3
Users can use @principal-ade/panel-framework-core + @principal-ade/panels directly if they don't need workspace management.$3
All components are composable - users can:
- Use pre-built layouts as-is (FeedViewLayout)
- Use ConfigurablePanelLayout with custom configs
- Use @principal-ade/panels directly for full control$3
Built-in support for saving/loading layout state to:
- localStorage (web)
- User preferences (Electron via IPC)
- Remote storage (optional extension point)š Implementation Steps
$3
1. ā
Set up package structure with TypeScript and Vite
2. ā
Install @principal-ade/panels as a dependency
3. ā
Create re-export index that exposes components from @principal-ade/panels
4. ā
Configure build to output ESM/CJS with CSSWhat we're doing: Setting up the foundation and making
@principal-ade/panels components available through our package.$3
1. Extract usePanelPersistence from electron-app
2. Adapt for both web (localStorage) and Electron (IPC) environments
3. Add type definitions
4. Write unit testsSource File:
-
/Users/griever/Developer/electron-app/src/renderer/hooks/usePanelPersistence.tsWhat we're doing: Adding the state persistence layer that
@principal-ade/panels doesn't provide.$3
1. Extract WorkspaceLayoutService from electron-app
2. Adapt for both web and Electron environments
3. Define built-in workspace presets
4. Create useWorkspace convenience hook
5. Write unit testsSource File:
-
/Users/griever/Developer/electron-app/src/renderer/services/WorkspaceLayoutService.tsWhat we're doing: Adding workspace management for quick layout switching.
$3
1. Extract FeedView layout configuration
2. Create React component wrappers for each preset
3. Make them configurable and extensible
4. Document each preset's use caseSource Files:
-
/Users/griever/Developer/electron-app/src/renderer/principal-window/views/FeedView/FeedView.tsx
- Workspace definitions from WorkspaceLayoutServiceWhat we're doing: Creating ready-to-use layout components for common use cases.
$3
1. Write comprehensive usage documentation
2. Create example applications (web + Electron)
3. Add migration guide from electron-app
4. Publish to npm as @principal-ade/panel-layoutsš Integration with electron-app
Once published, the electron-app can replace its current implementation:
`diff
- import { ConfigurablePanelLayout } from '@principal-ade/panels';
- import { usePanelPersistence } from '../hooks/usePanelPersistence';
+ import { ConfigurablePanelLayout, usePanelPersistence } from '@principal-ade/panel-layouts';
`Benefits:
- Shared between web and desktop
- Community can contribute improvements
- Consistent across all applications
- Easier to maintain
š Related Packages
- @principal-ade/panel-framework-core - Core panel system (published)
- @principal-ade/panel-layouts - This package (to be implemented)
- @principal-ade/panels - Current layout implementation in electron-app
- @principal-ade/industry-theme - Theming system used by layouts
š¤ Contributing
This package is designed to be the standard layout system for Panel Framework applications. Contributions should focus on:
1. Performance - Layouts should be fast and responsive
2. Flexibility - Support various use cases and customization
3. Accessibility - Keyboard navigation, screen reader support
4. Documentation - Clear examples and API docs
š License
MIT
---
š§ Current Status
Status: š§ In Active Development
This package is being actively developed with a focus on reusing
@principal-ade/panels and adding workspace/persistence features.$3
- ā
README specification complete
- ā
Package setup and build configuration (Vite + TypeScript)
- ā
Re-exports from @principal-ade/panels (25+ components)
- ā
usePanelPersistence hook extracted and adapted
- ā
LocalStoragePersistenceAdapter for web apps
- ā
Storybook with interactive component stories
- ā
ESLint + TypeScript linting configured
- ā
Vitest test suite (14 tests passing)
- ā³ Extract WorkspaceLayoutService (next)
- ā³ Create pre-built layout components
- ā³ Additional documentation and examples
- ā³ Publish to npm$3
We're reusing @principal-ade/panels@1.0.39 as a dependency rather than rebuilding layout components. This allows us to:
- Focus on high-value features (persistence, workspaces, presets)
- Leverage proven, tested layout components
- Maintain compatibility with existing electron-app code$3
`bash
Development
npm run dev # Start Vite dev server
npm run storybook # Start Storybook on :6006Quality Checks
npm run type-check # TypeScript type checking ā
npm run lint # ESLint (2 warnings) ā
npm run test # Vitest (14/14 passing) ā
Build
npm run build # Build ESM + CJS + types ā
`$3
- Re-exported: All components from @principal-ade/panels
- New: usePanelPersistence hook with localStorage adapter
- New: Comprehensive TypeScript types
- New: Interactive Storybook documentation$3
- Persistence: /Users/griever/Developer/electron-app/src/renderer/hooks/usePanelPersistence.ts
- Workspace Service: /Users/griever/Developer/electron-app/src/renderer/services/WorkspaceLayoutService.ts
- FeedView Layout: /Users/griever/Developer/electron-app/src/renderer/principal-window/views/FeedView/FeedView.tsx`