diff --git a/packages/rfw/CHANGELOG.md b/packages/rfw/CHANGELOG.md index ccf06fdf7d2..50f53e0bb86 100644 --- a/packages/rfw/CHANGELOG.md +++ b/packages/rfw/CHANGELOG.md @@ -3,6 +3,10 @@ * Updates minimum supported SDK version to Flutter 3.27/Dart 3.6. * Removes the wasm example. +## 1.0.32 +* Adds support for the `Flexible` core widget. + + ## 1.0.31 * Updates minimum supported SDK version to Flutter 3.22/Dart 3.4. diff --git a/packages/rfw/lib/src/flutter/core_widgets.dart b/packages/rfw/lib/src/flutter/core_widgets.dart index a60e17f0407..bfdfada58f1 100644 --- a/packages/rfw/lib/src/flutter/core_widgets.dart +++ b/packages/rfw/lib/src/flutter/core_widgets.dart @@ -34,6 +34,7 @@ import 'runtime.dart'; /// * [DefaultTextStyle] /// * [Directionality] /// * [Expanded] +/// * [Flexible] /// * [FittedBox] /// * [FractionallySizedBox] /// * [GestureDetector] @@ -349,6 +350,14 @@ Map get _coreWidgetsDefinitions => (['flex']) ?? 1, + fit: ArgumentDecoders.enumValue(FlexFit.values, source, ['fit']) ?? FlexFit.loose, + child: source.child(['child']), + ); + }, + 'FittedBox': (BuildContext context, DataSource source) { return FittedBox( fit: ArgumentDecoders.enumValue(BoxFit.values, source, ['fit']) ?? BoxFit.contain, diff --git a/packages/rfw/pubspec.yaml b/packages/rfw/pubspec.yaml index fa41eb7ef24..d2c6969df37 100644 --- a/packages/rfw/pubspec.yaml +++ b/packages/rfw/pubspec.yaml @@ -2,7 +2,7 @@ name: rfw description: "Remote Flutter widgets: a library for rendering declarative widget description files at runtime." repository: https://github.com/flutter/packages/tree/main/packages/rfw issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+rfw%22 -version: 1.0.31 +version: 1.0.32 environment: sdk: ^3.6.0 diff --git a/packages/rfw/test/core_widgets_test.dart b/packages/rfw/test/core_widgets_test.dart index de2336a3143..2f45e07b700 100644 --- a/packages/rfw/test/core_widgets_test.dart +++ b/packages/rfw/test/core_widgets_test.dart @@ -300,4 +300,137 @@ void main() { expect(renderClip.clipBehavior, equals(Clip.antiAlias)); expect(renderClip.borderRadius, equals(BorderRadius.zero)); }); -} + + testWidgets('Flexible widget', (WidgetTester tester) async { + final Runtime runtime = Runtime() + ..update(const LibraryName(['core']), createCoreWidgets()); + addTearDown(runtime.dispose); + final DynamicContent data = DynamicContent(); + + // Test Flexible with default values + runtime.update(const LibraryName(['test']), parseLibraryFile(''' + import core; + widget root = Directionality( + textDirection: "ltr", + child: Column( + children: [ + Flexible( + child: Text(text: "Default flexible"), + ), + ], + ), + ); + ''')); + + await tester.pumpWidget( + RemoteWidget( + runtime: runtime, + data: data, + widget: const FullyQualifiedWidgetName(LibraryName(['test']), 'root'), + ), + ); + await tester.pump(); + expect(find.byType(Flexible), findsOneWidget); + final Flexible defaultFlexible = tester.widget(find.byType(Flexible)); + expect(defaultFlexible.flex, equals(1)); + expect(defaultFlexible.fit, equals(FlexFit.loose)); + + // Test Flexible with custom flex value + runtime.update(const LibraryName(['test']), parseLibraryFile(''' + import core; + widget root = Directionality( + textDirection: "ltr", + child: Column( + children: [ + Flexible( + flex: 3, + child: Text(text: "Custom flex"), + ), + ], + ), + ); + ''')); + await tester.pumpAndSettle(); + final Flexible customFlexFlexible = tester.widget(find.byType(Flexible)); + expect(customFlexFlexible.flex, equals(3)); + expect(customFlexFlexible.fit, equals(FlexFit.loose)); + + // Test Flexible with fit: "tight" + runtime.update(const LibraryName(['test']), parseLibraryFile(''' + import core; + widget root = Directionality( + textDirection: "ltr", + child: Column( + children: [ + Flexible( + flex: 2, + fit: "tight", + child: Text(text: "Tight fit"), + ), + ], + ), + ); + ''')); + await tester.pumpAndSettle(); + final Flexible tightFlexible = tester.widget(find.byType(Flexible)); + expect(tightFlexible.flex, equals(2)); + expect(tightFlexible.fit, equals(FlexFit.tight)); + + // Test Flexible with fit: "loose" + runtime.update(const LibraryName(['test']), parseLibraryFile(''' + import core; + widget root = Directionality( + textDirection: "ltr", + child: Column( + children: [ + Flexible( + flex: 4, + fit: "loose", + child: Text(text: "Loose fit"), + ), + ], + ), + ); + ''')); + await tester.pumpAndSettle(); + final Flexible looseFlexible = tester.widget(find.byType(Flexible)); + expect(looseFlexible.flex, equals(4)); + expect(looseFlexible.fit, equals(FlexFit.loose)); + + // Test multiple Flexible widgets in a Column + runtime.update(const LibraryName(['test']), parseLibraryFile(''' + import core; + widget root = Directionality( + textDirection: "ltr", + child: Column( + children: [ + Flexible( + flex: 1, + fit: "loose", + child: Text(text: "First"), + ), + Flexible( + flex: 2, + fit: "tight", + child: Text(text: "Second"), + ), + Flexible( + flex: 1, + child: Text(text: "Third"), + ), + ], + ), + ); + ''')); + await tester.pumpAndSettle(); + expect(find.byType(Flexible), findsNWidgets(3)); + + final List flexibleWidgets = tester.widgetList(find.byType(Flexible)).toList(); + expect(flexibleWidgets[0].flex, equals(1)); + expect(flexibleWidgets[0].fit, equals(FlexFit.loose)); + expect(flexibleWidgets[1].flex, equals(2)); + expect(flexibleWidgets[1].fit, equals(FlexFit.tight)); + expect(flexibleWidgets[2].flex, equals(1)); + expect(flexibleWidgets[2].fit, equals(FlexFit.loose)); + }); +} \ No newline at end of file