diff --git a/compose-material/api/current.api b/compose-material/api/current.api index 69f71a466b..00c32e9c6d 100644 --- a/compose-material/api/current.api +++ b/compose-material/api/current.api @@ -80,6 +80,12 @@ package com.google.android.horologist.compose.material { enum_constant public static final com.google.android.horologist.compose.material.IconRtlMode Mirrored; } + public final class ListHeaderDefaults { + method @androidx.compose.runtime.Composable public androidx.compose.foundation.layout.PaddingValues firstItemPadding(); + method @androidx.compose.runtime.Composable public androidx.compose.foundation.layout.PaddingValues itemPadding(); + field public static final com.google.android.horologist.compose.material.ListHeaderDefaults INSTANCE; + } + public final class OutlinedChipKt { method @androidx.compose.runtime.Composable @com.google.android.horologist.annotations.ExperimentalHorologistApi public static void OutlinedChip(@StringRes int labelId, kotlin.jvm.functions.Function0 onClick, optional androidx.compose.ui.Modifier modifier, optional com.google.android.horologist.compose.material.IconRtlMode iconRtlMode, optional @StringRes Integer? secondaryLabel, optional com.google.android.horologist.images.base.paintable.Paintable? icon, optional boolean largeIcon, optional androidx.wear.compose.material.ChipColors colors, optional boolean enabled); method @androidx.compose.runtime.Composable @com.google.android.horologist.annotations.ExperimentalHorologistApi public static void OutlinedChip(String label, kotlin.jvm.functions.Function0 onClick, optional androidx.compose.ui.Modifier modifier, optional com.google.android.horologist.compose.material.IconRtlMode iconRtlMode, optional String? secondaryLabel, optional com.google.android.horologist.images.base.paintable.Paintable? icon, optional boolean largeIcon, optional androidx.wear.compose.material.ChipColors colors, optional boolean enabled); @@ -96,6 +102,10 @@ package com.google.android.horologist.compose.material { method @androidx.compose.runtime.Composable @com.google.android.horologist.annotations.ExperimentalHorologistApi public static void ResponsiveDialogContent(optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function0? icon, optional kotlin.jvm.functions.Function0? title, optional kotlin.jvm.functions.Function0? message, optional kotlin.jvm.functions.Function0? onOk, optional kotlin.jvm.functions.Function0? onCancel, optional String okButtonContentDescription, optional String cancelButtonContentDescription, optional com.google.android.horologist.compose.layout.ScalingLazyColumnState state, optional boolean showPositionIndicator, optional kotlin.jvm.functions.Function1? content); } + public final class ResponsiveListHeaderKt { + method @androidx.compose.runtime.Composable public static void ResponsiveListHeader(optional androidx.compose.ui.Modifier modifier, optional long backgroundColor, optional long contentColor, optional androidx.compose.foundation.layout.PaddingValues contentPadding, kotlin.jvm.functions.Function1 content); + } + public final class SplitToggleChipKt { method @androidx.compose.runtime.Composable @com.google.android.horologist.annotations.ExperimentalHorologistApi public static void SplitToggleChip(boolean checked, kotlin.jvm.functions.Function1 onCheckedChanged, String label, kotlin.jvm.functions.Function0 onClick, com.google.android.horologist.compose.material.ToggleChipToggleControl toggleControl, optional androidx.compose.ui.Modifier modifier, optional String? secondaryLabel, optional androidx.wear.compose.material.SplitToggleChipColors colors, optional boolean enabled, optional androidx.compose.foundation.interaction.MutableInteractionSource checkedInteractionSource, optional androidx.compose.foundation.interaction.MutableInteractionSource clickInteractionSource); } diff --git a/compose-material/src/main/java/com/google/android/horologist/compose/material/ResponsiveListHeader.kt b/compose-material/src/main/java/com/google/android/horologist/compose/material/ResponsiveListHeader.kt new file mode 100644 index 0000000000..ad9233acc2 --- /dev/null +++ b/compose-material/src/main/java/com/google/android/horologist/compose/material/ResponsiveListHeader.kt @@ -0,0 +1,97 @@ +/* + * 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 + * + * https://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 com.google.android.horologist.compose.material + +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.IntrinsicSize +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.RowScope +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.wrapContentSize +import androidx.compose.runtime.Composable +import androidx.compose.runtime.CompositionLocalProvider +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.platform.LocalConfiguration +import androidx.compose.ui.semantics.heading +import androidx.compose.ui.semantics.semantics +import androidx.compose.ui.unit.dp +import androidx.wear.compose.material.LocalContentColor +import androidx.wear.compose.material.LocalTextStyle +import androidx.wear.compose.material.MaterialTheme + +@Composable +public fun ResponsiveListHeader( + modifier: Modifier = Modifier, + backgroundColor: Color = Color.Transparent, + contentColor: Color = MaterialTheme.colors.onSurfaceVariant, + contentPadding: PaddingValues = ListHeaderDefaults.itemPadding(), + content: @Composable RowScope.() -> Unit, +) { + Row( + modifier = modifier + .height(IntrinsicSize.Min) + .wrapContentSize() + .background(backgroundColor) + .padding(contentPadding) + .semantics(mergeDescendants = true) { heading() }, + ) { + CompositionLocalProvider( + LocalContentColor provides contentColor, + LocalTextStyle provides MaterialTheme.typography.button, + ) { + content() + } + } +} + +public object ListHeaderDefaults { + /** + * Padding for the first item in the list. It is recommended to omit + * top padding for this item so that it is positioned directly below the + * list's own top padding. + */ + @Composable + public fun firstItemPadding(): PaddingValues = PaddingValues( + start = screenWidthDp().dp * HorizontalPaddingPercent, + end = screenWidthDp().dp * HorizontalPaddingPercent, + bottom = BottomPadding, + ) + + /** + * Padding for list items other than the top item in the list. + */ + @Composable + public fun itemPadding(): PaddingValues = PaddingValues( + start = screenWidthDp().dp * HorizontalPaddingPercent, + end = screenWidthDp().dp * HorizontalPaddingPercent, + top = TopPadding, + bottom = BottomPadding, + ) + + private const val HorizontalPaddingPercent = 0.073f + private val TopPadding = 12.dp + private val BottomPadding = 8.dp + + @Composable + internal fun screenHeightDp() = LocalConfiguration.current.screenHeightDp + + @Composable + internal fun screenWidthDp() = LocalConfiguration.current.screenWidthDp +}