Skip to content

jozzdart/exui

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

exui logo

Everything your widgets wish they had.

Accelerate your Flutter UI development, without compromising clarity.
exui helps you build clean, maintainable UIs faster, with no wrappers and zero boilerplate.

exui is a lightweight, zero-dependency extension library for Flutter that enhances your UI code with expressive, chainable utilities. It streamlines common layout and styling patterns using pure Dart and Flutter, no reliance on Material, Cupertino, or third-party frameworks.

Designed to work seamlessly in any project, exui makes your widget code more concise, readable, and efficient, all while keeping full control over your widget tree.

βœ… Features

  • Extensions - for most used Flutter widgets. Same names, same behavior.
  • Lightweight and efficient - wraps existing widgets without creating new classes.
  • Actively maintained - Production-ready and continuously evolving.
  • Zero dependencies - Pure Dart. No bloat. Add it to any project safely.
  • Battle-tested - backed by hundreds of unit tests to ensure safety and reliability.
  • Exceptional documentation - every extension is well documented with clear examples and fast navigation.

✨ All exui Extensions:

Each section below links to detailed documentation for a specific extension group. (Emojis only added to distinguish easily between extensions)

Layout Manipulation

πŸ“ padding - Quickly Add Padding
🎯 center - Center Widgets
↔️ expanded - Fill Available Space
🧬 flex - fast Flexibles
πŸ“ align - Position Widgets
πŸ“ positioned - Position Inside a Stack
πŸ”³ intrinsic - Size Widgets
βž– margin - Add Outer Spacing

Layout Creation

↕️ gap - Performant gaps
🧱 row / column - Rapid Layouts
🧭 row* / column* - Rapid Aligned Layouts
🧊 stack - Overlay Widgets

Visibility, Transitions & Interactions

πŸ‘οΈ visible - Conditional Visibility
🌫️ opacity - Widget Transparency
πŸ“± safeArea - SafeArea Padding
πŸ‘† gesture - Detect Gestures
🦸 hero - Shared Element Transitions

Containers & Effects

πŸ“¦ sizedBox - Put in a SizedBox
🚧 constrained - Limit Widget Sizes
πŸŸ₯ coloredBox - Wrap in a Colored Box
🎨 decoratedBox - Borders, Gradients & Effects
βœ‚οΈ clip - Clip Widgets into Shapes
πŸͺž fittedBox - Fit Widgets

Widget Creation

πŸ“ text - String to Widget
πŸŽ›οΈ styled text - Style Text
πŸ”£ icon - Create and Style Icons

exui is built on pure Flutter (flutter/widgets.dart) and avoids bundling unnecessary Material or Cupertino designs by default. For convenience, optional libraries are provided for those who want seamless integration with Flutter’s built-in design systems.

exui Libraries

Library Description
exui/exui.dart Core extensions for pure Flutter. Lightweight and universal.
exui/material.dart Adds extensions tailored to Material widgets and components.
exui/cupertino.dart Adds extensions for Cupertino widgets and iOS-style components.

Cupertino Extensions (Apple)

Material Extensions (Google)


exui Vision

exui is a practical toolkit for Flutter UI development β€” focused on saving time, reducing boilerplate, and writing layout code that’s readable, consistent, and fun.

This isn’t about replacing widgets β€” it’s about using concise, chainable extensions to help you build better UIs faster. You stay in full control of your widget tree and design system.

Whether you're working on layout, spacing, visibility, or sizing, exui gives you expressive helpers for the most common tasks β€” with zero dependencies and seamless integration into any codebase.

Here are just a few examples:


πŸ“ Padding

With exui:

Text("Hello").paddingAll(16)

Without:

Padding(
  padding: EdgeInsets.all(16),
  child: Text("Hello"),
)

With additional extensions for quickly adding specific padding: paddingHorizontal, paddingVertical, paddingOnly, paddingSymmetric, paddingLeft, paddingRight, paddingTop, paddingBottom


↔️ Expanded

With exui:

Text("Stretch me").expanded3

Without:

Expanded(
  flex: 3,
  child: Text("Stretch me"),
)

With additional extensions for quickly adding specific flex values: expanded2, expanded3, expanded4, expanded5, expanded6, expanded7, expanded8 or expandedFlex(int)


🎯 Center

With exui:

Icon(Icons.star).center()

Without:

Center(
  child: Icon(Icons.star),
)

With additional extensions for quickly adding specific center factors: centerWidth(double), centerHeight(double) or with parameters center({widthFactor, heightFactor})


↕️ Gaps

With exui:

Column(
  children: [
    Text("A"),
    16.gapColumn,
    Text("B"),
  ],
)

Without:

Column(
  children: [
    Text("A"),
    SizedBox(height: 16),
    Text("B"),
  ],
)

With additional extensions for quickly adding specific gap values: gapRow, gapColumn, gapVertical, gapHorizontal etc.


πŸ‘οΈ Visibility

With exui:

Text("Visible?").visibleIf(showText)

Without:

showText ? Text("Visible?") : const SizedBox.shrink()

With additional extensions for quickly adding specific visibility conditions: hide() visibleIfNot(bool) or visibleIfNull(bool) and more.


🚧 Constraints

With exui:

Image.asset("logo.png").maxWidth(200)

Without:

ConstrainedBox(
  constraints: BoxConstraints(maxWidth: 200),
  child: Image.asset("logo.png"),
)

With additional extensions for quickly adding specific constraints: constrainedWidth, constrainedHeight, minWidth, maxWidth, minHeight, maxHeight or with parameters constrained({minWidth, maxWidth, minHeight, maxHeight}) or constrainedBox(BoxConstraints)


These are just a few of the 200+ utilities in exui. Every method is chainable, production-safe, and built with clarity in mind.

From layout to constraints, visibility to spacing β€” exui keeps your UI code clean, fast, and Flutter-native.

Welcome to exui, I hope it'll save you time like it did for me (:


πŸ“ padding β€” Add Padding to Any Widget

Apply padding effortlessly with readable, chainable methods. These extensions wrap your widget in a Padding widget using concise, expressive syntax.

  • padding(EdgeInsets) β€” Use any EdgeInsets object directly.
  • paddingAll(double) β€” Uniform padding on all sides.
  • paddingOnly({left, top, right, bottom}) β€” Custom padding per side.
  • paddingSymmetric({horizontal, vertical}) β€” Padding for x/y axes.
  • paddingHorizontal(double) β€” Shorthand for horizontal-only padding.
  • paddingVertical(double) β€” Shorthand for vertical-only padding.
  • Per-side utilities:
    • paddingLeft(double)
    • paddingRight(double)
    • paddingTop(double)
    • paddingBottom(double)

All methods return a wrapped Padding widget and can be freely chained with other extensions.

πŸ§ͺ Examples

// 12px padding on all sides
MyWidget().paddingAll(12);
// 16px left and right, 8px top and bottom
MyWidget().paddingSymmetric(horizontal: 16, vertical: 8);
// 10px padding only on the left
MyWidget().paddingLeft(10);
// Custom per-side padding
MyWidget().paddingOnly(left: 8, top: 4, bottom: 12);

