Skip to content
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

Feat: TextField can scroll when disabled #140922

Merged

Conversation

bryanoli
Copy link
Contributor

@bryanoli bryanoli commented Jan 3, 2024

This PR is adding a flag parameter to the TextField widget. This flag controls whether the TextField ignores pointers. The flag takes priority over other TextField behaviors such as enabled, so it can be useful when trying to have a disabled TextField that can be scrolled (behavior observed using TextArea on the web).

Adding a flag parameter to TextField helps with more customization and flexibility to the widget which can improve user experience. I am open to other ideas.

Fixes issue #140147

Before:

localhost_52348.-.Google.Chrome.2024-01-03.14-10-29.mp4

After:

localhost_52348.-.Google.Chrome.2024-01-03.14-03-39.mp4

Usage:

child: TextField(
  ignorePointer: false,
  enabled: false,
),

Pre-launch Checklist

  • I read the [Contributor Guide] and followed the process outlined there for submitting PRs.
  • I read the [Tree Hygiene] wiki page, which explains my responsibilities.
  • I read and followed the [Flutter Style Guide], including [Features we expect every widget to implement].
  • I signed the [CLA].
  • I listed at least one issue that this PR fixes in the description above.
  • I updated/added relevant documentation (doc comments with ///).
  • I added new tests to check the change I am making, or this PR is [test-exempt].
  • All existing and new tests are passing.

@github-actions github-actions bot added a: text input Entering text in a text field or keyboard related problems framework flutter/packages/flutter repository. See also f: labels. f: material design flutter/packages/flutter/material repository. labels Jan 3, 2024
@Renzo-Olivares Renzo-Olivares self-requested a review January 3, 2024 22:16
@justinmc justinmc self-requested a review January 4, 2024 23:23
@@ -24,6 +24,7 @@ import 'package:flutter/rendering.dart';
import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart';

import '../cupertino/text_field_restoration_test.dart';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: I don't think this line is needed.

@@ -604,6 +605,10 @@ class TextField extends StatefulWidget {
/// [InputDecoration.enabled] property.
final bool? enabled;

/// If false the text field is "disabled" but still scrollable.
/// However, if [enabled] is true, then the text field is "active" and still scrollable.
final bool? ignorePointer;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe instead of discussing the specific scrollable use-case this parameter is solving, you could talk about what it does in general. i.e. ignorePointer decides whether the widget will handle pointer events.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1, especially since this parameter doesn't actually cause the field to be disabled like enabled does.

@@ -291,6 +291,7 @@ class TextField extends StatefulWidget {
this.onAppPrivateCommand,
this.inputFormatters,
this.enabled,
this.ignorePointer,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: maybe ignoresPointers?

Copy link
Contributor

@justinmc justinmc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The approach looks good, thanks for the PR! I'm on board with adding this parameter since it seems that we can't match textarea's behavior without it.

@@ -604,6 +605,10 @@ class TextField extends StatefulWidget {
/// [InputDecoration.enabled] property.
final bool? enabled;

/// If false the text field is "disabled" but still scrollable.
/// However, if [enabled] is true, then the text field is "active" and still scrollable.
final bool? ignorePointer;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1, especially since this parameter doesn't actually cause the field to be disabled like enabled does.

@@ -985,7 +990,7 @@ class _TextFieldState extends State<TextField> with RestorationMixin implements
final GlobalKey<EditableTextState> editableTextKey = GlobalKey<EditableTextState>();

@override
bool get selectionEnabled => widget.selectionEnabled;
bool get selectionEnabled => widget.selectionEnabled && _isEnabled;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why was this change needed?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change was made because the text selection menu (copy, paste, etc...) opens up when right-clicking on the textfield when disabled (and ignorePointers set to false). So the selectionEnabled should take into account for _isEnabled to prevent selection in all cases when the widget is disabled.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah makes sense, thanks for the explanation.

await gesture.moveBy(const Offset(0.0, -1000.0));
await tester.pump(const Duration(seconds: 1));
// Wait and drag again to trigger https://github.com/flutter/flutter/issues/6329
// (No idea why this is necessary, but the bug wouldn't repro without it.)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm we need to figure that out. Maybe try pumpAndSettle for the previous one on line 6573?

Comment on lines 6583 to 6584
final Offset newFirstPos = textOffsetToPosition(tester, kMoreThanFourLines.indexOf('First'));
final Offset newFourthPos = textOffsetToPosition(tester, kMoreThanFourLines.indexOf('Fourth'));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe finalFirstPos etc.

@github-actions github-actions bot added a: tests "flutter test", flutter_test, or one of our tests platform-ios iOS applications specifically tool Affects the "flutter" command-line tool. See also t: labels. engine flutter/engine repository. See also e: labels. d: api docs Issues with https://api.flutter.dev/ d: examples Sample code and demos f: gestures flutter/packages/flutter/gestures repository. a: desktop Running on desktop f: integration_test The flutter/packages/integration_test plugin labels Jan 9, 2024
@bryanoli bryanoli force-pushed the bryanoli-textfield-scroll-disable-140147 branch from 7502f2f to ec56971 Compare January 9, 2024 04:41
@github-actions github-actions bot removed a: tests "flutter test", flutter_test, or one of our tests platform-ios iOS applications specifically tool Affects the "flutter" command-line tool. See also t: labels. engine flutter/engine repository. See also e: labels. d: api docs Issues with https://api.flutter.dev/ d: examples Sample code and demos f: gestures flutter/packages/flutter/gestures repository. a: desktop Running on desktop labels Jan 9, 2024
@jmagman jmagman removed their request for review January 9, 2024 18:53
@christopherfujino christopherfujino removed their request for review January 9, 2024 20:14
@bryanoli bryanoli force-pushed the bryanoli-textfield-scroll-disable-140147 branch from d682ea8 to f405eae Compare January 23, 2024 20:21
Copy link
Contributor

@Renzo-Olivares Renzo-Olivares left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Copy link
Contributor

@justinmc justinmc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The only thing that I think should be changed is the tester.pump(const Duration(seconds: 1));, mentioned below. Otherwise this looks good.

///
/// If true, this widget does not respond to pointer events,
/// If false this widget responds to all pointer events.
final bool? ignorePointers;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1 to this suggestion.

await gesture.moveBy(const Offset(0.0, -1000.0));
await tester.pumpAndSettle();
await gesture.moveBy(const Offset(0.0, -1000.0));
await tester.pump(const Duration(seconds: 1));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this work with pumpAndSettle instead? Same question for the similar pump a few lines below.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, using pumpAndSettle does work.

@bryanoli bryanoli force-pushed the bryanoli-textfield-scroll-disable-140147 branch from ce769e4 to 9cad5ae Compare January 24, 2024 23:23
Copy link
Contributor

@justinmc justinmc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM 👍 . Thanks for the fixes!

One last nit: don't forget this comment asking for a small change to the docs there.

await gesture.moveBy(const Offset(0.0, -1000.0));
await tester.pumpAndSettle();
await gesture.up();
await tester.pump();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This pump is probably unnecessary.

@bryanoli bryanoli force-pushed the bryanoli-textfield-scroll-disable-140147 branch from 4b7c5fe to 1743a58 Compare January 26, 2024 17:10
@Renzo-Olivares Renzo-Olivares added the autosubmit Merge PR when tree becomes green via auto submit App label Jan 29, 2024
@auto-submit auto-submit bot merged commit 1d5c2c5 into flutter:master Jan 29, 2024
66 checks passed
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Jan 30, 2024
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Jan 30, 2024
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Jan 30, 2024
auto-submit bot pushed a commit to flutter/packages that referenced this pull request Jan 30, 2024
…6013)

Manual roll Flutter from 2f6fdf2650d4 to ace9181172b6 (57 revisions)

Manual roll requested by stuartmorgan@google.com

flutter/flutter@2f6fdf2...ace9181

2024-01-29 engine-flutter-autoroll@skia.org Roll Flutter Engine from 9c3ebf67b5da to bedafa8794b6 (4 revisions) (flutter/flutter#142478)
2024-01-29 jmccandless@google.com onNavigationNotification for *App.router (flutter/flutter#142190)
2024-01-29 fluttergithubbot@gmail.com Marks Mac_x64 framework_tests_misc to be unflaky (flutter/flutter#142118)
2024-01-29 engine-flutter-autoroll@skia.org Roll Flutter Engine from 3e2b8975bd5b to 9c3ebf67b5da (1 revision) (flutter/flutter#142472)
2024-01-29 66151079+bryanoli@users.noreply.github.com Feat: TextField can scroll when disabled (flutter/flutter#140922)
2024-01-29 engine-flutter-autoroll@skia.org Roll Flutter Engine from 436f91f3b06b to 3e2b8975bd5b (2 revisions) (flutter/flutter#142466)
2024-01-29 fluttergithubbot@gmail.com Marks Mac_arm64 framework_tests_misc to be unflaky (flutter/flutter#142119)
2024-01-29 goderbauer@google.com Fix InputDecorationTheme copyWith fallback for iconColor (flutter/flutter#142462)
2024-01-29 mbfakourii@gmail.com Add `SingleChildScrollView` for `NavigationRail` (flutter/flutter#137415)
2024-01-29 737941+loic-sharma@users.noreply.github.com [Windows Arm64] Run plugin test post-submit (flutter/flutter#141987)
2024-01-29 andrewrkolos@gmail.com Catch file system exceptions when trying to parse user-provided asset file paths (flutter/flutter#142214)
2024-01-29 nathan.wilson1232@gmail.com Implementing `switch` expressions in `foundation/` and `material/` (flutter/flutter#142279)
2024-01-29 engine-flutter-autoroll@skia.org Roll Flutter Engine from bff1e46c0d65 to 436f91f3b06b (1 revision) (flutter/flutter#142455)
2024-01-29 polinach@google.com Opt out test from leak tracking. (flutter/flutter#142417)
2024-01-29 zanderso@users.noreply.github.com Update Android minSdkVersion to 21 (flutter/flutter#142267)
2024-01-29 engine-flutter-autoroll@skia.org Roll Flutter Engine from 3d87470655b1 to bff1e46c0d65 (1 revision) (flutter/flutter#142446)
2024-01-29 engine-flutter-autoroll@skia.org Roll Packages from cbe8100 to 516648a (3 revisions) (flutter/flutter#142445)
2024-01-29 engine-flutter-autoroll@skia.org Roll Flutter Engine from 1405cb7b6e74 to 3d87470655b1 (1 revision) (flutter/flutter#142444)
2024-01-29 engine-flutter-autoroll@skia.org Roll Flutter Engine from 3e65f1720a6f to 1405cb7b6e74 (1 revision) (flutter/flutter#142432)
2024-01-29 engine-flutter-autoroll@skia.org Roll Flutter Engine from 210ed1dfb8cf to 3e65f1720a6f (1 revision) (flutter/flutter#142429)
2024-01-29 engine-flutter-autoroll@skia.org Roll Flutter Engine from f15cb86d31c3 to 210ed1dfb8cf (1 revision) (flutter/flutter#142426)
2024-01-29 engine-flutter-autoroll@skia.org Roll Flutter Engine from f3d48be76630 to f15cb86d31c3 (11 revisions) (flutter/flutter#142425)
2024-01-27 engine-flutter-autoroll@skia.org Roll Flutter Engine from 95e9a15fd909 to f3d48be76630 (1 revision) (flutter/flutter#142370)
2024-01-27 zanderso@users.noreply.github.com Add no-shuffle to language_version_test.dart (flutter/flutter#142378)
2024-01-27 engine-flutter-autoroll@skia.org Roll Flutter Engine from 2687ddb2655c to 95e9a15fd909 (8 revisions) (flutter/flutter#142369)
2024-01-27 98614782+auto-submit[bot]@users.noreply.github.com Reverts "Roll Flutter Engine from 2687ddb2655c to 2adad88a39f4 (4 revisions)" (flutter/flutter#142366)
2024-01-27 engine-flutter-autoroll@skia.org Roll Flutter Engine from 2687ddb2655c to 2adad88a39f4 (4 revisions) (flutter/flutter#142362)
2024-01-27 engine-flutter-autoroll@skia.org Roll Flutter Engine from 45c06c22d5c7 to 2687ddb2655c (1 revision) (flutter/flutter#142359)
2024-01-27 31859944+LongCatIsLooong@users.noreply.github.com Remove suspicious constant from input decorator layout (flutter/flutter#142342)
2024-01-27 engine-flutter-autoroll@skia.org Roll Flutter Engine from 2e32acf4c31a to 45c06c22d5c7 (2 revisions) (flutter/flutter#142353)
2024-01-27 engine-flutter-autoroll@skia.org Roll Flutter Engine from a65a1b55e06a to 2e32acf4c31a (1 revision) (flutter/flutter#142351)
2024-01-26 engine-flutter-autoroll@skia.org Roll Flutter Engine from 525bd7dcf7f3 to a65a1b55e06a (11 revisions) (flutter/flutter#142347)
2024-01-26 goderbauer@google.com Relands "Add runWidget to bootstrap a widget tree without a default View" (flutter/flutter#142344)
2024-01-26 amirpanahandeh@yahoo.com Fix assertion failure when reordering two dimensional children (flutter/flutter#141504)
2024-01-26 magder@google.com Limit `fuchsia_precache` in presubmit to engine rolls (flutter/flutter#142333)
2024-01-26 49699333+dependabot[bot]@users.noreply.github.com Bump github/codeql-action from 3.23.1 to 3.23.2 (flutter/flutter#142345)
2024-01-26 andrewrkolos@gmail.com refactor asset bundle code to not depend on the global Cache.flutterRoot (flutter/flutter#142277)
2024-01-26 christopherfujino@gmail.com [flutter_tools] remove await runZonedGuarded() in tests (flutter/flutter#142336)
2024-01-26 15619084+vashworth@users.noreply.github.com Only use iOS 17 physical devices in staging tests (flutter/flutter#142323)
2024-01-26 dacoharkes@google.com Roll deps from dart-lang/native in templates (flutter/flutter#142322)
2024-01-26 andrewrkolos@gmail.com Remove duplicate global declaration of `UserMessages` (flutter/flutter#142281)
2024-01-26 magder@google.com Redistribute iOS TESTOWNERS (flutter/flutter#142315)
2024-01-26 98614782+auto-submit[bot]@users.noreply.github.com Reverts "Add runWidget to bootstrap a widget tree without a default View" (flutter/flutter#142339)
2024-01-26 98614782+auto-submit[bot]@users.noreply.github.com Reverts "Roll Flutter Engine from 525bd7dcf7f3 to 65d1291c3add (1 revision)" (flutter/flutter#142332)
...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
a: text input Entering text in a text field or keyboard related problems autosubmit Merge PR when tree becomes green via auto submit App f: material design flutter/packages/flutter/material repository. framework flutter/packages/flutter repository. See also f: labels.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants