From ac02a7b0ed5a07db98b6cddd4e86e6d7b12456a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Meneses=20Leo=CC=81n?= Date: Mon, 24 Aug 2026 23:01:51 -0600 Subject: [PATCH 1/3] [pointer_interceptor] Adopt code-excerpts for README Replaces the hand-written Dart snippets in the README with pragmas backed by example/lib/readme_excerpts.dart, so they're validated against compilable, analyzed source instead of being free-hand text (one of them had a stray trailing comma that made it invalid Dart). Also drops the package's ci_config.yaml, whose only purpose was opting it out of that validation. Part of https://github.com/flutter/flutter/issues/102679. FPOCTSMP-9 --- .../pointer_interceptor/CHANGELOG.md | 2 + .../pointer_interceptor/README.md | 63 ++++++++++--------- .../pointer_interceptor/ci_config.yaml | 2 - .../example/lib/readme_excerpts.dart | 52 +++++++++++++++ 4 files changed, 86 insertions(+), 33 deletions(-) delete mode 100644 packages/pointer_interceptor/pointer_interceptor/ci_config.yaml create mode 100644 packages/pointer_interceptor/pointer_interceptor/example/lib/readme_excerpts.dart diff --git a/packages/pointer_interceptor/pointer_interceptor/CHANGELOG.md b/packages/pointer_interceptor/pointer_interceptor/CHANGELOG.md index d7aa50de475b..116344edf11f 100644 --- a/packages/pointer_interceptor/pointer_interceptor/CHANGELOG.md +++ b/packages/pointer_interceptor/pointer_interceptor/CHANGELOG.md @@ -5,6 +5,8 @@ versions of the endorsed platform implementations. * Applications built with older versions of Flutter will continue to use compatible versions of the platform implementations. +* Adopts `code-excerpt` for the README's Dart snippets so they are validated + against compilable, analyzed source. ## 0.10.1+2 diff --git a/packages/pointer_interceptor/pointer_interceptor/README.md b/packages/pointer_interceptor/pointer_interceptor/README.md index 2e5c3bfcc09f..a92a85cc6540 100644 --- a/packages/pointer_interceptor/pointer_interceptor/README.md +++ b/packages/pointer_interceptor/pointer_interceptor/README.md @@ -1,4 +1,5 @@ # pointer_interceptor + | | iOS | Web | |-------------|---------|-----| @@ -47,25 +48,23 @@ There's two ways that the `PointerInterceptor` widget can be used to solve the p 1. Wrapping your button element directly (FAB, Custom Play/Pause button...): - ```dart - PointerInterceptor( - child: ElevatedButton(...), - ) - ``` + +```dart +return PointerInterceptor( + child: ElevatedButton(onPressed: () {}, child: const Text('Button')), +); +``` 2. As a root container for a "layout" element, wrapping a bunch of other elements (like a Drawer): - ```dart - Scaffold( - ... - drawer: PointerInterceptor( - child: Drawer( - child: ... - ), - ), - ... - ) - ``` + +```dart +return Scaffold( + drawer: PointerInterceptor( + child: Drawer(child: ListView(children: const [Text('Drawer contents')])), + ), +); +``` ### `intercepting` @@ -76,24 +75,26 @@ 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(...), - } - ``` + +```dart +if (someCondition) { + return PointerInterceptor( + child: ElevatedButton(onPressed: () {}, child: const Text('Button')), + ); +} else { + return ElevatedButton(onPressed: () {}, child: const Text('Button')); +} +``` can be rewritten as: - ```dart - return PointerInterceptor( - intercepting: someCondition, - child: ElevatedButton(...), - ) - ``` + +```dart +return PointerInterceptor( + intercepting: someCondition, + child: ElevatedButton(onPressed: () {}, child: const Text('Button')), +); +``` Note: when `intercepting` is false, the `PointerInterceptor` will not render _anything_ in flutter, and just return its `child`. The code is exactly diff --git a/packages/pointer_interceptor/pointer_interceptor/ci_config.yaml b/packages/pointer_interceptor/pointer_interceptor/ci_config.yaml deleted file mode 100644 index b352e13e0dfa..000000000000 --- a/packages/pointer_interceptor/pointer_interceptor/ci_config.yaml +++ /dev/null @@ -1,2 +0,0 @@ -# TODO(stuartmorgan): Remove this; see https://github.com/flutter/flutter/issues/102679 -exempt_from_excerpts: true diff --git a/packages/pointer_interceptor/pointer_interceptor/example/lib/readme_excerpts.dart b/packages/pointer_interceptor/pointer_interceptor/example/lib/readme_excerpts.dart new file mode 100644 index 000000000000..67e509647b38 --- /dev/null +++ b/packages/pointer_interceptor/pointer_interceptor/example/lib/readme_excerpts.dart @@ -0,0 +1,52 @@ +// Copyright 2013 The Flutter Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter/material.dart'; +import 'package:pointer_interceptor/pointer_interceptor.dart'; + +/// Wraps a single button so that it can be clicked, even when it's on top of +/// a platform view. +Widget wrapButtonSnippet() { + // #docregion WrapButton + return PointerInterceptor( + child: ElevatedButton(onPressed: () {}, child: const Text('Button')), + ); + // #enddocregion WrapButton +} + +/// Wraps a whole subtree (a [Drawer], in this case) so that it can be +/// clicked, even when it's on top of a platform view. +Widget wrapSubtreeSnippet() { + // #docregion WrapSubtree + return Scaffold( + drawer: PointerInterceptor( + child: Drawer(child: ListView(children: const [Text('Drawer contents')])), + ), + ); + // #enddocregion WrapSubtree +} + +/// The naive way of conditionally intercepting pointer events, which +/// `intercepting` is meant to replace. +Widget interceptingBeforeSnippet(bool someCondition) { + // #docregion InterceptingBefore + if (someCondition) { + return PointerInterceptor( + child: ElevatedButton(onPressed: () {}, child: const Text('Button')), + ); + } else { + return ElevatedButton(onPressed: () {}, child: const Text('Button')); + } + // #enddocregion InterceptingBefore +} + +/// The equivalent of [interceptingBeforeSnippet], using `intercepting`. +Widget interceptingAfterSnippet(bool someCondition) { + // #docregion InterceptingAfter + return PointerInterceptor( + intercepting: someCondition, + child: ElevatedButton(onPressed: () {}, child: const Text('Button')), + ); + // #enddocregion InterceptingAfter +} From 44956cf777d67146ead9ef6a1273fdc407682506 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Meneses=20Leo=CC=81n?= Date: Tue, 25 Aug 2026 11:33:15 -0600 Subject: [PATCH 2/3] [pointer_interceptor] Bump to 0.10.1+3 for the code-excerpts README change Converts the NEXT section into a real release since the README change needs to be published, and bumps pubspec.yaml to match. --- .../pointer_interceptor/pointer_interceptor/CHANGELOG.md | 6 +++--- .../pointer_interceptor/pointer_interceptor/pubspec.yaml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/pointer_interceptor/pointer_interceptor/CHANGELOG.md b/packages/pointer_interceptor/pointer_interceptor/CHANGELOG.md index 116344edf11f..401bd88ecd84 100644 --- a/packages/pointer_interceptor/pointer_interceptor/CHANGELOG.md +++ b/packages/pointer_interceptor/pointer_interceptor/CHANGELOG.md @@ -1,12 +1,12 @@ -## NEXT +## 0.10.1+3 +* Adopts `code-excerpt` for the README's Dart snippets so they are validated + against compilable, analyzed source. * Updates minimum supported SDK version to Flutter 3.38/Dart 3.10. * Updates README to reflect currently supported OS versions for the latest versions of the endorsed platform implementations. * Applications built with older versions of Flutter will continue to use compatible versions of the platform implementations. -* Adopts `code-excerpt` for the README's Dart snippets so they are validated - against compilable, analyzed source. ## 0.10.1+2 diff --git a/packages/pointer_interceptor/pointer_interceptor/pubspec.yaml b/packages/pointer_interceptor/pointer_interceptor/pubspec.yaml index 259101e6f7e1..5a0495132567 100644 --- a/packages/pointer_interceptor/pointer_interceptor/pubspec.yaml +++ b/packages/pointer_interceptor/pointer_interceptor/pubspec.yaml @@ -2,7 +2,7 @@ name: pointer_interceptor 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/pointer_interceptor issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+pointer_interceptor%22 -version: 0.10.1+2 +version: 0.10.1+3 environment: sdk: ^3.10.0 From caabfc3ffb547f10ca22cbed3603692afb180efd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Meneses=20Leo=CC=81n?= Date: Wed, 9 Sep 2026 07:35:38 -0600 Subject: [PATCH 3/3] [pointer_interceptor] Address review: trim excerpt noise, add tests Per review feedback on the README code-excerpts PR: - Trims the WrapButton/WrapSubtree/InterceptingAfter excerpts back down to look like the original hand-written examples, by reopening each docregion around the ElevatedButton/Drawer arguments (eliding them to "// ..." like local_auth's README already does) and moving the enclosing `return`/`;` outside the extracted region. InterceptingBefore keeps its `return`s, since the if/else structure is the point of that example, but gets the same argument elision. - Adds example/test/readme_excerpts_test.dart, which actually pumps each snippet through a widget tree and asserts on the result, so the excerpts are verified to run correctly, not just compile. --- .../pointer_interceptor/README.md | 32 ++++++---- .../example/lib/readme_excerpts.dart | 52 +++++++++++++---- .../example/test/readme_excerpts_test.dart | 58 +++++++++++++++++++ 3 files changed, 120 insertions(+), 22 deletions(-) create mode 100644 packages/pointer_interceptor/pointer_interceptor/example/test/readme_excerpts_test.dart diff --git a/packages/pointer_interceptor/pointer_interceptor/README.md b/packages/pointer_interceptor/pointer_interceptor/README.md index a92a85cc6540..bb7394a5d803 100644 --- a/packages/pointer_interceptor/pointer_interceptor/README.md +++ b/packages/pointer_interceptor/pointer_interceptor/README.md @@ -50,20 +50,24 @@ There's two ways that the `PointerInterceptor` widget can be used to solve the p ```dart -return PointerInterceptor( - child: ElevatedButton(onPressed: () {}, child: const Text('Button')), -); +PointerInterceptor( + child: ElevatedButton( + // ··· + ), +) ``` 2. As a root container for a "layout" element, wrapping a bunch of other elements (like a Drawer): ```dart -return Scaffold( +Scaffold( drawer: PointerInterceptor( - child: Drawer(child: ListView(children: const [Text('Drawer contents')])), + child: Drawer( + // ··· + ), ), -); +) ``` ### `intercepting` @@ -79,10 +83,14 @@ write an `if/else` on the Flutter App widget tree, so code like this: ```dart if (someCondition) { return PointerInterceptor( - child: ElevatedButton(onPressed: () {}, child: const Text('Button')), + child: ElevatedButton( + // ··· + ), ); } else { - return ElevatedButton(onPressed: () {}, child: const Text('Button')); + return ElevatedButton( + // ··· + ); } ``` @@ -90,10 +98,12 @@ can be rewritten as: ```dart -return PointerInterceptor( +PointerInterceptor( intercepting: someCondition, - child: ElevatedButton(onPressed: () {}, child: const Text('Button')), -); + child: ElevatedButton( + // ··· + ), +) ``` Note: when `intercepting` is false, the `PointerInterceptor` will not render diff --git a/packages/pointer_interceptor/pointer_interceptor/example/lib/readme_excerpts.dart b/packages/pointer_interceptor/pointer_interceptor/example/lib/readme_excerpts.dart index 67e509647b38..3c400e94421f 100644 --- a/packages/pointer_interceptor/pointer_interceptor/example/lib/readme_excerpts.dart +++ b/packages/pointer_interceptor/pointer_interceptor/example/lib/readme_excerpts.dart @@ -8,23 +8,36 @@ import 'package:pointer_interceptor/pointer_interceptor.dart'; /// Wraps a single button so that it can be clicked, even when it's on top of /// a platform view. Widget wrapButtonSnippet() { + return // #docregion WrapButton - return PointerInterceptor( - child: ElevatedButton(onPressed: () {}, child: const Text('Button')), - ); + PointerInterceptor( + child: ElevatedButton( + // #enddocregion WrapButton + onPressed: () {}, + child: const Text('Button'), + // #docregion WrapButton + ), + ) // #enddocregion WrapButton + ; } /// Wraps a whole subtree (a [Drawer], in this case) so that it can be /// clicked, even when it's on top of a platform view. Widget wrapSubtreeSnippet() { + return // #docregion WrapSubtree - return Scaffold( + Scaffold( drawer: PointerInterceptor( - child: Drawer(child: ListView(children: const [Text('Drawer contents')])), + child: Drawer( + // #enddocregion WrapSubtree + child: ListView(children: const [Text('Drawer contents')]), + // #docregion WrapSubtree + ), ), - ); + ) // #enddocregion WrapSubtree + ; } /// The naive way of conditionally intercepting pointer events, which @@ -33,20 +46,37 @@ Widget interceptingBeforeSnippet(bool someCondition) { // #docregion InterceptingBefore if (someCondition) { return PointerInterceptor( - child: ElevatedButton(onPressed: () {}, child: const Text('Button')), + child: ElevatedButton( + // #enddocregion InterceptingBefore + onPressed: () {}, + child: const Text('Button'), + // #docregion InterceptingBefore + ), ); } else { - return ElevatedButton(onPressed: () {}, child: const Text('Button')); + return ElevatedButton( + // #enddocregion InterceptingBefore + onPressed: () {}, + child: const Text('Button'), + // #docregion InterceptingBefore + ); } // #enddocregion InterceptingBefore } /// The equivalent of [interceptingBeforeSnippet], using `intercepting`. Widget interceptingAfterSnippet(bool someCondition) { + return // #docregion InterceptingAfter - return PointerInterceptor( + PointerInterceptor( intercepting: someCondition, - child: ElevatedButton(onPressed: () {}, child: const Text('Button')), - ); + child: ElevatedButton( + // #enddocregion InterceptingAfter + onPressed: () {}, + child: const Text('Button'), + // #docregion InterceptingAfter + ), + ) // #enddocregion InterceptingAfter + ; } diff --git a/packages/pointer_interceptor/pointer_interceptor/example/test/readme_excerpts_test.dart b/packages/pointer_interceptor/pointer_interceptor/example/test/readme_excerpts_test.dart new file mode 100644 index 000000000000..7306e58e2b27 --- /dev/null +++ b/packages/pointer_interceptor/pointer_interceptor/example/test/readme_excerpts_test.dart @@ -0,0 +1,58 @@ +// Copyright 2013 The Flutter Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:pointer_interceptor/pointer_interceptor.dart'; +import 'package:pointer_interceptor_example/readme_excerpts.dart'; + +void main() { + testWidgets('wrapButtonSnippet wraps a button in a PointerInterceptor', ( + WidgetTester tester, + ) async { + await tester.pumpWidget(MaterialApp(home: wrapButtonSnippet())); + + expect(find.byType(PointerInterceptor), findsOneWidget); + expect(find.widgetWithText(ElevatedButton, 'Button'), findsOneWidget); + }); + + testWidgets('wrapSubtreeSnippet wraps a Drawer in a PointerInterceptor', ( + WidgetTester tester, + ) async { + await tester.pumpWidget(MaterialApp(home: wrapSubtreeSnippet())); + tester.state(find.byType(Scaffold)).openDrawer(); + await tester.pumpAndSettle(); + + expect(find.byType(PointerInterceptor), findsOneWidget); + expect(find.widgetWithText(Drawer, 'Drawer contents'), findsOneWidget); + }); + + testWidgets('interceptingBeforeSnippet returns a PointerInterceptor when true', ( + WidgetTester tester, + ) async { + await tester.pumpWidget(MaterialApp(home: interceptingBeforeSnippet(true))); + + expect(find.byType(PointerInterceptor), findsOneWidget); + expect(find.widgetWithText(ElevatedButton, 'Button'), findsOneWidget); + }); + + testWidgets('interceptingBeforeSnippet returns a plain button when false', ( + WidgetTester tester, + ) async { + await tester.pumpWidget(MaterialApp(home: interceptingBeforeSnippet(false))); + + expect(find.byType(PointerInterceptor), findsNothing); + expect(find.widgetWithText(ElevatedButton, 'Button'), findsOneWidget); + }); + + testWidgets('interceptingAfterSnippet sets intercepting from its argument', ( + WidgetTester tester, + ) async { + await tester.pumpWidget(MaterialApp(home: interceptingAfterSnippet(true))); + + final PointerInterceptor interceptor = tester.widget(find.byType(PointerInterceptor)); + expect(interceptor.intercepting, isTrue); + expect(find.widgetWithText(ElevatedButton, 'Button'), findsOneWidget); + }); +}