flutter_2yaml 0.6.0 copy "flutter_2yaml: ^0.6.0" to clipboard
flutter_2yaml: ^0.6.0 copied to clipboard

Convert Flutter widget files into compact YAML optimized for LLM token consumption, and back again. Pipe syntax, CSS-like shorthands, arrow callbacks.

0.6.0 #

Correctness release. Every item below is a bug that silently dropped or corrupted information; each is covered by a regression test in test/regression_test.dart.

Forward (Dart → YAML) — silent data loss fixed #

  • Hex colorsColor(0xFF123456) produced bg: Color, losing the value entirely. Now emits #123456, and keeps a non-opaque alpha channel as #AARRGGBB. Applies to const and non-const forms alike.
  • if/else children — a conditional child with an else branch lost both its condition and the alternative. Conditions are now emitted for complex children too, and the alternative is written as an else: branch.
  • Non-const EdgeInsets — the p/px/py shorthands only fired on const EdgeInsets…; a bare EdgeInsets.symmetric(...) lost its numbers. All forms are now recognised, plus EdgeInsets.zero and fromLTRB.
  • EdgeInsets.symmetric with both axes emitted the malformed mx: 16, my, dropping the vertical value (a split-on-= bug).
  • Theme-based text stylesText('x', style: Theme.of(context).textTheme.y) dropped the style. Kept now, as style: theme.y.
  • Single-word string literalsText('Home') became the unquoted Text: Home, indistinguishable from the identifier Text: title, so it came back as an undefined identifier. String literals are now quoted.
  • Multiple widget classes per file — only the first was converted and the rest discarded. Every class is now emitted, as one ----separated document each (DartFileAnalyzer.analyzeAll, YamlGenerator.generateAll).
  • switch in build() — produced no build: key at all. Both switch expressions and switch statements now become a switch(...) node with one case/default arm per branch.
  • Named children listsactions, items, tabs and friends were merged into the generic children list, so an AppBar's actions reversed into a children: argument it does not have. Each keeps its own slot now.
  • Generic widget classes kept their name but lost their type parameters.
  • Unrepresentable expressions (a _buildBody(context) build body, a non-widget child) were dropped; they are now preserved verbatim as expr:.
  • Argument values are no longer summarised into invalid Dart — a call's arguments used to be rewritten as the placeholder (...), and string literals inside them lost their quotes.
  • InputDecoration was flattened onto its parent as if it were a BoxDecoration, inventing named arguments the widget does not declare.
  • this.-constructor parameters now carry the type of the field they initialise.
  • Helper methods on a StatelessWidget are captured at --level full, which is what "all methods" promised.
  • Enums and typedefs the widget refers to are carried at --level full, so a widget that switches on a local enum still compiles after a round trip.

