wonzy_core_utils 0.3.0 copy "wonzy_core_utils: ^0.3.0" to clipboard
wonzy_core_utils: ^0.3.0 copied to clipboard

Flutter/Dart extensions and reusable widgets for rapid UI development. Context helpers, navigation shortcuts, text builders, layout extensions, and customizable widgets.

wonzy_core_utils #

pub package CI License: MIT Flutter Dart

A comprehensive collection of Flutter/Dart extensions and reusable widgets that eliminate boilerplate and accelerate UI development. One import, dozens of superpowers.

import 'package:wonzy_core_utils/core_utils.dart';

Table of Contents #


Installation #

dependencies:
  wonzy_core_utils: ^0.2.0

Option B — Git dependency #

dependencies:
  wonzy_core_utils:
    git:
      url: https://github.com/muhammedeminalan/core_utils.git
      ref: v0.2.0

Then run:

flutter pub get

Then import:

import 'package:wonzy_core_utils/core_utils.dart';

Context Extensions #

Shortcuts on BuildContext for screen size, theme, colors, and text styles.

// ── Screen Size ──
context.screenSize          // MediaQuery size
context.width               // screen width
context.height              // screen height
context.screenHeight(0.5)   // 50% of screen height
context.screenWidth(0.3)    // 30% of screen width

// ── Theme ──
context.theme               // ThemeData
context.colorScheme         // ColorScheme

// ── Color Shortcuts ──
context.primaryColor        // colorScheme.primary
context.secondaryColor      // colorScheme.secondary
context.errorColor          // colorScheme.error
context.surfaceColor        // colorScheme.surface
context.onPrimaryColor      // colorScheme.onPrimary
context.onSecondaryColor    // colorScheme.onSecondary
context.onSurfaceColor      // colorScheme.onSurface
context.outlineColor        // colorScheme.outline

// ── Text Style Shortcuts ──
context.displayLarge        // textTheme.displayLarge!
context.displayMedium       // textTheme.displayMedium!
context.headlineLarge       // textTheme.headlineLarge!
context.headlineMedium      // textTheme.headlineMedium!
context.titleLarge          // textTheme.titleLarge!
context.titleMedium         // textTheme.titleMedium!
context.bodyLarge           // textTheme.bodyLarge!
context.bodyMedium          // textTheme.bodyMedium!
context.labelLarge          // textTheme.labelLarge!
context.labelSmall          // textTheme.labelSmall!

// ── Widget Theme Shortcuts ──
context.appBarTheme         // theme.appBarTheme
context.cardTheme           // theme.cardTheme
context.inputTheme          // theme.inputDecorationTheme
context.elevatedButtonTheme // theme.elevatedButtonTheme
context.bottomNavTheme      // theme.bottomNavigationBarTheme

// ── Divider ──
context.divider(color: Colors.grey)

Num Extensions #

Turn any num into spacing, padding, radius, or duration — zero boilerplate.

// ── SizedBox Spacing ──
16.h          // SizedBox(height: 16)
24.w          // SizedBox(width: 24)
16.height     // SizedBox(height: 16)  — alias
24.width      // SizedBox(width: 24)   — alias

// ── EdgeInsets ──
12.all        // EdgeInsets.all(12)
16.horizontal // EdgeInsets.symmetric(horizontal: 16)
8.vertical    // EdgeInsets.symmetric(vertical: 8)

// ── BorderRadius ──
8.radius      // BorderRadius.circular(8)

// ── Duration ──
300.ms        // Duration(milliseconds: 300)
2.seconds     // Duration(seconds: 2)

Real-world usage:

Column(
  children: [
    Text('Title'),
    16.h,              // instead of SizedBox(height: 16)
    Text('Subtitle'),
    24.h,
    ElevatedButton(...)
        .paddingAll(12) // uses 12.all internally
  ],
)

String Extensions #

Rich set of string manipulation, formatting, validation, and conversion utilities.

Case Conversion #

'hello world'.capitalize()    // "Hello world"
'hello world'.toTitleCase()   // "Hello World"
'hello world'.toSnakeCase()   // "hello_world"
'hello world'.toKebabCase()   // "hello-world"
'hello world'.toCamelCase()   // "helloWorld"

Validation #

'42'.isNumeric              // true
'hello'.isAlphabetic        // true
'abc123'.isAlphanumeric     // true
'abc123'.hasNumber          // true
'abc123'.hasLetter          // true
''.isNullOrEmpty            // true
'hello'.isNotNullOrEmpty    // true

Manipulation #