πŸ’‘ Why use this? Instead of writing:

Padding(
  padding: EdgeInsets.symmetric(horizontal: 16),
  child: MyWidget(),
)

Just write:

MyWidget().paddingHorizontal(16)

‴️ Back β†’ All exui Extensions


🎯 center β€” Center Your Widget with Optional Factors

Effortlessly center any widget with precise control over layout behavior. These extensions wrap your widget in a Center and offer intuitive access to widthFactor and heightFactor when needed.

  • center({widthFactor, heightFactor}) β€” Fully customizable centering.
  • centerWidth(double?) β€” Center with horizontal shrink-wrapping only.
  • centerHeight(double?) β€” Center with vertical shrink-wrapping only.

All methods return a Center widget and can be seamlessly chained with other extensions.

πŸ§ͺ Examples

// Center without size constraints
MyWidget().center();
// Center and shrink-wrap width only
MyWidget().centerWidth(1);
// Center and shrink-wrap height only
MyWidget().centerHeight(1);
// Fully customized centering
MyWidget().center(widthFactor: 0.8, heightFactor: 0.5);

πŸ’‘ Instead of writing:

Center(
  widthFactor: 1,
  child: MyWidget(),
)

Just write:

MyWidget().centerWidth(1)

‴️ Back β†’ All exui Extensions


↔️ expanded - Make Widgets Fill Available Space

Add layout flexibility with zero boilerplate. These extensions wrap your widget in an Expanded, allowing you to quickly define how much space it should take relative to its siblings.

  • expandedFlex([int flex = 1]) β€” Wraps the widget in Expanded with an optional flex.
  • expanded1 β€” Shorthand for Expanded(flex: 1).
  • Predefined shorthand getters for fixed flex values:
    expanded2, expanded3, expanded4, expanded5, expanded6, expanded7, expanded8

Use them in Row, Column, or Flex to control space distribution without nesting or repetition.

πŸ§ͺ Examples

// Flex: 1 (default)
MyWidget().expanded1;
// Flex: 2
MyWidget().expanded2;
// Flex: 5
MyWidget().expandedFlex(5);

πŸ’‘ Instead of writing:

Expanded(
  flex: 3,
  child: MyWidget(),
)

Just write:

MyWidget().expanded3

‴️ Back β†’ All exui Extensions


🧬 flex β€” Flexible Layouts with Fine-Tuned Control

Wrap any widget in a Flexible with full control over flex and fit. These extensions reduce verbosity while giving you precise layout behavior in Row, Column, or Flex widgets.

  • flex({int flex, FlexFit fit}) β€” Custom flex and fit values (default: flex: 1, fit: FlexFit.loose)
  • flexLoose(int) β€” Loose-fit shortcut
  • flexTight(int) β€” Tight-fit shortcut
  • Predefined flex shortcuts (default fit: loose):
    flex2(), flex3(), flex4(), flex5(), flex6(), flex7(), flex8()

All methods return a Flexible widget and are safe to chain with other layout or styling extensions.

πŸ§ͺ Examples

// Default: flex 1, loose fit
MyWidget().flex();
// Predefined: flex 3, loose fit
MyWidget().flex3();
// Custom: flex 4, tight fit
MyWidget().flex(flex: 4, fit: FlexFit.tight);
// Loose-fit with custom flex
MyWidget().flexLoose(2);
// Tight-fit with custom flex
MyWidget().flexTight(6);

πŸ’‘ Instead of writing:

Flexible(
  flex: 3,
  fit: FlexFit.tight,
  child: MyWidget(),
)

Just write:

MyWidget().flexTight(3)

‴️ Back β†’ All exui Extensions


πŸ“ align β€” Position a Widget Precisely

Align your widget anywhere inside its parent with expressive, chainable methods. These extensions wrap your widget in an Align widget, giving you fine-grained control over its position.

  • align({ alignment, widthFactor, heightFactor }) β€” Custom alignment with optional size factors.
  • alignCenter() β€” Center of parent (default).
  • Top alignment:
    • alignTopLeft()
    • alignTopCenter()
    • alignTopRight()
  • Center alignment:
    • alignCenterLeft()
    • alignCenterRight()
  • Bottom alignment:
    • alignBottomLeft()
    • alignBottomCenter()
    • alignBottomRight()

All methods return an Align widget and are safe to use inside any layout context.

πŸ§ͺ Examples

// Center the widget (default)
MyWidget().alignCenter();
// Align to bottom-right
MyWidget().alignBottomRight();
// Top-left aligned with width factor
MyWidget().alignTopLeft(widthFactor: 2);

πŸ’‘ Instead of writing:

Align(
  alignment: Alignment.bottomRight,
  child: MyWidget(),
)

Just write:

MyWidget().alignBottomRight()

🧭 When to use positioned vs aligned
Use .positioned() inside a Stack when you need precise pixel placement (top, left, etc.).
Use .aligned() when you want relative alignment (like centering) within any parent.

⚠️ .positioned() only works inside a Stack. .aligned() works almost anywhere.

‴️ Back β†’ All exui Extensions


πŸ“ positioned β€” Position Widgets Inside a Stack

Easily wrap widgets with Positioned using expressive, side-specific methods. These extensions let you declare layout constraints cleanly inside a Stack without cluttering your build logic.

  • positioned({left, top, right, bottom, width, height}) β€” Full Positioned wrapper with optional constraints.
  • positionedTop(double) β€” Position from top.
  • positionedBottom(double) β€” Position from bottom.
  • positionedLeft(double) β€” Position from left.
  • positionedRight(double) β€” Position from right.
  • positionedWidth(double) β€” Set width directly.
  • positionedHeight(double) β€” Set height directly.

All methods return a Positioned widget and are designed to be composed fluently.

πŸ§ͺ Examples

// Position 10px from top and left
MyWidget().positioned(top: 10, left: 10);
// Set only the width, auto-positioned
MyWidget().positionedWidth(200);
// Position from bottom with fixed height
MyWidget().positionedBottom(0).positionedHeight(60);
// Custom full placement
MyWidget().positioned(top: 12, right: 16, width: 150);

πŸ’‘ Instead of writing:

Positioned(
  top: 12,
  right: 16,
  width: 150,
  child: MyWidget(),
)

Just write:

MyWidget().positioned(top: 12, right: 16, width: 150)

🧭 When to use positioned vs aligned
Use .positioned() inside a Stack when you need precise pixel placement (top, left, etc.).
Use .aligned() when you want relative alignment (like centering) within any parent.

⚠️ .positioned() only works inside a Stack. .aligned() works almost anywhere.

‴️ Back β†’ All exui Extensions


πŸ”³ intrinsic β€” Size Widgets to Their Natural Dimensions

