fix(w-input): native text selection (web mouse-drag + platform-adaptive handles)#116
Conversation
…ctorBuilder The Material-free rewrite (#106) dropped the selection gesture layer by rendering a bare EditableText, so mouse drag-select did nothing on web (only keyboard select-all worked). Adopt the framework's canonical Material-free recipe: _WInputState implements TextSelectionGestureDetectorBuilderDelegate, the whole decorated box is wrapped by buildGestureDetector, and EditableText.rendererIgnoresPointer is true so the gesture layer is the sole pointer handler. The hand-built whole-box GestureDetector is removed; onTap is forwarded via onUserTap. Selection handles are platform-adaptive via the lowercase *HandleControls constants (Cupertino on iOS, Cupertino-desktop on macOS, Material on Android/Fuchsia, desktop on Linux/Windows); each mixes in TextSelectionHandleControls so the toolbar stays on the Material-free contextMenuBuilder path and no Overlay-less long-press throws.
Update the w-input reference, the wind-ui SKILL.md WInput row (version 2.5.0 -> 2.6.0), and the forms reference to describe native text selection (mouse-drag, double-tap word, whole-box tap) and the platform-adaptive handles, replacing the stale Cupertino-on-all-platforms note. Add a web-reality note: Flutter renders selection to a canvas (no native browser input); right-click shows the browser menu by default, and an app opting into WInput's own toolbar calls BrowserContextMenu.disableContextMenu() at startup.
Add a Text Selection section with a prefilled read-only WInput and a caption explaining drag-to-select, double-tap word, and platform-adaptive handles, so the demo gallery showcases the native selection behavior.
|
Warning Review limit reached
More reviews will be available in 24 minutes and 4 seconds. Learn how PR review limits work. Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file). ⌛ How to resolve this issue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based credits. 🚦 How do rate limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan refill rate. For paid Pro and Pro+ PR reviews, CodeRabbit uses rolling per-developer review limits. Reviews become available again as older review attempts age out of the rolling limit window. Please see our Fair Usage Limits Policy for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (7)
📝 WalkthroughWalkthrough
ChangesWInput Native Text Selection
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Pull request overview
Restores native text selection behavior in WInput after the Material-free EditableText rewrite by adopting Flutter’s canonical TextSelectionGestureDetectorBuilder-based gesture layer and platform-adaptive selection handle controls, with corresponding tests and documentation updates.
Changes:
- Reintroduces pointer-driven selection gestures (mouse drag-select, double-tap word, whole-box tap-to-focus) via
TextSelectionGestureDetectorBuilderandrendererIgnoresPointer: true. - Switches selection handles to platform-adaptive
*TextSelectionHandleControlsconstants while keeping the input Material-free (no Material ancestor required). - Adds targeted widget tests plus doc/example/skill/changelog updates describing the restored selection behavior and web/Overlay constraints.
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| lib/src/widgets/w_input.dart | Installs the selection gesture detector builder, enables platform-adaptive handle controls, removes hand-rolled whole-box GestureDetector. |
| test/widgets/w_input/selection_test.dart | Adds coverage for drag selection, double-tap word selection, whole-box tap focus/onTap, disabled/read-only/no-Overlay behavior, and per-platform controls wiring. |
| doc/widgets/w-input.md | Documents native selection behavior, Overlay requirement, and web-specific context menu behavior. |
| example/lib/pages/forms/input_basic.dart | Adds a read-only “Text Selection” demo section with realistic prefilled content. |
| skills/wind-ui/SKILL.md | Bumps skill version and updates WInput capability summary to include native selection + Overlay notes. |
| skills/wind-ui/references/forms.md | Adds a concise note about WInput/WFormInput native selection + Overlay requirement. |
| CHANGELOG.md | Records the gesture-path change and the restored selection behavior under [Unreleased]. |
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
…rt import) Restore w_input.dart to its deliberate cupertino-only state from #106 (the only widget file that imports cupertino.dart and not material.dart). The platform-adaptive handle switch added the package:flutter/material.dart import back for materialTextSelectionHandleControls / desktopTextSelectionHandleControls, which #106 explicitly dropped. WInput now wires cupertinoTextSelectionHandleControls on every platform (unchanged from the 1.1.0 shipped behavior), keeping the widget cupertino-only while the gesture-builder fix (the actual web mouse drag-select bug) is untouched. Tests assert Cupertino handles on every TargetPlatform under a bare Material-free Overlay harness.
Update the w-input doc, the selectable example caption, the wind-ui skill + forms reference, and the CHANGELOG to state selection handles are Cupertino-style on all platforms (cupertino-only, no material.dart import), replacing the platform-adaptive wording.
Copilot flagged that the docs/comment claimed only the selection toolbar and handles are suppressed without an Overlay. In fact interactive selection is fully gated on an Overlay (enableInteractiveSelection and the gesture builder delegate's selectionEnabled both check Overlay.maybeOf), so without one drag-select, double-tap word, and long-press are all off too; only typing and focus work. Reword the class dartdoc, the selectionControls comment, the w-input doc note, and the wind-ui skill + forms reference to state this accurately.
Summary
WInputlost text selection when it was rewritten Material-free onto a bareEditableText(#106): a bareEditableTextdoes not install the selection pointer gestures (those live inTextSelectionGestureDetectorBuilder, whichTextField/CupertinoTextFielduse to wrap it). On web, mouse drag-select did nothing and only keyboard select-all (Ctrl/Cmd+A) worked.This wires the framework's canonical Material-free selectable-input recipe:
_WInputStateimplementsTextSelectionGestureDetectorBuilderDelegate(singleGlobalKey<EditableTextState>).TextSelectionGestureDetectorBuilder.buildGestureDetector, andEditableText.rendererIgnoresPointeristrueso the gesture layer is the sole pointer handler.GestureDetectoris removed;onTapis forwarded viaonUserTap.Selection handles: cupertino-only (no material.dart import)
WInputwirescupertinoTextSelectionHandleControlson every platform, unchanged from the 1.1.0 shipped behavior. This keeps the widget cupertino-only with nopackage:flutter/material.dartimport, preserving the deliberate import-free state established in #106 (WInput is the only widget file that importscupertino.dartand notmaterial.dart).cupertinoTextSelectionHandleControlsmixes inTextSelectionHandleControls, so the toolbar stays on the Material-freecontextMenuBuilderpath and noOverlay-less long-press throws. The Material-free guarantee (no Material ancestor required at runtime) holds;WFormInput/WSelect/WDynamicinherit the fix unchanged.(An earlier revision of this branch made handles platform-adaptive via the Material
*HandleControlsconstants, which re-introduced thematerial.dartimport. That was reverted to honor #106's cupertino-only intent; platform-adaptive handles can be revisited later via a widgets-only customTextSelectionControlsif desired.)Behavior change
onTapnow dispatches through the native gesture builder instead of a hand-builtGestureDetector. It continues to fire when the user taps the field; the change is the gesture mechanism (which also brings drag-select and double-tap word selection), not a newonTapcontract.Test plan
test/widgets/w_input/selection_test.dart: mouse drag-select (non-collapsed selection), double-tap word, whole-box tap focus +onTap, disabled inert, read-only selectable, no-Overlayno-crash, and a Cupertino-handle assertion across everyTargetPlatformunder a bare Material-free Overlay harness.dart analyze: clean (nomaterial.dartimport).dart format: no diff.flutter test: 1443 pass (1 pre-existing skip). Coverage: 91.2% (gate 90%).flutter build web --release: succeeds.Post-change sync
Closes the WInput selection regression from #106.