From 34ae6a1b5406af93a97cdbcc31e5675b26fc9cd8 Mon Sep 17 00:00:00 2001 From: AmirmahdiNourkazemi Date: Mon, 8 Jun 2026 20:02:51 +0330 Subject: [PATCH] style: tab bar --- .../presentation/common/SegmentedTabBar.kt | 90 +++++++++++++++++++ .../presentation/screens/DrugDetailScreen.kt | 33 +++---- 2 files changed, 100 insertions(+), 23 deletions(-) create mode 100644 app/src/main/java/com/approagency/pharmacy/presentation/common/SegmentedTabBar.kt diff --git a/app/src/main/java/com/approagency/pharmacy/presentation/common/SegmentedTabBar.kt b/app/src/main/java/com/approagency/pharmacy/presentation/common/SegmentedTabBar.kt new file mode 100644 index 0000000..696ad25 --- /dev/null +++ b/app/src/main/java/com/approagency/pharmacy/presentation/common/SegmentedTabBar.kt @@ -0,0 +1,90 @@ +package com.approagency.pharmacy.presentation.common + +import androidx.compose.animation.animateColorAsState +import androidx.compose.animation.core.tween +import androidx.compose.foundation.background +import androidx.compose.foundation.clickable +import androidx.compose.foundation.interaction.MutableInteractionSource +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.remember +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.text.style.TextOverflow +import com.vada.caller.ui.theme.dime + +/** + * نوار تب‌های سگمنتی: تبِ انتخاب‌شده به‌صورت یک «قرص» پررنگ نمایش داده می‌شود + * تا کاملاً قابل لمس و قابل‌تشخیص باشد. عرض همه‌ی تب‌ها برابر است. + */ +@Composable +fun SegmentedTabBar( + tabs: List, + selectedIndex: Int, + onSelected: (Int) -> Unit, + modifier: Modifier = Modifier +) { + val dime = MaterialTheme.dime + Row( + modifier = modifier + .fillMaxWidth() + .clip(MaterialTheme.shapes.large) + .background(MaterialTheme.colorScheme.surfaceContainerHigh) + .padding(dime.xxs), + horizontalArrangement = Arrangement.spacedBy(dime.xxs) + ) { + tabs.forEachIndexed { index, title -> + val selected = index == selectedIndex + + val background by animateColorAsState( + targetValue = if (selected) MaterialTheme.colorScheme.primary else Color.Transparent, + animationSpec = tween(durationMillis = 200), + label = "segmentBackground" + ) + val foreground by animateColorAsState( + targetValue = if (selected) + MaterialTheme.colorScheme.onPrimary + else + MaterialTheme.colorScheme.onSurfaceVariant, + animationSpec = tween(durationMillis = 200), + label = "segmentForeground" + ) + + val interactionSource = remember { MutableInteractionSource() } + + Box( + modifier = Modifier + .weight(1f) + .clip(MaterialTheme.shapes.medium) + .background(background) + .clickable( + interactionSource = interactionSource, + indication = null + ) { onSelected(index) } + .padding(vertical = dime.sm, horizontal = dime.xs), + contentAlignment = Alignment.Center + ) { + Text( + text = title, + style = MaterialTheme.typography.labelMedium, + fontWeight = if (selected) FontWeight.Bold else FontWeight.Medium, + color = foreground, + maxLines = 1, + overflow = TextOverflow.Ellipsis, + textAlign = TextAlign.Center + ) + } + } + } +} diff --git a/app/src/main/java/com/approagency/pharmacy/presentation/screens/DrugDetailScreen.kt b/app/src/main/java/com/approagency/pharmacy/presentation/screens/DrugDetailScreen.kt index 32fe122..4180a3e 100644 --- a/app/src/main/java/com/approagency/pharmacy/presentation/screens/DrugDetailScreen.kt +++ b/app/src/main/java/com/approagency/pharmacy/presentation/screens/DrugDetailScreen.kt @@ -14,8 +14,6 @@ import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Scaffold -import androidx.compose.material3.Tab -import androidx.compose.material3.TabRow import androidx.compose.material3.Text import androidx.compose.material3.TopAppBar import androidx.compose.material3.TopAppBarDefaults @@ -29,13 +27,13 @@ import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalLayoutDirection -import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.LayoutDirection import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.navigation.NavController import com.approagency.pharmacy.presentation.common.ErrorState import com.approagency.pharmacy.presentation.common.Loading +import com.approagency.pharmacy.presentation.common.SegmentedTabBar import com.approagency.pharmacy.presentation.components.drugdetail.BrandNamesTabContent import com.approagency.pharmacy.presentation.components.drugdetail.DosageFormsTabContent import com.approagency.pharmacy.presentation.components.drugdetail.GeneralInfoTabContent @@ -140,26 +138,15 @@ fun DrugDetailScreen( ) } - TabRow( - selectedTabIndex = selectedTab, - containerColor = MaterialTheme.colorScheme.surface, - contentColor = MaterialTheme.colorScheme.primary - ) { - tabs.forEachIndexed { index, title -> - Tab( - selected = selectedTab == index, - onClick = { selectedTab = index }, - text = { - Text( - text = title, - style = MaterialTheme.typography.labelLarge, - fontWeight = if (selectedTab == index) FontWeight.Bold else FontWeight.Normal, - maxLines = 1 - ) - } - ) - } - } + SegmentedTabBar( + tabs = tabs, + selectedIndex = selectedTab, + onSelected = { selectedTab = it }, + modifier = Modifier.padding( + horizontal = dime.md, + vertical = dime.sm + ) + ) LazyColumn( modifier = Modifier