Extended Wrapper

A extended version of wrapper by toly1994.com - a Flutter package that provides customizable wrapper widgets with spine/tail designs, perfect for creating chat bubbles, tooltips, and other UI elements that need directional indicators.

Features

  • 🎨 Customizable Spines: Create wrappers with spines pointing in any direction (top, left, right, bottom)
  • 🎯 Flexible Styling: Customize colors, borders, shadows, and corner radius
  • 📐 Precise Control: Adjust spine height, angle, offset, and positioning
  • 🎭 Custom Paths: Build your own custom spine paths using the SpinePathBuilder
  • 🌟 Shadow Support: Add beautiful shadows with full BoxShadow control
  • 📱 Responsive: Works seamlessly across different screen sizes and orientations

🆚 Differences from Original Package

This package is based on the excellent wrapper package by toly1994.com, but includes significant improvements and modifications:

Enhanced Features

Feature Original wrapper extended_wrapper
Shadow System Simple elevation and shadowColor Full BoxShadow support with proper spine shadow calculation

🔧 Technical Improvements

1. Enhanced Shadow SystemMajor Improvement

The most significant enhancement in extended_wrapper is the advanced shadow system that properly handles spines:

// Original wrapper - limited shadow that doesn't work with spines
Wrapper(
  elevation: 1,
  shadowColor: Colors.grey.withAlpha(88),
  child: Text('Message'),
)
// ❌ Shadow only applies to the main container, spine appears flat

// Extended wrapper - full BoxShadow with spine shadow calculation
Wrapper(
  shadow: BoxShadow(
    color: Colors.black26,
    blurRadius: 8,
    spreadRadius: 2,
    offset: Offset(2, 2),
  ),
  child: Text('Message'),
)
// ✅ Shadow properly calculated for both container AND spine

Getting Started

Installation

Add this to your package's pubspec.yaml file:

dependencies:
  extended_wrapper: ^1.0.0

Import

import 'package:extended_wrapper/extended_wrapper.dart';

Usage

Basic Usage

Wrapper(
  color: Colors.blue,
  child: Text('Hello World!'),
)

Chat Bubble with Left Spine

Wrapper(
  spineType: SpineType.left,
  spineHeight: 12.0,
  angle: 60,
  color: Colors.blue,
  shadow: BoxShadow(
    color: Colors.black26,
    blurRadius: 8,
    offset: Offset(2, 2),
  ),
  child: Padding(
    padding: EdgeInsets.all(12),
    child: Text('This is a chat message'),
  ),
)

Tooltip with Top Spine

Wrapper(
  spineType: SpineType.top,
  spineHeight: 8.0,
  angle: 45,
  color: Colors.grey[800]!,
  radius: 8.0,
  child: Padding(
    padding: EdgeInsets.all(8),
    child: Text(
      'Tooltip text',
      style: TextStyle(color: Colors.white),
    ),
  ),
)

Custom Spine Path

Wrapper(
  spineType: SpineType.right,
  spinePathBuilder: (canvas, spineType, range) {
    return Path()
      ..moveTo(range.left, range.top)
      ..lineTo(range.right, range.center.dy)
      ..lineTo(range.left, range.bottom)
      ..close();
  },
  color: Colors.green,
  child: Text('Custom spine!'),
)

Simple Wrapper (No Spine)

Wrapper.just(
  color: Colors.orange,
  radius: 12.0,
  shadow: BoxShadow(
    color: Colors.orange.withOpacity(0.3),
    blurRadius: 12,
    spreadRadius: 2,
  ),
  child: Text('Simple wrapper'),
)

API Reference

Wrapper Properties

Property Type Default Description
spineHeight double 8.0 Height of the spine
angle double 75 Angle of the spine in degrees
radius double 5.0 Corner radius of the wrapper
offset double 15 Offset from the edge for spine positioning
spineType SpineType SpineType.left Direction of the spine
color Color Colors.green Background color
shadow BoxShadow? null Shadow configuration
strokeWidth double? null Border width (if null, no border)
formEnd bool false Position spine at the end
padding EdgeInsets EdgeInsets.all(8) Internal padding
spinePathBuilder SpinePathBuilder? null Custom spine path builder

SpineType Enum

  • SpineType.top - Spine pointing upward
  • SpineType.left - Spine pointing leftward
  • SpineType.right - Spine pointing rightward
  • SpineType.bottom - Spine pointing downward

SpinePathBuilder

typedef SpinePathBuilder = Path Function(
  Canvas canvas,
  SpineType spineType,
  Rect range,
);

Examples

Check out the example folder for a complete demonstration app showcasing various use cases and configurations.

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

License

This project is licensed under the MIT License - see the LICENSE file for details.

Libraries

extended_wrapper