CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-org-jetbrains-compose-ui--ui-uikitsimarm64

Compose Multiplatform UI library for iOS Simulator ARM64 target providing declarative UI framework based on Jetpack Compose for multiplatform development

Pending
Overview
Eval results
Files

input.mddocs/

Input and Interaction

Multi-platform input handling system supporting touch, mouse, keyboard input, and gesture recognition with comprehensive focus management and accessibility features.

Capabilities

Pointer Input System

Low-level pointer input handling supporting touch, mouse, and stylus input with gesture recognition capabilities.

/**
 * Modifier that provides access to pointer input events.
 */
fun Modifier.pointerInput(
    key1: Any?,
    block: suspend PointerInputScope.() -> Unit
): Modifier

/**
 * Modifier that provides access to pointer input events with multiple keys.
 */
fun Modifier.pointerInput(
    key1: Any?,
    key2: Any?,
    block: suspend PointerInputScope.() -> Unit
): Modifier

/**
 * Modifier that provides access to pointer input events with arbitrary keys.
 */
fun Modifier.pointerInput(
    vararg keys: Any?,
    block: suspend PointerInputScope.() -> Unit
): Modifier

/**
 * Scope for handling pointer input events.
 */
interface PointerInputScope : Density {
    /**
     * The size of the pointer input region.
     */
    val size: IntSize
    
    /**
     * The extended touch slop for gestures.
     */
    val extendedTouchSlop: Float
    
    /**
     * Configuration for pointer input behavior.
     */
    val viewConfiguration: ViewConfiguration
    
    /**
     * Wait for a pointer event to occur.
     */
    suspend fun awaitPointerEventScope(
        pass: PointerEventPass = PointerEventPass.Main,
        block: suspend AwaitPointerEventScope.() -> Unit
    )
}

/**
 * Scope for awaiting and handling pointer events.
 */
interface AwaitPointerEventScope : Density {
    /**
     * The size of the pointer input region.
     */
    val size: IntSize
    
    /**
     * The current pointer event.
     */
    val currentEvent: PointerEvent
    
    /**
     * Extended touch slop configuration.
     */
    val extendedTouchSlop: Float
    
    /**
     * View configuration for pointer input.
     */
    val viewConfiguration: ViewConfiguration
    
    /**
     * Wait for the next pointer event.
     */
    suspend fun awaitPointerEvent(
        pass: PointerEventPass = PointerEventPass.Main
    ): PointerEvent
    
    /**
     * Attempt to drag one pointer.
     */
    suspend fun drag(
        pointerId: PointerId,
        onDrag: (PointerInputChange) -> Unit
    ): Boolean
    
    /**
     * Wait for all pointers to be up.
     */
    suspend fun waitForUpOrCancellation(
        pass: PointerEventPass = PointerEventPass.Main
    ): PointerInputChange?
}

/**
 * Represents a pointer event containing information about pointer changes.
 */
class PointerEvent(
    val changes: List<PointerInputChange>,
    val buttons: PointerButtons = PointerButtons(),
    val keyboardModifiers: PointerKeyboardModifiers = PointerKeyboardModifiers(),
    val type: PointerEventType = PointerEventType.Unknown
) {
    /**
     * The number of pointers in this event.
     */
    val pointerCount: Int
    
    /**
     * Get a pointer change by its ID.
     */
    fun getPointerById(pointerId: PointerId): PointerInputChange?
}

/**
 * Information about a single pointer's state changes.
 */
