Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ANDROAPP-6097-Create-AssistChip-component #243

Closed
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,17 @@ package org.hisp.dhis.common.screens.others

import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.size
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Search
import androidx.compose.material3.AssistChipDefaults
import androidx.compose.material3.Icon
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import org.hisp.dhis.mobile.ui.designsystem.component.AssistChip
import org.hisp.dhis.mobile.ui.designsystem.component.ColumnComponentContainer
import org.hisp.dhis.mobile.ui.designsystem.component.FilterChip
import org.hisp.dhis.mobile.ui.designsystem.component.InputChip
Expand Down Expand Up @@ -58,5 +63,46 @@ fun ChipsScreen() {
SubTitle("Filter Chips With badges")
FilterChip(label = "Label", selected = true, badge = "3")
FilterChip(label = "Label", selected = false, badge = "3")
Spacer(Modifier.size(Spacing.Spacing18))

SubTitle("Assist Chips")
// var isSelected5 by remember { mutableStateOf(false) }
AssistChip(
label = "Label",
onClick = { },
)
AssistChip(
label = "Label",
icon = {
Icon(
imageVector = Icons.Filled.Search,
contentDescription = "search icon",
modifier = Modifier
.size(AssistChipDefaults.IconSize),
)
},
onClick = { },
)
Spacer(Modifier.size(Spacing.Spacing18))

SubTitle("Assist Chips With badges")
AssistChip(
label = "Label",
icon = {
Icon(
imageVector = Icons.Filled.Search,
contentDescription = "search icon",
modifier = Modifier
.size(AssistChipDefaults.IconSize),
)
},
onClick = {},
badge = "2",
)
AssistChip(
label = "Label",
onClick = {},
badge = "4",
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package org.hisp.dhis.mobile.ui.designsystem

import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Search
import androidx.compose.material3.AssistChipDefaults
import androidx.compose.material3.Icon
import androidx.compose.ui.Modifier
import org.hisp.dhis.mobile.ui.designsystem.component.AssistChip
import org.hisp.dhis.mobile.ui.designsystem.component.ColumnComponentContainer
import org.hisp.dhis.mobile.ui.designsystem.theme.Spacing
import org.junit.Rule
import org.junit.Test

class AssistChipSanpshotTest {
@get:Rule
val paparazzi = paparazzi()

@Test
fun launchAssistChip() {
paparazzi.snapshot {
ColumnComponentContainer(modifier = Modifier.padding(Spacing.Spacing10)) {
AssistChip(
label = "Label",
icon = {
Icon(
imageVector = Icons.Filled.Search,
contentDescription = "search icon",
modifier = Modifier
.size(AssistChipDefaults.IconSize),
)
},
onClick = {},
badge = "3",
)
AssistChip(
label = "Label",
onClick = {},
badge = "3",
)
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
package org.hisp.dhis.mobile.ui.designsystem.component

import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.interaction.collectIsPressedAsState
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.offset
import androidx.compose.material.ripple.LocalRippleTheme
import androidx.compose.material3.AssistChip
import androidx.compose.material3.AssistChipDefaults
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.onSizeChanged
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.unit.IntOffset
import org.hisp.dhis.mobile.ui.designsystem.theme.Outline
import org.hisp.dhis.mobile.ui.designsystem.theme.Ripple
import org.hisp.dhis.mobile.ui.designsystem.theme.SurfaceColor
import org.hisp.dhis.mobile.ui.designsystem.theme.TextColor

/**
* DHIS2 [AssistChip] button with custom icon slot.
* wraps Material 3 [AssistChip].
* AssistChips are used to trigger actions.
* @param label: the text to be shown.
* @param icon: custom leading icon to be shown, use AssistChipDefaults in the
* Icon composable modifier to set the size of the icon.
* @param enabled: controls the enabled state. "False" will disabled the component
* @param modifier: optional [Modifier].
* @param onClick: Will be called when the user taps the chip.
* @param badge: the text to be displayed within the badge.
*/
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun AssistChip(
modifier: Modifier = Modifier,
label: String,
icon: @Composable (() -> Unit)? = null,
enabled: Boolean = true,
onClick: (() -> Unit),
badge: String? = null,
) {
val interactionSource = remember { MutableInteractionSource() }
val isPressed by interactionSource.collectIsPressedAsState()

Box(modifier = Modifier) {
CompositionLocalProvider(LocalRippleTheme provides Ripple.CustomDHISRippleTheme()) {
AssistChip(
onClick = { onClick.invoke() },
label = {
Text(
label,
color = TextColor.OnSurfaceVariant,
)
},
modifier = modifier,
enabled = enabled,
colors = if (isPressed) {
AssistChipDefaults.assistChipColors(
containerColor = SurfaceColor.Container,
leadingIconContentColor = TextColor.OnSurfaceVariant,
)
} else {
AssistChipDefaults.assistChipColors(
containerColor = SurfaceColor.SurfaceBright,
leadingIconContentColor = TextColor.OnSurfaceVariant,
)
},
border = AssistChipDefaults.assistChipBorder(
borderColor = Outline.Dark,
),
leadingIcon = {
icon?.invoke()
},

)
}
badge?.let {
var offset by remember { mutableStateOf(IntOffset(0, 0)) }
Badge(
modifier = Modifier
.align(Alignment.TopEnd)
.onSizeChanged { offset = IntOffset(it.width / 3, it.height / 3) }
.offset { offset }
.testTag("ASSIST_CHIP_BADGE"),
text = badge,
)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package org.hisp.dhis.mobile.ui.designsystem.component

import androidx.compose.foundation.layout.size
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Search
import androidx.compose.material3.AssistChipDefaults
import androidx.compose.material3.Icon
import androidx.compose.ui.Modifier
import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.test.onNodeWithTag
import org.junit.Rule
import org.junit.Test

class AssistChipTest {

@get:Rule
val rule = createComposeRule()

@Test
fun assistChipShouldDisplayBadges() {
rule.setContent {
AssistChip(
label = "Label",
icon = {
Icon(
imageVector = Icons.Filled.Search,
contentDescription = "search icon",
modifier = Modifier
.size(AssistChipDefaults.IconSize),
)
},
onClick = {},
badge = "2",
)
}

rule.onNodeWithTag("ASSIST_CHIP_BADGE").assertExists()
}
}
Loading