'Hello World'.reversed               // "dlroW olleH"
'Hello World'.ellipsis(5)            // "Hello..."
'Hello World'.trimmed                // "Hello World" (trim shortcut)
'Hello World'.containsIgnoreCase('hello')  // true
'Hello World'.replaceAllIgnoreCase('hello', 'Hi')  // "Hi World"
'<b>bold</b>'.stripHtml              // "bold"
'true'.toBool                        // true
'Hello World'.splitToList            // ["Hello", "World"]
'abc'.charAtOr(5, 'x')              // "x" (safe index access)
'abc'.padLeftToLength(6, '0')        // "000abc"
'abc'.padRightToLength(6, '0')       // "abc000"
'abc'.lengthSafe                     // 3

Turkish Formatters #

'5551234567'.toTurkishPhoneFormat()  // "+90 0555 123 4567"
'john'.toUsername()                  // "@john"
'@john'.toUsername()                 // "@john" (no double @)
'john'.toGmail()                    // "john@gmail.com"
'JOHN@gmail.com'.toGmail()          // "john@gmail.com"

Text Builder #

A fully chainable API to build styled Text widgets from any String. No more nested Text() + TextStyle() boilerplate.

// Basic usage
'Hello World'.text                   // plain Text widget

// Font weight
'Bold'.text.bold                     // FontWeight.w700
'Light'.text.light                   // FontWeight.w300
'Medium'.text.medium                 // FontWeight.w500
'SemiBold'.text.semiBold             // FontWeight.w600
'Black'.text.black                   // FontWeight.w900

// Font style
'Italic'.text.italic                 // FontStyle.italic

// Decoration
'Underline'.text.underline
'Strikethrough'.text.lineThrough
'Overline'.text.overline

// Alignment
'Centered'.text.alignCenter
'Right'.text.alignRight
'Justified'.text.alignJustify

// Overflow
'Long text...'.text.ellipsis.maxLine(2)

// Custom values
'Custom'.text
    .color(Colors.red)
    .backgroundColor(Colors.yellow)
    .fontSize(20)
    .letterSpacing(1.5)
    .wordSpacing(2.0)
    .height(1.4)
    .fontFamily('Roboto')

// Theme-based typography (Material 3)
'Display'.text.displayLarge(context)
'Headline'.text.headlineMedium(context)
'Title'.text.titleLarge(context)
'Body'.text.bodyMedium(context)
'Label'.text.labelSmall(context)

// Legacy Material 2 names (still supported)
'Legacy'.text.headline4(context)
'Legacy'.text.subtitle1(context)
'Legacy'.text.body1(context)
'Legacy'.text.caption(context)

// Merge with existing style
'Merged'.text.style(myTextStyle)

// ── Full chain example ──
'Welcome Back!'.text
    .bold
    .italic
    .titleLarge(context)
    .color(Colors.indigo)
    .letterSpacing(0.5)
    .maxLine(1)
    .ellipsis

Widget Extensions #

Padding & Margin #

// Padding
widget.paddingAll(16)                     // all sides
widget.paddingHorizontal(12)              // left + right
widget.paddingVertical(8)                 // top + bottom
widget.paddingSymmetric(h: 16, v: 8)     // symmetric
widget.paddingOnly(left: 8, top: 16)     // specific sides
widget.padding(EdgeInsets.all(10))        // custom EdgeInsets

// Margin (uses Container internally)
widget.marginAll(16)
widget.marginHorizontal(12)
widget.marginVertical(8)
widget.marginOnly(left: 8, bottom: 16)

Alignment #

widget.center          // Center(child: widget)
widget.alignLeft       // Alignment.centerLeft
widget.alignRight      // Alignment.centerRight
widget.alignTop        // Alignment.topCenter
widget.alignBottom     // Alignment.bottomCenter
widget.align(Alignment.topRight)  // custom

Container #

Wrap any widget in a fully customizable Container — one method call:

Text('Hello').container(
  color: Colors.blue,
  padding: EdgeInsets.all(16),
  margin: EdgeInsets.all(8),
  borderRadius: 12,
  width: 200,
  height: 50,
  gradient: LinearGradient(...),
  border: Border.all(color: Colors.white),
  boxShadow: [BoxShadow(...)],
  alignment: Alignment.center,
)

Expanded & Flexible #

widget.expanded()           // Expanded(child: widget)
widget.expanded(flex: 2)    // Expanded(flex: 2, child: widget)
widget.flexible()           // Flexible(child: widget)
widget.flexible(flex: 2, fit: FlexFit.tight)

Size Constraints #

widget.sized(width: 100, height: 50)    // SizedBox wrapper
widget.square(60)                        // square SizedBox(60×60)
widget.expandedWidth                     // width: double.infinity
widget.expandedHeight                    // height: double.infinity
widget.constrained(
  minWidth: 100,
  maxWidth: 300,
  minHeight: 50,
  maxHeight: 200,
)

Decoration & Interaction #

