DropdownMenuButton

同じ対象に関連する複数の操作をまとめてドロップダウン表示するメニューボタンコンポーネントです。編集・複製・削除など、オブジェクトに対する複数アクションをまとめるときに使います。

使用上の注意

操作の個数

レイアウトの一貫性やユーザーの利便性に応じて適切な個数を設定してください。ひと目で把握できるようにできるだけ少ない個数が望ましいです。

ただし以下の場合には操作が1つの場合でも、あえてドロップダウンパネルの中に配置することがあります。

  • 類似する画面とのレイアウトの一貫性を保ちたいとき

操作の順序

使用頻度が高い順を推奨しますが、破壊的なアクション(例:オブジェクトの削除)に関しては、順序を下げて配置してください。
操作の順序の典型的な例は以下のとおりです。

  • 編集
  • 複製
  • 削除

開かれた操作ドロップダウン。編集・複製・削除の順に操作が並んでいる。

レイアウト

ドロップダウンの引き金となるボタン(トリガー)とドロップダウンパネルをあわせて、「ドロップダウンメニューボタン」と呼びます。

ドロップダウンメニューボタンは、以下の要素で構成されています。

  1. トリガー
  2. ドロップダウンパネル

ドロップダウンメニューボタンの構成図

1. トリガー

複数の操作がまとまっていることを示唆するために、Secondaryボタンのアイコン付き(右)展開 アイコン(FaCaretDownIcon)を使っています。

2. ドロップダウンパネル

操作をリスト形式でまとめて表示します。
まとめ方は、デザインパターンから用途にあったものを選択してください。

[WIP] モバイル

操作項目の高さは通常サイズのボタンに揃える
モバイルで自動的に調整されるようコンポーネントを改修予定です。

デフォルトではドロップダウンパネル内の操作項目の高さはサイズのボタンに揃えられています。
モバイルでは、操作しやすいように通常サイズのボタンに揃えてください(TODO: ボタンの基準にリンクする)。

横幅は画面幅の2/3程度までに収まるように調整する
モバイルで自動的に調整されるようコンポーネントを改修予定です。

ドロップダウンパネルの横幅は画面幅の2/3程度までに収まるように調整してください。

ドロップダウンパネルはパネル外を押すことで閉じることができますが、モバイルのような画面幅の狭い環境でもパネル外の押せる領域を十分に確保するためです。
また、横幅が画面幅いっぱいに広がったパネルとその下のコンテンツとの区別がつきづらくなってしまうことも防げます。

Do
Do
Dont
Don't
縦幅は画面内に収まるように調整する
モバイルで自動的に調整されるようコンポーネントを改修予定です。

ドロップダウンパネルの縦幅は画面内に収まるように調整し、必要に応じてスクロールできるようにしてください。

ドロップダウンパネルが画面外にはみ出ていると、はみ出ている操作を押すためにページをスクロールすることになります。この際モバイルのようなタッチ操作を中心とする環境でスクロールしたときに、誤ってパネル外を押すことで意図せずパネルが閉じてしまうことを避けるためです。

Do
Do
Dont
Don't

デザインパターン

用途によって5つのパターンを定義します。

#パターン名用途
A単一のオブジェクトに対する操作オブジェクトに関する複数の操作をまとめるときに使います。
B単一のオブジェクトに対する操作(オブジェクト名省略)特定のオブジェクトの操作であることがレイアウト上自明なとき(例えば「よくあるテーブル」の行の中など)に使います。
C同一の操作同じ種類の操作をまとめるときに使います。
D異なる複数の操作A、B、Cのパターンに該当しないときに、異なる複数の操作をまとめるために使います。
Eラベル省略(非推奨)ボタンを配置するスペースを十分確保できないときの最終手段として検討できますが、基本的に利用を推奨しません。

A. 単一のオブジェクトに対する操作

オブジェクトに関する操作をまとめるときに使います。

要素説明
トリガーラベルは{オブジェクト名}の操作とします。
ドロップダウンパネルオブジェクトに対して行う操作を入れます。

B. 単一のオブジェクトに対する操作(オブジェクト名省略)

操作の対象になるオブジェクトがレイアウト上、明らかなときに使います。
(例:「よくあるテーブル」の行の中など)

要素説明
トリガー基本的に「A. 単一のオブジェクトに対する操作」のようにオブジェクト名を表示しますが、狭い場所にレイアウトするときにオブジェクト名を省けます。ラベルは操作にします。
ドロップダウンパネルオブジェクトに対して行う操作を入れます。トリガーのラベルと同様にオブジェクト名を省けます。

C. 同一の操作

同じ種類の操作をまとめるときに使います。

要素説明
トリガー操作をまとめるラベルにします。
ドロップダウンパネル同じ種類の操作を入れます。

D. 異なる複数の操作

A、B、Cのパターンに該当しないときに、異なる複数の操作をまとめるために使います。

要素説明
トリガーラベルはその他の操作とします。
ドロップダウンパネル異なる複数の操作を入れます。

E. ラベル省略(デスクトップでは非推奨)

ボタンを配置するスペースを十分確保できないときの最終手段として検討できます。

デスクトップでは基本的に利用を推奨しません。
モバイルはスペースが限られるため検討可能性は上がりますが、可能な限り避けることを推奨します。

要素説明
トリガーtrigger.onlyIcon を設定するとボタンを アイコンのみで表示できます(標準:FaEllipsisIcon)。アイコンの変更は非推奨ですが、やむを得ない場合はtrigger.onlyIcon.componentで変更可能です。なお、何のボタンか識別できるようにするため必ずtrigger.childrenを設定します。
ドロップダウンパネル操作を複数入れます。

