-
Notifications
You must be signed in to change notification settings - Fork 26.9k
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
Allow text wrapping behavior to be controlled #61081
Comments
word-break: break-all;
Reference how does it look in CSS https://developer.mozilla.org/en-US/docs/Web/CSS/word-break |
/cc @Hixie for thoughts. |
@VladyslavBondarenko are you saying you want the text to overflow its box? |
@Hixie I attached the link to CSS docs to show what behavior author would like to achieve: |
Ah, got it. FWIW, you should be able to do this today by just inserting a word separator between every character. It might make Thai and Arabic look a bit weird though. To implement this we would probably start by adding a wrapStyle property to ui.TextStyle. Exactly what values it takes is a little tricky. We need to express both where line breaking opportunities happen, and how they take priority (e.g. break at the first of these opportunities, unless you find none, in which case break at these, etc). We could do this by having a hard-coded set of patterns, like CSS, or we could have some more elaborate mechanism. I suppose the ultimate solution would be to just pass in a closure that gets called to see where we should wrap. Probably too expensive though. |
I'm also in need for this. I was looking everywhere thinking there must be a way to do it (wrapping text by breaking words). My use case is showing long URLs in little space, I want them to wrap but then since random characters of it are considered braking (like Where what I want is almost this (I'm replacing the hyphen with a non-breaking hyphen, The even if there were a non-breaking slash, replacing characters is not really a solution as I want the text to be selectable (and copyable) too, and then the text becomes an invalid URL. Same could be applied to long UUIDs or similar long strings. I even tried to look at Flutter's code to see how wrapping was done (as word-breaking wrapping is the simplest way of wrapping ever I guess it shouldn't be too hard to implement), but I failed to find where normal word wrapping is being done. |
+1 |
// Use Extension
String get breakWord{
String breakWord = '';
runes.forEach((element){
breakWord += String.fromCharCode(element);
breakWord +='\u200B';
});
return breakWord;
} Use caseText("中文information spropaganda accomplishment accomplishment".breakWord) Success,Perfect |
Thanks for the workaround, but again, this doesn't cover all use cases:
Adding a breaking character between each character have the same issue about being able to copy the original string by selecting it. |
Any update on this? |
Any advance on this? |
From #61081 (comment)
It's tedious but you can have total control of where to break or not |
I have published this package in pub. The MagicText widget solves this problem. The package is a auto-responsive text widget that supports a multitude of parameters to control text rendering behaviour. You can control line breaks that break words in half with a given character (default is '-'). Pub package: https://pub.dev/packages/magic_text Instance widget code example: |
Facing same problem, zero-width char broken text copy in third-party libraries. |
You can try magic_text widget to solve it. This widget wrap the text and handle word break character automatically. |
I came up with this solution. It looks like that: import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: Scaffold(
body: Center(
child: SingleChildScrollView(
child: SelectionArea(
child: Text.rich(
BreakAllTextSpan(
'''Loremipsumdolorsitamet, consecteturadipiscingelit.Sedauctoreuismodplacerat.Crassuscipitatmassasedpulvina.Inpurusnisl,bibendumsitametdolorac,feugiat mattis risus. Maecenas vehicula lobortis justo, nec tincidunt nulla convallis ac. Nam nulla lacus, tincidunt id malesuada in, ultricies non enim. Morbi non sodales ex. Integer vitae odio sit amet nisi finibus malesuada ut in libero. Sed auctor tempus nisl. Donec et scelerisque nunc. Quisque rhoncus nunc quam. Aliquam erat volutpat. Integer condimentum sit amet quam ac accumsan. Donec porttitor faucibus vulputate. Ut sollicitudin vestibulum augue vel suscipit.'''),
),
),
),
),
),
);
}
}
class BreakAllTextSpan extends TextSpan {
BreakAllTextSpan(String text) : super(text: text.breakString);
@override
void computeToPlainText(StringBuffer buffer,
{bool includeSemanticsLabels = true, bool includePlaceholders = true}) {
if (semanticsLabel != null && includeSemanticsLabels) {
buffer.write(semanticsLabel);
} else if (text != null) {
buffer.write(text?.unbreakString);
}
if (children != null) {
for (final child in children!) {
child.computeToPlainText(
buffer,
includeSemanticsLabels: includeSemanticsLabels,
includePlaceholders: includePlaceholders,
);
}
}
}
}
const zeroWidthSpace = '\u200B';
extension StringExtension on String {
String get breakString {
// Makes the string in [Text] widget behave like with CSS style `word-break: break-all;`
// (src: https://github.com/flutter/flutter/issues/61081#issuecomment-1103330522)
return runes
.map<String>(
(element) => '${String.fromCharCode(element)}$zeroWidthSpace')
.join();
}
String get unbreakString {
return replaceAll(zeroWidthSpace, String.fromCharCode(0xFFFC));
}
} |
when the word is very long, the text wrap will be not good.
at web, we can use
word-break: break-all;
to solve it.so, can flutter add the feature?
Use case
like this, between two long word, there is very large spacing.
Proposal
please add new params
wordBreak
toTextSpan
, let word wrap at end of line, instead of end of word.The text was updated successfully, but these errors were encountered: