CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-org-jetbrains-compose-ui--ui-wasm-js

Compose Multiplatform UI library for WebAssembly/JS target - declarative framework for sharing UIs across multiple platforms with Kotlin.

Pending
Overview
Eval results
Files

material-design.mddocs/

Material Design System

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.

Core Theming

MaterialTheme

The foundation of Material Design theming.

@Composable
fun MaterialTheme(
    colors: Colors = MaterialTheme.colors,
    typography: Typography = MaterialTheme.typography,
    shapes: Shapes = MaterialTheme.shapes,
    content: @Composable () -> Unit
)

Basic Setup:

@Composable
fun App() {
    MaterialTheme {
        Surface {
            // Your app content
            MainContent()
        }
    }
}

Custom Theme:

@Composable
fun CustomTheme(content: @Composable () -> Unit) {
    MaterialTheme(
        colors = lightColors(
            primary = Color(0xFF6200EE),
            primaryVariant = Color(0xFF3700B3),
            secondary = Color(0xFF03DAC6),
            surface = Color.White,
            background = Color(0xFFF5F5F5)
        ),
        typography = Typography(
            h1 = TextStyle(fontSize = 32.sp, fontWeight = FontWeight.Bold),
            body1 = TextStyle(fontSize = 16.sp, lineHeight = 24.sp)
        ),
        shapes = Shapes(
            small = RoundedCornerShape(4.dp),
            medium = RoundedCornerShape(8.dp),
            large = RoundedCornerShape(16.dp)
        ),
        content = content
    )
}

Colors

Material Design color system with light and dark theme support.

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
): Colors

Dark Theme:

fun darkColors(
    primary: Color = Color(0xFFBB86FC),
    primaryVariant: Color = Color(0xFF3700B3),
    secondary: Color = Color(0xFF03DAC6),
    secondaryVariant: Color = Color(0xFF03DAC6),
    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
): Colors

Dynamic Theme Selection:

@Composable
fun AdaptiveTheme(content: @Composable () -> Unit) {
    val isDarkMode = isSystemInDarkTheme()
    
    MaterialTheme(
        colors = if (isDarkMode) darkColors() else lightColors(),
        content = content
    )
}

Typography

Material Design typography scale.

data class Typography(
    val h1: TextStyle = TextStyle(/* defaults */),
    val h2: TextStyle = TextStyle(/* defaults */),
    val h3: TextStyle = TextStyle(/* defaults */),
    val h4: TextStyle = TextStyle(/* defaults */),
    val h5: TextStyle = TextStyle(/* defaults */),
    val h6: TextStyle = TextStyle(/* defaults */),
    val subtitle1: TextStyle = TextStyle(/* defaults */),
    val subtitle2: TextStyle = TextStyle(/* defaults */),
    val body1: TextStyle = TextStyle(/* defaults */),
    val body2: TextStyle = TextStyle(/* defaults */),
    val button: TextStyle = TextStyle(/* defaults */),
    val caption: TextStyle = TextStyle(/* defaults */),
    val overline: TextStyle = TextStyle(/* defaults */)
)

Usage:

@Composable
fun TypographyExample() {
    Column {
        Text("Headline 1", style = MaterialTheme.typography.h1)
        Text("Headline 6", style = MaterialTheme.typography.h6)
        Text("Body text", style = MaterialTheme.typography.body1)
        Text("Caption text", style = MaterialTheme.typography.caption)
    }
}

Layout Components

Scaffold

Main layout structure for Material Design apps.