状態

無効(disabled)

トリガーの無効

DropdownMenuButton自体を無効にすると、ドロップダウンパネルも操作できません。

ドロップダウンパネルの操作の無効

ドロップダウンパネル内の操作を無効にする場合、ButtonのdisabledReasonを使って無効状態の理由を表示します。

使い方チェックリスト

DropdownMenuButton
参照元:使用上の注意 > 操作の個数 「使用上の注意 > 操作の個数」の本文へ移動
  • Should
    DropdownMenuButton の操作はひと目で把握できるようできるだけ少ない個数にする
参照元:使用上の注意 > 操作の順序 「使用上の注意 > 操作の順序」の本文へ移動
  • Must
    破壊的なアクション(例: オブジェクトの削除)は操作の順序を下げて配置する
  • Should
    DropdownMenuButton の操作は使用頻度が高い順に並べる
    • 典型的な順序の例: 編集 → 複製 → 削除
参照元:レイアウト > [WIP] モバイル > 操作項目の高さは通常サイズのボタンに揃える
  • Must
    モバイルでは、ドロップダウンパネル内の操作項目の高さを通常サイズのボタンに揃える
参照元:レイアウト > [WIP] モバイル > 横幅は画面幅の2/3程度までに収まるように調整する
  • Must
    モバイルでは、ドロップダウンパネルの横幅を画面幅の 2/3 程度までに収まるように調整する
参照元:レイアウト > [WIP] モバイル > 縦幅は画面内に収まるように調整する
  • Must
    モバイルでは、ドロップダウンパネルの縦幅を画面内に収まるように調整し、必要に応じてスクロールできるようにする
参照元:デザインパターン > A. 単一のオブジェクトに対する操作 「デザインパターン > A. 単一のオブジェクトに対する操作」の本文へ移動
  • Must
    トリガーのラベルを `{オブジェクト名}の操作` とする
参照元:デザインパターン > B. 単一のオブジェクトに対する操作(オブジェクト名省略) 「デザインパターン > B. 単一のオブジェクトに対する操作(オブジェクト名省略)」の本文へ移動
  • Must
    トリガーのラベルを `操作` にする
  • Should
    操作の対象がレイアウト上明らかなとき・狭い場所にレイアウトするときに使う
参照元:デザインパターン > C. 同一の操作 「デザインパターン > C. 同一の操作」の本文へ移動
  • Must
    トリガーのラベルを操作をまとめるラベルにする
参照元:デザインパターン > D. 異なる複数の操作 「デザインパターン > D. 異なる複数の操作」の本文へ移動
  • Must
    トリガーのラベルを `その他の操作` とする
参照元:デザインパターン > E. ラベル省略(デスクトップでは非推奨) 「デザインパターン > E. ラベル省略(デスクトップでは非推奨)」の本文へ移動
  • Must
    何のボタンか識別できるよう必ず `trigger.children` を設定する
  • Avoid
    デスクトップでは利用を避ける
  • Avoid
    モバイルでも可能な限り利用を避ける
  • Avoid
    標準アイコン(`FaEllipsisIcon`)の変更は避ける
参照元:状態 > 無効(disabled) > ドロップダウンパネルの操作の無効 「状態 > 無効(disabled) > ドロップダウンパネルの操作の無効」の本文へ移動
  • Must
    ドロップダウンパネル内の操作を無効にする場合、Button の `disabledReason` を使って無効状態の理由を表示する

Props

DropdownMenuButton props

trigger必須
string number false true ReactElement<any, string | JSXElementConstructor<any>> Iterable<ReactNode> ReactPortal { children: ReactNode; size?: ButtonProps; onlyIcon?: boolean | { component?: ComponentType<any>; }; }

引き金となるボタン

children必須
string number false true ReactElement<any, string | JSXElementConstructor<any>> Iterable<ReactNode> ReactPortal ReactElement<{ size?: "S" | "M"; disabledReason?: { icon?: FunctionComponent<{}>; message: ReactNode; }; prefix?: ReactNode; suffix?: ReactNode; wide?: boolean; variant?: Variant; loading?: boolean; } & { ...; } & Omit<...> & RefAttributes<...>, string | JSXElementConstructor<...>> ReactElement<Omit<any, "disabledReason" | "variant"> & { elementAs?: ElementType; variant?: "text" | "primary" | "secondary" | "danger" | "skeleton"; inactiveReason?: { ...; }; } & { form?: string; slot?: string; style?: CSSProperties; title?: string; ref?: Ref<HTMLButtonElement>; key?: Key; defaultChecked?: boolean; defaultValue?: string | ... 1 more ... | readonly string[]; ... 266 more ...; formTarget?: string; }<...> & ElementRefProps<...>, string | JSXElementConstructor<...>> ReactElement<{ targetId: string; onClick?: (open: () => void) => void; } & { children?: ReactNode; }, string | JSXElementConstructor<any>> ReactNode | ReactElement<any, string | JSXElementConstructor<any>> | ReactElement<any, string | JSXElementConstructor<any>> | ReactElement<...>[]

操作群

onOpen
() => void

ドロップダウンメニューが開かれた際のイベント

onClose
() => void

ドロップダウンメニューが閉じられた際のイベント

ref
(instance: HTMLButtonElement) => void RefObject<HTMLButtonElement>

DropdownMenuGroup props

name
string number false true ReactElement<any, string | JSXElementConstructor<any>> Iterable<ReactNode> ReactPortal