package com.craigvg.lichun_android.ui.components.navigation import androidx.compose.animation.animateColorAsState import androidx.compose.animation.core.spring import androidx.compose.foundation.background import androidx.compose.foundation.clickable import androidx.compose.foundation.interaction.MutableInteractionSource import androidx.compose.foundation.layout.* import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.Icon 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.draw.shadow import androidx.compose.ui.graphics.Brush import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.unit.dp import com.craigvg.lichun_android.ui.theme.AppColors import com.craigvg.lichun_android.ui.theme.AppSpacing import com.craigvg.lichun_android.ui.theme.AppTypography /** * Custom tab bar with frosted glass aesthetic, pill selection indicator, and badge support. * Ported from iOS LiquidGlassTabBar.swift */ @Composable fun CozyTabBar( items: List, selectedIndex: Int, onItemSelected: (Int) -> Unit, modifier: Modifier = Modifier ) { Box( modifier = modifier .fillMaxWidth() .shadow( elevation = 8.dp, shape = RoundedCornerShape(topStart = AppSpacing.largeCornerRadius, topEnd = AppSpacing.largeCornerRadius), ambientColor = Color.Black.copy(alpha = 0.08f) ) .clip(RoundedCornerShape(topStart = AppSpacing.largeCornerRadius, topEnd = AppSpacing.largeCornerRadius)) .background( Brush.verticalGradient( colors = listOf( AppColors.glassTintLight, AppColors.surfaceElevated ) ) ) .padding(horizontal = AppSpacing.sm, vertical = AppSpacing.sm) ) { Row( modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceEvenly, verticalAlignment = Alignment.CenterVertically ) { items.forEachIndexed { index, item -> CozyTabBarItem( item = item, isSelected = index == selectedIndex, onClick = { onItemSelected(index) }, modifier = Modifier.weight(1f) ) } } } } @Composable private fun CozyTabBarItem( item: CozyTabItem, isSelected: Boolean, onClick: () -> Unit, modifier: Modifier = Modifier ) { val iconColor by animateColorAsState( targetValue = if (isSelected) AppColors.primary else AppColors.secondaryText, animationSpec = spring(), label = "iconColor" ) val bgColor by animateColorAsState( targetValue = if (isSelected) AppColors.tabSelection else Color.Transparent, animationSpec = spring(), label = "bgColor" ) Column( modifier = modifier .clip(RoundedCornerShape(AppSpacing.cornerRadius)) .background(bgColor) .clickable( interactionSource = remember { MutableInteractionSource() }, indication = null, onClick = onClick ) .padding(vertical = AppSpacing.xs), horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.spacedBy(2.dp) ) { Box { Icon( imageVector = item.icon, contentDescription = item.label, tint = iconColor, modifier = Modifier.size(AppSpacing.bottomNavIconSize) ) // Badge if (item.badgeCount > 0) { Box( modifier = Modifier .align(Alignment.TopEnd) .offset(x = 6.dp, y = (-4).dp) .size(16.dp) .background(AppColors.primary, RoundedCornerShape(8.dp)), contentAlignment = Alignment.Center ) { Text( text = if (item.badgeCount > 9) "9+" else "${item.badgeCount}", style = AppTypography.micro, color = Color.White ) } } } Text( text = item.label, style = AppTypography.micro, color = iconColor ) } } data class CozyTabItem( val label: String, val icon: ImageVector, val badgeCount: Int = 0 )