0
# Material Design System
1
2
Compose Multiplatform for WASM/JS includes the complete Material Design system, providing a comprehensive set of components, theming capabilities, and design tokens that follow Google's Material Design guidelines. All Material components are optimized for web deployment while maintaining consistency with other platforms.
3
4
## Core Theming
5
6
### MaterialTheme
7
8
The foundation of Material Design theming.
9
10
```kotlin { .api }
11
@Composable
12
fun MaterialTheme(
13
colors: Colors = MaterialTheme.colors,
14
typography: Typography = MaterialTheme.typography,
15
shapes: Shapes = MaterialTheme.shapes,
16
content: @Composable () -> Unit
17
)
18
```
19
20
**Basic Setup:**
21
```kotlin { .api }
22
@Composable
23
fun App() {
24
MaterialTheme {
25
Surface {
26
// Your app content
27
MainContent()
28
}
29
}
30
}
31
```
32
33
**Custom Theme:**
34
```kotlin { .api }
35
@Composable
36
fun CustomTheme(content: @Composable () -> Unit) {
37
MaterialTheme(
38
colors = lightColors(
39
primary = Color(0xFF6200EE),
40
primaryVariant = Color(0xFF3700B3),
41
secondary = Color(0xFF03DAC6),
42
surface = Color.White,
43
background = Color(0xFFF5F5F5)
44
),
45
typography = Typography(
46
h1 = TextStyle(fontSize = 32.sp, fontWeight = FontWeight.Bold),
47
body1 = TextStyle(fontSize = 16.sp, lineHeight = 24.sp)
48
),
49
shapes = Shapes(
50
small = RoundedCornerShape(4.dp),
51
medium = RoundedCornerShape(8.dp),
52
large = RoundedCornerShape(16.dp)
53
),
54
content = content
55
)
56
}
57
```
58
59
### Colors
60
61
Material Design color system with light and dark theme support.
62
63
```kotlin { .api }
64
fun lightColors(
65
primary: Color = Color(0xFF6200EE),
66
primaryVariant: Color = Color(0xFF3700B3),
67
secondary: Color = Color(0xFF03DAC6),
68
secondaryVariant: Color = Color(0xFF018786),
69
background: Color = Color.White,
70
surface: Color = Color.White,
71
error: Color = Color(0xFFB00020),
72
onPrimary: Color = Color.White,
73
onSecondary: Color = Color.Black,
74
onBackground: Color = Color.Black,
75
onSurface: Color = Color.Black,
76
onError: Color = Color.White
77
): Colors
78
```
79
80
**Dark Theme:**
81
```kotlin { .api }
82
fun darkColors(
83
primary: Color = Color(0xFFBB86FC),
84
primaryVariant: Color = Color(0xFF3700B3),
85
secondary: Color = Color(0xFF03DAC6),
86
secondaryVariant: Color = Color(0xFF03DAC6),
87
background: Color = Color(0xFF121212),
88
surface: Color = Color(0xFF121212),
89
error: Color = Color(0xFFCF6679),
90
onPrimary: Color = Color.Black,
91
onSecondary: Color = Color.Black,
92
onBackground: Color = Color.White,
93
onSurface: Color = Color.White,
94
onError: Color = Color.Black
95
): Colors
96
```
97
98
**Dynamic Theme Selection:**
99
```kotlin { .api }
100
@Composable
101
fun AdaptiveTheme(content: @Composable () -> Unit) {
102
val isDarkMode = isSystemInDarkTheme()
103
104
MaterialTheme(
105
colors = if (isDarkMode) darkColors() else lightColors(),
106
content = content
107
)
108
}
109
```
110
111
### Typography
112
113
Material Design typography scale.
114
115
```kotlin { .api }
116
data class Typography(
117
val h1: TextStyle = TextStyle(/* defaults */),
118
val h2: TextStyle = TextStyle(/* defaults */),
119
val h3: TextStyle = TextStyle(/* defaults */),
120
val h4: TextStyle = TextStyle(/* defaults */),
121
val h5: TextStyle = TextStyle(/* defaults */),
122
val h6: TextStyle = TextStyle(/* defaults */),
123
val subtitle1: TextStyle = TextStyle(/* defaults */),
124
val subtitle2: TextStyle = TextStyle(/* defaults */),
125
val body1: TextStyle = TextStyle(/* defaults */),
126
val body2: TextStyle = TextStyle(/* defaults */),
127
val button: TextStyle = TextStyle(/* defaults */),
128
val caption: TextStyle = TextStyle(/* defaults */),
129
val overline: TextStyle = TextStyle(/* defaults */)
130
)
131
```
132
133
**Usage:**
134
```kotlin { .api }
135
@Composable
136
fun TypographyExample() {
137
Column {
138
Text("Headline 1", style = MaterialTheme.typography.h1)
139
Text("Headline 6", style = MaterialTheme.typography.h6)
140
Text("Body text", style = MaterialTheme.typography.body1)
141
Text("Caption text", style = MaterialTheme.typography.caption)
142
}
143
}
144
```
145
146
## Layout Components
147
148
### Scaffold
149
150
Main layout structure for Material Design apps.
151
152
```kotlin { .api }
153
@Composable
154
fun Scaffold(
155
modifier: Modifier = Modifier,
156
scaffoldState: ScaffoldState = rememberScaffoldState(),
157
topBar: @Composable () -> Unit = {},
158
bottomBar: @Composable () -> Unit = {},
159
snackbarHost: @Composable (SnackbarHostState) -> Unit = { SnackbarHost(it) },
160
floatingActionButton: @Composable () -> Unit = {},
161
floatingActionButtonPosition: FabPosition = FabPosition.End,
162
isFloatingActionButtonDocked: Boolean = false,
163
drawerContent: @Composable (ColumnScope.() -> Unit)? = null,
164
drawerGesturesEnabled: Boolean = true,
165
drawerShape: Shape = MaterialTheme.shapes.large,
166
drawerElevation: Dp = DrawerDefaults.Elevation,
167
drawerBackgroundColor: Color = MaterialTheme.colors.surface,
168
drawerContentColor: Color = contentColorFor(drawerBackgroundColor),
169
drawerScrimColor: Color = DrawerDefaults.scrimColor,
170
backgroundColor: Color = MaterialTheme.colors.background,
171
contentColor: Color = contentColorFor(backgroundColor),
172
content: @Composable (PaddingValues) -> Unit
173
)
174
```
175
176
**Basic Scaffold:**
177
```kotlin { .api }
178
@Composable
179
fun MainScreen() {
180
Scaffold(
181
topBar = {
182
TopAppBar(title = { Text("My App") })
183
},
184
floatingActionButton = {
185
FloatingActionButton(onClick = { /* action */ }) {
186
Icon(Icons.Default.Add, contentDescription = "Add")
187
}
188
}
189
) { paddingValues ->
190
LazyColumn(
191
modifier = Modifier.padding(paddingValues)
192
) {
193
// Content
194
}
195
}
196
}
197
```
198
199
### TopAppBar
200
201
Application top bar with title and actions.
202
203
```kotlin { .api }
204
@Composable
205
fun TopAppBar(
206
title: @Composable () -> Unit,
207
modifier: Modifier = Modifier,
208
navigationIcon: @Composable (() -> Unit)? = null,
209
actions: @Composable RowScope.() -> Unit = {},
210
backgroundColor: Color = MaterialTheme.colors.primarySurface,
211
contentColor: Color = contentColorFor(backgroundColor),
212
elevation: Dp = AppBarDefaults.TopAppBarElevation
213
)
214
```
215
216
**Usage:**
217
```kotlin { .api }
218
TopAppBar(
219
title = { Text("Screen Title") },
220
navigationIcon = {
221
IconButton(onClick = { /* navigate back */ }) {
222
Icon(Icons.Default.ArrowBack, contentDescription = "Back")
223
}
224
},
225
actions = {
226
IconButton(onClick = { /* search */ }) {
227
Icon(Icons.Default.Search, contentDescription = "Search")
228
}
229
IconButton(onClick = { /* more options */ }) {
230
Icon(Icons.Default.MoreVert, contentDescription = "More")
231
}
232
}
233
)
234
```
235
236
### Surface
237
238
Foundation component for elevation and clipping.
239
240
```kotlin { .api }
241
@Composable
242
fun Surface(
243
modifier: Modifier = Modifier,
244
shape: Shape = RectangleShape,
245
color: Color = MaterialTheme.colors.surface,
246
contentColor: Color = contentColorFor(color),
247
border: BorderStroke? = null,
248
elevation: Dp = 0.dp,
249
content: @Composable () -> Unit
250
)
251
```
252
253
**Usage:**
254
```kotlin { .api }
255
Surface(
256
modifier = Modifier.padding(16.dp),
257
shape = RoundedCornerShape(8.dp),
258
elevation = 4.dp
259
) {
260
Text(
261
text = "Elevated content",
262
modifier = Modifier.padding(16.dp)
263
)
264
}
265
```
266
267
## Navigation Components
268
269
### BottomNavigation
270
271
Bottom navigation bar for primary destinations.
272
273
```kotlin { .api }
274
@Composable
275
fun BottomNavigation(
276
modifier: Modifier = Modifier,
277
backgroundColor: Color = MaterialTheme.colors.primarySurface,
278
contentColor: Color = contentColorFor(backgroundColor),
279
elevation: Dp = BottomNavigationDefaults.Elevation,
280
content: @Composable RowScope.() -> Unit
281
)
282
```
283
284
**Usage:**
285
```kotlin { .api }
286
var selectedItem by remember { mutableStateOf(0) }
287
val items = listOf("Home", "Search", "Profile")
288
289
BottomNavigation {
290
items.forEachIndexed { index, item ->
291
BottomNavigationItem(
292
icon = { Icon(getIcon(index), contentDescription = item) },
293
label = { Text(item) },
294
selected = selectedItem == index,
295
onClick = { selectedItem = index }
296
)
297
}
298
}
299
```
300
301
### NavigationRail
302
303
Side navigation for larger screens.
304
305
```kotlin { .api }
306
@Composable
307
fun NavigationRail(
308
modifier: Modifier = Modifier,
309
backgroundColor: Color = MaterialTheme.colors.surface,
310
contentColor: Color = contentColorFor(backgroundColor),
311
elevation: Dp = NavigationRailDefaults.Elevation,
312
header: @Composable (ColumnScope.() -> Unit)? = null,
313
content: @Composable ColumnScope.() -> Unit
314
)
315
```
316
317
## Input Components
318
319
### OutlinedTextField
320
321
Outlined text input field.
322
323
```kotlin { .api }
324
@Composable
325
fun OutlinedTextField(
326
value: String,
327
onValueChange: (String) -> Unit,
328
modifier: Modifier = Modifier,
329
enabled: Boolean = true,
330
readOnly: Boolean = false,
331
textStyle: TextStyle = LocalTextStyle.current,
332
label: @Composable (() -> Unit)? = null,
333
placeholder: @Composable (() -> Unit)? = null,
334
leadingIcon: @Composable (() -> Unit)? = null,
335
trailingIcon: @Composable (() -> Unit)? = null,
336
isError: Boolean = false,
337
visualTransformation: VisualTransformation = VisualTransformation.None,
338
keyboardOptions: KeyboardOptions = KeyboardOptions.Default,
339
keyboardActions: KeyboardActions = KeyboardActions(),
340
singleLine: Boolean = false,
341
maxLines: Int = Int.MAX_VALUE,
342
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
343
shape: Shape = MaterialTheme.shapes.small,
344
colors: TextFieldColors = TextFieldDefaults.outlinedTextFieldColors()
345
)
346
```
347
348
**Usage:**
349
```kotlin { .api }
350
var email by remember { mutableStateOf("") }
351
var isError by remember { mutableStateOf(false) }
352
353
OutlinedTextField(
354
value = email,
355
onValueChange = {
356
email = it
357
isError = !android.util.Patterns.EMAIL_ADDRESS.matcher(it).matches()
358
},
359
label = { Text("Email") },
360
placeholder = { Text("Enter your email") },
361
leadingIcon = {
362
Icon(Icons.Default.Email, contentDescription = "Email")
363
},
364
isError = isError,
365
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Email)
366
)
367
```
368
369
### Checkbox
370
371
Selection control for binary choices.
372
373
```kotlin { .api }
374
@Composable
375
fun Checkbox(
376
checked: Boolean,
377
onCheckedChange: ((Boolean) -> Unit)?,
378
modifier: Modifier = Modifier,
379
enabled: Boolean = true,
380
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
381
colors: CheckboxColors = CheckboxDefaults.colors()
382
)
383
```
384
385
**Usage:**
386
```kotlin { .api }
387
var isChecked by remember { mutableStateOf(false) }
388
389
Row(
390
verticalAlignment = Alignment.CenterVertically
391
) {
392
Checkbox(
393
checked = isChecked,
394
onCheckedChange = { isChecked = it }
395
)
396
Text("Accept terms and conditions")
397
}
398
```
399
400
### Switch
401
402
Toggle control for binary choices.
403
404
```kotlin { .api }
405
@Composable
406
fun Switch(
407
checked: Boolean,
408
onCheckedChange: ((Boolean) -> Unit)?,
409
modifier: Modifier = Modifier,
410
enabled: Boolean = true,
411
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
412
colors: SwitchColors = SwitchDefaults.colors()
413
)
414
```
415
416
**Usage:**
417
```kotlin { .api }
418
var isEnabled by remember { mutableStateOf(true) }
419
420
Row(
421
modifier = Modifier.fillMaxWidth(),
422
horizontalArrangement = Arrangement.SpaceBetween,
423
verticalAlignment = Alignment.CenterVertically
424
) {
425
Text("Notifications")
426
Switch(
427
checked = isEnabled,
428
onCheckedChange = { isEnabled = it }
429
)
430
}
431
```
432
433
## Feedback Components
434
435
### Snackbar
436
437
Brief messages about app processes.
438
439
```kotlin { .api }
440
@Composable
441
fun Snackbar(
442
modifier: Modifier = Modifier,
443
action: @Composable (() -> Unit)? = null,
444
actionOnNewLine: Boolean = false,
445
shape: Shape = MaterialTheme.shapes.small,
446
backgroundColor: Color = SnackbarDefaults.backgroundColor,
447
contentColor: Color = MaterialTheme.colors.surface,
448
elevation: Dp = 6.dp,
449
content: @Composable () -> Unit
450
)
451
```
452
453
**Usage:**
454
```kotlin { .api }
455
val snackbarHostState = remember { SnackbarHostState() }
456
457
LaunchedEffect(key1 = someEvent) {
458
snackbarHostState.showSnackbar(
459
message = "Item deleted",
460
actionLabel = "Undo",
461
duration = SnackbarDuration.Short
462
)
463
}
464
465
SnackbarHost(
466
hostState = snackbarHostState,
467
snackbar = { data ->
468
Snackbar(
469
action = {
470
data.actionLabel?.let { actionLabel ->
471
TextButton(onClick = { data.performAction() }) {
472
Text(actionLabel)
473
}
474
}
475
}
476
) {
477
Text(data.message)
478
}
479
}
480
)
481
```
482
483
### CircularProgressIndicator
484
485
Loading indicator for indeterminate progress.
486
487
```kotlin { .api }
488
@Composable
489
fun CircularProgressIndicator(
490
modifier: Modifier = Modifier,
491
color: Color = MaterialTheme.colors.primary,
492
strokeWidth: Dp = ProgressIndicatorDefaults.StrokeWidth
493
)
494
```
495
496
**Determinate Progress:**
497
```kotlin { .api }
498
@Composable
499
fun CircularProgressIndicator(
500
progress: Float,
501
modifier: Modifier = Modifier,
502
color: Color = MaterialTheme.colors.primary,
503
strokeWidth: Dp = ProgressIndicatorDefaults.StrokeWidth
504
)
505
```
506
507
**Usage:**
508
```kotlin { .api }
509
// Indeterminate
510
CircularProgressIndicator()
511
512
// Determinate
513
var progress by remember { mutableStateOf(0.0f) }
514
CircularProgressIndicator(progress = progress)
515
```
516
517
## Card Components
518
519
### Card
520
521
Material Design card container.
522
523
```kotlin { .api }
524
@Composable
525
fun Card(
526
modifier: Modifier = Modifier,
527
shape: Shape = MaterialTheme.shapes.medium,
528
backgroundColor: Color = MaterialTheme.colors.surface,
529
contentColor: Color = contentColorFor(backgroundColor),
530
border: BorderStroke? = null,
531
elevation: Dp = 1.dp,
532
content: @Composable () -> Unit
533
)
534
```
535
536
**Usage:**
537
```kotlin { .api }
538
Card(
539
modifier = Modifier
540
.fillMaxWidth()
541
.padding(16.dp)
542
.clickable { /* card clicked */ },
543
elevation = 4.dp
544
) {
545
Column(
546
modifier = Modifier.padding(16.dp)
547
) {
548
Text(
549
text = "Card Title",
550
style = MaterialTheme.typography.h6
551
)
552
Spacer(Modifier.height(8.dp))
553
Text(
554
text = "Card content goes here with additional information.",
555
style = MaterialTheme.typography.body2
556
)
557
}
558
}
559
```
560
561
## Dialog Components
562
563
### AlertDialog
564
565
Modal dialog for important decisions.
566
567
```kotlin { .api }
568
@Composable
569
fun AlertDialog(
570
onDismissRequest: () -> Unit,
571
buttons: @Composable () -> Unit,
572
modifier: Modifier = Modifier,
573
title: (@Composable () -> Unit)? = null,
574
text: (@Composable () -> Unit)? = null,
575
shape: Shape = MaterialTheme.shapes.medium,
576
backgroundColor: Color = MaterialTheme.colors.surface,
577
contentColor: Color = contentColorFor(backgroundColor)
578
)
579
```
580
581
**Usage:**
582
```kotlin { .api }
583
var showDialog by remember { mutableStateOf(false) }
584
585
if (showDialog) {
586
AlertDialog(
587
onDismissRequest = { showDialog = false },
588
title = { Text("Confirm Action") },
589
text = { Text("Are you sure you want to delete this item?") },
590
buttons = {
591
Row(
592
modifier = Modifier.fillMaxWidth(),
593
horizontalArrangement = Arrangement.End
594
) {
595
TextButton(onClick = { showDialog = false }) {
596
Text("Cancel")
597
}
598
TextButton(onClick = {
599
// Perform action
600
showDialog = false
601
}) {
602
Text("Delete")
603
}
604
}
605
}
606
)
607
}
608
```
609
610
## WASM-Specific Optimizations
611
612
### Performance Considerations
613
614
- **Theme switching**: Efficient dark/light mode transitions
615
- **Color animations**: Smooth color transitions between themes
616
- **Typography rendering**: Optimized text rendering for web
617
618
### Browser Integration
619
620
- **System theme detection**: Automatic dark mode detection
621
- **High contrast support**: Respects browser accessibility settings
622
- **Touch optimization**: Material components optimized for touch interaction
623
- **Responsive design**: Components adapt to different screen sizes
624
625
### Accessibility
626
627
- **Screen reader support**: Full ARIA label support
628
- **Keyboard navigation**: Complete keyboard accessibility
629
- **Color contrast**: Meets WCAG guidelines
630
- **Focus management**: Proper focus indication and management