// ── Rounded Box ──
Text('Chip').roundedBox(
  radius: 20,
  backgroundColor: Colors.blue,
  gradient: LinearGradient(...),
  border: Border.all(color: Colors.white),
  shadow: [BoxShadow(...)],
  innerPadding: EdgeInsets.symmetric(horizontal: 12, vertical: 6),
  outerMargin: EdgeInsets.all(4),
  width: 120,
  height: 40,
)

// ── Background ──
Icon(Icons.star).withBackground(
  Colors.amber,
  radius: 8,
  innerPadding: EdgeInsets.all(8),
)

// ── Shadow ──
widget.withShadow(
  color: Colors.black26,
  blurRadius: 8,
  offset: Offset(0, 2),
  spreadRadius: 0,
  borderRadius: 12,
)

// ── Card ──
widget.asCard(elevation: 4, radius: 16, color: Colors.white)

// ── Tap ──
widget.onTap(() => doSomething())
widget.onTap(() => doSomething(), borderRadius: BorderRadius.circular(8))

// ── InkWell (Material ripple) ──
widget.onInkTap(
  () => doSomething(),
  borderRadius: BorderRadius.circular(8),
  splashColor: Colors.blue.withOpacity(0.2),
)

// ── Long Press ──
widget.onLongPress(() => showMenu())

// ── Visibility ──
widget.withVisibility(false)                  // hidden
widget.withVisibility(false, maintainSize: true) // invisible but takes space

// ── Opacity ──
widget.withOpacity(0.5)

// ── Border ──
widget.withBorder(color: Colors.grey, width: 1, radius: 8)

Transform #

widget.rotated(0.785)                          // rotate by radians (≈45°)
widget.scaled(1.2)                             // scale up 120%
widget.translated(Offset(10, -5))              // translate by offset

Clip & Border #

widget.clipRect()                              // ClipRect
widget.clipOval()                              // ClipOval (circle/ellipse)
widget.clipRounded(12)                         // ClipRRect with radius
widget.asCircle(size: 80, backgroundColor: Colors.grey)  // circle container

Helpers #

widget.withTooltip('Helpful info')             // Tooltip wrapper
widget.asHero('unique-tag')                    // Hero animation
widget.withAspectRatio(16 / 9)                 // AspectRatio
widget.safeArea()                              // SafeArea (all edges)
widget.safeArea(top: true, bottom: false)      // selective SafeArea
widget.ignorePointer()                         // IgnorePointer
widget.absorbPointer()                         // AbsorbPointer

Image Extensions #

Extensions on Image widgets for shape, filter, overlay, and animation.

Shape #

Image.asset('photo.png').rounded(16)           // rounded corners
Image.asset('photo.png').circular(size: 80)    // circular crop
Image.asset('photo.png').bordered(
  color: Colors.white,
  width: 3,
  radius: 12,
)
Image.network(url).circleAvatar(
  size: 60,
  borderColor: Colors.white,
  borderWidth: 2,
  shadow: [BoxShadow(blurRadius: 8)],
)

Shadow & Color #

Image.asset('photo.png').shadow(
  blurRadius: 12,
  offset: Offset(0, 4),
  color: Colors.black26,
)

Image.asset('photo.png').colorFiltered(
  color: Colors.blue,
  blendMode: BlendMode.colorBurn,
)

Image.asset('photo.png').grayscale()           // black & white
Image.asset('photo.png').sepia()               // antique effect
Image.asset('photo.png').opacity(0.7)          // semi-transparent

Blur & Overlay #

Image.asset('bg.png').blurred(sigmaX: 5, sigmaY: 5)

Image.asset('banner.png').gradientOverlay(
  colors: [Colors.transparent, Colors.black87],
  begin: Alignment.topCenter,
  end: Alignment.bottomCenter,
  borderRadius: 12,
)

Image.asset('banner.png').colorOverlay(Colors.black45)

Size & Animation #

Image.asset('photo.png').sized(width: 200, height: 150)
Image.asset('photo.png').ratio(16 / 9)
Image.network(url).fadeIn(duration: Duration(milliseconds: 500))

String → Image Shortcuts #

Create image widgets directly from strings:

// ── Asset ──
'assets/logo.png'.asAssetImage(width: 120, fit: BoxFit.contain)

// ── Network ──
'https://example.com/photo.jpg'.asNetworkImage(
  width: 200,
  height: 200,
  fit: BoxFit.cover,
)

// ── Smart Network (with loading spinner + error fallback) ──
'https://example.com/photo.jpg'.asSmartNetworkImage(
  width: 200,
  height: 200,
  fit: BoxFit.cover,
  borderRadius: 12,
  placeholder: CircularProgressIndicator(),
  errorWidget: Icon(Icons.error),
)

// ── Image Providers ──
'assets/logo.png'.toAssetImageProvider()
'https://example.com/photo.jpg'.toNetworkImageProvider()

// ── Decoration Images (for Container backgrounds) ──
'assets/bg.png'.asDecorationImage(fit: BoxFit.cover)
'https://example.com/bg.jpg'.asNetworkDecorationImage(opacity: 0.8)

