Fields topic

MRETextField is an ordinary input with Unicode-wide direction, suggestions, clear and optional in-field images. MRETextFormField composes it with validation, saving and reset. Both take the host's theme and the same appearance parameters.

Basic field

The direction follows the first word with a letter, as the user types. See Text for how it is chosen. A clear button shows while the field has text.

final field = MRETextField(
  labelText: 'Name',
  hintText: 'Type in any language',
  showClearButton: true,
);

Lock the direction

Emails, links and numbers read left to right in any language. Set textDirection to turn detection off for that field.

final email = MRETextField(
  labelText: 'Email',
  keyboardType: TextInputType.emailAddress,
  textDirection: TextDirection.ltr,
);

Change one field

A parameter beats MREFieldsTheme, and MREFieldsTheme beats your InputDecorationTheme. Radius applies to outline borders only. Without a registered MREFieldsTheme or a borderRadius, borders stay as your theme defines them.

final field = MRETextField(
  labelText: 'Search',
  borderRadius: 28, // this field only; the theme keeps its own radius
  contentPadding: const EdgeInsets.symmetric(horizontal: 24, vertical: 12),
);

Use it in a form

final form = Form(
  key: formKey,
  child: MRETextFormField(
    labelText: 'Name',
    validator: (value) {
      if (value == null || value.trim().isEmpty) {
        return 'Enter a name';
      }
      return null;
    },
  ),
);

Call formKey.currentState!.validate() as with any form field. Without a parent Form, pass fieldKey and call fieldKey.currentState!.validate().

Suggestions

Suggestions show under the field while it has focus. They filter as the user types, ignore case, and hide the one that equals the text.

final field = MRETextField(
  labelText: 'City',
  suggestions: const ['Cairo', 'Alexandria', 'Giza', 'القاهرة'],
  maxSuggestions: 5,
);

Select the text on focus

final field = MRETextField(
  labelText: 'Title',
  initialValue: 'Draft',
  selectTextOnFocus: true,
);

Own the controller

Without a controller the field creates one and disposes it. With one, you own it. MRESafeTextEditingController is the one used by default; it replaces unpaired surrogates that crash Flutter's text layout.

final field = MRETextField(
  controller: controller,
  labelText: 'Notes',
  maxLines: 4,
);

Use the pieces alone

The clear button and the suggestion bar work in any field.

final field = TextField(
  controller: controller,
  decoration: InputDecoration(
    suffixIcon: MREFieldClearButton(
      onPressed: controller.clear,
      tooltip: 'Clear',
    ),
  ),
);
final bar = MRESuggestionBar(
  suggestions: const ['Cairo', 'Giza'],
  onSelected: (city) => controller.text = city,
);

Form lifecycle

MRETextFormField adds validator, onSaved, onReset, autovalidateMode and fieldKey. The ordinary MRETextField has no form registration. Both support imagePaste. Reset restores the text; attachments have their own controller. Use onReset: attachments.clear if your form should also clear its images.

Classes

MREFieldClearButton Fields
The small "x" button that empties a field.
MRESafeTextEditingController Fields
A TextEditingController that cannot crash the text layout.
MRESuggestionBar Fields
A row of tappable suggestions that scrolls sideways.
MRETextField Fields
A text field that follows the language of what the user types.
MRETextFormField Fields
A text form field with Unicode direction, suggestions and image paste.

Functions

mreFilterSuggestions(List<String> all, String query, {int limit = 20}) → List<String> Fields
Returns the suggestions in all that match query, at most limit.