Wrap widgets with IntrinsicWidth or IntrinsicHeight to size them based on their intrinsic (natural) dimensions. These extensions make it easy to apply intrinsic sizing with expressive, chainable syntax.

  • intrinsicHeight() β€” Wraps in IntrinsicHeight.
  • intrinsicWidth() β€” Wraps in IntrinsicWidth with default options.
  • intrinsicWidthWith({stepWidth, stepHeight}) β€” Custom step values.
  • intrinsicWidthStepWidth(double) β€” Set stepWidth only.
  • intrinsicWidthStepHeight(double) β€” Set stepHeight only.

All methods return intrinsic wrappers that measure content and size accordinglyβ€”ideal for fine-tuned layout control.

πŸ§ͺ Examples

// Wrap with IntrinsicHeight
MyWidget().intrinsicHeight();
// Wrap with IntrinsicWidth (default)
MyWidget().intrinsicWidth();
// Set stepWidth to 100
MyWidget().intrinsicWidthStepWidth(100);
// Set both stepWidth and stepHeight
MyWidget().intrinsicWidthWith(
  stepWidth: 80,
  stepHeight: 40,
);

πŸ’‘ Instead of writing:

IntrinsicWidth(
  stepHeight: 40,
  child: MyWidget(),
)

Just write:

MyWidget().intrinsicWidthStepHeight(40)

⚠️ Use intrinsic widgets with care β€” they can be expensive to layout and should only be used when needed for dynamic content sizing.

‴️ Back β†’ All exui Extensions


βž– margin β€” Add Outer Spacing Around Widgets

Add clean, configurable margins around any widget with chainable extensions. These methods wrap the widget in a Container with margin, avoiding cluttered layout nesting and improving code clarity.

  • margin(EdgeInsets) β€” Use any EdgeInsets object directly.
  • marginAll(double) β€” Equal margin on all sides.
  • marginOnly({left, top, right, bottom}) β€” Custom margin per side.
  • marginSymmetric({horizontal, vertical}) β€” Horizontal & vertical margin.
  • marginHorizontal(double) β€” Shorthand for horizontal-only margin.
  • marginVertical(double) β€” Shorthand for vertical-only margin.
  • One-sided margin helpers:
    • marginLeft(double)
    • marginRight(double)
    • marginTop(double)
    • marginBottom(double)

All methods return a wrapped Container and can be freely chained with other extensions.

πŸ§ͺ Examples

// 16px margin on all sides
"Card".text().marginAll(16);
// 24px horizontal, 12px vertical
"Tile".text().marginSymmetric(horizontal: 24, vertical: 12);
// 8px margin only on top
"Header".text().marginTop(8);
// Custom side-by-side margin
"Box".text().marginOnly(left: 6, bottom: 10);

πŸ’‘ Why use this? Instead of writing:

Container(
  margin: EdgeInsets.only(left: 8, top: 4),
  child: MyWidget(),
)

Just write:

MyWidget().marginOnly(left: 8, top: 4)

βš–οΈ Margin vs Padding
Use padding to add spacing inside a widget's boundary β€” like space around text in a button.
Use margin to add spacing outside a widget β€” like separating it from other widgets.

🟒 For most layout needs, padding is the preferred and safer default. Use margin when you need to push the widget away from surrounding elements, but be cautious with nesting to avoid layout issues.

‴️ Back β†’ All exui Extensions


↕️ gap - Add Spacing Using Number Extensions

Use doubles or ints to create SizedBox widgets with clear, expressive syntax. These extensions turn raw numbers into layout spacingβ€”perfect for columns, rows, and consistent vertical/horizontal gaps.

  • sizedWidth β€” SizedBox(width: this)
  • sizedHeight β€” SizedBox(height: this)
  • gapHorizontal / gapRow / gapWidth β€” Aliases for horizontal spacing
  • gapVertical / gapColumn / gapHeight β€” Aliases for vertical spacing

All extensions return a SizedBox and are ideal for use in layouts to avoid magic numbers and improve readability.

πŸ§ͺ Examples

// Horizontal space of 16
16.gapHorizontal,
// Vertical space of 8
8.gapVertical,
// SizedBox with explicit width
2.5.sizedWidth,
// SizedBox with explicit height
32.sizedHeight,
// Clean Row layout
Row(
  children: [
    WidgetOne(),
    12.gapRow,
    WidgetTwo(),
  ],
)
// Clean Column layout
Column(
  children: [
    WidgetOne(),
    16.gapColumn,
    WidgetTwo(),
  ],
)

πŸ’‘ Use .gapRow and .gapColumn when working inside Row or Column widgets for clarity and intent-based naming.

‴️ Back β†’ All exui Extensions


🧱 row / column β€” Instantly Wrap Widgets in Flex Layouts

Effortlessly create Row and Column layouts with readable, inline extensions. Whether you're working with a single widget or a whole list, these helpers make layout structure fast, chainable, and more expressive.

  • [].row() / [].column() β€” Wrap a list of widgets in a Row or Column.
  • .row() / .column() β€” Wrap a single widget in a Row or Column.

βœ… Fully supports all Row and Column parameters, including:
spacing, mainAxisAlignment, crossAxisAlignment, and more.

πŸ§ͺ Examples

// Two widgets in a Row with spacing
[
  WidgetOne(),
  WidgetTwo(),
].row(spacing: 12);
// Vertical layout with alignment and spacing
[
  WidgetOne(),
  WidgetTwo(),
].column(
  mainAxisAlignment: MainAxisAlignment.center,
  spacing: 8,
);
// Single widget inside a Row
MyWidget().row();
// Puts a single widget in a column with center alignment
MyWidget().column(
  mainAxisAlignment: MainAxisAlignment.center,
);

πŸ’‘ Instead of writing:

Column(
  spacing: 8,
  children: [
    WidgetOne(),
    WidgetTwo(),
  ],
)

Just write:

[
   WidgetOne(),
   WidgetTwo(),
].column(spacing: 8)

‴️ Back β†’ All exui Extensions


🧭 row* / column* β€” Rapid Alignment Extensions for Flex Layouts

Stop repeating alignment boilerplate in your Row and Column widgets. These expressive extensions let you instantly apply common combinations of mainAxisAlignment and crossAxisAlignment, all while preserving full layout control. They make UI creation dramatically faster and more readable, especially in complex layouts or dynamic widget lists.

🧩 Functional Groups

All extensions are available for both Row and Column, following the same structure:

  • βœ… columnMain* β€” Sets mainAxisAlignment, customize others
  • βœ… columnCross* β€” Sets crossAxisAlignment, customize others
  • βœ… column<Main><Cross>() β€” Aligns both axes (e.g., columnCenterStart)
  • βœ… rowMain* β€” Sets mainAxisAlignment, customize others
  • βœ… rowCross* β€” Sets crossAxisAlignment, customize others
  • βœ… row<Main><Cross>() β€” Aligns both axes (e.g., rowCenterStart)

All methods accept all standard layout parameters, including:

  • mainAxisSize
  • textDirection
  • verticalDirection
  • textBaseline
  • spacing

βœ… Why Use These?

πŸ’‘ Instead of writing:

Column(
  mainAxisAlignment: MainAxisAlignment.center,
  crossAxisAlignment: CrossAxisAlignment.start,
  children: [...],
)

Just write:

[...].columnCenterStart()

