Skip to content

Commit 7b635eb

Browse files
authored
[rfw] Make widget builders work with loops (#8650)
**Make widget builders work with loops** Fixes flutter/flutter#161544
1 parent 3e55269 commit 7b635eb

File tree

4 files changed

+55
-2
lines changed

4 files changed

+55
-2
lines changed

packages/rfw/CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
## NEXT
1+
## 1.0.31
22

33
* Updates minimum supported SDK version to Flutter 3.22/Dart 3.4.
4+
* Fixes an issue where Widget Builders didn't work properly with Loops.
45

56
## 1.0.30
67

packages/rfw/lib/src/flutter/runtime.dart

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -780,6 +780,10 @@ abstract class _CurriedWidget extends BlobNode {
780780
);
781781
} else if (inputList is DataReference) {
782782
inputList = dataResolver(inputList.parts);
783+
} else if (inputList is WidgetBuilderArgReference) {
784+
inputList = widgetBuilderArgResolver(
785+
<Object>[inputList.argumentName, ...inputList.parts],
786+
);
783787
} else if (inputList is BoundStateReference) {
784788
inputList = stateResolver(inputList.parts, inputList.depth);
785789
} else if (inputList is BoundLoopReference) {

packages/rfw/pubspec.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ name: rfw
22
description: "Remote Flutter widgets: a library for rendering declarative widget description files at runtime."
33
repository: https://github.com/flutter/packages/tree/main/packages/rfw
44
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+rfw%22
5-
version: 1.0.30
5+
version: 1.0.31
66

77
environment:
88
sdk: ^3.4.0

packages/rfw/test/runtime_test.dart

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1606,6 +1606,54 @@ void main() {
16061606
expect(textFinder, findsOneWidget);
16071607
expect(tester.widget<Text>(textFinder).data, 'The input is true, the output is false');
16081608
});
1609+
1610+
testWidgets('Widget builders - builder works with loops', (WidgetTester tester) async {
1611+
const LibraryName coreLibraryName = LibraryName(<String>['core']);
1612+
const LibraryName localLibraryName = LibraryName(<String>['local']);
1613+
const LibraryName remoteLibraryName = LibraryName(<String>['remote']);
1614+
final Runtime runtime = Runtime();
1615+
addTearDown(runtime.dispose);
1616+
final DynamicContent data = DynamicContent();
1617+
final Finder textFinder = find.byType(Text);
1618+
1619+
runtime.update(coreLibraryName, createCoreWidgets());
1620+
runtime.update(
1621+
localLibraryName,
1622+
LocalWidgetLibrary(<String, LocalWidgetBuilder>{
1623+
'Builder': (BuildContext context, DataSource source) {
1624+
return source.builder(
1625+
<String>['builder'],
1626+
<String, Object?>{
1627+
'values': <String>['Value1', 'Value2', 'Value3'],
1628+
},
1629+
);
1630+
},
1631+
}));
1632+
runtime.update(remoteLibraryName, parseLibraryFile('''
1633+
import core;
1634+
import local;
1635+
1636+
widget test = Builder(
1637+
builder: (scope) =>
1638+
Column(
1639+
children: [
1640+
...for value in scope.values:
1641+
Text(text: value, textDirection: 'ltr'),
1642+
],
1643+
),
1644+
);
1645+
'''));
1646+
await tester.pumpWidget(RemoteWidget(
1647+
runtime: runtime,
1648+
data: data,
1649+
widget: const FullyQualifiedWidgetName(remoteLibraryName, 'test'),
1650+
));
1651+
1652+
expect(textFinder, findsNWidgets(3));
1653+
expect((textFinder.at(0).evaluate().first.widget as Text).data, 'Value1');
1654+
expect((textFinder.at(1).evaluate().first.widget as Text).data, 'Value2');
1655+
expect((textFinder.at(2).evaluate().first.widget as Text).data, 'Value3');
1656+
});
16091657
}
16101658

16111659
final class RfwEvent {

0 commit comments

Comments
 (0)