Unverified Commit 896c19a2 authored by Justin McCandless's avatar Justin McCandless Committed by GitHub

Characters docs (#67361)

parent b5562c1b
......@@ -14,7 +14,7 @@ const String _kGalleryAssetsPackage = 'flutter_gallery_assets';
class _Page {
_Page({ this.label });
final String label;
String get id => label[0];
String get id => label.characters.first;
@override
String toString() => '$runtimeType("$label")';
}
......
......@@ -131,6 +131,8 @@ class _CupertinoTextFieldSelectionGestureDetectorBuilder extends TextSelectionGe
/// field (e.g., by pressing a button on the soft keyboard), the text field
/// calls the [onSubmitted] callback.
///
/// {@macro flutter.widgets.editableText.complexCharacters}
///
/// To control the text that is displayed in the text field, use the
/// [controller]. For example, to set the initial value of the text field, use
/// a [controller] that already contains some text such as:
......
......@@ -43,6 +43,9 @@ import 'theme.dart';
/// the [AppBar.leading] position e.g. from the hamburger menu to the back arrow
/// used to exit the search page.
///
/// ## Handling emojis and other complex characters
/// {@macro flutter.widgets.editableText.complexCharacters}
///
/// See also:
///
/// * [SearchDelegate] to define the content of the search page.
......@@ -85,6 +88,9 @@ Future<T> showSearch<T>({
/// A given [SearchDelegate] can only be associated with one active [showSearch]
/// call. Call [SearchDelegate.close] before re-using the same delegate instance
/// for another [showSearch] call.
///
/// ## Handling emojis and other complex characters
/// {@macro flutter.widgets.editableText.complexCharacters}
abstract class SearchDelegate<T> {
/// Constructor to be called by subclasses which may specify [searchFieldLabel], [keyboardType] and/or
......
......@@ -227,7 +227,7 @@ class _TextFieldSelectionGestureDetectorBuilder extends TextSelectionGestureDete
/// builder: (BuildContext context) {
/// return AlertDialog(
/// title: const Text('Thanks!'),
/// content: Text ('You typed "$value".'),
/// content: Text ('You typed "$value", which has length ${value.characters.length}.'),
/// actions: <Widget>[
/// TextButton(
/// onPressed: () { Navigator.pop(context); },
......@@ -256,6 +256,14 @@ class _TextFieldSelectionGestureDetectorBuilder extends TextSelectionGestureDete
///
/// Keep in mind you can also always read the current string from a TextField's
/// [TextEditingController] using [TextEditingController.text].
///
/// ## Handling emojis and other complex characters
/// {@macro flutter.widgets.editableText.complexCharacters}
///
/// In the live Dartpad example above, try typing the emoji 👨‍👩‍👦
/// into the field and submitting. Because the example code measures the length
/// with `value.characters.length`, the emoji is correctly counted as a single
/// character.
///
/// See also:
///
......
......@@ -25,6 +25,9 @@ import 'text_input.dart';
/// To create custom formatters, extend the [TextInputFormatter] class and
/// implement the [formatEditUpdate] method.
///
/// ## Handling emojis and other complex characters
/// {@macro flutter.widgets.editableText.complexCharacters}
///
/// See also:
///
/// * [EditableText] on which the formatting apply.
......@@ -300,13 +303,19 @@ class WhitelistingTextInputFormatter extends FilteringTextInputFormatter {
}
/// A [TextInputFormatter] that prevents the insertion of more characters
/// (currently defined as Unicode scalar values) than allowed.
/// than allowed.
///
/// Since this formatter only prevents new characters from being added to the
/// text, it preserves the existing [TextEditingValue.selection].
///
/// Characters are counted as user-perceived characters using the
/// [characters](https://pub.dev/packages/characters) package, so even complex
/// characters like extended grapheme clusters and surrogate pairs are counted
/// as single characters.
///
/// See also:
/// * [maxLength], which discusses the precise meaning of "number of
/// characters" and how it may differ from the intuitive meaning.
/// characters".
class LengthLimitingTextInputFormatter extends TextInputFormatter {
/// Creates a formatter that prevents the insertion of more characters than a
/// limit.
......
......@@ -946,6 +946,22 @@ class EditableText extends StatefulWidget {
/// {@end-tool}
/// {@endtemplate}
///
/// ## Handling emojis and other complex characters
/// {@template flutter.widgets.editableText.complexCharacters}
/// It's important to always use
/// [characters](https://pub.dev/packages/characters) when dealing with user
/// input text that may contain complex characters. This will ensure that
/// extended grapheme clusters and surrogate pairs are treated as single
/// characters, as they appear to the user.
///
/// For example, when finding the length of some user input, use
/// `string.characters.length`. Do NOT use `string.length` or even
/// `string.runes.length`. For the complex character "👨‍👩‍👦", this
/// appears to the user as a single character, and `string.characters.length`
/// intuitively returns 1. On the other hand, `string.length` returns 8, and
/// `string.runes.length` returns 5!
/// {@endtemplate}
///
/// See also:
///
/// * [inputFormatters], which are called before [onChanged]
......
......@@ -1571,6 +1571,16 @@ class Navigator extends StatefulWidget {
/// The [NavigatorState] and [initialRoute] will be passed to the callback.
/// The callback must return a list of [Route] objects with which the history
/// will be primed.
///
/// When parsing the initialRoute, if there's any chance that the it may
/// contain complex characters, it's best to use the
/// [characters](https://pub.dev/packages/characters) API. This will ensure
/// that extended grapheme clusters and surrogate pairs are treated as single
/// characters by the code, the same way that they appear to the user. For
/// example, the string "👨‍👩‍👦" appears to the user as a single
/// character and `string.characters.length` intuitively returns 1. On the
/// other hand, `string.length` returns 8, and `string.runes.length` returns
/// 5!
final RouteListFactory onGenerateInitialRoutes;
/// Whether this navigator should report route update message back to the
......
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