Or instead of:

Row(
  spacing: 12,
  mainAxisAlignment: MainAxisAlignment.spaceBetween,
  crossAxisAlignment: CrossAxisAlignment.end,
  children: [...],
)

Just write:

[...].rowSpaceBetweenEnd(spacing: 12)

These shortcuts reduce boilerplate and keep your layout code highly consistent and declarativeβ€”perfect for design systems, builder UIs, and everyday Flutter apps.

πŸ“š Available column Methods

columnMain<choose alignment>()
  • columnMainStart() β€” MainAxisAlignment.start
  • columnMainCenter() β€” MainAxisAlignment.center
  • columnMainEnd() β€” MainAxisAlignment.end
  • columnMainSpaceAround() β€” MainAxisAlignment.spaceAround
  • columnMainSpaceBetween() β€” MainAxisAlignment.spaceBetween
  • columnMainSpaceEvenly() β€” MainAxisAlignment.spaceEvenly
columnCross<choose alignment>()
  • columnCrossStart() β€” CrossAxisAlignment.start
  • columnCrossCenter() β€” CrossAxisAlignment.center
  • columnCrossEnd() β€” CrossAxisAlignment.end
  • columnCrossBaseline() β€” CrossAxisAlignment.baseline
  • columnCrossStretch() β€” CrossAxisAlignment.stretch
column<choose main alignment><choose cross alignment>()
  • columnStartStart()
  • columnStartCenter()
  • columnStartEnd()
  • columnStartBaseline()
  • columnStartStretch()
  • columnCenterStart()
  • columnCenterCenter()
  • columnCenterEnd()
  • columnCenterBaseline()
  • columnCenterStretch()
  • columnEndStart()
  • columnEndCenter()
  • columnEndEnd()
  • columnEndBaseline()
  • columnEndStretch()
  • columnSpaceAroundStart()
  • columnSpaceAroundCenter()
  • columnSpaceAroundEnd()
  • columnSpaceAroundBaseline()
  • columnSpaceAroundStretch()
  • columnSpaceBetweenStart()
  • columnSpaceBetweenCenter()
  • columnSpaceBetweenEnd()
  • columnSpaceBetweenBaseline()
  • columnSpaceBetweenStretch()
  • columnSpaceEvenlyStart()
  • columnSpaceEvenlyCenter()
  • columnSpaceEvenlyEnd()
  • columnSpaceEvenlyBaseline()
  • columnSpaceEvenlyStretch()

πŸ§ͺ Examples

// A vertically-centered column, aligned to start
[
  Icons.image.icon(), // same as Icon(Icons.image)
  Text("Profile"),
].columnCenterStart();
// Use main alignment only, keep full control of cross
[
  Text("Hello"),
  Text("World"),
].columnMainSpaceAround(crossAxisAlignment: CrossAxisAlignment.end);
// Use cross alignment only, keep full control of main
[
  Text("Item 1"),
  "Item 2".text(), // same as Text("Item 2")
].columnCrossStretch(mainAxisAlignment: MainAxisAlignment.end);

πŸ“š Available row Methods

rowMain<choose alignment>()
  • rowMainStart()
  • rowMainCenter()
  • rowMainEnd()
  • rowMainSpaceAround()
  • rowMainSpaceBetween()
  • rowMainSpaceEvenly()
rowCross<choose alignment>()
  • rowCrossStart()
  • rowCrossCenter()
  • rowCrossEnd()
  • rowCrossBaseline()
  • rowCrossStretch()
row<choose main alignment><choose cross alignment>()
  • rowStartStart()
  • rowStartCenter()
  • rowStartEnd()
  • rowStartBaseline()
  • rowStartStretch()
  • rowCenterStart()
  • rowCenterCenter()
  • rowCenterEnd()
  • rowCenterBaseline()
  • rowCenterStretch()
  • rowEndStart()
  • rowEndCenter()
  • rowEndEnd()
  • rowEndBaseline()
  • rowEndStretch()
  • rowSpaceAroundStart()
  • rowSpaceAroundCenter()
  • rowSpaceAroundEnd()
  • rowSpaceAroundBaseline()
  • rowSpaceAroundStretch()
  • rowSpaceBetweenStart()
  • rowSpaceBetweenCenter()
  • rowSpaceBetweenEnd()
  • rowSpaceBetweenBaseline()
  • rowSpaceBetweenStretch()
  • rowSpaceEvenlyStart()
  • rowSpaceEvenlyCenter()
  • rowSpaceEvenlyEnd()
  • rowSpaceEvenlyBaseline()
  • rowSpaceEvenlyStretch()

πŸ§ͺ Examples

// Centered row, aligned to top
[
  WidgetOne(),
  WidgetTwo(),
].rowCenterStart();
// Horizontal space between, vertically stretched
[
  WidgetOne(),
  WidgetTwo(),
].rowSpaceBetweenStretch();
// Apply only main alignment, customize cross
[
  WidgetOne(),
  WidgetTwo(),
].rowMainEnd(crossAxisAlignment: CrossAxisAlignment.start);
// Apply only cross alignment, keep full control of main
[
  WidgetOne(),
  WidgetTwo(),
].rowCrossEnd(mainAxisAlignment: MainAxisAlignment.center);

πŸ’‘ These extensions make horizontal layout code extremely fast and clean β€” especially when building repetitive layouts across your app.

βœ… Full support for layout parameters like spacing, mainAxisSize, textDirection, and more β€” no flexibility lost.

‴️ Back β†’ All exui Extensions


🧊 stack β€” Overlay Widgets with Full Stack Control

Build layered UI structures with intuitive, chainable extensions. These methods let you create Stack layouts directly from a List<Widget> and configure fit modes easily with named variants.

  • stack() β€” Wrap a list in a standard Stack (StackFit.loose by default).
  • stackLoose() β€” Equivalent to StackFit.loose (default).
  • stackExpand() β€” Children fill the available space (StackFit.expand).
  • stackPassthrough() β€” Children keep their intrinsic size (StackFit.passthrough).

βœ… Fully supports all native Stack parameters: alignment, textDirection, fit, and clipBehavior.

πŸ§ͺ Examples

// Default stack with loose fit
[
  WidgetOne(),
  WidgetTwo().positionedTop(0),
].stack();
// Stack with expanded fit
[
  WidgetOne(),
  WidgetTwo().positionedBottom(0),
].stackExpand();
// Stack with passthrough sizing
[
  WidgetOne(),
  WidgetTwo(),
].stackPassthrough();
// Stack with custom alignment and clip behavior
[
  ...someWidgets,
].stack(
  alignment: Alignment.center,
  clipBehavior: Clip.none,
);
// A single widget wrapped in a Stack
MyWidget().stack();

πŸ’‘ Instead of writing:

Stack(
  fit: StackFit.expand,
  alignment: Alignment.center,
  children: [ ... ],
)

Just write:

[...].stackExpand(alignment: Alignment.center)

‴️ Back β†’ All exui Extensions


πŸ‘οΈ visible - Conditional Visibility for Widgets

