-
Notifications
You must be signed in to change notification settings - Fork 213
How to Create a Flexible Custom Wrapper for Widgets to overriding some default properties? #3777
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
Comments
The short answer is: you can't avoid manually forwarding the properties. Dart does not have a way to abstract over parameter/argument lists and say "this function has all parameters of that other function" See also #1781 |
If foo (int a, int b, {int? c, int?d}) {
@ignoreRedundant bar(0, b, c:2, ...$arguments); // generally, ...myRecord
} Annotation @ignoreRedundant will instruct the compiler to take the first occurrence of the parameter in a parameter list (ignoring repetitions that come from the spread). All mandatory positional parameters are supposed to be passed explicitly If some "unexpected" (by bar) named parameter occurs in the spread - error. The spread operator is allowed only at the end of the parameter list. The case when Since every name and type are verified statically, the mechanism appears safe. (I'm not sure the annotation is even necessary. It can be assumed whenever we use the spread operator) |
Take 2 (trying to put it more coherently) Spread operator in parameter list Obtaining the list of actual parameters as a record Merging records Q: why all positional elements of r2 are ignored, instead of being merged with the positional elements of r1? Call forwarding foo (int a, int b, {int? c, int?d}) {
bar(... (0, b, c:2)+$arguments);
} EDIT: Removed the section about copyWith. I thought |
The idea can still be resurrected by introducing a type The type When the object of type However, to implement forwarding (or As an example, the implementation of class A {
final int a, b;
final int? c; // c is nullable!
A({required this.a, required this.b, this.c}){}
A copyWith({late int a, late int b, late int? c}) {
var args=$arguments;
return A(args.a.orElse(this.a), args.b.orElse(this.b), args.c.orElse(this.c));
// note that every parameter of `A(...)` constructor call has a correct static type.
}
} Here, we are reusing an idea of "late" introduced in #3680, but without the foo({late int b, late int c}) {
// forward b and c to bar, replacing b with zero if not set
var args = $arguments;
bar(b: args.b.orElse(0), c: args.c);
} This works without extra sugar, but we must manually pass every parameter, which quickly becomes boring and error-prone. To address this, we can introduce operations on records along the lines of the previous comment. (*) otherwise, we can't distinguish between omitted parameters and those explicitly passed by null, and, as a result, have to impose some unnatural restrictions. EDIT: forgot to mention another use case for foo(a: if (cond) 42); // the "if" expression has type NoneOr<int> |
NoneOr feels bad. Id rather go with the implicit constructor proposal, since passing something in would have it be wrapped, and necessarily not null. (Even if the passed in value is null, you'd just get |
I'm currently developing a custom wrapper for widgets in Flutter that enables extensive customization, similar to how
{...rest}
works in TypeScript with React components. However, Dart doesn't support the spread operator for widget properties, so I'm struggling to find an effective way to forward a wide range of properties to a base widget likeIconButton
.Here's an example of what I might do in TypeScript:
In Flutter, I'm looking for a way to achieve something similar. How can I create a wrapper that allows users to customize any widget with multiple properties without manually specifying each one? Here's a basic approach in Dart, but it requires explicitly forwarding each property, which isn't scalable. For example, an
IconButton
can have additional properties like color and border. Manually copying all of them can make the code redundant. Here's my current approach:How can I achieve similar behavior to React Native in Flutter? Any insights would be greatly appreciated!
I try to use extend and extension , but they all looks like required you copy all the properties.
The text was updated successfully, but these errors were encountered: