Merge "Add internal function to create an instance of MaterialTheme that defaults to the Material 3 Expressive subsystem values. Added samples and updated kdoc for the baseline MaterialTheme function and MaterialTheme Object's member variables." into androidx-main
diff --git a/compose/material3/material3/samples/src/main/java/androidx/compose/material3/samples/ThemeSamples.kt b/compose/material3/material3/samples/src/main/java/androidx/compose/material3/samples/ThemeSamples.kt
new file mode 100644
index 0000000..52ef2df
--- /dev/null
+++ b/compose/material3/material3/samples/src/main/java/androidx/compose/material3/samples/ThemeSamples.kt
@@ -0,0 +1,134 @@
+/*
+ * Copyright 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.compose.material3.samples
+
+import android.os.Build
+import androidx.annotation.Sampled
+import androidx.compose.foundation.background
+import androidx.compose.foundation.isSystemInDarkTheme
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.aspectRatio
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.shape.RoundedCornerShape
+import androidx.compose.material.icons.Icons
+import androidx.compose.material.icons.filled.Favorite
+import androidx.compose.material3.Button
+import androidx.compose.material3.ExtendedFloatingActionButton
+import androidx.compose.material3.Icon
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.Shapes
+import androidx.compose.material3.Text
+import androidx.compose.material3.Typography
+import androidx.compose.material3.darkColorScheme
+import androidx.compose.material3.dynamicDarkColorScheme
+import androidx.compose.material3.dynamicLightColorScheme
+import androidx.compose.material3.lightColorScheme
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.platform.LocalContext
+import androidx.compose.ui.text.TextStyle
+import androidx.compose.ui.text.font.FontWeight
+import androidx.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.unit.dp
+import androidx.compose.ui.unit.sp
+
+@Preview
+@Sampled
+@Composable
+fun MaterialThemeSample() {
+
+ val isDarkTheme = isSystemInDarkTheme()
+ val supportsDynamicColor = Build.VERSION.SDK_INT >= Build.VERSION_CODES.S
+
+ val lightColorScheme = lightColorScheme(
+ primary = Color(0xFF1EB980)
+ )
+
+ val darkColorScheme = darkColorScheme(
+ primary = Color(0xFF66ffc7)
+ )
+
+ val colorScheme = when {
+ supportsDynamicColor && isDarkTheme -> {
+ dynamicDarkColorScheme(LocalContext.current)
+ }
+ supportsDynamicColor && !isDarkTheme -> {
+ dynamicLightColorScheme(LocalContext.current)
+ }
+ isDarkTheme -> darkColorScheme
+ else -> lightColorScheme
+ }
+
+ val typography = Typography(
+ displaySmall = TextStyle(
+ fontWeight = FontWeight.W100,
+ fontSize = 96.sp
+ ),
+ labelLarge = TextStyle(
+ fontWeight = FontWeight.W600,
+ fontSize = 14.sp
+ )
+ )
+
+ val shapes = Shapes(
+ extraSmall = RoundedCornerShape(3.0.dp),
+ small = RoundedCornerShape(6.0.dp)
+ )
+
+ MaterialTheme(colorScheme = colorScheme, typography = typography, shapes = shapes) {
+ val currentTheme = if (!isSystemInDarkTheme()) "light" else "dark"
+ ExtendedFloatingActionButton(
+ text = { Text("FAB with text style and color from $currentTheme theme") },
+ icon = { Icon(Icons.Filled.Favorite, contentDescription = "Localized Description") },
+ onClick = {}
+ )
+ }
+}
+
+@Preview
+@Sampled
+@Composable
+fun ThemeColorSample() {
+ val colorScheme = MaterialTheme.colorScheme
+ Box(
+ Modifier
+ .aspectRatio(1f)
+ .fillMaxSize()
+ .background(color = colorScheme.primary))
+}
+
+@Preview
+@Sampled
+@Composable
+fun ThemeTextStyleSample() {
+ val typography = MaterialTheme.typography
+ Text(text = "Headline small styled text", style = typography.headlineSmall)
+}
+
+@Preview
+@Sampled
+@Composable
+fun ThemeShapeSample() {
+ val shape = MaterialTheme.shapes
+ Button(
+ shape = shape.small,
+ onClick = {}
+ ) {
+ Text("FAB with ${shape.small} shape")
+ }
+}
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/MaterialTheme.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/MaterialTheme.kt
index 6f88a0a..acb24f7 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/MaterialTheme.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/MaterialTheme.kt
@@ -23,11 +23,8 @@
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.ReadOnlyComposable
import androidx.compose.runtime.remember
+import androidx.compose.runtime.staticCompositionLocalOf
-// TODO: Create a sample androidx.compose.material3.samples.MaterialThemeSample
-// TODO(b/197880751) Update to link M3 Material Theming page (i.e. a <a href="https://material
-// .io/design/material-theming/overview.html" class="external" target="_blank">Material
-// Theming</a> M3 equivalent).
/**
* Material Theming refers to the customization of your Material Design app to better reflect your
* product’s brand.
@@ -36,7 +33,7 @@
* default values.
*
* All values may be set by providing this component with the [colorScheme][ColorScheme],
- * [typography][Typography] attributes. Use this to configure the overall
+ * [typography][Typography] and [shapes][Shapes] attributes. Use this to configure the overall
* theme of elements within this MaterialTheme.
*
* Any values that are not set will inherit the current value from the theme, falling back to the
@@ -44,6 +41,8 @@
* of your application, and then separate MaterialTheme(s) for different screens / parts of your
* UI, overriding only the parts of the theme definition that need to change.
*
+ * @sample androidx.compose.material3.samples.MaterialThemeSample
+ *
* @param colorScheme A complete definition of the Material Color theme for this hierarchy
* @param typography A set of text styles to be used as this hierarchy's typography system
* @param shapes A set of corner shapes to be used as this hierarchy's shape system
@@ -78,6 +77,8 @@
object MaterialTheme {
/**
* Retrieves the current [ColorScheme] at the call site's position in the hierarchy.
+ *
+ * @sample androidx.compose.material3.samples.ThemeColorSample
*/
val colorScheme: ColorScheme
@Composable
@@ -86,6 +87,8 @@
/**
* Retrieves the current [Typography] at the call site's position in the hierarchy.
+ *
+ * @sample androidx.compose.material3.samples.ThemeTextStyleSample
*/
val typography: Typography
@Composable
@@ -94,6 +97,8 @@
/**
* Retrieves the current [Shapes] at the call site's position in the hierarchy.
+ *
+ * @sample androidx.compose.material3.samples.ThemeShapeSample
*/
val shapes: Shapes
@Composable
@@ -101,6 +106,62 @@
get() = LocalShapes.current
}
+// TODO: Create a sample androidx.compose.material3.samples.MaterialExpressiveThemeSample
+/**
+ * Material Expressive Theming refers to the customization of your Material Design app to better
+ * reflect your product’s brand.
+ *
+ * Material components such as [Button] and [Checkbox] use values provided here when retrieving
+ * default values.
+ *
+ * All values may be set by providing this component with the [colorScheme][ColorScheme],
+ * [typography][Typography], [shapes][Shapes] attributes. Use this to configure the overall
+ * theme of elements within this MaterialTheme.
+ *
+ * Any values that are not set will fall back to the defaults. To inherit the current value from the
+ * theme, pass them into subsequent calls and override only the parts of the theme definition that
+ * need to change.
+ *
+ * Alternatively, only call this function at the top
+ * of your application, and then call [MaterialTheme] to specify separate MaterialTheme(s) for
+ * different screens / parts of your UI, overriding only the parts of the theme definition that need
+ * to change.
+ *
+ * @param colorScheme A complete definition of the Material Color theme for this hierarchy
+ * @param typography A set of text styles to be used as this hierarchy's typography system
+ * @param shapes A set of corner shapes to be used as this hierarchy's shape system
+ */
+// TODO: Mark as experimental if scope is changed to public
+@Composable
+internal fun MaterialExpressiveTheme(
+ colorScheme: ColorScheme? = null,
+ shapes: Shapes? = null,
+ typography: Typography? = null,
+ content: @Composable () -> Unit
+) {
+ if (LocalUsingExpressiveTheme.current) {
+ MaterialTheme(
+ colorScheme = colorScheme ?: MaterialTheme.colorScheme,
+ typography = typography ?: MaterialTheme.typography,
+ shapes = shapes ?: MaterialTheme.shapes,
+ content = content
+ )
+ } else {
+ CompositionLocalProvider(LocalUsingExpressiveTheme provides true) {
+ MaterialTheme(
+ colorScheme = colorScheme ?: lightColorScheme(),
+ // TODO: replace with calls to Expressive shape default
+ shapes = shapes ?: Shapes(),
+ // TODO: replace with calls to Expressive typography default
+ typography = typography ?: Typography(),
+ content = content
+ )
+ }
+ }
+}
+
+internal val LocalUsingExpressiveTheme = staticCompositionLocalOf { false }
+
@Composable
/*@VisibleForTesting*/
internal fun rememberTextSelectionColors(colorScheme: ColorScheme): TextSelectionColors {