Skip to content
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

Nested Copy with for Styles #360

Closed
dickermoshe opened this issue Jan 17, 2025 · 4 comments · Fixed by #386
Closed

Nested Copy with for Styles #360

dickermoshe opened this issue Jan 17, 2025 · 4 comments · Fixed by #386
Assignees
Labels
priority: low Features/Improvements that we "want" but not "need" type: ehancement A new feature or request

Comments

@dickermoshe
Copy link

Is your feature request related to a problem? Please describe.
I really like how forui handles styles. Instead of tens of arguments for widgets there is a single style object which you copyWith.
However copyWith for nested classes is verbose and ugly

Describe the solution you'd like
Support for nested copyWith using dart_mappable

Describe alternatives you've considered
N/A

Additional context
N/A

@dickermoshe dickermoshe added the type: ehancement A new feature or request label Jan 17, 2025
@Pante
Copy link
Member

Pante commented Jan 18, 2025

I agree that the current way of composing nested styles is extremely verbose. However, I don’t think we should commit to dart_mappable or any package for the time being as dart macros are on the horizon. We’ll probably wait until that comes out before making a decision.

@Pante Pante added the priority: low Features/Improvements that we "want" but not "need" label Jan 18, 2025
@Pante Pante moved this from Triage to Icebox in Forui Roadmap Jan 18, 2025
@dickermoshe
Copy link
Author

@Pante Remeber me?

Well, macros aint coming.

@Pante
Copy link
Member

Pante commented Jan 30, 2025

Yup, just saw the news as well, that's a massive shame.

@Pante
Copy link
Member

Pante commented Feb 2, 2025

I've been tinkering around with some ideas. And I wonder if introducing a map(...) function solves most of the current situation's pain points.

To me, it seems like the most annoying issue is not having a reference to a style immediately after it has been created. This disrupts the "natural nesting" of styles by forcing us to declare variables out of order. It also automatically excludes the usage inside arrow functions/expressions.

See FSelectGroupStyle.inherit for a real world example of this problem.

My idea is to introduce a map(Style Function(Style)) on all styles. This allows us to preserve the natural nesting of styles while allowing it to be used in an expression. It also the bonus perk of not introducing a dependency.

Given:

// Simulates a parent style/FThemeData.
void OtherStyle({
  required AStyle style,
}) {}

class AStyle {
  final int foo;
  final int bar;
  final BStyle b;

  AStyle({required this.foo, required this.bar, required this.b});

  factory AStyle.inherit() => AStyle(foo: 1, bar: 2, b: BStyle(foo: 3, bar: 4));

  AStyle map(AStyle Function(AStyle) builder) => builder(this);

  AStyle copyWith({
    int? foo,
    int? bar,
    BStyle? b,
  }) =>
      AStyle(
        foo: foo ?? this.foo,
        bar: bar ?? this.bar,
        b: b ?? this.b,
      );
}

class BStyle {
  final int foo;
  final int bar;

  BStyle({required this.foo, required this.bar});

  factory BStyle.inherit() => BStyle(foo: 1, bar: 2);

  BStyle map(BStyle Function(BStyle) builder) => builder(this);

  BStyle copyWith({
    int? foo,
    int? bar,
  }) =>
      BStyle(
        foo: foo ?? this.foo,
        bar: bar ?? this.bar,
      );
}

The current approach will yield:

void current() {
  // Requires a block.
  final a = AStyle.inherit();
  final b = a.b.copyWith(foo: 6);
  OtherStyle(style: AStyle(foo: 5, bar: a.bar, b: b));
}

The proposed changes will yield:

void proposed() {
  // Does not require a block (usable in arrow functions & expressions)
  OtherStyle(
    style: AStyle.inherit().map(
      (style) => style.copyWith(
        foo: 5,
        b: style.b.copyWith(foo: 6),
      ),
    ),
  );
}

This allows a style to be reused multiple times in a context. It also allows the modification of deeply nested (3+ levels) properties.

@Pante Pante moved this from Icebox to Todo in Forui Roadmap Feb 5, 2025
@Pante Pante self-assigned this Feb 5, 2025
@Pante Pante moved this from Todo to Assigned in Forui Roadmap Feb 8, 2025
@github-project-automation github-project-automation bot moved this from Assigned to Done in Forui Roadmap Feb 10, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
priority: low Features/Improvements that we "want" but not "need" type: ehancement A new feature or request
Projects
Status: Done
Development

Successfully merging a pull request may close this issue.

2 participants