@Immutable
data class PointerInputChange(
    val id: PointerId,
    val uptimeMillis: Long,
    val position: Offset,
    val pressed: Boolean,
    val pressure: Float = 1.0f,
    val previousUptimeMillis: Long = uptimeMillis,
    val previousPosition: Offset = position,
    val previousPressed: Boolean = pressed,
    val isConsumed: Boolean = false,
    val type: PointerType = PointerType.Unknown,
    val scrollDelta: Offset = Offset.Zero
) {
    /**
     * Whether this pointer change represents a press event.
     */
    val changedToDown: Boolean
    
    /**
     * Whether this pointer change represents a release event.
     */
    val changedToUp: Boolean
    
    /**
     * Whether this pointer change represents movement.
     */
    val changedToDownIgnoreConsumed: Boolean
    
    /**
     * The change in position.
     */
    val positionChange: Offset
    
    /**
     * The change in position, ignoring consumption.
     */
    val positionChangeIgnoreConsumed: Offset
    
    /**
     * Consume this pointer change.
     */
    fun consume()
    
    /**
     * Copy this change with consumption applied.
     */
    fun consumeAllChanges(): PointerInputChange
    
    /**
     * Copy this change with position change consumed.
     */
    fun consumePositionChange(): PointerInputChange
}

/**
 * Unique identifier for a pointer.
 */
@JvmInline
value class PointerId(val value: Long)

/**
 * Types of pointer events.
 */
enum class PointerEventType {
    Unknown, Press, Release, Move, Enter, Exit, Scroll
}

/**
 * Types of pointers.
 */
enum class PointerType {
    Unknown, Touch, Mouse, Stylus, Eraser
}

/**
 * Pointer event pass for event handling phases.
 */
enum class PointerEventPass {
    Initial, Main, Final
}

Usage Examples:

// Basic pointer input handling
@Composable
fun PointerInputExample() {
    var position by remember { mutableStateOf(Offset.Zero) }
    var isPressed by remember { mutableStateOf(false) }
    
    Box(
        modifier = Modifier
            .size(200.dp)
            .background(if (isPressed) Color.Red else Color.Blue)
            .pointerInput(Unit) {
                awaitPointerEventScope {
                    while (true) {
                        val event = awaitPointerEvent()
                        val change = event.changes.first()
                        
                        position = change.position
                        isPressed = change.pressed
                        
                        if (change.changedToDown || change.changedToUp) {
                            change.consume()
                        }
                    }
                }
            }
    ) {
        Text(
            text = "Position: (${position.x.toInt()}, ${position.y.toInt()})\nPressed: $isPressed",
            color = Color.White,
            modifier = Modifier.align(Alignment.Center)
        )
    }
}

// Multi-touch handling
@Composable
fun MultiTouchExample() {
    var pointers by remember { mutableStateOf(mapOf<PointerId, Offset>()) }
    
    Box(
        modifier = Modifier
            .fillMaxSize()
            .pointerInput(Unit) {
                awaitPointerEventScope {
                    while (true) {
                        val event = awaitPointerEvent()
                        
                        pointers = event.changes.associate { change ->
                            if (change.pressed) {
                                change.id to change.position
                            } else {
                                change.id to Offset.Unspecified
                            }
                        }.filterValues { it != Offset.Unspecified }
                        
                        event.changes.forEach { it.consume() }
                    }
                }
            }
    ) {
        pointers.forEach { (id, position) ->
            Box(
                modifier = Modifier
                    .offset(position.x.dp - 25.dp, position.y.dp - 25.dp)
                    .size(50.dp)
                    .background(Color.Red, CircleShape)
            )
        }
    }
}

High-Level Gesture Detection

Pre-built gesture detectors for common interaction patterns like taps, drags, and swipes.

/**
 * Detects tap gestures.
 */
suspend fun PointerInputScope.detectTapGestures(
    onDoubleTap: ((Offset) -> Unit)? = null,
    onLongPress: ((Offset) -> Unit)? = null,
    onPress: (suspend PressGestureScope.(Offset) -> Unit)? = null,
    onTap: ((Offset) -> Unit)? = null
)

/**
 * Detects drag gestures.
 */
suspend fun PointerInputScope.detectDragGestures(
    onDragStart: (Offset) -> Unit = { },
    onDragEnd: () -> Unit = { },
    onDrag: (change: PointerInputChange, dragAmount: Offset) -> Unit
)

/**
 * Detects drag gestures after a long press.
 */
suspend fun PointerInputScope.detectDragGesturesAfterLongPress(
    onDragStart: (Offset) -> Unit = { },
    onDragEnd: () -> Unit = { },
    onDrag: (change: PointerInputChange, dragAmount: Offset) -> Unit
)

