1. 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`.
      400702d1
  2. 17 Jul, 2023 1 commit
    • LongCatIsLooong's avatar
      Replaces `textScaleFactor` with `TextScaler` (#128522) · b2e22d35
      LongCatIsLooong authored
      Deprecate `textScaleFactor` in favor of `textScaler`, in preparation for Android 14 [Non-linear font scaling to 200%](https://developer.android.com/about/versions/14/features#non-linear-font-scaling). The `TextScaler` class can be moved to `dart:ui` in the future, if we decide to use the Android platform API or AndroidX to get the scaling curve instead of hard coding the curve in the framework.
      
      I haven't put the Flutter version in the deprecation message so the analyzer checks are failing. Will do so after I finish the migration guide.
      
      **Why `TextScaler.textScaleFactor`**
      The author of a `TextScaler` subclass should provide a fallback `textScaleFactor`. By making `TextScaler` also contain the `textScaleFactor` information it also makes it easier to migrate: if a widget overrides `MediaQueryData.textScaler` in the tree, for unmigrated widgets in the subtree it would also have to override `MediaQueryData.textScaleFactor`, and that makes it difficult to remove `MediaQueryData.textScaleFactor` in the future.
      
      ## A full list of affected APIs in this PR
      
      Deprecated: The method/getter/setter/argument is annotated with a `@Deprecated()` annotation in this PR, and the caller should replace it with `textScaler` instead. Unless otherwise specified there will be a Flutter fix available to help with migration but it's still recommended to migrate case-by-case.
      **Replaced**:  The method this `textScaleFactor` argument belongs to is rarely called directly by user code and is not overridden by any of the registered custom tests, so the argument is directly replaced by `TextScaler`.
      **To Be Deprecated**:  The method/getter/setter/argument can't be deprecated in this PR because a registered customer test depends on it and a Flutter fix isn't available (or the test was run without applying flutter fixes first). This method/getter/setter/argument will be deprecated in a followup PR once the registered test is migrated.
      
      ### `Painting` Library
      
      | Affected API | State of `textScaleFactor` | Comment | 
      | --- | --- | --- |
      | `InlineSpan.build({ double textScaleFactor = 1.0 })` argument | **Replaced** | | 
      | `TextStyle.getParagraphStyle({ double TextScaleFactor = 1.0 })` argument | **Replaced** | |
      | `TextStyle.getTextStyle({ double TextScaleFactor = 1.0 })`  argument| Deprecated | Can't replace: https://github.com/superlistapp/super_editor/blob/c47fd38dca4b7f43611690913b551a1773c563d7/super_editor/lib/src/infrastructure/super_textfield/desktop/desktop_textfield.dart#L1903-L1905|
      | `TextPainter({ double TextScaleFactor = 1.0 })` constructor argument | Deprecated | |
      | `TextPainter.textScaleFactor` getter and setter | Deprecated | No Flutter Fix, not expressible yet |
      | `TextPainter.computeWidth({ double TextScaleFactor = 1.0 })` argument | Deprecated | |
      | `TextPainter.computeMaxIntrinsicWidth({ double TextScaleFactor = 1.0 })` argument | Deprecated | |
      
      ### `Rendering` Library
      
      | Affected API | State of `textScaleFactor` | Comment | 
      | --- | --- | --- |
      | `RenderEditable({ double TextScaleFactor = 1.0 })` constructor argument | Deprecated | |
      | `RenderEditable.textScaleFactor` getter and setter | Deprecated | No Flutter Fix, not expressible yet |
      | `RenderParagraph({ double TextScaleFactor = 1.0 })` constructor argument | Deprecated | |
      | `RenderParagraph.textScaleFactor` getter and setter | Deprecated | No Flutter Fix, not expressible yet |
      
      ### `Widgets` Library
      
      | Affected API | State of `textScaleFactor` | Comment | 
      | --- | --- | --- |
      | `MediaQueryData({ double TextScaleFactor = 1.0 })` constructor argument | **To Be Deprecated** | https://github.com/flutter/packages/blob/cd7b93532e5cb605a42735e20f1de70fc00adae7/packages/flutter_markdown/test/text_scale_factor_test.dart#LL39C21-L39C35 |
      | `MediaQueryData.textScaleFactor` getter | Deprecated | |
      | `MediaQueryData.copyWith({ double? TextScaleFactor })` argument | Deprecated | |
      | `MediaQuery.maybeTextScaleFactorOf(BuildContext context)` static method | Deprecated | No Flutter Fix, not expressible yet  |
      | `MediaQuery.textScaleFactorOf(BuildContext context)` static method | **To Be Deprecated** | https://github.com/flutter/packages/blob/cd7b93532e5cb605a42735e20f1de70fc00adae7/packages/flutter_markdown/lib/src/_functions_io.dart#L68-L70, No Flutter Fix, not expressible yet |
      | `RichText({ double TextScaleFactor = 1.0 })` constructor argument | **To Be Deprecated** | https://github.com/flutter/packages/blob/cd7b93532e5cb605a42735e20f1de70fc00adae7/packages/flutter_markdown/lib/src/builder.dart#L829-L843 |
      | `RichText.textScaleFactor` getter | **To Be Deprecated** | A constructor argument can't be deprecated right away|
      | `Text({ double? TextScaleFactor = 1.0 })` constructor argument | **To Be Deprecated** | https://github.com/flutter/packages/blob/914d120da12fba458c020210727831c31bd71041/packages/rfw/lib/src/flutter/core_widgets.dart#L647 , No Flutter Fix because of https://github.com/dart-lang/sdk/issues/52664 |
      | `Text.rich({ double? TextScaleFactor = 1.0 })` constructor argument | **To Be Deprecated** | The default constructor has an argument that can't be deprecated right away. No Flutter Fix because of https://github.com/dart-lang/sdk/issues/52664 |
      | `Text.textScaleFactor` getter | **To Be Deprecated** | A constructor argument can't be deprecated right away |
      | `EditableText({ double? TextScaleFactor = 1.0 })` constructor argument | Deprecated | No Flutter Fix because of https://github.com/dart-lang/sdk/issues/52664 |
      | `EditableText.textScaleFactor` getter | Deprecated | |
      
      ### `Material` Library
      
      | Affected API | State of `textScaleFactor` | Comment | 
      | --- | --- | --- |
      | `SelectableText({ double? TextScaleFactor = 1.0 })` constructor argument | **To Be Deprecated** | https://github.com/flutter/packages/blob/cd7b93532e5cb605a42735e20f1de70fc00adae7/packages/flutter_markdown/lib/src/builder.dart#L829-L843, No Flutter Fix because of https://github.com/dart-lang/sdk/issues/52664 |
      | `SelectableText.rich({ double? TextScaleFactor = 1.0 })` constructor argument | **To Be Deprecated** | The default constructor has an argument that can't be deprecated right away. No Flutter Fix because of https://github.com/dart-lang/sdk/issues/52664 |
      | `SelectableText.textScaleFactor` getter | **To Be Deprecated** | A constructor argument can't be deprecated right away |
      
      A lot of material widgets (`Slider`, `RangeSlider`, `TimePicker`, and different types of buttons) also change their layout based on `textScaleFactor`. These need to be handled in a case-by-case fashion and will be migrated in follow-up PRs.
      b2e22d35
  3. 19 Jun, 2023 1 commit
    • Taha Tesser's avatar
      Introduce MaterialState `color` property for chips (#128584) · 467c970b
      Taha Tesser authored
      fixes https://github.com/flutter/flutter/issues/115827
      fixes https://github.com/flutter/flutter/issues/101325
      
      ### Description
      1. This PR adds a new MaterialState `color` property to all the chips (this makes it possible to customize chips in all states from the M3 specs).
      2. Updated defaults to use the new  MaterialState `color` property.
      3. Updated and added new tests to all the chip test classes.
      
      <details> 
      <summary>code sample</summary> 
      
      ```dart
      import 'package:flutter/material.dart';
      
      const Color disabledColor = Colors.black26;
      const Color backgroundColor = Colors.cyan;
      final Color disabledSelectedColor = Colors.red.shade100;
      const Color selectedColor = Colors.amber;
      final MaterialStateProperty<Color> color =
          MaterialStateProperty.resolveWith((Set<MaterialState> states) {
        if (states.contains(MaterialState.disabled) &&
            states.contains(MaterialState.selected)) {
          return disabledSelectedColor;
        }
        if (states.contains(MaterialState.disabled)) {
          return disabledColor;
        }
        if (states.contains(MaterialState.selected)) {
          return selectedColor;
        }
        return backgroundColor;
      });
      
      void main() => runApp(const MyApp());
      
      class MyApp extends StatelessWidget {
        const MyApp({super.key});
      
        @override
        Widget build(BuildContext context) {
          return MaterialApp(
            debugShowCheckedModeBanner: false,
            theme: ThemeData(
              useMaterial3: true,
              // chipTheme: ChipThemeData(color: color),
            ),
            home: const Example(),
          );
        }
      }
      
      class Example extends StatefulWidget {
        const Example({super.key});
      
        @override
        State<Example> createState() => _ExampleState();
      }
      
      class _ExampleState extends State<Example> {
        bool enabled = false;
        bool selected = true;
      
        @override
        Widget build(BuildContext context) {
          const Widget verticalSpace = SizedBox(height: 20);
      
          return Scaffold(
            body: Center(
              child: Column(
                children: <Widget>[
                  const SizedBox(height: 25),
                  Row(
                    mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                    children: <Widget>[
                      const Card(
                        elevation: 0.0,
                        color: disabledColor,
                        child: Padding(
                          padding: EdgeInsets.all(8.0),
                          child: Text('disabledColor'),
                        ),
                      ),
                      const Card(
                        elevation: 0.0,
                        color: backgroundColor,
                        child: Padding(
                          padding: EdgeInsets.all(8.0),
                          child: Text('backgroundColor'),
                        ),
                      ),
                      Card(
                        elevation: 0.0,
                        color: disabledSelectedColor,
                        child: const Padding(
                          padding: EdgeInsets.all(8.0),
                          child: Text('disabledSelectedColor'),
                        ),
                      ),
                      const Card(
                        elevation: 0.0,
                        color: selectedColor,
                        child: Padding(
                          padding: EdgeInsets.all(8.0),
                          child: Text('selectedColor'),
                        ),
                      ),
                    ],
                  ),
                  const Spacer(),
                  Row(
                    mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                    children: <Widget>[
                      Column(
                        mainAxisSize: MainAxisSize.min,
                        mainAxisAlignment: MainAxisAlignment.center,
                        children: <Widget>[
                          RawChip(
                            selected: selected,
                            selectedColor: selectedColor,
                            color: color,
                            label: const Text('RawChip'),
                            isEnabled: enabled,
                            onSelected: enabled ? (bool value) {} : null,
                          ),
                          verticalSpace,
                          InputChip(
                            isEnabled: enabled,
                            selected: selected,
                            selectedColor: selectedColor,
                            color: color,
                            label: const Text('InputChip'),
                            onSelected: enabled ? (bool value) {} : null,
                          ),
                        ],
                      ),
                      Column(
                        mainAxisSize: MainAxisSize.min,
                        children: <Widget>[
                          FilterChip(
                            selected: selected,
                            selectedColor: selectedColor,
                            color: color,
                            label: const Text('FilterChip'),
                            onSelected: enabled ? (bool value) {} : null,
                          ),
                          verticalSpace,
                          FilterChip.elevated(
                            selected: selected,
                            selectedColor: selectedColor,
                            color: color,
                            label: const Text('FilterChip.elevated'),
                            onSelected: enabled ? (bool value) {} : null,
                          ),
                        ],
                      ),
                      Column(
                        mainAxisSize: MainAxisSize.min,
                        children: <Widget>[
                          ChoiceChip(
                            selected: selected,
                            selectedColor: selectedColor,
                            color: color,
                            label: const Text('ChoiceChip'),
                            onSelected: enabled ? (bool value) {} : null,
                          ),
                          verticalSpace,
                          ChoiceChip.elevated(
                            selected: selected,
                            selectedColor: selectedColor,
                            color: color,
                            label: const Text('ChoiceChip.elevated'),
                            onSelected: enabled ? (bool value) {} : null,
                          ),
                        ],
                      ),
                    ],
                  ),
                  const Spacer(),
                  Row(
                    children: <Widget>[
                      Flexible(
                        child: SwitchListTile(
                          title: const Text('Enabled'),
                          value: enabled,
                          onChanged: (bool value) {
                            setState(() => enabled = value);
                          },
                        ),
                      ),
                      Flexible(
                        child: SwitchListTile(
                          title: const Text('Selected'),
                          value: selected,
                          onChanged: (bool value) {
                            setState(() => selected = value);
                          },
                        ),
                      ),
                    ],
                  )
                ],
              ),
            ),
          );
        }
      }
      
      ``` 
      	
      </details>
      
      ### Before (not possible to customize disabled and selected chips)
      
      ![Screenshot 2023-06-13 at 16 27 13](https://github.com/flutter/flutter/assets/48603081/633f09f7-16a1-469e-b326-b9cc0ed59242)
      
      ### After (using disabled and selected chips using the new  MaterialState `color` property)
      
      ![Screenshot 2023-06-13 at 16 26 53](https://github.com/flutter/flutter/assets/48603081/7f5dffb7-4074-4268-87c0-c059c2da67a8)
      467c970b
  4. 09 Jun, 2023 1 commit
    • Pierre-Louis's avatar
      Improve defaults generation with logging, stats, and token validation (#128244) · 66cda591
      Pierre-Louis authored
      ## Description
      
      This improves defaults generation with logging, stats, and token validation. 
      
      This PR includes these changes:
      * introduce `TokenLogger`, with a verbose mode
        * prints versions and tokens usage to the console
        * outputs `generated/used_tokens.csv`, a list of all used tokens, for use by Google
      * find token files in `data` automatically
      * hide tokens `Map`
        * tokens can be obtained using existing resolvers (e.g. `color`, `shape`), or directly through `getToken`.
        * tokens can be checked for existence with `tokenAvailable`
      * remove version from template, since the tokens are aggregated and multiple versions are possible (as is the case currently), it does not make sense to attribute a single version
      * improve documentation
      
      ## Related Issues
       - Fixes https://github.com/flutter/flutter/issues/122602
      
      ## Tests
       - Added tests for `TokenLogger`
       - Regenerated tokens, no-op except version removal
      
      ## Future work
      A future PR should replace or remove the following invalid tokens usages
      
      <img width="578" alt="image" src="https://github.com/flutter/flutter/assets/6655696/b6f9e5a7-523f-4f72-94f9-1b0bf4cc9f00">
      66cda591
  5. 31 Mar, 2023 1 commit
  6. 14 Mar, 2023 1 commit
  7. 13 Mar, 2023 1 commit
  8. 09 Feb, 2023 1 commit
  9. 07 Feb, 2023 1 commit
  10. 24 Jan, 2023 1 commit
  11. 17 Jan, 2023 1 commit
  12. 03 Jan, 2023 1 commit
  13. 09 Dec, 2022 1 commit
  14. 28 Nov, 2022 1 commit
  15. 15 Nov, 2022 1 commit
  16. 24 Oct, 2022 1 commit
  17. 19 Sep, 2022 2 commits
  18. 14 Sep, 2022 1 commit
  19. 06 Sep, 2022 1 commit
    • Darren Austin's avatar
      Fixing elevation issues with Material 3 (#110624) · 33ed6a35
      Darren Austin authored
      * Added support for surfaceTintColor and shadowColor to the Dialog widgets.
      * Updated the defaults for Material.shadowColor and Material.surfaceTint to allow turning off the features with a transparent color.
      * Added support for shadowColor and surfaceTintColor for Drawer widget.
      33ed6a35
  20. 29 Jul, 2022 1 commit
  21. 11 Jul, 2022 1 commit
  22. 06 Jul, 2022 1 commit
  23. 27 Apr, 2022 1 commit
  24. 14 Apr, 2022 1 commit
  25. 12 Apr, 2022 1 commit