// ── ImageProvider Extensions ──
AssetImage('logo.png').toImage(width: 100)
NetworkImage(url).toCircleAvatar(radius: 30)
AssetImage('logo.png').toDecorationImage(fit: BoxFit.cover)
NetworkImage(url).toInk(width: 200, height: 150)

Layout Extensions #

List → Column / Row #

Build Column or Row from a list of widgets with optional spacing:

// Column with spacing
[
  Text('First'),
  Text('Second'),
  Text('Third'),
].column(spacing: 8)

// Column with full customization
[widgets].column(
  mainAxisAlignment: MainAxisAlignment.center,
  crossAxisAlignment: CrossAxisAlignment.start,
  mainAxisSize: MainAxisSize.min,
  spacing: 12,
)

// Row with spacing
[Icon(Icons.star), Text('Favorite')].row(spacing: 4)

// Row with full customization
[widgets].row(
  mainAxisAlignment: MainAxisAlignment.spaceBetween,
  crossAxisAlignment: CrossAxisAlignment.center,
  spacing: 8,
)

Axis Alignment on Existing Widgets #

Chain alignment properties directly on Column or Row:

// Column cross-axis
Column(children: [...]).crossStart
Column(children: [...]).crossCenter
Column(children: [...]).crossEnd
Column(children: [...]).crossStretch

// Column main-axis
Column(children: [...]).mainStart
Column(children: [...]).mainCenter
Column(children: [...]).mainEnd
Column(children: [...]).mainSpaceBetween
Column(children: [...]).mainSpaceAround
Column(children: [...]).mainSpaceEvenly

// Row cross-axis
Row(children: [...]).crossStart
Row(children: [...]).crossCenter
Row(children: [...]).crossEnd
Row(children: [...]).crossStretch

// Row main-axis
Row(children: [...]).mainStart
Row(children: [...]).mainEnd
Row(children: [...]).mainSpaceBetween
Row(children: [...]).mainSpaceEvenly

// ── Chain them together ──
Column(children: [...]).crossCenter.mainSpaceBetween
Row(children: [...]).mainEnd.crossStretch

All navigation shortcuts are available directly on BuildContext:

// ── Basic Navigation ──
context.pushPage(DetailPage())
context.pop()
context.pop(result)  // pop with result

// ── Replacement ──
context.pushReplacementPage(HomePage())

// ── Clear Stack ──
context.pushAndRemoveUntilPage(LoginPage())  // removes all routes
context.pushAndRemoveUntilPage(
  HomePage(),
  predicate: (route) => route.isFirst,       // custom predicate
)

// ── Named Routes ──
context.pushNamed('/detail', arguments: {'id': 42})
context.pushReplacementNamed('/home')

// ── With Transitions ──
context.pushPage(
  ProfilePage(),
  transitionBuilder: RouteTransitions.fadeIn(),
  transitionDuration: Duration(milliseconds: 400),
)

context.pushReplacementPage(
  HomePage(),
  transitionBuilder: RouteTransitions.slideFromBottom(),
)

// ── Fullscreen Dialog ──
context.pushPage(SettingsPage(), fullscreenDialog: true)

// ── Navigator accessor ──
context.navigator  // Navigator.of(context)

Route Transitions #

RouteTransitions provides 17+ ready-to-use transition builders:

// ── Basic ──
RouteTransitions.fadeIn()                // fade in
RouteTransitions.slide()                 // slide from right (default)
RouteTransitions.scale()                 // zoom
RouteTransitions.rotation()              // rotate

// ── Directional Slides ──
RouteTransitions.slideFromTop()
RouteTransitions.slideFromBottom()
RouteTransitions.slideFromLeft()
RouteTransitions.slideFromRight()

// ── Size ──
RouteTransitions.size()                  // expand vertically
RouteTransitions.size(axis: Axis.horizontal) // expand horizontally

// ── Combined ──
RouteTransitions.fadeScale()             // fade + scale
RouteTransitions.fadeSlide()             // fade + slide from bottom
RouteTransitions.fadeRotate()            // fade + rotate
RouteTransitions.scaleRotate()           // scale + rotate
RouteTransitions.slideScale()            // slide + scale

// ── 3D Flip ──
RouteTransitions.flipX()                 // flip around X axis
RouteTransitions.flipY()                 // flip around Y axis

// ── Presets ──
RouteTransitions.zoomIn()                // fast zoom in
RouteTransitions.zoomOut()               // zoom out
RouteTransitions.bounceIn()              // bounce effect
RouteTransitions.elasticIn()             // elastic spring

// ── Custom curve ──
RouteTransitions.fadeIn(curve: Curves.easeInOutCubic)
RouteTransitions.slide(begin: Offset(0.5, 0.5), curve: Curves.bounceOut)

