🦁

[Amplify×figma]コンポーネント化した部品から、さらにコンポーネントを作成してみるも、あえなく撃沈した話

2023/04/15に公開

チェックボックスのデザインをデフォルトでどこまで変えられるのか

チェックボックスのデザインを変えたいと思ったとき、どこまで変えられるのでしょうか。
今のところ、AWS Amplify UI Kitで用意されているプリミティブなコンポーネントは、デザインに制約があって、その中でやる分にはいいのですが見た目をもう少し凝りたいときはそう簡単ではないことは分かっています。
もう少しどうにかなんないの?をやっていきたいと思います。

チェックボックスのアイコンの色・形を変えたい

というわけで、まずは色と角丸を変えてみたいのです。
実装上に変更するのはできます。できるのですがデザインの世界はできるだけデザインの世界で完結させたいんですよね。
デザインのことは全てfigma側だけでどうにかできないか。

デフォルトで用意されているCheckboxFieldにあるIconの角の半径をいじって丸くしてみました。
同様にIconの色を緑色にしてみます。

Amplify Studioに取り込んでみると、プレビュー画面上は下記のようになります。
見事に設定が無視されています。

Iconは🔒がついているので、読み取り専用?というか設定は無視されてしまうようですね。
なので、figmaでいくら設定を変更してもダメみたいです。

チェックボックスとラベルが連動するようにしたい

チェックボックスのON/OFFでラベルを変更させたいです。
とりあえず、既存に備わっているチェックボックス(CheckboxField)とバッジ(Badge)を組み合わせてみます。

バリアントを作成して、ON/OFF時のレイアウトを作成する

figma上でONとOFFのときのレイアウトを作成してみます。
バリアントを追加して、ON時のレイアウト、OFF時のレイアウトを作成すればいけそうですね。
checked=onchecked=offを作成してBadgeインスタンスの属性で、variation=successvariation=errorを使用します。
まずはあるものをうまく使ってやる方向で行きます。

figmaの出来上がりはこんな感じ。

では取り込んで画面表示してみましょう!

よしよしうまく行った!
チェックのON/OFFを切り替えてみます。

MyCheckboxの実装部分のサンプルです。
レイアウト部分は一切手を入れずに、動きの部分だけ実装しています。
色味については、もともと用意されているテーマに任せています。

const MyCheckboxWrapper = (props: MyCheckboxProps) => {
  const [myCheckbox, setMyCheckbox] = useState<MyCheckboxProps>({
    checked: props.checked ?? 'off',
  });

  return (
    <>
      <MyCheckbox
        checked={myCheckbox.checked}
        overrides={{
          CheckboxField: {
            defaultChecked: (myCheckbox.checked === 'on'),
            testId: "myCheckbox",
            value: "1",
            onClick: () => {
              const prop = { ...myCheckbox }
              if (myCheckbox.checked === 'off') {
                prop.checked = 'on'
              } else {
                prop.checked = 'off'
              }
              setMyCheckbox(prop)
            }
            },
        }}
      />
    </>
  )
}

export default MyCheckboxWrapper

作成したコンポーネントを使って、もう少し大きなコンポーネントを作成する

画面を作っていくと、1つ1つの部品もさることながら、もう少し大きな単位でコンポーネントを作成するケースもあると思います。
先ほど作ったチェックボックスのコンポーネントで、さらにそのチェックボックスを配置した部品を作ってみます。

イメージはこんな感じ。
この後いろいろ調整していきます。

オートレイアウトを使って並びをキレイにする

今回は単純に縦に並べるのと、「〜に同意する」とチェックボックスをワンセットで、空きをそれぞれ調整したいので、フレームを2階層にします。
最終系はこんな感じ。

え?なんでや?チェックボックスのテキスト部分が反映されない。

今のろころ解決策ないので、オーバーライドすることで回避します。

/**
 * overridesは、インスタンスの階層になっているので、
 * MyAgreement>MyCheckbox1、MyAgreement>MyCheckbox2のlabelを
 * 実装側で設定すれば画面表示で切り替えられます。
 */
export const MyAggrementWrapper = (props: MyAgreementProps) => {
  return (
    <>
      <MyAgreement
        overrides={{
          MyCheckbox1: {
            overrides: {
              CheckboxField: {
                label: '同意する',
              }
            }
          },
          MyCheckbox2: {
            overrides: {
              CheckboxField: {
                label: '同意する',
              }
            }
          }
        }}
      />
    </>
  )
}

これで回避できるやろと思っていたらダメでした。。
今時点で自分が理解できていないのかもしれないですが、現状の理解は下記の通り。

本当は動きをつけた〜Wrapper.tsxをコンポーネントとして使用したかったのですが、
実装側で作ってしまっているのでfigmaとうまく連動することができない。
→もしやるなら、動きの実装をさらに作成することになるので、コンポーネント側で隠蔽することができない。。

えー、そうなのー?😱
うーん、今日はひとまずここまでにしよう。。

GitHubで編集を提案

Discussion