From d18f227a6af312815b193a5aa419aee5ed14753f Mon Sep 17 00:00:00 2001 From: Pablo Date: Fri, 23 Aug 2024 11:38:51 +0200 Subject: [PATCH] Improve navigation bar items (#286) --- .../screens/others/NavigationBarScreen.kt | 133 +++++++---------- .../designsystem/NavigationBarSnapShotTest.kt | 134 +++++++---------- .../component/navigationBar/NavigationBar.kt | 47 ++++-- .../navigationBar/NavigationBarItem.kt | 9 +- .../navigationBar/NavigationBarTestTags.kt | 2 + .../component/NavigationBarTest.kt | 140 ++++++------------ 6 files changed, 188 insertions(+), 277 deletions(-) diff --git a/common/src/commonMain/kotlin/org/hisp/dhis/common/screens/others/NavigationBarScreen.kt b/common/src/commonMain/kotlin/org/hisp/dhis/common/screens/others/NavigationBarScreen.kt index 2feaf8f9f..2f8d266f3 100644 --- a/common/src/commonMain/kotlin/org/hisp/dhis/common/screens/others/NavigationBarScreen.kt +++ b/common/src/commonMain/kotlin/org/hisp/dhis/common/screens/others/NavigationBarScreen.kt @@ -2,7 +2,6 @@ package org.hisp.dhis.common.screens.others import androidx.compose.material.icons.Icons import androidx.compose.material.icons.automirrored.filled.Assignment -import androidx.compose.material.icons.automirrored.filled.List import androidx.compose.material.icons.automirrored.filled.StickyNote2 import androidx.compose.material.icons.automirrored.outlined.Assignment import androidx.compose.material.icons.automirrored.outlined.List @@ -15,7 +14,6 @@ import androidx.compose.material.icons.outlined.BarChart import androidx.compose.material.icons.outlined.Description import androidx.compose.material.icons.outlined.Hub import androidx.compose.material.icons.outlined.Map -import androidx.compose.material3.Icon import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf @@ -27,25 +25,27 @@ import org.hisp.dhis.mobile.ui.designsystem.component.ColumnScreenContainer import org.hisp.dhis.mobile.ui.designsystem.component.navigationBar.NavigationBar import org.hisp.dhis.mobile.ui.designsystem.component.navigationBar.NavigationBarItem +enum class NavigationItem { + DESCRIPTION, + VISUALIZATION, + LIST, + MAPS, + RELATIONSHIPS, + NOTES, + ASSIGNMENT, +} + @Composable fun NavigationBarScreen() { val homeItems = listOf( NavigationBarItem( - defaultIcon = { - Icon(imageVector = Icons.Outlined.Description, contentDescription = null) - }, - selectedIcon = { - Icon(imageVector = Icons.Filled.Description, contentDescription = null) - }, + id = NavigationItem.DESCRIPTION, + icon = Icons.Outlined.Description, label = "Description", ), NavigationBarItem( - defaultIcon = { - Icon(imageVector = Icons.Outlined.BarChart, contentDescription = null) - }, - selectedIcon = { - Icon(imageVector = Icons.Filled.BarChart, contentDescription = null) - }, + id = NavigationItem.VISUALIZATION, + icon = Icons.Outlined.BarChart, label = "Charts", showBadge = true, ), @@ -53,30 +53,20 @@ fun NavigationBarScreen() { val programItems = listOf( NavigationBarItem( - defaultIcon = { - Icon(imageVector = Icons.AutoMirrored.Outlined.List, contentDescription = null) - }, - selectedIcon = { - Icon(imageVector = Icons.AutoMirrored.Filled.List, contentDescription = null) - }, + id = NavigationItem.LIST, + icon = Icons.AutoMirrored.Outlined.List, label = "List", ), NavigationBarItem( - defaultIcon = { - Icon(imageVector = Icons.Outlined.Map, contentDescription = null) - }, - selectedIcon = { - Icon(imageVector = Icons.Filled.Map, contentDescription = null) - }, + id = NavigationItem.MAPS, + icon = Icons.Outlined.Map, + selectedIcon = Icons.Filled.Map, label = "Maps", ), NavigationBarItem( - defaultIcon = { - Icon(imageVector = Icons.Outlined.BarChart, contentDescription = null) - }, - selectedIcon = { - Icon(imageVector = Icons.Filled.BarChart, contentDescription = null) - }, + id = NavigationItem.VISUALIZATION, + icon = Icons.Outlined.BarChart, + selectedIcon = Icons.Filled.BarChart, label = "Charts", showBadge = true, badgeText = "32", @@ -85,39 +75,27 @@ fun NavigationBarScreen() { val enrollmentItems = listOf( NavigationBarItem( - defaultIcon = { - Icon(imageVector = Icons.AutoMirrored.Outlined.Assignment, contentDescription = null) - }, - selectedIcon = { - Icon(imageVector = Icons.AutoMirrored.Filled.Assignment, contentDescription = null) - }, + id = NavigationItem.ASSIGNMENT, + icon = Icons.AutoMirrored.Outlined.Assignment, + selectedIcon = Icons.AutoMirrored.Filled.Assignment, label = "Details", ), NavigationBarItem( - defaultIcon = { - Icon(imageVector = Icons.Outlined.BarChart, contentDescription = null) - }, - selectedIcon = { - Icon(imageVector = Icons.Filled.BarChart, contentDescription = null) - }, + id = NavigationItem.VISUALIZATION, + icon = Icons.Outlined.BarChart, + selectedIcon = Icons.Filled.BarChart, label = "Charts", ), NavigationBarItem( - defaultIcon = { - Icon(imageVector = Icons.Outlined.Hub, contentDescription = null) - }, - selectedIcon = { - Icon(imageVector = Icons.Filled.Hub, contentDescription = null) - }, + id = NavigationItem.RELATIONSHIPS, + icon = Icons.Outlined.Hub, + selectedIcon = Icons.Filled.Hub, label = "Relationships", ), NavigationBarItem( - defaultIcon = { - Icon(imageVector = Icons.AutoMirrored.Outlined.StickyNote2, contentDescription = null) - }, - selectedIcon = { - Icon(imageVector = Icons.AutoMirrored.Filled.StickyNote2, contentDescription = null) - }, + id = NavigationItem.NOTES, + icon = Icons.AutoMirrored.Outlined.StickyNote2, + selectedIcon = Icons.AutoMirrored.Filled.StickyNote2, label = "Notes", showBadge = true, ), @@ -125,30 +103,21 @@ fun NavigationBarScreen() { val formItems = listOf( NavigationBarItem( - defaultIcon = { - Icon(imageVector = Icons.Outlined.Description, contentDescription = null) - }, - selectedIcon = { - Icon(imageVector = Icons.Filled.Description, contentDescription = null) - }, + id = NavigationItem.DESCRIPTION, + icon = Icons.Outlined.Description, + selectedIcon = Icons.Filled.Description, label = "Description", ), NavigationBarItem( - defaultIcon = { - Icon(imageVector = Icons.Outlined.BarChart, contentDescription = null) - }, - selectedIcon = { - Icon(imageVector = Icons.Filled.BarChart, contentDescription = null) - }, + id = NavigationItem.VISUALIZATION, + icon = Icons.Outlined.BarChart, + selectedIcon = Icons.Filled.BarChart, label = "Charts", ), NavigationBarItem( - defaultIcon = { - Icon(imageVector = Icons.AutoMirrored.Outlined.StickyNote2, contentDescription = null) - }, - selectedIcon = { - Icon(imageVector = Icons.AutoMirrored.Filled.StickyNote2, contentDescription = null) - }, + id = NavigationItem.NOTES, + icon = Icons.AutoMirrored.Outlined.StickyNote2, + selectedIcon = Icons.AutoMirrored.Filled.StickyNote2, label = "Notes", showBadge = true, badgeText = "3", @@ -163,8 +132,8 @@ fun NavigationBarScreen() { NavigationBar( items = homeItems, selectedItemIndex = selectedHomeItemIndex, - ) { - selectedHomeItemIndex = it + ) { itemId -> + selectedHomeItemIndex = homeItems.indexOfFirst { it.id == itemId } } } ColumnComponentContainer("Program dashboard") { @@ -172,8 +141,8 @@ fun NavigationBarScreen() { NavigationBar( items = programItems, selectedItemIndex = selectedProgramItemIndex, - ) { - selectedProgramItemIndex = it + ) { itemId -> + selectedProgramItemIndex = programItems.indexOfFirst { it.id == itemId } } } @@ -182,8 +151,8 @@ fun NavigationBarScreen() { NavigationBar( items = enrollmentItems, selectedItemIndex = selectedEnrollmentItemIndex, - ) { - selectedEnrollmentItemIndex = it + ) { itemId -> + selectedEnrollmentItemIndex = enrollmentItems.indexOfFirst { it.id == itemId } } } @@ -192,8 +161,8 @@ fun NavigationBarScreen() { NavigationBar( items = formItems, selectedItemIndex = selectedFormItemIndex, - ) { - selectedFormItemIndex = it + ) { itemId -> + selectedFormItemIndex = formItems.indexOfFirst { it.id == itemId } } } } diff --git a/designsystem/src/androidUnitTest/kotlin/org/hisp/dhis/mobile/ui/designsystem/NavigationBarSnapShotTest.kt b/designsystem/src/androidUnitTest/kotlin/org/hisp/dhis/mobile/ui/designsystem/NavigationBarSnapShotTest.kt index 0774d7da7..852613287 100644 --- a/designsystem/src/androidUnitTest/kotlin/org/hisp/dhis/mobile/ui/designsystem/NavigationBarSnapShotTest.kt +++ b/designsystem/src/androidUnitTest/kotlin/org/hisp/dhis/mobile/ui/designsystem/NavigationBarSnapShotTest.kt @@ -2,7 +2,6 @@ package org.hisp.dhis.mobile.ui.designsystem import androidx.compose.material.icons.Icons import androidx.compose.material.icons.automirrored.filled.Assignment -import androidx.compose.material.icons.automirrored.filled.List import androidx.compose.material.icons.automirrored.filled.StickyNote2 import androidx.compose.material.icons.automirrored.outlined.Assignment import androidx.compose.material.icons.automirrored.outlined.List @@ -15,7 +14,6 @@ import androidx.compose.material.icons.outlined.BarChart import androidx.compose.material.icons.outlined.Description import androidx.compose.material.icons.outlined.Hub import androidx.compose.material.icons.outlined.Map -import androidx.compose.material3.Icon import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember @@ -31,26 +29,28 @@ class NavigationBarSnapShotTest { @get:Rule val paparazzi = paparazzi() + enum class NavigationItem { + DESCRIPTION, + VISUALIZATION, + LIST, + MAPS, + RELATIONSHIPS, + NOTES, + ASSIGNMENT, + } + @Test fun launchNavigationBar() { paparazzi.snapshot { val homeItems = listOf( NavigationBarItem( - defaultIcon = { - Icon(imageVector = Icons.Outlined.Description, contentDescription = null) - }, - selectedIcon = { - Icon(imageVector = Icons.Filled.Description, contentDescription = null) - }, + id = NavigationItem.DESCRIPTION, + icon = Icons.Outlined.Description, label = "Description", ), NavigationBarItem( - defaultIcon = { - Icon(imageVector = Icons.Outlined.BarChart, contentDescription = null) - }, - selectedIcon = { - Icon(imageVector = Icons.Filled.BarChart, contentDescription = null) - }, + id = NavigationItem.VISUALIZATION, + icon = Icons.Outlined.BarChart, label = "Charts", showBadge = true, ), @@ -58,30 +58,20 @@ class NavigationBarSnapShotTest { val programItems = listOf( NavigationBarItem( - defaultIcon = { - Icon(imageVector = Icons.AutoMirrored.Outlined.List, contentDescription = null) - }, - selectedIcon = { - Icon(imageVector = Icons.AutoMirrored.Filled.List, contentDescription = null) - }, + id = NavigationItem.LIST, + icon = Icons.AutoMirrored.Outlined.List, label = "List", ), NavigationBarItem( - defaultIcon = { - Icon(imageVector = Icons.Outlined.Map, contentDescription = null) - }, - selectedIcon = { - Icon(imageVector = Icons.Filled.Map, contentDescription = null) - }, + id = NavigationItem.MAPS, + icon = Icons.Outlined.Map, + selectedIcon = Icons.Filled.Map, label = "Maps", ), NavigationBarItem( - defaultIcon = { - Icon(imageVector = Icons.Outlined.BarChart, contentDescription = null) - }, - selectedIcon = { - Icon(imageVector = Icons.Filled.BarChart, contentDescription = null) - }, + id = NavigationItem.VISUALIZATION, + icon = Icons.Outlined.BarChart, + selectedIcon = Icons.Filled.BarChart, label = "Charts", showBadge = true, badgeText = "32", @@ -90,39 +80,27 @@ class NavigationBarSnapShotTest { val enrollmentItems = listOf( NavigationBarItem( - defaultIcon = { - Icon(imageVector = Icons.AutoMirrored.Outlined.Assignment, contentDescription = null) - }, - selectedIcon = { - Icon(imageVector = Icons.AutoMirrored.Filled.Assignment, contentDescription = null) - }, + id = NavigationItem.ASSIGNMENT, + icon = Icons.AutoMirrored.Outlined.Assignment, + selectedIcon = Icons.AutoMirrored.Filled.Assignment, label = "Details", ), NavigationBarItem( - defaultIcon = { - Icon(imageVector = Icons.Outlined.BarChart, contentDescription = null) - }, - selectedIcon = { - Icon(imageVector = Icons.Filled.BarChart, contentDescription = null) - }, + id = NavigationItem.VISUALIZATION, + icon = Icons.Outlined.BarChart, + selectedIcon = Icons.Filled.BarChart, label = "Charts", ), NavigationBarItem( - defaultIcon = { - Icon(imageVector = Icons.Outlined.Hub, contentDescription = null) - }, - selectedIcon = { - Icon(imageVector = Icons.Filled.Hub, contentDescription = null) - }, + id = NavigationItem.RELATIONSHIPS, + icon = Icons.Outlined.Hub, + selectedIcon = Icons.Filled.Hub, label = "Relationships", ), NavigationBarItem( - defaultIcon = { - Icon(imageVector = Icons.AutoMirrored.Outlined.StickyNote2, contentDescription = null) - }, - selectedIcon = { - Icon(imageVector = Icons.AutoMirrored.Filled.StickyNote2, contentDescription = null) - }, + id = NavigationItem.NOTES, + icon = Icons.AutoMirrored.Outlined.StickyNote2, + selectedIcon = Icons.AutoMirrored.Filled.StickyNote2, label = "Notes", showBadge = true, ), @@ -130,30 +108,21 @@ class NavigationBarSnapShotTest { val formItems = listOf( NavigationBarItem( - defaultIcon = { - Icon(imageVector = Icons.Outlined.Description, contentDescription = null) - }, - selectedIcon = { - Icon(imageVector = Icons.Filled.Description, contentDescription = null) - }, + id = NavigationItem.DESCRIPTION, + icon = Icons.Outlined.Description, + selectedIcon = Icons.Filled.Description, label = "Description", ), NavigationBarItem( - defaultIcon = { - Icon(imageVector = Icons.Outlined.BarChart, contentDescription = null) - }, - selectedIcon = { - Icon(imageVector = Icons.Filled.BarChart, contentDescription = null) - }, + id = NavigationItem.VISUALIZATION, + icon = Icons.Outlined.BarChart, + selectedIcon = Icons.Filled.BarChart, label = "Charts", ), NavigationBarItem( - defaultIcon = { - Icon(imageVector = Icons.AutoMirrored.Outlined.StickyNote2, contentDescription = null) - }, - selectedIcon = { - Icon(imageVector = Icons.AutoMirrored.Filled.StickyNote2, contentDescription = null) - }, + id = NavigationItem.NOTES, + icon = Icons.AutoMirrored.Outlined.StickyNote2, + selectedIcon = Icons.AutoMirrored.Filled.StickyNote2, label = "Notes", showBadge = true, badgeText = "3", @@ -168,8 +137,8 @@ class NavigationBarSnapShotTest { NavigationBar( items = homeItems, selectedItemIndex = selectedHomeItemIndex, - ) { - selectedHomeItemIndex = it + ) { itemId -> + selectedHomeItemIndex = homeItems.indexOfFirst { it.id == itemId } } } ColumnComponentContainer("Program dashboard") { @@ -177,8 +146,8 @@ class NavigationBarSnapShotTest { NavigationBar( items = programItems, selectedItemIndex = selectedProgramItemIndex, - ) { - selectedProgramItemIndex = it + ) { itemId -> + selectedProgramItemIndex = programItems.indexOfFirst { it.id == itemId } } } @@ -187,8 +156,9 @@ class NavigationBarSnapShotTest { NavigationBar( items = enrollmentItems, selectedItemIndex = selectedEnrollmentItemIndex, - ) { - selectedEnrollmentItemIndex = it + ) { itemId -> + selectedEnrollmentItemIndex = + enrollmentItems.indexOfFirst { it.id == itemId } } } @@ -197,8 +167,8 @@ class NavigationBarSnapShotTest { NavigationBar( items = formItems, selectedItemIndex = selectedFormItemIndex, - ) { - selectedFormItemIndex = it + ) { itemId -> + selectedFormItemIndex = formItems.indexOfFirst { it.id == itemId } } } } diff --git a/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/navigationBar/NavigationBar.kt b/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/navigationBar/NavigationBar.kt index edfb4dda3..d6c3ff291 100644 --- a/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/navigationBar/NavigationBar.kt +++ b/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/navigationBar/NavigationBar.kt @@ -4,6 +4,7 @@ import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.offset import androidx.compose.material3.HorizontalDivider +import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme import androidx.compose.material3.NavigationBarItem import androidx.compose.material3.NavigationBarItemDefaults @@ -15,24 +16,26 @@ import androidx.compose.ui.platform.testTag import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp -import org.hisp.dhis.mobile.ui.designsystem.component.ErrorBadge +import org.hisp.dhis.mobile.ui.designsystem.component.Badge import org.hisp.dhis.mobile.ui.designsystem.component.navigationBar.NavigationBarTestTags.NAVIGATION_BAR import org.hisp.dhis.mobile.ui.designsystem.component.navigationBar.NavigationBarTestTags.NAVIGATION_BAR_BORDER import org.hisp.dhis.mobile.ui.designsystem.component.navigationBar.NavigationBarTestTags.NAVIGATION_BAR_CONTAINER import org.hisp.dhis.mobile.ui.designsystem.component.navigationBar.NavigationBarTestTags.NAVIGATION_BAR_ITEM_BADGE_PREFIX +import org.hisp.dhis.mobile.ui.designsystem.component.navigationBar.NavigationBarTestTags.NAVIGATION_BAR_ITEM_DEFAULT_ICON_SUFFIX import org.hisp.dhis.mobile.ui.designsystem.component.navigationBar.NavigationBarTestTags.NAVIGATION_BAR_ITEM_LABEL_PREFIX import org.hisp.dhis.mobile.ui.designsystem.component.navigationBar.NavigationBarTestTags.NAVIGATION_BAR_ITEM_PREFIX +import org.hisp.dhis.mobile.ui.designsystem.component.navigationBar.NavigationBarTestTags.NAVIGATION_BAR_ITEM_SELECTED_ICON_SUFFIX import org.hisp.dhis.mobile.ui.designsystem.resource.provideFontResource import org.hisp.dhis.mobile.ui.designsystem.theme.Outline import org.hisp.dhis.mobile.ui.designsystem.theme.SurfaceColor import org.hisp.dhis.mobile.ui.designsystem.theme.TextColor @Composable -fun NavigationBar( +fun NavigationBar( modifier: Modifier = Modifier, - items: List, + items: List>, selectedItemIndex: Int? = null, - onItemClick: (Int) -> Unit, + onItemClick: (T) -> Unit, ) { Column( modifier = modifier.testTag(NAVIGATION_BAR_CONTAINER), @@ -75,7 +78,7 @@ fun NavigationBar( enabled = item.enabled, selected = selected, onClick = { - onItemClick(index) + onItemClick(item.id) }, ) } @@ -84,13 +87,24 @@ fun NavigationBar( } @Composable -fun NavigationBarItemIcon(item: NavigationBarItem, selected: Boolean) { +private fun NavigationBarItemIcon(item: NavigationBarItem, selected: Boolean) { Box { - if (selected) { - item.selectedIcon() - } else { - item.defaultIcon() - } + Icon( + modifier = Modifier.testTag( + item.iconTestTag(selected), + ), + imageVector = if (selected) { + item.selectedIcon + } else { + item.icon + }, + contentDescription = item.label, + tint = if (selected) { + SurfaceColor.Primary + } else { + TextColor.OnSurfaceVariant + }, + ) if (item.showBadge) { val badgeXOffset = if (!item.badgeText.isNullOrEmpty()) { 4.dp * item.badgeText.length @@ -99,7 +113,7 @@ fun NavigationBarItemIcon(item: NavigationBarItem, selected: Boolean) { } val badgeYOffset = if (!item.badgeText.isNullOrEmpty()) (-4).dp else 0.dp - ErrorBadge( + Badge( modifier = Modifier.testTag("$NAVIGATION_BAR_ITEM_BADGE_PREFIX${item.label}") .align(Alignment.TopEnd) .offset( @@ -112,6 +126,15 @@ fun NavigationBarItemIcon(item: NavigationBarItem, selected: Boolean) { } } +private fun NavigationBarItem.iconTestTag(selected: Boolean): String { + val iconTestId = if (selected) { + NAVIGATION_BAR_ITEM_SELECTED_ICON_SUFFIX + } else { + NAVIGATION_BAR_ITEM_DEFAULT_ICON_SUFFIX + } + return "${NAVIGATION_BAR_ITEM_PREFIX}${iconTestId}$label" +} + @Composable fun navigationBarItemColors() = NavigationBarItemDefaults.colors( selectedIconColor = SurfaceColor.Primary, diff --git a/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/navigationBar/NavigationBarItem.kt b/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/navigationBar/NavigationBarItem.kt index d47e24ebb..63d718018 100644 --- a/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/navigationBar/NavigationBarItem.kt +++ b/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/navigationBar/NavigationBarItem.kt @@ -1,10 +1,11 @@ package org.hisp.dhis.mobile.ui.designsystem.component.navigationBar -import androidx.compose.runtime.Composable +import androidx.compose.ui.graphics.vector.ImageVector -data class NavigationBarItem( - val defaultIcon: @Composable () -> Unit, - val selectedIcon: @Composable () -> Unit, +data class NavigationBarItem( + val id: T, + val icon: ImageVector, + val selectedIcon: ImageVector = icon, val label: String, val enabled: Boolean = true, val showBadge: Boolean = false, diff --git a/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/navigationBar/NavigationBarTestTags.kt b/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/navigationBar/NavigationBarTestTags.kt index 51972d3f6..e67926630 100644 --- a/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/navigationBar/NavigationBarTestTags.kt +++ b/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/navigationBar/NavigationBarTestTags.kt @@ -7,4 +7,6 @@ object NavigationBarTestTags { const val NAVIGATION_BAR_ITEM_PREFIX = "NAVIGATION_BAR_ITEM_" const val NAVIGATION_BAR_ITEM_LABEL_PREFIX = "NAVIGATION_BAR_ITEM_LABEL_" const val NAVIGATION_BAR_ITEM_BADGE_PREFIX = "NAVIGATION_BAR_ITEM_BADGE_" + const val NAVIGATION_BAR_ITEM_SELECTED_ICON_SUFFIX = "SELECTED_ICON_" + const val NAVIGATION_BAR_ITEM_DEFAULT_ICON_SUFFIX = "DEFAULT_ICON_" } diff --git a/designsystem/src/desktopTest/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/NavigationBarTest.kt b/designsystem/src/desktopTest/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/NavigationBarTest.kt index f9c2d922b..ac53f7e4b 100644 --- a/designsystem/src/desktopTest/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/NavigationBarTest.kt +++ b/designsystem/src/desktopTest/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/NavigationBarTest.kt @@ -5,13 +5,10 @@ import androidx.compose.material.icons.filled.BarChart import androidx.compose.material.icons.filled.Description import androidx.compose.material.icons.outlined.BarChart import androidx.compose.material.icons.outlined.Description -import androidx.compose.material3.Icon 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 androidx.compose.ui.platform.testTag import androidx.compose.ui.test.junit4.createComposeRule import androidx.compose.ui.test.onNodeWithTag import androidx.compose.ui.test.performClick @@ -31,42 +28,30 @@ class NavigationBarTest { @get:Rule val rule = createComposeRule() + enum class NavigationItem { + DESCRIPTION, + VISUALIZATION, + LIST, + MAPS, + RELATIONSHIPS, + NOTES, + ASSIGNMENT, + } + @Test fun shouldDisplayNavigationBarCorrectly() { rule.setContent { val items = listOf( NavigationBarItem( - defaultIcon = { - Icon( - modifier = Modifier.testTag("NAVIGATION_BAR_ITEM_DEFAULT_ICON_Description"), - imageVector = Icons.Outlined.Description, - contentDescription = null, - ) - }, - selectedIcon = { - Icon( - modifier = Modifier.testTag("NAVIGATION_BAR_ITEM_SELECTED_ICON_Description"), - imageVector = Icons.Filled.Description, - contentDescription = null, - ) - }, + id = NavigationItem.DESCRIPTION, + icon = Icons.Outlined.Description, + selectedIcon = Icons.Filled.Description, label = "Description", ), NavigationBarItem( - defaultIcon = { - Icon( - modifier = Modifier.testTag("NAVIGATION_BAR_ITEM_DEFAULT_ICON_Charts"), - imageVector = Icons.Outlined.BarChart, - contentDescription = null, - ) - }, - selectedIcon = { - Icon( - modifier = Modifier.testTag("NAVIGATION_BAR_ITEM_SELECTED_ICON_Charts"), - imageVector = Icons.Filled.BarChart, - contentDescription = null, - ) - }, + id = NavigationItem.VISUALIZATION, + icon = Icons.Outlined.BarChart, + selectedIcon = Icons.Filled.BarChart, label = "Charts", showBadge = true, ), @@ -84,8 +69,10 @@ class NavigationBarTest { rule.onNodeWithTag("${NAVIGATION_BAR_ITEM_PREFIX}Description", true).assertExists() rule.onNodeWithTag("${NAVIGATION_BAR_ITEM_LABEL_PREFIX}Description", true).assertExists() rule.onNodeWithTag("NAVIGATION_BAR_ITEM_DEFAULT_ICON_Description", true).assertExists() - rule.onNodeWithTag("NAVIGATION_BAR_ITEM_SELECTED_ICON_Description", true).assertDoesNotExist() - rule.onNodeWithTag("${NAVIGATION_BAR_ITEM_BADGE_PREFIX}Description", true).assertDoesNotExist() + rule.onNodeWithTag("NAVIGATION_BAR_ITEM_SELECTED_ICON_Description", true) + .assertDoesNotExist() + rule.onNodeWithTag("${NAVIGATION_BAR_ITEM_BADGE_PREFIX}Description", true) + .assertDoesNotExist() rule.onNodeWithTag("${NAVIGATION_BAR_ITEM_PREFIX}Charts", true).assertExists() rule.onNodeWithTag("${NAVIGATION_BAR_ITEM_LABEL_PREFIX}Charts", true).assertExists() rule.onNodeWithTag("NAVIGATION_BAR_ITEM_DEFAULT_ICON_Charts", true).assertExists() @@ -98,37 +85,15 @@ class NavigationBarTest { rule.setContent { val items = listOf( NavigationBarItem( - defaultIcon = { - Icon( - modifier = Modifier.testTag("NAVIGATION_BAR_ITEM_DEFAULT_ICON_Description"), - imageVector = Icons.Outlined.Description, - contentDescription = null, - ) - }, - selectedIcon = { - Icon( - modifier = Modifier.testTag("NAVIGATION_BAR_ITEM_SELECTED_ICON_Description"), - imageVector = Icons.Filled.Description, - contentDescription = null, - ) - }, + id = NavigationItem.DESCRIPTION, + icon = Icons.Outlined.Description, + selectedIcon = Icons.Filled.Description, label = "Description", ), NavigationBarItem( - defaultIcon = { - Icon( - modifier = Modifier.testTag("NAVIGATION_BAR_ITEM_DEFAULT_ICON_Charts"), - imageVector = Icons.Outlined.BarChart, - contentDescription = null, - ) - }, - selectedIcon = { - Icon( - modifier = Modifier.testTag("NAVIGATION_BAR_ITEM_SELECTED_ICON_Charts"), - imageVector = Icons.Filled.BarChart, - contentDescription = null, - ) - }, + id = NavigationItem.VISUALIZATION, + icon = Icons.Outlined.BarChart, + selectedIcon = Icons.Filled.BarChart, label = "Charts", showBadge = true, ), @@ -137,15 +102,17 @@ class NavigationBarTest { NavigationBar( items = items, selectedItemIndex = selectedItemIndex, - ) { - selectedItemIndex = it + ) { navigationItemId -> + selectedItemIndex = items.indexOfFirst { it.id == navigationItemId } } } rule.onNodeWithTag("NAVIGATION_BAR_ITEM_DEFAULT_ICON_Description", true).assertExists() - rule.onNodeWithTag("NAVIGATION_BAR_ITEM_SELECTED_ICON_Description", true).assertDoesNotExist() + rule.onNodeWithTag("NAVIGATION_BAR_ITEM_SELECTED_ICON_Description", true) + .assertDoesNotExist() rule.onNodeWithTag("${NAVIGATION_BAR_ITEM_PREFIX}Description", true).performClick() - rule.onNodeWithTag("NAVIGATION_BAR_ITEM_DEFAULT_ICON_Description", true).assertDoesNotExist() + rule.onNodeWithTag("NAVIGATION_BAR_ITEM_DEFAULT_ICON_Description", true) + .assertDoesNotExist() rule.onNodeWithTag("NAVIGATION_BAR_ITEM_SELECTED_ICON_Description", true).assertExists() } @@ -154,37 +121,14 @@ class NavigationBarTest { rule.setContent { val items = listOf( NavigationBarItem( - defaultIcon = { - Icon( - modifier = Modifier.testTag("NAVIGATION_BAR_ITEM_DEFAULT_ICON_Description"), - imageVector = Icons.Outlined.Description, - contentDescription = null, - ) - }, - selectedIcon = { - Icon( - modifier = Modifier.testTag("NAVIGATION_BAR_ITEM_SELECTED_ICON_Description"), - imageVector = Icons.Filled.Description, - contentDescription = null, - ) - }, + id = NavigationItem.DESCRIPTION, + icon = Icons.Outlined.Description, label = "Description", ), NavigationBarItem( - defaultIcon = { - Icon( - modifier = Modifier.testTag("NAVIGATION_BAR_ITEM_DEFAULT_ICON_Charts"), - imageVector = Icons.Outlined.BarChart, - contentDescription = null, - ) - }, - selectedIcon = { - Icon( - modifier = Modifier.testTag("NAVIGATION_BAR_ITEM_SELECTED_ICON_Charts"), - imageVector = Icons.Filled.BarChart, - contentDescription = null, - ) - }, + id = NavigationItem.VISUALIZATION, + icon = Icons.Outlined.BarChart, + selectedIcon = Icons.Filled.BarChart, label = "Charts", showBadge = true, ), @@ -193,18 +137,20 @@ class NavigationBarTest { NavigationBar( items = items, selectedItemIndex = selectedItemIndex, - ) { - selectedItemIndex = it + ) { navigationItemId -> + selectedItemIndex = items.indexOfFirst { it.id == navigationItemId } } } - rule.onNodeWithTag("NAVIGATION_BAR_ITEM_DEFAULT_ICON_Description", true).assertDoesNotExist() + rule.onNodeWithTag("NAVIGATION_BAR_ITEM_DEFAULT_ICON_Description", true) + .assertDoesNotExist() rule.onNodeWithTag("NAVIGATION_BAR_ITEM_SELECTED_ICON_Description", true).assertExists() rule.onNodeWithTag("NAVIGATION_BAR_ITEM_DEFAULT_ICON_Charts", true).assertExists() rule.onNodeWithTag("NAVIGATION_BAR_ITEM_SELECTED_ICON_Charts", true).assertDoesNotExist() rule.onNodeWithTag("${NAVIGATION_BAR_ITEM_PREFIX}Charts", true).performClick() rule.onNodeWithTag("NAVIGATION_BAR_ITEM_DEFAULT_ICON_Description", true).assertExists() - rule.onNodeWithTag("NAVIGATION_BAR_ITEM_SELECTED_ICON_Description", true).assertDoesNotExist() + rule.onNodeWithTag("NAVIGATION_BAR_ITEM_SELECTED_ICON_Description", true) + .assertDoesNotExist() rule.onNodeWithTag("NAVIGATION_BAR_ITEM_DEFAULT_ICON_Charts", true).assertDoesNotExist() rule.onNodeWithTag("NAVIGATION_BAR_ITEM_SELECTED_ICON_Charts", true).assertExists() }