diff --git a/core/test/src/main/AndroidManifest.xml b/core/test/src/main/AndroidManifest.xml
index cc58fed..9a40236 100644
--- a/core/test/src/main/AndroidManifest.xml
+++ b/core/test/src/main/AndroidManifest.xml
@@ -1,15 +1,3 @@
-
-
-
-
-
-
-
-
-
-
diff --git a/core/ui/src/androidTest/java/co/yml/coreui/ui/ytag/TagViewContainerTesting.kt b/core/ui/src/androidTest/java/co/yml/coreui/ui/ytag/TagViewContainerTesting.kt
new file mode 100644
index 0000000..96fcf88
--- /dev/null
+++ b/core/ui/src/androidTest/java/co/yml/coreui/ui/ytag/TagViewContainerTesting.kt
@@ -0,0 +1,102 @@
+package co.yml.coreui.ui.ytag
+
+import androidx.compose.foundation.layout.PaddingValues
+import androidx.compose.foundation.shape.CircleShape
+import androidx.compose.foundation.shape.RoundedCornerShape
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.test.*
+import androidx.compose.ui.test.junit4.createComposeRule
+import androidx.compose.ui.unit.dp
+import co.yml.coreui.core.ui.ytag.TagViewContainer
+import co.yml.coreui.core.ui.ytag.model.TagViewContainerModifiers
+import co.yml.coreui.core.ui.ytag.model.TagViewData
+import co.yml.coreui.core.ui.ytag.model.TagViewModifiers
+import org.junit.Rule
+import org.junit.Test
+
+class TagViewContainerTesting {
+ @get:Rule
+ val composeTestRule = createComposeRule()
+
+ private fun launchTagViewContainer(
+ tagViewContainerModifiers: TagViewContainerModifiers = TagViewContainerModifiers.Builder()
+ .shape(RoundedCornerShape(10.dp))
+ .width(200.dp)
+ .height(120.dp)
+ .build()
+ ) {
+ val tagViewModifiers = TagViewModifiers.Builder()
+ .shape(CircleShape)
+ .backgroundColor(Color.Black)
+ .textColor(Color.White)
+ .build()
+
+ val tagViewData = listOf(
+ TagViewData(text = "Tag 1", tagViewModifiers = tagViewModifiers),
+ TagViewData(text = "Tag 2", tagViewModifiers = tagViewModifiers),
+ TagViewData(text = "Tag 3", tagViewModifiers = tagViewModifiers),
+ TagViewData(text = "Tag 4", tagViewModifiers = tagViewModifiers)
+ )
+
+ composeTestRule.setContent {
+ TagViewContainer(
+ tagViewData = tagViewData,
+ tagViewContainerModifiers = tagViewContainerModifiers
+ )
+ }
+ }
+
+ @Test
+ fun tagViewContainer_shown() {
+ launchTagViewContainer()
+
+ println(
+ "tag_view_container ${composeTestRule.onNodeWithTag("tag_view_container", useUnmergedTree = true).printToString()}"
+ )
+
+ composeTestRule.onNodeWithTag("tag_view_container").assertIsDisplayed()
+ }
+
+ @Test
+ fun tagViewContainer_with_modifiers_are_executed() {
+ val tagViewContainerModifiers = TagViewContainerModifiers.Builder()
+ .minWidth(150.dp)
+ .minHeight(150.dp)
+ .width(200.dp)
+ .height(150.dp)
+ .enableBorder(true)
+ .borderWidth(1.dp)
+ .borderColor(Color.Red)
+ .backgroundColor(Color.Gray)
+ .shape(CircleShape)
+ .containerPaddingValues(PaddingValues(8.dp))
+ .tagSpacingHorizontal(8.dp)
+ .tagSpacingVertical(8.dp)
+ .moreTagConfiguration(TagViewData(text = "more"))
+ .build()
+
+ launchTagViewContainer(tagViewContainerModifiers)
+
+ composeTestRule.onNodeWithTag("tag_view_container")
+ .assertIsDisplayed()
+ }
+
+ @Test
+ fun tagViewContainer_tags_shown(){
+ launchTagViewContainer()
+
+ composeTestRule.onNodeWithText("Tag 1").assertIsDisplayed()
+ }
+
+ @Test
+ fun tagViewContainer_with_less_space_more_tag_shown(){
+ val tagViewContainerModifiers = TagViewContainerModifiers.Builder()
+ .width(150.dp)
+ .height(50.dp)
+ .build()
+
+ launchTagViewContainer(tagViewContainerModifiers)
+
+ composeTestRule.onNodeWithText("more").assertIsDisplayed()
+ }
+}
diff --git a/core/ui/src/main/AndroidManifest.xml b/core/ui/src/main/AndroidManifest.xml
index a5b3cd9..7bc4648 100644
--- a/core/ui/src/main/AndroidManifest.xml
+++ b/core/ui/src/main/AndroidManifest.xml
@@ -3,4 +3,4 @@
-
\ No newline at end of file
+
diff --git a/core/ui/src/main/java/co/yml/coreui/core/ui/ytag/TagView.kt b/core/ui/src/main/java/co/yml/coreui/core/ui/ytag/TagView.kt
index 7462276..9f72f73 100644
--- a/core/ui/src/main/java/co/yml/coreui/core/ui/ytag/TagView.kt
+++ b/core/ui/src/main/java/co/yml/coreui/core/ui/ytag/TagView.kt
@@ -7,9 +7,11 @@ import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape
-import androidx.compose.material3.*
+import androidx.compose.material3.Icon
+import androidx.compose.material3.IconButton
+import androidx.compose.material3.Surface
+import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
-import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.RectangleShape
@@ -21,6 +23,8 @@ import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
+import androidx.constraintlayout.compose.ConstraintLayout
+import androidx.constraintlayout.compose.Dimension
import co.yml.coreui.core.ui.ytag.model.TagViewModifiers
/**
@@ -38,7 +42,9 @@ fun TagView(
leadingIcon: @Composable ((enable: Boolean) -> Unit)? = null,
trailingIcon: @Composable ((enable: Boolean) -> Unit)? = null,
enabled: Boolean = true,
- tagViewModifiers: TagViewModifiers = TagViewModifiers.Builder().build()
+ tagViewModifiers: TagViewModifiers = TagViewModifiers.Builder().build(),
+ overFlowText: String = "",
+ onClick: () -> Unit = {}
) {
with(tagViewModifiers) {
Surface(
@@ -50,8 +56,10 @@ fun TagView(
.width(width = width ?: Dp.Unspecified)
.height(height = height)
) {
- Row(
+ ConstraintLayout(
modifier = Modifier
+ .width(width = width ?: Dp.Unspecified)
+ .height(height)
.run {
if (enableBorder) {
border(
@@ -66,6 +74,7 @@ fun TagView(
.clickable {
if (enabled) {
onClick.invoke()
+ tagViewModifiers.onClick.invoke()
}
}
.defaultMinSize(minWidth = minWidth, minHeight = minHeight)
@@ -73,13 +82,21 @@ fun TagView(
.background(
color = backgroundColor,
shape = shape
- ),
- verticalAlignment = Alignment.CenterVertically
+ )
) {
- leadingIcon?.invoke(enabled)
+ val (leading_icon, text_view, trailing_icon) = createRefs()
+
+ Box(modifier = Modifier.constrainAs(leading_icon) {
+ start.linkTo(parent.start)
+ top.linkTo(parent.top)
+ bottom.linkTo(parent.bottom)
+ }
+ ) {
+ leadingIcon?.invoke(enabled)
+ }
Text(
- text = text,
+ text = overFlowText.ifEmpty { text },
color = textColor,
fontSize = fontSize,
fontWeight = fontWeight,
@@ -87,12 +104,18 @@ fun TagView(
fontStyle = fontStyle,
letterSpacing = letterSpacing,
modifier = Modifier
+ .constrainAs(text_view) {
+ start.linkTo(leading_icon.end)
+ end.linkTo(trailing_icon.start)
+ top.linkTo(parent.top)
+ bottom.linkTo(parent.bottom)
+ width = Dimension.fillToConstraints
+ }
.padding(
textPadding
)
- .align(Alignment.CenterVertically)
.semantics {
- this.contentDescription = text
+ this.contentDescription = semantics
},
style = style,
textDecoration = textDecoration,
@@ -103,7 +126,15 @@ fun TagView(
maxLines = maxLines,
onTextLayout = onTextLayout
)
- trailingIcon?.invoke(enabled)
+ Box(modifier = Modifier.constrainAs(trailing_icon) {
+ end.linkTo(parent.end)
+ top.linkTo(parent.top)
+ bottom.linkTo(parent.bottom)
+ }
+ ) {
+ trailingIcon?.invoke(enabled)
+ }
+
}
}
}
diff --git a/core/ui/src/main/java/co/yml/coreui/core/ui/ytag/TagViewContainer.kt b/core/ui/src/main/java/co/yml/coreui/core/ui/ytag/TagViewContainer.kt
new file mode 100644
index 0000000..7cebc6e
--- /dev/null
+++ b/core/ui/src/main/java/co/yml/coreui/core/ui/ytag/TagViewContainer.kt
@@ -0,0 +1,385 @@
+package co.yml.coreui.core.ui.ytag
+
+import androidx.compose.foundation.background
+import androidx.compose.foundation.border
+import androidx.compose.foundation.clickable
+import androidx.compose.foundation.layout.*
+import androidx.compose.foundation.shape.CircleShape
+import androidx.compose.foundation.shape.RoundedCornerShape
+import androidx.compose.runtime.*
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.layout.Layout
+import androidx.compose.ui.layout.Placeable
+import androidx.compose.ui.platform.LocalContext
+import androidx.compose.ui.platform.LocalDensity
+import androidx.compose.ui.platform.testTag
+import androidx.compose.ui.semantics.contentDescription
+import androidx.compose.ui.semantics.semantics
+import androidx.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.unit.*
+import co.yml.coreui.core.ui.ytag.model.TagViewContainerModifiers
+import co.yml.coreui.core.ui.ytag.model.TagViewData
+import co.yml.coreui.core.ui.ytag.model.TagViewModifiers
+
+/**
+ * [TagViewContainer] compose method used for hosting multiple chips
+ *
+ * @param tagViewData Defines the list of tag view data
+ * @param tagViewContainerModifiers collection of modifier elements that decorate or add behavior to TagView elements
+ */
+@Composable
+fun TagViewContainer(
+ tagViewData: List,
+ tagViewContainerModifiers: TagViewContainerModifiers
+) {
+ //add overflow details tag into the list
+ val overFlowText = remember {
+ mutableStateOf("")
+ }
+
+ val moreTag = tagViewContainerModifiers.moreTagConfiguration
+ val remainingTags: (Int) -> Unit = { count ->
+ overFlowText.value = moreTag.overFlowText.invoke(count)
+ }
+
+ with(tagViewContainerModifiers) {
+ val context = LocalContext.current
+ var modifier = if (tagViewContainerModifiers.width != Dp.Unspecified) {
+ Modifier.width(tagViewContainerModifiers.width)
+ } else {
+ Modifier.wrapContentWidth()
+ }
+
+ modifier = if (tagViewContainerModifiers.height != Dp.Unspecified) {
+ modifier.then(Modifier.height(tagViewContainerModifiers.height))
+ } else {
+ modifier.then(Modifier.wrapContentHeight())
+ }
+
+ modifier = modifier.then(Modifier
+ .run {
+ if (enableBorder) {
+ border(
+ width = borderWidth,
+ color = borderColor,
+ shape = shape
+ )
+ } else {
+ background(color = backgroundColor, shape = shape)
+ }
+ }
+ .defaultMinSize(minWidth, minHeight)
+ .clickable { }
+ .semantics {
+ this.contentDescription =
+ tagViewContainerModifiers.semantics.ifEmpty { context.getString(co.yml.coreui.ui.R.string.tag_view_container_accessibility_title) }
+ }
+ .testTag("tag_view_container")
+ .background(
+ color = backgroundColor,
+ shape = shape
+ )
+ .padding(containerPaddingValues)
+ )
+
+ Box(
+ modifier = modifier
+ ) {
+ TagViewContainerLayout(
+ remainingTags = remainingTags,
+ tagViewContainerModifiers = tagViewContainerModifiers,
+ content = {
+ tagViewData.forEach {
+ with(it) {
+ val containerItemClick = {
+ tagViewContainerModifiers.onClick.invoke(it)
+ }
+ TagView(
+ text = text,
+ leadingIcon = leadingIcon,
+ trailingIcon = trailingIcon,
+ enabled = enabled,
+ tagViewModifiers = tagViewModifiers,
+ overFlowText = "",
+ onClick = containerItemClick
+ )
+ }
+ }
+
+ //over flow item
+ with(moreTag) {
+ val containerItemClick = {
+ tagViewContainerModifiers.onClick.invoke(this)
+ }
+ TagView(
+ text = overFlowText.value,
+ leadingIcon = leadingIcon,
+ trailingIcon = trailingIcon,
+ enabled = enabled,
+ tagViewModifiers = tagViewModifiers,
+ overFlowText = "",
+ onClick = containerItemClick
+ )
+ }
+ })
+ }
+ }
+}
+
+/**
+ * [TagViewContainerLayout] used for creating a custom layout to hosting y tag
+ * @param tagViewContainerModifiers collection of modifier elements that decorate or add behavior to tag view container
+ * @param content content of the tag view container
+ * @param remainingTags return item count which are not rendered in the tag view container
+ */
+@Composable
+fun TagViewContainerLayout(
+ remainingTags: (Int) -> Unit,
+ tagViewContainerModifiers: TagViewContainerModifiers,
+ content: @Composable () -> Unit
+) {
+ val localDensity = LocalDensity.current
+
+ Layout(content = content) { measurables, constraints ->
+ val looseConstraints = constraints.copy(
+ minWidth = 0,
+ minHeight = 0
+ )
+
+ var currentRow = 0
+ var currentOffset = IntOffset.Zero
+
+ //Measurement phase
+ val placeAbles = measurables.map { measurable ->
+ val placeAble: Placeable = measurable.measure(looseConstraints)
+
+ //calculate the offsets to place the tags in layout phase
+ if (currentOffset.x > 0f && currentOffset.x + placeAble.width + tagViewContainerModifiers.tagSpacingHorizontal.toPx()
+ .toInt() > constraints.maxWidth
+ ) {
+ currentRow += 1
+ currentOffset =
+ currentOffset.copy(
+ x = 0,
+ y = currentOffset.y + placeAble.height + tagViewContainerModifiers.tagSpacingVertical.toPx()
+ .toInt()
+ )
+ }
+ placeAble to currentOffset.also {
+ currentOffset = it.copy(
+ x = it.x + placeAble.width + tagViewContainerModifiers.tagSpacingHorizontal.toPx()
+ .toInt()
+ )
+ }
+ }
+
+ layout(
+ width = constraints.maxWidth,
+ height = constraints.maxHeight
+ ) {
+ placeAbles.forEachIndexed { index, tagPlaceable ->
+ if (index != placeAbles.lastIndex) {
+ val (placeable, offset) = tagPlaceable
+ //check whether container has enough space to place the current tag
+ if (offset.x + placeable.width < constraints.maxWidth && offset.y + placeable.height < constraints.maxHeight) {
+ //space available for current tag
+ val nextItemIndex = index + 1
+ //check whether container has enough space to place the next tag
+ if (nextItemIndex <= placeAbles.lastIndex) {
+ val nextItemOffset = placeAbles[nextItemIndex].second
+ if (nextItemOffset.x + placeAbles[nextItemIndex].first.width < constraints.maxWidth && nextItemOffset.y + placeAbles[nextItemIndex].first.height < constraints.maxHeight) {
+ //space available for next tag
+ placeable.place(offset.x, offset.y)
+ } else {
+ //space not available for next tag
+ //place the over flow tag
+ //check whether to accommodate current tag and more
+ val moreTagPlaceAble = placeAbles.last()
+ val moreXOffset =
+ offset.x + placeable.width + tagViewContainerModifiers.tagSpacingHorizontal.toPx()
+ .toInt()
+ val moreYOffset = offset.y
+ if (moreXOffset + moreTagPlaceAble.first.width < constraints.maxWidth &&
+ moreYOffset + moreTagPlaceAble.first.height < constraints.maxHeight
+ ) {
+ //place current tag
+ placeable.place(offset.x, offset.y)
+ //place more tag
+ val remainingItems = placeAbles.lastIndex - 1 - index
+ remainingTags.invoke(remainingItems)
+ moreTagPlaceAble.first.place(moreXOffset, moreYOffset)
+ return@layout
+ } else {
+ val overflow = showOverFlow(
+ index,
+ placeAbles,
+ tagViewContainerModifiers,
+ constraints,
+ localDensity,
+ remainingTags
+ )
+ overflow?.let {
+ it.first.place(it.second)
+ }
+ return@layout
+ }
+ }
+ }
+ } else {
+ //space not available for current tag
+ //place the over flow tag
+ val overflow = showOverFlow(
+ index,
+ placeAbles,
+ tagViewContainerModifiers,
+ constraints,
+ localDensity,
+ remainingTags
+ )
+ overflow?.let {
+ it.first.place(it.second)
+ }
+ return@layout
+ }
+ }
+ }
+ }
+ }
+}
+
+/**
+ * Used for displaying the over flow details when tags not fit in the container
+ * @param index current placeAble index
+ * @param placeAbles placeAble details of tags
+ * @param tagViewContainerModifiers collection of modifier elements that decorate or add behavior to tag view container
+ * @param constraints immutable constraints for measuring layouts
+ * @param localDensity A density of the screen. Used for the conversions between pixels and Dp
+ * @param remainingItems return item count which are not rendered in the tag view container
+ */
+fun showOverFlow(
+ index: Int,
+ placeAbles: List>,
+ tagViewContainerModifiers: TagViewContainerModifiers,
+ constraints: Constraints,
+ localDensity: Density,
+ remainingItems: (Int) -> Unit
+): Pair? {
+ val offset = placeAbles[index].second
+ val placeable = placeAbles[index]
+ if (tagViewContainerModifiers.moreTagConfiguration.showOverFlow) {
+ val moreTagPlaceAble = placeAbles.last()
+ if (offset.x + moreTagPlaceAble.first.width < constraints.maxWidth && offset.y + moreTagPlaceAble.first.height < constraints.maxHeight) {
+ //place more tag
+ //check whether space available for over flow tag to place in between current [which replace over flow tag] and previous tags
+ val previousIndex = index - 1
+ if (previousIndex >= 0) {
+ val previousOffset = placeAbles[previousIndex].second
+ val previousTag = placeAbles[previousIndex].first
+
+ val moreTagXOffset =
+ previousOffset.x + localDensity.run { tagViewContainerModifiers.tagSpacingHorizontal.toPx() }
+ .toInt() + previousTag.width
+ val moreTagYOffset = previousOffset.y
+
+ if (moreTagXOffset + moreTagPlaceAble.first.width < constraints.maxWidth && moreTagYOffset + moreTagPlaceAble.first.height < constraints.maxHeight) {
+ val remainingTags = placeAbles.lastIndex - index
+ remainingItems.invoke(remainingTags)
+ return Pair(moreTagPlaceAble.first, IntOffset(moreTagXOffset, moreTagYOffset))
+ }
+ }
+ val remainingTags = placeAbles.lastIndex - index
+ remainingItems.invoke(remainingTags)
+ return Pair(moreTagPlaceAble.first, IntOffset(offset.x, offset.y))
+ }
+ } else {
+ return placeable
+ }
+
+ return null
+}
+
+@Preview(name = "Default Tag container")
+@Composable
+fun DefaultTagContainer() {
+ val tagViewModifiers = TagViewModifiers.Builder()
+ .shape(CircleShape)
+ .backgroundColor(Color.Black)
+ .textColor(Color.White)
+ .build()
+ val tagViewData = listOf(
+ TagViewData(text = "Tag 1", tagViewModifiers = tagViewModifiers),
+ TagViewData(text = "Tag 2", tagViewModifiers = tagViewModifiers),
+ TagViewData(text = "Tag 3", tagViewModifiers = tagViewModifiers),
+ TagViewData(text = "Tag 4", tagViewModifiers = tagViewModifiers)
+ )
+
+ val tagViewContainerModifiers = TagViewContainerModifiers.Builder()
+ .shape(RoundedCornerShape(10.dp))
+ .width(200.dp)
+ .height(120.dp)
+ .build()
+
+ TagViewContainer(
+ tagViewData = tagViewData,
+ tagViewContainerModifiers = tagViewContainerModifiers
+ )
+}
+
+@Preview(name = "Tag container with border")
+@Composable
+fun BorderTagContainer() {
+ val tagViewModifiers = TagViewModifiers.Builder()
+ .shape(CircleShape)
+ .backgroundColor(Color.Black)
+ .textColor(Color.White)
+ .build()
+ val tagViewData = listOf(
+ TagViewData(text = "Tag 1", tagViewModifiers = tagViewModifiers),
+ TagViewData(text = "Tag 2", tagViewModifiers = tagViewModifiers),
+ TagViewData(text = "Tag 3", tagViewModifiers = tagViewModifiers),
+ TagViewData(text = "Tag 4", tagViewModifiers = tagViewModifiers)
+ )
+
+ val tagViewContainerModifiers = TagViewContainerModifiers.Builder()
+ .shape(RoundedCornerShape(10.dp))
+ .width(200.dp)
+ .height(120.dp)
+ .enableBorder(true)
+ .borderColor(Color.Red)
+ .borderWidth(1.dp)
+ .build()
+
+ TagViewContainer(
+ tagViewData = tagViewData,
+ tagViewContainerModifiers = tagViewContainerModifiers
+ )
+}
+
+@Preview(name = "Tag container with background")
+@Composable
+fun BackgroundTagContainer() {
+ val tagViewModifiers = TagViewModifiers.Builder()
+ .shape(CircleShape)
+ .backgroundColor(Color.Black)
+ .textColor(Color.White)
+ .build()
+ val tagViewData = listOf(
+ TagViewData(text = "Tag 1", tagViewModifiers = tagViewModifiers),
+ TagViewData(text = "Tag 2", tagViewModifiers = tagViewModifiers),
+ TagViewData(text = "Tag 3", tagViewModifiers = tagViewModifiers),
+ TagViewData(text = "Tag 4", tagViewModifiers = tagViewModifiers)
+ )
+
+ val tagViewContainerModifiers = TagViewContainerModifiers.Builder()
+ .shape(RoundedCornerShape(10.dp))
+ .backgroundColor(Color.Gray)
+ .width(200.dp)
+ .height(120.dp)
+ .build()
+
+ TagViewContainer(
+ tagViewData = tagViewData,
+ tagViewContainerModifiers = tagViewContainerModifiers
+ )
+}
diff --git a/core/ui/src/main/java/co/yml/coreui/core/ui/ytag/model/TagViewContainerModifiers.kt b/core/ui/src/main/java/co/yml/coreui/core/ui/ytag/model/TagViewContainerModifiers.kt
new file mode 100644
index 0000000..778ffb8
--- /dev/null
+++ b/core/ui/src/main/java/co/yml/coreui/core/ui/ytag/model/TagViewContainerModifiers.kt
@@ -0,0 +1,122 @@
+package co.yml.coreui.core.ui.ytag.model
+
+import androidx.compose.foundation.layout.PaddingValues
+import androidx.compose.foundation.shape.CircleShape
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.graphics.RectangleShape
+import androidx.compose.ui.graphics.Shape
+import androidx.compose.ui.unit.Dp
+import androidx.compose.ui.unit.dp
+
+//todo sree_ is min width and min height required?
+/**
+ * [TagViewContainerModifiers] Immutable collection of modifier elements that decorate or add behavior to TagView container.
+ * @param minWidth define a default min width of TagViewContainer
+ * @param minHeight define a default min height of TagViewContainer
+ * @param width define width of TagViewContainer
+ * @param height define height of TagViewContainer
+ * @param enableBorder enable border for TagViewContainer
+ * @param borderWidth define borderWidth of the TagViewContainer
+ * @param borderColor define borderColor of the TagViewContainer
+ * @param backgroundColor define backgroundColor of the TagViewContainer
+ * @param shape defines the shape of the TagViewContainer
+ * @param containerPaddingValues define padding for TagViewContainer
+ * @param tagSpacingHorizontal horizontal padding between tag views
+ * @param tagSpacingVertical vertical padding between tag views
+ * @param semantics add content description for tag view container
+ */
+data class TagViewContainerModifiers(
+ val minWidth: Dp,
+ val minHeight: Dp,
+ val width: Dp,
+ val height: Dp,
+ val enableBorder: Boolean,
+ val borderWidth: Dp,
+ val borderColor: Color,
+ val backgroundColor: Color,
+ val shape: Shape,
+ val containerPaddingValues: PaddingValues,
+ val tagSpacingHorizontal: Dp,
+ val tagSpacingVertical: Dp,
+ val moreTagConfiguration: TagViewData,
+ val onClick: (TagViewData) -> Unit,
+ val semantics: String
+) {
+ //todo sree_ check min and max default size
+ class Builder {
+ private var minWidth: Dp = 150.dp
+ private var minHeight: Dp = 150.dp
+ private var width: Dp = Dp.Unspecified
+ private var height: Dp = Dp.Unspecified
+ private var enableBorder: Boolean = false
+ private var borderWidth: Dp = 1.dp
+ private var borderColor: Color = Color.Black
+ private var backgroundColor: Color = Color.White
+ private var shape: Shape = RectangleShape
+ private var containerPaddingValues: PaddingValues =
+ PaddingValues(horizontal = 4.dp, vertical = 4.dp)
+ private var tagSpacingHorizontal: Dp = 8.dp
+ private var tagSpacingVertical: Dp = 8.dp
+ private var moreTagConfiguration: TagViewData = TagViewData(
+ text = "more",
+ tagViewModifiers = TagViewModifiers.Builder()
+ .shape(CircleShape)
+ .backgroundColor(Color.Black)
+ .textColor(Color.White)
+ .build()
+ )
+ private var onClick: (TagViewData) -> Unit = {}
+ private var semantics: String = ""
+
+ fun minWidth(minWidth: Dp) = apply { this.minWidth = minWidth }
+
+ fun minHeight(minHeight: Dp) = apply { this.minHeight = minHeight }
+
+ fun width(width: Dp) = apply { this.width = width }
+
+ fun height(height: Dp) = apply { this.height = height }
+
+ fun enableBorder(enableBorder: Boolean) = apply { this.enableBorder = enableBorder }
+
+ fun borderWidth(borderWidth: Dp) = apply { this.borderWidth = borderWidth }
+
+ fun borderColor(borderColor: Color) = apply { this.borderColor = borderColor }
+
+ fun backgroundColor(backgroundColor: Color) =
+ apply { this.backgroundColor = backgroundColor }
+
+ fun shape(shape: Shape) = apply { this.shape = shape }
+
+ fun containerPaddingValues(paddingValues: PaddingValues) =
+ apply { this.containerPaddingValues = paddingValues }
+
+ fun tagSpacingHorizontal(space: Dp) = apply { this.tagSpacingHorizontal = space }
+
+ fun tagSpacingVertical(space: Dp) = apply { this.tagSpacingVertical = space }
+
+ fun moreTagConfiguration(configuration: TagViewData) =
+ apply { this.moreTagConfiguration = configuration }
+
+ fun onCLick(onClick: (TagViewData) -> Unit) = apply { this.onClick = onClick }
+
+ fun semantics(semantics: String) = apply { this.semantics = semantics }
+
+ fun build() = TagViewContainerModifiers(
+ minWidth,
+ minHeight,
+ width,
+ height,
+ enableBorder,
+ borderWidth,
+ borderColor,
+ backgroundColor,
+ shape,
+ containerPaddingValues,
+ tagSpacingHorizontal,
+ tagSpacingVertical,
+ moreTagConfiguration,
+ onClick,
+ semantics
+ )
+ }
+}
diff --git a/core/ui/src/main/java/co/yml/coreui/core/ui/ytag/model/TagViewData.kt b/core/ui/src/main/java/co/yml/coreui/core/ui/ytag/model/TagViewData.kt
new file mode 100644
index 0000000..e1953ae
--- /dev/null
+++ b/core/ui/src/main/java/co/yml/coreui/core/ui/ytag/model/TagViewData.kt
@@ -0,0 +1,24 @@
+package co.yml.coreui.core.ui.ytag.model
+
+import androidx.compose.runtime.Composable
+
+/**
+ * [TagViewData] Used for holding the TagView data
+ *
+ * @param text Tag view text to be displayed
+ * @param leadingIcon the optional leading icon to be displayed at the beginning of the TagView
+ * @param trailingIcon the optional leading icon to be displayed at the end of the TagView
+ * @param enabled controls the enabled state of the TagView
+ * @param tagViewModifiers collection of modifier elements that decorate or add behavior to TagView elements
+ * @param showOverFlow show or hide over flow text
+ * @param overFlowText to be displayed for over flow tag [use overFlowText instead of [text] for over flow tag ]
+ */
+data class TagViewData(
+ val text: String = "",
+ val tagViewModifiers: TagViewModifiers = TagViewModifiers.Builder().build(),
+ val leadingIcon: @Composable ((enable: Boolean) -> Unit)? = null,
+ val trailingIcon: @Composable ((enable: Boolean) -> Unit)? = null,
+ val enabled: Boolean = true,
+ val showOverFlow: Boolean = true,
+ val overFlowText: (Int) -> String = { _ -> "" }
+)
diff --git a/core/ui/src/main/java/co/yml/coreui/core/ui/ytag/model/TagViewModifiers.kt b/core/ui/src/main/java/co/yml/coreui/core/ui/ytag/model/TagViewModifiers.kt
index e252d3c..fa693ba 100644
--- a/core/ui/src/main/java/co/yml/coreui/core/ui/ytag/model/TagViewModifiers.kt
+++ b/core/ui/src/main/java/co/yml/coreui/core/ui/ytag/model/TagViewModifiers.kt
@@ -19,7 +19,7 @@ import androidx.compose.ui.unit.sp
/**
- * Immutable collection of modifier elements that decorate or add behavior to TagView elements.
+ * [TagViewModifiers] Represents immutable collection of modifier elements that decorate or add behavior to TagView elements.
* - If a parameter is explicitly set here then that parameter will always be used.
* - If a parameter is not set then the corresponding default value will be used
*
@@ -50,6 +50,7 @@ import androidx.compose.ui.unit.sp
* @param shadowElevation The size of the shadow below the surface.
* @param containerPaddingValues define padding for TagView
* @param onClick perform click event
+ * @param semantics add content description for tag view
*/
data class TagViewModifiers(
val minWidth: Dp,
@@ -79,10 +80,11 @@ data class TagViewModifiers(
val tonalElevation: Dp,
val shadowElevation: Dp,
val containerPaddingValues: PaddingValues,
- val onClick: () -> Unit
+ val onClick: () -> Unit,
+ val semantics: String
) {
class Builder {
- private var minWidth: Dp = 52.dp
+ private var minWidth: Dp = 80.dp
private var minHeight: Dp = 32.dp
private var width: Dp? = null
private var height: Dp = minHeight
@@ -111,6 +113,7 @@ data class TagViewModifiers(
private var shadowElevation: Dp = 0.dp
private var containerPaddingValues: PaddingValues = PaddingValues(horizontal = 4.dp)
private var onClick: () -> Unit = {}
+ private var semantics: String = text
fun minWidth(minWidth: Dp) = apply { this.minWidth = minWidth }
@@ -166,6 +169,8 @@ data class TagViewModifiers(
apply { this.containerPaddingValues = paddingValues }
fun onCLick(onClick: () -> Unit) = apply { this.onClick = onClick }
+
+ fun semantics(semantics: String) = apply { this.semantics = semantics }
fun build() = TagViewModifiers(
minWidth,
minHeight,
@@ -194,7 +199,8 @@ data class TagViewModifiers(
tonalElevation,
shadowElevation,
containerPaddingValues,
- onClick
+ onClick,
+ semantics
)
}
}
diff --git a/core/ui/src/main/res/values/colors.xml b/core/ui/src/main/res/values/colors.xml
new file mode 100644
index 0000000..00a3be5
--- /dev/null
+++ b/core/ui/src/main/res/values/colors.xml
@@ -0,0 +1,13 @@
+
+
+ #E0E0E0
+ #0C0A3E
+ #C8FFBE
+ #EDFFAB
+ #F9564F
+ #89608E
+ #E1F5FE
+ #01579B
+ #0288D1
+
+
diff --git a/core/ui/src/main/res/values/strings.xml b/core/ui/src/main/res/values/strings.xml
index c51354a..5c92fc8 100644
--- a/core/ui/src/main/res/values/strings.xml
+++ b/core/ui/src/main/res/values/strings.xml
@@ -2,4 +2,6 @@
CoreUICatalogApp
Tags
+ more
+ Tag view container
diff --git a/feature/ytag/src/main/java/co/yml/coreui/feature/ytag/ui/YTagActivity.kt b/feature/ytag/src/main/java/co/yml/coreui/feature/ytag/ui/YTagActivity.kt
index e0d8626..6bf076c 100644
--- a/feature/ytag/src/main/java/co/yml/coreui/feature/ytag/ui/YTagActivity.kt
+++ b/feature/ytag/src/main/java/co/yml/coreui/feature/ytag/ui/YTagActivity.kt
@@ -1,5 +1,6 @@
package co.yml.coreui.feature.ytag.ui
+import android.content.Context
import android.os.Bundle
import android.widget.Toast
import androidx.activity.ComponentActivity
@@ -26,13 +27,18 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.font.FontStyle
+import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.style.TextOverflow
+import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import co.yml.coreui.core.ui.templates.AppBarWithBackButton
import co.yml.coreui.core.ui.theme.CoreUICatalogTheme
+import co.yml.coreui.core.ui.ytag.TagView
+import co.yml.coreui.core.ui.ytag.TagViewContainer
+import co.yml.coreui.core.ui.ytag.model.TagViewContainerModifiers
+import co.yml.coreui.core.ui.ytag.model.TagViewData
import co.yml.coreui.core.ui.ytag.model.TagViewModifiers
import co.yml.coreui.ui.R
-import co.yml.coreui.core.ui.ytag.TagView
import dagger.hilt.android.AndroidEntryPoint
@ExperimentalMaterial3Api
@@ -54,14 +60,13 @@ class YTagActivity : ComponentActivity() {
{
Box(
modifier = Modifier
- .fillMaxWidth()
+ .fillMaxSize()
.background(Color.White)
- .padding(it),
- contentAlignment = Alignment.TopCenter
+ .padding(it)
) {
LazyColumn(
content = {
- items(9) { item ->
+ items(10) { item ->
when (item) {
0 -> CapsuleTag()
1 -> RectangleTag()
@@ -72,11 +77,14 @@ class YTagActivity : ComponentActivity() {
6 -> TagWithLeadingTrailingIcon()
7 -> BorderTag()
8 -> ShadowTag()
+ 9 -> DefaultTagViewContainer()
}
}
},
verticalArrangement = Arrangement.spacedBy(dimensionResource(id = R.dimen.padding_normal)),
- modifier = Modifier.padding(dimensionResource(id = R.dimen.padding_normal_medium))
+ modifier = Modifier
+ .padding(dimensionResource(id = R.dimen.padding_normal_medium))
+ .align(Alignment.Center)
)
}
}
@@ -97,154 +105,93 @@ fun DefaultTag() {
@Composable
fun CapsuleTag() {
- val tagViewModifiers = TagViewModifiers.Builder()
- .shape(CircleShape)
- .backgroundColor(Color.Black)
- .textColor(Color.White)
- .style(textStyle)
- .build()
+ val context = LocalContext.current
+ val data = capsuleTagData(
+ context = context,
+ backgroundColor = colorResource(id = R.color.russian_violet)
+ )
TagView(
- text = stringResource(id = co.yml.coreui.feature.ytag.R.string.tag_capsule),
- tagViewModifiers = tagViewModifiers
+ text = data.text,
+ tagViewModifiers = data.tagViewModifiers
)
}
@Composable
fun RectangleTag() {
- val tagViewModifiers = TagViewModifiers.Builder()
- .shape(RectangleShape)
- .backgroundColor(Color.Black)
- .textColor(Color.White)
- .style(textStyle)
- .build()
+ val context = LocalContext.current
+ val data =
+ rectangleTagData(
+ context = context,
+ backgroundColor = colorResource(id = R.color.light_green),
+ textColor = Color.Black
+ )
TagView(
- text = stringResource(id = co.yml.coreui.feature.ytag.R.string.tag_rectangle),
- tagViewModifiers = tagViewModifiers
+ text = data.text,
+ tagViewModifiers = data.tagViewModifiers
)
}
@Composable
fun RoundRectangleTag() {
- val tagViewModifiers = TagViewModifiers.Builder()
- .shape(RoundedCornerShape(dimensionResource(id = R.dimen.padding_small)))
- .backgroundColor(Color.Black)
- .textColor(Color.White)
- .style(textStyle)
- .build()
-
+ val context = LocalContext.current
+ val data = roundRectTagData(
+ context = context,
+ backgroundColor = colorResource(id = R.color.light_yellow),
+ textColor = Color.Black
+ )
TagView(
- text = stringResource(id = co.yml.coreui.feature.ytag.R.string.tag_round_rectangle),
- tagViewModifiers = tagViewModifiers
+ text = data.text,
+ tagViewModifiers = data.tagViewModifiers
)
}
@Composable
fun TagWithLeadingIcon() {
val context = LocalContext.current
- val tagViewModifiers = TagViewModifiers.Builder()
- .shape(CircleShape)
- .backgroundColor(Color.Black)
- .textColor(Color.White)
- .fontStyle(FontStyle.Italic)
- .build()
- val text = stringResource(id = co.yml.coreui.feature.ytag.R.string.tag_leading_icon)
- TagView(text = text, leadingIcon = { enabled ->
- IconButton(
- modifier = Modifier.size(dimensionResource(id = R.dimen.padding_normal_medium)),
- onClick = {
- if (enabled) {
- Toast.makeText(context, text, Toast.LENGTH_SHORT).show()
- }
- }) {
- Icon(
- painter = painterResource(id = co.yml.coreui.feature.ytag.R.drawable.ic_location_24px),
- contentDescription = null,
- tint = Color.White
- )
- }
- }, tagViewModifiers = tagViewModifiers)
+ val data = leadingIconTagData(
+ context = context,
+ backgroundColor = colorResource(id = R.color.bitter_sweet),
+ textColor = Color.White
+ )
+ TagView(
+ text = data.text,
+ leadingIcon = data.leadingIcon,
+ tagViewModifiers = data.tagViewModifiers
+ )
}
@Composable
fun TagWithTrailingIcon() {
val context = LocalContext.current
- val tagViewModifiers = TagViewModifiers.Builder()
- .shape(CircleShape)
- .backgroundColor(Color.Black)
- .textColor(Color.White)
- .fontSize(15.sp)
- .build()
-
- val text = stringResource(id = co.yml.coreui.feature.ytag.R.string.tag_trailing_icon)
- TagView(text = text, trailingIcon = { enabled ->
- IconButton(modifier = Modifier
- .padding(end = dimensionResource(id = R.dimen.padding_medium))
- .size(dimensionResource(id = R.dimen.padding_normal_medium)), onClick = {
- if (enabled) {
- Toast.makeText(context, text, Toast.LENGTH_SHORT).show()
- }
- }) {
- Icon(
- painter = painterResource(id = co.yml.coreui.feature.ytag.R.drawable.ic_close_20px),
- contentDescription = null,
- tint = Color.White
- )
- }
- }, tagViewModifiers = tagViewModifiers)
+ val data = trailingIconData(
+ context = context,
+ backgroundColor = colorResource(id = R.color.power),
+ textColor = Color.White
+ )
+ TagView(
+ text = data.text,
+ trailingIcon = data.trailingIcon,
+ tagViewModifiers = data.tagViewModifiers
+ )
}
@Composable
fun TagWithLeadingTrailingIcon() {
val context = LocalContext.current
- val tagViewModifiers = TagViewModifiers.Builder()
- .shape(CircleShape)
- .backgroundColor(Color.Black)
- .maxLines(1)
- .overFlow(TextOverflow.Ellipsis)
- .textColor(Color.White)
- .onCLick {
-
- }
- .build()
+ val data = leadingIconTrailingIconData(
+ context = context,
+ backgroundColor = Color.Black,
+ textColor = Color.White
+ )
TagView(
- text = stringResource(id = co.yml.coreui.feature.ytag.R.string.tag_leading_trailing_icon),
- leadingIcon = { enabled ->
- val text = stringResource(id = co.yml.coreui.feature.ytag.R.string.tag_leading_icon)
- IconButton(
- modifier = Modifier.size(dimensionResource(id = R.dimen.padding_normal_medium)),
- onClick = {
- if (enabled) {
- Toast.makeText(context, text, Toast.LENGTH_SHORT).show()
- }
- }) {
- Icon(
- painter = painterResource(id = co.yml.coreui.feature.ytag.R.drawable.ic_location_24px),
- contentDescription = null,
- tint = Color.White
- )
- }
- },
- trailingIcon = { enabled ->
- val text = stringResource(id = co.yml.coreui.feature.ytag.R.string.tag_trailing_icon)
- IconButton(modifier = Modifier
- .padding(end = dimensionResource(id = R.dimen.padding_medium))
- .size(dimensionResource(id = R.dimen.padding_normal_small)), onClick = {
- if (enabled) {
- Toast.makeText(context, text, Toast.LENGTH_SHORT).show()
- }
- }) {
- Icon(
- painter = painterResource(id = co.yml.coreui.feature.ytag.R.drawable.ic_close_20px),
- contentDescription = null,
- tint = Color.White
- )
- }
- },
- tagViewModifiers = tagViewModifiers,
+ text = data.text,
+ leadingIcon = data.leadingIcon,
+ trailingIcon = data.trailingIcon,
+ tagViewModifiers = data.tagViewModifiers,
enabled = false
)
}
@@ -252,6 +199,7 @@ fun TagWithLeadingTrailingIcon() {
@Composable
fun BorderTag() {
val tagViewModifiers = TagViewModifiers.Builder()
+ .width(100.dp)
.textColor(Color.Black)
.enableBorder(true)
.borderColor(Color.Red)
@@ -270,6 +218,7 @@ fun BorderTag() {
@Composable
fun ShadowTag() {
val tagViewModifiers = TagViewModifiers.Builder()
+ .width(100.dp)
.textColor(colorResource(id = co.yml.coreui.feature.ytag.R.color.tag_text_color))
.backgroundColor(colorResource(id = co.yml.coreui.feature.ytag.R.color.tag_background_color))
.shape(CircleShape)
@@ -284,3 +233,266 @@ fun ShadowTag() {
tagViewModifiers = tagViewModifiers
)
}
+
+@Composable
+fun DefaultTagViewContainer() {
+ val context = LocalContext.current
+
+ val tagViewData = listOf(
+
+ capsuleTagData(context = context, backgroundColor = colorResource(id = R.color.cyan_900)),
+
+ rectangleTagData(
+ context = context,
+ backgroundColor = colorResource(id = R.color.cyan_700),
+ textColor = Color.White
+ ),
+
+ roundRectTagData(
+ context = context,
+ backgroundColor = colorResource(id = R.color.cyan_900),
+ textColor = Color.White
+ ),
+
+ leadingIconTagData(
+ context = context,
+ backgroundColor = colorResource(id = R.color.cyan_700),
+ textColor = Color.White
+ ),
+
+ trailingIconData(
+ context = context,
+ backgroundColor = colorResource(id = R.color.cyan_900),
+ textColor = Color.White
+ ),
+
+ leadingIconTrailingIconData(
+ context = context,
+ backgroundColor = colorResource(id = R.color.cyan_700),
+ textColor = Color.White
+ )
+ )
+
+ val tagViewContainerModifiers = TagViewContainerModifiers.Builder()
+ .containerPaddingValues(PaddingValues(8.dp))
+ .enableBorder(true)
+ .shape(RoundedCornerShape(4.dp))
+ .tagSpacingVertical(8.dp)
+ .tagSpacingHorizontal(8.dp)
+ .backgroundColor(colorResource(id = R.color.cyan_50))
+ .width(260.dp)
+ .height(180.dp)
+ .moreTagConfiguration(
+ TagViewData(
+ overFlowText = { count ->
+ "$count more"
+ },
+ tagViewModifiers = TagViewModifiers.Builder()
+ .backgroundColor(colorResource(id = R.color.cyan_50))
+ .width(80.dp)
+ .textAlign(TextAlign.Start)
+ .height(30.dp)
+ .textColor(Color.Black)
+ .onCLick { }.build()
+ )
+ )
+ .onCLick { item ->
+ val itemIndex = tagViewData.indexOf(item)
+ val updatedList = tagViewData.toMutableList()
+
+ if (itemIndex != -1) {
+ updatedList.removeAt(itemIndex)
+ }
+ }
+ .build()
+
+ TagViewContainer(
+ tagViewData = tagViewData,
+ tagViewContainerModifiers = tagViewContainerModifiers
+ )
+}
+
+/**
+ * @param context current context
+ * @param backgroundColor tag view background color
+ */
+fun capsuleTagData(context: Context, backgroundColor: Color): TagViewData {
+ return TagViewData(
+ text = context.getString(co.yml.coreui.feature.ytag.R.string.tag_capsule),
+ tagViewModifiers = TagViewModifiers.Builder()
+ .shape(CircleShape)
+ .backgroundColor(backgroundColor)
+ .textColor(Color.White)
+ .style(textStyle)
+ .build()
+ )
+}
+
+/**
+ * @param context current context
+ * @param backgroundColor tag view background color
+ * @param textColor tag view text color
+ */
+fun rectangleTagData(context: Context, backgroundColor: Color, textColor: Color): TagViewData {
+ return TagViewData(
+ text = context.getString(co.yml.coreui.feature.ytag.R.string.tag_rectangle),
+ tagViewModifiers = TagViewModifiers.Builder()
+ .width(90.dp)
+ .shape(RectangleShape)
+ .backgroundColor(backgroundColor)
+ .textColor(textColor)
+ .style(textStyle)
+ .build()
+ )
+}
+
+/**
+ * @param context current context
+ * @param backgroundColor tag view background color
+ * @param textColor tag view text color
+ */
+fun roundRectTagData(context: Context, backgroundColor: Color, textColor: Color): TagViewData {
+ return TagViewData(
+ text = context.getString(co.yml.coreui.feature.ytag.R.string.tag_round_rectangle),
+ tagViewModifiers = TagViewModifiers.Builder()
+ .shape(RoundedCornerShape(context.resources.getDimension(R.dimen.padding_small)))
+ .width(120.dp)
+ .backgroundColor(backgroundColor)
+ .textColor(textColor)
+ .style(textStyle)
+ .build()
+ )
+}
+
+/**
+ * @param context current context
+ * @param backgroundColor tag view background color
+ * @param textColor tag view text color
+ */
+fun leadingIconTagData(context: Context, backgroundColor: Color, textColor: Color): TagViewData {
+ return TagViewData(text = context.getString(co.yml.coreui.feature.ytag.R.string.tag_leading_icon),
+ tagViewModifiers = TagViewModifiers.Builder()
+ .width(120.dp)
+ .maxLines(1)
+ .overFlow(TextOverflow.Ellipsis)
+ .shape(CircleShape)
+ .backgroundColor(backgroundColor)
+ .textColor(textColor)
+ .fontStyle(FontStyle.Italic)
+ .build(),
+ leadingIcon = { enabled ->
+ IconButton(
+ modifier = Modifier.size(dimensionResource(id = R.dimen.padding_normal_medium)),
+ onClick = {
+ if (enabled) {
+ Toast.makeText(
+ context,
+ context.getString(co.yml.coreui.feature.ytag.R.string.tag_leading_icon),
+ Toast.LENGTH_SHORT
+ ).show()
+ }
+ }) {
+ Icon(
+ painter = painterResource(id = co.yml.coreui.feature.ytag.R.drawable.ic_location_24px),
+ contentDescription = null,
+ tint = Color.White
+ )
+ }
+ })
+}
+
+/**
+ * @param context current context
+ * @param backgroundColor tag view background color
+ * @param textColor tag view text color
+ */
+fun trailingIconData(context: Context, backgroundColor: Color, textColor: Color): TagViewData {
+ return TagViewData(text = context.getString(co.yml.coreui.feature.ytag.R.string.tag_trailing_icon),
+ tagViewModifiers = TagViewModifiers.Builder()
+ .width(150.dp)
+ .maxLines(1)
+ .textAlign(TextAlign.Start)
+ .overFlow(TextOverflow.Ellipsis)
+ .shape(CircleShape)
+ .backgroundColor(backgroundColor)
+ .textColor(textColor)
+ .fontSize(15.sp)
+ .build(),
+ trailingIcon = { enabled ->
+ IconButton(modifier = Modifier
+ .padding(end = dimensionResource(id = R.dimen.padding_medium))
+ .size(dimensionResource(id = R.dimen.padding_normal_medium)), onClick = {
+ if (enabled) {
+ Toast.makeText(
+ context,
+ context.getString(co.yml.coreui.feature.ytag.R.string.tag_trailing_icon),
+ Toast.LENGTH_SHORT
+ ).show()
+ }
+ }) {
+ Icon(
+ painter = painterResource(id = co.yml.coreui.feature.ytag.R.drawable.ic_close_20px),
+ contentDescription = null,
+ tint = Color.White
+ )
+ }
+ })
+}
+
+/**
+ * @param context current context
+ * @param backgroundColor tag view background color
+ * @param textColor tag view text color
+ */
+fun leadingIconTrailingIconData(
+ context: Context,
+ backgroundColor: Color,
+ textColor: Color
+): TagViewData {
+ return TagViewData(text = context.getString(co.yml.coreui.feature.ytag.R.string.tag_leading_trailing_icon),
+ tagViewModifiers = TagViewModifiers.Builder()
+ .width(140.dp)
+ .maxLines(1)
+ .overFlow(TextOverflow.Ellipsis)
+ .shape(CircleShape)
+ .backgroundColor(backgroundColor)
+ .maxLines(1)
+ .overFlow(TextOverflow.Ellipsis)
+ .textColor(textColor)
+ .onCLick {
+ }
+ .build(),
+ leadingIcon = { enabled ->
+ val text = stringResource(id = co.yml.coreui.feature.ytag.R.string.tag_leading_icon)
+ IconButton(
+ modifier = Modifier.size(dimensionResource(id = R.dimen.padding_normal_medium)),
+ onClick = {
+ if (enabled) {
+ Toast.makeText(context, text, Toast.LENGTH_SHORT).show()
+ }
+ }) {
+ Icon(
+ painter = painterResource(id = co.yml.coreui.feature.ytag.R.drawable.ic_location_24px),
+ contentDescription = null,
+ tint = Color.White
+ )
+ }
+ },
+ trailingIcon = { enabled ->
+ val text =
+ stringResource(id = co.yml.coreui.feature.ytag.R.string.tag_trailing_icon)
+ IconButton(modifier = Modifier
+ .padding(end = dimensionResource(id = R.dimen.padding_medium))
+ .size(dimensionResource(id = R.dimen.padding_normal_small)), onClick = {
+ if (enabled) {
+ Toast.makeText(context, text, Toast.LENGTH_SHORT).show()
+ }
+ }) {
+ Icon(
+ painter = painterResource(id = co.yml.coreui.feature.ytag.R.drawable.ic_close_20px),
+ contentDescription = null,
+ tint = Color.White
+ )
+ }
+ })
+}
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index e673153..505c3ca 100644
--- a/gradle/libs.versions.toml
+++ b/gradle/libs.versions.toml
@@ -23,6 +23,7 @@ androidxTestRunner = "1.5.1"
androidxTestMonitor = "1.6.0"
androidxTestCore = "1.4.0"
androidxTestExt = "1.1.4"
+constraintlayout = "1.0.1"
#hilt
hilt = "2.44"
@@ -94,6 +95,7 @@ androidx-navigation-compose = { group = "androidx.navigation", name = "navigatio
androidx-lifecycle-viewModelCompose = { group = "androidx.lifecycle", name = "lifecycle-viewmodel-compose", version.ref = "androidxLifecycle" }
androidx-lifecycle-viewModel-ktx = { group = "androidx.lifecycle", name = "lifecycle-viewmodel-ktx", version.ref = "androidxLifecycle" }
androidx-navigation-testing = { group = "androidx.navigation", name = "navigation-testing", version.ref = "androidxNavigation" }
+androidx-constraintlayout = { group = "androidx.constraintlayout", name = "constraintlayout-compose", version.ref = "constraintlayout" }
#hilt
hilt_compiler = { module = "com.google.dagger:hilt-android-compiler", version.ref = "hilt" }
@@ -130,7 +132,7 @@ test_runner = { module = "androidx.test:runner", version.ref = "test_runner" }
[bundles]
# Define bundles/groups of libraries
-compose = ["androidx.activity.compose", "androidx.compose.foundation", "androidx.navigation.compose", "androidx.compose.material3", "androidx.compose.material3.windowSizeClass", "androidx.compose.runtime","androidx.compose.ui.tooling","androidx.compose.ui.tooling.preview"]
+compose = ["androidx.activity.compose", "androidx.compose.foundation", "androidx.navigation.compose", "androidx.compose.material3", "androidx.compose.material3.windowSizeClass", "androidx.compose.runtime","androidx.compose.ui.tooling","androidx.compose.ui.tooling.preview", "androidx.constraintlayout"]
test = ["androidx.test.core","androidx.test.ext","androidx.test.rules","androidx.test.runner", "compose_ui_testing"]
coroutine_test = ["coroutine.test", "coroutine.turbine"]
hilt = ["hilt.compiler","hilt.android","hilt.test"]