Flutter Mac Dock

A macOS-style dock widget for Flutter with smooth magnification on hover, glassmorphism background, and animated tooltips.

Flutter Mac Dock Demo

๐ŸŒ Live Demo

Zero external dependencies โ€” only requires the Flutter SDK.

Features

  • ๐Ÿ” Cosine-based magnification โ€” Icons smoothly scale as the cursor approaches, just like the macOS dock
  • ๐ŸชŸ Glassmorphism background โ€” Blurred, translucent container with configurable opacity
  • ๐Ÿ’ฌ Animated tooltips โ€” Labels appear above hovered items with a frosted-glass effect
  • ๐ŸŽ Pixel-perfect Apple squircle โ€” Uses Flutter's native RoundedSuperellipseBorder for icon clipping that matches the exact macOS/iOS icon shape
  • ๐ŸŽจ Fully customizable โ€” Control icon size, magnification intensity, range, colors, and more via DockStyle
  • โž— Dividers โ€” Optional separators between item groups
  • โšก Zero dependencies โ€” Pure Flutter, no external packages required
  • ๐Ÿ“ฑ Framework-agnostic โ€” Works with Provider, Riverpod, Bloc, or plain setState

Installation

Add this to your pubspec.yaml:

dependencies:
  flutter_mac_dock: ^0.1.0

Then run:

flutter pub get

Quick Start

The icon property accepts any Widget โ€” use Icon, Image.asset, Image.network, or any custom widget:

import 'package:flutter_mac_dock/flutter_mac_dock.dart';

// Using Material Icons for a quick prototype
MacDock(
  items: [
    DockItem(
      label: 'Finder',
      icon: Icon(Icons.folder, color: Colors.blue),
      onTap: () => print('Finder tapped'),
    ),
    DockItem(
      label: 'Safari',
      icon: Icon(Icons.language, color: Colors.blue),
      onTap: () => print('Safari tapped'),
    ),
    DockItem(
      label: 'Mail',
      icon: Icon(Icons.mail, color: Colors.blue),
      onTap: () => print('Mail tapped'),
    ),
  ],
)

Using Image Assets

For a more authentic macOS look, pass image assets as the icon widget:

MacDock(
  items: [
    DockItem(
      label: 'Finder',
      icon: Image.asset('assets/finder.webp', fit: BoxFit.cover),
    ),
    DockItem(
      label: 'Chrome',
      icon: Image.asset('assets/chrome.png', fit: BoxFit.cover),
    ),
    DockItem(
      label: 'Notes',
      icon: Image.asset('assets/notes.png', fit: BoxFit.cover),
    ),
    DockItem(
      label: 'Settings',
      icon: Image.asset('assets/settings.png', fit: BoxFit.cover),
    ),
  ],
  dividerIndices: [2],  // Divider after the 3rd item
)

Tip: Images are automatically clipped to Apple's superellipse shape โ€” no need for ClipRRect or manual rounding. Use BoxFit.cover for best results.

Customization

Use DockStyle to control the appearance:

MacDock(
  items: myItems,
  dividerIndices: [3],  // Divider after the 4th item
  style: DockStyle(
    iconSize: 56,              // Base icon size
    magnification: 0.5,        // Max magnification (50% growth)
    range: 180,                // Hover influence range in pixels
    backgroundColor: Colors.black.withOpacity(0.3),
    borderRadius: 24,
    blurSigma: 20,
    showIndicator: true,       // Selection dot below items
    indicatorColor: Colors.white,
  ),
  onItemHover: (index) {
    // React to hover changes (e.g., update a preview)
  },
)

API Reference

MacDock

Property Type Default Description
items List<DockItem> required The dock items to display
style DockStyle DockStyle() Visual configuration
dividerIndices List<int> [] Indices after which to place dividers
onItemHover ValueChanged<int?>? null Hover change callback

DockItem

Property Type Default Description
label String required Tooltip text
icon Widget required The icon widget to render
onTap VoidCallback? null Tap callback
isSelected bool false Shows selection indicator

DockStyle

Property Type Default Description
iconSize double 48.0 Base icon size
magnification double 0.8 Max magnification factor
range double 150.0 Hover influence distance
backgroundColor Color White 15% Dock background color
borderRadius double 20.0 Container border radius
blurSigma double 15.0 Glassmorphism blur intensity
showIndicator bool true Show selection dot
indicatorColor Color Colors.black87 Selection dot color

How It Works

The magnification algorithm uses a cosine curve to calculate the scale factor for each item based on its distance from the cursor:

scale = 1.0 + magnification ร— cos(distance / range ร— ฯ€/2)

This produces a smooth bell-curve falloff where the item directly under the cursor is maximally scaled, and the effect gradually diminishes to 1.0 at the edge of the range.

Icons are clipped using Flutter's native RoundedSuperellipseBorder, which renders the exact Apple superellipse shape (the same as SwiftUI's .continuous corner style) with GPU acceleration. This ensures pixel-perfect icon corners that scale smoothly during magnification.

Requirements

  • Flutter โ‰ฅ 3.32.0 (for RoundedSuperellipseBorder support)
  • Dart โ‰ฅ 3.6.0

License

MIT License โ€” see LICENSE for details.

Author

Luis Portal โ€” Portfolio ยท LinkedIn ยท GitHub

Libraries

flutter_mac_dock
A macOS-style dock widget for Flutter with smooth magnification on hover.