flumpose 0.0.2 copy "flumpose: ^0.0.2" to clipboard
flumpose: ^0.0.2 copied to clipboard

A Flutter package for declarative, const-safe UI composition.

Flumpose #

pub package License: MIT

Flumpose is a Flutter package that brings declarative, chainable widget composition to your UI code. Say goodbye to deeply nested widget trees and hello to clean, readable, and maintainable Flutter UI.

Transform verbose code like this:

Container(
  color: Colors.blue,
  child: Padding(
    padding: EdgeInsets.all(16),
    child: Align(
      alignment: Alignment.center,
      child: Text('Hello World'),
    ),
  ),
)

Into this:

Text('Hello World')
  .pad(16)
  .backgroundColor(Colors.blue)
  .alignCenter()

✨ Features #

Core Extensions #

  • πŸ”— Chainable Extensions: Fluent API for widget composition
  • 🎨 Background & Decoration: Colors, gradients, images, and custom decorations
  • πŸ“ Layout Control: Padding, margin, alignment, sizing, and constraints
  • 🎭 Transform & Clip: Rotate, scale, translate, and clip with ease
  • ✍️ Text Styling: Font size, color, weight, and style helpers
  • β™Ώ Accessibility: Semantic label extensions for better a11y
  • 🎬 Animations: Fade and other animation helpers
  • πŸ”§ Parent Wrapping: Custom parent widget injection

New Feature Extensions #

  • πŸ‘οΈ Visibility Control: Show/hide, opacity, and pointer events
  • πŸ“ Flex Layouts: Expanded, flexible, and fractional sizing
  • πŸ“š Stack & Positioning: Absolute positioning and layering
  • πŸ“± Responsive Design: Breakpoints, adaptive sizing, and screen-aware helpers
  • πŸ‘† Advanced Gestures: Pan, drag, scale, and draggable widgets
  • πŸ›‘οΈ Utilities: SafeArea, Hero, Material, Card, Sliver helpers, and more

πŸ“¦ Installation #

Add flumpose to your pubspec.yaml:

dependencies:
  flumpose: ^0.0.1

Then run:

flutter pub get

πŸš€ Quick Start #

Import the package:

import 'package:flumpose/flumpose.dart';

Now you can chain extensions on any widget:

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

class MyWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Text('Hello, Flumpose!')
      .bold()
      .fontSize(24)
      .color(Colors.white)
      .pad(20)
      .backgroundColor(Colors.blue)
      .borderRadius(BorderRadius.circular(12))
      .onTap(() => print('Tapped!'))
      .alignCenter();
  }
}

πŸ“– Usage Examples #

Layout & Spacing #

// Padding
Text('Padded').pad(16) // All sides
Text('Padded').pad(EdgeInsets.symmetric(horizontal: 20))

// Margin
Container().margin(12)
Container().margin(EdgeInsets.only(top: 8))

// Alignment
Text('Centered').alignCenter()
Text('Top Left').alignTopLeft()
Text('Bottom Right').alignBottomRight()
Text('Custom').align(Alignment.topCenter)

// Sizing
Container().width(200).height(100)
Text('Constrained').constrained(BoxConstraints(maxWidth: 300))

// Scrollable
Column(children: [...]).scrollable()
Row(children: [...]).scrollable(axis: Axis.horizontal)

Background & Decoration #

// Solid color background
Text('Blue BG').backgroundColor(Colors.blue)

// Linear gradient
Container()
  .backgroundLinearGradient(
    colors: [Colors.purple, Colors.blue],
    begin: Alignment.topLeft,
    end: Alignment.bottomRight,
  )

// Radial gradient
Container()
  .backgroundRadialGradient(
    colors: [Colors.yellow, Colors.orange],
    radius: 0.8,
  )

// Background image
Container()
  .backgroundImage(
    NetworkImage('https://example.com/image.png'),
    fit: BoxFit.cover,
  )

// Custom decoration
Container().decorated(
  BoxDecoration(
    color: Colors.white,
    boxShadow: [BoxShadow(color: Colors.black26, blurRadius: 8)],
  ),
)

