Skip to content

Commit 21b5abb

Browse files
authored
Add rfw widgets (#5661)
Add two rfw widgets(ClipRRect and DropdownButton) and `flutter format` the widget files. ## Pre-launch Checklist - [x] I read the [Contributor Guide] and followed the process outlined there for submitting PRs. - [x] I read the [Tree Hygiene] wiki page, which explains my responsibilities. - [x] I read and followed the [relevant style guides] and ran the auto-formatter. (Unlike the flutter/flutter repo, the flutter/packages repo does use `dart format`.) - [x] I signed the [CLA]. - [x] The title of the PR starts with the name of the package surrounded by square brackets, e.g. `[shared_preferences]` - [ ] I listed at least one issue that this PR fixes in the description above. - [x] I updated `pubspec.yaml` with an appropriate new version according to the [pub versioning philosophy], or this PR is [exempt from version changes]. - [x] I updated `CHANGELOG.md` to add a description of the change, [following repository CHANGELOG style]. - [x] I updated/added relevant documentation (doc comments with `///`). - [x] I added new tests to check the change I am making, or this PR is [test-exempt]. - [x] All existing and new tests are passing. If you need help, consider asking for advice on the #hackers-new channel on [Discord]. <!-- Links --> [Contributor Guide]: https://github.com/flutter/packages/blob/main/CONTRIBUTING.md [Tree Hygiene]: https://github.com/flutter/flutter/wiki/Tree-hygiene [relevant style guides]: https://github.com/flutter/packages/blob/main/CONTRIBUTING.md#style [CLA]: https://cla.developers.google.com/ [flutter/tests]: https://github.com/flutter/tests [breaking change policy]: https://github.com/flutter/flutter/wiki/Tree-hygiene#handling-breaking-changes [Discord]: https://github.com/flutter/flutter/wiki/Chat [pub versioning philosophy]: https://dart.dev/tools/pub/versioning [exempt from version changes]: https://github.com/flutter/flutter/wiki/Contributing-to-Plugins-and-Packages#version-and-changelog-updates [following repository CHANGELOG style]: https://github.com/flutter/flutter/wiki/Contributing-to-Plugins-and-Packages#changelog-style [test-exempt]: https://github.com/flutter/flutter/wiki/Tree-hygiene#tests
1 parent ba43d73 commit 21b5abb

File tree

9 files changed

+143
-2
lines changed

9 files changed

+143
-2
lines changed

packages/rfw/CHANGELOG.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1-
## 1.0.18
1+
## 1.0.19
2+
* Add `DropdownButton` and `ClipRRect` widgets to rfw widget library.
23

4+
## 1.0.18
35
* Exposes `WidgetLibrary`s registered in `Runtime`.
46
* Exposes widgets map in `LocalWidgetLibrary`.
57

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import 'runtime.dart';
2727
/// * [Align]
2828
/// * [AspectRatio]
2929
/// * [Center]
30+
/// * [ClipRRect]
3031
/// * [ColoredBox]
3132
/// * [Column]
3233
/// * [Container] (actually uses [AnimatedContainer])
@@ -269,6 +270,15 @@ Map<String, LocalWidgetBuilder> get _coreWidgetsDefinitions => <String, LocalWid
269270
);
270271
},
271272

273+
'ClipRRect': (BuildContext context, DataSource source) {
274+
return ClipRRect(
275+
borderRadius: ArgumentDecoders.borderRadius(source, ['borderRadius']) ?? BorderRadius.zero,
276+
// CustomClipper<RRect> clipper,
277+
clipBehavior: ArgumentDecoders.enumValue<Clip>(Clip.values, source, ['clipBehavior']) ?? Clip.antiAlias,
278+
child: source.optionalChild(['child']),
279+
);
280+
},
281+
272282
'ColoredBox': (BuildContext context, DataSource source) {
273283
return ColoredBox(
274284
color: ArgumentDecoders.color(source, ['color']) ?? const Color(0xFF000000),

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

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import 'runtime.dart';
2727
/// * [CircularProgressIndicator]
2828
/// * [Divider]
2929
/// * [DrawerHeader]
30+
/// * [DropdownButton]
3031
/// * [ElevatedButton]
3132
/// * [FloatingActionButton]
3233
/// * [InkWell]
@@ -67,6 +68,11 @@ import 'runtime.dart';
6768
/// * The [Scaffold]'s floating action button position and animation features
6869
/// are not supported.
6970
///
71+
/// * [DropdownButton] takes a `items` object which contains a list of
72+
/// [DropdownMenuItem] configuration objects. Each object may contain
73+
/// `onTap`, `value`, `enabled` and `child`. The `child` parameter is
74+
/// required.
75+
///
7076
/// In general, the trend will all of these unsupported features is that this
7177
/// library doesn't support features that can't be trivially expressed using the
7278
/// JSON-like structures of RFW. For example, [MaterialStateProperty] is
@@ -188,6 +194,46 @@ Map<String, LocalWidgetBuilder> get _materialWidgetsDefinitions => <String, Loca
188194
);
189195
},
190196

