Remove materialcore for M2.5 CompactButton
With the current changes, materialcore Chip layer is no longer in use
(by neither M2.5 and M3), hence removing it as well.
Bug: 314924199
Test: Existing tests
Change-Id: Ica06358ab9d4cf739fc418aa4c0deacd61177fb1
diff --git a/wear/compose/compose-material-core/src/androidTest/kotlin/androidx/wear/compose/materialcore/ChipTest.kt b/wear/compose/compose-material-core/src/androidTest/kotlin/androidx/wear/compose/materialcore/ChipTest.kt
deleted file mode 100644
index 56436a3..0000000
--- a/wear/compose/compose-material-core/src/androidTest/kotlin/androidx/wear/compose/materialcore/ChipTest.kt
+++ /dev/null
@@ -1,898 +0,0 @@
-
-/*
- * Copyright 2023 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.wear.compose.materialcore
-
-import android.os.Build
-import androidx.compose.foundation.BorderStroke
-import androidx.compose.foundation.background
-import androidx.compose.foundation.interaction.MutableInteractionSource
-import androidx.compose.foundation.layout.Box
-import androidx.compose.foundation.layout.BoxScope
-import androidx.compose.foundation.layout.PaddingValues
-import androidx.compose.foundation.layout.RowScope
-import androidx.compose.foundation.layout.fillMaxSize
-import androidx.compose.foundation.layout.height
-import androidx.compose.foundation.layout.width
-import androidx.compose.foundation.shape.CircleShape
-import androidx.compose.foundation.shape.CornerSize
-import androidx.compose.foundation.shape.RoundedCornerShape
-import androidx.compose.runtime.Composable
-import androidx.compose.runtime.CompositionLocalProvider
-import androidx.compose.runtime.State
-import androidx.compose.runtime.mutableStateOf
-import androidx.compose.runtime.remember
-import androidx.compose.runtime.rememberUpdatedState
-import androidx.compose.ui.Modifier
-import androidx.compose.ui.graphics.Color
-import androidx.compose.ui.graphics.Shape
-import androidx.compose.ui.graphics.compositeOver
-import androidx.compose.ui.graphics.painter.ColorPainter
-import androidx.compose.ui.graphics.painter.Painter
-import androidx.compose.ui.platform.testTag
-import androidx.compose.ui.semantics.Role
-import androidx.compose.ui.semantics.SemanticsProperties
-import androidx.compose.ui.test.SemanticsMatcher
-import androidx.compose.ui.test.assert
-import androidx.compose.ui.test.assertHasClickAction
-import androidx.compose.ui.test.assertHeightIsEqualTo
-import androidx.compose.ui.test.assertIsEnabled
-import androidx.compose.ui.test.assertIsNotEnabled
-import androidx.compose.ui.test.assertTopPositionInRootIsEqualTo
-import androidx.compose.ui.test.assertWidthIsEqualTo
-import androidx.compose.ui.test.captureToImage
-import androidx.compose.ui.test.getUnclippedBoundsInRoot
-import androidx.compose.ui.test.junit4.createComposeRule
-import androidx.compose.ui.test.onNodeWithContentDescription
-import androidx.compose.ui.test.onNodeWithTag
-import androidx.compose.ui.test.onRoot
-import androidx.compose.ui.test.performClick
-import androidx.compose.ui.unit.Dp
-import androidx.compose.ui.unit.LayoutDirection
-import androidx.compose.ui.unit.dp
-import androidx.compose.ui.unit.height
-import androidx.test.filters.SdkSuppress
-import org.junit.Assert.assertEquals
-import org.junit.Rule
-import org.junit.Test
-
-private val DEFAULT_COMPACT_CHIP_VERTICAL_PADDING = 8.dp
-private val BACKGROUND_ENABLED_COLOR = Color.Green
-private val BACKGROUND_DISABLED_COLOR = Color.Red
-private val BORDER_ENABLED_COLOR = Color.Blue
-private val BORDER_DISABLED_COLOR = Color.Yellow
-
-@Suppress("DEPRECATION")
-class ChipTest {
- @get:Rule
- val rule = createComposeRule()
-
- @Test
- fun basechip_supports_testtag() {
- rule.setContent {
- BaseChipWithDefaults(modifier = Modifier.testTag(TEST_TAG)) {
- }
- }
- rule.onNodeWithTag(TEST_TAG).assertExists()
- }
-
- @Test
- fun threeslotchip_supports_testtag() {
- rule.setContent {
- ThreeSlotChipWithDefaults(modifier = Modifier.testTag(TEST_TAG))
- }
- rule.onNodeWithTag(TEST_TAG).assertExists()
- }
-
- @Test
- fun compactchip_supports_testtag() {
- rule.setContent {
- CompactChipWithDefaults(modifier = Modifier.testTag(TEST_TAG))
- }
- rule.onNodeWithTag(TEST_TAG).assertExists()
- }
-
- @Test
- fun basechip_has_clickaction_when_enabled() {
- rule.setContent {
- BaseChipWithDefaults(
- enabled = true,
- modifier = Modifier.testTag(TEST_TAG),
- ) {
- }
- }
- rule.onNodeWithTag(TEST_TAG).assertHasClickAction()
- }
-
- @Test
- fun threeslotchip_has_clickaction_when_enabled() {
- rule.setContent {
- ThreeSlotChipWithDefaults(
- enabled = true,
- modifier = Modifier.testTag(TEST_TAG),
- )
- }
- rule.onNodeWithTag(TEST_TAG).assertHasClickAction()
- }
-
- @Test
- fun compactchip_has_clickaction_when_enabled() {
- rule.setContent {
- CompactChipWithDefaults(
- enabled = true,
- modifier = Modifier.testTag(TEST_TAG),
- )
- }
- rule.onNodeWithTag(TEST_TAG).assertHasClickAction()
- }
-
- @Test
- fun basechip_has_clickaction_when_disabled() {
- rule.setContent {
- BaseChipWithDefaults(
- onClick = {},
- enabled = false,
- modifier = Modifier.testTag(TEST_TAG),
- ) {
- }
- }
- rule.onNodeWithTag(TEST_TAG).assertHasClickAction()
- }
-
- @Test
- fun threeslotchip_has_clickaction_when_disabled() {
- rule.setContent {
- ThreeSlotChipWithDefaults(
- onClick = {},
- enabled = false,
- modifier = Modifier.testTag(TEST_TAG),
- )
- }
- rule.onNodeWithTag(TEST_TAG).assertHasClickAction()
- }
-
- @Test
- fun compactchip_has_clickaction_when_disabled() {
- rule.setContent {
- CompactChipWithDefaults(
- onClick = {},
- enabled = false,
- modifier = Modifier.testTag(TEST_TAG),
- )
- }
- rule.onNodeWithTag(TEST_TAG).assertHasClickAction()
- }
-
- @Test
- fun basechip_is_correctly_enabled() {
- rule.setContent {
- BaseChipWithDefaults(
- enabled = true,
- modifier = Modifier.testTag(TEST_TAG),
- ) {
- }
- }
- rule.onNodeWithTag(TEST_TAG).assertIsEnabled()
- }
-
- @Test
- fun threeslotchip_is_correctly_enabled() {
- rule.setContent {
- ThreeSlotChipWithDefaults(
- enabled = true,
- modifier = Modifier.testTag(TEST_TAG),
- )
- }
- rule.onNodeWithTag(TEST_TAG).assertIsEnabled()
- }
-
- @Test
- fun compactchip_is_correctly_enabled() {
- rule.setContent {
- CompactChipWithDefaults(
- enabled = true,
- modifier = Modifier.testTag(TEST_TAG),
- )
- }
- rule.onNodeWithTag(TEST_TAG).assertIsEnabled()
- }
-
- @Test
- fun basechip_is_correctly_disabled() {
- rule.setContent {
- BaseChipWithDefaults(
- enabled = false,
- modifier = Modifier.testTag(TEST_TAG),
- ) {
- }
- }
- rule.onNodeWithTag(TEST_TAG).assertIsNotEnabled()
- }
-
- @Test
- fun threeslotchip_is_correctly_disabled() {
- rule.setContent {
- ThreeSlotChipWithDefaults(
- enabled = false,
- modifier = Modifier.testTag(TEST_TAG),
- )
- }
- rule.onNodeWithTag(TEST_TAG).assertIsNotEnabled()
- }
-
- @Test
- fun compactchip_is_correctly_disabled() {
- rule.setContent {
- CompactChipWithDefaults(
- enabled = false,
- modifier = Modifier.testTag(TEST_TAG),
- )
- }
- rule.onNodeWithTag(TEST_TAG).assertIsNotEnabled()
- }
-
- @Test
- fun basechip_responds_to_click_when_enabled() {
- var clicked = false
- rule.setContent {
- BaseChipWithDefaults(
- onClick = { clicked = true },
- enabled = true,
- modifier = Modifier.testTag(TEST_TAG),
- ) {
- }
- }
- rule.onNodeWithTag(TEST_TAG).performClick()
- rule.runOnIdle {
- assertEquals(true, clicked)
- }
- }
-
- @Test
- fun threeslotchip_responds_to_click_when_enabled() {
- var clicked = false
- rule.setContent {
- ThreeSlotChipWithDefaults(
- onClick = { clicked = true },
- enabled = true,
- modifier = Modifier.testTag(TEST_TAG),
- )
- }
- rule.onNodeWithTag(TEST_TAG).performClick()
- rule.runOnIdle {
- assertEquals(true, clicked)
- }
- }
-
- @Test
- fun compactchip_responds_to_click_when_enabled() {
- var clicked = false
- rule.setContent {
- CompactChipWithDefaults(
- onClick = { clicked = true },
- enabled = true,
- modifier = Modifier.testTag(TEST_TAG),
- )
- }
- rule.onNodeWithTag(TEST_TAG).performClick()
- rule.runOnIdle {
- assertEquals(true, clicked)
- }
- }
-
- @Test
- fun basechip_does_not_respond_to_click_when_disabled() {
- var clicked = false
- rule.setContent {
- BaseChipWithDefaults(
- onClick = { clicked = true },
- enabled = false,
- modifier = Modifier.testTag(TEST_TAG),
- ) {
- }
- }
- rule.onNodeWithTag(TEST_TAG).performClick()
- rule.runOnIdle {
- assertEquals(false, clicked)
- }
- }
-
- @Test
- fun threeslotchip_does_not_respond_to_click_when_disabled() {
- var clicked = false
- rule.setContent {
- ThreeSlotChipWithDefaults(
- onClick = { clicked = true },
- enabled = false,
- modifier = Modifier.testTag(TEST_TAG),
- )
- }
- rule.onNodeWithTag(TEST_TAG).performClick()
- rule.runOnIdle {
- assertEquals(false, clicked)
- }
- }
-
- @Test
- fun compactchip_does_not_respond_to_click_when_disabled() {
- var clicked = false
- rule.setContent {
- CompactChipWithDefaults(
- onClick = { clicked = true },
- enabled = false,
- modifier = Modifier.testTag(TEST_TAG),
- )
- }
- rule.onNodeWithTag(TEST_TAG).performClick()
- rule.runOnIdle {
- assertEquals(false, clicked)
- }
- }
-
- @Test
- fun basechip_uses_semantic_role_override() {
- rule.setContent {
- BaseChipWithDefaults(
- onClick = {},
- modifier = Modifier.testTag(TEST_TAG),
- role = Role.Image
- ) {
- }
- }
- rule.onNodeWithTag(TEST_TAG)
- .assert(
- SemanticsMatcher.expectValue(
- SemanticsProperties.Role,
- Role.Image
- )
- )
- }
-
- @Test
- fun threeslotchip_uses_semantic_role_override() {
- rule.setContent {
- ThreeSlotChipWithDefaults(
- onClick = {},
- modifier = Modifier.testTag(TEST_TAG),
- role = Role.Image
- )
- }
- rule.onNodeWithTag(TEST_TAG)
- .assert(
- SemanticsMatcher.expectValue(
- SemanticsProperties.Role,
- Role.Image
- )
- )
- }
-
- @Test
- fun compactchip_uses_semantic_role_override() {
- rule.setContent {
- CompactChipWithDefaults(
- modifier = Modifier.testTag(TEST_TAG),
- role = Role.Image
- )
- }
- rule.onNodeWithTag(TEST_TAG)
- .assert(
- SemanticsMatcher.expectValue(
- SemanticsProperties.Role,
- Role.Image
- )
- )
- }
-
- @Test
- fun basechip_uses_shape_override() =
- rule.isShape(CircleShape, LayoutDirection.Ltr) {
- BaseChipWithDefaults(
- shape = CircleShape,
- modifier = Modifier.testTag(TEST_TAG),
- ) {
- }
- }
-
- @Test
- fun threeslotchip_uses_shape_override() =
- rule.isShape(CircleShape, LayoutDirection.Ltr) {
- ThreeSlotChipWithDefaults(
- shape = CircleShape,
- modifier = Modifier.testTag(TEST_TAG),
- )
- }
-
- @Test
- fun compactchip_uses_shape_override() =
- rule.isShape(CircleShape, LayoutDirection.Ltr) {
- CompactChipWithDefaults(
- shape = CircleShape,
- modifier = Modifier.testTag(TEST_TAG),
- )
- }
-
- @Test
- fun threeslotchip_has_icon_in_correct_location_when_only_single_line_of_text() {
- val iconTag = "TestIcon"
- val chipTag = "chip"
- rule
- .setContentForSizeAssertions(useUnmergedTree = true) {
- ThreeSlotChipWithDefaults(
- label = { TestText("Blue green orange") },
- icon = { TestImage(iconLabel = iconTag) },
- modifier = Modifier.testTag(chipTag)
- )
- }
- val itemBounds = rule.onNodeWithTag(chipTag).getUnclippedBoundsInRoot()
- val iconBounds = rule.onNodeWithTag(iconTag, useUnmergedTree = true)
- .getUnclippedBoundsInRoot()
- rule.onNodeWithContentDescription(iconTag, useUnmergedTree = true)
- .assertTopPositionInRootIsEqualTo((itemBounds.height - iconBounds.height) / 2)
- }
-
- @Test
- fun icon_only_compactchip_has_correct_default_width_and_height() {
- val iconTag = "TestIcon"
- val chipTag = "chip"
- val width = 52.dp
- val height = 48.dp
- rule
- .setContentForSizeAssertions(useUnmergedTree = true) {
- CompactChipWithDefaults(
- modifier = Modifier.testTag(chipTag),
- icon = { TestImage(iconLabel = iconTag) },
- defaultIconOnlyCompactChipWidth = width,
- height = height,
- )
- }
- rule.onRoot()
- .assertWidthIsEqualTo(width)
- .assertHeightIsEqualTo(height)
- }
-
- @Test
- fun label_only_compactchip_has_correct_default_height() {
- val chipTag = "chip"
- val height = 48.dp
- rule
- .setContentForSizeAssertions(useUnmergedTree = true) {
- CompactChipWithDefaults(
- modifier = Modifier.testTag(chipTag),
- label = { TestText("Test") },
- height = height,
- )
- }
- rule.onRoot().assertHeightIsEqualTo(height)
- }
-
- @Test
- fun no_content_compactchip_has_correct_default_width_and_height() {
- val width = 52.dp
- val height = 48.dp
- rule
- .setContentForSizeAssertions(useUnmergedTree = true) {
- CompactChipWithDefaults(
- modifier = Modifier.testTag(TEST_TAG),
- defaultIconOnlyCompactChipWidth = width,
- height = height,
- )
- }
- rule.onRoot()
- .assertWidthIsEqualTo(width)
- .assertHeightIsEqualTo(height)
- }
-
- @Test
- fun icon_only_compactchip_can_have_width_overridden() {
- val iconTag = "TestIcon"
- rule
- .setContentForSizeAssertions(useUnmergedTree = true) {
- CompactChipWithDefaults(
- modifier = Modifier
- .testTag(TEST_TAG)
- .width(100.dp),
- icon = { TestImage(iconLabel = iconTag) }
- )
- }
- rule.onRoot().assertWidthIsEqualTo(100.dp)
- }
-
- @Test
- fun compactchip_has_icon_in_correct_location() {
- val iconTag = "TestIcon"
- rule
- .setContentForSizeAssertions(useUnmergedTree = true) {
- CompactChipWithDefaults(
- label = { TestText("Test label") },
- icon = { TestImage(iconLabel = iconTag) },
- modifier = Modifier.testTag(TEST_TAG)
- )
- }
- val itemBounds = rule.onNodeWithTag(TEST_TAG).getUnclippedBoundsInRoot()
- val iconBounds = rule.onNodeWithTag(iconTag, useUnmergedTree = true)
- .getUnclippedBoundsInRoot()
- rule.onNodeWithContentDescription(iconTag, useUnmergedTree = true)
- .assertTopPositionInRootIsEqualTo(
- (itemBounds.height - iconBounds.height) / 2 + DEFAULT_COMPACT_CHIP_VERTICAL_PADDING
- )
- }
-
- @Test
- fun icon_only_compactchip_has_icon_in_correct_location() {
- val iconTag = "TestIcon"
- rule
- .setContentForSizeAssertions(useUnmergedTree = true) {
- CompactChipWithDefaults(
- modifier = Modifier.testTag(TEST_TAG),
- icon = { TestImage(iconLabel = iconTag) }
- )
- }
- val itemBounds = rule.onNodeWithTag(TEST_TAG).getUnclippedBoundsInRoot()
- val iconBounds = rule.onNodeWithTag(iconTag, useUnmergedTree = true)
- .getUnclippedBoundsInRoot()
- rule.onNodeWithContentDescription(iconTag, useUnmergedTree = true)
- .assertTopPositionInRootIsEqualTo(
- (itemBounds.height - iconBounds.height) / 2 + DEFAULT_COMPACT_CHIP_VERTICAL_PADDING
- )
- }
-
- @Test
- fun gives_enabled_basechip_correct_colors() =
- verifyColors(
- expectedBackgroundColor = BACKGROUND_ENABLED_COLOR,
- expectedBorderColor = BORDER_ENABLED_COLOR,
- content = { BaseChipWithColor(enabled = true) }
- )
-
- @Test
- fun gives_disabled_basechip_correct_colors() =
- verifyColors(
- expectedBackgroundColor = BACKGROUND_DISABLED_COLOR,
- expectedBorderColor = BORDER_DISABLED_COLOR,
- content = { BaseChipWithColor(enabled = false) }
- )
-
- @Test
- fun gives_enabled_threeslotchip_correct_colors() =
- verifyColors(
- expectedBackgroundColor = BACKGROUND_ENABLED_COLOR,
- expectedBorderColor = BORDER_ENABLED_COLOR,
- content = { ThreeSlotChipWithColor(enabled = true) }
- )
-
- @Test
- fun gives_disabled_threeslotchip_correct_colors() =
- verifyColors(
- expectedBackgroundColor = BACKGROUND_DISABLED_COLOR,
- expectedBorderColor = BORDER_DISABLED_COLOR,
- content = { ThreeSlotChipWithColor(enabled = false) }
- )
-
- @Test
- fun gives_enabled_compactchip_correct_colors() =
- verifyColors(
- expectedBackgroundColor = BACKGROUND_ENABLED_COLOR,
- expectedBorderColor = BORDER_ENABLED_COLOR,
- content = { CompactChipWithColor(enabled = true) }
- )
-
- @Test
- fun gives_disabled_compactchip_correct_colors() =
- verifyColors(
- expectedBackgroundColor = BACKGROUND_DISABLED_COLOR,
- expectedBorderColor = BORDER_DISABLED_COLOR,
- content = { CompactChipWithColor(enabled = false) }
- )
-
- @Test
- fun basechip_obeys_content_provider_values() {
- var data = -1
- rule.setContent {
- Box(modifier = Modifier.fillMaxSize()) {
- BaseChipWithDefaults(
- content = {
- CompositionLocalProvider(
- LocalContentTestData provides EXPECTED_LOCAL_TEST_DATA
- ) {
- data = LocalContentTestData.current
- }
- },
- )
- }
- }
- assertEquals(data, EXPECTED_LOCAL_TEST_DATA)
- }
-
- @Test
- fun threeslotchip_obeys_icon_provider_values() {
- var data = -1
- rule.setContent {
- Box(modifier = Modifier.fillMaxSize()) {
- ThreeSlotChipWithDefaults(
- icon = {
- CompositionLocalProvider(
- LocalContentTestData provides EXPECTED_LOCAL_TEST_DATA
- ) {
- data = LocalContentTestData.current
- }
- },
- )
- }
- }
- assertEquals(data, EXPECTED_LOCAL_TEST_DATA)
- }
-
- @Test
- fun threeslotchip_obeys_label_provider_values() {
- var data = -1
- rule.setContent {
- Box(modifier = Modifier.fillMaxSize()) {
- ThreeSlotChipWithDefaults(
- label = {
- CompositionLocalProvider(
- LocalContentTestData provides EXPECTED_LOCAL_TEST_DATA
- ) {
- data = LocalContentTestData.current
- }
- },
- )
- }
- }
- assertEquals(data, EXPECTED_LOCAL_TEST_DATA)
- }
-
- @Test
- fun threeslotchip_obeys_secondary_label_provider_values() {
- var data = -1
- rule.setContent {
- Box(modifier = Modifier.fillMaxSize()) {
- ThreeSlotChipWithDefaults(
- secondaryLabel = {
- CompositionLocalProvider(
- LocalContentTestData provides EXPECTED_LOCAL_TEST_DATA
- ) {
- data = LocalContentTestData.current
- }
- },
- )
- }
- }
- assertEquals(data, EXPECTED_LOCAL_TEST_DATA)
- }
-
- @Test
- fun compactchip_obeys_icon_provider_values() {
- var data = -1
- rule.setContent {
- Box(modifier = Modifier.fillMaxSize()) {
- CompactChipWithDefaults(
- icon = {
- CompositionLocalProvider(
- LocalContentTestData provides EXPECTED_LOCAL_TEST_DATA
- ) {
- data = LocalContentTestData.current
- }
- },
- )
- }
- }
- assertEquals(data, EXPECTED_LOCAL_TEST_DATA)
- }
-
- @Test
- fun compactchip_obeys_label_provider_values() {
- var data = -1
- rule.setContent {
- Box(modifier = Modifier.fillMaxSize()) {
- CompactChipWithDefaults(
- label = {
- CompositionLocalProvider(
- LocalContentTestData provides EXPECTED_LOCAL_TEST_DATA
- ) {
- data = LocalContentTestData.current
- }
- },
- )
- }
- }
- assertEquals(data, EXPECTED_LOCAL_TEST_DATA)
- }
-
- @Composable
- private fun BaseChipWithDefaults(
- modifier: Modifier = Modifier,
- onClick: () -> Unit = {},
- background: @Composable (enabled: Boolean) -> State<Painter> = {
- remember { mutableStateOf(ColorPainter(DEFAULT_SHAPE_COLOR)) }
- },
- border: @Composable (enabled: Boolean) -> State<BorderStroke?>? = { null },
- enabled: Boolean = true,
- contentPadding: PaddingValues = PaddingValues(14.dp, 6.dp),
- shape: Shape = RoundedCornerShape(corner = CornerSize(50)),
- interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
- role: Role? = Role.Button,
- height: Dp = 52.dp,
- content: @Composable RowScope.() -> Unit,
- ) = Chip(
- modifier = modifier.height(height),
- onClick = onClick,
- background = background,
- border = border,
- enabled = enabled,
- contentPadding = contentPadding,
- shape = shape,
- interactionSource = interactionSource,
- role = role,
- ripple = EmptyIndication,
- content = content
- )
-
- @Composable
- private fun ThreeSlotChipWithDefaults(
- modifier: Modifier = Modifier,
- label: @Composable RowScope.() -> Unit = {},
- onClick: () -> Unit = {},
- background: @Composable (enabled: Boolean) -> State<Painter> = {
- remember { mutableStateOf(ColorPainter(DEFAULT_SHAPE_COLOR)) }
- },
- secondaryLabel: (@Composable RowScope.() -> Unit)? = null,
- icon: (@Composable BoxScope.() -> Unit)? = null,
- enabled: Boolean = true,
- interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
- contentPadding: PaddingValues = PaddingValues(14.dp, 6.dp),
- shape: Shape = RoundedCornerShape(corner = CornerSize(50)),
- border: @Composable (enabled: Boolean) -> State<BorderStroke?>? = { null },
- defaultIconSpacing: Dp = 6.dp,
- height: Dp = 52.dp,
- role: Role? = Role.Button,
- ) = Chip(
- modifier = modifier.height(height),
- label = label,
- onClick = onClick,
- background = background,
- secondaryLabel = secondaryLabel,
- icon = icon,
- enabled = enabled,
- interactionSource = interactionSource,
- contentPadding = contentPadding,
- shape = shape,
- border = border,
- defaultIconSpacing = defaultIconSpacing,
- role = role,
- ripple = EmptyIndication
- )
-
- @Composable
- private fun CompactChipWithDefaults(
- modifier: Modifier = Modifier,
- onClick: () -> Unit = {},
- background: @Composable (enabled: Boolean) -> State<Painter> = {
- remember { mutableStateOf(ColorPainter(DEFAULT_SHAPE_COLOR)) }
- },
- label: (@Composable RowScope.() -> Unit)? = null,
- icon: (@Composable BoxScope.() -> Unit)? = null,
- enabled: Boolean = true,
- interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
- contentPadding: PaddingValues = PaddingValues(14.dp, 6.dp),
- shape: Shape = RoundedCornerShape(corner = CornerSize(50)),
- border: @Composable (enabled: Boolean) -> State<BorderStroke?>? = { null },
- defaultIconOnlyCompactChipWidth: Dp = 52.dp,
- defaultCompactChipTapTargetPadding: PaddingValues = PaddingValues(
- vertical = DEFAULT_COMPACT_CHIP_VERTICAL_PADDING
- ),
- defaultIconSpacing: Dp = 6.dp,
- height: Dp = 48.dp,
- role: Role? = Role.Button,
- ) = CompactChip(
- modifier = modifier.height(height),
- onClick = onClick,
- background = background,
- label = label,
- icon = icon,
- enabled = enabled,
- interactionSource = interactionSource,
- contentPadding = contentPadding,
- shape = shape,
- border = border,
- defaultIconOnlyCompactChipWidth = defaultIconOnlyCompactChipWidth,
- defaultCompactChipTapTargetPadding = defaultCompactChipTapTargetPadding,
- defaultIconSpacing = defaultIconSpacing,
- role = role,
- ripple = EmptyIndication
- )
-
- @SdkSuppress(minSdkVersion = Build.VERSION_CODES.O)
- private fun verifyColors(
- expectedBackgroundColor: Color,
- expectedBorderColor: Color,
- backgroundThreshold: Float = 50.0f,
- borderThreshold: Float = 1.0f,
- content: @Composable () -> Unit,
- ) {
- val testBackground = Color.White
- val expectedColor = { color: Color ->
- if (color != Color.Transparent)
- color.compositeOver(testBackground)
- else
- testBackground
- }
- rule.setContent {
- Box(
- modifier = Modifier
- .fillMaxSize()
- .background(testBackground)
- ) {
- content()
- }
- }
-
- val bitmap = rule.onNodeWithTag(TEST_TAG).captureToImage()
- bitmap.assertContainsColor(expectedColor(expectedBackgroundColor), backgroundThreshold)
- bitmap.assertContainsColor(expectedColor(expectedBorderColor), borderThreshold)
- }
-
- @Composable
- private fun BaseChipWithColor(enabled: Boolean) =
- BaseChipWithDefaults(
- background = {
- rememberUpdatedState(
- ColorPainter(if (it) BACKGROUND_ENABLED_COLOR else BACKGROUND_DISABLED_COLOR)
- )
- },
- border = {
- rememberUpdatedState(
- BorderStroke(2.dp, if (it) BORDER_ENABLED_COLOR else BORDER_DISABLED_COLOR)
- )
- },
- enabled = enabled,
- modifier = Modifier.testTag(TEST_TAG)
- ) {
- }
-
- @Composable
- private fun ThreeSlotChipWithColor(enabled: Boolean) =
- ThreeSlotChipWithDefaults(
- background = {
- rememberUpdatedState(
- ColorPainter(if (it) BACKGROUND_ENABLED_COLOR else BACKGROUND_DISABLED_COLOR)
- )
- },
- border = {
- rememberUpdatedState(
- BorderStroke(2.dp, if (it) BORDER_ENABLED_COLOR else BORDER_DISABLED_COLOR)
- )
- },
- enabled = enabled,
- modifier = Modifier.testTag(TEST_TAG)
- )
-
- @Composable
- private fun CompactChipWithColor(enabled: Boolean) =
- CompactChipWithDefaults(
- background = {
- rememberUpdatedState(
- ColorPainter(if (it) BACKGROUND_ENABLED_COLOR else BACKGROUND_DISABLED_COLOR)
- )
- },
- border = {
- rememberUpdatedState(
- BorderStroke(2.dp, if (it) BORDER_ENABLED_COLOR else BORDER_DISABLED_COLOR)
- )
- },
- enabled = enabled,
- modifier = Modifier.testTag(TEST_TAG)
- )
-}
diff --git a/wear/compose/compose-material-core/src/main/java/androidx/wear/compose/materialcore/Chip.kt b/wear/compose/compose-material-core/src/main/java/androidx/wear/compose/materialcore/Chip.kt
deleted file mode 100644
index 05d429f..0000000
--- a/wear/compose/compose-material-core/src/main/java/androidx/wear/compose/materialcore/Chip.kt
+++ /dev/null
@@ -1,345 +0,0 @@
-
-/*
- * Copyright 2023 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.wear.compose.materialcore
-
-import androidx.annotation.RestrictTo
-import androidx.compose.foundation.BorderStroke
-import androidx.compose.foundation.Indication
-import androidx.compose.foundation.border
-import androidx.compose.foundation.clickable
-import androidx.compose.foundation.interaction.Interaction
-import androidx.compose.foundation.interaction.MutableInteractionSource
-import androidx.compose.foundation.layout.Box
-import androidx.compose.foundation.layout.BoxScope
-import androidx.compose.foundation.layout.Column
-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.Spacer
-import androidx.compose.foundation.layout.fillMaxHeight
-import androidx.compose.foundation.layout.fillMaxSize
-import androidx.compose.foundation.layout.padding
-import androidx.compose.foundation.layout.size
-import androidx.compose.foundation.layout.width
-import androidx.compose.foundation.layout.wrapContentSize
-import androidx.compose.runtime.Composable
-import androidx.compose.runtime.State
-import androidx.compose.ui.Alignment
-import androidx.compose.ui.Modifier
-import androidx.compose.ui.draw.clip
-import androidx.compose.ui.draw.paint
-import androidx.compose.ui.graphics.Shape
-import androidx.compose.ui.graphics.painter.Painter
-import androidx.compose.ui.layout.ContentScale
-import androidx.compose.ui.semantics.Role
-import androidx.compose.ui.unit.Dp
-
-/**
- * Base level [Chip] that offers a single slot to take any content.
- *
- * Is used as the container for more opinionated [Chip] components that take specific content such
- * as icons and labels.
- *
- * Chips can be enabled or disabled. A disabled chip will not respond to click events.
- *
- * For more information, see the
- * [Chips](https://developer.android.com/training/wearables/components/chips)
- * guide.
- *
- * @param onClick Will be called when the user clicks the chip
- * @param background Resolves the background for this chip in different states.
- * @param border Resolves the border for this chip in different states.
- * @param modifier Modifier to be applied to the chip
- * @param enabled Controls the enabled state of the chip. When `false`, this chip will not
- * be clickable
- * @param contentPadding The spacing values to apply internally between the container and the
- * content
- * @param shape Defines the chip's shape. It is strongly recommended to use the default as this
- * shape is a key characteristic of the Wear Material Theme
- * @param interactionSource The [MutableInteractionSource] representing the stream of
- * [Interaction]s for this Chip. You can create and pass in your own remembered
- * [MutableInteractionSource] if you want to observe [Interaction]s and customize the
- * appearance / behavior of this Chip in different [Interaction]s.
- * @param role The type of user interface element. Accessibility services might use this
- * to describe the element or do customizations
- * @param ripple Ripple used for this chip
- */
-@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
-@Composable
-fun Chip(
- onClick: () -> Unit,
- background: @Composable (enabled: Boolean) -> State<Painter>,
- border: @Composable (enabled: Boolean) -> State<BorderStroke?>?,
- modifier: Modifier,
- enabled: Boolean,
- contentPadding: PaddingValues,
- shape: Shape,
- interactionSource: MutableInteractionSource,
- role: Role?,
- ripple: Indication,
- content: @Composable RowScope.() -> Unit,
-) {
- val borderStroke = border(enabled)?.value
- Row(
- modifier = modifier
- .then(
- if (borderStroke != null) Modifier.border(
- border = borderStroke,
- shape = shape
- ) else Modifier
- )
- .clip(shape = shape)
- .width(intrinsicSize = IntrinsicSize.Max)
- .paint(
- painter = background(enabled).value,
- contentScale = ContentScale.Crop
- )
- .clickable(
- enabled = enabled,
- onClick = onClick,
- role = role,
- indication = ripple,
- interactionSource = interactionSource,
- )
- .padding(contentPadding),
- content = content
- )
-}
-
-/**
- * Wear Material [Chip] that offers three slots and a specific layout for an icon, label and
- * secondaryLabel. The icon and secondaryLabel are optional. The items are laid out with the icon,
- * if provided, at the start of a row, with a column next containing the two label slots.
- *
- * The [Chip] has a max height designed to take no more than two lines of text
- * If no secondary label is provided then the label
- * can be two lines of text. The label and secondary label should be consistently aligned.
- *
- * If a icon is provided then the labels should be "start" aligned, e.g. left aligned in ltr so that
- * the text starts next to the icon.
- *
- * The [Chip] can have different styles with configurable content colors and painted background
- * including gradients.
- *
- * Chips can be enabled or disabled. A disabled chip will not respond to click events.
- *
- * For more information, see the
- * [Chips](https://developer.android.com/training/wearables/components/chips)
- * guide.
- *
- * @param label A slot for providing the chip's main label. The contents are expected to be text
- * which is "start" aligned if there is an icon preset and "start" or "center" aligned if not.
- * @param onClick Will be called when the user clicks the chip
- * @param background Resolves the background for this chip in different states.
- * @param modifier Modifier to be applied to the chip
- * @param secondaryLabel A slot for providing the chip's secondary label. The contents are expected
- * to be text which is "start" aligned if there is an icon preset and "start" or "center" aligned if
- * not. label and secondaryLabel contents should be consistently aligned.
- * @param icon A slot for providing the chip's icon. The contents are expected to be a horizontally
- * and vertically aligned icon.
- * @param enabled Controls the enabled state of the chip. When `false`, this chip will not
- * be clickable
- * @param interactionSource The [MutableInteractionSource] representing the stream of
- * [Interaction]s for this Chip. You can create and pass in your own remembered
- * [MutableInteractionSource] if you want to observe [Interaction]s and customize the
- * appearance / behavior of this Chip in different [Interaction]s.
- * @param contentPadding The spacing values to apply internally between the container and the
- * content.
- * @param shape Defines the chip's shape. It is strongly recommended to use the default as this
- * shape is a key characteristic of the Wear Material Theme.
- * @param border Resolves the chip border in different states.
- * @param defaultIconSpacing Spacing between icon and label, if both are provided.
- * @param role Role semantics that accessibility services can use to provide more
- * context to users.
- * @param ripple Ripple used for this chip
- */
-@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
-@Composable
-fun Chip(
- label: @Composable RowScope.() -> Unit,
- onClick: () -> Unit,
- background: @Composable (enabled: Boolean) -> State<Painter>,
- modifier: Modifier,
- secondaryLabel: (@Composable RowScope.() -> Unit)?,
- icon: (@Composable BoxScope.() -> Unit)?,
- enabled: Boolean,
- interactionSource: MutableInteractionSource,
- contentPadding: PaddingValues,
- shape: Shape,
- border: @Composable (enabled: Boolean) -> State<BorderStroke?>?,
- defaultIconSpacing: Dp,
- role: Role?,
- ripple: Indication
-) {
- Chip(
- modifier = modifier,
- onClick = onClick,
- background = background,
- border = border,
- enabled = enabled,
- contentPadding = contentPadding,
- shape = shape,
- interactionSource = interactionSource,
- role = role,
- ripple = ripple
- ) {
- Row(
- verticalAlignment = Alignment.CenterVertically,
- // Fill the container height but not its width as chips have fixed size height but we
- // want them to be able to fit their content
- modifier = Modifier.fillMaxHeight()
- ) {
- if (icon != null) {
- Box(
- modifier = Modifier.wrapContentSize(align = Alignment.Center),
- content = icon
- )
- Spacer(modifier = Modifier.size(defaultIconSpacing))
- }
- Column {
- Row(content = label)
- secondaryLabel?.let {
- Row(content = secondaryLabel)
- }
- }
- }
- }
-}
-
-/**
- * A compact Wear Material Chip that offers two slots and a specific layout for an icon and label.
- * Both the icon and label are optional however it is expected that at least one will be provided.
- *
- * The [CompactChip] has a max height designed to take no more than one line
- * of text and/or one icon. This includes a visible chip height of 32.dp and
- * 8.dp of padding above and below the chip in order to meet accessibility guidelines that
- * request a minimum of 48.dp height and width of tappable area.
- *
- * If a icon is provided then the labels should be "start" aligned, e.g. left aligned in ltr so that
- * the text starts next to the icon.
- *
- * The items are laid out as follows.
- *
- * 1. If a label is provided then the chip will be laid out with the optional icon at the start of a
- * row followed by the label.
- *
- * 2. If only an icon is provided it will be laid out vertically and horizontally centered
- * and the default width of [defaultIconOnlyCompactChipWidth]
- *
- * If neither icon nor label is provided then the chip will displayed like an icon only chip but
- * with no contents and [background] color.
- *
- * The [CompactChip] can have different styles with configurable content colors and backgrounds
- * including gradients.
- *
- * Chips can be enabled or disabled. A disabled chip will not respond to click events.
- *
- * For more information, see the
- * [Chips](https://developer.android.com/training/wearables/components/chips)
- * guide.
- *
- * @param onClick Will be called when the user clicks the chip
- * @param background Resolves the background for this chip in different states.
- * @param modifier Modifier to be applied to the chip
- * @param label A slot for providing the chip's main label. The contents are expected to be text
- * which is "start" aligned if there is an icon preset and "center" aligned if not.
- * @param icon A slot for providing the chip's icon. The contents are expected to be a horizontally
- * and vertically aligned icon.
- * @param enabled Controls the enabled state of the chip. When `false`, this chip will not
- * be clickable
- * @param interactionSource The [MutableInteractionSource] representing the stream of
- * [Interaction]s for this Chip. You can create and pass in your own remembered
- * [MutableInteractionSource] if you want to observe [Interaction]s and customize the
- * appearance / behavior of this Chip in different [Interaction]s.
- * @param contentPadding The spacing values to apply internally between the container and the
- * content
- * @param shape Defines the chip's shape. It is strongly recommended to use the default as this
- * shape is a key characteristic of the Wear Material Theme
- * @param border Resolves the border for this chip in different states.
- * @param defaultIconOnlyCompactChipWidth The default width of the compact chip if there is no label
- * @param defaultCompactChipTapTargetPadding Default padding to increase the tap target
- * @param defaultIconSpacing Spacing between icon and label, if both are provided
- * @param role Role semantics that accessibility services can use to provide more
- * context to users.
- * @param ripple Ripple used for this chip
- */
-@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
-@Composable
-fun CompactChip(
- onClick: () -> Unit,
- background: @Composable (enabled: Boolean) -> State<Painter>,
- modifier: Modifier,
- label: (@Composable RowScope.() -> Unit)?,
- icon: (@Composable BoxScope.() -> Unit)?,
- enabled: Boolean,
- interactionSource: MutableInteractionSource,
- contentPadding: PaddingValues,
- shape: Shape,
- border: @Composable (enabled: Boolean) -> State<BorderStroke?>?,
- defaultIconOnlyCompactChipWidth: Dp,
- defaultCompactChipTapTargetPadding: PaddingValues,
- defaultIconSpacing: Dp,
- role: Role?,
- ripple: Indication
-) {
- if (label != null) {
- Chip(
- modifier = modifier
- .padding(defaultCompactChipTapTargetPadding),
- label = label,
- onClick = onClick,
- background = background,
- secondaryLabel = null,
- icon = icon,
- enabled = enabled,
- interactionSource = interactionSource,
- contentPadding = contentPadding,
- shape = shape,
- border = border,
- defaultIconSpacing = defaultIconSpacing,
- role = role,
- ripple = ripple
- )
- } else {
- // Icon only compact chips have their own layout with a specific width and center aligned
- // content. We use the base simple single slot Chip under the covers.
- Chip(
- modifier = modifier
- .width(defaultIconOnlyCompactChipWidth)
- .padding(defaultCompactChipTapTargetPadding),
- onClick = onClick,
- background = background,
- border = border,
- enabled = enabled,
- contentPadding = contentPadding,
- shape = shape,
- interactionSource = interactionSource,
- role = role,
- ripple = ripple
- ) {
- // Use a box to fill and center align the icon into the single slot of the Chip
- Box(modifier = Modifier
- .fillMaxSize()
- .wrapContentSize(align = Alignment.Center)) {
- if (icon != null) {
- icon()
- }
- }
- }
- }
-}
diff --git a/wear/compose/compose-material/src/main/java/androidx/wear/compose/material/Chip.kt b/wear/compose/compose-material/src/main/java/androidx/wear/compose/material/Chip.kt
index a9bf879..e28224dd 100644
--- a/wear/compose/compose-material/src/main/java/androidx/wear/compose/material/Chip.kt
+++ b/wear/compose/compose-material/src/main/java/androidx/wear/compose/material/Chip.kt
@@ -30,6 +30,7 @@
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.defaultMinSize
import androidx.compose.foundation.layout.fillMaxHeight
+import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
@@ -55,6 +56,7 @@
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalLayoutDirection
import androidx.compose.ui.semantics.Role
+import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.LayoutDirection
import androidx.compose.ui.unit.dp
@@ -184,34 +186,17 @@
role: Role? = Role.Button,
content: @Composable RowScope.() -> Unit,
) {
- val borderStroke = border.borderStroke(enabled).value
- val rowModifier = if (borderStroke != null) modifier.border(
- border = borderStroke,
- shape = shape
- ) else modifier
- Row(
- modifier = rowModifier
- .defaultMinSize(minHeight = ChipDefaults.Height)
- .height(IntrinsicSize.Min)
- .clip(shape = shape)
- .width(intrinsicSize = IntrinsicSize.Max)
- .paint(
- painter = colors.background(enabled).value,
- contentScale = ContentScale.Crop
- )
- .clickable(
- enabled = enabled,
- onClick = onClick,
- role = role,
- indication = rippleOrFallbackImplementation(),
- interactionSource = interactionSource,
- )
- .padding(contentPadding),
- content = provideScopeContent(
- colors.contentColor(enabled = enabled),
- MaterialTheme.typography.button,
- content
- )
+ ChipImpl(
+ onClick = onClick,
+ colors = colors,
+ border = border,
+ modifier = modifier.chipSizeModifier(),
+ enabled = enabled,
+ contentPadding = contentPadding,
+ shape = shape,
+ interactionSource = interactionSource,
+ role = role,
+ content = content
)
}
@@ -375,52 +360,21 @@
shape: Shape = MaterialTheme.shapes.small,
border: ChipBorder = ChipDefaults.chipBorder()
) {
- Chip(
- modifier = modifier
- .defaultMinSize(minHeight = ChipDefaults.Height)
- .height(IntrinsicSize.Min),
+ ChipImpl(
onClick = onClick,
+ label = label,
+ labelTypography = MaterialTheme.typography.button,
+ modifier = modifier.chipSizeModifier(),
+ secondaryLabel = secondaryLabel,
+ icon = icon,
colors = colors,
- border = border,
enabled = enabled,
+ interactionSource = interactionSource,
contentPadding = contentPadding,
shape = shape,
- interactionSource = interactionSource,
- role = Role.Button
- ) {
- Row(
- verticalAlignment = Alignment.CenterVertically,
- // Fill the container height but not its width as chips have fixed size height but we
- // want them to be able to fit their content
- modifier = Modifier.fillMaxHeight()
- ) {
- if (icon != null) {
- Box(
- modifier = Modifier.wrapContentSize(align = Alignment.Center),
- content = provideIcon(colors.iconColor(enabled), icon)
- )
- Spacer(modifier = Modifier.size(ChipDefaults.IconSpacing))
- }
- Column {
- Row(
- content = provideScopeContent(
- colors.contentColor(enabled = enabled),
- MaterialTheme.typography.button,
- label
- )
- )
- secondaryLabel?.let {
- Row(
- content = provideScopeContent(
- colors.secondaryContentColor(enabled = enabled),
- textStyle = MaterialTheme.typography.caption2,
- secondaryLabel
- )
- )
- }
- }
- }
- }
+ border = border,
+ defaultIconSpacing = ChipDefaults.IconSpacing
+ )
}
/**
@@ -684,30 +638,52 @@
shape: Shape = MaterialTheme.shapes.small,
border: ChipBorder = ChipDefaults.chipBorder()
) {
- androidx.wear.compose.materialcore.CompactChip(
- modifier = modifier.height(ChipDefaults.CompactChipHeight),
- onClick = onClick,
- background = { colors.background(enabled = it) },
- label = label?.let { provideScopeContent(
- colors.contentColor(enabled = enabled),
- MaterialTheme.typography.caption1,
- label
- ) },
- icon = icon?.let { provideIcon(
- colors.iconColor(enabled = enabled),
- icon
- ) },
- enabled = enabled,
- interactionSource = interactionSource,
- contentPadding = contentPadding,
- shape = shape,
- border = { border.borderStroke(enabled = it) },
- defaultIconOnlyCompactChipWidth = ChipDefaults.IconOnlyCompactChipWidth,
- defaultCompactChipTapTargetPadding = ChipDefaults.CompactChipTapTargetPadding,
- defaultIconSpacing = ChipDefaults.IconSpacing,
- role = Role.Button,
- ripple = rippleOrFallbackImplementation()
- )
+ if (label != null) {
+ ChipImpl(
+ modifier = modifier
+ .compactChipModifier()
+ .padding(ChipDefaults.CompactChipTapTargetPadding),
+ label = label,
+ labelTypography = MaterialTheme.typography.caption1,
+ onClick = onClick,
+ colors = colors,
+ secondaryLabel = null,
+ icon = icon,
+ enabled = enabled,
+ interactionSource = interactionSource,
+ contentPadding = contentPadding,
+ shape = shape,
+ border = border,
+ defaultIconSpacing = ChipDefaults.IconSpacing,
+ )
+ } else {
+ // Icon only compact chips have their own layout with a specific width and center aligned
+ // content. We use the base simple single slot Chip under the covers.
+ ChipImpl(
+ modifier = modifier
+ .compactChipModifier()
+ .width(ChipDefaults.IconOnlyCompactChipWidth)
+ .padding(ChipDefaults.CompactChipTapTargetPadding),
+ onClick = onClick,
+ colors = colors,
+ border = border,
+ enabled = enabled,
+ contentPadding = contentPadding,
+ shape = shape,
+ interactionSource = interactionSource,
+ ) {
+ // Use a box to fill and center align the icon into the single slot of the Chip
+ Box(
+ modifier = Modifier
+ .fillMaxSize()
+ .wrapContentSize(align = Alignment.Center)
+ ) {
+ if (icon != null) {
+ icon()
+ }
+ }
+ }
+ }
}
/**
@@ -1409,3 +1385,115 @@
return result
}
}
+
+@Composable
+private fun Modifier.chipSizeModifier() =
+ this.defaultMinSize(minHeight = ChipDefaults.Height)
+ .height(IntrinsicSize.Min)
+
+@Composable
+private fun Modifier.compactChipModifier() =
+ this.height(ChipDefaults.CompactChipHeight)
+
+@Composable
+private fun ChipImpl(
+ onClick: () -> Unit,
+ colors: ChipColors,
+ border: ChipBorder?,
+ modifier: Modifier,
+ enabled: Boolean,
+ contentPadding: PaddingValues,
+ shape: Shape,
+ interactionSource: MutableInteractionSource,
+ role: Role? = Role.Button,
+ content: @Composable RowScope.() -> Unit,
+) {
+ val borderStroke = border?.borderStroke(enabled)?.value
+ val borderModifier = if (borderStroke != null) modifier.border(
+ border = borderStroke,
+ shape = shape
+ ) else modifier
+ Row(
+ modifier = borderModifier
+ .clip(shape = shape)
+ .width(intrinsicSize = IntrinsicSize.Max)
+ .paint(
+ painter = colors.background(enabled).value,
+ contentScale = ContentScale.Crop
+ )
+ .clickable(
+ enabled = enabled,
+ onClick = onClick,
+ role = role,
+ indication = rippleOrFallbackImplementation(),
+ interactionSource = interactionSource,
+ )
+ .padding(contentPadding),
+ content = provideScopeContent(
+ colors.contentColor(enabled = enabled),
+ MaterialTheme.typography.button,
+ content
+ )
+ )
+}
+
+@Composable
+private fun ChipImpl(
+ label: @Composable RowScope.() -> Unit,
+ labelTypography: TextStyle,
+ onClick: () -> Unit,
+ modifier: Modifier,
+ secondaryLabel: (@Composable RowScope.() -> Unit)?,
+ icon: (@Composable BoxScope.() -> Unit)?,
+ colors: ChipColors,
+ enabled: Boolean,
+ interactionSource: MutableInteractionSource,
+ contentPadding: PaddingValues,
+ shape: Shape,
+ border: ChipBorder?,
+ defaultIconSpacing: Dp
+) {
+ ChipImpl(
+ onClick = onClick,
+ modifier = modifier,
+ colors = colors,
+ border = border,
+ enabled = enabled,
+ contentPadding = contentPadding,
+ shape = shape,
+ interactionSource = interactionSource,
+ ) {
+ Row(
+ verticalAlignment = Alignment.CenterVertically,
+ // Fill the container height but not its width as chips have fixed size height but we
+ // want them to be able to fit their content
+ modifier = Modifier.fillMaxHeight()
+ ) {
+ if (icon != null) {
+ Box(
+ modifier = Modifier.wrapContentSize(align = Alignment.Center),
+ content = provideIcon(colors.iconColor(enabled), icon)
+ )
+ Spacer(modifier = Modifier.size(defaultIconSpacing))
+ }
+ Column {
+ Row(
+ content = provideScopeContent(
+ colors.contentColor(enabled),
+ labelTypography,
+ label
+ )
+ )
+ secondaryLabel?.let {
+ Row(
+ content = provideScopeContent(
+ colors.secondaryContentColor(enabled),
+ MaterialTheme.typography.caption2,
+ secondaryLabel
+ )
+ )
+ }
+ }
+ }
+ }
+}