Simplify visibility logic in your widget tree with expressive, chainable methods. These extensions replace repetitive ternary conditions and help keep your UI code declarative and clean.

  • visibleIf(bool) β€” Show this widget only if the condition is true; otherwise returns an empty box.
  • visibleIfNot(bool) β€” Inverse of visibleIf.
  • visibleIfNull(Object?) β€” Show this widget only if the given value is null.
  • visibleIfNotNull(Object?) β€” Show this widget only if the given value is not null.
  • hide() β€” Always returns an empty widget (SizedBox.shrink()).
  • invisible() β€” Alias of hide() for readability.
  • boxShrink() β€” Returns SizedBox.shrink() directly.

All methods return valid widgets and are safe to chain inside build methods.

πŸ§ͺ Examples

MyWidget().visibleIf(isLoggedIn); // Show only if condition is true
MyWidget().visibleIfNot(isLoggedIn); // Show only if condition is false
MyWidget().visibleIfNull(user); // Show only if value is null
MyWidget().visibleIfNotNull(user); // Show only if value is not null
MyWidget().hide(); // Always hidden
MyWidget().invisible(); // Same as hide(), for clarity
final emptyBox = MyWidget().boxShrink(); // Returns an empty widget directly

πŸ’‘ Why use this? Instead of writing:

condition ? MyWidget() : const SizedBox.shrink()

Just write:

MyWidget().visibleIf(condition)

πŸ”’ These methods never break layout structure β€” they return a valid widget in all cases and help you write safer conditional UI.

‴️ Back β†’ All exui Extensions


🌫️ opacity - Control Widget Transparency

Quickly apply opacity to any widget using clean, expressive methods. These extensions eliminate the need to wrap widgets manually in Opacity and support percentage-based and common preset values.

  • opacity(double) β€” Set widget transparency using a 0.0–1.0 value.
  • opacityPercent(double) β€” Use percentage (0–100) for readability.
  • opacityHalf() β€” Set opacity to 50%.
  • opacityQuarter() β€” Set opacity to 25%.
  • opacityZero() β€” Set opacity to 0.
  • opacityTransparent() β€” Alias of opacityZero().
  • opacityInvisible() β€” Alias of opacityZero().

All methods return a wrapped Opacity widget and are safe to chain with other extensions.

πŸ§ͺ Examples

Set to 70% visible

MyWidget().opacity(0.7);

Set to 40% using percent

MyWidget().opacityPercent(40);
MyWidget().opacityHalf(); // Half visible (0.5)
MyWidget().opacityQuarter(); // Quarter visible (0.25)

πŸ’‘ Instead of writing:

Opacity(
  opacity: value,
  child: MyWidget(),
)

Just write:

MyWidget().opacity(value)

Use .opacityPercent() when working with designer specs or to make your code more intuitive at a glance.

‴️ Back β†’ All exui Extensions


πŸ“± safeArea β€” Add SafeArea Padding Declaratively

Easily wrap widgets in SafeArea using expressive, chainable extensions. These methods let you control which sides are paddedβ€”without nesting or verbose boilerplate.

  • safeArea({left, top, right, bottom, minimum, maintainBottomViewPadding}) β€” Full control over all sides and padding behavior.
  • safeAreaAll() β€” Padding on all sides.
  • safeAreaNone() β€” No padding at all.
  • safeAreaOnlyTop() / safeAreaOnlyBottom() β€” Top or bottom only.
  • safeAreaOnlyLeft() / safeAreaOnlyRight() β€” Left or right only.
  • safeAreaOnlyHorizontal() β€” Left + right.
  • safeAreaOnlyVertical() β€” Top + bottom.

All methods return a SafeArea widget wrapping the original widget.

πŸ§ͺ Examples

MyWidget().safeArea(); // Same as wrap in SafeArea;
// Only top padded (e.g., below status bar)
MyWidget().safeAreaOnlyTop();
// Bottom safe area only (e.g., above iPhone home indicator)
MyWidget().safeAreaOnlyBottom();
// Custom safe area: only horizontal
MyWidget().safeAreaOnlyHorizontal();
// No SafeArea applied
MyWidget().safeAreaNone();

πŸ’‘ Instead of writing:

SafeArea(
  child: MyWidget(),
)

Just write:

MyWidget().safeArea()

‴️ Back β†’ All exui Extensions


πŸ‘† gesture β€” Add Tap, Drag & Press Events Easily

Eliminate manual GestureDetector nesting with intuitive, chainable gesture methods. These extensions make it effortless to attach any gesture to any widget.

  • onTap(VoidCallback) β€” Handle basic tap gestures.
  • onDoubleTap(VoidCallback) β€” Respond to double-tap gestures.
  • onLongPress(VoidCallback) β€” Handle long presses.
  • onTapDown(...), onTapUp(...), onTapCancel(...) β€” Full tap phase handling.
  • onSecondaryTap(...), onTertiaryTapDown(...), etc. β€” Full multi-touch support.
  • onVerticalDrag..., onHorizontalDrag..., onPan... β€” Add drag gestures with full phase support.
  • onScale... β€” Handle pinch-to-zoom gestures.
  • onForcePress... β€” Support for pressure-sensitive gestures.
  • gestureDetector(...) β€” Attach multiple gestures at once in one call.

All methods return a wrapped GestureDetector and support optional customization of behavior, semantics, and supported devices.

πŸ§ͺ Examples

// Basic tap interaction
MyWidget().onTap(() => print("Tapped!"));
// Double tap
MyWidget().onDoubleTap(() => print("Double tapped"));
// Handle tap down position
MyWidget().onTapDown((details) {
  print("Tap down at ${details.globalPosition}");
});
// Add vertical drag support
MyWidget().onVerticalDragUpdate((details) {
  print("Dragging: ${details.delta.dy}");
});
// Combine multiple gestures
MyWidget().gestureDetector(
  onTap: () => print("Tap"),
  onLongPress: () => print("Long press"),
  onPanUpdate: (details) => print("Panning"),
);

πŸ’‘ Instead of writing:

GestureDetector(
  onTap: () => doSomething(),
  child: MyWidget(),
)

Just write:

MyWidget().onTap(() => doSomething())

‴️ Back β†’ All exui Extensions


🦸 hero β€” Add Seamless Shared Element Transitions

Effortlessly wrap any widget in a Hero for smooth page-to-page transitions. Customize behavior with optional parameters for animations, flight behavior, and placeholders.

  • hero(String tag) β€” Wraps the widget in a Hero with the given tag.
  • Optional parameters:
    • createRectTween(...) β€” Customize the transition animation path.
    • flightShuttleBuilder(...) β€” Override the animation widget during flight.
    • placeholderBuilder(...) β€” Placeholder shown during transition loading.
    • transitionOnUserGestures β€” Allow gesture-driven transitions.

All options mirror the native Hero widget and can be configured inline.

πŸ§ͺ Examples

// Basic shared element transition
MyWidget().hero("profile-avatar");
// Custom placeholder
MyWidget()
  .hero(
    "title-hero",
    placeholderBuilder: (context, size, child) =>
        SizedBox.fromSize(size: size),
  );
