/
flex_color_scheme.dart
7926 lines (7648 loc) · 385 KB
/
flex_color_scheme.dart
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
import 'dart:math' as math;
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:material_color_utilities/material_color_utilities.dart';
import 'flex_color.dart';
import 'flex_constants.dart';
import 'flex_core_palette.dart';
import 'flex_extensions.dart';
import 'flex_key_color.dart';
import 'flex_scheme.dart';
import 'flex_scheme_color.dart';
import 'flex_scheme_on_colors.dart';
import 'flex_sub_themes.dart';
import 'flex_sub_themes_data.dart';
import 'flex_tones.dart';
// ignore_for_file: comment_references
/// Enum for using predefined surface blend modes for surface and background
/// colors in [FlexColorScheme] based themes.
///
/// The mode [highBackgroundLowScaffold] is the closest equivalent to the style
/// used in [FlexColorScheme] before version 4 via the to be deprecated
/// [FlexSurface] enum property [surfaceStyle] in [FlexColorScheme.light] and
/// [FlexColorScheme.dark] factories.
enum FlexSurfaceMode {
/// All surfaces have same alpha blend level including scaffold background.
///
/// The blend level is at equal strength as set by blendLevel,
/// the blend strength mix definition is:
///
/// * Scaffold background, surface, dialogs, background: (1x)
///
/// This mode results in elevation overlay color on [Material] type
/// [MaterialType.card], [MaterialType.canvas] and [MaterialType.circle]
/// themed background color in dark theme mode.
///
/// In surface modes that use different blend strengths and blend color,
/// that differs from the value used for colorScheme.surface,
/// those [Material] surfaces will not get
/// elevation overlay color in dark mode, even if set to on. For more
/// information see issue: https://github.com/flutter/flutter/issues/90353
level,
/// Decreasing blend level in order background, surface, scaffold.
///
/// The blend level decreases on surfaces in this order:
///
/// * Background (3/2x)
/// * Surface & dialogs (1x)
/// * Scaffold (1/2x)
///
/// Theme colorScheme.primary color is used as blend color on all surfaces.
///
/// In combination with the blend level [FlexColorScheme.blendLevel], it
/// results in a style where scaffold background has a much lower blend
/// strength, 1/3x of blend level value and remains mostly unbranded at
/// low blend levels. Surface uses the blend level value, and
/// background gets 3/2x the blend level value.
///
/// The mode [FlexSurfaceMode.highBackgroundLowScaffold] can be used to
/// replace the style that was produced when using old and removed
/// `FlexColorScheme.surfaceStyle` enum property `FlexSurface` in
/// [FlexColorScheme.light] and [FlexColorScheme.dark] before version 4.
///
/// The mode [FlexSurfaceMode.highBackgroundLowScaffold] uses the same
/// design concept as the only style offered via removed `FlexSurface`
/// in `FlexColorScheme.surfaceStyle` that was in use before version 4,
/// and deprecated in version 4.2 and removed in version 5.0.0.
///
/// By adjusting the [FlexColorScheme.blendLevel] property and using this
/// style, you can find a similar visual effect when using
/// [FlexSurfaceMode.highBackgroundLowScaffold] with the following values when
/// matching match most prominent blended [ColorScheme.background] color.
///
/// In light theme mode:
///
/// * [FlexSurface.material] 0% : blendLevel = 0
/// * [FlexSurface.light] 2% : blendLevel = 3...4
/// * [FlexSurface.medium] 4% : blendLevel = 7
/// * [FlexSurface.strong] 6% : blendLevel = 10
/// * [FlexSurface.heavy] 8% : blendLevel = 13...14
///
/// In dark theme mode:
///
/// * [FlexSurface.material] 0% : blendLevel = 0
/// * [FlexSurface.light] 5% : blendLevel = 8
/// * [FlexSurface.medium] 8% : blendLevel = 13...14
/// * [FlexSurface.strong] 11% : blendLevel = 19
/// * [FlexSurface.heavy] 14% : blendLevel = 23
///
/// Since there is not the same relationship between background and
/// surface, when using the older [FlexSurface] based style, that uses
/// individually tuned relationships. The old and new designs do never
/// align exactly at any blendLevel. The above values produce visually
/// similar results for the most prominent background color blend.
///
/// To get elevation overlay color in dark themes on all surfaces used by
/// [Material], use one of the modes where background and dialog color equals
/// the blend strength on surface color, like [level],
/// [levelSurfacesLowScaffold], [highScaffoldLowSurfaces],
/// [levelSurfacesLowScaffoldVariantDialog] and
/// [highScaffoldLowSurfacesVariantDialog]. Other modes will only use
/// elevation overlay if their background happens to be equal to resulting
/// colorScheme.surface color. For more information
/// see issue: https://github.com/flutter/flutter/issues/90353
///
/// When using very strong surface branding in dark mode, having an overlay
/// elevation color in dark mode is less critical, since the elevation
/// becomes partially visible via shadows and the surface may even have
/// another color tint if using e.g. [levelSurfacesLowScaffoldVariantDialog]
/// or [highScaffoldLowSurfacesVariantDialog].
highBackgroundLowScaffold,
/// Decreasing blend level in order surface, background, scaffold.
///
/// The blend level decreases on surfaces in this order:
///
/// * Surface & dialogs (3/2x)
/// * Background (1x)
/// * Scaffold (1/2x)
///
/// Theme colorScheme.primary color is used as blend color on all surfaces.
///
/// To get elevation overlay color in dark themes on all surfaces used by
/// [Material], use one of the modes where background and dialog color equals
/// the blend strength on surface color, like [level],
/// [levelSurfacesLowScaffold], [highScaffoldLowSurfaces] and
/// [highScaffoldLowSurfaces]. Other modes will only use
/// elevation overlay if their background happens to be equal to resulting
/// colorScheme.surface color. For more information
/// see issue: https://github.com/flutter/flutter/issues/90353
///
/// When using very strong surface branding in dark mode, having an overlay
/// elevation color in dark mode is less critical, since the elevation
/// becomes partially visible via shadows and the surface may even have
/// another color tint if using e.g. [levelSurfacesLowScaffoldVariantDialog]
/// or [highScaffoldLowSurfacesVariantDialog].
highSurfaceLowScaffold,
/// Decreasing blend level in order scaffold, background, surface.
///
/// The blend level decreases on surfaces in this order:
///
/// * Scaffold (3x)
/// * Background (1x)
/// * Surface & dialogs (1/2x)
///
/// Theme colorScheme.primary color is used as blend color on all surfaces.
///
/// To get elevation overlay color in dark themes on all surfaces used by
/// [Material], use one of the modes where background and dialog color equals
/// the blend strength on surface color, like [level],
/// [levelSurfacesLowScaffold], [highScaffoldLowSurfaces] and
/// [highScaffoldLowSurfaces]. Other modes will only use
/// elevation overlay if their background happens to be equal to resulting
/// colorScheme.surface color. For more information
/// see issue: https://github.com/flutter/flutter/issues/90353
///
/// When using very strong surface branding in dark mode, having an overlay
/// elevation color in dark mode is less critical, since the elevation
/// becomes partially visible via shadows and the surface may even have
/// another color tint if using e.g. [levelSurfacesLowScaffoldVariantDialog]
/// or [highScaffoldLowSurfacesVariantDialog].
highScaffoldLowSurface,
/// Decreasing blend level in order scaffold, background, surface.
///
/// The blend level decreases on surfaces in this order:
///
/// * Scaffold (3x)
/// * Background (3/2x)
/// * Surface (1x)
///
/// Theme colorScheme.primary color is used as blend color on all surfaces.
///
/// To get elevation overlay color in dark themes on all surfaces used by
/// [Material], use one of the modes where background and dialog color equals
/// the blend strength on surface color, like [level],
/// [levelSurfacesLowScaffold], [highScaffoldLowSurfaces] and
/// [highScaffoldLowSurfaces]. Other modes will only use
/// elevation overlay if their background happens to be equal to resulting
/// colorScheme.surface color. For more information
/// see issue: https://github.com/flutter/flutter/issues/90353
///
/// When using very strong surface branding in dark mode, having an overlay
/// elevation color in dark mode is less critical, since the elevation
/// becomes partially visible via shadows and the surface may even have
/// another color tint if using e.g. [levelSurfacesLowScaffoldVariantDialog]
/// or [highScaffoldLowSurfacesVariantDialog].
highScaffoldLevelSurface,
/// Decreasing blend level in order background & surface, scaffold.
///
/// The blend level decreases on surfaces in this order:
///
/// * Surface & background (1x)
/// * Scaffold (1/2x)
///
/// Theme colorScheme.primary color is used as blend color.
///
/// This mode results in elevation overlay color on [Material] type
/// [MaterialType.card], [MaterialType.canvas] and [MaterialType.circle]
/// themed background color in dark theme mode. In surface modes that
/// use different blend strengths and blend color, that differs from the value
/// used for colorScheme.surface, those [Material] surfaces will not get
/// elevation overlay color in dark mode, even if set to on. For more
/// information see issue: https://github.com/flutter/flutter/issues/90353
levelSurfacesLowScaffold,
/// Decreasing blend level in order scaffold, background & surface.
///
/// The blend level decreases on surfaces in this order:
///
/// * Scaffold (3x)
/// * Surface & background (1/2x)
///
/// Theme colorScheme.primary color is used as blend color.
///
/// This mode results in elevation overlay color on [Material] type
/// [MaterialType.card], [MaterialType.canvas] and [MaterialType.circle]
/// themed background color in dark theme mode. In surface modes that
/// use different blend strengths and blend color, that differs from the value
/// used for colorScheme.surface, those [Material] surfaces will not get
/// elevation overlay color in dark mode, even if set to on. For more
/// information see issue: https://github.com/flutter/flutter/issues/90353
highScaffoldLowSurfaces,
/// Decreasing blend level in order background & surface, scaffold.
///
/// The blend level decreases on surfaces in this order:
///
/// * Surface, background, dialogs (1x)
/// * Scaffold (1/2x)
///
/// Theme colorScheme.primary color is used as blend color, but dialog
/// background color uses theme colorScheme.secondaryContainer as its
/// blend color.
///
/// This modes results in elevation overlay color on all Material types and
/// background colors in dark theme mode, except dialogs that do NOT get any
/// elevation overlay color. This happens because Dialogs use the
/// colorScheme.tertiary color for their blend color which typically
/// differs from the primary color used on surface color.
///
/// To get elevation overlay color in dark themes on all surfaces used by
/// [Material], use one of the modes where background and dialog color equals
/// the blend strength on surface color, like [level],
/// [levelSurfacesLowScaffold], [highScaffoldLowSurfaces] and
/// [highScaffoldLowSurfaces]. Other modes will only use elevation overlay
/// if their background happens to be equal to resulting
/// colorScheme.surface color. For more information
/// see issue: https://github.com/flutter/flutter/issues/90353
///
/// The color scheme secondary variant color is a good place in theme colors
/// to store a custom color you may want to use for special elements on custom
/// widgets in your application. The secondary variant color is not used
/// by default by any widget in Flutter SDK, so it can be assigned a color
/// without affecting any default color behavior of SDK widgets. If you do so
/// and want to get some funky dialog blends using this color, you can use
/// this surface mode.
levelSurfacesLowScaffoldVariantDialog,
/// Decreasing blend level in order scaffold, background & surface.
///
/// The blend level decreases on surfaces in this order:
///
/// * Scaffold (3x)
/// * Surface, background, dialogs (1/2x)
///
/// Theme colorScheme.primary color is used as blend color, but dialog
/// background uses theme colorScheme.secondaryContainer as its blend color.
///
/// This modes results in elevation overlay color on all Material types and
/// background colors in dark theme mode, except dialogs that do NOT get any
/// elevation overlay color. This happens because Dialogs use the
/// colorScheme.tertiary color for their blend color which typically
/// differs from the primary color used on surface color.
///
/// To get elevation overlay color in dark themes on all surfaces used by
/// [Material], use one of the modes where background and dialog color equals
/// the blend strength on surface color, like [level],
/// [levelSurfacesLowScaffold], [highScaffoldLowSurfaces] and
/// [highScaffoldLowSurfaces]. Other modes will only use
/// elevation overlay if their background happens to be equal to resulting
/// colorScheme.surface color. For more information
/// see issue: https://github.com/flutter/flutter/issues/90353
///
/// The color scheme secondary variant color is a good place in theme colors
/// to store a custom color you may want to use for special elements on custom
/// widgets in your application. The secondary variant color is not used
/// by default by any widget in Flutter SDK, so it can be assigned a color
/// without affecting any default color behavior of SDK widgets. If you do so
/// and want to get some funky dialog blends using this color, you can use
/// this surface mode.
highScaffoldLowSurfacesVariantDialog,
/// Use your own custom surface and background blend style.
///
/// Use this option and use the [FlexSchemeSurfaceColors.blend] constructor
/// to make your custom surface colors using the applied blend levels.
custom,
}
/// Enum to select the used AppBarTheme style in [FlexColorScheme] based themes
/// when using its `light` and `dark` factories.
enum FlexAppBarStyle {
/// Use the scheme primary color as the AppBar's themed background color.
///
/// This is the default for light themes.
primary,
/// Use Material surface color as the AppBar's themed background color.
///
/// This is the default for dark schemes.
///
/// For a dark scheme this choice will result in a near black app bar. If this
/// setting is used in a light scheme, it will result in a white app bar, as
/// the standard Material surface color for light scheme is white.
material,
/// Use scheme surface color as the the AppBar's themed background color,
/// including any blend color it may have.
surface,
/// Use scheme background color as the the AppBar's themed background color,
/// including any blend color it may have.
background,
/// Use a custom [AppBar] background color as its themed background color.
///
/// If you provide a color value to [FlexColorScheme.appBarBackground]
/// color directly, it will be used as the themed [AppBar] background color.
///
/// If it is not defined, then the [appBarColor] defined in passed in
/// [FlexSchemeColor] property [colors] is used when using the
/// factories [FlexColorScheme.light] and [FlexColorScheme.dark], as the
/// custom color for the [AppBar] theme.
///
/// The built-in color schemes have the same color value that is assigned to
/// [FlexSchemeColor.secondaryContainer] also assigned to
/// [FlexSchemeColor.appBarColor], so with them, the custom choice always
/// results in the [FlexSchemeColor.secondaryContainer] color, which is same
/// as output [ColorScheme.secondaryContainer], being used as the [AppBar]
/// color when using the [custom] choice with them.
///
/// FlexColorSchemes using custom [FlexSchemeColor] can assign any color
/// to their [FlexSchemeColor.appBarColor] color. It does not have to be
/// a part of the colors that exist in the standard [ColorScheme].
///
/// If there is no custom color definition in above paths when using the
/// [custom] style, the [AppBar] color will be same as with [material] choice.
custom,
}
/// Enum used to define the [SystemUiOverlayStyle] for the system navigation
/// bar.
///
/// Used with the [FlexColorScheme.themedSystemNavigationBar]
/// helper to select the background style of system navigation bar when using
/// the helper in an [AnnotatedRegion] to style the system navigation bar.
enum FlexSystemNavBarStyle {
/// Standard Android system style, white in light theme and black in
/// dark theme.
system,
/// The system navigation bar will be the same color as active theme
/// colorScheme.surface color. If your FlexColorScheme definition is set to
/// use primary branded surface and background colors, the same primary
/// color blend that the surface color has received will be used.
surface,
/// The system navigation bar will be the same color as active theme
/// colorScheme.background color. If your FlexColorScheme definition is set
/// to use primary branded surface and background colors, the same primary
/// color blend that the background color has received will be used.
background,
/// The system navigation bar will be the same color as active theme
/// scaffoldBackground color. If your FlexColorScheme definition is set
/// to use primary branded surface and background colors, the same primary
/// color blend that the scaffoldBackground color has received will be used.
scaffoldBackground,
/// Make the system navigation bar fully transparent, showing the background,
/// while navigation buttons float over the background.
/// For this to work Android SDK has to be >= 29.
///
/// The fully transparent system navigation bar works well when there is a
/// bottom navigation bar with some opacity, you can then share the same
/// background as it has with the system navigation bar, using same color
/// and opacity as on the bottom navigation bar, creating one shared surface
/// with same color and opacity on bottom navigation bar and the system
/// navigation bar. The package readme includes on example of this.
transparent,
}
/// Enum to select [TabBarTheme] preference in [FlexColorScheme] based themes.
enum FlexTabBarStyle {
/// Themed to fit with active [FlexAppBarStyle] and [AppBarTheme].
///
/// Indicator, text and icons contrast well with AppBar background color,
/// regardless of chosen [FlexAppBarStyle].
///
/// This is the default style for FlexColorScheme based themes and typically
/// the style you want.
forAppBar,
/// Themed to fit with current background and surface colors.
///
/// Indicator, text and icons contrast with background and surface colors
/// via primary color.
///
/// If you intend to use your TabBar's only on surfaces, like Scaffold
/// or in cards using default theme background color, then use this style.
/// If you use an AppBar theme that is surface colored in both light and dark
/// theme, then this style will also work well when the TabBar is used
/// in the AppBar, as well as on surfaces.
forBackground,
/// Make a [TabBarTheme] sub-theme that equals the style you get with
/// ThemeData.from constructor and Widget default values in Flutter SDK.
///
/// This works well with default primary colored AppBar's in light
/// theme and dark surface colored AppBars or other dark surfaces in dark
/// theme. It does not work with all app bar styles supported by
/// [FlexColorScheme], prefer using [forAppBar] for that.
flutterDefault,
/// An experimental [TabBarTheme] mode that works on both primary and
/// background colors.
///
/// This theme is more low contrast than the themes explicitly designed
/// for their target surface. Use with caution, with some combinations
/// the style may have poor contrast and look disabled.
///
/// WARNING: This feature is experimental and its resulting style
/// might be modified to improve it in future versions. Changes to the
/// produced style will not be considered breaking, only as a fix.
///
/// Prefer using [forAppBar] or [forBackground] depending on where you
/// primarily intend to use your tab bars.
universal,
}
/// Make beautiful Flutter themes using pre-designed color schemes or custom
/// colors. Get the resulting [ThemeData] with the [toTheme] method.
///
/// Flutter's [ThemeData.from] is a good starting point for [ColorScheme] based
/// themes. It has a some gaps leaving some properties in the theme
/// to their defaults from the standard [ThemeData] factory constructor, those
/// default values will end up not matching the used [ColorScheme], especially
/// in dark mode themes. [FlexColorScheme] fixes these gaps and makes it much
/// easier to create themes using the color scheme concept.
///
/// You can create the theme using a standard [ColorScheme], but you can also
/// create a theme by just providing a few selected color values, or
/// no color values at all and get defaults. If you provide both a [ColorScheme]
/// and some individual property values that also exist in a [ColorScheme], the
/// individual property values will override the corresponding ones in your
/// [ColorScheme].
///
/// [FlexColorScheme] does not rely on [ThemeData.from] a [ColorScheme] for
/// its implementation. It uses the [ThemeData] factory directly to create the
/// [ThemeData] object from its [FlexColorScheme] data, that is then returned
/// with the [FlexColorScheme.toTheme] getter.
///
/// A more opinionated theme and style can be returned by passing in a default
/// [FlexSubThemesData] () constructor to [subThemesData].
/// By default the sub-themes take inspiration from the Material 3 (M3) Design
/// guide [specification](https://m3.material.io) and uses its values as
/// defaults when it is possible to do so in Flutter
/// SDK theming, within its current Material 2 (M2) design limitations.
///
/// The component sub-themes can configured further by configuring a large
/// amount of properties in [FlexSubThemesData] that is passed into
/// [FlexColorScheme.subThemesData]. A commonly used feature is
/// to adjust the default corner border radius on all sub-themes for widgets
/// that supports it. The opinionated design is also more flat and features
/// primary tinted hover, focus, highlight and splash colors, among other
/// things.
///
/// It can be verbose to define nice color scheme directly with the default
/// unnamed constructor. [FlexColorScheme] is primarily intended to be used
/// with its two factory constructors [FlexColorScheme.light] and
/// [FlexColorScheme.dark], that create nice schemes using defaults and
/// computed color values. The light and dark schemes also give you access
/// to many predefined color schemes that you can use and easily modify.
///
/// With the light and dark factories you can also create
/// beautiful toned themes from just a single color.
/// [FlexColorScheme] makes it easy to create themes that use color branded
/// surfaces (backgrounds), that use alpha blend to mix in a varying degree
/// of a color, typically the primary color, into surfaces and backgrounds.
///
/// Branded surface are described in the Material design guide, but Flutter
/// offers no out of the box help to make such themes. With [FlexColorScheme]
/// you can use a varying degree of surface and background branding levels for
/// any theme you make, both in light and dark mode.
///
/// [FlexColorScheme] makes it easy to make a theme where the [AppBar]
/// themed background color is not tied to primary color in light theme mode or
/// to surface color in dark theme mode, and it can also follow the branded
/// scheme surface or background color.
///
/// [FlexColorScheme] can automatically adjust the [TabBarTheme] to fit with the
/// active [AppBar] background or to be themed to always fit on
/// background/surface colors, if its primary usage will be in e.g. a [Scaffold]
/// body, or [Material] surface or canvas.
///
/// You can also quickly adjust things like the scrim on the app bar in Android
/// with [transparentStatusBar] and tooltip style with
/// [tooltipsMatchBackground].
///
/// The two factory constructors [FlexColorScheme.light] and
/// [FlexColorScheme.dark] also offer support for more advanced and
/// customizable key color generated [ColorScheme]'s, than what is offered out
/// of the box in Flutter SDK via [ColorScheme.fromSeed].
@immutable
class FlexColorScheme with Diagnosticable {
/// Default constructor that requires [brightness] and four main color scheme
/// color properties in order to make a fully defined color scheme for
/// a [ThemeData] object.
///
/// For more convenient usage of [FlexColorScheme] consider using its two
/// factory constructors [FlexColorScheme.light] and [FlexColorScheme.dark],
/// that can create schemes using defaults and computed color values, with
/// custom overrides as needed.
///
/// The two factories also contain additional properties that can be used to
/// create color branded surfaces, toggle the [AppBarTheme] between a few
/// styles, and to make dark themes that use true black backgrounds and
/// surfaces. As well as using [FlexKeyColors] and [FlexTones] to make and
/// customize key color seed generated [ColorScheme]s.
const FlexColorScheme({
this.colorScheme,
this.brightness,
this.primary,
this.primaryContainer,
@Deprecated('Replaced with `primaryContainer`, after version 4.2.0, '
'due to deprecation in Flutter master from 2.10.0')
this.primaryVariant,
this.secondary,
this.secondaryContainer,
@Deprecated('Replaced with `secondaryContainer`, after version 4.2.0, '
'due to deprecation in Flutter master from 2.10.0')
this.secondaryVariant,
this.tertiary,
this.tertiaryContainer,
this.error,
this.surface,
this.background,
this.scaffoldBackground,
this.dialogBackground,
this.appBarBackground,
this.onPrimary,
this.onPrimaryContainer,
this.onSecondary,
this.onSecondaryContainer,
this.onTertiary,
this.onTertiaryContainer,
this.onSurface,
this.onBackground,
this.onError,
this.surfaceTint,
this.tabBarStyle = FlexTabBarStyle.forAppBar,
this.appBarElevation = 0,
this.bottomAppBarElevation = 0,
this.tooltipsMatchBackground = false,
this.transparentStatusBar = true,
this.visualDensity,
this.textTheme,
this.primaryTextTheme,
this.fontFamily,
this.platform,
this.typography,
this.applyElevationOverlayColor = true,
@Deprecated('This property has no function after 4.2.0. FlexColorScheme '
'opinionated component sub-themes are added by adding a default '
'constructor FlexSubThemesData() to subThemesData. This creates '
'sub-themes using the FlexColorScheme opinionated defaults. You can '
'modify the sub-themes by changing the FlexSubThemesData properties. '
'This property will be completely removed in version 6.0.0.')
this.useSubThemes = false,
this.subThemesData,
this.useMaterial3 = false,
this.extensions,
}) : assert(appBarElevation >= 0.0, 'AppBar elevation must be >= 0.'),
assert(bottomAppBarElevation >= 0.0,
'Bottom AppBar elevation must be >= 0.');
/// The overall [ColorScheme] based colors for the theme.
///
/// This property provides an alternative way to define custom colors for
/// [FlexColorScheme] and is available from version 4.2.0. It is useful if
/// you already have a custom [ColorScheme] based color definition that
/// you want to use with FlexColorScheme theming and its sub-theming
/// capabilities. This is useful when using fully custom scheme or using the
/// Material 3 based design and its seed generated color schemes.
///
/// The factories [FlexColorScheme.light] and [FlexColorScheme.dark] provide
/// convenience factories for also generating M3 based seeded themes using
/// the built in [ColorSchemes] as seed colors or custom colors you provide
/// as seeding colors.
///
/// If you provide both a [ColorScheme] and some individual direct property
/// values that also exist in a [ColorScheme], the individual property values
/// will override the corresponding ones in your [ColorScheme].
///
/// If you do not define a [colorScheme], the individual color value
/// properties and their defaults are used to define your effective
/// [FlexColorScheme] and its resulting [ColorScheme] and [ThemeData].
///
/// The [FlexColorScheme]'s effective [ColorScheme] can be returned with
/// [toScheme]. This will always get you a complete color scheme, including
/// calculated and derived color values, which is particularly useful when
/// using the [FlexColorScheme.light] and [FlexColorScheme.dark] factories
/// to compute color scheme branded surface colors for you. The effective
/// [ColorScheme] for your theme is often needed if you want to create custom
/// sub-themes that should use the colors from the scheme using none default
/// color assignments computed from the input colors.
final ColorScheme? colorScheme;
/// The overall brightness of this color scheme.
///
/// The [Brightness.light] denotes a theme for light theme mode and
/// [Brightness.dark] a dark theme mode. The colors you define should match
/// the used [brightness] value in order for the theme to make visual sense.
///
/// If not defined, and if there is no [colorScheme] defined, it defaults
/// to [Brightness.light].
final Brightness? brightness;
/// The color displayed most frequently across your application’s screens and
/// components.
///
/// If not defined and if there is no [colorScheme] defined, and [brightness]
/// is [Brightness.light] it defaults to [FlexColor.materialLightPrimary].
/// If not defined and if there is no [colorScheme] defined, and [brightness]
/// is [Brightness.dark] it defaults to [FlexColor.materialDarkPrimary].
final Color? primary;
/// A color used for elements needing less emphasis than [primary].
///
/// If not defined, and if there is no [colorScheme] defined, the default
/// result will be [primary] color.
final Color? primaryContainer;
/// (Deprecated) A darker version of the primary color.
///
/// In Flutter SDK the `primaryVariant` color is only used by [SnackBar]
/// button color in dark theme mode as a part of predefined widget behavior.
/// If you provide a custom [SnackBarThemeData] where you define
/// [SnackBarThemeData.actionTextColor] to [primary] or [secondary], this
/// color property becomes a good property to use if you need a custom color
/// for custom widgets accessible via your application's ThemeData, that is
/// not used as default color by any other built-in widgets. This applies
/// to Flutter 2.8.1 and earlier versions.
///
/// The property is deprecated in Flutter SDK and was replaced
/// by a new property called [primaryContainer]. It is deprecated from
/// master v2.6.0-0.0.pre, and in stable (2.10.0).
/// See https://github.com/flutter/flutter/issues/89852.
///
/// If not defined, and if there is no [colorScheme] defined, it will default
/// to [primary] color.
@Deprecated('Replaced with `primaryContainer`, after version 4.2.0, '
'due to deprecation in Flutter master from 2.10.0')
final Color? primaryVariant;
/// An accent color that, when used sparingly, calls attention to parts
/// of your application.
///
/// If not defined, and if there is no [colorScheme] defined, the default
/// result will be [primary] color.
final Color? secondary;
/// A color used for elements needing less emphasis than [secondary].
///
/// If not defined, and if there is no [colorScheme] defined, it will default
/// to [secondary] color, and if it is not defined either, then [primary].
final Color? secondaryContainer;
/// (Deprecated) A darker version of the secondary color.
///
/// In Flutter SDK the `secondaryVariant` color is not used by in any
/// built-in widgets default themes or predefined widget behavior.
/// It is an excellent property to use if you need a custom color for
/// custom widgets accessible via your application's ThemeData, and that is
/// not used as default color by any built-in widgets. So you are in
/// Flutter 2.8.1 and earlier version free to set it to whatever color you
/// need and not affect any built-in widgets theme based colors.
///
/// The property is deprecated in Flutter SDK and was replaced
/// by a new property called [secondaryContainer]. It is deprecated from
/// master v2.6.0-0.0.pre, and in stable (2.10.0).
/// See https://github.com/flutter/flutter/issues/89852.
///
/// If not defined, and if there is no [colorScheme] defining, scheme result
/// will be [secondary] color, and if it is not defined either then
/// [primary] color.
@Deprecated('Replaced with `secondaryContainer`, after version 4.2.0, '
'due to deprecation in Flutter master from 2.10.0')
final Color? secondaryVariant;
/// A color used as a contrasting accent that can balance [primary]
/// and [secondary] colors or bring heightened attention to an element,
/// such as an input field.
///
/// If not defined, and if there is no [colorScheme] defined, it will default
/// to [secondary] color, and if it is not defined either, then [primary].
final Color? tertiary;
/// A color used for elements needing less emphasis than [tertiary].
///
/// If not defined, and if there is no [colorScheme] defined, it will default
/// to [secondary] color, and if it is not defined either, then [primary].
final Color? tertiaryContainer;
/// The color to use for input validation errors, for example on
/// [InputDecoration.errorText].
///
/// If no value is given, and if there is no [colorScheme] defined, it
/// defaults to [FlexColor.materialLightError] if brightness is light,
/// and to [FlexColor.materialDarkError] if brightness is dark.
final Color? error;
/// The surface (background) color for widgets like [Card] and
/// [BottomAppBar].
///
/// The color is applied to [ThemeData.cardColor] and [ColorScheme.surface]
/// in [ThemeData.colorScheme], it is also used by all [Material] of type
/// [MaterialType.card].
///
/// If no value is given, and if there is no [colorScheme] defined, it
/// defaults to [FlexColor.materialLightSurface] if brightness is light,
/// and to [FlexColor.materialDarkSurface] if brightness is dark.
final Color? surface;
/// A color that typically appears behind scrollable content.
///
/// The color is applied to [ThemeData.canvasColor] and
/// [ThemeData.backgroundColor], it is used eg by menu [Drawer] and by all
/// [Material] of type [MaterialType.canvas].
///
/// If no value is given, and if there is no [colorScheme] defined, it
/// defaults to [FlexColor.materialLightBackground] if brightness is light,
/// and to [FlexColor.materialDarkBackground] if brightness is dark.
final Color? background;
/// The color of the [Scaffold] background.
///
/// The color is applied to [ThemeData.scaffoldBackgroundColor].
///
/// This color cannot be controlled separately with Flutter's standard
/// [ColorScheme] only based themes. FlexColorScheme brings back the
/// possibility to specify it directly when using color scheme based themes.
///
/// If no color is given, it defaults to [background].
final Color? scaffoldBackground;
/// The background color of [Dialog] elements.
///
/// The color is applied to [ThemeData.dialogBackgroundColor]. It cannot be
/// controlled separately with only a [ThemeData.from] a color scheme.
///
/// If no value is given, it defaults to [surface].
///
/// If you assign a background [SchemeColor] to [dialogBackgroundSchemeColor]
/// in [FlexSubThemesData] and you have opted in on using component sub themes
/// with [useSubThemes], then its selected scheme color will override this
/// value.
final Color? dialogBackground;
/// Background theme color for the [AppBar].
///
/// This AppBar theme color cannot be controlled separately with only
/// standard [ThemeData.from] a [ColorScheme]. [FlexColorScheme] enables you
/// to specify an AppBar theme color that is independent of the primary color
/// in light theme and in dark mode of the dark theme's dark surface color.
///
/// When you use it, the correct text and icon contrast color is computed and
/// set automatically based on provided color.
///
/// This AppBar color will also override any scheme color based selection
/// in active used sub-themes if you have selected on for the AppBar there.
final Color? appBarBackground;
/// A color that is clearly legible when drawn on [primary] color.
///
/// To ensure that an app is accessible, a contrast ratio of 4.5:1 for
/// [primary] and [onPrimary] is recommended. See
/// <https://www.w3.org/TR/UNDERSTANDING-WCAG20/visual-audio-contrast-contrast.html>.
///
/// If null, and if [colorScheme.onPrimary] is null, the color is derived
/// from the brightness of the effective primary color, and will be be black
/// if it is light and white if it is dark.
final Color? onPrimary;
/// A color that's clearly legible when drawn on [primaryContainer].
///
/// To ensure that an app is accessible, a contrast ratio between
/// [primaryContainer] and [onPrimaryContainer] of at least 4.5:1
/// is recommended. See
/// <https://www.w3.org/TR/UNDERSTANDING-WCAG20/visual-audio-contrast-contrast.html>.
///
/// If null, and if [colorScheme.onPrimaryContainer] is null, the color
/// will via [ColorScheme] default be equal to resulting color scheme
/// [ColorScheme.onPrimary].
final Color? onPrimaryContainer;
/// A color that is clearly legible when drawn on [secondary] color.
///
/// To ensure that an app is accessible, a contrast ratio of 4.5:1 for
/// [secondary] and [onSecondary] is recommended. See
/// <https://www.w3.org/TR/UNDERSTANDING-WCAG20/visual-audio-contrast-contrast.html>.
///
/// If null, the on color is derived from the brightness of the [secondary]
/// color, and will be be black if it is light and white if it is dark.
final Color? onSecondary;
/// A color that's clearly legible when drawn on [secondaryContainer].
///
/// To ensure that an app is accessible, a contrast ratio between
/// [secondaryContainer] and [onSecondaryContainer] of at least 4.5:1
/// is recommended. See
/// <https://www.w3.org/TR/UNDERSTANDING-WCAG20/visual-audio-contrast-contrast.html>.
///
/// If null, and if [colorScheme.onSecondaryContainer] is null, the color
/// will via [ColorScheme] default be equal to resulting color scheme
/// [ColorScheme.onSecondary].
final Color? onSecondaryContainer;
/// A color that's clearly legible when drawn on [tertiary].
///
/// To ensure that an app is accessible, a contrast ratio between
/// [tertiary] and [onTertiary] of at least 4.5:1 is recommended. See
/// <https://www.w3.org/TR/UNDERSTANDING-WCAG20/visual-audio-contrast-contrast.html>.
///
/// If null, and if [colorScheme.onTertiary] is null, the color
/// will via [ColorScheme] default be equal to resulting color scheme
/// [ColorScheme.onSecondary].
final Color? onTertiary;
/// A color that's clearly legible when drawn on [tertiaryContainer].
///
/// To ensure that an app is accessible, a contrast ratio between
/// [tertiaryContainer] and [onTertiaryContainer] of at least 4.5:1 is
/// recommended. See
/// <https://www.w3.org/TR/UNDERSTANDING-WCAG20/visual-audio-contrast-contrast.html>.
///
/// If null, and if [colorScheme.onTertiaryContainer] and [onTertiary) is
/// null, the color will via [ColorScheme] default be equal to resulting
/// color scheme [ColorScheme.onSecondary].
final Color? onTertiaryContainer;
/// A color that is clearly legible when drawn on [surface] color.
///
/// To ensure that an app is accessible, a contrast ratio of 4.5:1 for
/// [surface] and [onSurface] is recommended. See
/// <https://www.w3.org/TR/UNDERSTANDING-WCAG20/visual-audio-contrast-contrast.html>.
///
/// If null, the on color is derived from the brightness of the [surface]
/// color, and will be be black if it is light and white if it is dark.
final Color? onSurface;
/// A color that is clearly legible when drawn on [background] color.
///
/// To ensure that an app is accessible, a contrast ratio of 4.5:1 for
/// [background] and [onBackground] is recommended. See
/// <https://www.w3.org/TR/UNDERSTANDING-WCAG20/visual-audio-contrast-contrast.html>.
///
/// If null, the on color is derived from the brightness of the [background]
/// color, and will be be black if it is light and white if it is dark.
final Color? onBackground;
/// A color that is clearly legible when drawn on [error] color.
///
/// To ensure that an app is accessible, a contrast ratio of 4.5:1 for [error]
/// and [onError] is recommended. See
/// <https://www.w3.org/TR/UNDERSTANDING-WCAG20/visual-audio-contrast-contrast.html>.
///
/// If null, the on color is derived from the brightness of the [error]
/// color, and will be be black if it is light and white if it is dark.
final Color? onError;
/// A color used as an overlay on a surface color to indicate a component's
/// elevation.
///
/// You can use this property for convenience if you want to override the
/// color that this scheme color gets via the factory behavior.
/// If a [colorScheme] was provided where this corresponding color is
/// defined, this color property will override the same color in it.
///
/// This color is used by M3 for colored elevation, it is also used as the
/// blend color for FlexColorScheme surface blends.
///
/// If undefined it defaults to [primary] color.
final Color? surfaceTint;
/// Select preferred style for the default [TabBarTheme].
///
/// By default the TabBarTheme is made to fit with the style of the AppBar,
/// via default value [FlexTabBarStyle.forAppBar].
///
/// When setting this to [FlexTabBarStyle.forBackground], it will default
/// to a theme that uses the color scheme and fits on background color,
/// which typically also on works surface and scaffoldBackground color.
/// This TabBarTheme style is useful if you primarily intended to use the
/// TabBar in a Scaffold, Dialog, Drawer or Side panel on their background
/// colors.
final FlexTabBarStyle tabBarStyle;
/// The themed elevation for the [AppBar].
///
/// Defaults to 0, cannot be null.
///
/// The 0 elevation is an iOs style influenced opinionated choice, but it
/// can easily be adjusted for the theme with this property.
final double appBarElevation;
/// The themed elevation for the bottom app bar.
///
/// Defaults to 0, cannot be null.
///
/// The 0 default is so it matches the themed app bar elevation default,
/// but it can easily be adjusted for the theme with this property.
final double bottomAppBarElevation;
/// When `true`, tooltip background color will match the brightness of the
/// theme's background color.
///
/// By default Flutter's Material tooltips use a theme where the tooltip
/// background color brightness is inverted in relation to the overall
/// theme's background color.
///
/// [FlexColorScheme] allows you to use a single toggle to invert this.
/// Light tooltips on light background is e.g. the default style on
/// Windows Desktop. You can use this toggle to use this style, or use it as
/// a means to create a platform adaptive tooltip style, where the
/// Material and Flutter style is used on devices and Web, but the inverted
/// scheme is used on desktop platforms.
///
/// Defaults to false, and uses same background style as Material Design guide
/// and Flutter.
///
/// Regardless of value used on this property, the tooltip theme created by
/// [FlexColorScheme] does deviate a bit from Flutter's default tooltip theme.
/// With default Material text theme, it uses a slightly larger font 12dp, for
/// improved legibility on web and desktop with device pixel ratio 1.0, and
/// it also uses a padding style suitable for multiline tooltips.
///
/// Default tooltip theme in Flutter Material 2 is currently a bit flawed on
/// desktop and web, because it defaults to using a very small font (10 dp).
/// See issue: https:///github.com/flutter/flutter/issues/71429.
/// Material 3 changes the default tooltip theme size to 11dp.
final bool tooltipsMatchBackground;
/// When `true`, the status bar on Android will be the same color as
/// the rest of the AppBar.
///
/// Defaults to true.
///
/// When true, the AppBar in Android mimics the look of one-toned AppBar's
/// typically used on iOS. Set it to `false` to revert back and use
/// Android's default two-toned look. If true the status bar area is also
/// transparent, then if the app bar is also translucent, content that scrolls
/// behind it is also visible behind the status bar area.
final bool transparentStatusBar;
/// The density value for specifying the compactness of various UI components.
///
/// Consider using [FlexColorScheme.comfortablePlatformDensity].
/// It is similar to [VisualDensity.adaptivePlatformDensity], but the
/// density for desktop and Web is less dense in order to offer a bit larger
/// touch friendly surfaces, but not quite as large as small touch devices.
///
/// This is the same property as in [ThemeData] factory, it is just
/// passed along to it. Included for convenience to avoid a copyWith if
/// to change it.
///
/// Density, in the context of a UI, is the vertical and horizontal
/// "compactness" of the elements in the UI. It is unit less, since it means
/// different things to different UI elements. For buttons, it affects the
/// spacing around the centered label of the button. For lists, it affects the
/// distance between baselines of entries in the list.
///
/// Typically, density values are integral, but any value in range may be
/// used. The range includes values from [VisualDensity.minimumDensity] (which
/// is -4), to [VisualDensity.maximumDensity] (which is 4), inclusive, where
/// negative values indicate a denser, more compact, UI, and positive values
/// indicate a less dense, more expanded, UI. If a component doesn't support
/// the value given, it will clamp to the nearest supported value.
///
/// The default for visual densities is zero for both vertical and horizontal
/// densities, which corresponds to the default visual density of components
/// in the Material Design specification.