Skip to content

feat: Add maxLines to TextBoxConfig - #4214

Merged
ufrshubham merged 3 commits into
flame-engine:mainfrom
matthewalberto:feat/text-box-max-lines
Nov 7, 2026
Merged

ufrshubham merged 3 commits into
flame-engine:mainfrom
matthewalberto:feat/text-box-max-lines

Conversation

@matthewalberto

Copy link
Copy Markdown
Contributor

Description

Adds an optional maxLines to TextBoxConfig, as discussed in #2279. Text that would take up more lines is cut off after the last allowed line. The default is null, so existing boxes behave as before.

  • The limit applies after line breaking, so it works for both TextPaint and renderers that use the space-based fallback, and hard line breaks count as lines.
  • The automatic box height only fits the remaining lines. A box with a fixed size keeps its size.
  • Setting a different maxLines through boxConfig reflows the text, as maxWidth does.
  • totalCharTime used the length of the full text, so a truncated box would keep waiting after its last visible character, and finished and onComplete would come late. It now uses the length of the remaining lines when the text is truncated. Boxes that aren't truncated use the same calculation as before.
  • maxLines must be greater than zero, because a box with no lines has nothing for currentLine and _recomputeSize to work with.

This only cuts the text off. It doesn't add an ellipsis, which seemed better kept to a separate change if you want one.

Checklist

  • I have followed the Contributor Guide when preparing my PR.
  • I have updated/added tests for ALL new/updated/fixed functionality.
  • I have updated/added relevant documentation in docs and added dartdoc comments with ///.
  • [-] I have updated/added relevant examples in examples or docs.

Breaking Change?

  • Yes, this PR is a breaking change.
  • No, this PR is not a breaking change.

Related Issues

Closes #2279

@ufrshubham ufrshubham left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, this is nicely done. Truncating after line breaking is the right approach: the layout doesn't change, so the kept lines are exactly the first lines of the full wrap. I checked this with Chinese, Japanese and Korean text too, and wrapping is unchanged.

There's one thing to fix: ScrollTextBoxComponent ignores maxLines. It rebuilds its TextBoxConfig field by field, so the new option never reaches the inner text box. With maxLines: 2, I still got 21 lines. Since this file isn't in the diff, here's the change for packages/flame/lib/src/components/scroll_text_box_component.dart:

resolvedBoxConfig = TextBoxConfig(
  timePerChar: resolvedBoxConfig.timePerChar,
  dismissDelay: resolvedBoxConfig.dismissDelay,
  growingBox: resolvedBoxConfig.growingBox,
  maxLines: resolvedBoxConfig.maxLines,
  maxWidth: size.x,
  // ...
);

Could you also add this test to scroll_text_box_component_test.dart? It fails without the change and passes with it:

testWithFlameGame('respects maxLines', (game) async {
  final component = ScrollTextBoxComponent(
    size: Vector2(100, 200),
    text: 'The quick brown fox jumps over the lazy dog.',
    boxConfig: const TextBoxConfig(maxLines: 2),
  );
  await game.ensureAdd(component);
  await game.ready();

  final inner = component
      .descendants()
      .whereType<TextBoxComponent>()
      .single;
  expect(inner.lines.length, 2);
});

The failing analyze checks aren't caused by your PR. They come from a riverpod deprecation that we'll fix separately, so you'll just need to update your branch once that's merged.

ScrollTextBoxComponent rebuilds its TextBoxConfig field by field, so the
new maxLines option never reached the inner text box.
@matthewalberto

Copy link
Copy Markdown
Contributor Author

Done in 37185d9, with your test added as written. It fails without the change and passes with it. Thanks for checking the CJK cases.

@ufrshubham ufrshubham left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

@ufrshubham
ufrshubham enabled auto-merge (squash) November 7, 2026 08:14
@ufrshubham
ufrshubham merged commit 88c0438 into flame-engine:main Nov 7, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Any possible way to set maxLines of Text in Flame?

2 participants