/**
 * Detects horizontal drag gestures.
 */
suspend fun PointerInputScope.detectHorizontalDragGestures(
    onDragStart: (Offset) -> Unit = { },
    onDragEnd: () -> Unit = { },
    onHorizontalDrag: (change: PointerInputChange, dragAmount: Float) -> Unit
)

/**
 * Detects vertical drag gestures.
 */
suspend fun PointerInputScope.detectVerticalDragGestures(
    onDragStart: (Offset) -> Unit = { },
    onDragEnd: () -> Unit = { },
    onVerticalDrag: (change: PointerInputChange, dragAmount: Float) -> Unit
)

/**
 * Detects rotation and zoom gestures.
 */
suspend fun PointerInputScope.detectTransformGestures(
    panZoomLock: Boolean = false,
    onGesture: (centroid: Offset, pan: Offset, zoom: Float, rotation: Float) -> Unit
)

/**
 * Scope for press gestures.
 */
interface PressGestureScope : Density {
    /**
     * Try to await release of the press.
     */
    suspend fun tryAwaitRelease(): Boolean
    
    /**
     * Await release of the press.
     */
    suspend fun awaitRelease()
}

/**
 * Configuration for drag gestures.
 */
data class DragGestureDetectorConfig(
    val canDrag: (PointerInputChange) -> Boolean = { true }
)

Usage Examples:

// Tap gesture detection
@Composable
fun TapGestureExample() {
    var tapCount by remember { mutableStateOf(0) }
    var lastTapPosition by remember { mutableStateOf(Offset.Zero) }
    
    Box(
        modifier = Modifier
            .size(200.dp)
            .background(Color.Green)
            .pointerInput(Unit) {
                detectTapGestures(
                    onTap = { offset ->
                        tapCount++
                        lastTapPosition = offset
                    },
                    onDoubleTap = { offset ->
                        tapCount += 2
                        lastTapPosition = offset
                    },
                    onLongPress = { offset ->
                        tapCount = 0
                        lastTapPosition = offset
                    }
                )
            }
    ) {
        Text(
            text = "Taps: $tapCount\nLast: (${lastTapPosition.x.toInt()}, ${lastTapPosition.y.toInt()})",
            color = Color.White,
            modifier = Modifier.align(Alignment.Center)
        )
    }
}

// Drag gesture detection
@Composable
fun DragGestureExample() {
    var offset by remember { mutableStateOf(Offset.Zero) }
    var isDragging by remember { mutableStateOf(false) }
    
    Box(
        modifier = Modifier.fillMaxSize()
    ) {
        Box(
            modifier = Modifier
                .offset(offset.x.dp, offset.y.dp)
                .size(100.dp)
                .background(if (isDragging) Color.Red else Color.Blue)
                .pointerInput(Unit) {
                    detectDragGestures(
                        onDragStart = { 
                            isDragging = true 
                        },
                        onDragEnd = { 
                            isDragging = false 
                        },
                        onDrag = { change, dragAmount ->
                            offset += dragAmount
                        }
                    )
                }
        )
    }
}

// Transform gestures (zoom, rotate, pan)
@Composable
fun TransformGestureExample() {
    var scale by remember { mutableStateOf(1f) }
    var rotation by remember { mutableStateOf(0f) }
    var offset by remember { mutableStateOf(Offset.Zero) }
    
    Box(
        modifier = Modifier
            .fillMaxSize()
            .pointerInput(Unit) {
                detectTransformGestures { centroid, pan, zoom, rotationChange ->
                    scale *= zoom
                    rotation += rotationChange
                    offset += pan
                }
            }
    ) {
        Box(
            modifier = Modifier
                .size(200.dp)
                .offset(offset.x.dp, offset.y.dp)
                .scale(scale)
                .rotate(rotation)
                .background(Color.Yellow)
                .align(Alignment.Center)
        ) {
            Text(
                text = "Transform me!",
                modifier = Modifier.align(Alignment.Center)
            )
        }
    }
}

Clickable and Interactive Modifiers

