1. 20 Sep, 2023 1 commit
  2. 18 Sep, 2023 2 commits
  3. 14 Sep, 2023 1 commit
  4. 11 Sep, 2023 1 commit
  5. 08 Sep, 2023 1 commit
  6. 01 Sep, 2023 1 commit
    • Andrea Cioni's avatar
      Add an example for `InputChip` generated by user input (#130645) · 400702d1
      Andrea Cioni authored
      New example for `InputChip` that demonstrate how to create/delete them based on user text inputs.
      
      The sample application shows a custom text area where user can enter text. After the user has typed and hits _Enter_ the text will be replaced with an `InputChip` that contains that text. Is it possible to continue typing and add more chips in this way. All of them will be placed in a scrollable horizontal row. Also is it possible to have suggestion displayed below the text input field in case the typed text match some of the available suggestions.
      
      Issue I'm trying to solve:
      
      - https://github.com/flutter/flutter/issues/128247
      
      **Code structure:**
      
      The example app is composed of 2 main components that find places inside `MainScreen`:
      
       - `ChipsInput`
       - `ListView`
      
      `ChipsInput` emulates a `TextField` where you can enter text. This text field accepts also a list of values of generic type T (`Topping` in my example), that gets rendered as `InputChip` inside the text field, before the text inserted by the user. This widgets is basically an `InputDecorator` widget that implements `TextInputClient` to get `TextEditingValue` events from the user keyboard. At the end of the input field there is another component, the `TextCursor`, that is displayed just when the user give the focus to the field and emulates the carrets that `TextField` has.
      
      There are also some available callbacks that the user can use to capture events in the `ChipsInput` field like: `onChanged`, `onChipTapped`, `onSubmitted` and `onTextChanged`. This last callback is used to build a list of suggestion that will be placed just below the `ChipsInput` field inside the `ListView`.
      Unverified
      400702d1
  7. 31 Aug, 2023 1 commit
  8. 30 Aug, 2023 1 commit
  9. 29 Aug, 2023 2 commits
  10. 25 Aug, 2023 2 commits
  11. 21 Aug, 2023 1 commit
  12. 17 Aug, 2023 1 commit
  13. 15 Aug, 2023 1 commit
    • Ian Hickson's avatar
      PaginatedDataTable improvements (#131374) · ccdf8264
      Ian Hickson authored
      - slightly improved assert message when row cell counts don't match column count.
      - more breadcrumbs in API documentation. more documentation in general.
      - added more documentation for the direction of the "ascending" arrow.
      - two samples for PaginatedDataTable.
      - make PaginatedDataTable support hot reloading across changes to the number of columns.
      - introduce matrix3MoreOrLessEquals. An earlier version of this PR used it in tests, but eventually it was not needed. The function seems useful to keep though.
      Unverified
      ccdf8264
  14. 14 Aug, 2023 1 commit
  15. 10 Aug, 2023 2 commits
  16. 09 Aug, 2023 2 commits
  17. 08 Aug, 2023 1 commit
  18. 04 Aug, 2023 1 commit
    • Justin McCandless's avatar
      Predictive back support for root routes (#120385) · dedd100e
      Justin McCandless authored
      This PR aims to support Android's predictive back gesture when popping the entire Flutter app.  Predictive route transitions between routes inside of a Flutter app will come later.
      
      <img width="200" src="https://user-images.githubusercontent.com/389558/217918109-945febaa-9086-41cc-a476-1a189c7831d8.gif" />
      
      ### Trying it out
      
      If you want to try this feature yourself, here are the necessary steps:
      
        1. Run Android 33 or above.
        1. Enable the feature flag for predictive back on the device under "Developer
           options".
        1. Create a Flutter project, or clone [my example project](https://github.com/justinmc/flutter_predictive_back_examples).
        1. Set `android:enableOnBackInvokedCallback="true"` in
           android/app/src/main/AndroidManifest.xml (already done in the example project).
        1. Check out this branch.
        1. Run the app. Perform a back gesture (swipe from the left side of the
           screen).
      
      You should see the predictive back animation like in the animation above and be able to commit or cancel it.
      
      ### go_router support
      
      go_router works with predictive back out of the box because it uses a Navigator internally that dispatches NavigationNotifications!
      
      ~~go_router can be supported by adding a listener to the router and updating SystemNavigator.setFrameworkHandlesBack.~~
      
      Similar to with nested Navigators, nested go_routers is supported by using a PopScope widget.
      
      <details>
      
      <summary>Full example of nested go_routers</summary>
      
      ```dart
      // Copyright 2014 The Flutter Authors. All rights reserved.
      // Use of this source code is governed by a BSD-style license that can be
      // found in the LICENSE file.
      
      import 'package:go_router/go_router.dart';
      
      import 'package:flutter/material.dart';
      import 'package:flutter/scheduler.dart';
      
      void main() => runApp(_MyApp());
      
      class _MyApp extends StatelessWidget {
        final GoRouter router = GoRouter(
          routes: <RouteBase>[
            GoRoute(
              path: '/',
              builder: (BuildContext context, GoRouterState state) => _HomePage(),
            ),
            GoRoute(
              path: '/nested_navigators',
              builder: (BuildContext context, GoRouterState state) => _NestedGoRoutersPage(),
            ),
          ],
        );
      
        @override
        Widget build(BuildContext context) {
          return MaterialApp.router(
            routerConfig: router,
          );
        }
      }
      
      class _HomePage extends StatelessWidget {
        @override
        Widget build(BuildContext context) {
          return Scaffold(
            appBar: AppBar(
              title: const Text('Nested Navigators Example'),
            ),
            body: Center(
              child: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: <Widget>[
                  const Text('Home Page'),
                  const Text('A system back gesture here will exit the app.'),
                  const SizedBox(height: 20.0),
                  ListTile(
                    title: const Text('Nested go_router route'),
                    subtitle: const Text('This route has another go_router in addition to the one used with MaterialApp above.'),
                    onTap: () {
                      context.push('/nested_navigators');
                    },
                  ),
                ],
              ),
            ),
          );
        }
      }
      
      class _NestedGoRoutersPage extends StatefulWidget {
        @override
        State<_NestedGoRoutersPage> createState() => _NestedGoRoutersPageState();
      }
      
      class _NestedGoRoutersPageState extends State<_NestedGoRoutersPage> {
        late final GoRouter _router;
        final GlobalKey<NavigatorState> _nestedNavigatorKey = GlobalKey<NavigatorState>();
      
        // If the nested navigator has routes that can be popped, then we want to
        // block the root navigator from handling the pop so that the nested navigator
        // can handle it instead.
        bool get _popEnabled {
          // canPop will throw an error if called before build. Is this the best way
          // to avoid that?
          return _nestedNavigatorKey.currentState == null ? true : !_router.canPop();
        }
      
        void _onRouterChanged() {
          // Here the _router reports the location correctly, but canPop is still out
          // of date.  Hence the post frame callback.
          SchedulerBinding.instance.addPostFrameCallback((Duration duration) {
            setState(() {});
          });
        }
      
        @override
        void initState() {
          super.initState();
      
          final BuildContext rootContext = context;
          _router = GoRouter(
            navigatorKey: _nestedNavigatorKey,
            routes: [
              GoRoute(
                path: '/',
                builder: (BuildContext context, GoRouterState state) => _LinksPage(
                  title: 'Nested once - home route',
                  backgroundColor: Colors.indigo,
                  onBack: () {
                    rootContext.pop();
                  },
                  buttons: <Widget>[
                    TextButton(
                      onPressed: () {
                        context.push('/two');
                      },
                      child: const Text('Go to another route in this nested Navigator'),
                    ),
                  ],
                ),
              ),
              GoRoute(
                path: '/two',
                builder: (BuildContext context, GoRouterState state) => _LinksPage(
                  backgroundColor: Colors.indigo.withBlue(255),
                  title: 'Nested once - page two',
                ),
              ),
            ],
          );
      
          _router.addListener(_onRouterChanged);
        }
      
        @override
        void dispose() {
          _router.removeListener(_onRouterChanged);
          super.dispose();
        }
      
        @override
        Widget build(BuildContext context) {
          return PopScope(
            popEnabled: _popEnabled,
            onPopped: (bool success) {
              if (success) {
                return;
              }
              _router.pop();
            },
            child: Router<Object>.withConfig(
              restorationScopeId: 'router-2',
              config: _router,
            ),
          );
        }
      }
      
      class _LinksPage extends StatelessWidget {
        const _LinksPage ({
          required this.backgroundColor,
          this.buttons = const <Widget>[],
          this.onBack,
          required this.title,
        });
      
        final Color backgroundColor;
        final List<Widget> buttons;
        final VoidCallback? onBack;
        final String title;
      
        @override
        Widget build(BuildContext context) {
          return Scaffold(
            backgroundColor: backgroundColor,
            body: Center(
              child: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: <Widget>[
                  Text(title),
                  //const Text('A system back here will go back to Nested Navigators Page One'),
                  ...buttons,
                  TextButton(
                    onPressed: onBack ?? () {
                      context.pop();
                    },
                    child: const Text('Go back'),
                  ),
                ],
              ),
            ),
          );
        }
      }
      ```
      
      </details>
      
      ### Resources
      
      Fixes https://github.com/flutter/flutter/issues/109513
      Depends on engine PR https://github.com/flutter/engine/pull/39208 :heavy_check_mark: 
      Design doc: https://docs.google.com/document/d/1BGCWy1_LRrXEB6qeqTAKlk-U2CZlKJ5xI97g45U7azk/edit#
      Migration guide: https://github.com/flutter/website/pull/8952
      Unverified
      dedd100e
  19. 20 Jul, 2023 1 commit
  20. 17 Jul, 2023 3 commits
  21. 12 Jul, 2023 1 commit
  22. 11 Jul, 2023 2 commits
  23. 29 Jun, 2023 1 commit
  24. 28 Jun, 2023 1 commit
  25. 26 Jun, 2023 1 commit
  26. 21 Jun, 2023 1 commit
    • Renzo Olivares's avatar
      Selection area right click behavior should match native (#128224) · b36ef583
      Renzo Olivares authored
      This change updates `SelectableRegion`s right-click gesture to match native platform behavior.
      
      Before: Right-click gesture selects word at position and opens context menu (All Platforms)
      After: 
      - Linux, toggles context menu on/off, and collapses selection when click was not on an active selection (uncollapsed).
      - Windows, Android, Fuchsia, shows context menu at right-clicked position (unless the click is at an active selection).
      - macOS, toggles the context menu if right click was at the same position as the previous / or selects word at position and opens context menu.
      - iOS, selects word at position and opens context menu.
      
      This change also prevents the `copy` menu button from being shown when there is a collapsed selection (nothing to copy).
      
      Fixes #117561
      Unverified
      b36ef583
  27. 20 Jun, 2023 1 commit
    • Tae Hyung Kim's avatar
      DecoratedSliver (#127823) · 541fdd60
      Tae Hyung Kim authored
      This is a second attempt to merge #107269. Currently I've fixed two of the issues:
      1. Fixed horizontal scrollview by using a switch statement to consider vertical/horizontal case.
      2. Fixed issue of `paintExtent` not being the right extent for painting. Rather using a `scrollExtent` for the main axis length of the decoration box and painting it offsetted by the `scrollOffset`.
      3. If the sliver child has inifinite scrollExtent, then we only draw the decoration down to the bottom of the `cacheExtent`. The developer is expected to ensure that the border does not creep up above the cache area.
      
      This PR includes a test that checks that the correct rectangle is drawn at a certain scrollOffset for both the horizontal and vertical case which should be sufficient for checking that `SliverDecoration` works properly now.
      
      Fixes https://github.com/flutter/flutter/issues/107498.
      Unverified
      541fdd60
  28. 15 Jun, 2023 1 commit
  29. 13 Jun, 2023 1 commit
  30. 08 Jun, 2023 2 commits
  31. 07 Jun, 2023 1 commit
    • Greg Spencer's avatar
      Disable context menu (#128365) · 36f73cf6
      Greg Spencer authored
      ## Description
      
      Changes the context menu example for `MenuAnchor` so that it uses right-click, or (on macOS and iOS only) ctrl-left-click, for the context menu. Also disables the browser context menu on web platforms.
      
      ## Tests
       - Updated test to reflect new triggers.
      Unverified
      36f73cf6