npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@principal-ade/panel-layouts

v0.3.0

Published

Pre-built panel layout components and workspace management for the Panel Framework

Readme

@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.

🎯 Purpose

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

📦 What This Package Provides

Re-exported Components (from @principal-ade/panels)

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

Our Value-Add: Hooks (Extracted from electron-app)

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

Our Value-Add: Services (Extracted from electron-app)

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

Our Value-Add: Pre-built Layouts (Extracted from electron-app)

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

📋 Type Definitions

Re-exported from @principal-ade/panels

// 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[];
}

Our New Types

// 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';
}

🚀 Proposed Usage

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 (
    <PanelHarness context={context} actions={actions} events={events}>
      <FeedViewLayout
        defaultSizes={sizes}
        collapsed={collapsed}
        onResize={handleResize}
      />
    </PanelHarness>
  );
}

Using ConfigurablePanelLayout Directly

import { ConfigurablePanelLayout } from '@principal-ade/panel-layouts';

<ConfigurablePanelLayout
  panels={[
    { id: 'git-changes', content: <GitChangesPanel /> },
    { id: 'readme', content: <ReadmePanel /> },
    { id: 'commits', content: <CommitsPanel /> },
  ]}
  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)}
/>

Using Workspace Presets

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 }
});

📁 Package Structure

@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.

🔗 Dependencies

{
  "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
  • We re-export components from @principal-ade/panels for convenience
  • We add our own persistence, workspace management, and preset layouts on top

🎨 Design Principles

1. Layered Architecture

  • @principal-ade/panel-framework-core: Panel registration, lifecycle, events
  • @principal-ade/panels: Layout primitives, resizing, collapsing, theming
  • @principal-ade/panel-layouts (this package): Persistence, workspaces, presets

2. Reuse Over Rebuild

We build on top of proven components (@principal-ade/panels) 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. Optional Dependency

Users can use @principal-ade/panel-framework-core + @principal-ade/panels directly if they don't need workspace management.

4. Composable

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

5. Persistence-Ready

Built-in support for saving/loading layout state to:

  • localStorage (web)
  • User preferences (Electron via IPC)
  • Remote storage (optional extension point)

📝 Implementation Steps

Phase 1: Package Setup and Re-exports

  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 CSS

What we're doing: Setting up the foundation and making @principal-ade/panels components available through our package.

Phase 2: Extract Persistence Hook (High Priority)

  1. Extract usePanelPersistence from electron-app
  2. Adapt for both web (localStorage) and Electron (IPC) environments
  3. Add type definitions
  4. Write unit tests

Source File:

  • /Users/griever/Developer/electron-app/src/renderer/hooks/usePanelPersistence.ts

What we're doing: Adding the state persistence layer that @principal-ade/panels doesn't provide.

Phase 3: Extract Workspace Service

  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 tests

Source File:

  • /Users/griever/Developer/electron-app/src/renderer/services/WorkspaceLayoutService.ts

What we're doing: Adding workspace management for quick layout switching.

Phase 4: Create Pre-built Layout Components

  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 case

Source Files:

  • /Users/griever/Developer/electron-app/src/renderer/principal-window/views/FeedView/FeedView.tsx
  • Workspace definitions from WorkspaceLayoutService

What we're doing: Creating ready-to-use layout components for common use cases.

Phase 5: Documentation and Publishing

  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:

- 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.

Implementation Progress:

  • ✅ 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

Architecture Decision:

We're reusing @principal-ade/[email protected] 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

What's Working Now:

# Development
npm run dev          # Start Vite dev server
npm run storybook    # Start Storybook on :6006

# Quality 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 ✅

Package Contents:

  • Re-exported: All components from @principal-ade/panels
  • New: usePanelPersistence hook with localStorage adapter
  • New: Comprehensive TypeScript types
  • New: Interactive Storybook documentation

Reference Files (electron-app):

  • 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