コンポーネントを既存のコードにマッピングする

デベロッパーは、生成されたコードの代わりに、UI パッケージと既存のコード コンポーネント間のマッピングを提供することで、コード生成プロセスをカスタマイズできます。これは、アニメーションや複雑な動作(プルダウン メニューなど)など、生成されたコードでは実現できない機能が既存の実装にある場合に便利です。

デベロッパーは、マッピング ファイルを使用してコンポーネントをマッピングする方法を指定します。マッピング ファイルは、少なくとも、適切なクライアント コードを作成できるように、ターゲットのコンポーズ可能な関数にアクセスする方法をコード生成ツールに指示します。

マッピングされたコンポーネントの概要図

次に例を示します。

Figma でデザイナーは、Play Bar コンポーネントのインスタンスを含む Card コンポーネントを作成し、両方のコンポーネントをパッケージ化して、デベロッパーに送信します。

デベロッパーが Figma から UI パッケージをインポートすると、ui-packagescardplay_bar の 2 つのディレクトリが作成されます。プロジェクトをビルドすると、CardPlayBar の 2 つのコンポーズ可能な関数が作成されます。通常 Figma では、CardPlay Bar インスタンスが含まれているため、コードでは、コンポーズ可能な関数 CardPlayBar コンポーザブルの呼び出しが含まれています。

しかし、デザイナーとデベロッパーは、Card で、Figma では説明しにくい機能を持つ既存のコンポーザブル MyExistingPlaybar を使用する必要があります。そのため、デベロッパーは play_bar UI パッケージを MyExistingPlaybar にマッピングする play_bar.json というマッピング ファイルを追加します。

{
    "target": "MyExistingPlaybar",
    "package": "com.example.myApp"
}

これで、デベロッパーがプロジェクトをビルドすると、CardPlayBar ではなく MyExistingPlaybar を呼び出すようになりました。MyExistingPlaybar のパラメータは PlayBar と同じにする必要があります(ただし、以下の追加のディレクティブで説明しているように、いくつかの違いがあります)。

マッピング ファイル

Android Studio プロジェクトでは、ui-package-resources/mappings の下にある ui-packages フォルダの横にマッピング ファイルが追加されます。Relay はビルド中にマッピング ファイルを探します。

プロジェクト ビューのマッピング ファイル

マッピング ファイルを生成する

Relay では、インポートした UI パッケージのマッピング ファイルを生成できます。手順は次のとおりです。

  1. パッケージ フォルダまたは対象の ui-package フォルダ内のファイルを右クリックします。[マッピング ファイルを生成] を選択します。

    マッピング ファイル アフォーダンスを生成する

  2. ダイアログで次のオプションを構成します。

    マッピング ファイルを生成するためのダイアログ

    • File location: 生成されるマッピング ファイルの場所を設定します。

    • ターゲット コンポーザブル: 生成されたコンポーザブルの代わりに使用されるカスタム コンポーザブルを設定します。既存のコンポーザブルを使用するか、ダイアログで新しいコンポーザブルを作成するかを選択できます。新しいコンポーザブルを作成すると、UI パッケージで定義されているものと同じパラメータを持つコンポーザブルが作成されます。

    • 生成されたファイル: マッピング ファイルの generateImplementation オプションと generatePreview オプションを設定します。詳しくは、以下のマッピング ファイルの内容をご覧ください。
  3. [マッピング ファイルを生成] をクリックします。指定した構成で新しいマッピング ファイルが ui-package-resources/mapping フォルダ内に作成されます。

次の手順で、Relay パッケージ モジュール UI から [Generate mapping file] ダイアログを開くこともできます。

  1. ターゲットの ui-package フォルダ内にある UI パッケージのファイルをクリックします。

  2. [Relay] ツール ウィンドウが自動的に開かない場合は、[Relay] アイコンをクリックしてウィンドウを開きます。

  3. [Package Options] で [Generate mapping file] ボタンをクリックします。

    マッピング ファイル アフォーダンスを生成する

マッピング ファイル名

