起動条件
Compose UIの構築(Jetpack ComposeまたはCompose Multiplatform)
affaan-m/ECC
Use it for engineering and design tasks; the detail page covers purpose, installation, and practical steps.
npx skills add https://github.com/affaan-m/ECC --skill "docs/ja-JP/skills/compose-multiplatform-patterns"Source checked Jul 28, 2026·Refresh due Oct 26, 2026
Reorganized from the pinned upstream SKILL.md
Compose MultiplatformとJetpack Composeを使用して、Android、iOS、デスクトップ、Web間で共有UIを構築するためのパターン。状態管理、ナビゲーション、テーマ設定、パフォーマンスをカバーします。
npx skills add https://github.com/affaan-m/ECC --skill "docs/ja-JP/skills/compose-multiplatform-patterns"The pinned source contains enough sections and task detail for a source-grounded deep guide; automated content is still not an independent test.
505 source words · 22 usable sections
Documentation workflow
Sections are extracted automatically from the pinned SKILL.md and link back to the source.
Compose UIの構築(Jetpack ComposeまたはCompose Multiplatform)
画面状態には単一のデータクラスを使用します。StateFlowとして公開し、Composeで収集します:
画面状態には単一のデータクラスを使用します。StateFlowとして公開し、Composeで収集します:
Review the “Composeでの状態収集” section in the pinned source before continuing.
複雑な画面では、複数のコールバックラムダの代わりにイベント用のシールドインターフェースを使用します:
SkillSignal prompt templates
These prompts were written by SkillSignal from the source structure; they are not upstream text.
Source-grounded prompt
Use for a documentation task while explicitly checking the source sections.
Use compose-multiplatform-patterns for this documentation task: [task]. Inputs and constraints: [details]. Work through these pinned SKILL.md sections: “起動条件”, “状態管理”, “ViewModel + 単一状態オブジェクト”, “Composeでの状態収集”, “イベントシンクパターン”. Cite the concrete requirements that shape each step, do not invent capabilities absent from the source, and verify the result against: [acceptance criteria].
Documentation checklist
The source section “起動条件” has been checked.
The source section “状態管理” has been checked.
The source section “ViewModel + 単一状態オブジェクト” has been checked.
The source section “Composeでの状態収集” has been checked.
Choose a different workflow
Use it for engineering and design tasks; the detail page covers purpose, installation, and practical steps.
A separate implementation from affaan-m/ECC; compare its source, maintenance signals, and permission requirements.
Open source detailCompose Multiplatform and Jetpack Compose patterns for KMP projects — state management, navigation, theming, performance, and platform-specific UI.
A separate implementation from affaan-m/ECC; compare its source, maintenance signals, and permission requirements.
Open source detailWhen the user wants to plan, design, or implement an A/B test or experiment, or build a growth experimentation program. Also use when the user mentions "A/B test," "split test," "experiment," "test this change," "variant copy," "multivariate test," "hypothesis," "should I test this," "which version is better," "test two versions," "statistical significance," "how long should I run this test," "growth experiments," "experiment velocity," "experiment backlog," "ICE score," "experimentation program
A separate implementation from coreyhaines31/marketingskills; compare its source, maintenance signals, and permission requirements.
Open source detailFAQ
Compose MultiplatformとJetpack Composeを使用して、Android、iOS、デスクトップ、Web間で共有UIを構築するためのパターン。状態管理、ナビゲーション、テーマ設定、パフォーマンスをカバーします。
The source record exposes this install command: npx skills add https://github.com/affaan-m/ECC --skill "docs/ja-JP/skills/compose-multiplatform-patterns". Inspect the command and pinned source before running it.
Quality breakdown
Based on traceable docs and repository signals; stars are not treated as quality.
Compare before choosing
These links are selected from shared tasks, functions, stacks, platforms, and same-name variants. Compare the source owner, documentation, permissions, and maintenance signals.
Use it for engineering and design tasks; the detail page covers purpose, installation, and practical steps.
Compose Multiplatform and Jetpack Compose patterns for KMP projects — state management, navigation, theming, performance, and platform-specific UI.
When the user wants to plan, design, or implement an A/B test or experiment, or build a growth experimentation program. Also use when the user mentions "A/B test," "split test," "experiment," "test this change," "variant copy," "multivariate test," "hypothesis," "should I test this," "which version is better," "test two versions," "statistical significance," "how long should I run this test," "growth experiments," "experiment velocity," "experiment backlog," "ICE score," "experimentation program
Grounded design brief from the adopted corpus — style, WCAG-checked color tokens, typography, layout pattern, anti-patterns. Use on ui-design-brief or any which-style/palette/font/chart decision.
Use BEFORE writing or editing any non-trivial UI — inventories components, design tokens, shadcn primitives, and reusable patterns into state.ui_audit. Hard gate for the ui directive set.
Compose MultiplatformとJetpack Composeを使用して、Android、iOS、デスクトップ、Web間で共有UIを構築するためのパターン。状態管理、ナビゲーション、テーマ設定、パフォーマンスをカバーします。
画面状態には単一のデータクラスを使用します。StateFlowとして公開し、Composeで収集します:
data class ItemListState(
val items: List<Item> = emptyList(),
val isLoading: Boolean = false,
val error: String? = null,
val searchQuery: String = ""
)
class ItemListViewModel(
private val getItems: GetItemsUseCase
) : ViewModel() {
private val _state = MutableStateFlow(ItemListState())
val state: StateFlow<ItemListState> = _state.asStateFlow()
fun onSearch(query: String) {
_state.update { it.copy(searchQuery = query) }
loadItems(query)
}
private fun loadItems(query: String) {
viewModelScope.launch {
_state.update { it.copy(isLoading = true) }
getItems(query).fold(
onSuccess = { items -> _state.update { it.copy(items = items, isLoading = false) } },
onFailure = { e -> _state.update { it.copy(error = e.message, isLoading = false) } }
)
}
}
}
@Composable
fun ItemListScreen(viewModel: ItemListViewModel = koinViewModel()) {
val state by viewModel.state.collectAsStateWithLifecycle()
ItemListContent(
state = state,
onSearch = viewModel::onSearch
)
}
@Composable
private fun ItemListContent(
state: ItemListState,
onSearch: (String) -> Unit
) {
// ステートレスなコンポーザブル — プレビューとテストが容易
}
複雑な画面では、複数のコールバックラムダの代わりにイベント用のシールドインターフェースを使用します:
sealed interface ItemListEvent {
data class Search(val query: String) : ItemListEvent
data class Delete(val itemId: String) : ItemListEvent
data object Refresh : ItemListEvent
}
// ViewModelの中
fun onEvent(event: ItemListEvent) {
when (event) {
is ItemListEvent.Search -> onSearch(event.query)
is ItemListEvent.Delete -> deleteItem(event.itemId)
is ItemListEvent.Refresh -> loadItems(_state.value.searchQuery)
}
}
// コンポーザブルの中 — 多数ではなく単一ラムダ
ItemListContent(
state = state,
onEvent = viewModel::onEvent
)
ルートを@Serializableオブジェクトとして定義します:
@Serializable data object HomeRoute
@Serializable data class DetailRoute(val id: String)
@Serializable data object SettingsRoute
@Composable
fun AppNavHost(navController: NavHostController = rememberNavController()) {
NavHost(navController, startDestination = HomeRoute) {
composable<HomeRoute> {
HomeScreen(onNavigateToDetail = { id -> navController.navigate(DetailRoute(id)) })
}
composable<DetailRoute> { backStackEntry ->
val route = backStackEntry.toRoute<DetailRoute>()
DetailScreen(id = route.id)
}
composable<SettingsRoute> { SettingsScreen() }
}
}
命令型のshow/hideの代わりにdialog()とオーバーレイパターンを使用します:
NavHost(navController, startDestination = HomeRoute) {
composable<HomeRoute> { /* ... */ }
dialog<ConfirmDeleteRoute> { backStackEntry ->
val route = backStackEntry.toRoute<ConfirmDeleteRoute>()
ConfirmDeleteDialog(
itemId = route.itemId,
onConfirm = { navController.popBackStack() },
onDismiss = { navController.popBackStack() }
)
}
}
柔軟性のためにスロットパラメータを持つコンポーザブルを設計します:
@Composable
fun AppCard(
modifier: Modifier = Modifier,
header: @Composable () -> Unit = {},
content: @Composable ColumnScope.() -> Unit,
actions: @Composable RowScope.() -> Unit = {}
) {
Card(modifier = modifier) {
Column {
header()
Column(content = content)
Row(horizontalArrangement = Arrangement.End, content = actions)
}
}
}
Modifierの順序は重要です — 以下の順序で適用します:
Text(
text = "Hello",
modifier = Modifier
.padding(16.dp) // 1. レイアウト(パディング、サイズ)
.clip(RoundedCornerShape(8.dp)) // 2. 形状
.background(Color.White) // 3. 描画(背景、ボーダー)
.clickable { } // 4. インタラクション
)
// commonMain
@Composable
expect fun PlatformStatusBar(darkIcons: Boolean)
// androidMain
@Composable
actual fun PlatformStatusBar(darkIcons: Boolean) {
val systemUiController = rememberSystemUiController()
SideEffect { systemUiController.setStatusBarColor(Color.Transparent, darkIcons) }
}
// iosMain
@Composable
actual fun PlatformStatusBar(darkIcons: Boolean) {
// iOSはUIKitインターロップまたはInfo.plistで処理
}
すべてのプロパティが安定している場合、クラスを@Stableまたは@Immutableでマークします:
@Immutable
data class ItemUiModel(
val id: String,
val title: String,
val description: String,
val progress: Float
)
key()と遅延リストの正しい使用LazyColumn {
items(
items = items,
key = { it.id } // 安定したキーによりアイテムの再利用とアニメーションが可能
) { item ->
ItemRow(item = item)
}
}
derivedStateOfで読み取りを遅延val listState = rememberLazyListState()
val showScrollToTop by remember {
derivedStateOf { listState.firstVisibleItemIndex > 5 }
}
// 悪い例 — リコンポジションのたびに新しいラムダとリストが作られる
items.filter { it.isActive }.forEach { ActiveItem(it, onClick = { handle(it) }) }
// 良い例 — 各アイテムにキーを付けてコールバックが正しい行に紐づくようにする
val activeItems = remember(items) { items.filter { it.isActive } }
activeItems.forEach { item ->
key(item.id) {
ActiveItem(item, onClick = { handle(item) })
}
}
@Composable
fun AppTheme(
darkTheme: Boolean = isSystemInDarkTheme(),
dynamicColor: Boolean = true,
content: @Composable () -> Unit
) {
val colorScheme = when {
dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> {
if (darkTheme) dynamicDarkColorScheme(LocalContext.current)
else dynamicLightColorScheme(LocalContext.current)
}
darkTheme -> darkColorScheme()
else -> lightColorScheme()
}
MaterialTheme(colorScheme = colorScheme, content = content)
}
collectAsStateWithLifecycleを使用したMutableStateFlowがある場合にViewModelでmutableStateOfを使用することNavControllerを渡すこと — 代わりにラムダコールバックを渡す@Composable関数内の重い計算 — ViewModelかremember {}に移動するLaunchedEffect(Unit)を使用することスキル: モジュール構造とレイヤーについてはandroid-clean-architectureを参照。
スキル: コルーチンとFlowパターンについてはkotlin-coroutines-flowsを参照。