@Composable
fun Scaffold(
    modifier: Modifier = Modifier,
    scaffoldState: ScaffoldState = rememberScaffoldState(),
    topBar: @Composable () -> Unit = {},
    bottomBar: @Composable () -> Unit = {},
    snackbarHost: @Composable (SnackbarHostState) -> Unit = { SnackbarHost(it) },
    floatingActionButton: @Composable () -> Unit = {},
    floatingActionButtonPosition: FabPosition = FabPosition.End,
    isFloatingActionButtonDocked: Boolean = false,
    drawerContent: @Composable (ColumnScope.() -> Unit)? = null,
    drawerGesturesEnabled: Boolean = true,
    drawerShape: Shape = MaterialTheme.shapes.large,
    drawerElevation: Dp = DrawerDefaults.Elevation,
    drawerBackgroundColor: Color = MaterialTheme.colors.surface,
    drawerContentColor: Color = contentColorFor(drawerBackgroundColor),
    drawerScrimColor: Color = DrawerDefaults.scrimColor,
    backgroundColor: Color = MaterialTheme.colors.background,
    contentColor: Color = contentColorFor(backgroundColor),
    content: @Composable (PaddingValues) -> Unit
)

Basic Scaffold:

@Composable
fun MainScreen() {
    Scaffold(
        topBar = {
            TopAppBar(title = { Text("My App") })
        },
        floatingActionButton = {
            FloatingActionButton(onClick = { /* action */ }) {
                Icon(Icons.Default.Add, contentDescription = "Add")
            }
        }
    ) { paddingValues ->
        LazyColumn(
            modifier = Modifier.padding(paddingValues)
        ) {
            // Content
        }
    }
}

TopAppBar

Application top bar with title and actions.

@Composable
fun TopAppBar(
    title: @Composable () -> Unit,
    modifier: Modifier = Modifier,
    navigationIcon: @Composable (() -> Unit)? = null,
    actions: @Composable RowScope.() -> Unit = {},
    backgroundColor: Color = MaterialTheme.colors.primarySurface,
    contentColor: Color = contentColorFor(backgroundColor),
    elevation: Dp = AppBarDefaults.TopAppBarElevation
)

Usage:

TopAppBar(
    title = { Text("Screen Title") },
    navigationIcon = {
        IconButton(onClick = { /* navigate back */ }) {
            Icon(Icons.Default.ArrowBack, contentDescription = "Back")
        }
    },
    actions = {
        IconButton(onClick = { /* search */ }) {
            Icon(Icons.Default.Search, contentDescription = "Search")
        }
        IconButton(onClick = { /* more options */ }) {
            Icon(Icons.Default.MoreVert, contentDescription = "More")
        }
    }
)

Surface

Foundation component for elevation and clipping.

@Composable
fun Surface(
    modifier: Modifier = Modifier,
    shape: Shape = RectangleShape,
    color: Color = MaterialTheme.colors.surface,
    contentColor: Color = contentColorFor(color),
    border: BorderStroke? = null,
    elevation: Dp = 0.dp,
    content: @Composable () -> Unit
)

Usage:

Surface(
    modifier = Modifier.padding(16.dp),
    shape = RoundedCornerShape(8.dp),
    elevation = 4.dp
) {
    Text(
        text = "Elevated content",
        modifier = Modifier.padding(16.dp)
    )
}

Navigation Components

BottomNavigation

Bottom navigation bar for primary destinations.

@Composable
fun BottomNavigation(
    modifier: Modifier = Modifier,
    backgroundColor: Color = MaterialTheme.colors.primarySurface,
    contentColor: Color = contentColorFor(backgroundColor),
    elevation: Dp = BottomNavigationDefaults.Elevation,
    content: @Composable RowScope.() -> Unit
)

Usage:

var selectedItem by remember { mutableStateOf(0) }
val items = listOf("Home", "Search", "Profile")

BottomNavigation {
    items.forEachIndexed { index, item ->
        BottomNavigationItem(
            icon = { Icon(getIcon(index), contentDescription = item) },
            label = { Text(item) },
            selected = selectedItem == index,
            onClick = { selectedItem = index }
        )
    }
}

NavigationRail

Side navigation for larger screens.

@Composable
fun NavigationRail(
    modifier: Modifier = Modifier,
    backgroundColor: Color = MaterialTheme.colors.surface,
    contentColor: Color = contentColorFor(backgroundColor),
    elevation: Dp = NavigationRailDefaults.Elevation,
    header: @Composable (ColumnScope.() -> Unit)? = null,
    content: @Composable ColumnScope.() -> Unit
)

Input Components

OutlinedTextField

Outlined text input field.

@Composable
fun OutlinedTextField(
    value: String,
    onValueChange: (String) -> Unit,
    modifier: Modifier = Modifier,
    enabled: Boolean = true,
    readOnly: Boolean = false,
    textStyle: TextStyle = LocalTextStyle.current,
    label: @Composable (() -> Unit)? = null,
    placeholder: @Composable (() -> Unit)? = null,
    leadingIcon: @Composable (() -> Unit)? = null,
    trailingIcon: @Composable (() -> Unit)? = null,
    isError: Boolean = false,
    visualTransformation: VisualTransformation = VisualTransformation.None,
    keyboardOptions: KeyboardOptions = KeyboardOptions.Default,
    keyboardActions: KeyboardActions = KeyboardActions(),
    singleLine: Boolean = false,
    maxLines: Int = Int.MAX_VALUE,
    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
    shape: Shape = MaterialTheme.shapes.small,
    colors: TextFieldColors = TextFieldDefaults.outlinedTextFieldColors()
)

Usage:

var email by remember { mutableStateOf("") }
var isError by remember { mutableStateOf(false) }

OutlinedTextField(
    value = email,
    onValueChange = { 
        email = it
        isError = !android.util.Patterns.EMAIL_ADDRESS.matcher(it).matches()
    },
    label = { Text("Email") },
    placeholder = { Text("Enter your email") },
    leadingIcon = {
        Icon(Icons.Default.Email, contentDescription = "Email")
    },
    isError = isError,
    keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Email)
)

Checkbox

Selection control for binary choices.

@Composable
fun Checkbox(
    checked: Boolean,
    onCheckedChange: ((Boolean) -> Unit)?,
    modifier: Modifier = Modifier,
    enabled: Boolean = true,
    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
    colors: CheckboxColors = CheckboxDefaults.colors()
)

Usage:

var isChecked by remember { mutableStateOf(false) }

Row(
    verticalAlignment = Alignment.CenterVertically
) {
    Checkbox(
        checked = isChecked,
        onCheckedChange = { isChecked = it }
    )
    Text("Accept terms and conditions")
}

Switch

Toggle control for binary choices.

@Composable
fun Switch(
    checked: Boolean,
    onCheckedChange: ((Boolean) -> Unit)?,
    modifier: Modifier = Modifier,
    enabled: Boolean = true,
    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
    colors: SwitchColors = SwitchDefaults.colors()
)

Usage:

var isEnabled by remember { mutableStateOf(true) }

Row(
    modifier = Modifier.fillMaxWidth(),
    horizontalArrangement = Arrangement.SpaceBetween,
    verticalAlignment = Alignment.CenterVertically
) {
    Text("Notifications")
    Switch(
        checked = isEnabled,
        onCheckedChange = { isEnabled = it }
    )
}

Feedback Components

Snackbar

Brief messages about app processes.

@Composable
fun Snackbar(
    modifier: Modifier = Modifier,
    action: @Composable (() -> Unit)? = null,
    actionOnNewLine: Boolean = false,
    shape: Shape = MaterialTheme.shapes.small,
    backgroundColor: Color = SnackbarDefaults.backgroundColor,
    contentColor: Color = MaterialTheme.colors.surface,
    elevation: Dp = 6.dp,
    content: @Composable () -> Unit
)

Usage:

val snackbarHostState = remember { SnackbarHostState() }

LaunchedEffect(key1 = someEvent) {
    snackbarHostState.showSnackbar(
        message = "Item deleted",
        actionLabel = "Undo",
        duration = SnackbarDuration.Short
    )
}

