Amplify Studio向けFigma作成のハマりどころ

この記事は2023/6月アドベントカレンダー7日目の記事となります。

Amplify Studioの売りポイントは、Figmaデザインを迅速にコード化できるところにあります。
コード拡張の仕組み(overridesプロパティを介して業務ロジックを差し込む)を利用することで、デザインだけを修正して簡単にリリースすることができます。コード周りではおおよそ期待通りの迅速化をもたらしてくれます。

一方で、デザインの元となるFigmaファイルを作る際には、Amplify Studioの「前提」に合わせて作り込む必要があり、多くの場合、デザイナーが作成したFigmaを手直しすることになります。ドキュメント化されていない前提も多数あり、迅速化の妨げになりがちです。

時短のためのFigma x Amplifyなのに、面倒な作業があっては勿体無いです。もっとAmplify仲間を増やしたいので、我々が検証を行う中でわかった罠回避のTipsをみなさまと共有できたらと思います。

FigmaをAmplify Studioの「前提」に合わせるとは?

デザイナーが作成したFigmaをそのままの形でAmplify Studioに取り込めればベストなのですが、現実的にはAmplify Studioが定めている前提に従ったFigmaの書き方をしなければ取り込みエラーとなったり、レイアウト崩れが発生します。

まずは、大前提となるものを挙げておきます。

前提1:Amplify UI Kitを使う

Amplify Studioに限らず、Figmaをコード変換するツール類は、ツール固有の規則に従わせることが一般的です。Amplify Studioでは「Amplify UI Kit」の使用を大前提としています。

例えば、下記ようなRectangleで構成されたテキスト入力風のデザインを作ったとします。


AI搭載の変換ツールであれば、上記「1」の部分をinput type=”text”のUIコンポーネントに変換してくれるかもしれませんが、Amplify Studioでは、ReadOnlyなタグ(Flex、View)を出力するだけです。

Amplify Studioでは、TextFiledのようなAmplify UI Kitのプリミティブ部品を使用して、テキスト入力できる部品に変換させる必要があります。

前提2:Amplify Studioが認識できない書き方をしない

Figmaでは問題なくとも、Amplify Studioに取り込むとエラーやレイアウト崩れになることはよくあります。Amplify Studioできちんと表示できていれば体感的に95%くらいはコード化して動かしても問題ないので、Amplify Studio取り込み時に細心の注意を払うことが重要です。(残り5%は、実コードにして初めて判ります。この程度は仕方ありませんね・・・)

どの書き方がNGなのか、マニュアルに明示されていないものが多い印象ですので、Amplify Studioを採用する場合には、必ず使用するコンポーネントを使ったPocを一通り行ってみることをお勧めします。
以下では、明示されていない前提によるトラブルを避けるためのTipsを解説していきます。

Figma全般編

最初に、特定のコンポーネントに依存しない全体的な前提事項を記載します。

マスタコンポーネントは同一ファイル上に置く

Amplify Studioに取り込みたいFigmaコンポーネントは、同じFigmaファイル上に配置します。
同じFigmaファイル上にあれば、別ページでもOKです。

別のFigmaファイルに配置した場合、Amplify Studio取り込み時に読み込みできないというインフォメーションメッセージが出て、ダミーが差し込まれます。インフォメーションメッセージであっても読み飛ばさないことが大事です。

入力系コンポーネントはAmplify UI Kitのプリミティブを使用する

文字を入力したければ、必ずAmplify UI Kitのプリミティブ部品を使用します。

要素Amplify UI Kitプリミティブ部品名
テキスト入力TextField、TextArea(新しいUI Kitから追加、複数行入力用)
パスワード入力PasswordField
ドロップダウンSelectField


ボタン、チェックボックス、ラジオンボタンは自作できるため、プリミティブの動きが目的に合わなければ自作をお勧めします。プリミティブ部品のカスタマイズには様々な制約があるため、経験上、プリミティブを触り倒すよりも自作の方が早く作れ、コードも多少増える程度です。

レイヤーの命名規則を定義する

