[pointer_interceptor] Allow conditional pointer interception (#538)
diff --git a/packages/pointer_interceptor/CHANGELOG.md b/packages/pointer_interceptor/CHANGELOG.md
index da40c20..52f4af7 100644
--- a/packages/pointer_interceptor/CHANGELOG.md
+++ b/packages/pointer_interceptor/CHANGELOG.md
@@ -1,7 +1,8 @@
-## NEXT
+## 0.9.1
* Removed `android` and `ios` directories from `example`, as the example doesn't
build for those platforms.
+* Added `intercepting` field to allow for conditional pointer interception
## 0.9.0+1
diff --git a/packages/pointer_interceptor/README.md b/packages/pointer_interceptor/README.md
index bcd3b06..d51c2bc 100644
--- a/packages/pointer_interceptor/README.md
+++ b/packages/pointer_interceptor/README.md
@@ -64,6 +64,38 @@
)
```
+### `intercepting`
+
+A common use of the `PointerInterceptor` widget is to block clicks only under
+certain conditions (`isVideoShowing`, `isPanelOpen`...).
+
+The `intercepting` property allows the `PointerInterceptor` widget to render
+itself (or not) depending on a boolean value, instead of having to manually
+write an `if/else` on the Flutter App widget tree, so code like this:
+
+ ```dart
+ if (someCondition) {
+ return PointerInterceptor(
+ child: ElevatedButton(...),
+ )
+ } else {
+ return ElevatedButton(...),
+ }
+ ```
+
+can be rewritten as:
+
+ ```dart
+ return PointerInterceptor(
+ intercepting: someCondition,
+ child: ElevatedButton(...),
+ )
+ ```
+
+Note: when `intercepting` is false, the `PointerInterceptor` will not render
+_anything_ in flutter, and just return its `child`. The code is exactly
+equivalent to the example above.
+
### `debug`
The `PointerInterceptor` widget has a `debug` property, that will render it visibly on the screen (similar to the images above).
diff --git a/packages/pointer_interceptor/example/integration_test/widget_test.dart b/packages/pointer_interceptor/example/integration_test/widget_test.dart
index f996898..c1c054a 100644
--- a/packages/pointer_interceptor/example/integration_test/widget_test.dart
+++ b/packages/pointer_interceptor/example/integration_test/widget_test.dart
@@ -17,6 +17,8 @@
group('Widget', () {
final Finder nonClickableButtonFinder =
find.byKey(const Key('transparent-button'));
+ final Finder clickableWrappedButtonFinder =
+ find.byKey(const Key('wrapped-transparent-button'));
final Finder clickableButtonFinder =
find.byKey(const Key('clickable-button'));
@@ -42,6 +44,27 @@
});
testWidgets(
+ 'on wrapped elements with intercepting set to false, the browser hits the background-html-view',
+ (WidgetTester tester) async {
+ app.main();
+ await tester.pumpAndSettle();
+
+ final html.Element? element =
+ _getHtmlElementFromFinder(clickableWrappedButtonFinder, tester);
+
+ if (html.document.querySelector('flt-glass-pane')?.shadowRoot != null) {
+ // In flutter master...
+ expect(element?.id, 'background-html-view');
+ } else {
+ // In previous versions (--web-renderer=html only)...
+ expect(element?.tagName.toLowerCase(), 'flt-platform-view');
+ final html.Element? platformViewRoot =
+ element?.shadowRoot?.getElementById('background-html-view');
+ expect(platformViewRoot, isNotNull);
+ }
+ });
+
+ testWidgets(
'on unwrapped elements, the browser hits the background-html-view',
(WidgetTester tester) async {
app.main();
diff --git a/packages/pointer_interceptor/example/lib/main.dart b/packages/pointer_interceptor/example/lib/main.dart
index 0064889..234d31d 100644
--- a/packages/pointer_interceptor/example/lib/main.dart
+++ b/packages/pointer_interceptor/example/lib/main.dart
@@ -131,6 +131,16 @@
},
),
PointerInterceptor(
+ intercepting: false,
+ child: ElevatedButton(
+ key: const Key('wrapped-transparent-button'),
+ child: const Text('Never calls onPressed'),
+ onPressed: () {
+ _clickedOn('wrapped-transparent-button');
+ },
+ ),
+ ),
+ PointerInterceptor(
child: ElevatedButton(
key: const Key('clickable-button'),
child: const Text('Works As Expected'),
diff --git a/packages/pointer_interceptor/lib/src/mobile.dart b/packages/pointer_interceptor/lib/src/mobile.dart
index 1e2c9e3..dab6b86 100644
--- a/packages/pointer_interceptor/lib/src/mobile.dart
+++ b/packages/pointer_interceptor/lib/src/mobile.dart
@@ -9,6 +9,7 @@
/// Create a `PointerInterceptor` wrapping a `child`.
const PointerInterceptor({
required this.child,
+ this.intercepting = true,
this.debug = false,
Key? key,
}) : super(key: key);
@@ -16,6 +17,9 @@
/// The `Widget` that is being wrapped by this `PointerInterceptor`.
final Widget child;
+ /// Whether or not this `PointerInterceptor` should intercept pointer events.
+ final bool intercepting;
+
/// When true, the widget renders with a semi-transparent red background, for debug purposes.
///
/// This is useful when rendering this as a "layout" widget, like the root child
diff --git a/packages/pointer_interceptor/lib/src/web.dart b/packages/pointer_interceptor/lib/src/web.dart
index ad38e9f..17c8384 100644
--- a/packages/pointer_interceptor/lib/src/web.dart
+++ b/packages/pointer_interceptor/lib/src/web.dart
@@ -38,6 +38,7 @@
/// Creates a PointerInterceptor for the web.
PointerInterceptor({
required this.child,
+ this.intercepting = true,
this.debug = false,
Key? key,
}) : super(key: key) {
@@ -49,6 +50,9 @@
/// The `Widget` that is being wrapped by this `PointerInterceptor`.
final Widget child;
+ /// Whether or not this `PointerInterceptor` should intercept pointer events.
+ final bool intercepting;
+
/// When true, the widget renders with a semi-transparent red background, for debug purposes.
///
/// This is useful when rendering this as a "layout" widget, like the root child
@@ -70,6 +74,10 @@
@override
Widget build(BuildContext context) {
+ if (!intercepting) {
+ return child;
+ }
+
final String viewType = _getViewType(debug: debug);
return Stack(
alignment: Alignment.center,
diff --git a/packages/pointer_interceptor/pubspec.yaml b/packages/pointer_interceptor/pubspec.yaml
index dcbd35b..98292a2 100644
--- a/packages/pointer_interceptor/pubspec.yaml
+++ b/packages/pointer_interceptor/pubspec.yaml
@@ -2,7 +2,7 @@
description: A widget to prevent clicks from being swallowed by underlying HtmlElementViews on the web.
repository: https://github.com/flutter/packages/tree/main/packages/pointer_interceptor
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+pointer_interceptor%22
-version: 0.9.0+1
+version: 0.9.1
environment:
sdk: ">=2.12.0 <3.0.0"