code_formatter_package 1.0.0 copy "code_formatter_package: ^1.0.0" to clipboard
code_formatter_package: ^1.0.0 copied to clipboard

A Flutter package for formatting and splitting Dart code into widgets.

Code Formatter Package #

A powerful Flutter package for splitting large Dart files containing multiple widgets into separate, well-organized files.

pub package License: MIT

Features #

  • Widget Extraction: Automatically extracts StatelessWidget and StatefulWidget classes from your code
  • State Class Bundling: Automatically includes the corresponding State class with each StatefulWidget
  • Import Preservation: Preserves all import statements from the original file
  • Smart Naming: Uses widget class names for file naming (PascalCase to snake_case conversion)
  • Flexible Configuration: Customize output directory, file names, and more
  • Detailed Results: Returns comprehensive results with success/failure status and warnings
  • Async Support: Provides both sync and async methods for file operations
  • Error Handling: Proper error types and messages for debugging

Installation #

Add this to your pubspec.yaml:

dependencies:
  code_formatter_package: ^1.0.0

Then run:

flutter pub get

Usage #

Basic Usage - Format Code from String #

import 'package:code_formatter_package/code_formatter_package.dart';

void main() {
  const code = '''
import 'package:flutter/material.dart';

class HomeScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Home')),
      body: Center(child: Text('Hello World')),
    );
  }
}

class ProfileScreen extends StatefulWidget {
  @override
  State<ProfileScreen> createState() => _ProfileScreenState();
}

class _ProfileScreenState extends State<ProfileScreen> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(child: Text('Profile')),
    );
  }
}
''';

  final result = CodeFormatter.formatCode(code);

  if (result.success) {
    print('Successfully extracted ${result.widgets.length} widgets:');
    for (final widget in result.widgets) {
      print('  - ${widget.className} -> ${widget.savedPath}');
    }
  } else {
    print('Error: ${result.errorMessage}');
  }
}

This will create:

  • lib/generated_widgets/home_screen.dart
  • lib/generated_widgets/profile_screen.dart (includes _ProfileScreenState class)

Format Code from File #

final result = CodeFormatter.formatFile('lib/screens/all_screens.dart');

if (result.success) {
  print('Extracted ${result.widgets.length} widgets');
} else {
  print('Error: ${result.errorMessage}');
}

Using Configuration Options #

final result = CodeFormatter.formatCode(
  myCode,
  config: FormatterConfig(
    outputDir: 'lib/widgets/generated',
    useClassNameAsFileName: true,
    includeFlutterImports: true,
    includeHeaderComment: true,
    overwriteExisting: false,
  ),
);

Custom File Names #

final result = CodeFormatter.formatCode(
  myCode,
  config: FormatterConfig(
    customNames: ['home_widget', 'profile_widget'],
    outputDir: 'lib/custom_widgets',
  ),
);

Async File Formatting #

final result = await CodeFormatter.formatFileAsync(
  'lib/screens/large_file.dart',
  config: FormatterConfig(outputDir: 'lib/widgets'),
);

Preview Widgets Without Saving #

final widgets = CodeFormatter.previewWidgets(myCode);

for (final widget in widgets) {
  print('Found widget: ${widget.className}');
  print('Is StatefulWidget: ${widget.isStateful}');
  if (widget.associatedClasses.isNotEmpty) {
    print('Associated classes: ${widget.associatedClasses.join(", ")}');
  }
}

Flutter App Integration #

class MyApp extends StatefulWidget {
  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  @override
  void initState() {
    super.initState();

    CodeFormatter.initializeFormatter(
      'lib/screens/home.dart',
      config: FormatterConfig(outputDir: 'lib/widgets'),
      onComplete: (result) {
        if (result.success) {
          print('Formatted ${result.widgets.length} widgets');
        } else {
          print('Error: ${result.errorMessage}');
        }
      },
    );
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(home: HomeScreen());
  }
}

Configuration Options #

Option Type Default Description
outputDir String 'lib/generated_widgets' Output directory for generated files
customNames List<String>? null Custom file names for generated widgets
useClassNameAsFileName bool true Use widget class name as file name
includeFlutterImports bool true Add Flutter imports if not present
includeHeaderComment bool true Add header comment to generated files
formatOutput bool true Format the output code
overwriteExisting bool true Overwrite existing files

API Reference #

Classes #

CodeFormatter

Main class with static methods for formatting code.

Methods:

  • formatCode(String code, {FormatterConfig config}) - Format code from string
  • formatFile(String filePath, {FormatterConfig config}) - Format code from file
  • formatFileAsync(String filePath, {FormatterConfig config}) - Async file formatting
  • initializeFormatter(String filePath, {FormatterConfig config, Function? onComplete}) - Flutter lifecycle integration
  • previewWidgets(String code) - Preview widgets without saving

FormatterResult

Result object returned by formatting methods.

Properties:

  • success - Whether the operation succeeded
  • widgets - List of extracted widgets
  • errorMessage - Error message if failed
  • errorType - Type of error if failed
  • warnings - List of warnings

ExtractedWidget

Represents an extracted widget.

Properties:

  • className - Name of the widget class
  • sourceCode - Full source code including imports
  • savedPath - Path where widget was saved
  • isStateful - Whether it's a StatefulWidget
  • associatedClasses - List of associated class names

FormatterConfig

Configuration options for the formatter.

CodeFormatterException

Exception thrown when formatting fails.

CodeFormatterErrorType

Enum of possible error types:

  • fileNotFound
  • fileWriteError
  • parseError
  • noWidgetsFound
  • directoryCreationError
  • invalidInput
  • unknown

Error Handling #

final result = CodeFormatter.formatFile('lib/my_file.dart');

if (!result.success) {
  switch (result.errorType) {
    case CodeFormatterErrorType.fileNotFound:
      print('File not found!');
      break;
    case CodeFormatterErrorType.noWidgetsFound:
      print('No widgets in this file');
      break;
    case CodeFormatterErrorType.parseError:
      print('Could not parse the code');
      break;
    default:
      print('Error: ${result.errorMessage}');
  }
}

// Check for warnings
if (result.warnings.isNotEmpty) {
  print('Warnings:');
  for (final warning in result.warnings) {
    print('  - $warning');
  }
}

Example Output #

Input file with multiple widgets:

// lib/screens/home.dart
import 'package:flutter/material.dart';

class HomeScreen extends StatelessWidget { ... }
class SettingsScreen extends StatefulWidget { ... }
class _SettingsScreenState extends State<SettingsScreen> { ... }

Output files:

lib/generated_widgets/
├── home_screen.dart      // Contains HomeScreen
└── settings_screen.dart  // Contains SettingsScreen + _SettingsScreenState

Each generated file includes:

  • Header comment with widget name
  • Required imports (Flutter + original imports)
  • Widget class definition
  • Associated State class (for StatefulWidget)

Requirements #

  • Dart SDK: >=3.4.4 <4.0.0
  • Flutter: >=3.0.0

License #

MIT License - see LICENSE for details.

Contributing #

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

Issues #

If you find a bug or have a feature request, please open an issue on GitHub.

2
likes
150
points
134
downloads

Publisher

unverified uploader

Weekly Downloads

A Flutter package for formatting and splitting Dart code into widgets.

Repository (GitHub)
View/report issues

Documentation

API reference

License

MIT (license)

Dependencies

analyzer, flutter, path

More

Packages that depend on code_formatter_package