Unverified Commit d1185337 authored by Taufiq Rahman's avatar Taufiq Rahman Committed by GitHub

Feature: Allow `minLines` in `SelectableText` (#50750)

* Feature: allow minLines in SelectableText
parent 85ab331c
......@@ -205,6 +205,7 @@ class SelectableText extends StatefulWidget {
this.showCursor = false,
this.autofocus = false,
ToolbarOptions toolbarOptions,
this.minLines,
this.maxLines,
this.cursorWidth = 2.0,
this.cursorRadius,
......@@ -218,6 +219,11 @@ class SelectableText extends StatefulWidget {
assert(autofocus != null),
assert(dragStartBehavior != null),
assert(maxLines == null || maxLines > 0),
assert(minLines == null || minLines > 0),
assert(
(maxLines == null) || (minLines == null) || (maxLines >= minLines),
'minLines can\'t be greater than maxLines',
),
assert(
data != null,
'A non-null String must be provided to a SelectableText widget.',
......@@ -248,6 +254,7 @@ class SelectableText extends StatefulWidget {
this.showCursor = false,
this.autofocus = false,
ToolbarOptions toolbarOptions,
this.minLines,
this.maxLines,
this.cursorWidth = 2.0,
this.cursorRadius,
......@@ -261,6 +268,11 @@ class SelectableText extends StatefulWidget {
assert(autofocus != null),
assert(dragStartBehavior != null),
assert(maxLines == null || maxLines > 0),
assert(minLines == null || minLines > 0),
assert(
(maxLines == null) || (minLines == null) || (maxLines >= minLines),
'minLines can\'t be greater than maxLines',
),
assert(
textSpan != null,
'A non-null TextSpan must be provided to a SelectableText.rich widget.',
......@@ -329,6 +341,9 @@ class SelectableText extends StatefulWidget {
/// {@macro flutter.widgets.editableText.autofocus}
final bool autofocus;
/// {@macro flutter.widgets.editableText.minLines}
final int minLines;
/// {@macro flutter.widgets.editableText.maxLines}
final int maxLines;
......@@ -398,6 +413,7 @@ class SelectableText extends StatefulWidget {
properties.add(DiagnosticsProperty<TextStyle>('style', style, defaultValue: null));
properties.add(DiagnosticsProperty<bool>('autofocus', autofocus, defaultValue: false));
properties.add(DiagnosticsProperty<bool>('showCursor', showCursor, defaultValue: false));
properties.add(IntProperty('minLines', minLines, defaultValue: null));
properties.add(IntProperty('maxLines', maxLines, defaultValue: null));
properties.add(EnumProperty<TextAlign>('textAlign', textAlign, defaultValue: null));
properties.add(EnumProperty<TextDirection>('textDirection', textDirection, defaultValue: null));
......@@ -582,6 +598,7 @@ class _SelectableTextState extends State<SelectableText> with AutomaticKeepAlive
autofocus: widget.autofocus,
forceLine: false,
toolbarOptions: widget.toolbarOptions,
minLines: widget.minLines,
maxLines: widget.maxLines ?? defaultTextStyle.maxLines,
selectionColor: themeData.textSelectionColor,
selectionControls: widget.selectionEnabled ? textSelectionControls : null,
......
......@@ -177,12 +177,17 @@ void main() {
debugResetSemanticsIdCounter();
});
Widget selectableTextBuilder({String text = '', int maxLines = 1}) {
Widget selectableTextBuilder({
String text = '',
int maxLines = 1,
int minLines,
}) {
return boilerplate(
child: SelectableText(
text,
style: const TextStyle(color: Colors.black, fontSize: 34.0),
maxLines: maxLines,
minLines: minLines,
),
);
}
......@@ -1155,6 +1160,41 @@ void main() {
expect(inputBox.hitTest(BoxHitTestResult(), position: inputBox.globalToLocal(newFourthPos)), isFalse);
});
testWidgets('minLines cannot be greater than maxLines', (WidgetTester tester) async {
try {
await tester.pumpWidget(
overlay(
child: Container(
width: 300.0,
child: SelectableText(
'abcd',
minLines: 4,
maxLines: 3,
),
),
),
);
} on AssertionError catch (e) {
expect(e.toString(), contains("minLines can't be greater than maxLines"));
return;
}
fail('An assert should be triggered when minLines is greater than maxLines');
});
testWidgets('Selectable height with minLine', (WidgetTester tester) async {
await tester.pumpWidget(selectableTextBuilder());
RenderBox findTextBox() => tester.renderObject(find.byType(SelectableText));
final RenderBox textBox = findTextBox();
final Size emptyInputSize = textBox.size;
// Even if the text is a one liner, minimum height of SelectableText will determined by minLines
await tester.pumpWidget(selectableTextBuilder(text: 'No wrapping here.', minLines: 2, maxLines: 3));
expect(findTextBox(), equals(textBox));
expect(textBox.size.height, emptyInputSize.height * 2);
});
testWidgets('Can align to center', (WidgetTester tester) async {
await tester.pumpWidget(
overlay(
......@@ -3189,6 +3229,7 @@ void main() {
textScaleFactor: 1.0,
autofocus: true,
showCursor: true,
minLines: 2,
maxLines: 10,
cursorWidth: 1.0,
cursorRadius: Radius.zero,
......@@ -3206,6 +3247,7 @@ void main() {
'style: TextStyle(inherit: true, color: Color(0xff00ff00))',
'autofocus: true',
'showCursor: true',
'minLines: 2',
'maxLines: 10',
'textAlign: end',
'textDirection: ltr',
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment