
compose-state-generator
by shoheikawano
SKILL.md
name: compose-state-generator description: | Generate ViewModel, UiState, and state management code for Compose applications. Use when: (1) Creating ViewModel with StateFlow, (2) Designing UiState sealed classes, (3) Implementing state hoisting patterns, (4) Adding one-time events/effects, (5) Connecting ViewModel to Compose screens. Triggers: "viewmodel", "uistate", "stateflow", "state management", "mvi", "one-time event", "side effect", "compose state". context: fork agent: general-purpose user-invocable: true allowed-tools:
- Read
- Write
- Edit
- Glob
- Grep
- Bash
Compose State Generator
Generate idiomatic state management code for Compose following UDF (Unidirectional Data Flow).
Coding Standards
MANDATORY: This skill follows kotlin-compose-standards. All generated code MUST comply with these standards:
- Trailing comma EXCEPT for Modifier arguments
- Parameter order: required → Modifier → optional
- Each Modifier method on its own line
- New line at end of file
Quick Start
// UiState
sealed interface ProfileUiState {
data object Loading : ProfileUiState
data class Success(val user: User) : ProfileUiState
data class Error(val message: String) : ProfileUiState
}
// ViewModel
class ProfileViewModel(
private val userRepository: UserRepository,
) : ViewModel() {
private val _uiState = MutableStateFlow<ProfileUiState>(ProfileUiState.Loading)
val uiState: StateFlow<ProfileUiState> = _uiState.asStateFlow()
}
Decision Tree
What kind of state?
├─ Screen-level state → ViewModel + UiState
├─ Component-level state → State hoisting or remember
└─ Shared across screens → SharedFlow or StateHolder
Is there async loading?
├─ Yes → Sealed interface (Loading/Success/Error)
└─ No → Data class with fields
Need one-time events?
├─ Yes → Channel + Flow for events
└─ No → Just StateFlow for state
References
| File | When to Read |
|---|---|
| viewmodel-patterns.md | ViewModel structure, StateFlow setup |
| uistate-design.md | Sealed vs data class, state modeling |
| multiplatform.md | KMP ViewModel alternatives |
Standard ViewModel Template
class FeatureViewModel(
private val repository: FeatureRepository,
savedStateHandle: SavedStateHandle, // Optional: for args
) : ViewModel() {
private val _uiState = MutableStateFlow(FeatureUiState())
val uiState: StateFlow<FeatureUiState> = _uiState.asStateFlow()
private val _events = Channel<FeatureEvent>(Channel.BUFFERED)
val events = _events.receiveAsFlow()
init {
loadData()
}
fun onAction(action: FeatureAction) {
when (action) {
is FeatureAction.Refresh -> loadData()
is FeatureAction.ItemClick -> handleItemClick(action.id)
}
}
private fun loadData() {
viewModelScope.launch {
_uiState.update { it.copy(isLoading = true) }
repository.getData()
.onSuccess { data ->
_uiState.update { it.copy(isLoading = false, items = data) }
}
.onFailure { error ->
_uiState.update { it.copy(isLoading = false, error = error.message) }
}
}
}
}
Output Location
feature/
├── FeatureScreen.kt # UI
├── FeatureViewModel.kt # ViewModel
├── FeatureUiState.kt # State model (or in ViewModel file if small)
└── FeatureAction.kt # Actions/Events (optional, if complex)
Score
Total Score
Based on repository quality metrics
SKILL.mdファイルが含まれている
ライセンスが設定されている
100文字以上の説明がある
GitHub Stars 100以上
3ヶ月以内に更新がある
10回以上フォークされている
オープンIssueが50未満
プログラミング言語が設定されている
1つ以上のタグが設定されている
Reviews
Reviews coming soon