11import 'package:flutter/material.dart' ;
22
3- /// {@template color_theme}
4- /// Theme that holds colors
5- /// {@endtemplate}
3+ /// Defines a color theme for the Stream Chat UI,
4+ /// including core surfaces, text colors, accents, and visual effects.
5+ ///
6+ /// This theme provides two variants:
7+ /// - `StreamColorTheme.light` : for light mode
8+ /// - `StreamColorTheme.dark` : for dark mode
69class StreamColorTheme {
7- /// Initialise with light theme
8- StreamColorTheme .light ({
10+ /// Creates a [StreamColorTheme] instance based on the provided [brightness] .
11+ ///
12+ /// Returns a light theme when [brightness] is [Brightness.light] and
13+ /// a dark theme when [brightness] is [Brightness.dark] .
14+ factory StreamColorTheme ({
15+ Brightness brightness = Brightness .light,
16+ }) {
17+ return switch (brightness) {
18+ Brightness .light => const StreamColorTheme .light (),
19+ Brightness .dark => const StreamColorTheme .dark (),
20+ };
21+ }
22+
23+ /// Creates a light mode [StreamColorTheme] using design system values.
24+ const StreamColorTheme .light ({
925 this .textHighEmphasis = const Color (0xff000000 ),
10- this .textLowEmphasis = const Color (0xff7a7a7a ),
11- this .disabled = const Color (0xffdbdbdb ),
12- this .borders = const Color (0xffecebeb ),
26+ this .textLowEmphasis = const Color (0xff72767e ),
27+ this .disabled = const Color (0xffb4b7bb ),
28+ this .borders = const Color (0xffdbdde1 ),
1329 this .inputBg = const Color (0xffe9eaed ),
14- this .appBg = const Color (0xfff7f7f8 ),
30+ this .appBg = const Color (0xffffffff ),
1531 this .barsBg = const Color (0xffffffff ),
1632 this .linkBg = const Color (0xffe9f2ff ),
17- this .accentPrimary = const Color (0xff005FFF ),
18- this .accentError = const Color (0xffFF3842 ),
19- this .accentInfo = const Color (0xff20E070 ),
33+ this .accentPrimary = const Color (0xff005fff ),
34+ this .accentError = const Color (0xffff3742 ),
35+ this .accentInfo = const Color (0xff20e070 ),
2036 this .highlight = const Color (0xfffbf4dd ),
2137 this .overlay = const Color .fromRGBO (0 , 0 , 0 , 0.2 ),
2238 this .overlayDark = const Color .fromRGBO (0 , 0 , 0 , 0.6 ),
2339 this .bgGradient = const LinearGradient (
2440 begin: Alignment .topCenter,
2541 end: Alignment .bottomCenter,
26- colors: [Color (0xfff7f7f7 ), Color (0xfffcfcfc )],
42+ colors: [Color (0xfff7f7f8 ), Color (0xffe9eaed )],
2743 stops: [0 , 1 ],
2844 ),
2945 this .borderTop = const Effect (
3046 sigmaX: 0 ,
3147 sigmaY: - 1 ,
32- color: Color (0xff000000 ),
48+ color: Color (0xffdbdde1 ),
3349 blur: 0 ,
34- alpha: 0.08 ,
50+ alpha: 1 ,
3551 ),
3652 this .borderBottom = const Effect (
3753 sigmaX: 0 ,
3854 sigmaY: 1 ,
39- color: Color (0xff000000 ),
55+ color: Color (0xffdbdde1 ),
4056 blur: 0 ,
41- alpha: 0.08 ,
57+ alpha: 1 ,
4258 ),
4359 this .shadowIconButton = const Effect (
4460 sigmaX: 0 ,
4561 sigmaY: 2 ,
4662 color: Color (0xff000000 ),
47- alpha: 0.5 ,
4863 blur: 4 ,
64+ alpha: 0.25 ,
4965 ),
5066 this .modalShadow = const Effect (
5167 sigmaX: 0 ,
5268 sigmaY: 0 ,
5369 color: Color (0xff000000 ),
54- alpha : 1 ,
55- blur : 8 ,
70+ blur : 4 ,
71+ alpha : 0.6 ,
5672 ),
5773 }) : brightness = Brightness .light;
5874
59- /// Initialise with dark theme
60- StreamColorTheme .dark ({
75+ /// Creates a dark mode [StreamColorTheme] using design system values.
76+ const StreamColorTheme .dark ({
6177 this .textHighEmphasis = const Color (0xffffffff ),
62- this .textLowEmphasis = const Color (0xff7a7a7a ),
63- this .disabled = const Color (0xff2d2f2f ),
64- this .borders = const Color (0xff1c1e22 ),
65- this .inputBg = const Color (0xff13151b ),
78+ this .textLowEmphasis = const Color (0xff72767e ),
79+ this .disabled = const Color (0xff4c525c ),
80+ this .borders = const Color (0xff272a30 ),
81+ this .inputBg = const Color (0xff1c1e22 ),
6682 this .appBg = const Color (0xff000000 ),
6783 this .barsBg = const Color (0xff121416 ),
68- this .linkBg = const Color (0xff00193D ),
84+ this .linkBg = const Color (0xff00193d ),
6985 this .accentPrimary = const Color (0xff337eff ),
70- this .accentError = const Color (0xffFF3742 ),
71- this .accentInfo = const Color (0xff20E070 ),
86+ this .accentError = const Color (0xffff3742 ),
87+ this .accentInfo = const Color (0xff20e070 ),
88+ this .highlight = const Color (0xff302d22 ),
89+ this .overlay = const Color .fromRGBO (0 , 0 , 0 , 0.4 ),
90+ this .overlayDark = const Color .fromRGBO (255 , 255 , 255 , 0.6 ),
91+ this .bgGradient = const LinearGradient (
92+ begin: Alignment .topCenter,
93+ end: Alignment .bottomCenter,
94+ colors: [Color (0xff101214 ), Color (0xff070a0d )],
95+ stops: [0 , 1 ],
96+ ),
7297 this .borderTop = const Effect (
7398 sigmaX: 0 ,
7499 sigmaY: - 1 ,
75- color: Color (0xff141924 ),
100+ color: Color (0xff272a30 ),
76101 blur: 0 ,
102+ alpha: 1 ,
77103 ),
78104 this .borderBottom = const Effect (
79105 sigmaX: 0 ,
80106 sigmaY: 1 ,
81- color: Color (0xff141924 ),
107+ color: Color (0xff272a30 ),
82108 blur: 0 ,
83109 alpha: 1 ,
84110 ),
85111 this .shadowIconButton = const Effect (
86112 sigmaX: 0 ,
87113 sigmaY: 2 ,
88114 color: Color (0xff000000 ),
89- alpha: 0.5 ,
90115 blur: 4 ,
116+ alpha: 0.5 ,
91117 ),
92118 this .modalShadow = const Effect (
93119 sigmaX: 0 ,
94120 sigmaY: 0 ,
95121 color: Color (0xff000000 ),
96- alpha: 1 ,
97122 blur: 8 ,
98- ),
99- this .highlight = const Color (0xff302d22 ),
100- this .overlay = const Color .fromRGBO (0 , 0 , 0 , 0.4 ),
101- this .overlayDark = const Color .fromRGBO (255 , 255 , 255 , 0.6 ),
102- this .bgGradient = const LinearGradient (
103- begin: Alignment .topCenter,
104- end: Alignment .bottomCenter,
105- colors: [
106- Color (0xff101214 ),
107- Color (0xff070a0d ),
108- ],
109- stops: [0 , 1 ],
123+ alpha: 1 ,
110124 ),
111125 }) : brightness = Brightness .dark;
112126
113- ///
127+ /// Main body text or primary icons.
114128 final Color textHighEmphasis;
115129
116- ///
130+ /// Secondary or less prominent text/icons.
117131 final Color textLowEmphasis;
118132
119- ///
133+ /// Disabled UI elements (icons, inputs).
120134 final Color disabled;
121135
122- ///
136+ /// Standard UI borders and dividers.
123137 final Color borders;
124138
125- ///
139+ /// Background for input fields.
126140 final Color inputBg;
127141
128- ///
142+ /// Main app background.
129143 final Color appBg;
130144
131- ///
145+ /// Bars: headers, footers, and toolbars.
132146 final Color barsBg;
133147
134- ///
148+ /// Background for links and link cards.
135149 final Color linkBg;
136150
137- ///
151+ /// Primary action color (buttons, active states).
138152 final Color accentPrimary;
139153
140- ///
154+ /// Error color (alerts, badges).
141155 final Color accentError;
142156
143- ///
157+ /// Informational highlights (e.g., status).
144158 final Color accentInfo;
145159
146- ///
147- final Effect borderTop;
148-
149- ///
150- final Effect borderBottom;
151-
152- ///
153- final Effect shadowIconButton;
154-
155- ///
156- final Effect modalShadow;
157-
158- ///
160+ /// Highlighted rows, pinned messages.
159161 final Color highlight;
160162
161- ///
163+ /// General translucent overlay for modals, sheets.
162164 final Color overlay;
163165
164- ///
166+ /// Overlay for dark mode interactions or highlight effects.
165167 final Color overlayDark;
166168
167- ///
169+ /// Background gradient for section headers.
168170 final Gradient bgGradient;
169171
170- ///
172+ /// Theme brightness indicator.
171173 final Brightness brightness;
172174
173- /// Copy with theme
175+ /// Top border effect (for elevation).
176+ final Effect borderTop;
177+
178+ /// Bottom border effect.
179+ final Effect borderBottom;
180+
181+ /// Icon button drop shadow effect.
182+ final Effect shadowIconButton;
183+
184+ /// Modal shadow effect.
185+ final Effect modalShadow;
186+
187+ /// Returns a new [StreamColorTheme] by overriding selected fields.
174188 StreamColorTheme copyWith ({
175- Brightness brightness = Brightness .light ,
189+ Brightness ? brightness,
176190 Color ? textHighEmphasis,
177191 Color ? textLowEmphasis,
178192 Color ? disabled,
@@ -184,16 +198,16 @@ class StreamColorTheme {
184198 Color ? accentPrimary,
185199 Color ? accentError,
186200 Color ? accentInfo,
187- Effect ? borderTop,
188- Effect ? borderBottom,
189- Effect ? shadowIconButton,
190- Effect ? modalShadow,
191201 Color ? highlight,
192202 Color ? overlay,
193203 Color ? overlayDark,
194204 Gradient ? bgGradient,
205+ Effect ? borderTop,
206+ Effect ? borderBottom,
207+ Effect ? shadowIconButton,
208+ Effect ? modalShadow,
195209 }) {
196- return brightness == Brightness .light
210+ return ( brightness ?? this .brightness) == Brightness .light
197211 ? StreamColorTheme .light (
198212 textHighEmphasis: textHighEmphasis ?? this .textHighEmphasis,
199213 textLowEmphasis: textLowEmphasis ?? this .textLowEmphasis,
@@ -206,14 +220,14 @@ class StreamColorTheme {
206220 accentPrimary: accentPrimary ?? this .accentPrimary,
207221 accentError: accentError ?? this .accentError,
208222 accentInfo: accentInfo ?? this .accentInfo,
209- borderTop: borderTop ?? this .borderTop,
210- borderBottom: borderBottom ?? this .borderBottom,
211- shadowIconButton: shadowIconButton ?? this .shadowIconButton,
212- modalShadow: modalShadow ?? this .modalShadow,
213223 highlight: highlight ?? this .highlight,
214224 overlay: overlay ?? this .overlay,
215225 overlayDark: overlayDark ?? this .overlayDark,
216226 bgGradient: bgGradient ?? this .bgGradient,
227+ borderTop: borderTop ?? this .borderTop,
228+ borderBottom: borderBottom ?? this .borderBottom,
229+ shadowIconButton: shadowIconButton ?? this .shadowIconButton,
230+ modalShadow: modalShadow ?? this .modalShadow,
217231 )
218232 : StreamColorTheme .dark (
219233 textHighEmphasis: textHighEmphasis ?? this .textHighEmphasis,
@@ -227,18 +241,18 @@ class StreamColorTheme {
227241 accentPrimary: accentPrimary ?? this .accentPrimary,
228242 accentError: accentError ?? this .accentError,
229243 accentInfo: accentInfo ?? this .accentInfo,
230- borderTop: borderTop ?? this .borderTop,
231- borderBottom: borderBottom ?? this .borderBottom,
232- shadowIconButton: shadowIconButton ?? this .shadowIconButton,
233- modalShadow: modalShadow ?? this .modalShadow,
234244 highlight: highlight ?? this .highlight,
235245 overlay: overlay ?? this .overlay,
236246 overlayDark: overlayDark ?? this .overlayDark,
237247 bgGradient: bgGradient ?? this .bgGradient,
248+ borderTop: borderTop ?? this .borderTop,
249+ borderBottom: borderBottom ?? this .borderBottom,
250+ shadowIconButton: shadowIconButton ?? this .shadowIconButton,
251+ modalShadow: modalShadow ?? this .modalShadow,
238252 );
239253 }
240254
241- /// Merge color theme
255+ /// Merges this theme with [other] , replacing any fields that [other] defines.
242256 StreamColorTheme merge (StreamColorTheme ? other) {
243257 if (other == null ) return this ;
244258 return copyWith (
@@ -265,9 +279,9 @@ class StreamColorTheme {
265279 }
266280}
267281
268- /// Effect store
282+ /// Visual effect such as blur or shadow used by the theme.
269283class Effect {
270- /// Constructor for creating [Effect]
284+ /// Creates an [Effect] instance.
271285 const Effect ({
272286 this .sigmaX,
273287 this .sigmaY,
@@ -276,22 +290,22 @@ class Effect {
276290 this .blur,
277291 });
278292
279- ///
293+ /// Horizontal shadow offset.
280294 final double ? sigmaX;
281295
282- ///
296+ /// Vertical shadow offset.
283297 final double ? sigmaY;
284298
285- ///
299+ /// Color of the shadow or border.
286300 final Color ? color;
287301
288- ///
302+ /// Opacity (0–1) of the effect.
289303 final double ? alpha;
290304
291- ///
305+ /// Blur radius.
292306 final double ? blur;
293307
294- /// Copy with new effect
308+ /// Returns a copy with updated fields.
295309 Effect copyWith ({
296310 double ? sigmaX,
297311 double ? sigmaY,
@@ -303,7 +317,7 @@ class Effect {
303317 sigmaX: sigmaX ?? this .sigmaX,
304318 sigmaY: sigmaY ?? this .sigmaY,
305319 color: color ?? this .color,
306- alpha: color as double ? ?? this .alpha,
320+ alpha: alpha ?? this .alpha,
307321 blur: blur ?? this .blur,
308322 );
309323 }
0 commit comments