Usage with navigation:

context.pushPage(
  DetailPage(),
  transitionBuilder: RouteTransitions.fadeScale(),
  transitionDuration: Duration(milliseconds: 500),
);

Log Extensions #

Debug logging shortcuts on String:

'User logged in'.debugLog()               // debugPrint
'Loading data'.infoLog()                  // log level 800 (INFO)
'Cache miss'.warningLog()                 // log level 900 (WARNING)
'Connection failed'.errorLog()            // log level 1000 (ERROR)

// Custom log name
'Data fetched'.infoLog(name: 'API')       // [API] Data fetched
'Timeout'.errorLog(name: 'NETWORK')       // [NETWORK] Timeout

Reusable Widgets #

CustomAppBar #

A fully customizable AppBar that implements PreferredSizeWidget:

CustomAppBar(
  // Title
  title: 'Home Page',
  titleWidget: CustomTitleWidget(),       // overrides title
  titleStyle: TextStyle(fontSize: 20),
  titleColor: Colors.white,
  titleFontSize: 18,
  titleFontWeight: FontWeight.bold,
  centerTitle: true,

  // Leading
  leadingIcon: Icons.menu,
  leadingIconColor: Colors.white,
  leadingIconSize: 24,
  onLeadingPressed: () => openDrawer(),
  leading: CustomWidget(),                // overrides leadingIcon
  automaticallyImplyLeading: true,

  // Actions
  actions: [
    CustomIconButton(iconData: Icons.search, onPressed: () {}),
    CustomIconButton(iconData: Icons.more_vert, onPressed: () {}),
  ],

  // Appearance
  backgroundColor: Colors.indigo,
  gradient: LinearGradient(colors: [Colors.indigo, Colors.purple]),
  elevation: 4,
  shadowColor: Colors.black26,
  shape: RoundedRectangleBorder(
    borderRadius: BorderRadius.vertical(bottom: Radius.circular(16)),
  ),
  borderRadius: 16,                       // shortcut for bottom corners

  // Bottom (TabBar etc.)
  bottom: TabBar(tabs: [...]),

  // Status bar
  systemOverlayStyle: SystemUiOverlayStyle.light,
)

CustomButton #

General purpose button with loading state, gradient, and full customization:

CustomButton(
  text: 'Sign In',
  onPressed: () => signIn(),
  onLongPress: () => showOptions(),

  // Icon
  iconData: Icons.login,
  iconSize: 20,
  iconColor: Colors.white,
  iconSpacing: 8,

  // Size
  width: double.infinity,
  height: 48,
  padding: EdgeInsets.symmetric(horizontal: 24),
  borderRadius: 12,

  // Colors
  backgroundColor: Colors.indigo,
  foregroundColor: Colors.white,
  disabledBackgroundColor: Colors.grey,

  // Loading state
  isLoading: _isLoading,
  loadingColor: Colors.white,
  loadingSize: 20,

  // Disabled state
  isDisabled: false,

  // Gradient
  gradient: LinearGradient(colors: [Colors.indigo, Colors.purple]),

  // Border
  borderColor: Colors.indigoAccent,
  borderWidth: 2,

  // Elevation
  elevation: 4,

  // Tooltip
  tooltip: 'Sign in to your account',
)

CustomIconButton #

Circular icon button with badge support:

CustomIconButton(
  iconData: Icons.notifications,
  onPressed: () => showNotifications(),
  size: 48,
  backgroundColor: Colors.indigo,
  foregroundColor: Colors.white,
  borderColor: Colors.white,
  borderWidth: 2,
  elevation: 4,

  // Badge
  badgeCount: 5,
  badgeColor: Colors.red,
  badgeTextColor: Colors.white,
  showBadge: true,

  // Loading
  isLoading: false,
  isDisabled: false,

  // Gradient
  gradient: RadialGradient(colors: [Colors.indigo, Colors.purple]),
)

CustomBottomSheet #

Feature-rich bottom sheet — use as widget or show directly:

// ── Quick show ──
CustomBottomSheet.show(
  context,
  title: 'Filter Options',
  subtitle: 'Select your preferences',
  child: FilterWidget(),

  // Handle
  showHandle: true,
  handleColor: Colors.grey,

  // Close button
  showCloseButton: true,

  // Actions
  primaryActionText: 'Apply',
  onPrimaryAction: () => applyFilter(),
  secondaryActionText: 'Reset',
  onSecondaryAction: () => resetFilter(),

  // Appearance
  backgroundColor: Colors.white,
  borderRadius: 20,
  elevation: 8,

  // Size
  maxHeight: 0.8,  // 80% of screen
  padding: EdgeInsets.all(16),

  // Behavior
  isDismissible: true,
  enableDrag: true,
  isDraggable: true,
  useSafeArea: true,

  // Draggable options
  initialChildSize: 0.5,
  minChildSize: 0.25,
  maxChildSize: 0.9,
  snap: true,

  // Scroll
  isScrollable: true,
);

