From ceabea0f664d669e70e800e82c13bd4850882166 Mon Sep 17 00:00:00 2001 From: Rydmike <39990307+rydmike@users.noreply.github.com> Date: Wed, 23 Nov 2022 21:41:10 +0200 Subject: [PATCH] Version 3.0.0 New feature: transitionBuilder and transitionDuration added to dialogs. Review and update README --- .github/workflows/deploy.yml | 2 +- .github/workflows/deploy_test.yml | 2 +- CHANGELOG.md | 146 +++++----- README.md | 367 ++++++++++++++------------ example/lib/main.dart | 27 +- lib/src/color_picker.dart | 99 +++++-- lib/src/show_color_picker_dialog.dart | 19 ++ 7 files changed, 399 insertions(+), 263 deletions(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 575fb14..97681d5 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -54,7 +54,7 @@ jobs: - name: Analyze Dart source run: dart analyze - - name: Show outdated packges + - name: Show outdated packages run: flutter pub outdated - name: Verify that Dart formatting is used, fail if not diff --git a/.github/workflows/deploy_test.yml b/.github/workflows/deploy_test.yml index c0bcac0..4a54cac 100644 --- a/.github/workflows/deploy_test.yml +++ b/.github/workflows/deploy_test.yml @@ -52,7 +52,7 @@ jobs: - name: Analyze Dart source run: dart analyze - - name: Show outdated packges + - name: Show outdated packages run: flutter pub outdated - name: Verify that Dart formatting is used, fail if not diff --git a/CHANGELOG.md b/CHANGELOG.md index 160976d..3203925 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,22 +6,28 @@ All notable changes to the **FlexColorPicker** package are documented in this fi **Nov 23, 2022** -**STYLE BREAKING** +**BREAKING - STYLE** * The color picker dialog `actionsPadding` now default to null. This results in that if it is undefined, its value is determined by the ambient `AlertDialogTheme`, or if it is not defined either, the default for `AlertDialog`. Which have different defaults depending on if Material 2 or Material 3 is used. Default value in previous versions of **FlexColorPicker** was: `EdgeInsets.symmetric(horizontal: 16)` * The color picker dialog `buttonPadding` now default to null. This results in that if it is undefined, its value is determined by the ambient `AlertDialogTheme`, or if it is not defined either, the default for `AlertDialog`. Which have different defaults depending on if Material 2 or Material 3 is used. Default value in previous versions of **FlexColorPicker** was: `EdgeInsets.all(16)` -* The API usage of the above properties is unchanged. It is only the default behavior that has been updated to be less opinionated and enabled correct theme response. +* The API usage of the above properties is unchanged. It is only the default behavior that has been updated to be less opinionated and to enable using theme-dependent settings. -**REMOVED** +**BREAKING - REMOVED** -* Removed in version 2.1.0 no longer used and deprecated parameter `useRootNavigator` in `ColorPicker` method `showPickerDialog`. -* Removed in version 2.1.0 no longer used and deprecated parameter `useRootNavigator` in function `showColorPickerDialog`. +* Removed in version 2.1.0 no longer used and already deprecated parameter `useRootNavigator` in `ColorPicker` method `showPickerDialog`. +* Removed in version 2.1.0 no longer used and already deprecated parameter `useRootNavigator` in function `showColorPickerDialog`. **NEW** -* To `ColorPicker` method `showPickerDialog` added parameters `barrierLabel` and `anchorPoint` as pass along values to Flutter SDK `showDialog`. -* To function `showColorPickerDialog` added parameters `barrierLabel` and `anchorPoint` as pass along values to Flutter SDK `showDialog`. +* To `ColorPicker` method `showPickerDialog` and to function `showColorPickerDialog`, added parameters `barrierLabel` and `anchorPoint` as pass along values to Flutter SDK `showDialog` and `showGeneralDialog`. + +* To `ColorPicker` method `showPickerDialog` and to function `showColorPickerDialog` added parameters `transitionBuilder` and `transitionDuration`. If `transitionBuilder` is not null, the `showPickerDialog` and `showColorPickerDialog` will use the `showGeneralDialog` Flutter SDK function instead of `showDialog`. The `showGeneralDialog` function will be used with the provided `transitionBuilder` and `transitionDuration`. The `transitionDuration` only has any impact when the `transitionBuilder` is used. If `transitionBuilder` is null, then the `showPickerDialog` and `showColorPickerDialog` use the Flutter SDK `showDialog` implementation as before, thus using the default Material platform dependent `showDialog` transition and duration. + +**EXAMPLES** + +* Default example: Added an example of how to use the `transitionBuilder`. +* Web example: Modernized its theme by using Material 3 and a seed generated `ColorScheme`. ## 2.6.1 @@ -29,7 +35,7 @@ All notable changes to the **FlexColorPicker** package are documented in this fi **Sep 9, 2022** * Add `secondaryOffset` to `OpacitySliderTrack` `paint` method override to **fix** new requirement - for master channel compatibility, works with the stable channel too. Thanks + for master channel compatibility, works with the stable channel too. Thanks, [Dan Reynolds](https://github.com/danReynolds) for the PR. ## 2.6.0 @@ -59,10 +65,10 @@ All notable changes to the **FlexColorPicker** package are documented in this fi **CHANGE** -* This is a dev release for those that need to work with both master channel where Flutter master +* This is a dev release for those that need to work with both master channel, where Flutter master SDK depends on material_color_utilities 0.2.0 and 3.3.0 beta, pre for upcoming Flutter 3.3.0 stable, use material_color_utilities 0.1.5. It uses a controversial package constraint of: - `material_color_utilities: '>=0.1.5 <=0.2.0'`. Using older version 0.1.3 and 0.1.4 in theory + `material_color_utilities: '>=0.1.5 <=0.2.0'`. Using older versions 0.1.3 and 0.1.4 in theory also works, but they contain some breaking color values in the used algorithm for calculation of tonal palettes. The color changes are very minor and typically not visible to the eye. @@ -75,15 +81,15 @@ All notable changes to the **FlexColorPicker** package are documented in this fi **CHANGE** -* This is a dev release for those that need to work with master channel where Flutter SDK depends on - material_color_utilities ^0.2.0. +* This is a dev release for those that need to work with the master channel, where Flutter SDK + depends on material_color_utilities ^0.2.0. * Updated material_color_utilities to ^0.2.0. This version constraint does not work with Flutter 3.0.x stable or beta 3.3.x, and their earlier versions. This dev release is required to use Flutter SDK **master** 3.1.0-0.0.pre.2111 or later, that uses material_color_utilities 0.2.0. -* For other (older) version of Flutter SDK you can use package version 2.5.0 that has a +* For other (older) versions of Flutter SDK you can use package version 2.5.0 that has a material_color_utilities version constraint of ^0.1.3. * This release also updates Dart SDK constraint to '>=2.17.0 <3.0.0' and has Flutter listed as @@ -135,11 +141,11 @@ All notable changes to the **FlexColorPicker** package are documented in this fi setting [autoFocus] to false might help. If both [ctrlC] and [ctrlV] are false, the picker yields the focus the - same way as setting [autoFocus] false, but then you have no keyboard shortcut + same way as setting [autoFocus] false, but then you have no keyboard-shortcut copy-paste functions at all. With [autoFocus] false, you can still use keyboard copy-paste shortcuts and yield the focus from the picker. When you do this, the copy-paste keyboard shortcuts will not work until - one of the pickers components have been focused by interacting with them. + one of the picker's components is focused by interacting with any of them. The picker still grabs focus when you click on its background, as one way to set focus to keyboard listener to enable copy-paste keyboard shortcuts @@ -157,16 +163,16 @@ All notable changes to the **FlexColorPicker** package are documented in this fi * The generated Material Color swatch you get when you click on any color in the wheel picker has been updated and is a bit improved. It is still not the actual M2 `MaterialColor` swatch algorithm, like the Tonal Palette is when it - comes to Material 3. Which is using the actual seed algorithm for the primary - tonal palette you get with the selected color as input. The wheel does detect when - you have selected any Material 2 swatch color and shows its swatch then. + comes to Material 3. It uses the actual seed algorithm for the primary + tonal palette you get with the selected color as input. The wheel detects when + you select any Material 2 swatch color and shows its swatch then. For other colors, it computes a `MaterialColor` swatch. This swatch is still not using the correct algorithm, but it is a bit better looking than before. There is currently no know Dart implementation of this algorithm, if there were it would be in use here. There are some versions in JS of the algorithm - that have been reverse engineered from the Material 2 design guide website. + that have been reverse-engineered from the Material 2 design guide website. If someone wants to make a Dart version, that would be fabulous. Links and more information can be found in `ColorTools.createPrimarySwatch` @@ -180,7 +186,7 @@ All notable changes to the **FlexColorPicker** package are documented in this fi **FIX** -* Fix for nullable/none nullable difference for Flutter `IconButton` between Flutter +* Fix for nullable/none-nullable difference for Flutter `IconButton` between Flutter version 2.10.0 and earlier versions Flutter 2.8.1, where `iconSize` is nullable in Flutter 2.10.x, but not in Flutter 2.8.1. See issues [report #40](https://github.com/rydmike/flex_color_picker/issues/40) and [PR #41](https://github.com/rydmike/flex_color_picker/pull/41). @@ -191,7 +197,7 @@ All notable changes to the **FlexColorPicker** package are documented in this fi **NEW** -* Added capability to show a Material 3 tonal palette as per +* Added capability to show a Material 3 tonal-palette as per [Material 3 design specification](https://m3.material.io/styles/color/the-color-system/key-colors-tones). * To enable it set new `ColorPicker` property `enableTonalPalette` to true. @@ -200,44 +206,44 @@ All notable changes to the **FlexColorPicker** package are documented in this fi you can show an optional `tonalSubheading` widget above it. - When you click/select a color in the color picker and tonal palette is - enabled, a 13 shade Material 3 tonal palette for the selected color will be + enabled, a 13 shade Material 3 tonal-palette for the selected color will be generated, always starting with black, tone 0 for the used seed color and ending in white, tone 100. - The official Material 3 Dart library is used to create the tonal palette from any selected color. The color you select functions a seed color to generate the tonal palette and might not be included itself and selected in - the palette. You can of course click on any color in the generated palette to + the palette. You can, of course, click on any color in the generated palette to select and pick a color. - - Selecting a color in the tonal palette, only selects the color in the palette, - it does not update the palette. Only when you select a color from the other - color sources in the picker, is that color used as key, to seed and generate + - Selecting a color in the tonal palette, only selects the color in the palette. + It does not update the palette. Only when you select a color from the other + color sources in the picker, is that color used as key color, to seed and generate an updated color palette for the selected color. **CHANGE** * The WEB example was updated to include enabling and disabling - the tonal palette and built it with Flutter version, stable 2.10.1. + the tonal palette and built it with the Flutter version stable 2.10.1. * All dependencies in the Web demo were updated to their latest released version. - The Web demo example requires at least Flutter 2.10.0 to be built, - it uses ColorScheme properties in its theme that were not available + The Web demo example requires at least Flutter 2.10.0 to be built. + It uses ColorScheme properties in its theme that were not available earlier and removed in 2.10.0 deprecated color properties from its theme. - The color picker package itself, still has unchanged version requirement + The color picker package itself, still has the same version requirement as before of Dart SDK: '>=2.14.0 < 3.0.0'. ## 2.2.0 **November 17, 2021** -* Fixed the style for color entry field, to always uses the intended fixed stadium style. +* Fixed the style for color entry field, to always use the intended fixed stadium style. * Updated dependencies for the web demo, big change was Riverpod to use v1.0.0. * Lint rule updates. * Bump Dart SDK requirement to 2.14. -* Build and publish WEB demo with updated version using Flutter 2.5.3. +* Build and publish WEB demo with the updated version using Flutter 2.5.3. ## 2.1.2 @@ -290,7 +296,7 @@ All notable changes to the **FlexColorPicker** package are documented in this fi ColorPickerCopyPasteBehavior, to enable using long press in the color picker, to open up the COPY-PASTE context menu on Web, iOS and Android touch devices. While using secondary mouse button on desktop platforms Windows, Mac and Linux, but not if it is a desktop web app. -* **Documentation:** Fixed broken API reference links in API guide chapter. Mentioned that WEB build +* **Documentation:** Fixed broken API reference links in the API guide chapter. Mentioned that WEB build requires a canvas kit build if `enableOpacity` feature is used. * **Web example:** The live web example got updated to use the latest Flutter stable embedder. * **CI/CD:** Tried the CI/CD deployment with --base-href="/flexcolorpicker/" instead of `repl`. Did not @@ -303,10 +309,10 @@ All notable changes to the **FlexColorPicker** package are documented in this fi * **New feature:** Enabled updating the color picker externally. Just set the `color` property of the widget to a new value to update it. You can even "remote control" the color picker by updating the `color`, if so needed. - This is mostly a potential use-case for desktop/web when the picker is not used in a dialog. - You can of course use this on a phone or tablet too, but often there is not enough room to keep the picker + This is mostly a potential use-case for desktop and web, when the picker is not used in a dialog. + You can, of course, use this on a phone or tablet too, but often there is not enough space to keep the picker visible on the main surface this way on mobile devices. However, on desktops it is certainly a valid use - case that should be supported. It was previously not supported by design, but as we are going for covering + case that should be supported. It was previously not supported by design, but as we are going to support web/desktop use-cases, it should certainly be supported. This update adds support for it. The picker only updates if the externally provided `color` constructor property differs from its internally kept color state. Finding the right picker, computing its swatches, is a bit demanding, but it seems to work fluidly, @@ -327,12 +333,12 @@ All notable changes to the **FlexColorPicker** package are documented in this fi Please see changelogs from 2.0.0-nullsafety.0 to nullsafety.5, for a complete list of changes and new features. * To get familiar with version 2.0.0 and all its new features, it is recommended to go through the updated tutorial, and the API guide in the readme file. -* For convenience, the list of breaking changes from last stable version 1.1.5 are listed below. +* For convenience, the list of breaking changes from the previous stable version 1.1.5 is shown below. **BREAKING** -In addition to breaking changes as a result of the null-safety implementation, this release contain a few other +In addition to breaking changes as a result of the null-safety implementation, this release contains a few other **minor breaking changes** from version 1.x, they mostly concern visual nuances and label defaults. * The `colorCodeIcon` has been deprecated and no longer has any function. To modify the copy icon on the color @@ -348,11 +354,11 @@ In addition to breaking changes as a result of the null-safety implementation, t * The extension `FlexPickerNoNullStringExtensions` on none nullable `String` named `toColor`, no longer returns color value `Color(0x00000000)` for colors that cannot be parsed to a Color. It now returns `Color(0xFF000000)`. This is because the Flutter SDK dislikes the fully transparent - black `Color(0x00000000)`, if it is full opaque black, it works better as a fallback safety color. + black `Color(0x00000000)`, if it is fully opaque black, it works better as a fallback safety color. The `FlexPickerNullableStringExtensions` on `String?` named `toColorMaybeNull` works as before by returning null when the `String?` cannot be parsed to a `Color`. -* The color code edit and entry field now works more like a normal text entry field. It still - only accepts valid hex input and converts all input to uppercase. +* The color code edit and entry field now work more like a normal text entry field. It still + only accepts valid hex input and converts all inputs to uppercase. ## 2.0.0-nullsafety.5 @@ -375,19 +381,19 @@ In addition to breaking changes as a result of the null-safety implementation, t named properties in `ColorPicker`. The dialog's elevation and title in the `showColorPickerDialog` are instead called `dialogElevation` and `dialogTitle` in it. * **Improvement:** Performance was improved via more optimized rebuilds. -* **Documentation:** First version of updated documentation with API guide documentation is now included. It still - requires proofreading before stable release, but getting close to be ready for release now. +* **Documentation:** The first version of updated documentation with API guide documentation is now included. It still + requires proofreading before stable release, but getting close to being ready for release now. * **Default example:** The default example got a new picker that shows how to the new `showColorPickerDialog` function. * **Web example:** The Web example, with the built-in API tooltips guides, got a major rewrite. It was originally not intended to be as large as it grew to be, but since it grew so much it needed a rewrite. It now uses Riverpod to make its simple state management needs easy to handle and much cleaner than before. - It also includes persisting the settings directly as settings are changed in the app. The persistence is - implemented with Hive and should work on all Flutter platforms as well, but it has only been tested on Android, + It also includes persisting the settings directly as settings are changed in the app. Persistence is + implemented with Hive, and should work on all Flutter platforms as well, but it has only been tested on Android, Web and Windows. As an experiment, only RiverPod StateProviders were used. While the setup is a bit tedious, it enables the desired fine-grained control over rebuilds of all the used setting control widgets. Each setting is also stored as an individual key-value pair in the used Hive box. - A ProviderObserver that observes changes in the StateProviders we want to persist, is used to save any state change + A ProviderObserver that observes changes in the StateProviders we want to persist is used to save any state change to the used Hive box, regardless of where the state is changed in the demo app. This setup was an experiment to see if it might work and provide some simplification benefits. At least in this case it did, and it is also a pretty interesting and simple solution. @@ -412,19 +418,19 @@ In addition to breaking changes as a result of the null-safety implementation, t **March 12, 2021** -* **Fix:** Color code field no longer receives focus when switching to it on wheel page. - Focus is set to color wheel, or the selected color shade, if the - shade colors are present. The focus handling has also been improved for desktop usage. +* **Fix:** Color code field no longer receives focus when switching to it on the wheel page. + Focus is set to color wheel, or the selected color shade if shade colors are present. + The focus handling has also been improved for desktop usage. * **Fix:** The property `editUsesParsedPaste` now works as intended, if true, desktop keyboard paste commands, while editing a color value are intercepted, and the hole pasted buffer value gets parsed, it does not get pasted into the field. For normal field paste functionality keep `editUsesParsedPaste` false (default). -* **Minor breaking:** The color code edit and entry field now works more like a normal text entry field. It still - only accepts valid hex input and converts all input to uppercase. +* **Minor breaking:** The color code edit and entry field now work more like a normal text entry field. It still + only accepts valid hex input and converts all inputs to uppercase. * **New property:** If `colorCodeHasColor` is true, then the background of the color code entry field uses the current selected color. -* **New property** If `colorCodeReadOnly` the color code entry field is always read only. Normally color code can +* **New property** If `colorCodeReadOnly` the color code entry field is always read only. Normally, color code can be edited on the wheel picker, set this to true to make it read only there as well. Copy/paste operations still work - if they are enabled even if the color code field entry is in read only mode. + if they are enabled even if the color code field entry is in read-only mode. * **New feature:** The `copyPasteBehavior` property received three new features and properties: * The copy/paste context menu can now also optionally use secondary, typically mouse right, click by setting `secondaryMenu` to true. @@ -439,7 +445,7 @@ In addition to breaking changes as a result of the null-safety implementation, t * **Minor breaking:** The extension `FlexPickerNoNullStringExtensions` on none nullable `String` named `toColor`, no longer returns color value `Color(0x00000000)` for colors that cannot be parsed to a Color. It now returns `Color(0xFF000000)`. This is because the Flutter SDK dislikes the fully transparent - black `Color(0x00000000)`, if it is full opaque black, it works better as a fallback safety color. + black `Color(0x00000000)`, if it is fully opaque black, it works better as a fallback safety color. The `FlexPickerNullableStringExtensions` on `String?` named `toColorMaybeNull` works as before by returning null when the `String?` cannot be parsed to a `Color`. * **Tests:** Added unit tests for `ColorPickerActionButtonType` and `ColorPickerCopyPasteBehavior`. @@ -456,12 +462,12 @@ In addition to breaking changes as a result of the null-safety implementation, t **March 3, 2021** -There are many new features included in this version 2 pre-release. The new features can be explored with +There are many new features included in this version 2 pre-release. The new features can be explored with the [live Web example](https://rydmike.com/flexcolorpicker/). Its source code is also included in the package example folder, in "example/lib/demo/main.dart". -* **Improvement:** The wheel picker now move on pointer down to point location, it no longer requires a slight movement - for its thumbs to move to the selected start tracking point. +* **Improvement:** The wheel picker now moves on pointer-down to point location, it no longer + requires a slight movement for its thumbs to move to the selected start tracking point. * **Improvements:** Keyboard traversal of the colors and selecting indicator colors with the keyboard via enter or space. The wheel can however still not be operated with a keyboard, only touch and mouse controlled. * **New property:** `onColorChangeStart` called when user starts color selection with current color before the change. @@ -472,13 +478,13 @@ example folder, in "example/lib/demo/main.dart". If not defined it defaults to same style as `colorCodeTextStyle`. Ported from none null-safe version 1.1.4, does not exist in version 2.0.0-nullsafety.0. * **New property:** `title` is a Widget used as an app bar type of title widget above the heading. Can also - include copy, paste, select-close and cancel-cancel icon buttons when picker is used as a dialog. + include copy, paste, select-close and cancel-cancel icon buttons when the picker is used as a dialog. * **New feature:** There is an `actionButtons` property that takes an `ColorPickerActionButtons()`. It is used to define what type of **Ok** and **Cancel** action buttons the color picker has when used in a dialog. It is possible to define if bottom action buttons should be `TextButton`, `OutlinedButton` or `ElevatedButton` - per button. If not defined, the labels on the buttons come from Material localizations, not from default hard - coded values. See breaking label for the 'Select' label. There are optional select/OK and cancel icon buttons - that can be used in the title bar for a more compact dialog. + per button. If not defined, the labels on the buttons come from Material localizations, not from + hard-coded default values. See breaking label for the 'Select' label. There are optional select/OK and + cancel icon buttons that can be used in the title bar for a more compact dialog. * **New feature**: There is a `copyPasteBehavior` property that takes an `ColorPickerCopyPasteBehavior()`. It is used to define the copy/paste behavior of the color picker, including: * Keyboard shortcuts: CTRL-C, CMD-C, CTRL-V, CMD-V @@ -503,7 +509,7 @@ example folder, in "example/lib/demo/main.dart". the picker. You can use the following properties to control it. * `showRecentColors` set to true/false to enable/disable the usage of the recent colors feature. * `recentColorsSubheading` subheading widget for the recently used colors. Typically, a Text widget, - e.g., Text('Recent colors'). If not provided there is no sub heading for the recently used colors. + e.g., Text('Recent colors'). If not provided, there is no sub heading for the recently used colors. * `maxRecentColors` number of recent colors to track, from 2 to 20 allowed. * `recentColors` a list with current recent color, defaults to empty. You can store the last list and use this list to restore the previous recent colors list. @@ -535,10 +541,10 @@ The following are **minor breaking changes** from version 1.1.5, they mostly con * A workaround to issue [#71687](https://github.com/flutter/flutter/issues/71687) was introduced. The issue has not been solved. However, the workaround allows for the Wrap implementation that was changed to a Row in version 1.1.2, to be used again. -* The almost full API configurable Web example and demo, was included in the package in +* The almost full API-configurable Web demo is included in the package in "example/lib/demo/main.dart" together with the previous default example in "example/lib/main.dart". Previously this Web example was in a separate GitHub repository. The example was updated to make it - responsive, to offer better usability on Web. + responsive, to offer better usability on Web builds. ## 1.1.5 @@ -579,7 +585,7 @@ When the issue is resolved, the implementation will be reverted to Wrap again. U **November 11, 2020** * Updated the example app and documentation. The update includes updated screenshots and updated animated gifs. -* Unit tests for ColorTools added, widget tests still pending for later updates. +* Unit tests for ColorTools added. Widget tests are still pending for later updates. ## 1.1.0 @@ -597,7 +603,7 @@ When the issue is resolved, the implementation will be reverted to Wrap again. U * First official release. * Example and documentation updated. * Updated the live Web demo version to use the released package. -* New API: Added `shouldUpdate` to the color wheel picker, as a fix for an issue where black selection changed hue to red. This is a lower level API that is not needed unless you make your own picker from scratch, and you want to use the wheel picker in your own picker. +* New API: Added `shouldUpdate` to the color-wheel picker, as a fix for an issue where black selection changed hue to red. This is a lower level API. It is not needed unless you make your own picker from scratch, and you want to use the wheel picker in your own picker. * Final API name tweaks before version 1.0.0 release: * Renamed: API `createPrimaryColor` -> `createPrimarySwatch` * Renamed: API `createAccentColor` -> `createAccentSwatch` @@ -628,7 +634,7 @@ When the issue is resolved, the implementation will be reverted to Wrap again. U **November 2, 2020** -* Significant API name changes and cleanup. Decided to implement previously planned changes before the official release, even if it will also impact our own usage of the package when we move to using the published version. +* Significant API name changes and cleanup. Decided to implement previously planned changes before the official release. ## 1.0.0-dev.2 @@ -650,17 +656,17 @@ Feel free to open a [suggestion or issue](https://github.com/rydmike/flex_color_ - [ ] Maybe: Add selected colors to the custom colors section. - [ ] Add more tests. - [ ] Finalize tests. -- [x] Release stable version 2.0.0 +- [x] Release the stable version 2.0.0 - [x] Add GitHub actions for test, analyze, coverage, build and web demo deployment. - [x] Add a simpler optional async dialog picker function, that returns selected color. - [x] Add support for colors with opacity or alpha. - [x] Improve copy/paste feature. - [x] Version 2.0.0-nullsafety.0: Add null safe version. -- [x] Version 1.1.1: Add first set of tests for the ColorPicker, so far only unit tests for ColorTools, more tests will be added later. ColorTools has 4694 tests. +- [x] Version 1.1.1: Add first tests of the ColorPicker, so far only unit tests for ColorTools, more tests will be added later. ColorTools has 4694 tests. - [x] Publish version 1.0.0 on pub.dev. - [x] Release version 1.0.0. - [x] Add "name that color" function that can give a name to "any" color in English. -- [x] For the color wheel picker, add text input to get a given color based on entered HEX code. +- [x] For the color-wheel picker, add text input to get a given color based on entered HEX code. - [x] Fix doc images that show up OK in GitHub readme.md, but not on pub.dev. - [x] Review and correct documentation mistakes and typos, first pass anyway. - [x] Review and update the API. diff --git a/README.md b/README.md index af87fbc..6f8a54d 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,4 @@ -[![Pub Version](https://img.shields.io/pub/v/flex_color_picker?label=flex_color_picker&labelColor=333940&logo=dart)](https://pub.dev/packages/flex_color_picker) ![GitHub Workflow Status (event)](https://img.shields.io/github/workflow/status/rydmike/flex_color_picker/Test?event=push) -![Test](https://github.com/rydmike/flex_color_picker/workflows/Test/badge.svg) [![codecov](https://codecov.io/gh/rydmike/flex_color_picker/branch/master/graph/badge.svg?token=4XJU30IGO3)](https://codecov.io/gh/rydmike/flex_color_picker) [![License](https://img.shields.io/badge/License-BSD%203--Clause-blue.svg)](https://opensource.org/licenses/BSD-3-Clause) +[![Pub Version](https://img.shields.io/pub/v/flex_color_picker?label=flex_color_picker&labelColor=333940&logo=dart)](https://pub.dev/packages/flex_color_picker) ![Test](https://github.com/rydmike/flex_color_picker/workflows/Test/badge.svg) [![codecov](https://codecov.io/gh/rydmike/flex_color_picker/branch/master/graph/badge.svg?token=4XJU30IGO3)](https://codecov.io/gh/rydmike/flex_color_picker) [![License](https://img.shields.io/badge/License-BSD%203--Clause-blue.svg)](https://opensource.org/licenses/BSD-3-Clause) # FlexColorPicker @@ -10,7 +9,7 @@ The size and style used for the pick items can be customized. The picker can optionally also generate Material Design 3 color system accurate tonal palettes, using any selected color in the picker, as key color to generate the tonal palette. A color from the generated tonal palette can then be picked as well. -See the [Material Design 3 site](https://m3.material.io/styles/color/the-color-system/key-colors-tones) +See the [Material 3 Design Guide website](https://m3.material.io/styles/color/the-color-system/key-colors-tones) for more information about the Material 3 color system and tonal palettes. @@ -75,7 +74,7 @@ The different types of available color pickers are: 3. Both primary and accent colors and their shades, in the same color picker. `ColorPickerType.both` 4. Black and white colors, including very near black and white shades. `ColorPickerType.bw` 5. Custom color swatches and their shades, that you define and name. `ColorPickerType.custom` -6. HSV color wheel picker, that allows you to select or enter any color. `ColorPickerType.wheel` +6. HSV color-wheel picker, that allows you to select or enter any color. `ColorPickerType.wheel` When you show more than one color picker, a segmented sliding control allows you to select which one to use. You can configure the `ColorPicker` to include any of the above color pickers. Showing pickers 1 and 2, together with picker 3 @@ -85,12 +84,12 @@ accent colors. Give the `ColorPicker` a heading and a subheading for the color shades, typically Text widgets with appropriate style. Decide if the Material shades can be selected or not and if the selected color name and RGB code are visible in the picker. If the color HEX RGB code is visible, the picker can also include a button that allows you to copy the selected -color's code to the clipboard directly from the field. On the wheel picker you can enter a HEX RGB color code, and +color code to the clipboard directly from the field. On the wheel picker you can enter a HEX RGB color code, and the wheel picker will move to select the entered color, while also creating a color swatch for it. The shape, size and spacing of the color picker items can be modified. There is a built-in dialog that can be used to show and use the `ColorPicker` in a dialog. You can of course also make your own dialog and just use the `ColorPicker` -widget in your own custom dialog or other overlay. +widget in your own custom dialog or some other type of overlay. ColorPicker variations lower @@ -117,7 +116,7 @@ flutter run --release ``` The result is a default color picker in a Card on the screen, with only the Material primary and accent color -pickers enabled. It also has two other color pickers that opens up in dialogs with different styles and different +pickers enabled. It also has two other color pickers that open up in dialogs with different styles and different enabled picker types. The [tutorial](#tutorial) goes through and explains the example application in detail. ColorPicker Basic @@ -125,42 +124,42 @@ enabled picker types. The [tutorial](#tutorial) goes through and explains the ex ### Live Web Demo You can also try a live Web demo of the [**FlexColorPicker here**](https://rydmike.com/flexcolorpicker). With the Web -demo you can modify most of the color picker's API values and use it as a tool to find a style that fits your +demo, you can modify most of the color picker's API values and use it as a tool to find a style that fits your application. The source code for the Web demo, which is a bit more elaborate example than examples normally are, is also bundled with the package source code in the "example/lib/demo" folder. > **IMPORTANT:** If the color picker's opacity slider feature is used on WEB builds `enableOpacity: true`, then you -> must build using the SKIA **canvaskit** renderer only. The opacity slider uses `ImageShader`, a Flutter API that -> was not yet available on **html** builds, at least not in version stable 2.2.1. +> may prefer using the SKIA **canvaskit** renderer on builds with older Flutter versions. The opacity slider +> uses `ImageShader`, a Flutter API that is not available on **html** builds, at least not in the stable 2.2.1 version > > ``` > flutter run -d chrome --web-renderer canvaskit > flutter build web --web-renderer canvaskit > ``` -> For more information see https://flutter.dev/docs/development/tools/web-renderers +> For more information, see https://flutter.dev/docs/development/tools/web-renderers > -> **UPDATE Feb 18, 2022:** When using Flutter stable version 2.10.1, the `ImageShader` API +> **UPDATE Feb 18, 2022:** When using Flutter stable version 2.10.1, the `ImageShader` API > seems to be available and working also when using --web-renderer html, build. However, if you -> run into issues with the opacity slider on web builds, try using canvaskit, instead of auto or -> html renderer when you build the Web app. +> run into issues with the opacity slider on web builds, prefer using canvaskit instead of auto or +> html renderer when you use the `ColorPicker` in web apps and enable the opacity slider. -The Web demo has a responsive view, that expands into maximum four separately scrollable columns. The columns contain +The Web demo has a responsive view that expands into maximum four separately scrollable columns. The columns contain a massive amount of controls that you can use to adjust the color picker's settings. On a 1080p desktop screen, -you can see most of the settings at the same time as the color picker. With this you can test the settings and see their +you can see most of the settings at the same time as the color picker. With this, you can test the settings and see their impact on the picker as you adjust them. The Web demo also has tooltips for each setting control. The tooltips show the name of the API it modifies and its -current value. With this feature you can use the web demo as a tool configure the color picker to a desired style, +current value. With this feature, you can use the web demo as a tool to configure the color picker to a desired style, and find the APIs and values that you used. -The same toggle that is used to turn OFF the tooltips in the color picker, also turns OFF +The same toggle that is used to turn OFF the tooltips in the color picker also turns OFF the API tooltips in the demo, in case they get in the way. By default, the tooltips are ON, to show the used API and its current value. -The **FlexColorPicker** web demo also persist the settings as you change them. The next time you use it, with the same +The **FlexColorPicker** web demo also persists the settings as you change them. The next time you use it, with the same device and browser, it will restore the configuration that you left it in last time you used it. You can reset the settings to their start default values as well. @@ -168,14 +167,14 @@ settings to their start default values as well. # Tutorial -In this chapter we use the default bundled example application as an introduction to the **FlexColorPicker**. We will +In this chapter, we use the default and bundled example application as an introduction to the **FlexColorPicker**. We will create three different color pickers, with different configurations and use the `ColorPicker` three different ways. This example uses a `StatefulWidget` as its main page, the `ColorPickerPage`, where we define three different `Color` objects in its local state, and give them a start value in the `StatefulWidget`'s `initState()`. We will use these colors to indicate the currently selected color for the three examples and as start color value -for each example color picker. +for each color picker. ```dart class _ColorPickerPageState extends State { @@ -197,7 +196,7 @@ void initState() { ## Color Indicator We can use the `ColorIndicator` Widget, that the `ColorPicker` also uses internally, to show and select a new color. -Alternatively you can make and use a custom for Widget for this purpose. In this tutorial we use the `ColorIndicator` in +Alternatively, you can make and use a custom for Widget for this purpose. In this tutorial we use the `ColorIndicator` in a `ListTile`, and use the `ColorIndicator` as its trailing property to show the selected color. The **FlexColorPicker** package also includes `ColorTools`, a set of helper functions that among other things, @@ -288,9 +287,9 @@ A common use case for a color picker is to show a color selection widget and all a dialog. The `ColorPicker` comes with a built-in dialog that can be used for this. Alternatively you can just use the `ColorPicker` widget and include it in your own custom dialog. -For the first dialog example we will show all the built-in picker types, except the combined +For the first dialog example, we will show all the built-in picker types, except the combined primary and accent colors picker type, and the near black and white shades' picker. We will add some custom colors -for the **Custom** colors section of the `ColorPicker`. +for the **Custom** section of the `ColorPicker`. First we define our custom colors and from our color definitions we create primary and accent color swatches by using `ColorTools.createPrimarySwatch`, and for some example colors with the `ColorTools.createAccentSwatch` @@ -327,7 +326,7 @@ swatches from a single color value. }; ``` -We will use another `ListTile` to display a `ColorIndicator`, that we style a bit differently for this example. We also +We will use another `ListTile` to display a `ColorIndicator`, that we style a bit differently in this example. We also use its `onSelect` callback to open a dialog with another `ColorPicker`. As the starting pre-selected color, we will use the `dialogPickerColor` we defined already at the beginning of the tutorial. @@ -369,8 +368,8 @@ we want this color to be visible and not obscured by the dialog. > The above `onSelectFocus` property is used to inform the `ColorIndicator` that we do not want it to keep focus > when we select and click on it in desktop and Web applications. On those platforms it gets focus when we > click on it to open the dialog from it. If it keeps focus while the dialog is open and after the dialog is closed, -> the active focus overlay color will distort its actual color a bit. In that case we cannot observe the selected -> color until we un-focus it. We don't want that, this property addresses this issues by automatically un-focusing +> the active focus overlay color will distort its actual color a bit. In that case, we cannot observe the selected +> color until we unfocus it. We don't want that, this property addresses this issue, by automatically unfocusing > it after we clicked on it. Next we create a method to show a `ColorPicker` with the built-in `colorPickerDialog` dialog method. @@ -378,11 +377,11 @@ The `colorPickerDialog` method is an asynchronous bool function, that returns `t picker with the **OK** or **Select** dialog button. If **Cancel/Close** was selected, or if the user dismissed the dialog by clicking outside it, then `false` is returned. -In this example we first enable a few more color picker types. The `pickersEnabled` property takes a map +In this example, we first enable a few more color picker types. The `pickersEnabled` property takes a map with `ColorPickerType` enum keys to boolean values. The map defines which color pickers we want to enable and use in the `ColorPicker`. -In the example below we included Material **primary**, **accent** colors, and the **custom** colors we defined above, +In the example below, we included Material **primary**, **accent** colors, and the **custom** colors we defined above, plus the HSV **color wheel** that allows us to select any color. We did not include the picker that combines the primary and accent colors in the same picker, nor the near black and near white color picker. @@ -436,6 +435,23 @@ happen to have `ColorPickerType.custom: true` enabled, the custom picker will no customColorSwatchesAndNames: colorsNameMap, ).showPickerDialog( context, + // New in version 3.0.0 custom transitions support. + transitionBuilder: (BuildContext context, + Animation a1, + Animation a2, + Widget widget) { + final double curvedValue = + Curves.easeInOutBack.transform(a1.value) - 1.0; + return Transform( + transform: Matrix4.translationValues( + 0.0, curvedValue * 200, 0.0), + child: Opacity( + opacity: a1.value, + child: widget, + ), + ); + }, + transitionDuration: const Duration(milliseconds: 400), constraints: const BoxConstraints(minHeight: 460, minWidth: 300, maxWidth: 320), ); @@ -444,22 +460,24 @@ happen to have `ColorPickerType.custom: true` enabled, the custom picker will no The above example uses a few more `ColorPicker` properties. It is styled to be more compact and to show the general color name via `showColorName`, as well as the selected color's HEX color code by enabling `showColorCode`. With the -color code field you can also copy the color value to the clipboard using the copy icon button +color code field, you can also copy the color value to the clipboard using the copy icon button suffix in the field. With the wheel picker you can also enter a hex color RGB value in the color code field. The two wheel color HSV selection indicators will move to the color selection matching the entered HEX RGB value. The above example also uses the `copyPasteBehavior` configuration class `ColorPickerCopyPasteBehavior()` with `longPressMenu` set to true, to activate a long press context COPY-PASTE menu in the picker. -Most importantly the above example uses the `showPickerDialog` method to show the defined `ColorPicker` in a -pre-made dialog. The dialog also needs a build context, that we pass to it. +Most importantly, the above example uses the `showPickerDialog` method to show the defined `ColorPicker` in a +pre-made dialog. The dialog also needs a build-context, that we pass to it. + +The above example also demonstrates in version 3.0.0 new custom `transitionBuilder` and `transitionDuration` usage. This part has not been updated to be included in the screen recording below. Please make your own build of the default example to see it. In this example we also define size `constraints` for the dialog. If you do not define size constraints, it will auto size to fit the dialog content. Using constraints allows the dialog to keep the same size when the content size changes slightly as you switch between the different color picker types you enabled. It just looks a bit -better if the dialog size does not change when you switch picker type with the type selector. The color -wheel picker in particular will often require more space. The wheel size can be customized as well, it does -however become more difficult to use if it is made very small. In this example it is on purposes on the +better if the dialog size does not change when you switch picker-type with the type selector. The color-wheel +picker in particular will often require more space. The wheel size can be customized as well. It does, +however, become more difficult to use if it is made very small. In this example, it is on purposes on the lower side of a still usable size. The end result of the above setup is a `ListTile` where the trailing color indicator widget can be clicked to @@ -502,7 +520,7 @@ color manipulation we just did. ## Dialog ColorPicker Function If you do not need the feature that allows you to modify and update colors interactively from the dialog via a -callback, you can use a more straight forward async dialog function API. This function opens the picker +callback, you can use a more straight-forward async dialog function API. This function opens the picker with a pre-selected color and either returns the new selected color when closed with **OK**, or returns the color you opened it with, when closed with **Cancel** action. @@ -513,7 +531,7 @@ wait for `showColorPickerDialog` to return the selected color value. Let's take a look at how this works. As before, first we define another `ListTile` with a trailing `ColorIndicator`. We place it last after the previous two `ListTile`'s in our `ListView`, just before the `ColorPicker` that is in the `Card` in the `ListView`. For the color that we manipulate, we use the `dialogSelectColor` Color that we defined -earlier. In this case the start color value is not a color that exists in the default Material primary and accent +earlier. In this case, the start color value is not a color that exists in the default Material primary and accent color picker or any shade of them. Because the color cannot be found in the pickers with pre-defined colors, the color picker will automatically select the **Wheel** picker and show the start color value we defined in it. @@ -602,13 +620,12 @@ in the `ColorPicker`, that we can use to adjust the opacity from 0 to 100% of th We also set `colorCodeHasColor: true`, this changes the style of the displayed color code field's background color. It will now use the currently selected color as the field's background color. Making it show the color result of our current color selection and opacity slider setting. The opacity slider has a checkered background, -so you can see how opaque the selected opacity value is, when it is used -on top of other widgets or images. +so you can see how opaque the selected opacity value is when it is used on top of other widgets or images. Below you can see the result of this picker setup, and also a demo of how you can copy-paste a selected color. -In the demo below we just copy and pate a color from one dialog picker to another, but you can copy-paste colors -between the picker and any other app. On desktop the app also supports keyboard COPY-PASTE shortcuts. For more +In the demo below, we just copy and pate a color from one dialog picker to another, but you can copy-paste colors +between the picker and any other app. On desktop builds, the app also supports keyboard COPY-PASTE shortcuts. For more information about the COPY-PASTE features, see the API guide's chapter regarding its [features](#copy-paste-actions-and-behavior). @@ -630,12 +647,12 @@ can test the look and operation of the color picker with a dark theme. # API Guide -In addition to what is covered in the above [tutorial](#tutorial), the **FlexColorPicker** has a large amount of +In addition to what is covered in the above [tutorial](#tutorial), the **FlexColorPicker** has a large number of additional features. Its behavior can easily be modified with its direct properties and two additional configuration property classes `ColorPickerActionButtons` and `ColorPickerCopyPasteBehavior`, that can be configured and passed in for even more customization options. -This guide goes through most of the API settings, and provides links to API references. Below we will explore +This guide goes through most of the API settings and provides links to API references. Below we will explore the `ColorPicker` APIs in more detail, and cover both basic and advanced features of the **FlexColorPicker**. @@ -645,7 +662,7 @@ This chapter shows the different visible elements of the color picker that you c extra Widgets to the picker. In [**main example**](#tutorial) and its tutorial, at the core is a passed in `Color()` object to the color picker's -`color` property. It is used to pass in the color that the picker should pre-select. It will update to show the new +`color` property. It is used to pass in the color that the picker should pre-select. It will update, to show the new color if the picker Widget is updated with a new color. The `color` property is **not** required, it defaults to `Colors.blue` if it is omitted, but normally you would give it a starting value based on the color you want to modify. @@ -656,7 +673,7 @@ on your use-case. In the tutorial examples we update the passed in color with `s color is shown in a color indicator widget, in the shape of a colored box or circle. However, in the one of the dialog examples, it was also demonstrated how it can also be used to interactively change -the `AppBar` color of the app itself. You can of use the picker to change any color in +the `AppBar` color of the app itself. You can use the picker to change any color in your application theme, or the color used by any Widget. **The two core properties of the ColorPicker:** @@ -678,7 +695,7 @@ or even remote control, or mirror it completely from another **FlexColorPicker** API reference: [pickersEnabled](https://pub.dev/documentation/flex_color_picker/latest/flex_color_picker/ColorPicker/pickersEnabled.html) -By default, the Material **primary** colors and **accent** colors pickers are enabled. To change the enabled pickers +By default, the Material **primary** colors and **accent** colors pickers are enabled. To change the enabled pickers, you provide a `ColorPickerType` key to `bool` value map, with the pickers you want enabled to the property `pickersEnabled`. You only need to provide key-values pairs for picker keys you want to change. Key values that are not provided use their defaults. @@ -687,22 +704,22 @@ If you only have one picker enabled, there is no sliding segment (tab) control s between different color picker types. That would be pointless, since there is only one color picker. If all pickers are disabled, the Material primary color picker will be shown. -If all other features are disabled (by default they are not), the screenshot below represents an example of a +If all other features are disabled, by default, they are not, then the screenshot below represents an example of a bare-bones **minimum picker**, showing only the main colors of the Material primary colors. If other defaults are OFF, to enable producing this picker style, only the `pickersEnabled` setting to disable the accent color picker is needed to get the shown picker: Pickers 1 -Normally you would enable a few more pickers, below we enable the primary, secondary, near black and white and the wheel +Normally, you would enable a few more pickers. Below we enable the primary, secondary, near black and white and the wheel picker. Since more than one picker is enabled, the color picker selector automatically appears: Pickers 2 -If you want to show both Material primary and accent colors in the same picker you can enable the +If you want to show both Material primary and accent colors in the same picker, you can enable the `ColorPickerType.both` picker. In that case you usually want to disable `ColorPickerType.primary` and `ColorPickerType.accent`, as they contain duplicates of already available colors in the `both` picker. The live -Web demo implements this as exclusive selections in its own logic. It is of course possible to show all three pickers, +Web demo implements this as exclusive selections in its own logic. It is, of course, possible to show all three pickers, but it does not really make much sense. ### Enable Shades Selection @@ -714,7 +731,7 @@ color, is **enabled**. In the above example `enableShadesSelection` had on purpo main only color, very compact color picker example. Below we enable the Material color swatch shades selection. Typically, you want to be able -to also select the Material shade colors. Normally you would just keep the default enabled setting and don't have to +to also select the Material shade colors. Normally, you would just keep the default enabled setting and don't have to use this property at all. You only need this property if you ant to disable the color-shade selection feature, which you do by setting `enableShadesSelection` to false. @@ -724,21 +741,21 @@ which you do by setting `enableShadesSelection` to false. API reference: [enableTonalPalette](https://pub.dev/documentation/flex_color_picker/latest/flex_color_picker/ColorPicker/enableTonalPalette.html) -By default, generation of a selected color's new Material 3 tonal palette is disabled, you can enable +By default, generation of a selected color's new Material 3 tonal-palette is disabled. You can enable it by setting `enableTonalPalette` to true. -When you click/select a color in the color picker and tonal palette is enabled, a 13 shade -Material 3 tonal palette for the selected color will be generated, always starting with black, +When you click/select a color in the color picker and tonal palette is enabled, a 15 shade +Material 3 tonal-palette for the selected color will be generated, always starting with black, tone 0 for the used seed color and ending in white, tone 100. The official Material 3 Dart library is used to create the tonal palette from any selected color. The color you select functions a seed color to generate the tonal -palette and might not itself be included and selected in the palette. You can -of course click on any color in the generated palette to select and pick a color. +palette and might not itself be included and selected in the palette. You can, +of course, click on any color in the generated palette to select and pick a color. -Selecting a color in the tonal palette, only selects the color in the palette, it +Selecting a color in the tonal palette, only selects the color in the palette; it does not update the palette. Only when you select a color from the other color -sources in the picker, is that color used as key, to seed and generate an +sources in the picker, is that color used as key color, to seed and generate an updated color palette for the selected color. For more info on Material 3 Color system, see: @@ -747,10 +764,8 @@ https://m3.material.io/styles/color/the-color-system/key-colors-tones The picker item size for tonal palette color indicator items is 10/13 the size of defined width and height. This is done in order to as far as possible try to match the width of the Primary Material Swatch -items total width, it has 10 colors, the M3 tonal palette has 13 colors. -The idea is try to match their width when they are both shown. - - +items total width. It has 10 colors, the M3 tonal palette has 15 colors. +The goal is to match their width when they are both shown. Tonal pickers 4 @@ -758,7 +773,7 @@ The idea is try to match their width when they are both shown. API reference: [customColorSwatchesAndNames](https://pub.dev/documentation/flex_color_picker/latest/flex_color_picker/ColorPicker/customColorSwatchesAndNames.html) -To use the custom color swatch picker you have to define your own custom `ColorSwatch` colors and pass them to the +To use the custom-color swatch picker, you have to define your own custom `ColorSwatch` colors and pass them to the picker via the `customColorSwatchesAndNames` property. By default, there are no custom colors defined. If you enabled the `custom` picker and have not provided any custom color swatches, the picker will not be shown despite being enabled, since it has no colors to show. @@ -775,8 +790,7 @@ for `createAccentSwatch` for as color for index [200], the rest of the index col To define color data to use with the `customColorSwatchesAndNames` property, to start using the custom color picker, first make a final **Map** with your custom `ColorSwatch` objects, and their color names. -You decide what the colors are called. Here we make three custom colors, with the different -methods. +You decide what the colors are called. Here we use different methods make three custom colors. ```dart final Map, String> customSwatches = @@ -833,12 +847,12 @@ will keep their default labels. API reference: [enableOpacity](https://pub.dev/documentation/flex_color_picker/latest/flex_color_picker/ColorPicker/enableOpacity.html) You can enable a color opacity slider by setting `enableOpacity` to `true`. With the slider you can adjust the opacity -of the selected color. You can adjust opacity from fully opaque at 100%, to totally transparent at 0%. The selected -color and the impact of the opacity value on it, is visualized by the checkered gradient on the opacity slider, +of the selected color. You can adjust opacity from totally opaque at 100%, to totally transparent at 0%. The selected +color and the impact of the opacity value on it are visualized by the checkered gradient on the opacity slider, and the selected color's opacity gradient on the slider. The thumb's position is over the resulting color's opacity when applied over a background. -The slider thumb label only show opacity value changes in 1% increments. However, the slider has 255 discrete steps, +The slider thumb label only shows opacity value changes in 1% increments. However, the slider has 255 discrete steps, so there is a step for every alpha value in the resulting ARGB color value. If the color code value is enabled and set to a format that includes the alpha, you can see that the alpha value can be adjusted in single increments with the slider. @@ -878,7 +892,7 @@ provide your own localized Material color names. For example: Picker 8 >The "name that color" feature, using the lookup from 1566 color names, is only available in English and cannot be -translated in the current version. +translated, in the current version. ### Show Color Code @@ -893,7 +907,7 @@ as a HEX RGB color code **entry** field. The Wheel picker will move its indicato color code, as the entry is done for every entered or deleted character in the field. By default, the code field has a grey background, but you can also configure it to use the current selected color -as its background color. The color code field can also have a copy button as a suffix. This is **enabled by default**, +as its background color. The color code field can also have a copy button as a suffix. This is **enabled by default** it allows you to copy the current color to the clipboard. There are different options for enabling copy-paste commands in the FlexColorPicker and configuring the copy format also shown as prefix in the color code field. These features are described in detail in the [copy-paste actions and behavior](#copy-paste-actions-and-behavior) chapter. @@ -917,12 +931,12 @@ color picker. The list uses first-in, first-out to keep min 2 to max 20 colors ( used colors list, the desired max value can be modified with `maxRecentColors`. Selecting a recently used color, moves the picker to the picker where the color is located and selects it again. If -opacity is enabled, the opacity the color had when it was selected is also applied. Normally when selecting colors and -opacity is enabled, the value the opacity slider is at is kept. However, when selecting a recently used color the +opacity is enabled, the opacity the color had when it was selected is also applied. Normally, when selecting colors and +opacity is enabled, the value the opacity slider is at is kept. However, when selecting a recently used color, the opacity the color had when it was selected and added to the recently used colors list will be used. -Selecting a color on the recently used colors list, will not move it first in the list, it will keep its current -position. Selecting a color that is already on the list, will not add it again. The currently selected color is +Selecting a color on the recently used colors list will not move it first in the list. It will keep its current +position. Selecting a color that is already on the list will not add it again. The currently selected color is not added to the list until you select a new current color. Picker 10 @@ -933,10 +947,10 @@ You can use this callback to save and restore the recently used colors. To initialize the list when the color picker is created, give it a starting list with `recentColors`. This start list could be a list kept in state during the current app session. It is then used -when the color picker is created and re-opened to show same recent colors that were used previously during the +when the color picker is created and re-opened to show the same recent colors that were used previously during the session. The start list could also even have been persisted and restored from a previous session. -The live Web demo persists and restores the recently used colors lists between -sessions, in addition to all the settings, you can use it as an example on how to do this. +The live Web demo persists and restores the recently used colors-lists between +sessions, in addition to all the settings, you can use it as an example of how to do this. ### Title and Heading Widgets @@ -962,7 +976,7 @@ image below, but it would be below the shade `subheading` and equivalent to it. ## Picker Design -The picker design APIs refers to properties that affect size, shape and spacing of the individual color indicator +The picker design APIs refer to properties that affect size, shape and spacing of the individual color indicator Widgets inside the color picker, as well as the color wheel and opacity slider sizing. The [ColorIndicator](https://pub.dev/documentation/flex_color_picker/latest/flex_color_picker/ColorIndicator-class.html) @@ -999,8 +1013,8 @@ API reference: [wheelDiameter, ](https://pub.dev/documentation/flex_color_picker The **wheel** color picker's `wheelDiameter`, `wheelWidth` and border can be modified. The `borderColor` is the same property as the color picker's color items' border, but it has its own enable/disable toggle -`wheelHasBorder` (defaults to false). The color wheel width must be from 4 to 50 dp, and it defaults to 16 dp. The -color wheel diameter must be from 100 to max 500 dp, and it defaults to 190 dp. +`wheelHasBorder` (defaults to false). The color-wheel width must be from 4 to 50 dp, and it defaults to 16 dp. The +color-wheel diameter must be from 100 to max 500 dp, and it defaults to 190 dp. Picker 15 @@ -1031,7 +1045,7 @@ The `columnSpacing` refers to the additional vertical spacing between each eleme picker layout. The `padding` and `crossAxisAlignment` are as typically used in Flutter. Please note that `title` widget is not a part of the `Column` body layout of the color picker, and it is not affected by the `crossAxisAlignment` property. You can think of the `title` a bit like an app bar title. It is always start -aligned to leave enough room for 1 to 4 action buttons. The action buttons can optionally be enabled for the title bar, +aligned to leave enough space for 1 to 4 action buttons. The action buttons can optionally be enabled for the title bar, and they always appear at the end. Picker 12 @@ -1040,30 +1054,30 @@ and they always appear at the end. API reference: [enableTooltips](https://pub.dev/documentation/flex_color_picker/latest/flex_color_picker/ColorPicker/enableTooltips.html) -The `enableTooltips` property defaults to true, and enables all tooltips that are available in the color picker. If the +The `enableTooltips` property defaults to true and enables all tooltips that are available in the color picker. If the tooltips get in the way, you can disable them all by setting this property to `false`. Why not consider providing a property in your app that allows users to turn ON and OFF all the tooltips in the app? **FlexColorPicker** -includes this toggle to make that easy to implement when it comes to its own tooltip behavior. +includes this toggle to make this easy to implement when it comes to its own tooltip behavior. The tooltip strings used in FlexColorPicker are all based on existing labels in Flutter SDK and by default use -Material localizations and thus change with the locale. Via that, they support all languages that Flutter does out +Material localizations and thus change with the locale. By doing this, they support all languages that Flutter does out of the box. You can still override the tooltip labels if so required and provide your own tooltip labels. -The following tooltips exist, and have the default values shown in the table below. +The following tooltips exist and use the default values shown in the table below. -| Usage | English tooltip | Used MaterialLocalizations.of(context) | -| --- | --- | --- | -| Copy button | Copy | copyButtonLabel | -| Paste button | Paste | pasteButtonLabel | -| OK button | OK | okButtonLabel | -| Cancel button | Cancel | cancelButtonLabel | -| Close button | Close | closeButtonLabel | +| Usage | English tooltip | Used MaterialLocalizations.of(context) | +|---------------|-----------------|----------------------------------------| +| Copy button | Copy | copyButtonLabel | +| Paste button | Paste | pasteButtonLabel | +| OK button | OK | okButtonLabel | +| Cancel button | Cancel | cancelButtonLabel | +| Close button | Close | closeButtonLabel | Picker 14 When the keyboard copy/paste shortcuts are enabled, the Copy and Paste tooltips automatically -also receive platform aware keyboard shortcut info, after the localized tooltip label. On macOS +also receive platform aware keyboard-shortcut info, after the localized tooltip label. On macOS ' (CMD-C)' is appended to the copy tooltip and ' (CMD-V)' is appended to the paste tooltip. On other platforms ' (CTRL-C)' is appended to the copy tooltip and ' (CTRL-V)' to the paste tooltip. @@ -1071,8 +1085,9 @@ On other platforms ' (CTRL-C)' is appended to the copy tooltip and ' (CTRL-V)' t API reference: [ColorPickerActionButtons](https://pub.dev/documentation/flex_color_picker/latest/flex_color_picker/ColorPickerActionButtons-class.html) -The API surface of the color picker was getting quite large, therefore two less used configuration classes were -created to group additional settings. The first one is the `ColorPickerActionButtons` used to define the color picker's +The API surface of the color picker was getting quite large. Therefore, two configuration classes are +used to configure additional less frequently used settings. The first one is the +`ColorPickerActionButtons` used to define the color picker's OK and Cancel action buttons, and their style when they are used by the built-in dialogs. You use it by passing in a `ColorPickerActionButtons` configuration to the `ColorPicker()`'s property `actionButtons`: @@ -1087,26 +1102,26 @@ area. The top toolbar buttons are plain icon only buttons. For the bottom dialog `TextButton`, `OutlinedButton` and `ElevatedButton` for each button. The used icons can be changed from default ones, as can their used tooltips. The labels on the bottom -action buttons can also be changed. By the default they, like the tooltips, use Material localizations, so they +action buttons can also be changed. By default, they, like the tooltips, use Material localizations, so they work well enough out of the box for most locales. The bottom action buttons can also use the default or customized OK and Cancel **icons as prefix** icons to the labels. These icons are always shared with the corresponding icons defined for the top toolbar icon buttons. The recommendation is to **not** use the top and bottom action buttons at the same time, but rather select one of the -two options. The API does however allow using both or even a mix and match. It is for example possible to +two options. The API does, however, allow us to use both, or even a mix and match. It is, for example, possible to show **Cancel** and **OK** actions at the bottom of the dialog, and also add just the 'x' close icon in the upper -end corner of the dialog. This 'x' icon then also cancel closes the dialog as expected, this is a usable combination. -Adding the **OK** icon button (by default a check icon) as a select close button to the top toolbar is a bit -unconventional, if you also have the OK as a bottom action. Without it enabled, the OK and Close buttons +end corner of the dialog. This 'x' icon then also cancel closes the dialog as expected. This is a useful combination. +Adding the **OK** icon button, by default a check icon, as a close button to the top toolbar is a bit +unconventional, if you also have the OK button as a bottom action. Without it enabled, the OK and Close buttons on the toolbar are a nice and compact alternative to selecting color or cancelling the dialog. Picker 17 The bottom action buttons, and their style depend on their ambient theme. -There are more dialog action buttons design properties you can adjust, you can for example change +There are more dialog action buttons design properties you can adjust, you can, for example, change the order of the OK and Cancel action, or have it be platform adaptive. -By default OK is on the right. Please see the +By default, OK is on the right. Please see the [ColorPickerActionButtons API reference](https://pub.dev/documentation/flex_color_picker/latest/flex_color_picker/ColorPickerActionButtons-class.html) for additional details. @@ -1114,7 +1129,7 @@ for additional details. API reference: [ColorPickerCopyPasteBehavior](https://pub.dev/documentation/flex_color_picker/latest/flex_color_picker/ColorPickerCopyPasteBehavior-class.html) -The `ColorPickerCopyPasteBehavior` is the second configuration class group. It is used to configure the desired +The `ColorPickerCopyPasteBehavior` is the second configuration-class group. It is used to configure the desired COPY-PASTE behavior of the color picker. You use it by passing in a `ColorPickerCopyPasteBehavior` configuration to the `ColorPicker()`'s property `copyPasteBehavior`: @@ -1126,16 +1141,16 @@ ColorPicker( You can control if the picker has: * Copy and paste action buttons in the top toolbar. -* Long press and/or right click copy and paste context menu. +* Long press and/or right click copy and paste context-menu. * Ctrl-C and Ctrl-V keyboard shortcuts, also when not in edit field. - Keyboard shortcuts automatically uses Command instead of Ctrl on macOS. + Keyboard shortcuts automatically use Command instead of Ctrl on macOS. * A copy color action button in the code entry and display field. You can also: -* Define default result RGB string format for the copy command. +* Define a default result RGB string-format, for the copy command. * Define icons for copy and paste action buttons. -* Define icon theme for the copy and paste icons. -* Define paste color string parsing error feedback type and message if used. +* Define an icon-theme for the copy and paste icons. +* Define paste color-string parsing error feedback-type and message if used. * Modify the tooltips for copy and paste buttons. Paste operation supports all RGB string formats defined by @@ -1146,7 +1161,7 @@ but the copy format is only in the selected `copyFormat`. API reference: [editFieldCopyButton](https://pub.dev/documentation/flex_color_picker/latest/flex_color_picker/ColorPickerCopyPasteBehavior/editFieldCopyButton.html) -The color code display and entry field suffix **color copy icon button**, is enabled by default. This +The color code display and entry field suffix **color copy icon button** are enabled by default. This button existed already in version 1.x. It can now if so desired be removed by setting `ColorPickerCopyPasteBehavior.editFieldCopyButton` to false. @@ -1161,16 +1176,16 @@ When `ctrlC` and `ctrlV` properties are set to `true`, by default they are, a CT desktop keyboard will copy the currently selected color's RGB color code to the clipboard. A CTRL/CMD-V will paste the current clipboard text into the picker. The color picker will then try to parse the pasted value as a color value and move to display the pasted color with the most suitable available picker. The CTRL keyboard modifier is used on -Windows and Linux desktop OS and the CMD modifier is used on macOS and iOS. +Windows and Linux desktop OS, and the CMD modifier is used on macOS and iOS. -When enabled, the keyboard copy color shortcuts work when one of the ColorPicker's focusable widgets have focus. +When enabled, the keyboard copy color shortcuts work when one of the ColorPicker's focusable widgets has focus. These include the color indicators, color field, buttons, and the picker selector, as well as the color wheel. When the -picker is used in a modal dialog, one of these widgets will typically always have focus. If the picker is used in -layouts on the main surface, where other widgets may have focus, the keyboard shortcuts will not work until +picker is used in a modal dialog, one of its widgets will typically always have focus. If the picker is used in +layouts on the main surface, where other widgets may have focus, the keyboard shortcuts will not work until one of the color picker's focusable widgets gets focus. When the keyboard copy/paste shortcuts are enabled, the Copy and Paste tooltips by default -also receive platform aware keyboard shortcut info. After the localized default tooltip label, on macOS +also receive platform aware keyboard-shortcut info. After the localized default tooltip label, on macOS ' (CMD-C)' is appended to the copy tooltip and ' (CMD-V)' is appended to the paste tooltip. On other platforms ' (CTRL-C)' is appended to the copy tooltip and ' (CTRL-V)' to the paste tooltip. This is shown in the example in the next chapter. @@ -1209,9 +1224,9 @@ enable a context like COPY-PASTE menu that can be triggered either via a long pr typically the right mouse button. The secondary right click is often a good option on Windows and Linux desktop apps, to some extent it may also work -on desktop web browsers. However, desktop browsers' built in right click menu also tend to ge triggered by it. +on desktop web browsers. However, desktop browsers' built-in right-click menu also tends to ge triggered by it. This menu may get in the way of the color picker's COPY-PASTE menu when secondary click is used in -a desktop Web browser. On touch only devices, or other use cases when a mouse right click is not optimal, +a desktop Web browser. On touch-only devices, or other use cases when a mouse right click is not optimal, the long press option to show the COPY-PASTE menu may work better. Set property `secondaryMenu` to `true` (defaults to false), to enable using secondary button click anywhere in @@ -1221,21 +1236,21 @@ Set property `longPressMenu` to `true` (defaults to false) to enable using long picker, to open up the COPY-PASTE context menu. Set property `secondaryOnDesktopLongOnDevice` to `true` (defaults to false), to enable using long press in the color -picker, to open up the COPY-PASTE context menu on iOS and Android touch devices. While using secondary mouse button -on desktop platforms Windows, Mac and Linux and their web variants. +picker to open up the COPY-PASTE context menu on iOS and Android touch devices. While using secondary mouse-button click +on desktop platforms Windows, Mac and Linux, as well as on desktop-based web browsers. Set property `secondaryOnDesktopLongOnDeviceAndWeb` to `true` (defaults to false), to enable using long press in the color picker, to open up the COPY-PASTE context menu on Web, iOS and Android touch devices. While using secondary mouse button on desktop platforms Windows, Mac and Linux, but not if it is a desktop web app. -> Due to secondary mouse button on desktop Web browsers often activating the browser's own +> Due to secondary-button on desktop Web browsers often activating the browser's own > secondary-button context menu, the `secondaryOnDesktopLongOnDevice` option may not be ideal for desktop -> web browsers. You may want to use `secondaryOnDesktopLongOnDeviceAndWeb` option instead to avoid right click -> menu on web desktop automatically, and thus automatically prefer long press on it as well. +> web browsers. You may want to use `secondaryOnDesktopLongOnDeviceAndWeb` option instead to avoid right-click +> menus on web desktop automatically, and thus automatically prefer long press on it as well. Picker 20 -If you want to style and customize the look of the popup menu, it can also be done. Please refer to the following +If you want to style and customize the look of the popup-menu, it can also be done. Please refer to the following APIs [menuThemeData](https://pub.dev/documentation/flex_color_picker/latest/flex_color_picker/ColorPickerCopyPasteBehavior/menuThemeData.html), [menuWidth](https://pub.dev/documentation/flex_color_picker/latest/flex_color_picker/ColorPickerCopyPasteBehavior/menuWidth.html), [menuItemHeight](https://pub.dev/documentation/flex_color_picker/latest/flex_color_picker/ColorPickerCopyPasteBehavior/menuItemHeight.html), and @@ -1252,19 +1267,19 @@ API reference: [copyFormat, ](https://pub.dev/documentation/flex_color_picker/la [feedbackParseError.](https://pub.dev/documentation/flex_color_picker/latest/flex_color_picker/ColorPickerCopyPasteBehavior/feedbackParseError.html) [**copyFormat**](https://pub.dev/documentation/flex_color_picker/latest/flex_color_picker/ColorPickerCopyPasteBehavior/copyFormat.html) -The color code display and edit field's value can be shown in five different formats by the setting the + The color code display and edit field's value can be shown in five different formats by the setting the `copyformat` enum [ColorPickerCopyFormat](https://pub.dev/documentation/flex_color_picker/latest/flex_color_picker/ColorPickerCopyFormat-class.html) to desired format value. The `copyFormat` **also** defines the received string format of the copied RGB value when **any** of the copy functions are used. It defaults to `ColorPickerCopyFormat.dartCode`. -| ColorPickerCopyFormat | Resulting format | -| --- | --- | -| dartCode | Flutter Hex RGB format '0xAARRGGBB' (**default**)| -| hexRRGGBB | Hex RGB format with no alpha 'RRGGBB' | -| hexAARRGGBB | Hex RGB format with alpha 'AARRGGBB' | -| numHexRRGGBB | Web Hex RGB format with a leading num # sign and no alpha '#RRGGBB' | -| numHexAARRGGBB | Web Hex RGB format with a leading num # sign and alpha '#AARRGGBB' | +| ColorPickerCopyFormat | Resulting format | +|-----------------------|---------------------------------------------------------------------| +| dartCode | Flutter Hex RGB format '0xAARRGGBB' (**default**) | +| hexRRGGBB | Hex RGB format with no alpha 'RRGGBB' | +| hexAARRGGBB | Hex RGB format with alpha 'AARRGGBB' | +| numHexRRGGBB | Web Hex RGB format with a leading num # sign and no alpha '#RRGGBB' | +| numHexAARRGGBB | Web Hex RGB format with a leading num # sign and alpha '#AARRGGBB' | When pasting color RGB text string values into the color picker, any of the above formats are always accepted and parsed to its color value. @@ -1280,10 +1295,10 @@ If alpha values are not included in a pasted hex char string, it is always set t is not enabled for the color picker, then the alpha value included in the pasted color string value will be replaced with 'FF' or fully opaque. -[**parseShortHexCode**](https://pub.dev/documentation/flex_color_picker/latest/flex_color_picker/ColorPickerCopyPasteBehavior/parseShortHexCode.html) +[**parseShortHexCode**](https://pub.dev/documentation/flex_color_picker/latest/flex_color_picker/ColorPickerCopyPasteBehavior/parseShortHexCode.html) The color picker's paste parser can optionally also interpret 3-char hex code as done by CSS/WEB. This is enabled by setting `parseShortHexCode` to `true` (defaults to false). When true, the hex color code paste action and field -entry parser will interpret short three character web hex color codes like it is done in CSS/WEB. This results in +entry parser will interpret short three character web hex color codes like when using CSS/WEB. This results in short HEX RGB color codes, like 123, ABC, F0C and 5D1 being interpreted as 112233, AABBCC, FF00CC and 55DD11. [**editUsesParsedPaste**](https://pub.dev/documentation/flex_color_picker/latest/flex_color_picker/ColorPickerCopyPasteBehavior/editUsesParsedPaste.html) @@ -1296,7 +1311,7 @@ chars (0-9, A-F). It thus always filters out and pastes only the acceptable inpu When `editUsesParsedPaste` property is `true`, the edit field will use the same color paste value parser that is used by the other paste actions when the input field is not in focus. This results in a paste action in the entry field that always fully replaces the content, with the parsed color value of the pasted string data. It does not paste in the -string in the paste buffer into the text field, it changes it to its parsed value, converted back to a string. +string, in the paste buffer into the text field, it changes it to its parsed value, converted back to a string. Currently, this setting only impacts CTRL-V and CMD-V keyboard shortcut pasting on desktops. The paste on Android and iOS are not intercepted when this setting is true. The false setting is equivalent to past versions (1.x) default behavior when pasting strings into the code entry field. @@ -1313,15 +1328,14 @@ The `snackBarMessage` defines the text message label shown in the paste parse er label is shown in the snack bar when there is a paste parse error, and `snackBarParseError` is true. If the `snackBarMessage` is not defined (is null), it defaults to the combination of the two Material localization -labels `pasteButtonLabel`: `invalidDateFormatLabel`. In English this will it say -**Paste: Invalid format**. The snackbar uses the closest ambient theme with SnackBarThemeData for its theming. +labels `pasteButtonLabel`: `invalidDateFormatLabel`. In English, this will it say +**Paste: Invalid format**. The `Snackbar`, uses the closest ambient theme with `SnackBarThemeData` for its theming. Below an example of a `copyformat`, `parseShortHexCode`, `editUsesParsedPaste` and `snackBarParseError` configuration, and a snack bar parse error message. Picker 21 - [**snackBarDuration**](https://pub.dev/documentation/flex_color_picker/latest/flex_color_picker/ColorPickerCopyPasteBehavior/snackBarDuration.html) The duration the paste parse error snack bar message is shown can be set via `snackBarDuration`. It defaults to `const Duration(milliseconds: 1800)`. @@ -1335,7 +1349,6 @@ supports the Material Sound Guide sounds, this feature can be improved with bett be improved without importing none SDK plugins/packages to make sounds. This package strives to work without any plugins or packages, so it will not add any none Flutter SDK imports. (Defaults to `false`). - ## onChange Callbacks API reference: [onColorChanged, ](https://pub.dev/documentation/flex_color_picker/latest/flex_color_picker/ColorPicker/onColorChanged.html) @@ -1350,22 +1363,22 @@ not needed. If they are null, they will not be called. [**onColorChanged**](https://pub.dev/documentation/flex_color_picker/latest/flex_color_picker/ColorPicker/onColorChanged.html) A required `ValueChanged` callback, called when user selects a new color with the selected new color value. -Called every time the color value changes via a color selection click, when operating thumbs on the color wheel, or -transparency sliders, or entering a new character in the color code field. Changing which picker type is viewed does not +Called every time, the color value changes via a color selection click. When operating thumbs on the color wheel, or +transparency sliders, or entering a new character in the color code field. Changing which picker-type is viewed does not trigger this callback, it is not triggered until a color in the viewed picker is selected. [**onColorChangeStart**](https://pub.dev/documentation/flex_color_picker/latest/flex_color_picker/ColorPicker/onColorChangeStart.html) Optional `ValueChanged` callback. Called when user starts color selection with current color value, before the new color selection is applied. When clicking a new color in color items, the color value before the selected -new value was clicked is thus returned. It is also called with the current color when user starts the interaction +new value was clicked is thus returned. It is also called with the current color, when the user starts the interaction on the color wheel, or the transparency slider. [**onColorChangeEnd**](https://pub.dev/documentation/flex_color_picker/latest/flex_color_picker/ColorPicker/onColorChangeEnd.html) Optional `ValueChanged` callback. Called when user ends color selection with the new color value. -When clicking a new color on color items, the clicked color is returned, the change basically ends after first click. -The callback's main purpose is when it is called with the resulting color value, when user ends the interaction on -the color wheel or the transparency slider, with the final color value. The purpose of the callback is to indicate -when such interaction ended. The `onColorChanged` and `onColorChangeEnd` will always end with the same returned +When clicking a new color on color items, the clicked color is returned at once, as the change ends directly after first click. +The callback's main purpose is, when it is called with the resulting color value, when the user ends the interaction on +the color-wheel or the transparency slider, to inform us when such interaction ended. The +`onColorChanged` and `onColorChangeEnd` will always end with the same returned color value, but `onColorChangeEnd` only when the interaction on the wheel and sliders have ended, with only the final result from the interaction. @@ -1377,11 +1390,11 @@ may not want to log. If it is applicable to the use-case, then using the `showCo [here](#function-showcolorpickerdialog), is another way around this when logging is used. It is worth noticing that for keyboard color code entry, as each entry also changes the selected color interactively -for every entered character, we cannot know when the editing is actually done. Thus keyboard entries generate start +for every entered character, we cannot know when the editing is actually done. Thus, keyboard entries generate start and end events for every char input, just as when selecting a color by clicking on direct color items or when pasting in a new color. -You can use you the [LIVE web example](https://rydmike.com/flexcolorpicker/#/) to observe and study the behavior of the +You can use the [LIVE web example](https://rydmike.com/flexcolorpicker/#/) to observe and study the behavior of the above callbacks when you use the picker. The demo includes trackers that show their behavior. Picker 22 @@ -1392,21 +1405,21 @@ Optional `ValueChanged>` callback that returns the current list of r This optional callback is called every time a new color is added to the recent colors list with the complete current list of recently used colors. If the optional callback is not provided, then it is not called. You can use this callback to save and restore the recently used colors. To initialize the list when the color picker -is created give it a starting value via `recentColors`. This could be a list kept just in state during +is created, give it a starting value via `recentColors`. This could be a list kept just in state during the current app session, or it could have been persisted and restored from a previous session. ## Dialogs -The **FlexColorPicker** comes with two built-in ready to use dialogs. You can also make your own custom dialogs by +The **FlexColorPicker** comes with two built-in dialogs. You can also make your own custom dialog by including the `ColorPicker()` in your own dialog or overlays designs. In this chapter we will look at the two built-in -dialogs, that are really the same dialog, but designed for slightly different use cases. +dialogs. They are really using the same dialog under the hood, but they are intended different use cases. ### ColorPicker showPickerDialog Method API reference: [showPickerDialog](https://pub.dev/documentation/flex_color_picker/latest/flex_color_picker/ColorPicker/showPickerDialog.html) -This dialog allows you track the ColorPicker's different **onChange** callbacks when the dialog is open and colors are -being manipulated and react to the changes as they happen. You can use this to for example interactively change color -properties of the application's Widgets and even its theme. You can see the effect of changes applied as a new color is +This dialog allows you to track the ColorPicker's different **onChange** callbacks when the dialog is open, as colors are +being manipulated, and to react to the changes as they happen. You can use this to interactively change color +properties of the application's Widgets and even its entire theme. You can see the effect of changes applied as a new color is selected in the dialog picker, even while dragging the wheel and sliders. The `showPickerDialog` dialog demo in the default example app shown earlier [here](#dialog-colorpicker-method) @@ -1414,15 +1427,15 @@ explains how to use the built-in [ColorPicker(...).showPickerDialog](https://pub.dev/documentation/flex_color_picker/latest/flex_color_picker/ColorPicker/showPickerDialog.html) method. -The disadvantage with this dialog is that to maintain the state yourself. You have to store color before you open the -dialog and restore this color if the dialog is cancelled, instead of a color selected. The API can also be a bit -cumbersome to use, the above example demonstrates how to do it. +The disadvantage of this dialog is that you have to maintain the state yourself. You have to store the color before you open the +dialog, and restore this color if the dialog is cancelled, instead of a color selected. The API can also be a bit +cumbersome to use. The above example demonstrates how to do it. ### Function showColorPickerDialog API reference: [showColorPickerDialog](https://pub.dev/documentation/flex_color_picker/latest/flex_color_picker/showColorPickerDialog.html) -The `showColorPickerDialog` function is often simpler to use. Just pass in a build context for the dialog, and the +The `showColorPickerDialog` function is often simpler to use. Just pass in a build-context for the dialog, and the required start color value. Call the function, with needed color picker and dialog setup properties, and await for it to return the selected color when the dialog is closed. If no color is selected, when the dialog is cancelled or dismissed, then it just returns the passed in start color. @@ -1433,19 +1446,19 @@ even closed. It also cannot return the list of recently selected colors, but you set of recently selected colors. Potentially the callback for the recently used colors lists could be added to the `showColorPickerDialog`'s exposed APIs, it is however currently not exposed. -In many cases when you just need to open a picker dialog, to select a color, or cancel the selection and move on, this +In many cases, when you just need to open a picker dialog to select a color and move on, this version offers a simpler API for that. Under the hood it is just a wrapper for the other version with the on change callbacks. It thus shares all other properties and features with the `ColorPicker`, combined with its `showPickerDialog` method. -The `showColorPickerDialog` dialog demo in the default example app shown earlier [here](#dialog-colorpicker-function) +The `showColorPickerDialog` dialog demo in the default example app shown [earlier](#dialog-colorpicker-function), explains how to use the built-in [ColorPicker(...).showColorPickerDialog](https://pub.dev/documentation/flex_color_picker/latest/flex_color_picker/showColorPickerDialog.html) function. Since the properties `elevation` and `title`, in the `showPickerDialog` method would collide with the same named ones in the `ColorPicker`, the dialog's elevation and title in `showColorPickerDialog` are instead -called `dailogElevation` and `dialogTitle`. This is to avoid the property name conflict when they are +called `dailogElevation` and `dialogTitle`. This is to avoid name conflicts when they are present in the same function. # Desktop and Web Ready @@ -1455,35 +1468,43 @@ Here is an example of the demo application running on Windows desktop. ColorPicker on Windows -The live [Web demo](https://rydmike.com/flexcolorpicker/) is of course an example of it running in a Web environment. -For the major part the color picker runs well with either +The live [Web demo](https://rydmike.com/flexcolorpicker/) is an example of it running and being used in a Web build. +For the major part, the color picker runs well with either [Flutter Web renderer](https://flutter.dev/docs/development/tools/web-renderers), HTML or CanvasKit. If the color picker's opacity slider feature is used on WEB builds `enableOpacity: true`, then you -must build using the SKIA **canvaskit** renderer only. The opacity slider uses `ImageShader`, a Flutter API that -is not yet available on **html** builds, at least not in version stable 2.2.1. +may prefer build using the SKIA **canvaskit** renderer only. The opacity slider uses `ImageShader`, +a Flutter API that is not available on **html** builds in older Flutter versions. It was not +available not in stable version 2.2.1. + ``` flutter run -d chrome --web-renderer canvaskit flutter build web --web-renderer canvaskit ``` -The FlexColorPicker goes a bit further than just working on Web and Desktop. For example, pick item focusing + +> **UPDATE Feb 18, 2022:** When using Flutter stable version 2.10.1, the `ImageShader` API +> seems to be available and working also when using --web-renderer html, build. However, if you +> run into issues with the opacity slider on web builds, prefer using canvaskit instead of auto or +> html renderer when you use the `ColorPicker` in web apps and enable the opacity slider. + +The **FlexColorPicker** goes a bit further than just working on web and desktop builds. For example, pick item focusing behaves as can be expected. The picker supports keyboard navigation and control selection and control activation, especially when it is used in a dialog where other controls on the screen do not affect the intended keyboard navigation order. As mentioned in the API guide, if the picker is so configured, it also has keyboard shortcuts for copy and paste commands, that even adapt to the used desktop platform. -The wheel picker cannot be operated with just a keyboard, it needs a mouse or touch control. It will remain so, as it -is not a design well suited to keyboard control, it is designed to require a mouse or touch input to be operated. +The wheel-picker cannot be operated with just a keyboard, it needs a mouse or touch control. It will remain so, as it +is not a design well suited for keyboard control. It is designed to require a mouse or touch-input to be operated. -The opacity slider can be operated via keyboard controls too. Future picker options will offer additional advanced -color picker type, designed using only sliders for selecting any custom color. This design will enable this -picker to use keyboard controls to define and select any color. +The opacity slider can be operated via keyboard controls too. Future picker options may offer additional, advanced +color picker types, designed using only sliders for selecting any custom color. This design will be able to +use keyboard controls to define and select any color. The currently used color picker type selection control is based on the `CupertinoSlidingSegmentedControl` widget. -It unfortunately does not support keyboard control. A future version may include additional optional picker type +It unfortunately does not support keyboard control. A future version may include additional picker-type selection controls, that support keyboard navigation and picker "tab" selection. When such controls are added, the -current version will remain available as default for backwards compatibility. +current version will remain available as default for backward compatibility. # Additional Resources @@ -1492,10 +1513,10 @@ API guide, please use the complete [API doc reference](https://pub.dev/documenta additional information. The source code of the [live Web example](https://rydmike.com/flexcolorpicker/) is included in the package example -folder, in "example/lib/demo". By studying it, you can see a practical examples of how to use all the features +folder, in "example/lib/demo". By studying it, you can see a practical example of how to use all the features it uses. The live Web demo also has tooltips showing the used API behind every demonstrated interactive control. This can be used as quick reference and to find the actual used API-value as you interactively configure the Web example. -**Happy color picking!** +**Happy color picking!** \ No newline at end of file diff --git a/example/lib/main.dart b/example/lib/main.dart index 7f7a215..f2467f4 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -99,9 +99,12 @@ class _ColorPickerPageState extends State { body: ListView( padding: const EdgeInsets.fromLTRB(8, 0, 8, 0), children: [ + const SizedBox(height: 16), // Pick color in a dialog. ListTile( - title: const Text('Click this color to modify it in a dialog'), + title: const Text('Click this color to modify it in a dialog. ' + 'The color is modified while dialog is open, but returns ' + 'to previous value if dialog is cancelled'), subtitle: Text( // ignore: lines_longer_than_80_chars '${ColorTools.materialNameAndCode(dialogPickerColor, colorSwatchNameMap: colorsNameMap)} ' @@ -127,7 +130,9 @@ class _ColorPickerPageState extends State { ), ), ListTile( - title: const Text('Click to select a new color from a dialog'), + title: const Text('Click to select a new color from a dialog ' + 'that uses custom open/close animation. The color is only ' + 'modified after dialog is closed with OK'), subtitle: Text( // ignore: lines_longer_than_80_chars '${ColorTools.materialNameAndCode(dialogSelectColor, colorSwatchNameMap: colorsNameMap)} ' @@ -171,6 +176,22 @@ class _ColorPickerPageState extends State { closeButton: true, dialogActionButtons: false, ), + transitionBuilder: (BuildContext context, + Animation a1, + Animation a2, + Widget widget) { + final double curvedValue = + Curves.easeInOutBack.transform(a1.value) - 1.0; + return Transform( + transform: Matrix4.translationValues( + 0.0, curvedValue * 200, 0.0), + child: Opacity( + opacity: a1.value, + child: widget, + ), + ); + }, + transitionDuration: const Duration(milliseconds: 400), constraints: const BoxConstraints( minHeight: 480, minWidth: 320, maxWidth: 320), ); @@ -229,7 +250,7 @@ class _ColorPickerPageState extends State { ), // Theme mode toggle - SwitchListTile.adaptive( + SwitchListTile( title: const Text('Turn ON for dark mode'), subtitle: const Text('Turn OFF for light mode'), value: isDark, diff --git a/lib/src/color_picker.dart b/lib/src/color_picker.dart index 0551b8d..86b2676 100644 --- a/lib/src/color_picker.dart +++ b/lib/src/color_picker.dart @@ -1,3 +1,5 @@ +// ignore_for_file: comment_references + import 'package:flutter/cupertino.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; @@ -683,8 +685,13 @@ class ColorPicker extends StatefulWidget { /// /// The [showPickerDialog] method is a convenience function to show the /// [ColorPicker] widget in a modal dialog. It re-implements the standard - /// `showDialog` function with opinionated Cancel and OK buttons. It - /// also by default uses a lighter barrier color. This is useful if the + /// [showDialog] function with opinionated Cancel and OK buttons. + /// + /// If a [transitionBuilder] is provided the [showPickerDialog] instead uses + /// a [showGeneralDialog] implementation to show the [ColorPicker], this + /// allows for customization of the show animation. + /// + /// It also by default uses a lighter barrier color. This is useful if the /// color picker is used to dynamically change color of a widget or entire /// application theme, since we can then better see the impact of the color /// choice behind the modal dialog when the barrier is made almost fully @@ -848,6 +855,21 @@ class ColorPicker extends StatefulWidget { /// Offset anchorPoint for the dialog. Offset? anchorPoint, + /// The [transitionBuilder] argument is used to define how the route + /// arrives on and leaves off the screen. + /// + /// If this transition is not specified, the default Material platform + /// transition builder for [showDialog] is used. + RouteTransitionsBuilder? transitionBuilder, + + /// The [transitionDuration] argument is used to determine how long it takes + /// for the route to arrive on or leave off the screen. + /// + /// It only has any effect when a custom `transitionBuilder`is used. + /// + /// This argument defaults to 200 milliseconds. + Duration transitionDuration = const Duration(milliseconds: 200), + /// You can provide BoxConstraints to constrain the size of the dialog. /// /// You might want to do this at least for the height, otherwise @@ -969,7 +991,9 @@ class ColorPicker extends StatefulWidget { actionButtons.dialogActionOrder == ColorPickerActionButtonOrder.okIsLeft; - final AlertDialog pickerDialog = AlertDialog( + // Put or [ColorPicker] instance `this` in an `AlertDialog` using all + // to it assigned and above defined properties. + Widget dialog = AlertDialog( title: title, titlePadding: titlePadding, titleTextStyle: titleTextStyle, @@ -1002,22 +1026,65 @@ class ColorPicker extends StatefulWidget { scrollable: true, ); - await showDialog( + // No `transitionBuilder` give, then use + // the platform and Material2/3 dependent default MaterialPage route + // transition via `showDialog`, as in all versions before 3.0.0. + if (transitionBuilder == null) { + await showDialog( + context: context, + barrierDismissible: barrierDismissible, + barrierColor: barrierColor, + barrierLabel: barrierLabel, + useSafeArea: useSafeArea, + useRootNavigator: actionButtons.useRootNavigator, + routeSettings: routeSettings, + anchorPoint: anchorPoint, + builder: (BuildContext context) { + return dialog; + }).then((bool? value) { + // If the dialog return value was null, then we got here by a + // barrier dismiss, then we set the return value to false. + colorWasSelected = value ?? false; + }); + } + // If a `transitionBuilder` is given, we use `showGeneralDialog` using the + // given `transitionBuilder` and a custom `pageBuilder`, conditionally + // wrapping `SafeArea` around or AlertDialog widget and capturing the + // current theme that we and wrapping it around the page builder. + else { + final CapturedThemes themes = InheritedTheme.capture( + from: context, + to: Navigator.of( + context, + rootNavigator: true, + ).context, + ); + if (useSafeArea) { + dialog = SafeArea(child: dialog); + } + await showGeneralDialog( context: context, barrierDismissible: barrierDismissible, barrierColor: barrierColor, - barrierLabel: barrierLabel, - useSafeArea: useSafeArea, + barrierLabel: barrierLabel ?? + MaterialLocalizations.of(context).modalBarrierDismissLabel, useRootNavigator: actionButtons.useRootNavigator, routeSettings: routeSettings, anchorPoint: anchorPoint, - builder: (BuildContext context) { - return pickerDialog; - }).then((bool? value) { - // If the dialog return value was null, then we got here by a - // barrier dismiss, then we set the return value to false. - colorWasSelected = value ?? false; - }); + transitionBuilder: transitionBuilder, + transitionDuration: transitionDuration, + pageBuilder: (BuildContext context, Animation animation1, + Animation animation2) { + return themes.wrap(Builder( + builder: (BuildContext context) => dialog, + )); + }, + ).then((bool? value) { + // If the dialog return value was null, then we got here by a + // barrier dismiss, then we set the return value to false. + colorWasSelected = value ?? false; + }); + } return colorWasSelected; } } @@ -1193,8 +1260,10 @@ class _ColorPickerState extends State { // Picker labels map changed, update used one, with its default fallbacks. if (!mapEquals(widget.pickerTypeLabels, oldWidget.pickerTypeLabels)) { if (_debug) { - debugPrint('didUpdateWidget pickerTypeLabels mapEquals: ' - '${mapEquals(widget.pickerTypeLabels, oldWidget.pickerTypeLabels)}'); + debugPrint( + 'didUpdateWidget pickerTypeLabels mapEquals: ' + '${mapEquals(widget.pickerTypeLabels, oldWidget.pickerTypeLabels)}', + ); } _pickerLabels = { ColorPickerType.both: widget.pickerTypeLabels[ColorPickerType.both] ?? diff --git a/lib/src/show_color_picker_dialog.dart b/lib/src/show_color_picker_dialog.dart index 8324a40..f40d5bd 100644 --- a/lib/src/show_color_picker_dialog.dart +++ b/lib/src/show_color_picker_dialog.dart @@ -1,3 +1,5 @@ +// ignore_for_file: comment_references + part of 'color_picker.dart'; /// Define a color picker, show its dialog and wait for it to return a color. @@ -600,6 +602,21 @@ Future showColorPickerDialog( /// Offset anchorPoint for the dialog. Offset? anchorPoint, + /// The [transitionBuilder] argument is used to define how the route + /// arrives on and leaves off the screen. + /// + /// If this transition is not specified, the default Material platform + /// transition builder for [showDialog] is used. + RouteTransitionsBuilder? transitionBuilder, + + /// The [transitionDuration] argument is used to determine how long it takes + /// for the route to arrive on or leave off the screen. + /// + /// It only has any effect when a custom `transitionBuilder`is used. + /// + /// This argument defaults to 200 milliseconds. + Duration transitionDuration = const Duration(milliseconds: 200), + /// You can provide BoxConstraints to constrain the size of the dialog. /// /// You might want to do this at least for the height, otherwise @@ -694,6 +711,8 @@ Future showColorPickerDialog( useSafeArea: useSafeArea, routeSettings: routeSettings, anchorPoint: anchorPoint, + transitionBuilder: transitionBuilder, + transitionDuration: transitionDuration, constraints: constraints, ))) { selectedColor = color;