1 /*
2  * Copyright 2023 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package androidx.tv.material3
18 
19 import androidx.compose.runtime.Composable
20 import androidx.compose.runtime.ReadOnlyComposable
21 import androidx.compose.runtime.Stable
22 import androidx.compose.runtime.getValue
23 import androidx.compose.runtime.mutableStateOf
24 import androidx.compose.runtime.setValue
25 import androidx.compose.runtime.staticCompositionLocalOf
26 import androidx.compose.runtime.structuralEqualityPolicy
27 import androidx.compose.ui.graphics.Color
28 import androidx.compose.ui.graphics.compositeOver
29 import androidx.compose.ui.graphics.takeOrElse
30 import androidx.compose.ui.unit.Dp
31 import androidx.compose.ui.unit.dp
32 import androidx.tv.material3.tokens.ColorDarkTokens
33 import androidx.tv.material3.tokens.ColorLightTokens
34 import androidx.tv.material3.tokens.ColorSchemeKeyTokens
35 import kotlin.math.ln
36 
37 /** Returns a light Material color scheme. */
lightColorSchemenull38 fun lightColorScheme(
39     primary: Color = ColorLightTokens.Primary,
40     onPrimary: Color = ColorLightTokens.OnPrimary,
41     primaryContainer: Color = ColorLightTokens.PrimaryContainer,
42     onPrimaryContainer: Color = ColorLightTokens.OnPrimaryContainer,
43     inversePrimary: Color = ColorLightTokens.InversePrimary,
44     secondary: Color = ColorLightTokens.Secondary,
45     onSecondary: Color = ColorLightTokens.OnSecondary,
46     secondaryContainer: Color = ColorLightTokens.SecondaryContainer,
47     onSecondaryContainer: Color = ColorLightTokens.OnSecondaryContainer,
48     tertiary: Color = ColorLightTokens.Tertiary,
49     onTertiary: Color = ColorLightTokens.OnTertiary,
50     tertiaryContainer: Color = ColorLightTokens.TertiaryContainer,
51     onTertiaryContainer: Color = ColorLightTokens.OnTertiaryContainer,
52     background: Color = ColorLightTokens.Background,
53     onBackground: Color = ColorLightTokens.OnBackground,
54     surface: Color = ColorLightTokens.Surface,
55     onSurface: Color = ColorLightTokens.OnSurface,
56     surfaceVariant: Color = ColorLightTokens.SurfaceVariant,
57     onSurfaceVariant: Color = ColorLightTokens.OnSurfaceVariant,
58     surfaceTint: Color = primary,
59     inverseSurface: Color = ColorLightTokens.InverseSurface,
60     inverseOnSurface: Color = ColorLightTokens.InverseOnSurface,
61     error: Color = ColorLightTokens.Error,
62     onError: Color = ColorLightTokens.OnError,
63     errorContainer: Color = ColorLightTokens.ErrorContainer,
64     onErrorContainer: Color = ColorLightTokens.OnErrorContainer,
65     border: Color = ColorLightTokens.Border,
66     borderVariant: Color = ColorLightTokens.BorderVariant,
67     scrim: Color = ColorLightTokens.Scrim
68 ): ColorScheme =
69     ColorScheme(
70         primary = primary,
71         onPrimary = onPrimary,
72         primaryContainer = primaryContainer,
73         onPrimaryContainer = onPrimaryContainer,
74         inversePrimary = inversePrimary,
75         secondary = secondary,
76         onSecondary = onSecondary,
77         secondaryContainer = secondaryContainer,
78         onSecondaryContainer = onSecondaryContainer,
79         tertiary = tertiary,
80         onTertiary = onTertiary,
81         tertiaryContainer = tertiaryContainer,
82         onTertiaryContainer = onTertiaryContainer,
83         background = background,
84         onBackground = onBackground,
85         surface = surface,
86         onSurface = onSurface,
87         surfaceVariant = surfaceVariant,
88         onSurfaceVariant = onSurfaceVariant,
89         surfaceTint = surfaceTint,
90         inverseSurface = inverseSurface,
91         inverseOnSurface = inverseOnSurface,
92         error = error,
93         onError = onError,
94         errorContainer = errorContainer,
95         onErrorContainer = onErrorContainer,
96         border = border,
97         borderVariant = borderVariant,
98         scrim = scrim
99     )
100 
101 /**
102  * A color scheme holds all the named color parameters for a [MaterialTheme].
103  *
104  * Color schemes are designed to be harmonious, ensure accessible text, and distinguish UI elements
105  * and surfaces from one another. There are two built-in baseline schemes, [lightColorScheme] and a
106  * [darkColorScheme], that can be used as-is or customized.
107  *
108  * The Material color system and custom schemes provide default values for color as a starting point
109  * for customization.
110  *
111  * To learn more about colors, see
112  * [Material Design colors](https://m3.material.io/styles/color/overview).
113  *
114  * @property primary The primary color is the color displayed most frequently across your app’s
115  *   screens and components.
116  * @property onPrimary Color used for text and icons displayed on top of the primary color.
117  * @property primaryContainer The preferred tonal color of containers.
118  * @property onPrimaryContainer The color (and state variants) that should be used for content on
119  *   top of [primaryContainer].
120  * @property inversePrimary Color to be used as a "primary" color in places where the inverse color
121  *   scheme is needed, such as the button on a SnackBar.
122  * @property secondary The secondary color provides more ways to accent and distinguish your
123  *   product. Secondary colors are best for:
124  * - Floating action buttons
125  * - Selection controls, like checkboxes and radio buttons
126  * - Highlighting selected text
127  * - Links and headlines
128  *
129  * @property onSecondary Color used for text and icons displayed on top of the secondary color.
130  * @property secondaryContainer A tonal color to be used in containers.
131  * @property onSecondaryContainer The color (and state variants) that should be used for content on
132  *   top of [secondaryContainer].
133  * @property tertiary The tertiary color that can be used to balance primary and secondary colors,
134  *   or bring heightened attention to an element such as an input field.
135  * @property onTertiary Color used for text and icons displayed on top of the tertiary color.
136  * @property tertiaryContainer A tonal color to be used in containers.
137  * @property onTertiaryContainer The color (and state variants) that should be used for content on
138  *   top of [tertiaryContainer].
139  * @property background The background color that appears behind scrollable content.
140  * @property onBackground Color used for text and icons displayed on top of the background color.
141  * @property surface The surface color that affect surfaces of components, such as cards, sheets,
142  *   and menus.
143  * @property onSurface Color used for text and icons displayed on top of the surface color.
144  * @property surfaceVariant Another option for a color with similar uses of [surface].
145  * @property onSurfaceVariant The color (and state variants) that can be used for content on top of
146  *   [surface].
147  * @property surfaceTint This color will be used by components that apply tonal elevation and is
148  *   applied on top of [surface]. The higher the elevation the more this color is used.
149  * @property inverseSurface A color that contrasts sharply with [surface]. Useful for surfaces that
150  *   sit on top of other surfaces with [surface] color.
151  * @property inverseOnSurface A color that contrasts well with [inverseSurface]. Useful for content
152  *   that sits on top of containers that are [inverseSurface].
153  * @property error The error color is used to indicate errors in components, such as invalid text in
154  *   a text field.
155  * @property onError Color used for text and icons displayed on top of the error color.
156  * @property errorContainer The preferred tonal color of error containers.
157  * @property onErrorContainer The color (and state variants) that should be used for content on top
158  *   of [errorContainer].
159  * @property border Subtle color used for boundaries. Border color role adds contrast for
160  *   accessibility purposes.
161  * @property borderVariant Utility color used for boundaries for decorative elements when strong
162  *   contrast is not required.
163  * @property scrim Color of a scrim that obscures content.
164  */
165 @Stable
166 class ColorScheme(
167     primary: Color,
168     onPrimary: Color,
169     primaryContainer: Color,
170     onPrimaryContainer: Color,
171     inversePrimary: Color,
172     secondary: Color,
173     onSecondary: Color,
174     secondaryContainer: Color,
175     onSecondaryContainer: Color,
176     tertiary: Color,
177     onTertiary: Color,
178     tertiaryContainer: Color,
179     onTertiaryContainer: Color,
180     background: Color,
181     onBackground: Color,
182     surface: Color,
183     onSurface: Color,
184     surfaceVariant: Color,
185     onSurfaceVariant: Color,
186     surfaceTint: Color,
187     inverseSurface: Color,
188     inverseOnSurface: Color,
189     error: Color,
190     onError: Color,
191     errorContainer: Color,
192     onErrorContainer: Color,
193     border: Color,
194     borderVariant: Color,
195     scrim: Color
196 ) {
197     var primary by mutableStateOf(primary, structuralEqualityPolicy())
198         internal set
199 
200     var onPrimary by mutableStateOf(onPrimary, structuralEqualityPolicy())
201         internal set
202 
203     var primaryContainer by mutableStateOf(primaryContainer, structuralEqualityPolicy())
204         internal set
205 
206     var onPrimaryContainer by mutableStateOf(onPrimaryContainer, structuralEqualityPolicy())
207         internal set
208 
209     var inversePrimary by mutableStateOf(inversePrimary, structuralEqualityPolicy())
210         internal set
211 
212     var secondary by mutableStateOf(secondary, structuralEqualityPolicy())
213         internal set
214 
215     var onSecondary by mutableStateOf(onSecondary, structuralEqualityPolicy())
216         internal set
217 
218     var secondaryContainer by mutableStateOf(secondaryContainer, structuralEqualityPolicy())
219         internal set
220 
221     var onSecondaryContainer by mutableStateOf(onSecondaryContainer, structuralEqualityPolicy())
222         internal set
223 
224     var tertiary by mutableStateOf(tertiary, structuralEqualityPolicy())
225         internal set
226 
227     var onTertiary by mutableStateOf(onTertiary, structuralEqualityPolicy())
228         internal set
229 
230     var tertiaryContainer by mutableStateOf(tertiaryContainer, structuralEqualityPolicy())
231         internal set
232 
233     var onTertiaryContainer by mutableStateOf(onTertiaryContainer, structuralEqualityPolicy())
234         internal set
235 
236     var background by mutableStateOf(background, structuralEqualityPolicy())
237         internal set
238 
239     var onBackground by mutableStateOf(onBackground, structuralEqualityPolicy())
240         internal set
241 
242     var surface by mutableStateOf(surface, structuralEqualityPolicy())
243         internal set
244 
245     var onSurface by mutableStateOf(onSurface, structuralEqualityPolicy())
246         internal set
247 
248     var surfaceVariant by mutableStateOf(surfaceVariant, structuralEqualityPolicy())
249         internal set
250 
251     var onSurfaceVariant by mutableStateOf(onSurfaceVariant, structuralEqualityPolicy())
252         internal set
253 
254     var surfaceTint by mutableStateOf(surfaceTint, structuralEqualityPolicy())
255         internal set
256 
257     var inverseSurface by mutableStateOf(inverseSurface, structuralEqualityPolicy())
258         internal set
259 
260     var inverseOnSurface by mutableStateOf(inverseOnSurface, structuralEqualityPolicy())
261         internal set
262 
263     var error by mutableStateOf(error, structuralEqualityPolicy())
264         internal set
265 
266     var onError by mutableStateOf(onError, structuralEqualityPolicy())
267         internal set
268 
269     var errorContainer by mutableStateOf(errorContainer, structuralEqualityPolicy())
270         internal set
271 
272     var onErrorContainer by mutableStateOf(onErrorContainer, structuralEqualityPolicy())
273         internal set
274 
275     var border by mutableStateOf(border, structuralEqualityPolicy())
276         internal set
277 
278     var borderVariant by mutableStateOf(borderVariant, structuralEqualityPolicy())
279         internal set
280 
281     var scrim by mutableStateOf(scrim, structuralEqualityPolicy())
282         internal set
283 
284     internal var defaultCheckboxColorsCached: CheckboxColors? = null
285 
286     /** Returns a copy of this ColorScheme, optionally overriding some of the values. */
287     fun copy(
288         primary: Color = this.primary,
289         onPrimary: Color = this.onPrimary,
290         primaryContainer: Color = this.primaryContainer,
291         onPrimaryContainer: Color = this.onPrimaryContainer,
292         inversePrimary: Color = this.inversePrimary,
293         secondary: Color = this.secondary,
294         onSecondary: Color = this.onSecondary,
295         secondaryContainer: Color = this.secondaryContainer,
296         onSecondaryContainer: Color = this.onSecondaryContainer,
297         tertiary: Color = this.tertiary,
298         onTertiary: Color = this.onTertiary,
299         tertiaryContainer: Color = this.tertiaryContainer,
300         onTertiaryContainer: Color = this.onTertiaryContainer,
301         background: Color = this.background,
302         onBackground: Color = this.onBackground,
303         surface: Color = this.surface,
304         onSurface: Color = this.onSurface,
305         surfaceVariant: Color = this.surfaceVariant,
306         onSurfaceVariant: Color = this.onSurfaceVariant,
307         surfaceTint: Color = this.surfaceTint,
308         inverseSurface: Color = this.inverseSurface,
309         inverseOnSurface: Color = this.inverseOnSurface,
310         error: Color = this.error,
311         onError: Color = this.onError,
312         errorContainer: Color = this.errorContainer,
313         onErrorContainer: Color = this.onErrorContainer,
314         border: Color = this.border,
315         borderVariant: Color = this.borderVariant,
316         scrim: Color = this.scrim
317     ): ColorScheme =
318         ColorScheme(
319             primary = primary,
320             onPrimary = onPrimary,
321             primaryContainer = primaryContainer,
322             onPrimaryContainer = onPrimaryContainer,
323             inversePrimary = inversePrimary,
324             secondary = secondary,
325             onSecondary = onSecondary,
326             secondaryContainer = secondaryContainer,
327             onSecondaryContainer = onSecondaryContainer,
328             tertiary = tertiary,
329             onTertiary = onTertiary,
330             tertiaryContainer = tertiaryContainer,
331             onTertiaryContainer = onTertiaryContainer,
332             background = background,
333             onBackground = onBackground,
334             surface = surface,
335             onSurface = onSurface,
336             surfaceVariant = surfaceVariant,
337             onSurfaceVariant = onSurfaceVariant,
338             surfaceTint = surfaceTint,
339             inverseSurface = inverseSurface,
340             inverseOnSurface = inverseOnSurface,
341             error = error,
342             onError = onError,
343             errorContainer = errorContainer,
344             onErrorContainer = onErrorContainer,
345             border = border,
346             borderVariant = borderVariant,
347             scrim = scrim
348         )
349 
350     override fun toString(): String {
351         return "ColorScheme(" +
352             "primary=$primary" +
353             "onPrimary=$onPrimary" +
354             "primaryContainer=$primaryContainer" +
355             "onPrimaryContainer=$onPrimaryContainer" +
356             "inversePrimary=$inversePrimary" +
357             "secondary=$secondary" +
358             "onSecondary=$onSecondary" +
359             "secondaryContainer=$secondaryContainer" +
360             "onSecondaryContainer=$onSecondaryContainer" +
361             "tertiary=$tertiary" +
362             "onTertiary=$onTertiary" +
363             "tertiaryContainer=$tertiaryContainer" +
364             "onTertiaryContainer=$onTertiaryContainer" +
365             "background=$background" +
366             "onBackground=$onBackground" +
367             "surface=$surface" +
368             "onSurface=$onSurface" +
369             "surfaceVariant=$surfaceVariant" +
370             "onSurfaceVariant=$onSurfaceVariant" +
371             "surfaceTint=$surfaceTint" +
372             "inverseSurface=$inverseSurface" +
373             "inverseOnSurface=$inverseOnSurface" +
374             "error=$error" +
375             "onError=$onError" +
376             "errorContainer=$errorContainer" +
377             "onErrorContainer=$onErrorContainer" +
378             "border=$border" +
379             "borderVariant=$borderVariant" +
380             "scrim=$scrim" +
381             ")"
382     }
383 
384     internal var defaultSwitchColorsCached: SwitchColors? = null
385     internal var defaultRadioButtonColorsCached: RadioButtonColors? = null
386 }
387 
388 /** Returns a dark Material color scheme. */
darkColorSchemenull389 fun darkColorScheme(
390     primary: Color = ColorDarkTokens.Primary,
391     onPrimary: Color = ColorDarkTokens.OnPrimary,
392     primaryContainer: Color = ColorDarkTokens.PrimaryContainer,
393     onPrimaryContainer: Color = ColorDarkTokens.OnPrimaryContainer,
394     inversePrimary: Color = ColorDarkTokens.InversePrimary,
395     secondary: Color = ColorDarkTokens.Secondary,
396     onSecondary: Color = ColorDarkTokens.OnSecondary,
397     secondaryContainer: Color = ColorDarkTokens.SecondaryContainer,
398     onSecondaryContainer: Color = ColorDarkTokens.OnSecondaryContainer,
399     tertiary: Color = ColorDarkTokens.Tertiary,
400     onTertiary: Color = ColorDarkTokens.OnTertiary,
401     tertiaryContainer: Color = ColorDarkTokens.TertiaryContainer,
402     onTertiaryContainer: Color = ColorDarkTokens.OnTertiaryContainer,
403     background: Color = ColorDarkTokens.Background,
404     onBackground: Color = ColorDarkTokens.OnBackground,
405     surface: Color = ColorDarkTokens.Surface,
406     onSurface: Color = ColorDarkTokens.OnSurface,
407     surfaceVariant: Color = ColorDarkTokens.SurfaceVariant,
408     onSurfaceVariant: Color = ColorDarkTokens.OnSurfaceVariant,
409     surfaceTint: Color = primary,
410     inverseSurface: Color = ColorDarkTokens.InverseSurface,
411     inverseOnSurface: Color = ColorDarkTokens.InverseOnSurface,
412     error: Color = ColorDarkTokens.Error,
413     onError: Color = ColorDarkTokens.OnError,
414     errorContainer: Color = ColorDarkTokens.ErrorContainer,
415     onErrorContainer: Color = ColorDarkTokens.OnErrorContainer,
416     border: Color = ColorDarkTokens.Border,
417     borderVariant: Color = ColorDarkTokens.BorderVariant,
418     scrim: Color = ColorDarkTokens.Scrim
419 ): ColorScheme =
420     ColorScheme(
421         primary = primary,
422         onPrimary = onPrimary,
423         primaryContainer = primaryContainer,
424         onPrimaryContainer = onPrimaryContainer,
425         inversePrimary = inversePrimary,
426         secondary = secondary,
427         onSecondary = onSecondary,
428         secondaryContainer = secondaryContainer,
429         onSecondaryContainer = onSecondaryContainer,
430         tertiary = tertiary,
431         onTertiary = onTertiary,
432         tertiaryContainer = tertiaryContainer,
433         onTertiaryContainer = onTertiaryContainer,
434         background = background,
435         onBackground = onBackground,
436         surface = surface,
437         onSurface = onSurface,
438         surfaceVariant = surfaceVariant,
439         onSurfaceVariant = onSurfaceVariant,
440         surfaceTint = surfaceTint,
441         inverseSurface = inverseSurface,
442         inverseOnSurface = inverseOnSurface,
443         error = error,
444         onError = onError,
445         errorContainer = errorContainer,
446         onErrorContainer = onErrorContainer,
447         border = border,
448         borderVariant = borderVariant,
449         scrim = scrim
450     )
451 
452 /**
453  * The Material color system contains pairs of colors that are typically used for the background and
454  * content color inside a component. For example, a Button typically uses `primary` for its
455  * background, and `onPrimary` for the color of its content (usually text or iconography).
456  *
457  * This function tries to match the provided [backgroundColor] to a 'background' color in this
458  * [ColorScheme], and then will return the corresponding color used for content. For example, when
459  * [backgroundColor] is [ColorScheme.primary], this will return [ColorScheme.onPrimary].
460  *
461  * If [backgroundColor] does not match a background color in the theme, this will return
462  * [Color.Unspecified].
463  *
464  * @return the matching content color for [backgroundColor]. If [backgroundColor] is not present in
465  *   the theme's [ColorScheme], then returns [Color.Unspecified].
466  * @see contentColorFor
467  */
468 fun ColorScheme.contentColorFor(backgroundColor: Color): Color =
469     when (backgroundColor) {
470         primary -> onPrimary
471         secondary -> onSecondary
472         tertiary -> onTertiary
473         background -> onBackground
474         error -> onError
475         surface -> onSurface
476         surfaceVariant -> onSurfaceVariant
477         primaryContainer -> onPrimaryContainer
478         secondaryContainer -> onSecondaryContainer
479         tertiaryContainer -> onTertiaryContainer
480         errorContainer -> onErrorContainer
481         inverseSurface -> inverseOnSurface
482         else -> Color.Unspecified
483     }
484 
485 /**
486  * The Material color system contains pairs of colors that are typically used for the background and
487  * content color inside a component. For example, a Button typically uses `primary` for its
488  * background, and `onPrimary` for the color of its content (usually text or iconography).
489  *
490  * This function tries to match the provided [backgroundColor] to a 'background' color in this
491  * [ColorScheme], and then will return the corresponding color used for content. For example, when
492  * [backgroundColor] is [ColorScheme.primary], this will return [ColorScheme.onPrimary].
493  *
494  * If [backgroundColor] does not match a background color in the theme, this will return the current
495  * value of [LocalContentColor] as a best-effort color.
496  *
497  * @return the matching content color for [backgroundColor]. If [backgroundColor] is not present in
498  *   the theme's [ColorScheme], then returns the current value of [LocalContentColor].
499  * @see ColorScheme.contentColorFor
500  */
501 @Composable
502 @ReadOnlyComposable
contentColorFornull503 fun contentColorFor(backgroundColor: Color) =
504     MaterialTheme.colorScheme.contentColorFor(backgroundColor).takeOrElse {
505         LocalContentColor.current
506     }
507 
508 /**
509  * Returns the new background [Color] to use, representing the original background [color] with an
510  * overlay corresponding to [elevation] applied. The overlay will only be applied to
511  * [ColorScheme.surface].
512  */
applyTonalElevationnull513 internal fun ColorScheme.applyTonalElevation(backgroundColor: Color, elevation: Dp): Color {
514     return if (backgroundColor == surface) {
515         surfaceColorAtElevation(elevation)
516     } else {
517         backgroundColor
518     }
519 }
520 
521 /**
522  * Computes the surface tonal color at different elevation levels e.g. surface1 through surface5.
523  *
524  * @param elevation Elevation value used to compute alpha of the color overlay layer.
525  * @return the [ColorScheme.surface] color with an alpha of the [ColorScheme.surfaceTint] color
526  *   overlaid on top of it.
527  */
surfaceColorAtElevationnull528 fun ColorScheme.surfaceColorAtElevation(elevation: Dp): Color {
529     if (elevation == 0.dp) return surface
530     val alpha = ((4.5f * ln(elevation.value + 1)) + 2f) / 100f
531     return surfaceTint.copy(alpha = alpha).compositeOver(surface)
532 }
533 
534 /**
535  * Updates the internal values of a given [ColorScheme] with values from the [other] [ColorScheme].
536  * This allows efficiently updating a subset of [ColorScheme], without recomposing every composable
537  * that consumes values from [LocalColorScheme].
538  *
539  * Because [ColorScheme] is very wide-reaching, and used by many expensive composables in the
540  * hierarchy, providing a new value to [LocalColorScheme] causes every composable consuming
541  * [LocalColorScheme] to recompose, which is prohibitively expensive in cases such as animating one
542  * color in the theme. Instead, [ColorScheme] is internally backed by [mutableStateOf], and this
543  * function mutates the internal state of [this] to match values in [other]. This means that any
544  * changes will mutate the internal state of [this], and only cause composables that are reading the
545  * specific changed value to recompose.
546  */
updateColorSchemeFromnull547 internal fun ColorScheme.updateColorSchemeFrom(other: ColorScheme) {
548     primary = other.primary
549     onPrimary = other.onPrimary
550     primaryContainer = other.primaryContainer
551     onPrimaryContainer = other.onPrimaryContainer
552     inversePrimary = other.inversePrimary
553     secondary = other.secondary
554     onSecondary = other.onSecondary
555     secondaryContainer = other.secondaryContainer
556     onSecondaryContainer = other.onSecondaryContainer
557     tertiary = other.tertiary
558     onTertiary = other.onTertiary
559     tertiaryContainer = other.tertiaryContainer
560     onTertiaryContainer = other.onTertiaryContainer
561     background = other.background
562     onBackground = other.onBackground
563     surface = other.surface
564     onSurface = other.onSurface
565     surfaceVariant = other.surfaceVariant
566     onSurfaceVariant = other.onSurfaceVariant
567     surfaceTint = other.surfaceTint
568     inverseSurface = other.inverseSurface
569     inverseOnSurface = other.inverseOnSurface
570     error = other.error
571     onError = other.onError
572     errorContainer = other.errorContainer
573     onErrorContainer = other.onErrorContainer
574     border = other.border
575     borderVariant = other.borderVariant
576     scrim = other.scrim
577 }
578 
579 /**
580  * Helper function for component color tokens. Here is an example on how to use component color
581  * tokens: ``MaterialTheme.colorScheme.fromToken(ExtendedFabBranded.BrandedContainerColor)``
582  */
fromTokennull583 internal fun ColorScheme.fromToken(value: ColorSchemeKeyTokens): Color {
584     return when (value) {
585         ColorSchemeKeyTokens.Background -> background
586         ColorSchemeKeyTokens.Error -> error
587         ColorSchemeKeyTokens.ErrorContainer -> errorContainer
588         ColorSchemeKeyTokens.InverseOnSurface -> inverseOnSurface
589         ColorSchemeKeyTokens.InversePrimary -> inversePrimary
590         ColorSchemeKeyTokens.InverseSurface -> inverseSurface
591         ColorSchemeKeyTokens.OnBackground -> onBackground
592         ColorSchemeKeyTokens.OnError -> onError
593         ColorSchemeKeyTokens.OnErrorContainer -> onErrorContainer
594         ColorSchemeKeyTokens.OnPrimary -> onPrimary
595         ColorSchemeKeyTokens.OnPrimaryContainer -> onPrimaryContainer
596         ColorSchemeKeyTokens.OnSecondary -> onSecondary
597         ColorSchemeKeyTokens.OnSecondaryContainer -> onSecondaryContainer
598         ColorSchemeKeyTokens.OnSurface -> onSurface
599         ColorSchemeKeyTokens.OnSurfaceVariant -> onSurfaceVariant
600         ColorSchemeKeyTokens.SurfaceTint -> surfaceTint
601         ColorSchemeKeyTokens.OnTertiary -> onTertiary
602         ColorSchemeKeyTokens.OnTertiaryContainer -> onTertiaryContainer
603         ColorSchemeKeyTokens.Border -> border
604         ColorSchemeKeyTokens.BorderVariant -> borderVariant
605         ColorSchemeKeyTokens.Primary -> primary
606         ColorSchemeKeyTokens.PrimaryContainer -> primaryContainer
607         ColorSchemeKeyTokens.Scrim -> scrim
608         ColorSchemeKeyTokens.Secondary -> secondary
609         ColorSchemeKeyTokens.SecondaryContainer -> secondaryContainer
610         ColorSchemeKeyTokens.Surface -> surface
611         ColorSchemeKeyTokens.SurfaceVariant -> surfaceVariant
612         ColorSchemeKeyTokens.Tertiary -> tertiary
613         ColorSchemeKeyTokens.TertiaryContainer -> tertiaryContainer
614     }
615 }
616 
617 /**
618  * CompositionLocal used to pass [ColorScheme] down the tree.
619  *
620  * Setting the value here is typically done as part of [MaterialTheme], which will automatically
621  * handle efficiently updating any changed colors without causing unnecessary recompositions, using
622  * [ColorScheme.updateColorSchemeFrom]. To retrieve the current value of this CompositionLocal, use
623  * [MaterialTheme.colorScheme].
624  */
<lambda>null625 internal val LocalColorScheme = staticCompositionLocalOf { lightColorScheme() }
626 
627 /**
628  * A low level of alpha used to represent disabled components, such as text in a disabled Button.
629  */
630 internal const val DisabledAlpha = 0.38f
631 
632 /** Converts a color token key to the local color scheme provided by the theme */
633 @ReadOnlyComposable
634 @Composable
toColornull635 internal fun ColorSchemeKeyTokens.toColor(): Color {
636     return MaterialTheme.colorScheme.fromToken(this)
637 }
638