// ── As widget (inside a builder) ──
CustomBottomSheet(
  title: 'Options',
  children: [
    ListTile(title: Text('Option 1')),
    ListTile(title: Text('Option 2')),
  ],
  footer: CustomButton(text: 'Done', onPressed: () {}),
)

CustomTextField #

A production-ready, type-driven smart text field built on top of FormBuilderTextField. Select a CustomFieldType and the widget automatically configures keyboard type, autofill hints, obscure mode, and validation rules — all with Turkish error messages by default.

Requires: flutter_form_builder and form_builder_validators (already included as transitive dependencies).

CustomFieldType Enum

Type Keyboard Autofill Obscure Default Min Length
text text false
email emailAddress email false
phone phone telephoneNumber false
password visiblePassword password true 6
number number false
studentNumber number false 6

Basic Usage

// Simple text field
CustomTextField(
  name: 'username',
  label: 'Kullanıcı Adı',
  hint: 'Kullanıcı adınızı girin',
  required: true,
)

// Email field — auto keyboard, autofill & validation
CustomTextField(
  name: 'email',
  type: CustomFieldType.email,
  label: 'E-posta',
  required: true,
)

// Password field — auto obscure, toggle icon, min 6 chars
CustomTextField(
  name: 'password',
  type: CustomFieldType.password,
  label: 'Şifre',
  required: true,
)

// Phone field — numeric keyboard, phone autofill
CustomTextField(
  name: 'phone',
  type: CustomFieldType.phone,
  label: 'Telefon',
  required: true,
)

// Number field — numeric keyboard & validation
CustomTextField(
  name: 'age',
  type: CustomFieldType.number,
  label: 'Yaş',
)

// Student number — numeric, min 6 chars
CustomTextField(
  name: 'student_no',
  type: CustomFieldType.studentNumber,
  label: 'Öğrenci No',
  required: true,
)

Password Toggle & Clear Button

// Password with show/hide toggle (enabled by default)
CustomTextField(
  name: 'password',
  type: CustomFieldType.password,
  label: 'Şifre',
  showPasswordToggle: true,   // 👁 toggle icon (default: true)
)

// Text field with clear button (requires controller)
final _controller = TextEditingController();

CustomTextField(
  name: 'search',
  label: 'Ara',
  controller: _controller,
  showClearButton: true,       // ✕ clear icon when text is present
)

Focus Management & Submit Flow

final _emailFocus = FocusNode();
final _passwordFocus = FocusNode();

// Email → Password auto-focus on submit
CustomTextField(
  name: 'email',
  type: CustomFieldType.email,
  label: 'E-posta',
  focusNode: _emailFocus,
  nextFocusNode: _passwordFocus,  // pressing "Next" moves focus here
)

CustomTextField(
  name: 'password',
  type: CustomFieldType.password,
  label: 'Şifre',
  focusNode: _passwordFocus,
  onSubmitted: (_) => _submit(),  // pressing "Done" submits the form
)

Validation & Custom Error Messages

// Required + custom error messages
CustomTextField(
  name: 'email',
  type: CustomFieldType.email,
  label: 'E-posta',
  required: true,
  requiredMessage: 'E-posta adresi gereklidir',
  invalidEmailMessage: 'Lütfen geçerli bir e-posta girin',
)

// Min/max length validation
CustomTextField(
  name: 'bio',
  label: 'Biyografi',
  minLength: 10,
  maxLengthValidator: 200,
  maxLength: 200,              // shows counter
  showCounter: true,
  maxLines: 5,
  minLengthMessage: 'En az 10 karakter yazmalısınız',
  maxLengthMessage: 'En fazla 200 karakter olabilir',
)

// Custom validator
CustomTextField(
  name: 'code',
  label: 'Davet Kodu',
  customValidator: (value) {
    if (value != null && !value.startsWith('INV-')) {
      return 'Kod "INV-" ile başlamalıdır';
    }
    return null;
  },
)

Value Transform

// Trim & lowercase before saving
CustomTextField(
  name: 'email',
  type: CustomFieldType.email,
  label: 'E-posta',
  transform: (value) => value?.trim().toLowerCase(),
)

Decoration Customization

// Custom borders & padding
CustomTextField(
  name: 'note',
  label: 'Not',
  contentPadding: EdgeInsets.symmetric(horizontal: 16, vertical: 12),
  border: OutlineInputBorder(borderRadius: BorderRadius.circular(12)),
  focusedBorder: OutlineInputBorder(
    borderRadius: BorderRadius.circular(12),
    borderSide: BorderSide(color: Colors.indigo, width: 2),
  ),
  style: TextStyle(fontSize: 16),
  labelStyle: TextStyle(color: Colors.grey),
)

