dock_panel 0.1.1 copy "dock_panel: ^0.1.1" to clipboard
dock_panel: ^0.1.1 copied to clipboard

A dockable, splittable, and draggable panel system for Flutter. Build IDE-like layouts with drag-and-drop tab docking, resizable splits, panel maximize/restore, and persistent layout state. Powered by [...]

dock_panel #

pub package License: BSD-3

A dockable, splittable, and draggable panel system for Flutter. Build IDE-like layouts with drag-and-drop tab docking, resizable splits, panel maximize/restore, and persistent layout state.

Powered by Riverpod for state management.

Demo Layout

Features #

  • Drag & Drop Docking — Drag tabs to dock panels left, right, top, bottom, or as a new tab
  • Resizable Splits — Drag dividers to resize panel areas with smooth hover highlighting
  • Tab Reordering — Drag tabs within the same group to reorder them
  • Panel Maximize/Restore — Double-click or use the maximize button to fullscreen a panel
  • Animated Indicators — Smooth animated drop zones and drag feedback
  • Themeable — Full control over colors, tab shapes, and divider styles
  • Persistent Layout — Save and restore layout state via a pluggable storage interface
  • Keyboard Shortcuts — Extensible shortcut system for split/merge operations
  • Zero Platform Dependencies — Pure Flutter core, works on desktop, web, and mobile

Installation #

dependencies:
  dock_panel: ^latest
flutter pub add dock_panel

Quick Start #

import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:dock_panel/dock_panel.dart';

void main() {
  runApp(const ProviderScope(child: MyApp()));
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: const DockDemo(),
    );
  }
}

class DockDemo extends ConsumerStatefulWidget {
  const DockDemo({super.key});

  @override
  ConsumerState<DockDemo> createState() => _DockDemoState();
}

class _DockDemoState extends ConsumerState<DockDemo> {
  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance.addPostFrameCallback((_) {
      final manager = ref.read(dockManagerProvider.notifier);

      manager.addPanel(DockPanel(
        id: 'explorer',
        title: 'Explorer',
        icon: Icons.folder,
        builder: (_) => const Center(child: Text('File Explorer')),
      ));

      manager.addPanel(DockPanel(
        id: 'editor',
        title: 'main.dart',
        icon: Icons.code,
        builder: (_) => const Center(child: Text('Code Editor')),
      ));

      manager.addPanel(DockPanel(
        id: 'terminal',
        title: 'Terminal',
        icon: Icons.terminal,
        builder: (_) => const Center(child: Text('Terminal')),
      ));

      // Create IDE-like layout: explorer left, terminal bottom
      manager.movePanel('terminal', 'explorer', DockPosition.bottom);
      manager.movePanel('explorer', 'editor', DockPosition.left);
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: DockTheme(
        data: const DockThemeData(), // or DockThemeData.light
        child: const DockArea(),
      ),
    );
  }
}

Core Concepts #

Layout Tree #

The layout is a tree structure:

DockArea (root widget)
  └─ DockNode (recursive)
       ├─ DockSplit  — splits space along an axis, holds children + flex ratios
       └─ DockGroup  — holds tabbed panels, one active at a time
            └─ DockPanel — a single panel (id, title, icon, builder)

DockManager (Riverpod Notifier) #

All layout mutations go through DockManager:

final manager = ref.read(dockManagerProvider.notifier);

// Add a panel
manager.addPanel(DockPanel(
  id: 'my_panel',
  title: 'My Panel',
  builder: (_) => const MyWidget(),
));

// Move panel to create a split
manager.movePanel('my_panel', 'target_group_id', DockPosition.right);

// Remove a panel
manager.removePanel('my_panel');

// Maximize / restore
manager.toggleMaximize('my_panel');

// Reorder tabs within a group
manager.reorderPanel('group_id', 0, 2);

Theming #

DockTheme(
  data: DockThemeData(
    backgroundColor: Colors.grey[900]!,
    tabBarColor: Colors.grey[850]!,
    activeTabColor: Colors.grey[900]!,
    dividerColor: Colors.grey[700]!,
    dropIndicatorColor: Colors.blue.withOpacity(0.3),
    tabShape: DockTabShape.rounded,
    dividerThickness: 4.0,
    tabHeight: 36.0,
  ),
  child: const DockArea(),
)

Built-in presets: DockThemeData() (dark) and DockThemeData.light.

Persistent Layout #

Implement DockStorage to save/restore layouts:

class MyStorage implements DockStorage {
  @override
  FutureOr<Map<String, dynamic>?> read() async {
    final json = prefs.getString('dock_layout');
    return json != null ? jsonDecode(json) : null;
  }

  @override
  FutureOr<void> write(Map<String, dynamic> data) async {
    await prefs.setString('dock_layout', jsonEncode(data));
  }

  @override
  FutureOr<void> clear() async {
    await prefs.remove('dock_layout');
  }
}

// Usage
final manager = ref.read(dockManagerProvider.notifier);
manager.setStorage(MyStorage());
await manager.restore(); // Load saved layout

API Reference #

Widgets #

Widget Description
DockArea Root widget that renders the layout tree
DockTheme Provides theme data to descendant dock widgets

Models #

Class Description
DockPanel Defines a panel: id, title, icon, builder, closable
DockGroup A group of tabbed panels
DockSplit A split container with axis and flex ratios
DockLayout Root layout state (root node + maximized panel id)

Enums #

Enum Values
DockAxis horizontal, vertical
DockPosition top, bottom, left, right, center
DockTabShape square, rounded, pill

Providers #

Provider Type
dockManagerProvider NotifierProvider<DockManager, DockLayout>

Screenshots #

IDE Layout Drag & Drop
Layout & Drag Max

Example #

See the full example in lib/main.dart — an IDE-like demo with file explorer, code editor, terminal, output, problems, and outline panels.

cd dock_panel
flutter run -d windows  # or -d chrome

Roadmap #

  • ❌ Multi-window support (OS-level detachable panels via Flutter windowing API)
  • ❌ Keyboard shortcuts (Ctrl+\ split, Ctrl+Shift+\ merge)
  • ❌ Panel minimize to sidebar
  • ❌ Layout presets / templates
  • ❌ Activity bar integration

License #

BSD 3-Clause License. See LICENSE for details.

2
likes
130
points
178
downloads
screenshot

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

A dockable, splittable, and draggable panel system for Flutter. Build IDE-like layouts with drag-and-drop tab docking, resizable splits, panel maximize/restore, and persistent layout state. Powered by Riverpod.

Repository (GitHub)
View/report issues

Topics

#ui #layout #desktop #docking #panel

License

BSD-3-Clause (license)

Dependencies

collection, flutter, flutter_riverpod, riverpod_annotation, uuid

More

Packages that depend on dock_panel