Borders & Clipping #

// Border
Container()
  .border(Border.all(color: Colors.red, width: 2))

// Border radius with clip
Container()
  .borderRadius(BorderRadius.circular(16))

// Clip rounded rectangle
Image.network('url').clipRRect(BorderRadius.circular(12))

// Clip oval
Image.network('url').clipOval()

// Box shadow
Container().boxShadow(
  color: Colors.black26,
  blurRadius: 10,
  offset: Offset(0, 4),
)

// Elevation (Material)
Container().elevation(8, color: Colors.white, borderRadius: BorderRadius.circular(8))

Transform & Animation #

// Rotate (angle in radians)
Icon(Icons.refresh).rotate(0.5)

// Scale
Container().scaleWidget(1.5)

// Translate
Text('Shifted').translate(x: 10, y: 20)

// Custom transform
Container().transform(Matrix4.skewX(0.2))

// Fade animation
Container().fade(duration: Duration(milliseconds: 500))

Gestures & Interaction #

// Simple tap
Text('Click me').onTap(() => print('Tapped'))

// Double tap
Text('Double click').onDoubleTap(() => print('Double tapped'))

// Long press
Text('Hold me').onLongPress(() => print('Long pressed'))

// Material ripple effect
Container()
  .ripple(
    () => print('Ripple tapped'),
    borderRadius: BorderRadius.circular(8),
  )

// Multiple gestures
Container().gestures(
  onTap: () => print('Tap'),
  onLongPress: () => print('Long press'),
)

Text Styling #

Text('Styled Text')
  .fontSize(20)
  .color(Colors.blue)
  .bold()
  .italic()

// Chain multiple styles
Text('Hello')
  .fontSize(18)
  .textColor(Colors.red)
  .bold()

Visibility Control #

// Conditional visibility
Text('Visible').visible(true)
Text('Hidden').hide()
Text('Shown').show()
Text('Conditional').showIf(userLoggedIn)

// Opacity control
Container().opacity(0.5)
Text('Semi-transparent').semiTransparent() // 50% opacity
Image.asset('logo.png').mostlyTransparent() // 25% opacity

// Pointer events
Container().ignorePointer() // Non-interactive
Container().absorbPointer() // Blocks events from widgets behind

Flex & Responsive Layouts #

// Expanded and Flexible
Container().expanded() // flex: 1
Container().expanded(flex: 2)
Container().flexible(flex: 2, fit: FlexFit.loose)

// Fractional sizing
Container().fractionalSize(widthFactor: 0.5, heightFactor: 0.8)

// Aspect ratios
Image.network('photo.jpg').square() // 1:1
Video().aspect16x9() // 16:9 widescreen
Image.asset('portrait.jpg').aspect4x3() // 4:3

// Fitted boxes
Image.network('large.jpg').fitContain() // Fit within bounds
Container().fitCover() // Cover entire area
Widget().fitScaleDown() // Scale down only

Stack & Positioning #

// Positioned within Stack
Stack(
  children: [
    Background(),
    Overlay().positionedTopRight(top: 16, right: 16),
    Logo().positionedBottomLeft(bottom: 20, left: 20),
    Badge().positioned(left: 100, top: 50),
    FullscreenOverlay().positionedFill(),
  ],
)

// Stack builders
Container(color: Colors.blue).stack(
  children: [
    Icon(Icons.star).positionedTopRight(),
    Text('Overlay').positionedCenter(),
  ],
)

// Layer helpers
Background().withOverlay(Foreground())
Logo().onTopOf(BackgroundImage())

// IndexedStack (for tabs)
[HomePage(), ProfilePage(), SettingsPage()]
  .indexedStack(index: currentTabIndex)

Responsive Design #

// Breakpoint-based visibility
Widget().onlyMobile() // Shows only on mobile (<600dp)
Widget().onlyTablet() // Shows only on tablet (600-900dp)
Widget().onlyDesktop() // Shows only on desktop (>=900dp)

