スタイルに関する推奨事項と禁止事項

このページでは、コードベース全体で一貫性を実現するスタイルを扱うためのベスト プラクティスと、API の設計時に従った原則について説明します。

推奨事項

次のベスト プラクティスに従ってください。

推奨: スタイルをビジュアルに、修飾子を動作に使用する

Styles API を使用して、背景、パディング、境界線などの視覚的な構成を行い、クリック ロジック、ジェスチャー検出、ユーザー補助などの動作には修飾子を予約します。

推奨: デザイン システムでスタイル パラメータを公開する

独自のカスタム デザイン システム コンポーネントの場合は、修飾子パラメータの後に Style オブジェクトを公開する必要があります。

@Composable
fun GradientButton(
    modifier: Modifier = Modifier,
    // ✅ DO: for design system components, expose a style modifier to consumers to be able to customize the components
    style: Style = Style
) {
    // Consume the style
}

推奨: 視覚ベースのパラメータをスタイルに置き換える

コンポーザブルのパラメータを 1 つの Style パラメータに置き換えることを検討してください。次に例を示します。

// Before
@Composable
fun OldButton(background: Color, fontColor: Color) {
}

// After
// ✅ DO: Replace visual-based parameters with a style that includes same properties
@Composable
fun NewButton(style: Style = Style) {
}

推奨: アニメーションのスタイルを優先する

組み込みの animate ブロックを使用して、状態ベースのスタイル設定とアニメーションを行い、修飾子よりもパフォーマンスを向上させます。

推奨: 「Last-write-wins」を活用する

style プロパティはスタックではなく上書きされるという事実を利用します。これを使用すると、複数のパラメータを必要とせずに、デフォルトのコンポーネントの境界線や背景をオーバーライドできます。

非推奨事項

次のパターンは推奨されません。

禁止: インタラクション ロジックにスタイルを使用する

スタイル内で onClick やジェスチャー検出を処理しようとしないでください。スタイルは状態に基づく視覚的な構成に限定されるため、ビジネス ロジックを処理すべきではありません。代わりに、状態に基づいて異なる視覚的な表現のみを行うべきです。

非推奨: デフォルトのスタイルをデフォルトのパラメータとして指定する

スタイル パラメータは常に style: Style = Style を使用して宣言する必要があります。

@Composable
fun BadButton(
    modifier: Modifier = Modifier,
    // ❌ DON'T set a default style here as a parameter
    style: Style = Style { background(Color.Red) }
) {
}

「デフォルト」パラメータを含めるには、受信パラメータ スタイルを定義済みのデフォルトとマージします。

@Composable
fun GoodButton(
    modifier: Modifier = Modifier,
    // ✅ Do: always pass it as a Style, do not pass other defaults
    style: Style = Style
) {
    // ...
    val defaultStyle = Style { background(Color.Red) }
    // ✅ Do Combine defaults inside with incoming parameter
    Box(modifier = modifier.styleable(styleState, defaultStyle, style)) {
      // your logic
    }
}

非推奨: レイアウト ベースのコンポーザブルにスタイル パラメータを指定する

任意のコンポーザブルにスタイルを指定できますが、レイアウト ベースのコンポーザブルや画面レベルのコンポーザブルがスタイルを受け入れることは想定されていません。このレベルでスタイルが何をするのかが、ユーザーの視点から見て不明確であるためです。スタイルはレイアウトではなく、コンポーネント用に設計されています。