flutter_web_split_view

pub.dev License: MIT Flutter Platform Likes Pub Points

A production-ready Flutter package for resizable split-pane layouts, optimized for Flutter Web and desktop-style applications.

Build professional layouts like:

  • ๐Ÿ–ฅ๏ธ IDE-style code editors (VS Code, IntelliJ style)
  • ๐Ÿ“Š Admin dashboards with resizable panels
  • ๐Ÿ“ File explorers with sidebar + content
  • ๐Ÿ“ CMS tools with preview panes
  • ๐Ÿ“ˆ Analytics panels with filter + chart sections
  • ๐Ÿ’ฌ Chat applications (sidebar list + conversation)
  • ๐ŸŽจ Nested split workspaces for complex layouts

๐ŸŽฅ Demo

flutter_web_split_view demo

Try it live! Run the example app to see all features in action:

cd example && flutter run -d chrome

โœจ Features

Feature Description
๐Ÿ”€ Horizontal & Vertical Split views in any direction
๐Ÿ–ฑ๏ธ Draggable Divider Smooth, responsive resizing
๐Ÿ“ Min/Max Constraints Control pane size limits
๐Ÿ“Š Ratio or Pixel Sizing Flexible initial configuration
๐ŸŽฎ Controller Support Programmatic control via SplitViewController
๐Ÿ“ Collapsible Panes Toggle sidebar/panel visibility
๐ŸŽจ Custom Dividers Build your own divider UI
๐Ÿ”„ Browser Resize Aware Handles window/container resizes
๐Ÿ“Œ Fixed Pane Mode Lock a pane during resizes
๐Ÿช† Nested Split Views Build complex dashboard layouts
๐ŸŒ Web & Desktop Optimized Perfect for mouse-driven interfaces
๐Ÿ“ฑ Mobile Support Works on all platforms

๐Ÿ“ฆ Installation

Add this to your pubspec.yaml:

dependencies:
  flutter_web_split_view: ^1.0.0

Then run:

flutter pub get

๐Ÿš€ Quick Start

Basic horizontal split (sidebar + content)

import 'package:flutter/material.dart';
import 'package:flutter_web_split_view/flutter_web_split_view.dart';

class MyPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return SplitView(
      direction: Axis.horizontal,
      initialRatio: 0.25,
      minFirstPaneSize: 200,
      minSecondPaneSize: 400,
      dividerThickness: 8,
      first: const SidebarWidget(),
      second: const ContentWidget(),
    );
  }
}

๐Ÿ“š Complete Examples

1๏ธโƒฃ Basic Horizontal Split

SplitView(
  first: const SidebarWidget(),
  second: const ContentWidget(),
)

2๏ธโƒฃ Vertical Split (Top/Bottom)

SplitView(
  direction: Axis.vertical,
  initialRatio: 0.6,
  minFirstPaneSize: 150,
  minSecondPaneSize: 100,
  first: const EditorPanel(),
  second: const TerminalPanel(),
)

3๏ธโƒฃ Using a Controller (Programmatic Control)

final controller = SplitViewController(initialRatio: 0.35);

// In your widget:
SplitView(
  controller: controller,
  first: const Sidebar(),
  second: const Content(),
)

// Control from anywhere:
controller.setRatio(0.5);        // Set ratio
controller.setFirstPaneSize(320); // Set pixel size
controller.collapseFirst();       // Collapse first pane
controller.expand();              // Expand collapsed panes
controller.toggleFirst();         // Toggle collapse

4๏ธโƒฃ Collapsible Sidebar

SplitView(
  initialRatio: 0.25,
  collapsibleFirst: true,
  collapseThreshold: 100,
  minFirstPaneSize: 80,
  minSecondPaneSize: 320,
  first: const Sidebar(),
  second: const Content(),
)

5๏ธโƒฃ Custom Divider

// Simple color customization
SplitView(
  dividerThickness: 12,
  dividerColor: Colors.blue,
  first: const Sidebar(),
  second: const Content(),
)

// Fully custom divider
SplitView(
  dividerBuilder: (context, direction, thickness, isCollapsed, onToggle) {
    return GestureDetector(
      onTap: onToggle,
      child: Container(
        color: isCollapsed ? Colors.red : Colors.blue,
        child: Center(
          child: Icon(
            direction == Axis.horizontal
                ? (isCollapsed ? Icons.chevron_right : Icons.drag_indicator)
                : (isCollapsed ? Icons.expand_more : Icons.drag_handle),
          ),
        ),
      ),
    );
  },
  first: const Sidebar(),
  second: const Content(),
)

6๏ธโƒฃ Dashboard Layout (Nested)

SplitView(
  initialRatio: 0.22,
  minFirstPaneSize: 220,
  minSecondPaneSize: 500,
  first: const NavigationPanel(),
  second: SplitView(
    direction: Axis.vertical,
    initialRatio: 0.7,
    minFirstPaneSize: 300,
    minSecondPaneSize: 180,
    first: const AnalyticsWorkspace(),
    second: const ActivityPanel(),
  ),
)

