Material Design components for Compose Multiplatform, specifically optimized for iOS devices running on ARM64 architecture
—
Comprehensive theming system that adapts Material Design principles to iOS platform conventions while maintaining design consistency across platforms.
Main theming composable that provides colors, typography, and shapes to child components with iOS-specific adaptations.
/**
* MaterialTheme defines the styling principles from the Material Design specification
* This component also provides theme values to child components through composition locals
* @param colors A complete definition of the Material Design color palette
* @param typography A set of text styles to be used as this theme's typography system
* @param shapes A set of corner shapes to be used as this theme's shape system
* @param content The content inheriting this theme
*/
@Composable
fun MaterialTheme(
colors: Colors = MaterialTheme.colors,
typography: Typography = MaterialTheme.typography,
shapes: Shapes = MaterialTheme.shapes,
content: @Composable () -> Unit
)Usage Examples:
// Basic theme setup
MaterialTheme {
// Your app content
MyAppContent()
}
// Custom theme with iOS-appropriate colors
MaterialTheme(
colors = lightColors(
primary = Color(0xFF007AFF), // iOS blue
secondary = Color(0xFF34C759), // iOS green
surface = Color(0xFFF2F2F7), // iOS system background
background = Color(0xFFFFFFFF)
),
typography = Typography(
// iOS-friendly typography scale
)
) {
MyAppContent()
}
// Dark theme for iOS
MaterialTheme(
colors = darkColors(
primary = Color(0xFF0A84FF), // iOS dark blue
secondary = Color(0xFF30D158), // iOS dark green
surface = Color(0xFF1C1C1E), // iOS dark surface
background = Color(0xFF000000)
)
) {
MyAppContent()
}Material color palette data class with iOS platform adaptations and accessibility considerations.
/**
* A color scheme holds all the named color parameters for a Material theme
* Material components use these color parameters to style themselves
* @param primary The primary color is the color displayed most frequently across your app's screens and components
* @param primaryVariant The primary variant color is used to distinguish elements using primary colors
* @param secondary The secondary color provides more ways to accent and distinguish your product
* @param secondaryVariant The secondary variant color is used to distinguish elements using secondary colors
* @param background The background color appears behind scrollable content
* @param surface Surface colors affect surfaces of components, such as cards, sheets, and menus
* @param error The error color is used to indicate errors in components
* @param onPrimary Color used for text and icons displayed on top of the primary color
* @param onSecondary Color used for text and icons displayed on top of the secondary color
* @param onBackground Color used for text and icons displayed on top of the background color
* @param onSurface Color used for text and icons displayed on top of the surface color
* @param onError Color used for text and icons displayed on top of the error color
* @param isLight Whether this Colors represents a light or dark theme
*/
@Stable
class Colors(
val primary: Color,
val primaryVariant: Color,
val secondary: Color,
val secondaryVariant: Color,
val background: Color,
val surface: Color,
val error: Color,
val onPrimary: Color,
val onSecondary: Color,
val onBackground: Color,
val onSurface: Color,
val onError: Color,
val isLight: Boolean
)Factory function for creating light theme colors with iOS system color integration.
/**
* The Material Design light color scheme
* @param primary The primary color is the color displayed most frequently across your app's screens and components
* @param primaryVariant The primary variant color is used to distinguish elements using primary colors
* @param secondary The secondary color provides more ways to accent and distinguish your product
* @param secondaryVariant The secondary variant color is used to distinguish elements using secondary colors
* @param background The background color appears behind scrollable content
* @param surface Surface colors affect surfaces of components, such as cards, sheets, and menus
* @param error The error color is used to indicate errors in components
* @param onPrimary Color used for text and icons displayed on top of the primary color
* @param onSecondary Color used for text and icons displayed on top of the secondary color
* @param onBackground Color used for text and icons displayed on top of the background color
* @param onSurface Color used for text and icons displayed on top of the surface color
* @param onError Color used for text and icons displayed on top of the error color
*/
fun lightColors(
primary: Color = Color(0xFF6200EE),
primaryVariant: Color = Color(0xFF3700B3),
secondary: Color = Color(0xFF03DAC6),
secondaryVariant: Color = Color(0xFF018786),
background: Color = Color.White,
surface: Color = Color.White,
error: Color = Color(0xFFB00020),
onPrimary: Color = Color.White,
onSecondary: Color = Color.Black,
onBackground: Color = Color.Black,
onSurface: Color = Color.Black,
onError: Color = Color.White
): ColorsiOS System Color Examples:
// iOS-style light colors
val iOSLightColors = lightColors(
primary = Color(0xFF007AFF), // iOS system blue
primaryVariant = Color(0xFF0051D0), // Darker iOS blue
secondary = Color(0xFF34C759), // iOS system green
secondaryVariant = Color(0xFF248A3D), // Darker iOS green
background = Color(0xFFFFFFFF), // iOS system background
surface = Color(0xFFF2F2F7), // iOS system grouped background
error = Color(0xFFFF3B30), // iOS system red
onPrimary = Color.White,
onSecondary = Color.White,
onBackground = Color(0xFF000000), // iOS label
onSurface = Color(0xFF000000), // iOS label
onError = Color.White
)Factory function for creating dark theme colors optimized for iOS dark mode.
/**
* The Material Design dark color scheme
* @param primary The primary color is the color displayed most frequently across your app's screens and components
* @param primaryVariant The primary variant color is used to distinguish elements using primary colors
* @param secondary The secondary color provides more ways to accent and distinguish your product
* @param secondaryVariant The secondary variant color is used to distinguish elements using secondary colors
* @param background The background color appears behind scrollable content
* @param surface Surface colors affect surfaces of components, such as cards, sheets, and menus
* @param error The error color is used to indicate errors in components
* @param onPrimary Color used for text and icons displayed on top of the primary color
* @param onSecondary Color used for text and icons displayed on top of the secondary color
* @param onBackground Color used for text and icons displayed on top of the background color
* @param onSurface Color used for text and icons displayed on top of the surface color
* @param onError Color used for text and icons displayed on top of the error color
*/
fun darkColors(
primary: Color = Color(0xFFBB86FC),
primaryVariant: Color = Color(0xFF3700B3),
secondary: Color = Color(0xFF03DAC6),
secondaryVariant: Color = secondary,
background: Color = Color(0xFF121212),
surface: Color = Color(0xFF121212),
error: Color = Color(0xFFCF6679),
onPrimary: Color = Color.Black,
onSecondary: Color = Color.Black,
onBackground: Color = Color.White,
onSurface: Color = Color.White,
onError: Color = Color.Black
): ColorsiOS Dark Mode Examples:
// iOS-style dark colors
val iOSDarkColors = darkColors(
primary = Color(0xFF0A84FF), // iOS dark system blue
primaryVariant = Color(0xFF0056CC), // Darker variant
secondary = Color(0xFF30D158), // iOS dark system green
secondaryVariant = Color(0xFF248A3D), // Darker variant
background = Color(0xFF000000), // iOS system background dark
surface = Color(0xFF1C1C1E), // iOS system grouped background dark
error = Color(0xFFFF453A), // iOS system red dark
onPrimary = Color.White,
onSecondary = Color.Black,
onBackground = Color(0xFFFFFFFF), // iOS label dark
onSurface = Color(0xFFFFFFFF), // iOS label dark
onError = Color.White
)Material typography scale optimized for iOS text rendering and accessibility.
/**
* The Material Design typography scale includes a range of contrasting styles that support the needs of your product
* @param h1 The largest headline, reserved for short, important text or numerals
* @param h2 The second largest headline, reserved for short, important text or numerals
* @param h3 The third largest headline, reserved for short, important text or numerals
* @param h4 The fourth largest headline, reserved for short, important text or numerals
* @param h5 The fifth largest headline, reserved for short, important text or numerals
* @param h6 The smallest headline, reserved for short, important text or numerals
* @param subtitle1 The largest subtitle, and is typically reserved for medium-emphasis text that is shorter in length
* @param subtitle2 The smallest subtitle, and is typically reserved for medium-emphasis text that is shorter in length
* @param body1 The largest body, and is typically used for long-form writing as it works well for small text sizes
* @param body2 The smallest body, and is typically used for long-form writing as it works well for small text sizes
* @param button Text style for buttons - all caps and medium weight
* @param caption Used sparingly to annotate imagery or to introduce a headline
* @param overline Used sparingly to introduce a headline
*/
@Immutable
class Typography(
val h1: TextStyle = TextStyle(
fontWeight = FontWeight.Light,
fontSize = 96.sp,
letterSpacing = (-1.5).sp
),
val h2: TextStyle = TextStyle(
fontWeight = FontWeight.Light,
fontSize = 60.sp,
letterSpacing = (-0.5).sp
),
val h3: TextStyle = TextStyle(
fontWeight = FontWeight.Normal,
fontSize = 48.sp,
letterSpacing = 0.sp
),
val h4: TextStyle = TextStyle(
fontWeight = FontWeight.Normal,
fontSize = 34.sp,
letterSpacing = 0.25.sp
),
val h5: TextStyle = TextStyle(
fontWeight = FontWeight.Normal,
fontSize = 24.sp,
letterSpacing = 0.sp
),
val h6: TextStyle = TextStyle(
fontWeight = FontWeight.Medium,
fontSize = 20.sp,
letterSpacing = 0.15.sp
),
val subtitle1: TextStyle = TextStyle(
fontWeight = FontWeight.Normal,
fontSize = 16.sp,
letterSpacing = 0.15.sp
),
val subtitle2: TextStyle = TextStyle(
fontWeight = FontWeight.Medium,
fontSize = 14.sp,
letterSpacing = 0.1.sp
),
val body1: TextStyle = TextStyle(
fontWeight = FontWeight.Normal,
fontSize = 16.sp,
letterSpacing = 0.5.sp
),
val body2: TextStyle = TextStyle(
fontWeight = FontWeight.Normal,
fontSize = 14.sp,
letterSpacing = 0.25.sp
),
val button: TextStyle = TextStyle(
fontWeight = FontWeight.Medium,
fontSize = 14.sp,
letterSpacing = 1.25.sp
),
val caption: TextStyle = TextStyle(
fontWeight = FontWeight.Normal,
fontSize = 12.sp,
letterSpacing = 0.4.sp
),
val overline: TextStyle = TextStyle(
fontWeight = FontWeight.Normal,
fontSize = 10.sp,
letterSpacing = 1.5.sp
)
)iOS Typography Examples:
// iOS-optimized typography
val iOSTypography = Typography(
h1 = TextStyle(
fontFamily = FontFamily.Default, // Maps to iOS system font
fontWeight = FontWeight.Light,
fontSize = 96.sp,
letterSpacing = (-1.5).sp
),
body1 = TextStyle(
fontFamily = FontFamily.Default,
fontWeight = FontWeight.Normal,
fontSize = 16.sp,
letterSpacing = 0.5.sp,
lineHeight = 24.sp // iOS-appropriate line height
)
// ... other styles
)
// Using typography in components
Text(
text = "Large Title",
style = MaterialTheme.typography.h4
)
Text(
text = "Body text content",
style = MaterialTheme.typography.body1
)Material shape definitions for component corners, optimized for iOS visual guidelines.
/**
* Material shape values used to style different shape categories
* @param small The default shape style used by small components like Button or Chip
* @param medium The default shape style used by medium components like Card or AlertDialog
* @param large The default shape style used by large components like ModalBottomSheetLayout
*/
@Immutable
class Shapes(
val small: CornerBasedShape = RoundedCornerShape(4.dp),
val medium: CornerBasedShape = RoundedCornerShape(4.dp),
val large: CornerBasedShape = RoundedCornerShape(0.dp)
)iOS Shape Examples:
// iOS-style shapes with larger corner radius
val iOSShapes = Shapes(
small = RoundedCornerShape(8.dp), // iOS-style small corner radius
medium = RoundedCornerShape(12.dp), // iOS-style medium corner radius
large = RoundedCornerShape(16.dp) // iOS-style large corner radius
)
// Using shapes in components
Card(
shape = MaterialTheme.shapes.medium
) {
// Card content
}
Button(
shape = MaterialTheme.shapes.small
) {
Text("Rounded Button")
}Utilities for accessing current theme values throughout the component tree.
object MaterialTheme {
/**
* Retrieves the current Colors at the call site's position in the hierarchy
*/
val colors: Colors
@Composable
@ReadOnlyComposable
get()
/**
* Retrieves the current Typography at the call site's position in the hierarchy
*/
val typography: Typography
@Composable
@ReadOnlyComposable
get()
/**
* Retrieves the current Shapes at the call site's position in the hierarchy
*/
val shapes: Shapes
@Composable
@ReadOnlyComposable
get()
}Usage Examples:
@Composable
fun ThemedComponent() {
// Access current theme colors
val currentColors = MaterialTheme.colors
Surface(
color = currentColors.surface,
contentColor = currentColors.onSurface
) {
Text(
text = "Themed text",
style = MaterialTheme.typography.body1,
color = MaterialTheme.colors.onSurface
)
}
}Helper functions for determining appropriate content colors based on background colors.
/**
* The Material color system contains pairs of colors that are typically used for the background
* and content color inside a component. For example, a Button typically uses `primary` for its
* background, and `onPrimary` for the color of its content (usually text or iconography).
* This function tries to match the provided backgroundColor to a 'background' color in this
* Colors, and then will return the corresponding color used for content. For example, when
* backgroundColor is Colors.primary, this will return Colors.onPrimary.
* @param backgroundColor the background color to calculate a content color for
* @return the matching content color for backgroundColor. If backgroundColor is not present in
* the theme's Colors, then returns Color.Unspecified.
*/
@Composable
@ReadOnlyComposable
fun contentColorFor(backgroundColor: Color): Color
/**
* Updates the alpha of this color. Useful for creating translucent colors for iOS-style overlays
*/
fun Color.copy(alpha: Float): ColorUsage Examples:
// Automatic content color selection
Surface(
color = MaterialTheme.colors.primary
) {
Text(
text = "Automatically colored text",
color = contentColorFor(MaterialTheme.colors.primary) // Will be onPrimary
)
}
// Manual content color with alpha
Surface(
color = MaterialTheme.colors.surface.copy(alpha = 0.9f) // iOS-style translucent surface
) {
// Content
}Install with Tessl CLI
npx tessl i tessl/maven-org-jetbrains-compose-material--material-uikitarm64