Modernize Android UI design system to match iOS
- Create comprehensive design system with Theme.kt, Type.kt, and Shape.kt - Update color palette to match iOS (primary #2563EB, accent #8B5CF6) - Implement modern typography scale across all text styles - Add consistent corner radius system (AppRadius) UI Improvements: - HomeScreen: Add personalized greeting, gradient icons, modern stats - TaskCard: Pill-style badges, semantic colors, clean metadata - ResidencesScreen: Gradient circular icons, location indicators - LoginScreen: Gradient button background, modern card styling Design Features: - Gradient backgrounds for visual interest - Semantic color coding for states - Flat design with minimal elevation - Consistent spacing and typography - Material3 shapes throughout 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
package com.mycrib.android.ui.components.task
|
||||
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.shape.CircleShape
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.*
|
||||
@@ -8,8 +10,11 @@ import androidx.compose.material3.*
|
||||
import androidx.compose.runtime.*
|
||||
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.unit.dp
|
||||
import com.mycrib.android.ui.theme.AppColors
|
||||
import com.mycrib.shared.models.TaskDetail
|
||||
import com.mycrib.shared.models.TaskCategory
|
||||
import com.mycrib.shared.models.TaskPriority
|
||||
@@ -32,10 +37,10 @@ fun TaskCard(
|
||||
) {
|
||||
Card(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
shape = RoundedCornerShape(16.dp),
|
||||
elevation = CardDefaults.cardElevation(defaultElevation = 2.dp),
|
||||
shape = MaterialTheme.shapes.large,
|
||||
elevation = CardDefaults.cardElevation(defaultElevation = 0.dp),
|
||||
colors = CardDefaults.cardColors(
|
||||
containerColor = MaterialTheme.colorScheme.surfaceContainerLowest
|
||||
containerColor = MaterialTheme.colorScheme.surface
|
||||
)
|
||||
) {
|
||||
Column(
|
||||
@@ -51,54 +56,75 @@ fun TaskCard(
|
||||
Column(modifier = Modifier.weight(1f)) {
|
||||
Text(
|
||||
text = task.title,
|
||||
style = MaterialTheme.typography.titleLarge,
|
||||
fontWeight = FontWeight.Bold
|
||||
style = MaterialTheme.typography.titleMedium,
|
||||
color = MaterialTheme.colorScheme.onSurface
|
||||
)
|
||||
Spacer(modifier = Modifier.height(4.dp))
|
||||
Spacer(modifier = Modifier.height(8.dp))
|
||||
// Pill-style category badge
|
||||
Surface(
|
||||
color = MaterialTheme.colorScheme.secondaryContainer,
|
||||
shape = RoundedCornerShape(8.dp)
|
||||
color = MaterialTheme.colorScheme.surfaceVariant,
|
||||
shape = RoundedCornerShape(12.dp)
|
||||
) {
|
||||
Text(
|
||||
text = task.category.name,
|
||||
modifier = Modifier.padding(horizontal = 8.dp, vertical = 4.dp),
|
||||
style = MaterialTheme.typography.labelMedium,
|
||||
color = MaterialTheme.colorScheme.onSecondaryContainer
|
||||
text = task.category.name.uppercase(),
|
||||
modifier = Modifier.padding(horizontal = 12.dp, vertical = 6.dp),
|
||||
style = MaterialTheme.typography.labelSmall,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Column(
|
||||
horizontalAlignment = Alignment.End,
|
||||
verticalArrangement = Arrangement.spacedBy(6.dp)
|
||||
verticalArrangement = Arrangement.spacedBy(8.dp)
|
||||
) {
|
||||
Surface(
|
||||
color = when (task.priority.name.lowercase()) {
|
||||
"urgent" -> MaterialTheme.colorScheme.error
|
||||
"high" -> MaterialTheme.colorScheme.errorContainer
|
||||
"medium" -> MaterialTheme.colorScheme.primaryContainer
|
||||
else -> MaterialTheme.colorScheme.surfaceVariant
|
||||
},
|
||||
shape = RoundedCornerShape(10.dp)
|
||||
// Priority badge with semantic colors
|
||||
val priorityColor = when (task.priority.name.lowercase()) {
|
||||
"urgent", "high" -> Color(0xFFEF4444) // Error/Red
|
||||
"medium" -> Color(0xFFF59E0B) // Warning/Orange
|
||||
else -> Color(0xFF10B981) // Success/Green
|
||||
}
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.background(
|
||||
priorityColor.copy(alpha = 0.15f),
|
||||
RoundedCornerShape(12.dp)
|
||||
)
|
||||
.padding(horizontal = 12.dp, vertical = 6.dp),
|
||||
horizontalArrangement = Arrangement.spacedBy(4.dp),
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.size(6.dp)
|
||||
.clip(CircleShape)
|
||||
.background(priorityColor)
|
||||
)
|
||||
Text(
|
||||
text = task.priority.name.uppercase(),
|
||||
modifier = Modifier.padding(horizontal = 10.dp, vertical = 6.dp),
|
||||
style = MaterialTheme.typography.labelMedium,
|
||||
fontWeight = FontWeight.Bold
|
||||
style = MaterialTheme.typography.labelSmall,
|
||||
color = priorityColor
|
||||
)
|
||||
}
|
||||
|
||||
// Status badge with semantic colors
|
||||
if (task.status != null) {
|
||||
val statusColor = when (task.status.name.lowercase()) {
|
||||
"completed" -> AppColors.taskCompleted
|
||||
"in_progress" -> AppColors.taskInProgress
|
||||
"pending" -> Color(0xFFF59E0B)
|
||||
"cancelled" -> AppColors.taskCanceled
|
||||
else -> Color(0xFF9CA3AF)
|
||||
}
|
||||
Surface(
|
||||
color = MaterialTheme.colorScheme.tertiaryContainer,
|
||||
shape = RoundedCornerShape(10.dp)
|
||||
color = statusColor.copy(alpha = 0.15f),
|
||||
shape = RoundedCornerShape(12.dp)
|
||||
) {
|
||||
Text(
|
||||
text = task.status.name.uppercase(),
|
||||
modifier = Modifier.padding(horizontal = 10.dp, vertical = 6.dp),
|
||||
style = MaterialTheme.typography.labelMedium,
|
||||
color = MaterialTheme.colorScheme.onTertiaryContainer
|
||||
text = task.status.name.replace("_", " ").uppercase(),
|
||||
modifier = Modifier.padding(horizontal = 12.dp, vertical = 6.dp),
|
||||
style = MaterialTheme.typography.labelSmall,
|
||||
color = statusColor
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -114,42 +140,61 @@ fun TaskCard(
|
||||
)
|
||||
}
|
||||
|
||||
Spacer(modifier = Modifier.height(12.dp))
|
||||
HorizontalDivider()
|
||||
Spacer(modifier = Modifier.height(12.dp))
|
||||
Spacer(modifier = Modifier.height(16.dp))
|
||||
HorizontalDivider(color = MaterialTheme.colorScheme.outlineVariant)
|
||||
Spacer(modifier = Modifier.height(16.dp))
|
||||
|
||||
// Metadata pills
|
||||
Row(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
horizontalArrangement = Arrangement.SpaceBetween
|
||||
horizontalArrangement = Arrangement.spacedBy(12.dp)
|
||||
) {
|
||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||
// Date pill
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.background(
|
||||
MaterialTheme.colorScheme.surfaceVariant,
|
||||
RoundedCornerShape(12.dp)
|
||||
)
|
||||
.padding(horizontal = 12.dp, vertical = 6.dp),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.spacedBy(6.dp)
|
||||
) {
|
||||
Icon(
|
||||
Icons.Default.CalendarToday,
|
||||
contentDescription = null,
|
||||
modifier = Modifier.size(16.dp),
|
||||
tint = MaterialTheme.colorScheme.primary
|
||||
modifier = Modifier.size(14.dp),
|
||||
tint = MaterialTheme.colorScheme.onSurfaceVariant
|
||||
)
|
||||
Spacer(modifier = Modifier.width(4.dp))
|
||||
Text(
|
||||
text = task.nextScheduledDate ?: task.dueDate ?: "N/A",
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
fontWeight = FontWeight.SemiBold
|
||||
style = MaterialTheme.typography.labelSmall,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant
|
||||
)
|
||||
}
|
||||
|
||||
// Cost pill
|
||||
task.estimatedCost?.let {
|
||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.background(
|
||||
MaterialTheme.colorScheme.surfaceVariant,
|
||||
RoundedCornerShape(12.dp)
|
||||
)
|
||||
.padding(horizontal = 12.dp, vertical = 6.dp),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.spacedBy(6.dp)
|
||||
) {
|
||||
Icon(
|
||||
Icons.Default.AttachMoney,
|
||||
contentDescription = null,
|
||||
modifier = Modifier.size(16.dp),
|
||||
tint = MaterialTheme.colorScheme.tertiary
|
||||
modifier = Modifier.size(14.dp),
|
||||
tint = MaterialTheme.colorScheme.onSurfaceVariant
|
||||
)
|
||||
Spacer(modifier = Modifier.width(4.dp))
|
||||
Text(
|
||||
text = "$$it",
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
fontWeight = FontWeight.SemiBold,
|
||||
color = MaterialTheme.colorScheme.tertiary
|
||||
style = MaterialTheme.typography.labelSmall,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -282,7 +327,8 @@ fun CompletionCard(completion: TaskCompletion) {
|
||||
colors = CardDefaults.cardColors(
|
||||
containerColor = MaterialTheme.colorScheme.surfaceVariant
|
||||
),
|
||||
shape = RoundedCornerShape(12.dp)
|
||||
shape = MaterialTheme.shapes.medium,
|
||||
elevation = CardDefaults.cardElevation(defaultElevation = 0.dp)
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
|
||||
@@ -1,15 +1,22 @@
|
||||
package com.mycrib.android.ui.screens
|
||||
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.shape.CircleShape
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.*
|
||||
import androidx.compose.material3.*
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.graphics.Brush
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||
import com.mycrib.android.ui.theme.AppColors
|
||||
import com.mycrib.android.ui.theme.AppRadius
|
||||
import com.mycrib.android.viewmodel.ResidenceViewModel
|
||||
import com.mycrib.shared.network.ApiResult
|
||||
|
||||
@@ -30,10 +37,17 @@ fun HomeScreen(
|
||||
Scaffold(
|
||||
topBar = {
|
||||
TopAppBar(
|
||||
title = { Text("myCrib") },
|
||||
title = { Text("myCrib", style = MaterialTheme.typography.headlineSmall) },
|
||||
colors = TopAppBarDefaults.topAppBarColors(
|
||||
containerColor = MaterialTheme.colorScheme.background
|
||||
),
|
||||
actions = {
|
||||
IconButton(onClick = onLogout) {
|
||||
Icon(Icons.Default.ExitToApp, contentDescription = "Logout")
|
||||
Icon(
|
||||
Icons.Default.ExitToApp,
|
||||
contentDescription = "Logout",
|
||||
tint = MaterialTheme.colorScheme.primary
|
||||
)
|
||||
}
|
||||
}
|
||||
)
|
||||
@@ -42,71 +56,116 @@ fun HomeScreen(
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.background(MaterialTheme.colorScheme.background)
|
||||
.padding(paddingValues)
|
||||
.padding(16.dp),
|
||||
verticalArrangement = Arrangement.spacedBy(16.dp)
|
||||
.padding(horizontal = 16.dp, vertical = 12.dp),
|
||||
verticalArrangement = Arrangement.spacedBy(20.dp)
|
||||
) {
|
||||
// Personalized Greeting
|
||||
Column(
|
||||
modifier = Modifier.padding(vertical = 8.dp)
|
||||
) {
|
||||
Text(
|
||||
text = "Welcome back",
|
||||
style = MaterialTheme.typography.titleLarge,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant
|
||||
)
|
||||
Text(
|
||||
text = "Manage your properties",
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant
|
||||
)
|
||||
}
|
||||
// Summary Card
|
||||
when (summaryState) {
|
||||
is ApiResult.Success -> {
|
||||
val summary = (summaryState as ApiResult.Success).data
|
||||
Card(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
shape = MaterialTheme.shapes.large,
|
||||
colors = CardDefaults.cardColors(
|
||||
containerColor = MaterialTheme.colorScheme.primaryContainer
|
||||
)
|
||||
containerColor = MaterialTheme.colorScheme.surface
|
||||
),
|
||||
elevation = CardDefaults.cardElevation(defaultElevation = 0.dp)
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(16.dp)
|
||||
.padding(20.dp)
|
||||
) {
|
||||
Text(
|
||||
text = "Overview",
|
||||
style = MaterialTheme.typography.titleMedium,
|
||||
color = MaterialTheme.colorScheme.onPrimaryContainer
|
||||
)
|
||||
Spacer(modifier = Modifier.height(8.dp))
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.spacedBy(12.dp)
|
||||
) {
|
||||
// Gradient circular icon
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.size(44.dp)
|
||||
.clip(CircleShape)
|
||||
.background(
|
||||
Brush.linearGradient(
|
||||
listOf(
|
||||
Color(0xFF2563EB),
|
||||
Color(0xFF8B5CF6)
|
||||
)
|
||||
)
|
||||
),
|
||||
contentAlignment = Alignment.Center
|
||||
) {
|
||||
Icon(
|
||||
Icons.Default.Home,
|
||||
contentDescription = null,
|
||||
tint = Color.White,
|
||||
modifier = Modifier.size(24.dp)
|
||||
)
|
||||
}
|
||||
Column {
|
||||
Text(
|
||||
text = "Overview",
|
||||
style = MaterialTheme.typography.titleMedium,
|
||||
color = MaterialTheme.colorScheme.onSurface
|
||||
)
|
||||
Text(
|
||||
text = "Your property stats",
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Spacer(modifier = Modifier.height(20.dp))
|
||||
|
||||
Row(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
horizontalArrangement = Arrangement.SpaceEvenly
|
||||
) {
|
||||
Column(horizontalAlignment = Alignment.CenterHorizontally) {
|
||||
Text(
|
||||
text = "${summary.residences.size}",
|
||||
style = MaterialTheme.typography.headlineMedium,
|
||||
color = MaterialTheme.colorScheme.onPrimaryContainer
|
||||
)
|
||||
Text(
|
||||
text = "Properties",
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
color = MaterialTheme.colorScheme.onPrimaryContainer
|
||||
)
|
||||
}
|
||||
Column(horizontalAlignment = Alignment.CenterHorizontally) {
|
||||
Text(
|
||||
text = "${summary.summary.totalTasks}",
|
||||
style = MaterialTheme.typography.headlineMedium,
|
||||
color = MaterialTheme.colorScheme.onPrimaryContainer
|
||||
)
|
||||
Text(
|
||||
text = "Total Tasks",
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
color = MaterialTheme.colorScheme.onPrimaryContainer
|
||||
)
|
||||
}
|
||||
Column(horizontalAlignment = Alignment.CenterHorizontally) {
|
||||
Text(
|
||||
text = "${summary.summary.totalPending}",
|
||||
style = MaterialTheme.typography.headlineMedium,
|
||||
color = MaterialTheme.colorScheme.onPrimaryContainer
|
||||
)
|
||||
Text(
|
||||
text = "Pending",
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
color = MaterialTheme.colorScheme.onPrimaryContainer
|
||||
)
|
||||
}
|
||||
StatItem(
|
||||
value = "${summary.residences.size}",
|
||||
label = "Properties",
|
||||
color = Color(0xFF3B82F6)
|
||||
)
|
||||
Divider(
|
||||
modifier = Modifier
|
||||
.height(48.dp)
|
||||
.width(1.dp),
|
||||
color = MaterialTheme.colorScheme.outlineVariant
|
||||
)
|
||||
StatItem(
|
||||
value = "${summary.summary.totalTasks}",
|
||||
label = "Total Tasks",
|
||||
color = Color(0xFF8B5CF6)
|
||||
)
|
||||
Divider(
|
||||
modifier = Modifier
|
||||
.height(48.dp)
|
||||
.width(1.dp),
|
||||
color = MaterialTheme.colorScheme.outlineVariant
|
||||
)
|
||||
StatItem(
|
||||
value = "${summary.summary.totalPending}",
|
||||
label = "Pending",
|
||||
color = Color(0xFFF59E0B)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -131,66 +190,126 @@ fun HomeScreen(
|
||||
}
|
||||
|
||||
// Residences Card
|
||||
Card(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.clickable { onNavigateToResidences() }
|
||||
) {
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(24.dp),
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
Icon(
|
||||
Icons.Default.Home,
|
||||
contentDescription = null,
|
||||
modifier = Modifier.size(48.dp)
|
||||
)
|
||||
Spacer(modifier = Modifier.width(16.dp))
|
||||
Column {
|
||||
Text(
|
||||
text = "Residences",
|
||||
style = MaterialTheme.typography.titleLarge
|
||||
)
|
||||
Text(
|
||||
text = "Manage your properties",
|
||||
style = MaterialTheme.typography.bodyMedium
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
NavigationCard(
|
||||
title = "Properties",
|
||||
subtitle = "Manage your residences",
|
||||
icon = Icons.Default.Home,
|
||||
iconColor = Color(0xFF3B82F6),
|
||||
onClick = onNavigateToResidences
|
||||
)
|
||||
|
||||
// Tasks Card
|
||||
Card(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.clickable { onNavigateToTasks() }
|
||||
) {
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(24.dp),
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
Icon(
|
||||
Icons.Default.CheckCircle,
|
||||
contentDescription = null,
|
||||
modifier = Modifier.size(48.dp)
|
||||
)
|
||||
Spacer(modifier = Modifier.width(16.dp))
|
||||
Column {
|
||||
Text(
|
||||
text = "Tasks",
|
||||
style = MaterialTheme.typography.titleLarge
|
||||
)
|
||||
Text(
|
||||
text = "View and manage tasks",
|
||||
style = MaterialTheme.typography.bodyMedium
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
NavigationCard(
|
||||
title = "Tasks",
|
||||
subtitle = "View and manage tasks",
|
||||
icon = Icons.Default.CheckCircle,
|
||||
iconColor = Color(0xFF10B981),
|
||||
onClick = onNavigateToTasks
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun StatItem(
|
||||
value: String,
|
||||
label: String,
|
||||
color: Color
|
||||
) {
|
||||
Column(
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
verticalArrangement = Arrangement.spacedBy(4.dp)
|
||||
) {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.size(36.dp)
|
||||
.clip(CircleShape)
|
||||
.background(color.copy(alpha = 0.1f)),
|
||||
contentAlignment = Alignment.Center
|
||||
) {
|
||||
Text(
|
||||
text = value,
|
||||
style = MaterialTheme.typography.titleLarge,
|
||||
color = color
|
||||
)
|
||||
}
|
||||
Text(
|
||||
text = label,
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun NavigationCard(
|
||||
title: String,
|
||||
subtitle: String,
|
||||
icon: androidx.compose.ui.graphics.vector.ImageVector,
|
||||
iconColor: Color,
|
||||
onClick: () -> Unit
|
||||
) {
|
||||
Card(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.clickable { onClick() },
|
||||
shape = MaterialTheme.shapes.large,
|
||||
colors = CardDefaults.cardColors(
|
||||
containerColor = MaterialTheme.colorScheme.surface
|
||||
),
|
||||
elevation = CardDefaults.cardElevation(defaultElevation = 0.dp)
|
||||
) {
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(20.dp),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.spacedBy(16.dp)
|
||||
) {
|
||||
// Gradient circular icon
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.size(56.dp)
|
||||
.clip(CircleShape)
|
||||
.background(
|
||||
Brush.linearGradient(
|
||||
listOf(
|
||||
iconColor,
|
||||
iconColor.copy(alpha = 0.7f)
|
||||
)
|
||||
)
|
||||
),
|
||||
contentAlignment = Alignment.Center
|
||||
) {
|
||||
Icon(
|
||||
icon,
|
||||
contentDescription = null,
|
||||
tint = Color.White,
|
||||
modifier = Modifier.size(28.dp)
|
||||
)
|
||||
}
|
||||
|
||||
Column(
|
||||
modifier = Modifier.weight(1f)
|
||||
) {
|
||||
Text(
|
||||
text = title,
|
||||
style = MaterialTheme.typography.titleMedium,
|
||||
color = MaterialTheme.colorScheme.onSurface
|
||||
)
|
||||
Spacer(modifier = Modifier.height(4.dp))
|
||||
Text(
|
||||
text = subtitle,
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant
|
||||
)
|
||||
}
|
||||
|
||||
Icon(
|
||||
Icons.Default.KeyboardArrowRight,
|
||||
contentDescription = null,
|
||||
tint = MaterialTheme.colorScheme.onSurfaceVariant
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.mycrib.android.ui.screens
|
||||
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.shape.CircleShape
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.*
|
||||
@@ -11,6 +12,8 @@ import androidx.compose.foundation.text.KeyboardOptions
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.graphics.Brush
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.text.input.ImeAction
|
||||
import androidx.compose.ui.text.input.KeyboardType
|
||||
@@ -63,11 +66,11 @@ fun LoginScreen(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth(0.9f)
|
||||
.wrapContentHeight(),
|
||||
shape = RoundedCornerShape(24.dp),
|
||||
shape = MaterialTheme.shapes.extraLarge,
|
||||
colors = CardDefaults.cardColors(
|
||||
containerColor = MaterialTheme.colorScheme.surface
|
||||
),
|
||||
elevation = CardDefaults.cardElevation(defaultElevation = 8.dp)
|
||||
elevation = CardDefaults.cardElevation(defaultElevation = 4.dp)
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
@@ -123,28 +126,54 @@ fun LoginScreen(
|
||||
|
||||
ErrorCard(message = errorMessage)
|
||||
|
||||
Button(
|
||||
onClick = {
|
||||
viewModel.login(username, password)
|
||||
},
|
||||
// Gradient button
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.height(56.dp),
|
||||
enabled = username.isNotEmpty() && password.isNotEmpty(),
|
||||
shape = RoundedCornerShape(12.dp)
|
||||
.height(56.dp)
|
||||
.clip(MaterialTheme.shapes.medium)
|
||||
.then(
|
||||
if (username.isNotEmpty() && password.isNotEmpty() && !isLoading) {
|
||||
Modifier.background(
|
||||
Brush.linearGradient(
|
||||
listOf(
|
||||
Color(0xFF2563EB),
|
||||
Color(0xFF8B5CF6)
|
||||
)
|
||||
)
|
||||
)
|
||||
} else {
|
||||
Modifier.background(MaterialTheme.colorScheme.onSurfaceVariant.copy(alpha = 0.3f))
|
||||
}
|
||||
),
|
||||
contentAlignment = Alignment.Center
|
||||
) {
|
||||
if (isLoading) {
|
||||
CircularProgressIndicator(
|
||||
modifier = Modifier.size(24.dp),
|
||||
color = MaterialTheme.colorScheme.onPrimary,
|
||||
strokeWidth = 2.dp
|
||||
)
|
||||
} else {
|
||||
Text(
|
||||
"Sign In",
|
||||
style = MaterialTheme.typography.titleMedium,
|
||||
fontWeight = FontWeight.SemiBold
|
||||
Button(
|
||||
onClick = {
|
||||
viewModel.login(username, password)
|
||||
},
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
enabled = username.isNotEmpty() && password.isNotEmpty(),
|
||||
shape = MaterialTheme.shapes.medium,
|
||||
colors = ButtonDefaults.buttonColors(
|
||||
containerColor = Color.Transparent,
|
||||
disabledContainerColor = Color.Transparent
|
||||
)
|
||||
) {
|
||||
if (isLoading) {
|
||||
CircularProgressIndicator(
|
||||
modifier = Modifier.size(24.dp),
|
||||
color = Color.White,
|
||||
strokeWidth = 2.dp
|
||||
)
|
||||
} else {
|
||||
Text(
|
||||
"Sign In",
|
||||
style = MaterialTheme.typography.titleMedium,
|
||||
fontWeight = FontWeight.SemiBold,
|
||||
color = Color.White
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
package com.mycrib.android.ui.screens
|
||||
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.foundation.shape.CircleShape
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.*
|
||||
@@ -11,6 +13,9 @@ import androidx.compose.material3.*
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.graphics.Brush
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||
@@ -315,8 +320,11 @@ fun ResidencesScreen(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.clickable { onResidenceClick(residence.id) },
|
||||
shape = RoundedCornerShape(16.dp),
|
||||
elevation = CardDefaults.cardElevation(defaultElevation = 2.dp)
|
||||
shape = MaterialTheme.shapes.large,
|
||||
elevation = CardDefaults.cardElevation(defaultElevation = 0.dp),
|
||||
colors = CardDefaults.cardColors(
|
||||
containerColor = MaterialTheme.colorScheme.surface
|
||||
)
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
@@ -325,32 +333,67 @@ fun ResidencesScreen(
|
||||
) {
|
||||
Row(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
horizontalArrangement = Arrangement.SpaceBetween,
|
||||
horizontalArrangement = Arrangement.spacedBy(16.dp),
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
// Gradient circular house icon
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.size(56.dp)
|
||||
.clip(CircleShape)
|
||||
.background(
|
||||
Brush.linearGradient(
|
||||
listOf(
|
||||
Color(0xFF2563EB),
|
||||
Color(0xFF8B5CF6)
|
||||
)
|
||||
)
|
||||
),
|
||||
contentAlignment = Alignment.Center
|
||||
) {
|
||||
Icon(
|
||||
Icons.Default.Home,
|
||||
contentDescription = null,
|
||||
tint = Color.White,
|
||||
modifier = Modifier.size(28.dp)
|
||||
)
|
||||
}
|
||||
|
||||
Column(modifier = Modifier.weight(1f)) {
|
||||
Text(
|
||||
text = residence.name,
|
||||
style = MaterialTheme.typography.titleLarge,
|
||||
fontWeight = FontWeight.Bold
|
||||
style = MaterialTheme.typography.titleMedium,
|
||||
color = MaterialTheme.colorScheme.onSurface
|
||||
)
|
||||
Spacer(modifier = Modifier.height(4.dp))
|
||||
Text(
|
||||
text = "${residence.streetAddress}",
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant
|
||||
)
|
||||
Text(
|
||||
text = "${residence.city}, ${residence.stateProvince}",
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant
|
||||
)
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.spacedBy(4.dp)
|
||||
) {
|
||||
Icon(
|
||||
Icons.Default.LocationOn,
|
||||
contentDescription = null,
|
||||
modifier = Modifier.size(14.dp),
|
||||
tint = MaterialTheme.colorScheme.onSurfaceVariant
|
||||
)
|
||||
Text(
|
||||
text = "${residence.city}, ${residence.stateProvince}",
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Icon(
|
||||
Icons.Default.KeyboardArrowRight,
|
||||
contentDescription = null,
|
||||
tint = MaterialTheme.colorScheme.onSurfaceVariant
|
||||
)
|
||||
}
|
||||
|
||||
Spacer(modifier = Modifier.height(16.dp))
|
||||
HorizontalDivider()
|
||||
Spacer(modifier = Modifier.height(12.dp))
|
||||
HorizontalDivider(color = MaterialTheme.colorScheme.outlineVariant)
|
||||
Spacer(modifier = Modifier.height(16.dp))
|
||||
|
||||
Row(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
@@ -360,19 +403,19 @@ fun ResidencesScreen(
|
||||
icon = Icons.Default.Assignment,
|
||||
value = "${residence.taskSummary.total}",
|
||||
label = "Tasks",
|
||||
color = MaterialTheme.colorScheme.primary
|
||||
color = Color(0xFF3B82F6)
|
||||
)
|
||||
TaskStatChip(
|
||||
icon = Icons.Default.CheckCircle,
|
||||
value = "${residence.taskSummary.completed}",
|
||||
label = "Done",
|
||||
color = MaterialTheme.colorScheme.tertiary
|
||||
color = Color(0xFF10B981)
|
||||
)
|
||||
TaskStatChip(
|
||||
icon = Icons.Default.Schedule,
|
||||
value = "${residence.taskSummary.pending}",
|
||||
label = "Pending",
|
||||
color = MaterialTheme.colorScheme.error
|
||||
color = Color(0xFFF59E0B)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
package com.mycrib.android.ui.theme
|
||||
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material3.Shapes
|
||||
import androidx.compose.ui.unit.dp
|
||||
|
||||
// Modern Shape System - Matching iOS Design System
|
||||
object AppRadius {
|
||||
val xs = 4.dp
|
||||
val sm = 8.dp
|
||||
val md = 12.dp
|
||||
val lg = 16.dp
|
||||
val xl = 20.dp
|
||||
val xxl = 24.dp
|
||||
}
|
||||
|
||||
val AppShapes = Shapes(
|
||||
// Small components (buttons, chips, badges)
|
||||
extraSmall = RoundedCornerShape(AppRadius.xs),
|
||||
small = RoundedCornerShape(AppRadius.sm),
|
||||
|
||||
// Medium components (cards, inputs)
|
||||
medium = RoundedCornerShape(AppRadius.md),
|
||||
|
||||
// Large components (dialogs, sheets)
|
||||
large = RoundedCornerShape(AppRadius.lg),
|
||||
extraLarge = RoundedCornerShape(AppRadius.xl)
|
||||
)
|
||||
@@ -5,51 +5,73 @@ import androidx.compose.material3.*
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.graphics.Color
|
||||
|
||||
// Bright color palette
|
||||
private val BrightBlue = Color(0xFF007AFF)
|
||||
private val BrightGreen = Color(0xFF34C759)
|
||||
private val BrightOrange = Color(0xFFFF9500)
|
||||
private val BrightRed = Color(0xFFFF3B30)
|
||||
private val BrightPurple = Color(0xFFAF52DE)
|
||||
private val BrightTeal = Color(0xFF5AC8FA)
|
||||
// Modern Color Palette - Matching iOS Design System
|
||||
// Primary Colors - Modern blue gradient
|
||||
private val Primary = Color(0xFF2563EB)
|
||||
private val PrimaryLight = Color(0xFF3B82F6)
|
||||
private val PrimaryDark = Color(0xFF1E40AF)
|
||||
|
||||
// Light variations for containers
|
||||
private val LightBlue = Color(0xFFE3F2FD)
|
||||
private val LightGreen = Color(0xFFE8F5E9)
|
||||
private val LightOrange = Color(0xFFFFF3E0)
|
||||
// Accent Colors
|
||||
private val Accent = Color(0xFF8B5CF6)
|
||||
private val AccentLight = Color(0xFFA78BFA)
|
||||
|
||||
// Dark variations
|
||||
private val DarkBlue = Color(0xFF0A84FF)
|
||||
private val DarkGreen = Color(0xFF30D158)
|
||||
private val DarkOrange = Color(0xFFFF9F0A)
|
||||
// Semantic Colors
|
||||
private val Success = Color(0xFF10B981)
|
||||
private val Warning = Color(0xFFF59E0B)
|
||||
private val Error = Color(0xFFEF4444)
|
||||
private val Info = Color(0xFF3B82F6)
|
||||
|
||||
// Neutral Colors - Modern grays
|
||||
private val Background = Color(0xFFF9FAFB)
|
||||
private val Surface = Color.White
|
||||
private val SurfaceSecondary = Color(0xFFF3F4F6)
|
||||
|
||||
private val TextPrimary = Color(0xFF111827)
|
||||
private val TextSecondary = Color(0xFF6B7280)
|
||||
private val TextTertiary = Color(0xFF9CA3AF)
|
||||
|
||||
private val Border = Color(0xFFE5E7EB)
|
||||
private val BorderLight = Color(0xFFF3F4F6)
|
||||
|
||||
// Task Status Colors
|
||||
private val TaskUpcoming = Color(0xFF3B82F6)
|
||||
private val TaskInProgress = Color(0xFFF59E0B)
|
||||
private val TaskCompleted = Color(0xFF10B981)
|
||||
private val TaskCanceled = Color(0xFF6B7280)
|
||||
private val TaskArchived = Color(0xFF9CA3AF)
|
||||
|
||||
// Dark mode variations
|
||||
private val DarkBackground = Color(0xFF1C1B1F)
|
||||
private val DarkSurface = Color(0xFF2B2930)
|
||||
private val DarkSurfaceSecondary = Color(0xFF3B3842)
|
||||
|
||||
private val DarkColorScheme = darkColorScheme(
|
||||
primary = DarkBlue,
|
||||
primary = PrimaryLight,
|
||||
onPrimary = Color.White,
|
||||
primaryContainer = Color(0xFF003D75),
|
||||
primaryContainer = PrimaryDark,
|
||||
onPrimaryContainer = Color(0xFFD0E4FF),
|
||||
|
||||
secondary = DarkGreen,
|
||||
secondary = Success,
|
||||
onSecondary = Color.White,
|
||||
secondaryContainer = Color(0xFF1B5E20),
|
||||
onSecondaryContainer = Color(0xFFB9F6CA),
|
||||
|
||||
tertiary = DarkOrange,
|
||||
tertiary = Warning,
|
||||
onTertiary = Color.White,
|
||||
tertiaryContainer = Color(0xFF663C00),
|
||||
onTertiaryContainer = Color(0xFFFFE0B2),
|
||||
|
||||
error = BrightRed,
|
||||
error = Error,
|
||||
onError = Color.White,
|
||||
errorContainer = Color(0xFF93000A),
|
||||
onErrorContainer = Color(0xFFFFDAD6),
|
||||
|
||||
background = Color(0xFF1C1B1F),
|
||||
background = DarkBackground,
|
||||
onBackground = Color(0xFFE6E1E5),
|
||||
|
||||
surface = Color(0xFF1C1B1F),
|
||||
surface = DarkSurface,
|
||||
onSurface = Color(0xFFE6E1E5),
|
||||
surfaceVariant = Color(0xFF49454F),
|
||||
surfaceVariant = DarkSurfaceSecondary,
|
||||
onSurfaceVariant = Color(0xFFCAC4D0),
|
||||
|
||||
outline = Color(0xFF938F99),
|
||||
@@ -57,36 +79,36 @@ private val DarkColorScheme = darkColorScheme(
|
||||
)
|
||||
|
||||
private val LightColorScheme = lightColorScheme(
|
||||
primary = BrightBlue,
|
||||
primary = Primary,
|
||||
onPrimary = Color.White,
|
||||
primaryContainer = LightBlue,
|
||||
onPrimaryContainer = Color(0xFF001D35),
|
||||
primaryContainer = Color(0xFFEBF2FF),
|
||||
onPrimaryContainer = PrimaryDark,
|
||||
|
||||
secondary = BrightGreen,
|
||||
secondary = Success,
|
||||
onSecondary = Color.White,
|
||||
secondaryContainer = LightGreen,
|
||||
onSecondaryContainer = Color(0xFF002106),
|
||||
secondaryContainer = Color(0xFFD1FAE5),
|
||||
onSecondaryContainer = Color(0xFF064E3B),
|
||||
|
||||
tertiary = BrightOrange,
|
||||
tertiary = Warning,
|
||||
onTertiary = Color.White,
|
||||
tertiaryContainer = LightOrange,
|
||||
onTertiaryContainer = Color(0xFF2B1700),
|
||||
tertiaryContainer = Color(0xFFFEF3C7),
|
||||
onTertiaryContainer = Color(0xFF78350F),
|
||||
|
||||
error = BrightRed,
|
||||
error = Error,
|
||||
onError = Color.White,
|
||||
errorContainer = Color(0xFFFFDAD6),
|
||||
onErrorContainer = Color(0xFF410002),
|
||||
errorContainer = Color(0xFFFEE2E2),
|
||||
onErrorContainer = Color(0xFF7F1D1D),
|
||||
|
||||
background = Color(0xFFFFFBFE),
|
||||
onBackground = Color(0xFF1C1B1F),
|
||||
background = Background,
|
||||
onBackground = TextPrimary,
|
||||
|
||||
surface = Color(0xFFFFFBFE),
|
||||
onSurface = Color(0xFF1C1B1F),
|
||||
surfaceVariant = Color(0xFFE7E0EC),
|
||||
onSurfaceVariant = Color(0xFF49454F),
|
||||
surface = Surface,
|
||||
onSurface = TextPrimary,
|
||||
surfaceVariant = SurfaceSecondary,
|
||||
onSurfaceVariant = TextSecondary,
|
||||
|
||||
outline = Color(0xFF79747E),
|
||||
outlineVariant = Color(0xFFCAC4D0)
|
||||
outline = Border,
|
||||
outlineVariant = BorderLight
|
||||
)
|
||||
|
||||
@Composable
|
||||
@@ -98,6 +120,20 @@ fun MyCribTheme(
|
||||
|
||||
MaterialTheme(
|
||||
colorScheme = colorScheme,
|
||||
typography = AppTypography,
|
||||
shapes = AppShapes,
|
||||
content = content
|
||||
)
|
||||
}
|
||||
|
||||
// Extended colors for semantic states (not part of Material3 ColorScheme)
|
||||
object AppColors {
|
||||
val accent = Accent
|
||||
val accentLight = AccentLight
|
||||
val info = Info
|
||||
val taskUpcoming = TaskUpcoming
|
||||
val taskInProgress = TaskInProgress
|
||||
val taskCompleted = TaskCompleted
|
||||
val taskCanceled = TaskCanceled
|
||||
val taskArchived = TaskArchived
|
||||
}
|
||||
|
||||
@@ -0,0 +1,94 @@
|
||||
package com.mycrib.android.ui.theme
|
||||
|
||||
import androidx.compose.material3.Typography
|
||||
import androidx.compose.ui.text.TextStyle
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.unit.sp
|
||||
|
||||
// Modern Typography Scale - Matching iOS Design System
|
||||
val AppTypography = Typography(
|
||||
// Display - For hero sections
|
||||
displayLarge = TextStyle(
|
||||
fontSize = 57.sp,
|
||||
fontWeight = FontWeight.Bold,
|
||||
lineHeight = 64.sp
|
||||
),
|
||||
displayMedium = TextStyle(
|
||||
fontSize = 45.sp,
|
||||
fontWeight = FontWeight.Bold,
|
||||
lineHeight = 52.sp
|
||||
),
|
||||
displaySmall = TextStyle(
|
||||
fontSize = 36.sp,
|
||||
fontWeight = FontWeight.Bold,
|
||||
lineHeight = 44.sp
|
||||
),
|
||||
|
||||
// Headline - For section headers
|
||||
headlineLarge = TextStyle(
|
||||
fontSize = 32.sp,
|
||||
fontWeight = FontWeight.Bold,
|
||||
lineHeight = 40.sp
|
||||
),
|
||||
headlineMedium = TextStyle(
|
||||
fontSize = 28.sp,
|
||||
fontWeight = FontWeight.SemiBold,
|
||||
lineHeight = 36.sp
|
||||
),
|
||||
headlineSmall = TextStyle(
|
||||
fontSize = 24.sp,
|
||||
fontWeight = FontWeight.SemiBold,
|
||||
lineHeight = 32.sp
|
||||
),
|
||||
|
||||
// Title - For card titles
|
||||
titleLarge = TextStyle(
|
||||
fontSize = 22.sp,
|
||||
fontWeight = FontWeight.SemiBold,
|
||||
lineHeight = 28.sp
|
||||
),
|
||||
titleMedium = TextStyle(
|
||||
fontSize = 18.sp,
|
||||
fontWeight = FontWeight.SemiBold,
|
||||
lineHeight = 24.sp
|
||||
),
|
||||
titleSmall = TextStyle(
|
||||
fontSize = 16.sp,
|
||||
fontWeight = FontWeight.SemiBold,
|
||||
lineHeight = 20.sp
|
||||
),
|
||||
|
||||
// Body - For main content
|
||||
bodyLarge = TextStyle(
|
||||
fontSize = 17.sp,
|
||||
fontWeight = FontWeight.Normal,
|
||||
lineHeight = 24.sp
|
||||
),
|
||||
bodyMedium = TextStyle(
|
||||
fontSize = 15.sp,
|
||||
fontWeight = FontWeight.Normal,
|
||||
lineHeight = 20.sp
|
||||
),
|
||||
bodySmall = TextStyle(
|
||||
fontSize = 13.sp,
|
||||
fontWeight = FontWeight.Normal,
|
||||
lineHeight = 16.sp
|
||||
),
|
||||
|
||||
// Label - For labels and captions
|
||||
labelLarge = TextStyle(
|
||||
fontSize = 14.sp,
|
||||
fontWeight = FontWeight.Medium,
|
||||
lineHeight = 20.sp
|
||||
),
|
||||
labelMedium = TextStyle(
|
||||
fontSize = 12.sp,
|
||||
fontWeight = FontWeight.Medium,
|
||||
lineHeight = 16.sp
|
||||
),
|
||||
labelSmall = TextStyle(
|
||||
fontSize = 11.sp,
|
||||
fontWeight = FontWeight.Medium,
|
||||
lineHeight = 16.sp
|
||||
)
|
||||
)
|
||||
Reference in New Issue
Block a user