High-level modifiers for common interactive behaviors like clicks, selections, and toggles.

/**
 * Modifier that makes a component clickable.
 */
fun Modifier.clickable(
    enabled: Boolean = true,
    onClickLabel: String? = null,
    role: Role? = null,
    onClick: () -> Unit
): Modifier

/**
 * Modifier that makes a component clickable with custom indication.
 */
fun Modifier.clickable(
    interactionSource: MutableInteractionSource,
    indication: Indication?,
    enabled: Boolean = true,
    onClickLabel: String? = null,
    role: Role? = null,
    onClick: () -> Unit
): Modifier

/**
 * Modifier that makes a component selectable.
 */
fun Modifier.selectable(
    selected: Boolean,
    enabled: Boolean = true,
    role: Role? = null,
    onValueChange: (Boolean) -> Unit
): Modifier

/**
 * Modifier that makes a component toggleable.
 */
fun Modifier.toggleable(
    value: Boolean,
    enabled: Boolean = true,
    role: Role? = null,
    onValueChange: (Boolean) -> Unit
): Modifier

/**
 * Modifier that makes a component tristate toggleable.
 */
fun Modifier.triStateToggleable(
    state: ToggleableState,
    enabled: Boolean = true,
    role: Role? = null,
    onClick: () -> Unit
): Modifier

/**
 * Represents the state of a toggleable component.
 */
enum class ToggleableState {
    On, Off, Indeterminate
}

/**
 * Semantic roles for accessibility.
 */
enum class Role {
    Button, Checkbox, Switch, RadioButton, Tab, Image, DropdownList
}

Usage Examples:

// Basic clickable component
@Composable
fun ClickableExample() {
    var clickCount by remember { mutableStateOf(0) }
    
    Box(
        modifier = Modifier
            .size(150.dp)
            .background(Color.Blue)
            .clickable {
                clickCount++
            }
    ) {
        Text(
            text = "Clicked: $clickCount",
            color = Color.White,
            modifier = Modifier.align(Alignment.Center)
        )
    }
}

// Selectable component
@Composable
fun SelectableExample() {
    var selected by remember { mutableStateOf(false) }
    
    Row(
        modifier = Modifier
            .fillMaxWidth()
            .selectable(
                selected = selected,
                onClick = { selected = !selected },
                role = Role.Checkbox
            )
            .padding(16.dp)
    ) {
        Box(
            modifier = Modifier
                .size(24.dp)
                .background(
                    if (selected) Color.Blue else Color.Gray,
                    RoundedCornerShape(4.dp)
                )
        ) {
            if (selected) {
                Text(
                    text = "✓",
                    color = Color.White,
                    modifier = Modifier.align(Alignment.Center)
                )
            }
        }
        
        Spacer(modifier = Modifier.width(16.dp))
        
        Text(text = "Select this option")
    }
}

// Toggleable component
@Composable
fun ToggleableExample() {
    var isOn by remember { mutableStateOf(false) }
    
    Row(
        modifier = Modifier
            .toggleable(
                value = isOn,
                onValueChange = { isOn = it },
                role = Role.Switch
            )
            .padding(16.dp),
        verticalAlignment = Alignment.CenterVertically
    ) {
        Text(text = "Enable feature")
        
        Spacer(modifier = Modifier.width(16.dp))
        
        Box(
            modifier = Modifier
                .size(50.dp, 30.dp)
                .background(
                    if (isOn) Color.Green else Color.Gray,
                    RoundedCornerShape(15.dp)
                )
        ) {
            Box(
                modifier = Modifier
                    .size(26.dp)
                    .background(Color.White, CircleShape)
                    .align(if (isOn) Alignment.CenterEnd else Alignment.CenterStart)
            )
        }
    }
}

