Commit 279c6149 authored by Jason Simmons's avatar Jason Simmons

Merge pull request #1747 from jason-simmons/input_field_clear

Change the text/selection value API of the input field
parents c27dc641 52c55344
......@@ -51,10 +51,10 @@ class MealFragment extends StatefulComponent {
}
class MealFragmentState extends State<MealFragment> {
String _description = "";
InputValue _description = InputValue.empty;
void _handleSave() {
config.onCreated(new Meal(when: new DateTime.now(), description: _description));
config.onCreated(new Meal(when: new DateTime.now(), description: _description.text));
Navigator.pop(context);
}
......@@ -75,7 +75,7 @@ class MealFragmentState extends State<MealFragment> {
);
}
void _handleDescriptionChanged(String description) {
void _handleDescriptionChanged(InputValue description) {
setState(() {
_description = description;
});
......
......@@ -63,13 +63,13 @@ class MeasurementFragment extends StatefulComponent {
}
class MeasurementFragmentState extends State<MeasurementFragment> {
String _weight = "";
InputValue _weight = InputValue.empty;
DateTime _when = new DateTime.now();
void _handleSave() {
double parsedWeight;
try {
parsedWeight = double.parse(_weight);
parsedWeight = double.parse(_weight.text);
} on FormatException catch(e) {
print("Exception $e");
Scaffold.of(context).showSnackBar(new SnackBar(
......@@ -97,7 +97,7 @@ class MeasurementFragmentState extends State<MeasurementFragment> {
);
}
void _handleWeightChanged(String weight) {
void _handleWeightChanged(InputValue weight) {
setState(() {
_weight = weight;
});
......
......@@ -4,6 +4,64 @@
part of fitness;
class _SettingsDialog extends StatefulComponent {
_SettingsDialogState createState() => new _SettingsDialogState();
}
class _SettingsDialogState extends State<_SettingsDialog> {
final GlobalKey weightGoalKey = new GlobalKey();
InputValue _goalWeight = InputValue.empty;
void _handleGoalWeightChanged(InputValue goalWeight) {
setState(() {
_goalWeight = goalWeight;
});
}
void _handleGoalWeightSubmitted(InputValue goalWeight) {
_goalWeight = goalWeight;
_handleSavePressed();
}
void _handleSavePressed() {
double goalWeight;
try {
goalWeight = double.parse(_goalWeight.text);
} on FormatException {
goalWeight = 0.0;
}
Navigator.pop(context, goalWeight);
}
Widget build(BuildContext context) {
return new Dialog(
title: new Text("Goal Weight"),
content: new Input(
key: weightGoalKey,
value: _goalWeight,
autofocus: true,
hintText: 'Goal weight in lbs',
keyboardType: KeyboardType.number,
onChanged: _handleGoalWeightChanged,
onSubmitted: _handleGoalWeightSubmitted
),
actions: <Widget>[
new FlatButton(
child: new Text('CANCEL'),
onPressed: () {
Navigator.pop(context);
}
),
new FlatButton(
child: new Text('SAVE'),
onPressed: _handleSavePressed
),
]
);
}
}
typedef void SettingsUpdater({
BackupMode backup,
double goalWeight
......@@ -36,52 +94,10 @@ class SettingsFragmentState extends State<SettingsFragment> {
return "${config.userData.goalWeight}";
}
static final GlobalKey weightGoalKey = new GlobalKey();
double _goalWeight;
void _handleGoalWeightChanged(String goalWeight) {
// TODO(jackson): Looking for null characters to detect enter key is a hack
if (goalWeight.endsWith("\u{0}")) {
Navigator.pop(context, double.parse(goalWeight.replaceAll("\u{0}", "")));
} else {
setState(() {
try {
_goalWeight = double.parse(goalWeight);
} on FormatException {
_goalWeight = 0.0;
}
});
}
}
Future _handleGoalWeightPressed() async {
double goalWeight = await showDialog(
context: context,
child: new Dialog(
title: new Text("Goal Weight"),
content: new Input(
key: weightGoalKey,
autofocus: true,
hintText: 'Goal weight in lbs',
keyboardType: KeyboardType.number,
onChanged: _handleGoalWeightChanged
),
actions: <Widget>[
new FlatButton(
child: new Text('CANCEL'),
onPressed: () {
Navigator.pop(context);
}
),
new FlatButton(
child: new Text('SAVE'),
onPressed: () {
Navigator.pop(context, _goalWeight);
}
),
]
)
child: new _SettingsDialog()
);
config.updater(goalWeight: goalWeight);
}
......
......@@ -33,14 +33,14 @@ class StockHomeState extends State<StockHome> {
final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
bool _isSearching = false;
String _searchQuery;
InputValue _searchQuery = InputValue.empty;
void _handleSearchBegin() {
ModalRoute.of(context).addLocalHistoryEntry(new LocalHistoryEntry(
onRemove: () {
setState(() {
_isSearching = false;
_searchQuery = null;
_searchQuery = InputValue.empty;
});
}
));
......@@ -53,7 +53,7 @@ class StockHomeState extends State<StockHome> {
Navigator.pop(context);
}
void _handleSearchQueryChanged(String query) {
void _handleSearchQueryChanged(InputValue query) {
setState(() {
_searchQuery = query;
});
......@@ -197,9 +197,9 @@ class StockHomeState extends State<StockHome> {
}
Iterable<Stock> _filterBySearchQuery(Iterable<Stock> stocks) {
if (_searchQuery == null)
if (_searchQuery.text.isEmpty)
return stocks;
RegExp regexp = new RegExp(_searchQuery, caseSensitive: false);
RegExp regexp = new RegExp(_searchQuery.text, caseSensitive: false);
return stocks.where((Stock stock) => stock.symbol.contains(regexp));
}
......@@ -254,6 +254,7 @@ class StockHomeState extends State<StockHome> {
tooltip: 'Back'
),
center: new Input(
value: _searchQuery,
key: searchFieldKey,
autofocus: true,
hintText: 'Search stocks',
......
......@@ -7,12 +7,12 @@ import 'package:flutter/rendering.dart' show debugDumpRenderTree;
class CardModel {
CardModel(this.value, this.height) {
label = "Item $value";
inputValue = new InputValue(text: "Item $value");
}
int value;
double height;
int get color => ((value % 9) + 1) * 100;
String label;
InputValue inputValue;
Key get key => new ObjectKey(this);
}
......@@ -305,9 +305,11 @@ class CardCollectionState extends State<CardCollection> {
new Center(
child: new Input(
key: new GlobalObjectKey(cardModel),
initialValue: cardModel.label,
onChanged: (String value) {
cardModel.label = value;
value: cardModel.inputValue,
onChanged: (InputValue value) {
setState(() {
cardModel.inputValue = value;
});
}
)
)
......@@ -317,7 +319,7 @@ class CardCollectionState extends State<CardCollection> {
),
child: new Column(
children: <Widget>[
new Text(cardModel.label)
new Text(cardModel.inputValue.text)
],
alignItems: FlexAlignItems.stretch,
justifyContent: FlexJustifyContent.center
......
......@@ -4,7 +4,6 @@
import 'package:flutter/services.dart';
import 'package:flutter/widgets.dart';
import 'package:sky_services/editing/editing.mojom.dart' as mojom;
import 'colors.dart';
import 'debug.dart';
......@@ -17,8 +16,7 @@ export 'package:sky_services/editing/editing.mojom.dart' show KeyboardType;
class Input extends StatefulComponent {
Input({
GlobalKey key,
this.initialValue: '',
this.initialSelection,
this.value: InputValue.empty,
this.keyboardType: KeyboardType.text,
this.icon,
this.labelText,
......@@ -34,11 +32,8 @@ class Input extends StatefulComponent {
assert(key != null);
}
/// The initial editable text for the input field.
final String initialValue;
/// The initial selection for this input field.
final TextSelection initialSelection;
/// The text of the input field.
final InputValue value;
/// The type of keyboard to use for editing the text.
final KeyboardType keyboardType;
......@@ -68,10 +63,10 @@ class Input extends StatefulComponent {
final bool autofocus;
/// Called when the text being edited changes.
final ValueChanged<String> onChanged;
final ValueChanged<InputValue> onChanged;
/// Called when the user indicates that they are done editing the text in the field.
final ValueChanged<String> onSubmitted;
final ValueChanged<InputValue> onSubmitted;
_InputState createState() => new _InputState();
}
......@@ -80,89 +75,13 @@ const Duration _kTransitionDuration = const Duration(milliseconds: 200);
const Curve _kTransitionCurve = Curves.ease;
class _InputState extends State<Input> {
String _value;
EditableString _editableString;
KeyboardHandle _keyboardHandle;
// Used by tests.
EditableString get editableValue => _editableString;
void initState() {
super.initState();
_value = config.initialValue;
_editableString = new EditableString(
text: _value,
selection: config.initialSelection,
onUpdated: _handleTextUpdated,
onSubmitted: _handleTextSubmitted
);
}
void dispose() {
if (_isAttachedToKeyboard)
_keyboardHandle.release();
super.dispose();
}
bool get _isAttachedToKeyboard => _keyboardHandle != null && _keyboardHandle.attached;
void _attachOrDetachKeyboard(bool focused) {
if (focused && !_isAttachedToKeyboard) {
_keyboardHandle = keyboard.attach(_editableString.createStub(),
new mojom.KeyboardConfiguration()
..type = config.keyboardType);
_keyboardHandle.setEditingState(_editableString.editingState);
_keyboardHandle.show();
} else if (!focused && _isAttachedToKeyboard) {
_keyboardHandle.release();
_keyboardHandle = null;
_editableString.didDetachKeyboard();
}
}
void _requestKeyboard() {
if (Focus.at(context)) {
assert(_isAttachedToKeyboard);
_keyboardHandle.show();
} else {
Focus.moveTo(config.key);
// we'll get told to rebuild and we'll take care of the keyboard then
}
}
void _handleTextUpdated() {
if (_value != _editableString.text) {
setState(() {
_value = _editableString.text;
});
if (config.onChanged != null)
config.onChanged(_value);
}
}
void _handleTextSubmitted() {
Focus.clear(context);
if (config.onSubmitted != null)
config.onSubmitted(_value);
}
void _handleSelectionChanged(TextSelection selection) {
if (_isAttachedToKeyboard) {
_editableString.setSelection(selection);
_keyboardHandle.setEditingState(_editableString.editingState);
} else {
_editableString.setSelection(selection);
_requestKeyboard();
}
}
GlobalKey<RawInputLineState> _rawInputLineKey = new GlobalKey<RawInputLineState>();
Widget build(BuildContext context) {
assert(debugCheckHasMaterial(context));
ThemeData themeData = Theme.of(context);
bool focused = Focus.at(context, autofocus: config.autofocus);
_attachOrDetachKeyboard(focused);
TextStyle textStyle = config.style ?? themeData.text.subhead;
Color focusHighlightColor = themeData.accentColor;
if (themeData.primarySwatch != null)
......@@ -171,7 +90,7 @@ class _InputState extends State<Input> {
List<Widget> stackChildren = <Widget>[];
bool hasInlineLabel = config.labelText != null && !focused && !_value.isNotEmpty;
bool hasInlineLabel = config.labelText != null && !focused && !config.value.text.isNotEmpty;
if (config.labelText != null) {
TextStyle labelStyle = hasInlineLabel ?
......@@ -194,7 +113,7 @@ class _InputState extends State<Input> {
topPadding += topPaddingIncrement;
}
if (config.hintText != null && _value.isEmpty && !hasInlineLabel) {
if (config.hintText != null && config.value.text.isEmpty && !hasInlineLabel) {
TextStyle hintStyle = themeData.text.subhead.copyWith(color: themeData.hintColor);
stackChildren.add(new Positioned(
left: 0.0,
......@@ -234,14 +153,17 @@ class _InputState extends State<Input> {
)
)
),
child: new RawEditableLine(
value: _editableString,
focused: focused,
child: new RawInputLine(
key: _rawInputLineKey,
value: config.value,
focusKey: config.key,
style: textStyle,
hideText: config.hideText,
cursorColor: cursorColor,
selectionColor: cursorColor,
onSelectionChanged: _handleSelectionChanged
keyboardType: config.keyboardType,
onChanged: config.onChanged,
onSubmitted: config.onSubmitted
)
));
......@@ -278,7 +200,7 @@ class _InputState extends State<Input> {
return new GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: _requestKeyboard,
onTap: () => _rawInputLineKey.currentState?.requestKeyboard(),
child: new Padding(
padding: const EdgeDims.symmetric(horizontal: 16.0),
child: child
......
......@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'dart:ui' show TextAffinity, TextPosition;
import 'dart:ui' show hashValues, TextAffinity, TextPosition;
export 'dart:ui' show TextAffinity, TextPosition;
......@@ -50,6 +50,22 @@ class TextRange {
assert(isNormalized);
return text.substring(start, end);
}
bool operator ==(dynamic other) {
if (identical(this, other))
return true;
if (other is! TextRange)
return false;
TextRange typedOther = other;
return typedOther.start == start
&& typedOther.end == end;
}
int get hashCode => hashValues(
start.hashCode,
end.hashCode
);
}
/// A range of text that represents a selection.
......@@ -122,4 +138,23 @@ class TextSelection extends TextRange {
String toString() {
return '$runtimeType(baseOffset: $baseOffset, extentOffset: $extentOffset, affinity: $affinity, isDirectional: $isDirectional)';
}
bool operator ==(dynamic other) {
if (identical(this, other))
return true;
if (other is! TextSelection)
return false;
TextSelection typedOther = other;
return typedOther.baseOffset == baseOffset
&& typedOther.extentOffset == extentOffset
&& typedOther.affinity == affinity
&& typedOther.isDirectional == isDirectional;
}
int get hashCode => hashValues(
baseOffset.hashCode,
extentOffset.hashCode,
affinity.hashCode,
isDirectional.hashCode
);
}
......@@ -6,13 +6,16 @@ import 'dart:async';
import 'package:flutter/rendering.dart' show RenderEditableLine;
import 'package:sky_services/editing/editing.mojom.dart' as mojom;
import 'package:flutter/services.dart';
import 'basic.dart';
import 'framework.dart';
import 'focus.dart';
import 'scrollable.dart';
import 'scroll_behavior.dart';
export 'package:flutter/painting.dart' show TextSelection;
export 'package:sky_services/editing/editing.mojom.dart' show KeyboardType;
const Duration _kCursorBlinkHalfPeriod = const Duration(milliseconds: 500);
......@@ -27,17 +30,16 @@ TextSelection _getTextSelectionFromEditingState(mojom.EditingState state) {
class _KeyboardClientImpl implements mojom.KeyboardClient {
_KeyboardClientImpl({
String text: '',
TextSelection selection,
this.inputValue,
this.onUpdated,
this.onSubmitted
}) : text = text, selection = selection ?? new TextSelection.collapsed(offset: text.length) {
}) {
assert(inputValue != null);
assert(onUpdated != null);
assert(onSubmitted != null);
}
/// The current text being edited.
String text;
InputValue inputValue;
/// Called whenever the text changes.
final VoidCallback onUpdated;
......@@ -45,12 +47,6 @@ class _KeyboardClientImpl implements mojom.KeyboardClient {
/// Called whenever the user indicates they are done editing the string.
final VoidCallback onSubmitted;
// The range of text that is still being composed.
TextRange composing = TextRange.empty;
/// The range of text that is currently selected.
TextSelection selection;
/// A keyboard client stub that can be attached to a keyboard service.
mojom.KeyboardClientStub createStub() {
return new mojom.KeyboardClientStub.unbound()..impl = this;
......@@ -58,69 +54,82 @@ class _KeyboardClientImpl implements mojom.KeyboardClient {
mojom.EditingState get editingState {
return new mojom.EditingState()
..text = text
..selectionBase = selection.baseOffset
..selectionExtent = selection.extentOffset
..selectionAffinity = mojom.TextAffinity.values[selection.affinity.index]
..selectionIsDirectional = selection.isDirectional
..composingBase = composing.start
..composingExtent = composing.end;
..text = inputValue.text
..selectionBase = inputValue.selection.baseOffset
..selectionExtent = inputValue.selection.extentOffset
..selectionAffinity = mojom.TextAffinity.values[inputValue.selection.affinity.index]
..selectionIsDirectional = inputValue.selection.isDirectional
..composingBase = inputValue.composing.start
..composingExtent = inputValue.composing.end;
}
void updateEditingState(mojom.EditingState state) {
text = state.text;
selection = _getTextSelectionFromEditingState(state);
composing = new TextRange(start: state.composingBase, end: state.composingExtent);
inputValue = new InputValue(
text: state.text,
selection: _getTextSelectionFromEditingState(state),
composing: new TextRange(start: state.composingBase, end: state.composingExtent)
);
onUpdated();
}
void clearComposing() {
inputValue = inputValue.copyWith(composing: TextRange.empty);
}
void submit(mojom.SubmitAction action) {
composing = TextRange.empty;
clearComposing();
onSubmitted();
}
}
/// A string that can be manipulated by a keyboard.
///
/// Can be displayed with [RawEditableLine]. For a more featureful input widget,
/// consider using [Input].
class EditableString {
EditableString({
String text: '',
TextSelection selection,
VoidCallback onUpdated,
VoidCallback onSubmitted
}) : _client = new _KeyboardClientImpl(
text: text,
selection: selection,
onUpdated: onUpdated,
onSubmitted: onSubmitted
);
final _KeyboardClientImpl _client;
/// Configurable state of an input field.
class InputValue {
const InputValue({
this.text: '',
this.selection: const TextSelection.collapsed(offset: -1),
this.composing: TextRange.empty
});
/// The current text being edited.
String get text => _client.text;
final String text;
/// The range of text that is currently selected.
final TextSelection selection;
// The range of text that is still being composed.
TextRange get composing => _client.composing;
final TextRange composing;
/// The range of text that is currently selected.
TextSelection get selection => _client.selection;
static const InputValue empty = const InputValue();
void setSelection(TextSelection selection) {
_client.selection = selection;
}
String toString() => '$runtimeType(text: $text, selection: $selection, composing: $composing)';
mojom.EditingState get editingState => _client.editingState;
bool operator ==(dynamic other) {
if (identical(this, other))
return true;
if (other is! InputValue)
return false;
InputValue typedOther = other;
return typedOther.text == text
&& typedOther.selection == selection
&& typedOther.composing == composing;
}
/// A keyboard client stub that can be attached to a keyboard service.
///
/// See [Keyboard].
mojom.KeyboardClientStub createStub() => _client.createStub();
int get hashCode => hashValues(
text.hashCode,
selection.hashCode,
composing.hashCode
);
void didDetachKeyboard() {
_client.composing = TextRange.empty;
InputValue copyWith({
String text,
TextSelection selection,
TextRange composing
}) {
return new InputValue (
text: text ?? this.text,
selection: selection ?? this.selection,
composing: composing ?? this.composing
);
}
}
......@@ -128,27 +137,29 @@ class EditableString {
///
/// This control is not intended to be used directly. Instead, consider using
/// [Input], which provides focus management and material design.
class RawEditableLine extends Scrollable {
RawEditableLine({
class RawInputLine extends Scrollable {
RawInputLine({
Key key,
this.value,
this.focused: false,
this.focusKey,
this.hideText: false,
this.style,
this.cursorColor,
this.selectionColor,
this.onSelectionChanged
this.keyboardType,
this.onChanged,
this.onSubmitted
}) : super(
key: key,
initialScrollOffset: 0.0,
scrollDirection: Axis.horizontal
);
/// The editable string being displayed in this widget.
final EditableString value;
/// The string being displayed in this widget.
final InputValue value;
/// Whether this widget is focused.
final bool focused;
/// Key of the enclosing widget that holds the focus.
final GlobalKey focusKey;
/// Whether to hide the text being edited (e.g., for passwords).
final bool hideText;
......@@ -162,22 +173,51 @@ class RawEditableLine extends Scrollable {
/// The color to use when painting the selection.
final Color selectionColor;
/// Called when the user requests a change to the selection.
final ValueChanged<TextSelection> onSelectionChanged;
/// The type of keyboard to use for editing the text.
final KeyboardType keyboardType;
RawEditableTextState createState() => new RawEditableTextState();
/// Called when the text being edited changes.
final ValueChanged<InputValue> onChanged;
/// Called when the user indicates that they are done editing the text in the field.
final ValueChanged<InputValue> onSubmitted;
RawInputLineState createState() => new RawInputLineState();
}
class RawEditableTextState extends ScrollableState<RawEditableLine> {
class RawInputLineState extends ScrollableState<RawInputLine> {
Timer _cursorTimer;
bool _showCursor = false;
double _contentWidth = 0.0;
double _containerWidth = 0.0;
_KeyboardClientImpl _keyboardClient;
KeyboardHandle _keyboardHandle;
ScrollBehavior createScrollBehavior() => new BoundedBehavior();
BoundedBehavior get scrollBehavior => super.scrollBehavior;
void initState() {
super.initState();
_keyboardClient = new _KeyboardClientImpl(
inputValue: config.value,
onUpdated: _handleTextUpdated,
onSubmitted: _handleTextSubmitted
);
}
void didUpdateConfig(RawInputLine oldConfig) {
if (_keyboardClient.inputValue != config.value) {
_keyboardClient.inputValue = config.value;
if (_isAttachedToKeyboard) {
_keyboardHandle.setEditingState(_keyboardClient.editingState);
}
}
}
bool get _isAttachedToKeyboard => _keyboardHandle != null && _keyboardHandle.attached;
void _handleContainerSizeChanged(Size newSize) {
_containerWidth = newSize.width;
_updateScrollBehavior();
......@@ -198,6 +238,48 @@ class RawEditableTextState extends ScrollableState<RawEditableLine> {
));
}
void _attachOrDetachKeyboard(bool focused) {
if (focused && !_isAttachedToKeyboard) {
_keyboardHandle = keyboard.attach(_keyboardClient.createStub(),
new mojom.KeyboardConfiguration()
..type = config.keyboardType);
_keyboardHandle.setEditingState(_keyboardClient.editingState);
_keyboardHandle.show();
} else if (!focused && _isAttachedToKeyboard) {
_keyboardHandle.release();
_keyboardHandle = null;
_keyboardClient.clearComposing();
}
}
void requestKeyboard() {
if (_isAttachedToKeyboard) {
_keyboardHandle.show();
} else {
Focus.moveTo(config.focusKey);
}
}
void _handleTextUpdated() {
if (config.onChanged != null)
config.onChanged(_keyboardClient.inputValue);
}
void _handleTextSubmitted() {
Focus.clear(context);
if (config.onSubmitted != null)
config.onSubmitted(_keyboardClient.inputValue);
}
void _handleSelectionChanged(TextSelection selection) {
// Note that this will show the keyboard for all selection changes on the
// EditableLineWidget, not just changes triggered by user gestures.
requestKeyboard();
if (config.onChanged != null)
config.onChanged(_keyboardClient.inputValue.copyWith(selection: selection));
}
/// Whether the blinking cursor is actually visible at this precise moment
/// (it's hidden half the time, since it blinks).
bool get cursorCurrentlyVisible => _showCursor;
......@@ -219,6 +301,8 @@ class RawEditableTextState extends ScrollableState<RawEditableLine> {
}
void dispose() {
if (_isAttachedToKeyboard)
_keyboardHandle.release();
if (_cursorTimer != null)
_stopCursorTimer();
super.dispose();
......@@ -232,12 +316,15 @@ class RawEditableTextState extends ScrollableState<RawEditableLine> {
Widget buildContent(BuildContext context) {
assert(config.style != null);
assert(config.focused != null);
assert(config.focusKey != null);
assert(config.cursorColor != null);
if (_cursorTimer == null && config.focused && config.value.selection.isCollapsed)
bool focused = Focus.at(config.focusKey.currentContext);
_attachOrDetachKeyboard(focused);
if (_cursorTimer == null && focused && config.value.selection.isCollapsed)
_startCursorTimer();
else if (_cursorTimer != null && (!config.focused || !config.value.selection.isCollapsed))
else if (_cursorTimer != null && (!focused || !config.value.selection.isCollapsed))
_stopCursorTimer();
return new SizeObserver(
......@@ -250,7 +337,7 @@ class RawEditableTextState extends ScrollableState<RawEditableLine> {
selectionColor: config.selectionColor,
hideText: config.hideText,
onContentSizeChanged: _handleContentSizeChanged,
onSelectionChanged: config.onSelectionChanged,
onSelectionChanged: _handleSelectionChanged,
paintOffset: new Offset(-scrollOffset, 0.0)
)
);
......@@ -271,7 +358,7 @@ class _EditableLineWidget extends LeafRenderObjectWidget {
this.paintOffset
}) : super(key: key);
final EditableString value;
final InputValue value;
final TextStyle style;
final Color cursorColor;
final bool showCursor;
......
......@@ -30,15 +30,16 @@ void main() {
test('Editable text has consistent size', () {
testWidgets((WidgetTester tester) {
GlobalKey inputKey = new GlobalKey();
String inputValue;
InputValue inputValue = InputValue.empty;
Widget builder() {
return new Center(
child: new Material(
child: new Input(
value: inputValue,
key: inputKey,
hintText: 'Placeholder',
onChanged: (String value) { inputValue = value; }
onChanged: (InputValue value) { inputValue = value; }
)
)
);
......@@ -58,7 +59,7 @@ void main() {
..composingExtent = testValue.length);
// Check that the onChanged event handler fired.
expect(inputValue, equals(testValue));
expect(inputValue.text, equals(testValue));
tester.pumpWidget(builder());
}
......@@ -88,7 +89,7 @@ void main() {
tester.pumpWidget(builder());
RawEditableTextState editableText = tester.findStateOfType(RawEditableTextState);
RawInputLineState editableText = tester.findStateOfType(RawInputLineState);
// Check that the cursor visibility toggles after each blink interval.
void checkCursorToggle() {
......
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