// Full decoration override
CustomTextField(
  name: 'custom',
  decoration: InputDecoration(
    labelText: 'Tam Özel',
    filled: true,
    fillColor: Colors.grey.shade100,
    border: OutlineInputBorder(borderRadius: BorderRadius.circular(20)),
  ),
)

Icons

// Prefix & suffix icons
CustomTextField(
  name: 'email',
  type: CustomFieldType.email,
  label: 'E-posta',
  prefixIcon: Icon(Icons.email_outlined),
  suffixIcon: Icon(Icons.check_circle, color: Colors.green),
)

Full Form Example

final _formKey = GlobalKey<FormBuilderState>();
final _passwordFocus = FocusNode();
final _searchController = TextEditingController();

FormBuilder(
  key: _formKey,
  child: Column(
    children: [
      CustomTextField(
        name: 'email',
        type: CustomFieldType.email,
        label: 'E-posta',
        prefixIcon: Icon(Icons.email_outlined),
        required: true,
        nextFocusNode: _passwordFocus,
        transform: (v) => v?.trim().toLowerCase(),
      ),
      SizedBox(height: 16),
      CustomTextField(
        name: 'password',
        type: CustomFieldType.password,
        label: 'Şifre',
        prefixIcon: Icon(Icons.lock_outline),
        required: true,
        focusNode: _passwordFocus,
        minLength: 8,
      ),
      SizedBox(height: 16),
      CustomTextField(
        name: 'phone',
        type: CustomFieldType.phone,
        label: 'Telefon',
        prefixIcon: Icon(Icons.phone_outlined),
      ),
      SizedBox(height: 24),
      ElevatedButton(
        onPressed: () {
          if (_formKey.currentState?.saveAndValidate() ?? false) {
            final data = _formKey.currentState!.value;
            print(data); // {email: ..., password: ..., phone: ...}
          }
        },
        child: Text('Giriş Yap'),
      ),
    ],
  ),
)

All Parameters

Parameter Type Default Description
name * String FormBuilder field name (required)
type CustomFieldType .text Field type — drives defaults
label String? null Label text
hint String? null Hint text
helperText String? null Helper text below the field
initialValue String? null Initial value
controller TextEditingController? null External text controller
focusNode FocusNode? null External focus node
nextFocusNode FocusNode? null Focus moves here on submit
enabled bool true Whether the field is enabled
readOnly bool false Read-only mode
autofocus bool false Auto-focus on build
obscureText bool? null (type default) Obscure text override
enableSuggestions bool true Keyboard suggestions
autocorrect bool true Auto-correct
maxLength int? null Max character count (with counter)
maxLines int 1 Max lines
minLines int? null Min lines
keyboardType TextInputType? null (type default) Keyboard type override
textInputAction TextInputAction? null (auto: next/done) Keyboard action button
inputFormatters List<TextInputFormatter>? null Input formatters
autofillHints Iterable<String>? null (type default) Autofill hints override
showCounter bool false Show character counter
showClearButton bool false Show clear (×) icon (needs controller)
showPasswordToggle bool true Show password toggle (password type only)
prefixIcon Widget? null Leading icon
suffixIcon Widget? null Trailing icon (combined with toggle/clear)
onTap VoidCallback? null On tap callback
onChanged ValueChanged<String?>? null On change callback
onSubmitted ValueChanged<String?>? null On submit callback
transform String? Function(String?)? null Value transformer before save
autovalidateMode AutovalidateMode .onUserInteraction Validation trigger mode
required bool false Required field rule
minLength int? null (type default) Min length validation
maxLengthValidator int? null Max length validation
customValidator FormFieldValidator<String>? null Custom validator (appended last)
requiredMessage String? 'Bu alan zorunludur' Required error override
invalidEmailMessage String? 'Geçerli bir e-posta...' Email error override
invalidPhoneMessage String? 'Geçerli bir telefon...' Phone error override
minLengthMessage String? 'En az N karakter...' Min length error override
maxLengthMessage String? 'En fazla N karakter...' Max length error override
numericMessage String? 'Sadece rakam girin' Numeric error override
decoration InputDecoration? null Full decoration override
contentPadding EdgeInsetsGeometry? null Content padding
border InputBorder? null Default border
enabledBorder InputBorder? null Enabled border
focusedBorder InputBorder? null Focused border
errorBorder InputBorder? null Error border
style TextStyle? null Field text style
labelStyle TextStyle? null Label style
hintStyle TextStyle? null Hint style

Full Export Tree #

All public API is exposed through a single barrel file — import 'package:wonzy_core_utils/core_utils.dart';

lib/core_utils.dart
│
├── Context Extensions
│   └── ContextExtension on BuildContext
│       (screenSize, width, height, theme, colorScheme, textTheme,
│        primaryColor, secondaryColor, ..., appBarTheme, cardTheme, ...)
│
├── Layout Extensions
│   ├── ColumnCrossAxis / ColumnMainAxis on Column
│   │   (.crossStart, .crossCenter, .mainSpaceBetween, ...)
│   ├── RowCrossAxis / RowMainAxis on Row
│   │   (.crossStart, .mainEnd, .mainSpaceEvenly, ...)
│   ├── ColumnExtension on List<Widget>
│   │   (.column(spacing: ...))
│   └── RowExtension on List<Widget>
│       (.row(spacing: ...))
│
├── Navigation Extensions
│   ├── NavigatorExtensions on BuildContext
│   │   (.pushPage, .pop, .pushReplacementPage, .pushAndRemoveUntilPage,
│   │    .pushNamed, .pushReplacementNamed)
│   └── RouteTransitions (static class)
│       (.fadeIn, .slide, .slideFromTop, .slideFromBottom, .scale,
│        .rotation, .size, .fadeScale, .fadeSlide, .fadeRotate,
│        .scaleRotate, .flipX, .flipY, .zoomIn, .zoomOut,
│        .bounceIn, .elasticIn, .slideScale)
│
├── Primitive Extensions
│   ├── SizeExtensions on num
│   │   (.h, .w, .height, .width, .all, .horizontal, .vertical,
│   │    .radius, .ms, .seconds)
│   ├── StringExtensions on String
│   │   (.capitalize, .toTitleCase, .toSnakeCase, .toKebabCase,
│   │    .toCamelCase, .isNumeric, .isAlphabetic, .isAlphanumeric,
│   │    .reversed, .ellipsis, .containsIgnoreCase, .stripHtml,
│   │    .toBool, .toTurkishPhoneFormat, .toUsername, .toGmail, ...)
│   └── TextBuilderExtension on String
│       (.text → TextBuilder chainable API)
│
├── Utility Extensions
│   └── LogExtensions on String
│       (.debugLog, .infoLog, .warningLog, .errorLog)
│
├── Widget Extensions
│   ├── PaddingExtensions on Widget
│   │   (.paddingAll, .paddingHorizontal, .paddingVertical,
│   │    .paddingSymmetric, .paddingOnly, .padding,
│   │    .marginAll, .marginHorizontal, .marginVertical, .marginOnly)
│   ├── AlignmentExtensions on Widget
│   │   (.center, .alignLeft, .alignRight, .alignTop, .alignBottom, .align)
│   ├── ContainerExtensions on Widget
│   │   (.container(...))
│   ├── FlexExtensions on Widget
│   │   (.expanded, .flexible)
│   ├── SizeConstraintExtensions on Widget
│   │   (.sized, .square, .expandedWidth, .expandedHeight, .constrained)
│   ├── WidgetDecorationExtensions on Widget
│   │   (.roundedBox, .withBackground, .withShadow, .asCard,
│   │    .onTap, .onInkTap, .onLongPress, .withVisibility, .withOpacity,
│   │    .rotated, .scaled, .translated, .withTooltip, .asHero,
│   │    .withAspectRatio, .safeArea, .ignorePointer, .absorbPointer,
│   │    .clipRect, .clipOval, .clipRounded, .asCircle, .withBorder)
│   └── ImageExtensions on Image
│       (.rounded, .circular, .bordered, .circleAvatar, .shadow,
│        .colorFiltered, .grayscale, .sepia, .opacity, .blurred,
│        .sized, .ratio, .gradientOverlay, .colorOverlay, .fadeIn)
│
├── String → Image Extensions
│   ├── StringImageExtensions on String
│   │   (.asAssetImage, .asNetworkImage, .asSmartNetworkImage,
│   │    .toAssetImageProvider, .toNetworkImageProvider,
│   │    .asDecorationImage, .asNetworkDecorationImage)
│   └── ImageProviderExtensions on ImageProvider
│       (.toImage, .toDecorationImage, .toCircleAvatar, .toInk)
│
└── Reusable Widgets
    ├── CustomAppBar         (PreferredSizeWidget)
    ├── CustomBottomSheet    (widget + static show method)
    ├── CustomButton         (general purpose button)
    ├── CustomIconButton     (circular icon button with badge)
    └── CustomTextField      (type-driven smart text field)

Requirements #

Requirement Version
Dart SDK ^3.11.0
Flutter >=3.29.0

Contributing #

See CONTRIBUTING.md for guidelines.

License #

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

1
likes
160
points
11
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

Flutter/Dart extensions and reusable widgets for rapid UI development. Context helpers, navigation shortcuts, text builders, layout extensions, and customizable widgets.

Repository (GitHub)
View/report issues
Contributing

Topics

#extensions #widget #ui #utilities

License

MIT (license)

Dependencies

flutter, flutter_form_builder, form_builder_validators

More

Packages that depend on wonzy_core_utils