// Custom interaction source and indication
@Composable
fun CustomInteractionExample() {
    val interactionSource = remember { MutableInteractionSource() }
    val isPressed by interactionSource.collectIsPressedAsState()
    val isHovered by interactionSource.collectIsHoveredAsState()
    
    Box(
        modifier = Modifier
            .size(150.dp)
            .background(
                when {
                    isPressed -> Color.Red
                    isHovered -> Color.Yellow
                    else -> Color.Blue
                }
            )
            .clickable(
                interactionSource = interactionSource,
                indication = null // Custom indication handling
            ) {
                // Handle click
            }
    ) {
        Text(
            text = when {
                isPressed -> "Pressed"
                isHovered -> "Hovered"
                else -> "Normal"
            },
            color = Color.White,
            modifier = Modifier.align(Alignment.Center)
        )
    }
}

Focus Management

Comprehensive focus handling system for keyboard navigation and accessibility.

/**
 * Modifier that makes a component focusable.
 */
fun Modifier.focusable(
    enabled: Boolean = true,
    interactionSource: MutableInteractionSource? = null
): Modifier

/**
 * Modifier that specifies focus behavior.
 */
fun Modifier.focusTarget(): Modifier

/**
 * Modifier that specifies focus properties.
 */
fun Modifier.focusProperties(scope: FocusProperties.() -> Unit): Modifier

/**
 * Modifier for observing focus changes.
 */
fun Modifier.onFocusChanged(onFocusChanged: (FocusState) -> Unit): Modifier

/**
 * Modifier for observing focus events.
 */
fun Modifier.onFocusEvent(onFocusEvent: (FocusState) -> Unit): Modifier

/**
 * Represents the focus state of a component.
 */
interface FocusState {
    /**
     * Whether this component has focus.
     */
    val hasFocus: Boolean
    
    /**
     * Whether this component is focused or contains a focused descendant.
     */
    val isFocused: Boolean
    
    /**
     * Whether focus is captured by this component.
     */
    val isCaptured: Boolean
}

/**
 * Properties for configuring focus behavior.
 */
interface FocusProperties {
    /**
     * Whether this component can be focused.
     */
    var canFocus: Boolean
    
    /**
     * Custom focus enter behavior.
     */
    var enter: (FocusDirection) -> FocusRequester?
    
    /**
     * Custom focus exit behavior.
     */
    var exit: (FocusDirection) -> FocusRequester?
    
    /**
     * Focus order within the parent.
     */
    var next: FocusRequester?
    var previous: FocusRequester?
    var up: FocusRequester?
    var down: FocusRequester?
    var left: FocusRequester?
    var right: FocusRequester?
    var start: FocusRequester?
    var end: FocusRequester?
}

/**
 * Used to request focus programmatically.
 */
class FocusRequester {
    /**
     * Request focus for this component.
     */
    fun requestFocus()
    
    /**
     * Capture focus for this component.
     */
    fun captureFocus(): Boolean
    
    /**
     * Free captured focus.
     */
    fun freeFocus(): Boolean
    
    companion object {
        /**
         * Default focus requester.
         */
        val Default: FocusRequester
        
        /**
         * Focus requester that cancels focus.
         */
        val Cancel: FocusRequester
    }
}

/**
 * Directions for focus movement.
 */
enum class FocusDirection {
    Next, Previous, Up, Down, Left, Right, In, Out, Enter, Exit
}

/**
 * CompositionLocal for accessing the focus manager.
 */
val LocalFocusManager: ProvidableCompositionLocal<FocusManager>

/**
 * Interface for managing focus.
 */
interface FocusManager {
    /**
     * Clear focus from the currently focused component.
     */
    fun clearFocus(force: Boolean = false)
    
    /**
     * Move focus in the specified direction.
     */
    fun moveFocus(focusDirection: FocusDirection): Boolean
}

Usage Examples:

// Basic focus handling
@Composable
fun FocusExample() {
    val focusRequester = remember { FocusRequester() }
    var isFocused by remember { mutableStateOf(false) }
    
    Column {
        Box(
            modifier = Modifier
                .size(100.dp)
                .background(if (isFocused) Color.Blue else Color.Gray)
                .focusRequester(focusRequester)
                .focusable()
                .onFocusChanged { focusState ->
                    isFocused = focusState.isFocused
                }
        ) {
            Text(
                text = if (isFocused) "Focused" else "Not Focused",
                color = Color.White,
                modifier = Modifier.align(Alignment.Center)
            )
        }
        
        Button(
            onClick = { focusRequester.requestFocus() }
        ) {
            Text("Request Focus")
        }
    }
}