// Adaptive sizing
Container().adaptiveSize(
  mobile: 100,
  tablet: 150,
  desktop: 200,
)

// Screen scaling
Logo().scaleWithScreen(
  baseWidth: 375,
  maxScale: 1.5,
  minScale: 0.8,
)

// Constrained layouts
Content().maxWidthBox(600) // Max 600dp width, centered

// Responsive padding
Container().responsivePadding(
  mobilePadding: 16,
  tabletPadding: 32,
  desktopPadding: 64,
)

// BuildContext helpers
Builder(builder: (context) {
  final isMobile = context.isMobile;
  final screenWidth = context.screenWidth;
  
  final fontSize = context.responsiveValue(
    mobile: 14.0,
    tablet: 16.0,
    desktop: 18.0,
  );
  
  return Text('Responsive').fontSize(fontSize);
})

Advanced Gestures #

// Pan gestures
Container().onPan(
  onPanStart: (details) => print('Pan started'),
  onPanUpdate: (details) => print('Panning: ${details.delta}'),
  onPanEnd: (details) => print('Pan ended'),
)

// Drag gestures
Container().onHorizontalDrag(
  onUpdate: (details) => print('Dragging X: ${details.delta.dx}'),
)

Container().onVerticalDrag(
  onUpdate: (details) => print('Dragging Y: ${details.delta.dy}'),
)

// Scale gestures (pinch to zoom)
Image.asset('photo.jpg').onScale(
  onScaleUpdate: (details) {
    print('Scale: ${details.scale}');
    print('Rotation: ${details.rotation}');
  },
)

// Draggable
Container().draggable<String>(
  data: 'item-id',
  feedback: Container(color: Colors.blue.withOpacity(0.5)),
  onDragStarted: () => print('Drag started'),
)

// Tap with position
Widget().onTapWithPosition(
  onTapDown: (details) {
    print('Tapped at: ${details.localPosition}');
  },
)

Utilities #

// SafeArea
Content().safeArea() // All edges
Header().safeTop() // Top only (status bar)
NavBar().safeBottom() // Bottom only (nav bar)
Content().safeHorizontal() // Left and right only

// Hero animations
Image.network('photo.jpg').hero(tag: 'photo-hero')

// Material wrappers
Widget().material(color: Colors.white, elevation: 4)
Content().card(elevation: 2, margin: EdgeInsets.all(8))

// Slivers
Container().toSliverBox() // SliverToBoxAdapter
[Widget1(), Widget2()].toSliverList()
[Item1(), Item2()].toSliverGrid(crossAxisCount: 2)

// Scaffold
Content().scaffold(
  appBar: AppBar(title: Text('Title')),
  floatingActionButton: FloatingActionButton(
    onPressed: () {},
    child: Icon(Icons.add),
  ),
)

// Keyboard dismissal
Form().dismissKeyboard() // Tap anywhere to dismiss

// Rotation
Icon(Icons.arrow_forward).rotatedBox(1) // 90Β° clockwise

Accessibility #

// Add semantic label
Icon(Icons.home)
  .semanticsLabel('Home button')

// Exclude child semantics
Container()
  .semanticsLabel('Custom label', excludeSemantics: true)

Custom Parent Wrapping #

// Wrap with custom parent
Text('Child').parent((child) => 
  Card(child: Padding(padding: EdgeInsets.all(8), child: child))
)

πŸ“š API Reference #

Layout Extensions #

  • pad(dynamic) - Add padding (double or EdgeInsets)
  • margin(dynamic) - Add margin (double or EdgeInsets)
  • alignCenter(), alignTopLeft(), alignBottomRight() - Quick alignments
  • align(Alignment) - Custom alignment
  • width(double), height(double) - Set dimensions
  • constrained(BoxConstraints) - Apply constraints
  • scrollable({Axis, ScrollController}) - Make scrollable
  • overflow({Clip}) - Clip overflow