Reverse (YAML → Dart) — invalid output fixed #

  • Named slots emitted empty argumentsappBar: ,, title: ,, icon: , and builder: , were produced for the converter's own forward output, a hard syntax error on any screen with an AppBar or a list builder. Slot keys are now parsed as child slots instead of value-less properties.
  • for-in elements generated for(child: ProductCard(...)); spreads were dropped silently. Both now emit valid collection elements, and the documented keyword-less for(item in items) form is made valid Dart.
  • Single-child Row/Column/Stack reversed to Row(child: …), a parameter those widgets do not have.
  • EdgeInsets double-wrapping produced padding: EdgeInsets.all(EdgeInsets.symmetric(...)).
  • py leaked as a bare argument when paired with px.
  • t/l/r/b/gap/runGap were never expanded, reaching the output in abbreviated form as arguments no widget declares.
  • bg: gradient(...) on a Container became color: Colors.gradient(...).
  • screen.* and theme.* were emitted verbatim, and screen.w could land inside a const constructor.
  • Quoted hex colors (bg: "#123456", which YAML often requires because # starts a comment) became Colors."#123456".
  • Lossy lifecycle summaries were emitted as code — set _x;, controller.close(...);, conditional logic; — none of which parses. They are now emitted as comments, and a navigate: summary becomes a real Navigator call.
  • Custom methods were emitted as @override void _onTap() { super._onTap(); } — an override of nothing calling a member that does not exist. They now keep their parameters and return type.
  • Opaque callback bodies produced validator: () => (...); they now become a valid empty lambda of the right arity.
  • Inline brace syntax dropped nested widgets and arrow callbacks, so the documented AppBar: { title: Text: "Home" | 20 | bold } and { onPressed → add(), child: Icon: add } were copied into the output as garbage.
  • An Icon carrying a callback vanished entirely. It is now generated as the widget that can carry one — an IconButton for onPressed, otherwise a GestureDetector.
  • const is no longer guessed for arbitrary zero-argument widgets; it is emitted only where the const constructor is known to exist.
  • Contradictory shorthands can no longer emit the same named argument twice.
  • Empty named lists (items: []) are preserved rather than dropped.

Documentation #

  • The token-savings claim is now the measured range (40-65%, ~50% average at the default level) rather than 50-70%.
  • New Known Limitations section stating plainly what the format does not carry: summarised method bodies, multi-statement callback bodies, field mutability, and non-enum/typedef top-level code.
  • Documented else: branches, named child slots, switch arms, the expr: escape hatch, --- multi-class documents, generics and declarations:.

Packaging and pub.flutter-io.cn score #

Diagnosed the 120/160 pub score by reading pana's own scoring rules, and fixed every deduction:

  • Description length — at 210 characters the description tripped pana's "description too long" check (the limit is 180). A single non-URL pubspec issue zeroes the whole 10-point subsection rather than deducting from it, which is the entire 20/30 in "Follow Dart file conventions".
  • Static analysis — the correctness rewrite above removed the four warnings (two unnecessary_cast, two unused_import) that capped this section at 30/50. They only surface under package:lints/core.yaml, which is what pana analyses with; the package's own recommended + strict-* options reported them differently, so dart analyze alone never showed them as warnings.
  • analyzer dependency — bumped from ^7.4.5 to ^14.0.0 so the constraint admits the latest release. This raises the minimum Dart SDK from 3.8 to 3.11, which analyzer 14 requires. Migrated the AST usage accordingly: NamedExpressionNamedArgument (with Token name and argumentExpression), ArgumentList.arguments now yielding Argument rather than Expression, ClassDeclaration.membersbody.members, ClassDeclaration.name/typeParametersnamePart.*, NamedType.name2name, and the removal of DefaultFormalParameter / SimpleFormalParameter in favour of FormalParameter.defaultClause and RegularFormalParameter.

Verified #

  • dart analyze: clean. dart format: clean. Test suite: 110 tests (was 65).
  • dart pub outdated: no outdated direct dependencies. dart pub downgrade followed by dart analyze is clean, so the dependency lower bounds hold.
  • Every fixture in this repo round-trips Dart → YAML → Dart at --level full into code that passes flutter analyze with zero errors (previously 11 errors plus unparseable output).

0.5.0 #

  • Component reference tags — new <ComponentName:Key=Value> syntax for referencing figma2flutter plugin components in YAML
  • Component tags are parsed by the reverse converter and output as const Text('ComponentName (Variant)') placeholder widgets
  • Warning (not error) printed when component tags are detected: "Full component resolution requires the figma2flutter MCP server"
  • _componentRef internal metadata stored on placeholder nodes for future MCP integration
  • Arrow callbacks in # → comments no longer misinterpreted as widget callbacks
  • Internal _ prefixed properties skipped by the Dart generator
  • Supports all variant patterns: <B-NavBar:Status=Home, Mode=Light>, <Tab Menu:Type=Active, Style=Solid>, <WOWR Card List:Type=WO>, <ComponentName> (no variants)

0.4.1 #

  • Reverse codegen: Container BoxDecorationbg, br, border, shadow, gradient properties on Container are now collected into a single decoration: BoxDecoration(...) instead of emitting raw properties
  • Per-corner border radiusbr: {tl: 24, tr: 24, bl: 0, br: 0} now generates BorderRadius.only(topLeft: Radius.circular(24), topRight: Radius.circular(24)) instead of invalid BorderRadius.circular({...})
  • Border shorthand expansionborder: {c: #121212, w: 1} now generates Border.all(color: Color(0xFF121212), width: 1)
  • Shadow offset fixshadow: {c: black, blur: 3, offset: Offset(0, 1)} no longer crashes on nested commas inside Offset(); now uses paren-aware splitting
  • figma2flutter compatibility — reverse codegen validated against real Figma plugin YAML output (full pages with Stack, Positioned, per-corner radii, shadows, borders)

0.4.0 #

  • Forward conversion hardened — full Scaffold support with named children
  • Named children model: appBar, drawer, floatingActionButton, bottomNavigationBar, endDrawer, bottomSheet, leading, title, icon, label all properly nested
  • Expanded children list detection: slivers, items, destinations
  • SpreadElement support in children lists (...items)
  • ForElement support in children lists (for (x in list) Widget())
  • Ternary expression support (condition ? WidgetA : WidgetB)
  • ListView.builder / GridView.builder itemBuilder pattern extraction
  • BoxDecoration complete: shape, border, image extraction added
  • Border.all shorthand: Border.all(color: black, width: 2)border: {c: black, w: 2}
  • Positioned widget shorthand: top/left/right/bottomt/l/r/b
  • TextStyle complete: wordSpacing, height, decorationColor, decorationStyle, decorationThickness, overflow
  • Icons prefix stripped: Icons.menumenu, Icons.searchsearch
  • double.infinityfull
  • Wrap spacing shorthand: spacinggap, runSpacingrunGap
  • Theme.of(context) shorthand: → theme.textTheme.headline
  • MediaQuery shorthand: → screen.w, screen.h
  • Multiple positional argument support with indexed tracking
  • Complex screen test fixture with full Scaffold + AppBar + Drawer + FAB + BottomNav

0.3.0 #

  • Reverse conversion: YAML → Dart via flutter_2yaml reverse <path.yaml>
  • Full round-trip support: .dart.yaml.dart with idiomatic output
  • YAML parser with pipe syntax, arrow notation, parenthetical alignment parsing
  • Dart code generator producing properly formatted Flutter code
  • Automatic const propagation, super.key constructors, @override annotations
  • Reverse expansion of all shorthands (bg → backgroundColor, p → EdgeInsets.all, etc.)
  • State class skeleton generation for StatefulWidget
  • Lifecycle method generation with proper super. calls
  • Directory-level reverse conversion with --recursive support
  • Programmatic API: YamlParser, DartGenerator, ReverseConverter

0.2.0 #

  • Breaking: Unified Compact Format — complete output format overhaul
  • Pipe syntax for Text, Image, Icon widgets (Text: "Hello" | 20 | bold | white)
  • CSS-like property shorthands (bg, br, p, px, py, h, w)
  • Arrow callback notation (onPressed → handleTap())
  • Parenthetical alignment (Column(center), Row(spaceBetween))
  • Color shorthand (Colors.blueblue)
  • Dimension shorthand (200x200, w: full)
  • Auto-detect state management (GetX, Riverpod, Bloc, Provider)
  • Auto-classify page: vs widget: based on Scaffold presence
  • Compact inline state format (state: [isLoading: bool = true])
  • EdgeInsets shorthand (EdgeInsets.all(16)p: 16)
  • BoxDecoration shorthand (bg, br, shadow, gradient)
  • Support for ConsumerWidget, GetView, and other framework base classes

0.1.0 #

  • Initial release
  • Convert Flutter StatelessWidget and StatefulWidget files to YAML
  • Three verbosity levels: minimal, standard, full
  • CLI support for single file and directory conversion
  • Watch mode for automatic regeneration on file changes
  • Configurable output directory
1
likes
160
points
111
downloads

Documentation

API reference

Publisher

verified publishermsishamim.com

Weekly Downloads

Convert Flutter widget files into compact YAML optimized for LLM token consumption, and back again. Pipe syntax, CSS-like shorthands, arrow callbacks.

Repository (GitHub)
View/report issues
Contributing

License

MIT (license)

Dependencies

analyzer, args, path, watcher

More

Packages that depend on flutter_2yaml