197+
'DropdownButton': (BuildContext context, DataSource source) {
198+
final int length = source.length(['items']);
199+
final List<DropdownMenuItem<Object>> dropdownMenuItems = List<DropdownMenuItem<Object>>.generate(
200+
length,
201+
(int index) => DropdownMenuItem<Object>(
202+
onTap: source.voidHandler(['items', index, 'onTap']),
203+
value: source.v<String>(['items', index, 'value']) ?? source.v<int>(['items', index, 'value']) ?? source.v<double>(['items', index, 'value']) ?? source.v<bool>(['items', index, 'value']),
204+
enabled: source.v<bool>(['items', index, 'enabled']) ?? true,
205+
alignment: ArgumentDecoders.alignment(source, ['items', index, 'alignment']) ?? AlignmentDirectional.centerStart,
206+
child: source.child(['items', index, 'child']),
207+
),
208+
);
209+
210+
return DropdownButton<Object>(
211+
items: dropdownMenuItems,
212+
value: source.v<String>(['value']) ?? source.v<int>(['value']) ?? source.v<double>(['value']) ?? source.v<bool>(['value']),
213+
disabledHint: source.optionalChild(['disabledHint']),
214+
onChanged: source.handler(<Object>['onChanged'], (HandlerTrigger trigger) => (Object? value) => trigger(<String, Object?>{'value': value})),
215+
onTap: source.voidHandler(['onTap']),
216+
elevation: source.v<int>(['elevation']) ?? 8,
217+
style: ArgumentDecoders.textStyle(source, ['style']),
218+
underline: source.optionalChild(['underline']),
219+
icon: source.optionalChild(['icon']),
220+
iconDisabledColor: ArgumentDecoders.color(source, ['iconDisabledColor']),
221+
iconEnabledColor: ArgumentDecoders.color(source, ['iconEnabledColor']),
222+
iconSize: source.v<double>(['iconSize']) ?? 24.0,
223+
isDense: source.v<bool>(['isDense']) ?? false,
224+
isExpanded: source.v<bool>(['isExpanded']) ?? false,
225+
itemHeight: source.v<double>(['itemHeight']) ?? kMinInteractiveDimension,
226+
focusColor: ArgumentDecoders.color(source, ['focusColor']),
227+
autofocus: source.v<bool>(['autofocus']) ?? false,
228+
dropdownColor: ArgumentDecoders.color(source, ['dropdownColor']),
229+
menuMaxHeight: source.v<double>(['menuMaxHeight']),
230+
enableFeedback: source.v<bool>(['enableFeedback']),
231+
alignment: ArgumentDecoders.alignment(source, ['alignment']) ?? AlignmentDirectional.centerStart,
232+
borderRadius: ArgumentDecoders.borderRadius(source, ['borderRadius'])?.resolve(Directionality.of(context)),
233+
padding: ArgumentDecoders.edgeInsets(source, ['padding']),
234+
);
235+
},
236+
191237
'ElevatedButton': (BuildContext context, DataSource source) {
192238
// not implemented: buttonStyle, focusNode
193239
return ElevatedButton(

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.18
5+
version: 1.0.19
66

77
environment:
88
sdk: ">=3.0.0 <4.0.0"

packages/rfw/test/core_widgets_test.dart

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import 'dart:typed_data';
88

99
import 'package:flutter/material.dart';
10+
import 'package:flutter/rendering.dart';
1011
import 'package:flutter_test/flutter_test.dart';
1112
import 'package:rfw/formats.dart' show parseLibraryFile;
1213
import 'package:rfw/rfw.dart';
@@ -278,5 +279,15 @@ void main() {
278279
'''));
279280
await tester.pump();
280281
expect(find.byType(Wrap), findsOneWidget);
282+
283+
runtime.update(const LibraryName(<String>['test']), parseLibraryFile('''
284+
import core;
285+
widget root = ClipRRect();
286+
'''));
287+
await tester.pump();
288+
expect(find.byType(ClipRRect), findsOneWidget);
289+
final RenderClipRRect renderClip = tester.allRenderObjects.whereType<RenderClipRRect>().first;
290+
expect(renderClip.clipBehavior, equals(Clip.antiAlias));
291+
expect(renderClip.borderRadius, equals(BorderRadius.zero));
281292
});
282293
}
188 Bytes
Loading
Loading
Loading

packages/rfw/test/material_widgets_test.dart

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// Use of this source code is governed by a BSD-style license that can be
33
// found in the LICENSE file.
44

5+
import 'package:flutter/foundation.dart';
56
import 'package:flutter/material.dart';
67
import 'package:flutter_test/flutter_test.dart';
78
import 'package:rfw/formats.dart' show parseLibraryFile;
@@ -123,6 +124,55 @@ void main() {
123124
),
124125
),
125126
),
127+
Divider(),
128+
Padding(
129+
padding: [20.0],
130+
child: Row(
131+
mainAxisAlignment: 'spaceEvenly',
132+
children: [
133+
DropdownButton(
134+
value: 'foo',
135+
elevation: 14,
136+
dropdownColor: 0xFF9E9E9E,
137+
underline: Container(
138+
height: 2,
139+
color: 0xFF7C4DFF,
140+
),
141+
style: {
142+
color:0xFF7C4DFF,
143+
},
144+
items: [
145+
{
146+
value: 'foo',
147+
child: Text(text: 'foo'),
148+
},
149+
{
150+
value: 'bar',
151+
child: Text(text: 'bar'),
152+
onTap: event 'menu_item' { args: 'bar' },
153+
},
154+
],
155+
borderRadius:[{x: 8.0, y: 8.0}, {x: 8.0, y: 8.0}, {x: 8.0, y: 8.0}, {x: 8.0, y: 8.0}],
156+
onChanged: event 'dropdown' {},
157+
),
158+
DropdownButton(
159+
value: 1.0,
160+
items: [
161+
{
162+
value: 1.0,
163+
child: Text(text: 'first'),
164+
},
165+
{
166+
value: 2.0,
167+
child: Text(text: 'second'),
168+
onTap: event 'menu_item' { args: 'second' },
169+
},
170+
],
171+
onChanged: event 'dropdown' {},
172+
),
173+
],
174+
),
175+
),
126176
],
127177
),
128178
floatingActionButton: FloatingActionButton(
@@ -137,6 +187,28 @@ void main() {
137187
matchesGoldenFile('goldens/material_test.scaffold.png'),
138188
skip: !runGoldens,
139189
);
190+
191+
await tester.tap(find.byType(DropdownButton<Object>).first);
192+
await tester.pumpAndSettle();
193+
await expectLater(
194+
find.byType(MaterialApp),
195+
matchesGoldenFile('goldens/material_test.dropdown.png'),
196+
skip: !runGoldens,
197+
);
198+
// Tap on the second item.
199+
await tester.tap(find.text('bar'));
200+
await tester.pumpAndSettle();
201+
expect(eventLog, contains('menu_item {args: bar}'));
202+
expect(eventLog, contains('dropdown {value: bar}'));
203+
204+
await tester.tap(find.byType(DropdownButton<Object>).last);
205+
await tester.pumpAndSettle();
206+
await tester.tap(find.text('second'));
207+
await tester.pumpAndSettle();
208+
expect(eventLog, contains('menu_item {args: second}'));
209+
expect(eventLog,
210+
contains(kIsWeb ? 'dropdown {value: 2}' : 'dropdown {value: 2.0}'));
211+
140212
await tester.tapAt(const Offset(20.0, 20.0));
141213
await tester.pump();
142214
await tester.pump(const Duration(seconds: 1));

0 commit comments

Comments
 (0)