Background Extensions #

  • backgroundColor(Color) - Solid color background
  • backgroundGradient(Gradient) - Custom gradient
  • backgroundLinearGradient({colors, begin, end, ...}) - Linear gradient
  • backgroundRadialGradient({colors, center, radius, ...}) - Radial gradient
  • backgroundImage(ImageProvider, {fit, alignment}) - Background image
  • decorated(BoxDecoration) - Custom decoration

Border & Clip Extensions #

  • border(Border) - Add border
  • borderRadius(BorderRadius) - Rounded corners with clip
  • clipRRect(BorderRadius) - Clip as rounded rectangle
  • clipOval() - Clip as oval
  • elevation(double, {color, borderRadius, ...}) - Material elevation
  • boxShadow({color, blurRadius, offset}) - Box shadow

Transform Extensions #

  • rotate(double, {alignment}) - Rotate (radians)
  • scaleWidget(double, {alignment}) - Scale
  • translate({x, y}) - Translate
  • transform(Matrix4, {alignment}) - Custom transform

Gesture Extensions #

  • onTap(VoidCallback) - Tap handler
  • onDoubleTap(VoidCallback) - Double tap handler
  • onLongPress(VoidCallback) - Long press handler
  • ripple(VoidCallback?, {borderRadius}) - Material ripple
  • gestures({onTap, onLongPress}) - Multiple gestures

Text Extensions #

  • fontSize(double) - Set font size
  • color(Color) - Set text color
  • textColor(Color) - Set text color (alias)
  • bold() - Make text bold
  • italic() - Make text italic

Animation Extensions #

  • fade({duration}) - Animated opacity

Semantics Extensions #

  • semanticsLabel(String, {excludeSemantics}) - Add semantic label

Parent Extensions #

  • parent(Widget Function(Widget)) - Wrap with custom parent

Visibility Extensions #

  • visible(bool) - Control visibility
  • hide() - Hide widget (invisible)
  • show() - Show widget (visible)
  • showIf(bool) - Conditional visibility
  • opacity(double) - Set opacity
  • semiTransparent() - 50% opacity
  • mostlyTransparent() - 25% opacity
  • ignorePointer({ignoring}) - Ignore pointer events
  • absorbPointer({absorbing}) - Absorb pointer events

Flex & Layout Extensions #

  • expanded({flex}) - Wrap in Expanded
  • flexible({flex, fit}) - Wrap in Flexible
  • fractionalSize({widthFactor, heightFactor}) - Fractional sizing
  • aspectRatio(double) - Set aspect ratio
  • square() - 1:1 aspect ratio
  • aspect16x9() - 16:9 aspect ratio
  • aspect4x3() - 4:3 aspect ratio
  • fitted({fit, alignment}) - Wrap in FittedBox
  • fitContain() - BoxFit.contain
  • fitCover() - BoxFit.cover
  • fitFill() - BoxFit.fill
  • fitScaleDown() - BoxFit.scaleDown