// Custom focus navigation
@Composable
fun FocusNavigationExample() {
    val focusRequesters = remember { List(4) { FocusRequester() } }
    val focusManager = LocalFocusManager.current
    
    LazyVerticalGrid(
        columns = GridCells.Fixed(2),
        modifier = Modifier.padding(16.dp)
    ) {
        items(4) { index ->
            var isFocused by remember { mutableStateOf(false) }
            
            Box(
                modifier = Modifier
                    .size(100.dp)
                    .padding(4.dp)
                    .background(
                        if (isFocused) Color.Blue else Color.LightGray,
                        RoundedCornerShape(8.dp)
                    )
                    .focusRequester(focusRequesters[index])
                    .focusProperties {
                        // Custom focus navigation
                        next = if (index < 3) focusRequesters[index + 1] else FocusRequester.Default
                        previous = if (index > 0) focusRequesters[index - 1] else FocusRequester.Default
                        
                        // Grid-like navigation
                        down = if (index < 2) focusRequesters[index + 2] else FocusRequester.Default
                        up = if (index >= 2) focusRequesters[index - 2] else FocusRequester.Default
                    }
                    .focusable()
                    .onFocusChanged { focusState ->
                        isFocused = focusState.isFocused
                    }
                    .clickable {
                        focusRequesters[index].requestFocus()
                    }
            ) {
                Text(
                    text = "Item ${index + 1}",
                    color = if (isFocused) Color.White else Color.Black,
                    modifier = Modifier.align(Alignment.Center)
                )
            }
        }
    }
}

// Focus capture for modal behavior
@Composable
fun FocusCaptureExample() {
    var showModal by remember { mutableStateOf(false) }
    val modalFocusRequester = remember { FocusRequester() }
    
    Box(modifier = Modifier.fillMaxSize()) {
        Column {
            Button(onClick = { showModal = true }) {
                Text("Show Modal")
            }
            
            Text("This content becomes unfocusable when modal is shown")
            
            Button(onClick = { /* Regular button */ }) {
                Text("Regular Button")
            }
        }
        
        if (showModal) {
            Box(
                modifier = Modifier
                    .fillMaxSize()
                    .background(Color.Black.copy(alpha = 0.5f))
                    .clickable { showModal = false }
            ) {
                Box(
                    modifier = Modifier
                        .size(300.dp, 200.dp)
                        .background(Color.White, RoundedCornerShape(8.dp))
                        .align(Alignment.Center)
                        .focusRequester(modalFocusRequester)
                        .focusProperties {
                            // Capture focus to prevent navigation outside modal
                            canFocus = true
                        }
                        .focusable()
                ) {
                    Column(
                        modifier = Modifier
                            .fillMaxSize()
                            .padding(16.dp),
                        verticalArrangement = Arrangement.SpaceAround,
                        horizontalAlignment = Alignment.CenterHorizontally
                    ) {
                        Text("Modal Dialog")
                        Button(onClick = { showModal = false }) {
                            Text("Close")
                        }
                    }
                }
            }
            
            LaunchedEffect(showModal) {
                modalFocusRequester.requestFocus()
            }
        }
    }
}

Keyboard Input

Keyboard event handling for text input, shortcuts, and navigation keys.

/**
 * Modifier for handling key events.
 */
fun Modifier.onKeyEvent(
    onKeyEvent: (KeyEvent) -> Boolean
): Modifier

/**
 * Modifier for handling pre-view key events.
 */
fun Modifier.onPreviewKeyEvent(
    onPreviewKeyEvent: (KeyEvent) -> Boolean
): Modifier

/**
 * Represents a keyboard event.
 */