7๏ธโƒฃ Persist Layout Preferences

SplitView(
  onRatioChanged: (ratio) {
    // Save to SharedPreferences, Hive, etc.
    prefs.setDouble('split_ratio', ratio);
  },
  onSizeChanged: (first, second, total) {
    print('First: $first, Second: $second, Total: $total');
  },
  first: const Sidebar(),
  second: const Content(),
)

โš™๏ธ API Reference

SplitView

Parameter Type Default Description
first Widget required First (left/top) pane widget
second Widget required Second (right/bottom) pane widget
direction Axis Axis.horizontal Split direction
initialRatio double 0.5 Initial ratio of first pane (0.0โ€“1.0)
initialFirstPaneSize double? 0.0 Initial first pane size in pixels (takes precedence over ratio)
minFirstPaneSize double 0.0 Minimum first pane size
maxFirstPaneSize double double.infinity Maximum first pane size
minSecondPaneSize double 0.0 Minimum second pane size
maxSecondPaneSize double double.infinity Maximum second pane size
dividerThickness double 8.0 Divider thickness in pixels
dividerColor Color? null Divider color (default: theme divider color)
dividerBuilder SplitViewDividerBuilder? null Custom divider widget builder
onRatioChanged ValueChanged<double>? null Called when ratio changes
onSizeChanged void Function(double, double, double)? null Called when pane sizes change
controller SplitViewController? null External controller
fixedPane SplitViewFixedPane SplitViewFixedPane.none Which pane stays fixed during resize
collapsibleFirst bool false Allow first pane to collapse
collapsibleSecond bool false Allow second pane to collapse
collapseThreshold double 48.0 Pixel threshold for collapse

SplitViewController

Properties

Property Type Description
ratio double Current ratio of first pane (0.0โ€“1.0)
firstPaneSize double Current first pane size in pixels
isFirstCollapsed bool Whether first pane is collapsed
isSecondCollapsed bool Whether second pane is collapsed
isCollapsed bool Whether any pane is collapsed

Methods

Method Description
setRatio(double ratio) Set the pane ratio (0.0โ€“1.0)
setFirstPaneSize(double size) Set first pane size in pixels
collapseFirst() Collapse the first pane
collapseSecond() Collapse the second pane
expand() Expand all collapsed panes
toggleFirst() Toggle first pane collapse
toggleSecond() Toggle second pane collapse

SplitViewFixedPane

Value Description
none Both panes resize proportionally (default)
first First pane stays fixed during resize
second Second pane stays fixed during resize

๐Ÿ’ก Best Practices

1. Set Minimum Sizes

Always provide sensible minimum sizes so panes remain usable:

SplitView(
  minFirstPaneSize: 220,  // Sidebar min width
  minSecondPaneSize: 320, // Content min width
  first: const Sidebar(),
  second: const Content(),
)

2. Use Controllers for Dashboards

Controllers are perfect for:

  • Restoring saved layout preferences
  • Programmatic collapse/expand
  • Dashboard workspace layouts
  • IDE-like interfaces

3. Persist User Preferences

Save layout state for returning users:

SplitView(
  onRatioChanged: (ratio) {
    // Save to SharedPreferences
    prefs.setDouble('layout_ratio', ratio);
  },
  // ...
)

4. Nest Carefully

Nested splits work great for complex layouts. Keep constraints realistic to avoid cramped UIs.


๐Ÿงช Testing

Run the test suite:

flutter test

Run static analysis:

flutter analyze

๐Ÿ“ฑ Platform Support

Platform Support Level Notes
Web โœ… Primary Optimized for Flutter Web
macOS โœ… Full Perfect for desktop apps
Windows โœ… Full Perfect for desktop apps
Linux โœ… Full Perfect for desktop apps
iOS โœ… Supported Works but touch interactions differ
Android โœ… Supported Works but touch interactions differ

โš ๏ธ Notes & Limitations

  • Optimized for Web & Desktop: Primary design target is mouse/trackpad interfaces
  • Mobile is supported: Touch works, but drag precision is limited
  • Deep nesting: Very deep nesting may increase layout complexity

๐Ÿค Contributing

Contributions are welcome! Please see CONTRIBUTING.md for guidelines.

Quick contribution steps:

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Make your changes
  4. Add tests for new functionality
  5. Run flutter analyze && flutter test
  6. Commit your changes
  7. Open a Pull Request

๐Ÿ“„ License

MIT License โ€” see LICENSE for details.


๐Ÿ“ฆ Changelog

See CHANGELOG.md for release history.


๐Ÿ’ฌ Community & Support


Made with โค๏ธ for the Flutter community

If this package helped you, please consider giving it a like on pub.dev โญ

Libraries

flutter_web_split_view
A production-grade split-pane / resizable layout widget for Flutter Web and desktop.