Refactor map screen panel state to nullable contracts.
This replaces visibility booleans and error state fields with nullable `searchPanelState`/`devicePanelState` and action-based error toasts for one-shot UI effects. Made-with: Cursor
This commit is contained in:
41
.cursor/rules/screen-ui-contract.mdc
Normal file
41
.cursor/rules/screen-ui-contract.mdc
Normal file
@@ -0,0 +1,41 @@
|
||||
---
|
||||
description: Screen UI contract structure for State, Action, and Event
|
||||
alwaysApply: false
|
||||
---
|
||||
# Screen UI Contract Rule
|
||||
|
||||
Every screen must define its contract in a `*ScreenContract.kt` file using `State`, `Action`, and `Event`.
|
||||
|
||||
## Required structure
|
||||
|
||||
1. Define `State` with all static UI data required to render the screen.
|
||||
2. Define `Action` (enum or sealed interface) for what the ViewModel does.
|
||||
3. Define `Event` (enum or sealed interface) for user interactions.
|
||||
|
||||
## State guidelines
|
||||
|
||||
- `State` must include stable screen data (for example `deviceName`, `deviceId`, `isSharingEnabled`).
|
||||
- Do not put user interaction triggers in `State`; those belong to `Event`.
|
||||
|
||||
## Action guidelines
|
||||
|
||||
- Use `Action` for ViewModel-driven outcomes such as navigation or side effects.
|
||||
- Example: `Action.NavigateTo*Screen`, `Action.Show*Toast`
|
||||
|
||||
## Event guidelines
|
||||
|
||||
- Use `Event` for user-originated input.
|
||||
- Examples: `Event.*ButtonClicked`, `Event.*InputChanged(value)`.
|
||||
|
||||
## Example
|
||||
|
||||
```kotlin
|
||||
data class State(val deviceName: String, val deviceId: String, val isSharingEnabled: Boolean)
|
||||
|
||||
sealed interface Action { data object NavigateToScreenX : Action }
|
||||
|
||||
sealed interface Event {
|
||||
data object XButtonClicked : Event
|
||||
data class InputChanged(val value: String) : Event
|
||||
}
|
||||
```
|
||||
Reference in New Issue
Block a user