SnackbarHost(
    hostState = snackbarHostState,
    snackbar = { data ->
        Snackbar(
            action = {
                data.actionLabel?.let { actionLabel ->
                    TextButton(onClick = { data.performAction() }) {
                        Text(actionLabel)
                    }
                }
            }
        ) {
            Text(data.message)
        }
    }
)

CircularProgressIndicator

Loading indicator for indeterminate progress.

@Composable
fun CircularProgressIndicator(
    modifier: Modifier = Modifier,
    color: Color = MaterialTheme.colors.primary,
    strokeWidth: Dp = ProgressIndicatorDefaults.StrokeWidth
)

Determinate Progress:

@Composable
fun CircularProgressIndicator(
    progress: Float,
    modifier: Modifier = Modifier,
    color: Color = MaterialTheme.colors.primary,
    strokeWidth: Dp = ProgressIndicatorDefaults.StrokeWidth
)

Usage:

// Indeterminate
CircularProgressIndicator()

// Determinate
var progress by remember { mutableStateOf(0.0f) }
CircularProgressIndicator(progress = progress)

Card Components

Card

Material Design card container.

@Composable
fun Card(
    modifier: Modifier = Modifier,
    shape: Shape = MaterialTheme.shapes.medium,
    backgroundColor: Color = MaterialTheme.colors.surface,
    contentColor: Color = contentColorFor(backgroundColor),
    border: BorderStroke? = null,
    elevation: Dp = 1.dp,
    content: @Composable () -> Unit
)

Usage:

Card(
    modifier = Modifier
        .fillMaxWidth()
        .padding(16.dp)
        .clickable { /* card clicked */ },
    elevation = 4.dp
) {
    Column(
        modifier = Modifier.padding(16.dp)
    ) {
        Text(
            text = "Card Title",
            style = MaterialTheme.typography.h6
        )
        Spacer(Modifier.height(8.dp))
        Text(
            text = "Card content goes here with additional information.",
            style = MaterialTheme.typography.body2
        )
    }
}

Dialog Components

AlertDialog

Modal dialog for important decisions.

@Composable
fun AlertDialog(
    onDismissRequest: () -> Unit,
    buttons: @Composable () -> Unit,
    modifier: Modifier = Modifier,
    title: (@Composable () -> Unit)? = null,
    text: (@Composable () -> Unit)? = null,
    shape: Shape = MaterialTheme.shapes.medium,
    backgroundColor: Color = MaterialTheme.colors.surface,
    contentColor: Color = contentColorFor(backgroundColor)
)

Usage:

var showDialog by remember { mutableStateOf(false) }

if (showDialog) {
    AlertDialog(
        onDismissRequest = { showDialog = false },
        title = { Text("Confirm Action") },
        text = { Text("Are you sure you want to delete this item?") },
        buttons = {
            Row(
                modifier = Modifier.fillMaxWidth(),
                horizontalArrangement = Arrangement.End
            ) {
                TextButton(onClick = { showDialog = false }) {
                    Text("Cancel")
                }
                TextButton(onClick = { 
                    // Perform action
                    showDialog = false 
                }) {
                    Text("Delete")
                }
            }
        }
    )
}

WASM-Specific Optimizations

Performance Considerations

  • Theme switching: Efficient dark/light mode transitions
  • Color animations: Smooth color transitions between themes
  • Typography rendering: Optimized text rendering for web

Browser Integration

  • System theme detection: Automatic dark mode detection
  • High contrast support: Respects browser accessibility settings
  • Touch optimization: Material components optimized for touch interaction
  • Responsive design: Components adapt to different screen sizes

Accessibility

  • Screen reader support: Full ARIA label support
  • Keyboard navigation: Complete keyboard accessibility
  • Color contrast: Meets WCAG guidelines
  • Focus management: Proper focus indication and management

Install with Tessl CLI

npx tessl i tessl/maven-org-jetbrains-compose-ui--ui-wasm-js

docs

browser-integration.md

index.md

material-design.md

resource-management.md

state-management.md

ui-components.md

window-management.md

tile.json