Skip to content

[rfw] Add Flexible widget support to core widgets #9750

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions packages/rfw/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
9 changes: 9 additions & 0 deletions packages/rfw/lib/src/flutter/core_widgets.dart
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import 'runtime.dart';
/// * [DefaultTextStyle]
/// * [Directionality]
/// * [Expanded]
/// * [Flexible]
/// * [FittedBox]
/// * [FractionallySizedBox]
/// * [GestureDetector]
Expand Down Expand Up @@ -349,6 +350,14 @@ Map<String, LocalWidgetBuilder> get _coreWidgetsDefinitions => <String, LocalWid
);
},

'Flexible': (BuildContext context, DataSource source) {
return Flexible(
flex: source.v<int>(['flex']) ?? 1,
fit: ArgumentDecoders.enumValue<FlexFit>(FlexFit.values, source, ['fit']) ?? FlexFit.loose,
child: source.child(['child']),
);
},

'FittedBox': (BuildContext context, DataSource source) {
return FittedBox(
fit: ArgumentDecoders.enumValue<BoxFit>(BoxFit.values, source, ['fit']) ?? BoxFit.contain,
Expand Down
2 changes: 1 addition & 1 deletion packages/rfw/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
135 changes: 134 additions & 1 deletion packages/rfw/test/core_widgets_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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(<String>['core']), createCoreWidgets());
addTearDown(runtime.dispose);
final DynamicContent data = DynamicContent();

// Test Flexible with default values
runtime.update(const LibraryName(<String>['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(<String>['test']), 'root'),
),
);
await tester.pump();
expect(find.byType(Flexible), findsOneWidget);
final Flexible defaultFlexible = tester.widget<Flexible>(find.byType(Flexible));
expect(defaultFlexible.flex, equals(1));
expect(defaultFlexible.fit, equals(FlexFit.loose));

// Test Flexible with custom flex value
runtime.update(const LibraryName(<String>['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<Flexible>(find.byType(Flexible));
expect(customFlexFlexible.flex, equals(3));
expect(customFlexFlexible.fit, equals(FlexFit.loose));

// Test Flexible with fit: "tight"
runtime.update(const LibraryName(<String>['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<Flexible>(find.byType(Flexible));
expect(tightFlexible.flex, equals(2));
expect(tightFlexible.fit, equals(FlexFit.tight));

// Test Flexible with fit: "loose"
runtime.update(const LibraryName(<String>['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<Flexible>(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(<String>['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<Flexible> flexibleWidgets = tester.widgetList<Flexible>(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));
});
}