// With custom flight behavior
MyWidget().hero(
  "star-icon",
  flightShuttleBuilder: (context, animation, direction, from, to) {
    return ScaleTransition(scale: animation, child: to.widget);
  },
);

πŸ’‘ Instead of writing:

Hero(
  tag: "avatar",
  child: Image.asset("avatar.png"),
)

Just write:

Image.asset("avatar.png").hero("avatar")

‴️ Back β†’ All exui Extensions


πŸ“¦ sizedBox β€” Wrap Widgets in Fixed-Size Boxes

Quickly wrap any widget in a SizedBox with a specified width, height, or both. These extensions improve readability and reduce boilerplate when sizing widgets inline.

  • sizedBox({width, height}) β€” Wrap with custom width and/or height.
  • sizedWidth(double) β€” Set only the width.
  • sizedHeight(double) β€” Set only the height.

All methods return a SizedBox with your widget as the child, and are safe to chain.

πŸ§ͺ Examples

// Fixed width and height
MyWidget().sizedBox(width: 120, height: 40);
// Only width
MyWidget().sizedWidth(200);
// Only height
MyWidget().sizedHeight(60);

πŸ’‘ Instead of writing:

SizedBox(width: 120, height: 40, child: MyWidget())

Just write:

MyWidget().sizedBox(width: 120, height: 40)

‴️ Back β†’ All exui Extensions


🎨 decoratedBox β€” Add Backgrounds, Borders, Gradients & Effects

Decorate any widget with rich visuals using a clean, expressive API. These extensions wrap your widget in a DecoratedBox with common presets like gradients, shadows, images, borders, and shapes β€” no boilerplate required.

  • decoratedBox(...) β€” Core method using any Decoration.
  • decoratedBoxDecoration(...) β€” Configure BoxDecoration inline with full control.
  • imageBox(...) β€” Add a background image with all DecorationImage options.
  • gradientBox(Gradient) β€” Add a linear, radial, or sweep gradient.
  • shadowedBox(...) β€” Apply shadow effects with offset, blur, spread.
  • borderedBox(...) β€” Add a border (and optional border radius).
  • shapedBox(BoxShape) β€” Change the shape (e.g., circle, rectangle).
  • circularBorderBox(...) β€” Draw a colored, circular border with width and radius.

All methods return a DecoratedBox and can be safely combined with padding, opacity, or gesture extensions.

πŸ§ͺ Examples

// Apply a gradient background
MyWidget().gradientBox(
  LinearGradient(colors: [Colors.purple, Colors.blue]),
);
// Add a background image
MyWidget().imageBox(
  image: NetworkImage("https://example.com/image.png"),
  fit: BoxFit.cover,
);
// Add a shadow
MyWidget().shadowedBox(
  offset: Offset(2, 2),
  blurRadius: 6,
);
// Circular border
MyWidget().circularBorderBox(
  radius: 12,
  color: Colors.red,
  width: 2,
);
// Full decorated box manually
MyWidget().decoratedBoxDecoration(
  color: Colors.grey.shade100,
  border: Border.all(color: Colors.black26),
  borderRadius: BorderRadius.circular(8),
);

πŸ’‘ Instead of wrapping your widget manually like this:

DecoratedBox(
  decoration: BoxDecoration(
    color: Colors.red,
    borderRadius: BorderRadius.circular(12),
  ),
  child: MyWidget(),
)

You can write:

MyWidget().decoratedBoxDecoration(
  color: Colors.red,
  borderRadius: BorderRadius.circular(12),
)

‴️ Back β†’ All exui Extensions


🚧 constrained β€” Add Size Limits to Widgets

Apply size constraints directly to any widget without manually wrapping in ConstrainedBox. These extensions make layout constraints clean, readable, and fully chainable.

  • constrained({minWidth, maxWidth, minHeight, maxHeight}) β€” General constraint utility.
  • constrainedBox(BoxConstraints) β€” Use custom BoxConstraints directly.
  • constrainedWidth({min, max}) β€” Horizontal size limits.
  • constrainedHeight({min, max}) β€” Vertical size limits.
  • minWidth(double) / maxWidth(double) β€” Individual width constraints.
  • minHeight(double) / maxHeight(double) β€” Individual height constraints.

All methods return a ConstrainedBox and are safe to chain in layout compositions.

πŸ§ͺ Examples

// Limit to a width between 100–200
MyWidget().constrainedWidth(min: 100, max: 200);
// Limit to a height between 50–100
MyWidget().constrainedHeight(min: 50, max: 100);
// Only limit max height
MyWidget().maxHeight(120);
// Fully custom constraints
MyWidget().constrained(
  minWidth: 80,
  maxWidth: 150,
  minHeight: 40,
  maxHeight: 90,
);
// Using BoxConstraints directly
MyWidget().constrainedBox(
  constraints: BoxConstraints.tightFor(width: 100, height: 40),
);

πŸ’‘ Instead of writing:

ConstrainedBox(
  constraints: BoxConstraints(
    minWidth: 100,
    maxWidth: 200,
  ),
  child: MyWidget(),
)

Just write:

MyWidget().constrainedWidth(min: 100, max: 200)

‴️ Back β†’ All exui Extensions


πŸŸ₯ coloredBox β€” Add Background Color to Any Widget

Wrap any widget with a solid background using ColoredBox, without nesting manually. This extension is a clean and efficient way to apply color without additional containers.

  • coloredBox(Color) β€” Wraps the widget in a ColoredBox with the given background color.

Use this to apply color styling in layout compositions without using Container, keeping your UI lightweight.

πŸ§ͺ Example

// Red background
MyWidget().coloredBox(Colors.red);

πŸ’‘ Why use this? Instead of writing:

ColoredBox(
  color: Colors.blue,
  child: MyWidget(),
)

Just write:

MyWidget().coloredBox(Colors.blue)

βœ… A minimal, performant way to color backgrounds without unnecessary overhead.

‴️ Back β†’ All exui Extensions


🎨 Material coloredBox β€” Background Color with One Line

Apply colorful backgrounds to any widget using expressive .colorBox() helpers. These extensions wrap your widget in a ColoredBox with a specific Color from the Material palette.

No need to write Container or manage BoxDecorationβ€”just add color directly to any widget in one line.

All extensions return a ColoredBox.

🌈 Available Colors

  • redBox() / redAccentBox()
  • greenBox() / greenAccentBox()
  • blueBox() / blueAccentBox()
  • yellowBox() / yellowAccentBox()
  • orangeBox() / orangeAccentBox()
  • purpleBox() / purpleAccentBox()
  • deepPurpleBox() / deepPurpleAccentBox()
  • pinkBox() / pinkAccentBox()
  • brownBox()
  • tealBox() / tealAccentBox()
  • cyanBox() / cyanAccentBox()
  • lightBlueBox() / lightBlueAccentBox()
  • lightGreenBox() / lightGreenAccentBox()
  • limeBox() / limeAccentBox()
  • greyBox()
  • blackBox()
  • whiteBox()

