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

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

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

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

次に例を示します。

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

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

しかし、デザイナーとデベロッパーは、Card で、Figma では説明しにくい機能を持つ既存のコンポーザブル MyExistingPlaybar を使用する必要があります。そこで、デベロッパーは UI パッケージ play_barMyExistingPlaybar にマッピングする 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. ダイアログで次のオプションを構成します。

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

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

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

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

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

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

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

  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 コンポーネントを既存のコードにマッピングする場合は、生成されたコンポーザブルと同じパラメータを受け取るコンポーザブルにマッピングする必要があります。たとえば、Chip という Figma コンポーネントにバリアントが含まれており、そのプロパティが ChipType である場合、生成されたコンポーザブル署名は次のようになります。

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

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