Skip to content

Commit

Permalink
Adds TopBar component and samples
Browse files Browse the repository at this point in the history
  • Loading branch information
ferdyrod committed Aug 23, 2024
1 parent d34f7be commit 88fa414
Show file tree
Hide file tree
Showing 4 changed files with 325 additions and 0 deletions.
2 changes: 2 additions & 0 deletions common/src/commonMain/kotlin/org/hisp/dhis/common/App.kt
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import org.hisp.dhis.common.screens.others.ProgressScreen
import org.hisp.dhis.common.screens.others.SearchBarScreen
import org.hisp.dhis.common.screens.others.SectionScreen
import org.hisp.dhis.common.screens.others.TagsScreen
import org.hisp.dhis.common.screens.others.TopBarScreen
import org.hisp.dhis.common.screens.parameter.ParameterSelectorScreen
import org.hisp.dhis.common.screens.toggleableInputs.ToggleableInputsScreen
import org.hisp.dhis.mobile.ui.designsystem.component.DropdownItem
Expand Down Expand Up @@ -101,6 +102,7 @@ fun Main(
Groups.SEARCH_BAR -> SearchBarScreen()
Groups.NAVIGATION_BAR -> NavigationBarScreen()
Groups.NO_GROUP_SELECTED -> NoComponentSelectedScreen()
Groups.TOP_BAR -> TopBarScreen()
}
} else {
NoComponentSelectedScreen(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,6 @@ enum class Groups(val label: String) {
INDICATOR("Indicators"),
PARAMETER_SELECTOR("Parameter selector"),
NAVIGATION_BAR("Navigation Bar"),
TOP_BAR("Top Bar"),
NO_GROUP_SELECTED("No group selected"),
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
package org.hisp.dhis.common.screens.others

import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.outlined.ArrowBack
import androidx.compose.material.icons.outlined.Delete
import androidx.compose.material.icons.outlined.FileDownload
import androidx.compose.material.icons.outlined.Menu
import androidx.compose.material.icons.outlined.Share
import androidx.compose.material3.DropdownMenu
import androidx.compose.material3.DropdownMenuItem
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import org.hisp.dhis.common.screens.Groups
import org.hisp.dhis.mobile.ui.designsystem.component.ColumnComponentContainer
import org.hisp.dhis.mobile.ui.designsystem.component.ColumnScreenContainer
import org.hisp.dhis.mobile.ui.designsystem.component.IconButton
import org.hisp.dhis.mobile.ui.designsystem.component.TopBar
import org.hisp.dhis.mobile.ui.designsystem.component.TopBarAction
import org.hisp.dhis.mobile.ui.designsystem.component.TopBarData
import org.hisp.dhis.mobile.ui.designsystem.component.TopBarType
import org.hisp.dhis.mobile.ui.designsystem.theme.SurfaceColor

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun TopBarScreen() {
val defaultTopBarData = TopBarData(
type = TopBarType.DEFAULT,
title = "Title",
navigationIcon = {
IconButton(
onClick = { },
icon = {
Icon(
imageVector = Icons.Outlined.Menu,
contentDescription = "Menu Button",
)
},
)
},
primaryAction = TopBarAction(
icon = Icons.Outlined.Share,
onClick = { },
),
secondaryAction = TopBarAction(
icon = Icons.Outlined.FileDownload,
onClick = { },
),
dropdownMenu = {
DropdownMenu(
expanded = false,
onDismissRequest = { },
) {
DropdownMenuItem(
text = { Text("Action 1") },
onClick = {},
leadingIcon = {
IconButton(
onClick = { },
icon = {
Icon(
imageVector = Icons.Outlined.Delete,
contentDescription = "Edit Button",
)
},
)
},
)
}
},
color = SurfaceColor.PrimaryContainer,
)

ColumnScreenContainer(
title = Groups.TOP_BAR.label,
) {
ColumnComponentContainer("Default") {
TopBar(
topBarData = defaultTopBarData,
)
}

ColumnComponentContainer("Back") {
val backTopBarData = defaultTopBarData
.copy(
navigationIcon = {
IconButton(
onClick = { },
icon = {
Icon(
imageVector = Icons.AutoMirrored.Outlined.ArrowBack,
contentDescription = "Back Button",
)
},
)
},
primaryAction = TopBarAction(
icon = Icons.Outlined.Delete,
onClick = {},
),
secondaryAction = null,
)
TopBar(
topBarData = backTopBarData,
)
}

ColumnComponentContainer("Without Icons") {
val backTopBarData = defaultTopBarData
.copy(
navigationIcon = {
IconButton(
onClick = { },
icon = {
Icon(
imageVector = Icons.AutoMirrored.Outlined.ArrowBack,
contentDescription = "Back Button",
)
},
)
},
primaryAction = null,
secondaryAction = null,
dropdownMenu = null,
)
TopBar(
topBarData = backTopBarData,
)
}

ColumnComponentContainer("Centered") {
val centeredTopBarData = defaultTopBarData
.copy(
type = TopBarType.CENTERED,
primaryAction = null,
secondaryAction = null,
dropdownMenu = {
DropdownMenu(
expanded = false,
onDismissRequest = { },
) {
DropdownMenuItem(
text = { Text("Action 1") },
onClick = {},
leadingIcon = {
IconButton(
onClick = { },
icon = {
Icon(
imageVector = Icons.Outlined.Delete,
contentDescription = "Edit Button",
)
},
)
},
)
}
},
)

TopBar(
topBarData = centeredTopBarData,
)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
package org.hisp.dhis.mobile.ui.designsystem.component

import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.MoreVert
import androidx.compose.material3.CenterAlignedTopAppBar
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBar
import androidx.compose.material3.TopAppBarDefaults
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 androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.text.style.TextOverflow

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun TopBar(
modifier: Modifier = Modifier,
topBarData: TopBarData,
) {
var showMenu by remember { mutableStateOf(false) }

if (topBarData.type == TopBarType.DEFAULT) {
TopAppBar(
modifier = modifier,
title = {
Text(text = topBarData.title)
},
navigationIcon = {
topBarData.navigationIcon()
},
actions = {
if (topBarData.primaryAction != null) {
IconButton(
onClick = { topBarData.primaryAction.onClick() },
icon = {
Icon(
imageVector = topBarData.primaryAction.icon,
contentDescription = "Primary Action",
)
},
)
}
if (topBarData.secondaryAction != null) {
IconButton(
onClick = { topBarData.secondaryAction.onClick() },
icon = {
Icon(
imageVector = topBarData.secondaryAction.icon,
contentDescription = "Primary Action",
)
},
)
}

if (topBarData.dropdownMenu != null) {
IconButton(
onClick = { showMenu = !showMenu },
icon = {
Icon(
imageVector = Icons.Default.MoreVert,
contentDescription = "More",
)
},
)
topBarData.dropdownMenu()
}
},
colors = TopAppBarDefaults.topAppBarColors(
containerColor = topBarData.color,
),
)
} else {
CenterAlignedTopAppBar(
modifier = modifier,
title = {
Text(
text = topBarData.title,
maxLines = 1,
overflow = TextOverflow.Ellipsis,
)
},
navigationIcon = {
topBarData.navigationIcon()
},
actions = {
if (topBarData.primaryAction != null) {
IconButton(
onClick = { topBarData.primaryAction.onClick() },
icon = {
Icon(
imageVector = topBarData.primaryAction.icon,
contentDescription = "Primary Action",
)
},
)
}
if (topBarData.secondaryAction != null) {
IconButton(
onClick = { topBarData.secondaryAction.onClick() },
icon = {
Icon(
imageVector = topBarData.secondaryAction.icon,
contentDescription = "Primary Action",
)
},
)
}

if (topBarData.dropdownMenu != null) {
IconButton(
onClick = { showMenu = !showMenu },
icon = {
Icon(
imageVector = Icons.Default.MoreVert,
contentDescription = "More",
)
},
)
topBarData.dropdownMenu()
}
},
colors = TopAppBarDefaults.topAppBarColors(
containerColor = topBarData.color,
),
)
}
}

@ExperimentalMaterial3Api
data class TopBarData(
val type: TopBarType = TopBarType.DEFAULT,
val title: String,
val navigationIcon: @Composable () -> Unit,
val primaryAction: TopBarAction? = null,
val secondaryAction: TopBarAction? = null,
val dropdownMenu: (@Composable () -> Unit)? = null,
val color: Color,
)

data class TopBarAction(
val icon: ImageVector,
val onClick: () -> Unit,
)

enum class TopBarType {
DEFAULT,
CENTERED,
}

0 comments on commit 88fa414

Please sign in to comment.