πŸ§ͺ Examples

// Add a red background
MyWidget().redBox();
// Success message with green accent
MyWidget().greenAccentBox();
// Stylized button background
MyWidget().blueBox().paddingAll(12);

πŸ’‘ Instead of writing:

ColoredBox(
  color: Colors.red,
  child: MyWidget(),
)

Just write:

MyWidget().redBox()

‴️ Back β†’ All exui Extensions


🎨 Cupertino coloredBox β€” Apply iOS-Themed Background Colors

Quickly apply Cupertino-style background colors to any widget using expressive, pre-named methods. These extensions wrap your widget in a ColoredBox using native CupertinoColors.

  • redBox() / destructiveRedBox()
  • greenBox() / activeGreenBox()
  • blueBox() / activeBlueBox()
  • orangeBox() / orangeAccentBox()
  • yellowBox() / purpleBox() / pinkBox()
  • tealBox() / cyanBox() / brownBox()
  • greyBox() / blackBox() / whiteBox()
  • darkGrayBox() / lightGrayBox()

All methods return a ColoredBox using system-consistent Cupertino color values, ideal for quick prototyping and iOS-native look and feel.

πŸ§ͺ Examples

// Apply iOS system red background
MyWidget().redBox();
// Use active Cupertino blue
MyWidget().activeBlueBox();
// Style with light gray background
MyWidget().lightGrayBox();
// Warning or alert color
MyWidget().orangeAccentBox();

πŸ’‘ Instead of writing:

ColoredBox(
  color: CupertinoColors.systemTeal,
  child: MyWidget(),
)

Just write:

MyWidget().tealBox()

‴️ Back β†’ All exui Extensions


πŸͺž fit β€” Control How Widgets Scale to Fit

Wrap your widget with a FittedBox to control how it resizes within its parent. These extensions provide clean, expressive access to BoxFit options β€” without the boilerplate.

  • fittedBox({fit, alignment, clipBehavior}) β€” Base method with full control.
  • fitContain() β€” Preserves aspect ratio, fits within bounds.
  • fitCover() β€” Fills bounds, possibly cropping.
  • fitFill() β€” Stretches to fill bounds, ignoring aspect ratio.
  • fitScaleDown() β€” Only scales down, never up.
  • fitHeight() β€” Scales to match parent height.

All methods return a FittedBox and preserve your widget tree cleanly.

πŸ§ͺ Examples

// Scale to fit within constraints
MyWidget().fitContain();
// Fill the available space
MyWidget().fitCover();
// Scale down only if too large
MyWidget().fitScaleDown();
// Stretch to fill all dimensions
MyWidget().fitFill();

πŸ’‘ Instead of writing:

FittedBox(
  fit: BoxFit.cover,
  child: MyWidget(),
)

Just write:

MyWidget().fitCover()

‴️ Back β†’ All exui Extensions


πŸ“¦ container β€” Wrap Any Widget in a Container

Easily apply layout, styling, and decoration to any widget by wrapping it in a Containerβ€”without cluttering your code. This extension saves you from manual nesting while exposing all the powerful layout features of Container.

  • container({...}) β€” Adds padding, margin, size, decoration, alignment, and more in a single call.

Supports all Container options:

  • width, height β€” Size constraints
  • color, decoration β€” Background and border styling
  • padding, margin β€” Inner and outer spacing
  • alignment β€” Align child within the container
  • clipBehavior, constraints β€” Additional layout control

πŸ§ͺ Examples

// Wrap with background color and padding
MyWidget().container(
  color: const Color(0xFFE0E0E0),
  padding: const EdgeInsets.all(12),
);
// Add margin and align center
MyWidget().container(
  margin: const EdgeInsets.symmetric(vertical: 16),
  alignment: Alignment.center,
);
// Fully customized container
MyWidget().container(
  width: 150,
  height: 80,
  decoration: BoxDecoration(
    color: const Color(0xFF2196F3),
    borderRadius: BorderRadius.circular(12),
  ),
  alignment: Alignment.center,
);

πŸ’‘ Instead of writing:

Container(
  padding: EdgeInsets.all(12),
  color: Colors.grey,
  child: MyWidget(),
)

Just write:

MyWidget().container(padding: EdgeInsets.all(12), color: Colors.grey)

‴️ Back β†’ All exui Extensions


βœ‚οΈ clip - Clip Widgets into Shapes

Easily apply clipping to any widget using expressive, chainable methods. These extensions eliminate boilerplate when working with ClipPath, ClipRRect, ClipOval, and even advanced shapes like squircles.

  • clipRRect({borderRadius}) β€” Clip with rounded corners using ClipRRect.
  • clipCircular([radius]) β€” Clip into a circle.
  • clipOval() β€” Clip into an oval or circle.
  • clipCircle() β€” Alias for clipOval() (semantic clarity).
  • clipPath({clipper}) β€” General-purpose custom path clipping.
  • clipSquircle([radiusFactor]) β€” Clip into a modern "squircle" shape.
  • clipContinuousRectangle([radiusFactor]) β€” Alias for clipSquircle().

All methods return wrapped Clip* widgets and are safe to chain.

πŸ§ͺ Examples

// Rounded corners (16 radius)
Container().clipRRect(borderRadius: BorderRadius.circular(16));
// Circular/oval clip
Image.asset("avatar.png").clipCircle();
// Custom path clip (e.g. star shape)
MyWidget().clipPath(clipper: StarClipper());
// Squircle shape (iOS-style corners)
MyWidget().clipSquircle(2.5);
// Same as above but with alternative naming
MyWidget().clipContinuousRectangle(2.5);

πŸ’‘ Instead of writing:

ClipRRect(
  borderRadius: BorderRadius.circular(12),
  child: MyWidget(),
)

Just write:

MyWidget().clipRRect(borderRadius: BorderRadius.circular(12))

‴️ Back β†’ All exui Extensions


πŸ“ text β€” Turn Any String into a Text Widget

Effortlessly convert a String into a fully configurable Text widget. The .text() and .styledText() extensions make your UI code clean, readable, and expressive β€” no more boilerplate, no more clutter.

  • .text({...}) β€” Create a Text widget with any native Text constructor parameters.
  • .styledText({...}) β€” Configure full TextStyle in one place: font, color, spacing, shadows, decoration, and more.

Both methods return a standard Flutter Text widget β€” no wrappers, no magic.

πŸ”Ή Basic Text

"Hello world".text(); // same as Text("Hello world");
Text("Hello world"); // same as "Hello world".text();

πŸ”Ή Styled Text with Alignment

"Hello exui".text(
  style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
  textAlign: TextAlign.center,
);
Text(
  "Hello exui",
  style: TextStyle(
    fontSize: 18,
    fontWeight: FontWeight.bold,
  ),
  textAlign: TextAlign.center,
);

πŸ”Ή Rich Styling in One Call

"Stylish!".styledText(
  fontSize: 24,
  fontWeight: FontWeight.w600,
  color: Colors.purple,
);
Text(
  "Stylish!",
  style: TextStyle(
    fontSize: 24,
    fontWeight: FontWeight.w600,
    color: Colors.purple,
  ),
);