Figmaでコンポーネントをデザインする場合、図形の配置、グループ化やフレーム化などをすることが多々あります。このときに、Figmaの方で自動的にユニークなレイヤー名を付けてくれるので、基本的にはこのままでOKです。

ただし、コード側でoverridesを使って業務ロジックを注入するもの(例:ボタン類)、動作を上書きするもの(例:可変文言)、値を読み書きするもの(例:TextField)、については、命名規則を作って命名した方がよいです。

命名する際に、日本語でレイヤー名をつけると、コード上ではUnicodeエスケープされた文字列として見えるので、視認性が悪く、扱いが煩雑になります。以下のような命名規則を検討してください。

命名規則説明
アルファベットから始まる英数字(先頭は大文字)コード生成時に数字部分が除去されるため⚪︎:AgreeCheckbox01
×:01AgreeCheckbox
スラッシュやハイフンは使用しない(/、-)コード生成時に強制的に除去されるため⚪︎:FirstName
×:First-Name、First/Name
Pascal形式で命名するコード生成時に強制的に変換されるため⚪︎:Address
×:address

(推奨)Figma上で使用するフォントは統一する

異種OS間でFigmaを使う場合、テキストなどに使用するフォントを統一した方がよいです。
我々のチームでは「Noto Sans JP」を使用しました。

フォント統一と共に、Figmaネイティブアプリの利用をおすすめします。
https://www.figma.com/ja/downloads/

動作も高速で、インストールしたフォントがきちんと利用できます。
なお、Figmaで作成したWebページが実際に表示される時のフォントを固定するかどうは自由です。上記は、Figma上での見た目を統一するためにフォントを同じにするというTipsとなります。

(推奨)フォントサイズを直接指定するのではなくテキストスタイルを定義する

フォントの利用ルールの明確化とページを通したデザインの統一のため、フォントサイズは数値指定せずテキストスタイルから選択します。

Amplify Studioに取り込み時には、「xs」などの名前ではなく、「xs」などで定義されたフォント名、サイズなどがコンポーネントに直接指定されるため、自分たちで直接指定した場合と遜色ありません。Figma上でのスタイル統一できるため、扱いが楽になります。

なお、TextFieldなどのAmplify UI Kitのフォントは別の仕組みで決定されるため、Figmaのテキストスタイルには影響を受けません。

(推奨)静的なテキストはFigmaで定義する

中身の変わらない静的なテキスト(インタラクティブに変化しないテキスト)はFigma側で定義します。もちろん、コード側でも定義できますが、overridesを経由して書き換えることになるため、Figmaとコードのどちらでテキストを管理しているのか判り難くなります。

(例)overridesを使って書き換える場合