Stack & Positioned Extensions #

  • positioned({left, top, right, bottom, width, height}) - Position in Stack
  • positionedTopLeft({top, left}) - Position at top-left
  • positionedTopRight({top, right}) - Position at top-right
  • positionedBottomLeft({bottom, left}) - Position at bottom-left
  • positionedBottomRight({bottom, right}) - Position at bottom-right
  • positionedFill() - Fill entire Stack
  • positionedDirectional(...) - RTL-aware positioning
  • positionedCenter() - Center in Stack
  • stack({children, alignment, ...}) - Create Stack
  • withOverlay(Widget) - Add overlay on top
  • onTopOf(Widget) - Place on top of background
  • indexedStack({index, alignment, ...}) - Create IndexedStack (on List

Responsive Extensions #

  • responsive({builder, maxWidth, maxHeight}) - Responsive rendering
  • onlyMobile() - Show only on mobile (<600dp)
  • onlyTablet() - Show only on tablet (600-900dp)
  • onlyDesktop() - Show only on desktop (>=900dp)
  • adaptiveSize({mobile, tablet, desktop, ...}) - Adaptive sizing
  • scaleWithScreen({baseWidth, maxScale, minScale}) - Scale with screen
  • maxWidthBox(double, {alignment}) - Constrain max width
  • responsivePadding({mobilePadding, tabletPadding, desktopPadding, ...}) - Adaptive padding
  • fillWithAspectRatio(double) - Fill with aspect ratio

BuildContext Extensions:

  • context.screenWidth - Get screen width
  • context.screenHeight - Get screen height
  • context.isMobile - Check if mobile
  • context.isTablet - Check if tablet
  • context.isDesktop - Check if desktop
  • context.responsiveValue<T>({mobile, tablet, desktop}) - Select value by screen size

Advanced Gesture Extensions #

  • onPan({onPanStart, onPanUpdate, onPanEnd, ...}) - Pan gestures
  • onHorizontalDrag({onStart, onUpdate, onEnd}) - Horizontal drag
  • onVerticalDrag({onStart, onUpdate, onEnd}) - Vertical drag
  • onScale({onScaleStart, onScaleUpdate, onScaleEnd}) - Scale gestures (pinch)
  • draggable<T>({data, feedback, ...}) - Make draggable
  • dragTarget<T>({builder, onWillAccept, onAccept, ...}) - Drag target
  • onLongPressWithDuration(...) - Long press with details
  • onTapWithPosition({onTapDown, ...}) - Tap with position

Utility Extensions #

  • safeArea({top, bottom, left, right, minimum}) - SafeArea wrapper
  • safeTop() - SafeArea for top only
  • safeBottom() - SafeArea for bottom only
  • safeHorizontal() - SafeArea for sides
  • hero({tag, createRectTween, ...}) - Hero animation
  • material({color, elevation, borderRadius, ...}) - Material wrapper
  • card({color, elevation, shape, ...}) - Card wrapper
  • baseline({baseline, baselineType}) - Baseline alignment
  • toSliverBox() - Convert to SliverToBoxAdapter
  • sliverFillRemaining({hasScrollBody, ...}) - SliverFillRemaining
  • sliverPadding(EdgeInsets) - SliverPadding
  • toSliverList() - Convert List
  • toSliverGrid({crossAxisCount, ...}) - Convert List
  • scaffold({appBar, floatingActionButton, ...}) - Scaffold wrapper
  • dismissKeyboard() - Tap to dismiss keyboard
  • rotatedBox(int) - Rotate by quarter turns

πŸ—ΊοΈ Roadmap #

Version 0.1.0 (Upcoming) #

  • βœ… Visibility extensions (visible(), hide(), opacity()) βœ…
  • βœ… Flex/Expanded helpers βœ…
  • βœ… Hero animation support βœ…
  • βœ… SafeArea and MediaQuery helpers βœ…
  • βœ… Positioned and Stack helpers βœ…
  • βœ… Responsive layout helpers βœ…
  • βœ… Advanced gesture types (pan, drag, scale) βœ…
  • βœ… Sliver extensions βœ…
  • βœ… Material/Card wrappers βœ…

Version 0.2.0 (Planned) #

  • ❌ AnimatedContainer extensions
  • ❌ Theme-aware helpers
  • ❌ Form and input extensions
  • ❌ Custom animation builders

Future Considerations #

  • ❌ More layout helpers (Wrap, Flow, etc.)
  • ❌ Enhanced accessibility features

🀝 Contributing #

Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/AmazingFeature)
  3. Commit your changes (git commit -m 'Add some AmazingFeature')
  4. Push to the branch (git push origin feature/AmazingFeature)
  5. Open a Pull Request

πŸ“„ License #

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


πŸ™ Acknowledgments #

Inspired by SwiftUI's modifier pattern and other declarative UI frameworks. Built with ❀️ for the Flutter community.


πŸ“ž Support #


Made with Flutter οΏ½οΏ½

17
likes
0
points
99
downloads

Publisher

verified publishertribestick.com

Weekly Downloads

A Flutter package for declarative, const-safe UI composition.

Repository (GitHub)
View/report issues

Documentation

Documentation

License

unknown (license)

Dependencies

flutter

More

Packages that depend on flumpose

Packages that implement flumpose