‴️ Back β†’ All exui Extensions


πŸŽ›οΈ styled text - Modify and Style Text Widgets Easily

Powerfully enhance your Text widgets with dozens of chainable extensions. Control alignment, overflow, semantics, and apply fine-grained stylingβ€”without verbose TextStyle blocks.

These extensions are non-intrusive, composable, and maintain the immutability of the original widget.

πŸ“ Layout & Metadata Modifiers

  • textAlign(...)
  • textDirection(...)
  • locale(...)
  • softWrap(...)
  • overflow(...)
  • maxLines(...)
  • semanticsLabel(...)
  • widthBasis(...)
  • heightBehavior(...)
  • selectionColor(...)
  • strutStyle(...)
  • textScaler(...)

🎨 Style Extensions

Apply full or partial TextStyle changes with expressive one-liners:

  • fontSize(...)
  • fontWeight(...)
  • fontStyle(...)
  • letterSpacing(...)
  • wordSpacing(...)
  • height(...)
  • foreground(...) / background(...)
  • shadows(...)
  • fontFeatures(...) / fontVariations(...)
  • decoration(...)
  • decorationColor(...)
  • decorationStyle(...)
  • decorationThickness(...)
  • fontFamily(...) / fontFamilyFallback(...)
  • leadingDistribution(...)
  • debugLabel(...)

⚑ Expressive Shortcuts

Use simple methods for common typography tasks:

  • bold()
  • italic()
  • underline()
  • strikethrough()
  • boldItalic()
  • boldUnderline()
  • boldStrikethrough()

πŸ§ͺ Example

"Hello World"
  .text()
  .fontSize(20)
  .boldItalic()
  .textAlign(TextAlign.center)
  .maxLines(2)
  .overflow(TextOverflow.ellipsis);

Or, apply full styling in one go:

"Sale!"
  .text()
  .styled(
    fontSize: 24,
    fontWeight: FontWeight.w900,
    decoration: TextDecoration.lineThrough,
    color: Colors.red,
  );

‴️ Back β†’ All exui Extensions


πŸ”£ icon β€” Quickly Create and Style Icons

Easily create and customize Icon widgets from an IconData, or update existing Icon instances with expressive, chainable methods. These extensions support all styling parameters available on Flutter's Icon.

🧩 On IconData

  • icon({...}) β€” Create an Icon from IconData with full styling options.
  • iconSized(double) β€” Shorthand for setting size.
  • iconFilled(double) β€” Set the fill level (for Material symbols).
  • iconColored(Color) β€” Apply color.

🧩 On Icon

  • .sized(double) β€” Change icon size.
  • .filled(double) β€” Set fill level.
  • .weight(double) / .grade(double) / .opticalSize(double) β€” Fine-tune variable font icons.
  • .colored(Color) β€” Change icon color.
  • .shadowed(List<Shadow>) β€” Add text-style shadows.
  • .semanticLabeled(String) β€” Set semantic label for accessibility.
  • .textDirectioned(TextDirection) β€” Set directionality.
  • .applyTextScaling(bool) β€” Respect or ignore text scaling.
  • .blendMode(BlendMode) β€” Control blend behavior.

All methods return a new Icon and preserve other properties unless overwritten.


πŸ§ͺ Examples

Icons.settings.icon(size: 32, color: Colors.amber,);
// Create a red icon at 24px
Icons.home.iconSized(24).colored(Colors.red);
// Create and fill a Material symbol icon
Icons.favorite.iconFilled(1.0);
// Chain multiple style changes
Icons.star.icon().sized(32).filled(0.8).colored(Colors.amber);

πŸ’‘ Instead of:

Icon(
  Icons.star,
  size: 32,
  color: Colors.amber,
  fill: 0.8,
)

Just write:

Icons.star.icon(size: 32, color: Colors.amber, fill: 0.8)

‴️ Back β†’ All exui Extensions


🍎 cupertinoButton β€” Turn Any Widget into an iOS Button

Transform any widget into a fully styled CupertinoButton, with fluent syntax and optional variants for filled or tinted styles. These extensions reduce boilerplate while preserving full configurability.

  • cupertinoButton(...) β€” Standard iOS-style button.
  • cupertinoFilledButton(...) β€” Filled style, best for emphasis.
  • cupertinoTintedButton(...) β€” Tinted (outlined) style with subtle color emphasis.

Each method returns a CupertinoButton and supports all common options, including pressedOpacity, autofocus, borderRadius, and onLongPress.

πŸ§ͺ Examples

// Basic Cupertino button
Text("Continue").cupertinoButton(onPressed: () {});
// Filled iOS-style button
Text("Submit").cupertinoFilledButton(onPressed: () {});
// Tinted iOS-style button with border and color
Text("Retry").cupertinoTintedButton(
  color: CupertinoColors.systemRed,
  onPressed: () {},
);

πŸ’‘ Instead of writing:

CupertinoButton(
  child: Text("Continue"),
  onPressed: () {},
)

Just write:

"Continue".text().cupertinoButton(onPressed: () {})

‴️ Back β†’ All exui Extensions


πŸ–²οΈ button - Instantly Turn Any Widget into a Button

Wrap any widget in a Material Design button with a single method. These extensions let you create ElevatedButton, FilledButton, OutlinedButton, and TextButton variants with or without iconsβ€”without boilerplate.

βœ… Supported Types

  • elevatedButton({onPressed})
  • elevatedIconButton({onPressed, icon})
  • filledButton({onPressed})
  • filledTonalButton({onPressed})
  • filledIconButton({onPressed, icon})
  • filledTonalIconButton({onPressed, icon})
  • outlinedButton({onPressed})
  • outlinedIconButton({onPressed, icon})
  • textButton({onPressed})
  • textIconButton({onPressed, icon})

Each method supports full customization via Flutter's native parameters: style, focusNode, clipBehavior, onHover, autofocus, statesController, and more.


πŸ§ͺ Examples

// Basic elevated button
Text("Submit").elevatedButton(onPressed: () => print("Tapped"))
// Filled button with icon
Text("Send").filledIconButton(
  onPressed: () => print("Sent"),
  icon: const Icon(Icons.send),
)
// Text button, semantic only
Text("Cancel").textButton(onPressed: () => print("Canceled"))
// Outlined button with icon and custom style
Text("Info").outlinedIconButton(
  onPressed: () {},
  icon: const Icon(Icons.info_outline),
  style: OutlinedButton.styleFrom(
    foregroundColor: Colors.blue,
  ),
)

πŸ’‘ Instead of writing:

ElevatedButton(
  onPressed: () {},
  child: Text("Confirm"),
)

Just write:

"Confirm".text().elevatedButton(onPressed: () {})

‴️ Back β†’ All exui Extensions


πŸ”— License MIT Β© Jozz

β˜• Enjoying this package? You can support it here.

About

Build your UI faster. No boilerplate, no dependencies, just powerful widget extensions.

Topics

Resources

License

Stars

Watchers

Forks

Languages