特定のマッピング ファイルの名前は、置き換えるコンポーネントの UI パッケージ フォルダの名前と一致する必要があります。そのため、play_bar.jsonui-packages/mappings フォルダの UI パッケージを既存のコード コンポーネントにマッピングします。

マッピング ファイルの内容

マッピング ファイルには次のプロパティが含まれています。

  • target: (必須)コンポーズ可能なカスタム関数の名前。デフォルトでは、生成されたコードによって作成された関数の名前です。

    "target" : "CustomComposableName"
    
  • package:(必須)カスタム コンポーザブルが配置されているパッケージの名前。デフォルトでは、生成されたコードによって作成された関数のパッケージです。

    "package" : "com.example.podcastapp.ui.components"
    
  • generateImplementation: (省略可)true または false。true の場合、この UI パッケージの実装は、生成されたコードファイルに引き続き作成されます。false の場合、実装は作成されません。デフォルトは true です。

    "generateImplementation" : true
    
  • generatePreviews: (省略可)true または false。true の場合、マッピングされたカスタム コンポーネントのプレビューが、生成されたコードファイルに作成されます。false の場合、プレビューは作成されません。デフォルトは true です。

    "generatePreviews" : true
    

マッピングされたバリアント

Figma コンポーネントにバリアントがある場合、生成されるコンポーザブルには、バリアントをエンコードする列挙型パラメータが含まれます(デザイン バリアントの処理のチュートリアルを参照)。バリアントを含む Figma コンポーネントを既存のコードにマッピングする場合は、生成されたコンポーザブルと同じパラメータを受け取るコンポーザブルにマッピングする必要があります。たとえば、プロパティが ChipType のバリアントを持つ Chip という Figma コンポーネントの場合、Chip が生成するコンポーザブル署名は次のようになります。

@Composable
fun Chip(
    modifier: Modifier = Modifier,
    chipType: ChipType = ChipType.Red,
    chipText: String
) { ... }

Chip Figma コンポーネントを既存の MyChip コンポーザブルにマッピングする場合、MyChip の署名は、生成されたコンポーザブルと同じ署名である必要があります(追加のディレクティブが指定されていない場合)。概念的には、これは既存のコード コンポーネントが Figma コンポーネントと同じデザイン バリアントに対応できることを示しています。

その他のディレクティブ

たとえば、ターゲットとするコンポーズ可能な関数に次のシグネチャがあるとします。

@Composable
fun MyChip(
    modifier: Modifier = Modifier,
    chipType: ChipType = ChipType.Red,
    description: String  // instead of chipText
) { ... }

パラメータのマッピング方法に影響を与える fieldMappings ブロックをマッピング ファイルに追加できます。この場合、ChipchipText パラメータから MyChipdescription パラメータへのマッピングが含まれています。

{
    "target": "MyChip",
    "package": "com.example.myApp",
    "fieldMappings": [
        {
            "type": "parameter",
            "source": "chipText",
            "target": "description"
        }
    ]
}

fieldMappings ブロックのタイプは次のとおりです。

  • parameter: UI パッケージ フィールドをコード パラメータにマッピングします。
    • source: UI パッケージで指定されたパラメータの名前。
    • target: ターゲット コード コンポーネントで指定されたパラメータの名前。
  • lambda: UI Package フィールドをコンテンツ ラムダにマッピングします。
    • source: UI パッケージで指定されたパラメータの名前。
    • target: ターゲット コード コンポーネントで指定されたパラメータの名前。
  • modifier: UI パッケージ フィールドを修飾子メソッドにマッピングします。

    • source: UI パッケージで指定されたパラメータの名前。
    • method: 生成されたコードで呼び出す必要がある Modifier オブジェクトのメソッド。
    • parameter: 指定された Modifier メソッド内のパラメータの名前。
    • library: Modifier メソッドにアクセスするためにインポートする修飾パッケージ名。
    • scope: Modifier の範囲を示す 2 つの値のいずれか。
    • any: 修飾子は、任意のレシーバ スコープで使用できます。
    • relay: 修飾子は、Relay の RelayContainer オブジェクトのレシーバ スコープで使用する必要があります。