<MyUiComponent
  overrides={{
    MyText: {
      children: '入力内容を保存し、確認しました。次の操作を行なってください。',
    },

コードにUI要素が紛れ込んでスッキリしないですよね。

(推奨)可変文言を含むコンポーネント作成時の考慮

部品コンポーネントを作成するとき、文言を書き換えたいことが良くあります。

(例)自作チェックボックスのコンポーネント
 「可変文言」の部分をAコンポーネントから使われた時には「理解しました」、Bコンポーネントからは「はい」のように書き換えて使いたい


Figma上では問題なく書き換え可能ですが、Amplify Studioに取り込むと「理解しました」や「はい」にはならず、自作チェックボックスコンポーネントの文言「可変文言」で固定されます。可変にするには以下2つの戦略を検討してください。

戦略1:コードで書き換える

コード上でoverrides経由で書き換えます。「静的なテキストはFigmaで定義する」の例と同じ書き方です。どこが元ネタなのか判り難くなるため、あまりお勧めできないやり方です。

戦略2:プリミティブ部品を使う

Figmaのテキストを使った部品では呼び出しコンポーネント毎に書き換えできませんが、「Heading」のようなプリミティブ部品を「可変文言」の表示部に使用すると書き換えることができます。いまのところ把握できているのは、Heading、TextFieldの「placeholder」、Alertの「body」です。

(例)TextFiledのplaceholderに「例)花子」を設定
 この内容はAmplify Studioでも認識される(コードにしたとき、placeholderに反映)

レイアウト編(全般)

FigmaからAmplifyへの取り込みをこまめに行う

「なぜこれがレイアウトのところに」と思いましたか?
レイアウト崩れを防ぎたければ、Amplify Studioの「Sync with Figma」ボタンと友達になることです。無意識で押していた、になるまでよく自分を訓練してください。


エラーメッセージが不親切なので、まとめて取り込むとエラー発生箇所の特定が困難です。そのため、Figmaを触ったら「Sync with Figma」するのが手戻りを小さくする上で重要です。Amplify Studioに取り込み済みのコンポーネントが多くなるほど取り込み時間も掛かるようになりますが、50個で20秒程度です。大丈夫です、まだ待てます。

なお、「Sync with Figma」で同期している最中は、Figmaでの変更は控えた方がよいです。どの瞬間のFigmaが同期されているのか怪しいです。

オートレイアウトを使用する

マニュアルにもありますが、オートレイアウトを使うことがベストプラクティスです。
オートレイアウトを使わないことでAmplify Studio特有の問題が起きる訳ではありませんが、breakpointを使用したレスポンシブデザインをするとき、非常に面倒になります。

レイアウト編(細かなTips)

ここからは怒涛のTips集です。

均等割を使う場合

オートレイアウトで「間隔設定モード」を「詰めて配置」→「間隔を開けて配置」に変更する場合、設定済みのgap値を「0」にしてから変更します。

(例)TestMainを変更する

「frame2」が見切れてしまったので、gapを固定の「300」にするのではなく、自動調整させるよう設定します。


Figma上では正しく見えますが、Amplify Studioに取り込むとgrap「300」が復活し、frame2が見切れることになります。

図形の回転を行う場合

Figmaから設定した図形の回転はAmplify取り込み時にリセットされるため、フレームで囲って右クリックメニューから「統合」で回転が0°になるようにします。

グラデーションを使う場合

Figma上のグラデーションの方向がAmplify取り込み時に変わってしまうため、コード上でオーバーライドします。

<MyUiComponent
    backgroundImage="linear-gradient(180deg, rgba(255,255,255,1), rgba(255,255,255,0))"

フレームの固定幅/拡大を設定する場合

バリアント「breakpoint」を使用し、smallの時にはフレームを「拡大」、largeの時にはフレームを「固定」ように異なる設定にしたいことがあります。
例えば、small(スマフォ)は、スマフォデバイスの横幅に応じて拡大したいが、large(PC)は固定でいい、というケースです。

このようなケースでも、smallとlargeともにフレームの拡大、固定が同じになるように設定します。異なる設定にすると、デフォルトではない方のバリアント(smallがデフォルトであればlarge)側で意図した通りのレイアウトになりません。

SVG画像を扱う場合

Amplify StudioではPNGなどの画像ファイルがプレビューできないため、表示可能なSVGを使用することがあります。しかし、SVGを使うとAmplifyのクォータリミットに抵触しやすくなるため注意してください。

リミットに抵触したら、PNGなどのラスター画像に変換して対応しますが、解像度の余裕を持たせるため、3倍サイズでの書き出しを推奨します。

プリミティブ部品のサイズを変更する場合

Amplify UI Kitのプリミティブ部品のサイズを変更する場合には、sizeやvariationプロパティを使って変更します。

(例)TextFieldのsize、variationプロパティ

Figma上で「W」(横幅)「H」(高さ)を書き換えるとAmplify Studio取り込み時にスタイル崩れが発生しやすいです(特に「H」の修正は絶望的、「W」は比較的うまくいきます)。
安全に書き換えたい場合には、コード上でcssを使います。

passwordFieldを使う場合

passwordFieldを使うと、Amplify Studioへの取り込みで、目玉アイコンのコンポーネント「Button Icon」がないと警告されますが、これは無視しても問題ありません。

Amplify Studio取り込み時に警告文言

A source component was not found for component id 2976:3119 with name 'Button Icon'. 
Please ensure it exists in the Figma file you are working with. For the time being, we have recreated it inside of this component.

直接原因は、Amplify UI Kitから提供されている「passwordField」の目玉アイコンの元ネタとなるマスターコンポーネントがUI Kitにパッケージングされていないためです。

Radioを使う場合

Radioはツッコミどころが多いプリミティブ部品です。

RadioGroupFieldを使いたければFigmaではRadioを使わない

Radioをグループ化する「RadioGroupField」がAmplify Studioでは自動生成されません。
RadioGroupFieldを指定しないと、全てRadioが同じRadioボタングループに入ってしまいます。

(例)性別(「男性」など)のRadio群と続柄(「子」「配偶者」など)のRadio群が同じグループになる →「男性」と「配偶者」のRadioがどれか一つしか選択できない

RadioGroupFieldを付けるには、FigmaでのRadioの使用を諦めて、Figmaではフレームだけを配置します。その上で、Amplify Studioで「Component Slots」を使うか、コード上でフレームのchildrenを介して「RadioGroupField」と「Radio」を配置します。

(例)フレームのchildrenを利用して設定する。入力チェック部品にReact Hook Formを使用

<MyUiComponent
  overrides={{
    MyFrame: {
      children: (
        <RadioGroupField
          ...methods.register('code', {required: '性別を選択してください。',}),
        >
          <Radio value="1">男性</Radio>
          <Radio value="2">女性</Radio>
                </RadioGroupField>
      ),
    },

FigmaでRadioをデザインしたいが、すべて同じグループに入るのは困るという方は、FigmaでRadioを配置し、コード上で同じnameを設定します。

(例)入力チェック部品にReact Hook Formを使用
 React Hook Formがnameを設定しれくれます。

<MyUiComponent
  overrides={{
    RadioMan: {
      ...methods.register('code', {required: '性別を選択してください。',}),
    },
    RadioWoman: {
      ...methods.register('code', {required: '性別を選択してください。',}),
    },

ただし、RadioGroupFieldを使えないため、同じ単項目チェックを複製したりと煩雑な部分が出てきてしまいます。

塗りやアウトラインはcssで指定

Radioに対して塗りやアウトラインを設定してもAmplify Studio取り込み時に無視されます。付けたければ、cssで指定します。

(例)背景色、枠線を指定するcss

.my-radio {
    background-color: white;
  border-radius: 9px;
  border: 1px SOLID rgba(174, 179, 183, 1);
}

上記をRadioのclassNameに指定します。

Radioはフレームに包んで使う

Radioを囲うオートレイアウトのフレームを用意し、フレームにgrapを設定します。フレームに包んでいない場合、下記のように、Radioボタンの丸とlabeの間のgapが効かなくなる事象があるためです。

Radio自体にgrapを設定しても無視され、Radioを囲むフレームが持つgrapを継承するようです。(なお、Radioを囲む枠線は自前のcssで入れています)

widthとheightは「固定」を指定

Radioをフレームで包む場合、以下の2通りが考えられます。

  • 方法1:フレームのwidth、heightを「固定」、Radioのwidth、heightを「コンテナに合わせて拡大」
  • 方法2:フレームのwidth、heightを「内包」、Radioのwidth、heightを「固定」


Figma上ではどちらも問題なく表示されますが、Amplify Studioでは 方法2のみ有効です。
方法1では、Radioのwidthとheightが未設定になり、Radioに外枠を付けていた場合に潰れてしまいます。

バリアント編

バリアントはレイアウト崩れを引き起こす代表格です。
例えば、このようなレイアウト崩れはよく起きます。

  • 部品コンポーネントにバリアント設定したら隠し表示(目を閉じたマーク)のレイヤーが丸見えになった
  • デフォルトでない方のバリアントが設定を無視する(デフォルト側と同じになりがち)

Amplify Studioでは、Figmaが持つバリアント以外のプロパティ、例えば「テキスト」を利用することができないため、バリアントを使ってテキストのバリエーションを持たせるようなことをします。そして、仕方なく使ったバリアントでスタイル崩れを起こす、までがセットです。

レイアウト崩れの発生はAmplify Studioによるコード生成方法に起因しており、事象と回避方法だけみても納得感を得にくいのですが、できるだけコードを使わずに説明してみます。

コンポーネントのレイヤー構成は全く同じにする

バリアント「breakpoint」を使って、smallとlargeを作ったとします。
この場合、Figma上の左側のメニューに表示されるレイヤーの構成を全く同じにします。

(例)Figmaの左側のメニューに表示されるsmallとlargeのレイヤーを左右に並べる
 例えば、インスタンス「CommonHeader」は、small、largeの両方でこの名前でないとNG。

レイヤーの構成が同じでないと、Amplify Studioで「Sync with Figma」を実行したとき、下記のようなメッセージが表示され、同期に失敗します。
このメッセージが表示された場合は、対象コンポーネントのレイヤー構成を確認してください。

このメッセージには、「対象のコンポーネント名」と「largeがおかしい」という情報しかありません。そして、smallをデフォルトとしているのでlargeがおかしいと出ているだけで、どちらがおかしいのか定かではありません。こまめに「Sync with Figma」を実行し、壊れた瞬間を捉えることが重要です。

バリアント間のプロパティ構成を同じにする、または、デフォルト側のプロパティを少なくする

バリアント間でレイヤー構成の違いはエラーとなりますが、プロパティ構成の違いは許容されています。ただし、許容されているだけで正しく表示できるとは限りません。

(例)バリアント「check」を持つコンポーネント「TestVariantComp」

NGケース:on(デフォルト)側にのみボックスシャドーをつけた

Figma上では設定通りに見えますが、Amplify Studioに取り込むと、onとoffの両方にボックスシャドーが適用されます。Amplify Studioには、デフォルト側にのみ存在するプロパティを自動的に全てのバリアントに適用する性質があるためです。

OKケース:off側にのみボックスシャドーをつけた(プロパティ数:on < off)

OKケース:どちらにもボックスシャドーをつけない(プロパティ数:on = off)

「いやいや、check=on側にだけボックスシャドーを付けたいのだが」であれば、check=offをバリアントのデフォルトにしてください。「装飾が少ない方をデフォルトとする」を基本とします。

装飾は最上位要素ではなく子要素に付ける

装飾はコンポーネントの最上位要素ではなく、子要素に付けます。

(パターン1)塗りを最上位要素に付ける

(パターン2)「塗り」を子要素(下記ではフレーム「inner」)に付ける

このコンポーネントを別のコンポーネントから使用した場合、Figmaでは全く問題ありませんが、Amplify Studioに取り込んだとき、見え方が変化します。

  • パターン1:デフォルトではないバリアント(上記では「label=off」の方)の「塗り」が無視されて、デフォルト(「label=on」の方)と同じ塗り(5555FF)になる
  • パターン2:Figmaと同じ見た目

明らかにパターン1はFigmaのコンポーネントと合っていません。
パターン1の構成で塗りを正しくしたければ、TestComp1の「label=off」の塗りをFFFFFのように別の色とし、呼び出し側のコンポーネントで本来の塗り(55FF55)を指定します。

このような部品を使う側に苦労を強いないために、パターン2の子要素に「塗り」などの装飾を付ける方針で設計した方が安全です。ただし、呼び出し側の都合で塗りを変えたい場合には、上書きできなくなるため、要注意です。

まとめ

Amplify Studio用Figmaデザインをする際のハマりどころをご紹介しました。

人力で全てやるのは煩雑と感じており、例えば、「バリアント間でレイヤー構成と名前が全て同じかどうか目視で確認する」ような単純作業であれば、機械的に(Figmaの自作プラグイン等)チェックしたいですよね。うまく時短ができたら、またご紹介したいと思います。

最後まで読んでいただき、ありがとうございました。