expect class KeyEvent {
    /**
     * The key that was pressed or released.
     */
    val key: Key
    
    /**
     * The type of key event.
     */
    val type: KeyEventType
    
    /**
     * Whether the Alt key is pressed.
     */
    val isAltPressed: Boolean
    
    /**
     * Whether the Ctrl key is pressed.
     */
    val isCtrlPressed: Boolean
    
    /**
     * Whether the Meta key is pressed.
     */
    val isMetaPressed: Boolean
    
    /**
     * Whether the Shift key is pressed.
     */
    val isShiftPressed: Boolean
}

/**
 * Types of key events.
 */
enum class KeyEventType {
    KeyDown, KeyUp, Unknown
}

/**
 * Represents keyboard keys.
 */
expect class Key {
    companion object {
        val A: Key
        val B: Key
        // ... other alphabet keys
        val Zero: Key
        val One: Key
        // ... other number keys
        val Enter: Key
        val Escape: Key
        val Backspace: Key
        val Delete: Key
        val Tab: Key
        val Spacebar: Key
        val DirectionUp: Key
        val DirectionDown: Key
        val DirectionLeft: Key
        val DirectionRight: Key
        val PageUp: Key
        val PageDown: Key
        val Home: Key
        val MoveEnd: Key
        val F1: Key
        val F2: Key
        // ... other function keys
    }
}

Usage Examples:

// Keyboard event handling
@Composable
fun KeyboardHandlingExample() {
    var lastKey by remember { mutableStateOf("None") }
    var keyCount by remember { mutableStateOf(0) }
    
    Box(
        modifier = Modifier
            .size(300.dp, 200.dp)
            .background(Color.LightGray, RoundedCornerShape(8.dp))
            .focusable()
            .onKeyEvent { keyEvent ->
                if (keyEvent.type == KeyEventType.KeyDown) {
                    lastKey = keyEvent.key.toString()
                    keyCount++
                    
                    // Handle specific keys
                    when (keyEvent.key) {
                        Key.Escape -> {
                            lastKey = "Escape pressed"
                            true // Consume event
                        }
                        Key.Enter -> {
                            lastKey = "Enter pressed"
                            true
                        }
                        else -> false // Don't consume
                    }
                } else {
                    false
                }
            }
    ) {
        Column(
            modifier = Modifier.align(Alignment.Center),
            horizontalAlignment = Alignment.CenterHorizontally
        ) {
            Text("Focus this box and press keys")
            Text("Last key: $lastKey")
            Text("Key count: $keyCount")
        }
    }
}

// Keyboard shortcuts
@Composable
fun KeyboardShortcutsExample() {
    var content by remember { mutableStateOf("Type here...") }
    var saved by remember { mutableStateOf(false) }
    
    Column(
        modifier = Modifier
            .fillMaxSize()
            .padding(16.dp)
            .onPreviewKeyEvent { keyEvent ->
                if (keyEvent.type == KeyEventType.KeyDown && keyEvent.isCtrlPressed) {
                    when (keyEvent.key) {
                        Key.S -> {
                            // Ctrl+S to save
                            saved = true
                            true
                        }
                        Key.N -> {
                            // Ctrl+N for new
                            content = ""
                            saved = false
                            true
                        }
                        else -> false
                    }
                } else {
                    false
                }
            }
    ) {
        if (saved) {
            Text(
                text = "Saved!",
                color = Color.Green,
                fontWeight = FontWeight.Bold
            )
        } else {
            Text(
                text = "Unsaved changes",
                color = Color.Orange
            )
        }
        
        Spacer(modifier = Modifier.height(16.dp))
        
        TextField(
            value = content,
            onValueChange = { 
                content = it
                saved = false
            },
            label = { Text("Content (Ctrl+S to save, Ctrl+N for new)") },
            modifier = Modifier.fillMaxWidth()
        )
        
        Spacer(modifier = Modifier.height(16.dp))
        
        Text("Keyboard shortcuts:")
        Text("• Ctrl+S: Save")
        Text("• Ctrl+N: New document")
    }
}

Install with Tessl CLI

npx tessl i tessl/maven-org-jetbrains-compose-ui--ui-uikitsimarm64

docs

composables.md

core-ui.md

graphics.md

index.md

input.md

ios-integration.md

layout.md

material-design.md

resources.md

state.md

text.md

window.md

tile.json