MenuとPanelの見極め方
ニコニコ生放送でフロントエンドを担当している misuken です。
今回はとあるPull Requestを発端として、Menu
と Panel
の違いやその関係性を明らかにするため、一歩ずつ分析を進め、最終的に多角的な分析で高精度の結論に達した考察の過程を共有します。
コンポーネント設計やコンポーネント名を明らかにするときの参考になれば幸いです。
2024-03-11追記: 記事タイトルを変更しました
前提
この記事は BCD Design を基礎とし、以下の記事で紹介した理論を踏まえた内容となっていますが、記事中にリンクが貼られているので、適宜参照しながら読み進めてみてください。
気付きの発端
ある日の Pull Request
BCD Design の Base のディレクトリに以下のような構成になる RadioGroupMenu
というコンポーネントを追加するPull Requestのレビュー依頼が来ました。
// このような構成になるコンポーネント
<div>
<RadioGroup />
</div>
イメージ画像
これを見て、所感として以下が浮かびました。
-
Menu
は本来Item
と組み合わさった<ul>
<li>
形式の型(または aria でそれ相当)であると考えられるので何かおかしそう -
RadioGroupMenu
はMenuMenu
と言っているように冗長に感じられる - この構成の場合
Menu
ではなくRadioGroup
を持つPanel
なのでRadioGroupPanel
となりそう
このコンポーネントは浮遊して表示されるものでもあったので、RadioGroupMenu
のように UI(RadioGroup) + UI(Menu) のコンポーネントとして素直に考えると、RadioGroup
を Panel
に組み合わせた RadioGroupPanel
と表現したほうが適していると考えられます。
RadioGroupMenu の利用先
RadioGroupMenu
は新着順、更新順などの並び順を選ぶための OrderMenu
というコンポーネントで使用されていました。(サイトが注文を扱うような場合は Order
よりも SortOrder
を使用したほうが良いでしょう)
RadioGroupPanel
に変われば OrderMenu
も OrderPanel
に変わることになりますが、OrderPanel
だと若干の言葉足らず感が否めません。
OrderPanel
を日本語に置き換えてみると "並び順パネル" であり、"並び順メニュー" や "並び順メニューパネル" のほうがまだしっくりきてしまいます。
理由を考えてみると、ここでメニューが指すのは Menu
というUIの型ではなく "選択できるもの" という意図だと受け取れます。
そこで menu の単語の意味を調べてみると、以下あたりにしっくりくる表現があります。
2.《コ》メニュー◆ユーザーが利用可能なオプションのリスト。
3.〔利用可能なものの〕一覧、メニュー
つまり、選べる(利用可能)ということが読み取れれば良いので、例えば OrderSelectPanel
"並び順選択パネル" などでも意図が表現できるわけです。
拡張性の問題
並び順を選ぶという具体的な目的が見えてきたところで、コンポーネントの拡張性に関しても考えてみます。
これまでの流れで、UIの単位としては RadioGroupMenu
よりも RadioGroupPanel
のほうが適切であると述べましたが、実際は RadioGroupPanel
という単位でコンポーネントにする価値はほとんどありません。
RadioGroupPanel
というコンポーネント名は、以前の記事に書いた "部品Aを利用するB" に該当しますが、 "RadioGroup
を利用する Panel
" を定義しようとしても、BCD Design の Base の段階では RadioGroup
を一つまたは複数置けるようにしておくことしかできません。
さらに、そのコンポーネントを利用する際に他の表示要素を追加したくなると、無理に RadioGroupPanel
を使ってレイアウトの制約を受けるより、新たに RadioGroup
と Panel
を組み合わせて自由に作ったほうがスムーズであるためです。
パネルで決まることは少ない
コンポーネント名を明名するときに考えたことで扱っていた Field
というコンポーネントの話を思い出してみます。
Field コンポーネントとの比較
Field
のときは、ラベル、メッセージ、必須表現等、一般的にそれ自体が持つ構成がある程度はっきりしていて、あとは「どのような入力UIと連携するか?」という限られた部分だけが抽象化されていました。
しかし Panel
は内容の部分が自由であり、Panel
という名前によって決まる部分が少ない違いがあります。
Panel
で決まるのはだいたい以下で、それ以上の構成は具体的な関心と結び付いたときに決まります。
- パネルとしての土台がある
- 閉じるボタンの有無
つまり、これ以上の構成を含む XxxPanel
を作る時点で、必ず関心への依存が発生することを意味します。
関心の名前を探る
関心への依存が発生するということは、コンポーネント名にその依存を表す単語を含めることになるので、RadioGroup
というUI名ではなく、 RadioGroup
を含める必要が生じた理由を関心の視点から捉えてみます。
それは "並び順を選択したい" という理由ではあるのですが、"選択する" という表現がちょっと具体的すぎる感じがするので、もう少し汎用性の高いスコープのイメージで漠然と思考を巡らせると "並び順に関する設定を行えるもの" といった表現が浮かんできます。
ここで "設定" という単語が出てきたのでこれを当てはめてみましょう。
OrderSelectPanel
よりも OrderSettingPanel
のほうがよりピントの合った印象になります。
例えば、そこに "設定を記憶する" のようなチェックボックスを置くような拡張を行う場合も OrderSettingPanel
のほうが馴染みます。
OrderSettingPanel
は設定内容が "並び順" に限定されているだけで、一般的な SettingPanel
の概念と一致するため、この方向性の精度は高いと言えます。
設定パネルという切り口
それでは設定パネルの切り口から考えてみます。
ここではイメージしやすいように、具体的な関心名として "番組" Program
を使います。
設定パネルとして組み立てる
具体的な関心 ProgramOrderSetting
において Panel
を利用する場合、"関心Aで利用するB"" に該当するので ProgramOrderSettingPanel
になります。 日本語では "番組並び順設定パネル" になります。
名称 | 日本語 | BCD Design の分類 |
---|---|---|
Program |
番組 | Domain |
OrderSetting |
並び順設定 | Common |
Panel |
パネル | Base |
そこそこ精度が上がってきたのですが、並び順の設定が行える場合、このコンポーネントの成長軸を考慮すると、並び順に限らずフィルタ条件のような要求はありがちです。 そこで、"一覧" に関する設定を行えるような成長軸も意識してみます。
するとこれまで "一覧" という意味を表す単語がコンポーネント名から欠けていたことに気付きます。
たしかに並び順は単一の番組自体にかけているわけではなく、番組の一覧(一覧にするとき)にかけているので ProgramListingOrderSettingPanel
のほうが正しかったということになります。
名称 | 日本語 | BCD Design の分類 |
---|---|---|
Program |
番組 | Domain |
ListingOrderSetting |
一覧並び順設定 | Common |
Panel |
パネル | Base |
その上で、並び順以外の設定も含められるように Order
の縛りを外してスコープを広げると、 ProgramListingSettingPanel
という名前になります。
名称 | 日本語 | BCD Design の分類 |
---|---|---|
Program |
番組 | Domain |
ListingSetting |
一覧設定 | Common |
Panel |
パネル | Base |
ProgramListingSettingPanel
は、一覧に関する設定全般を含められるスコープになっているので、番組の一覧設定で使用される設定項目を全部詰め込んでおいて、使用する場所で必要な設定項目だけ表示すると効率的であることが見えてきます。(ある場所では A と B、他の場所では B と C の設定項目を使用する場合があるため)
番組コマンドパレットの例
ここでニコニコ生放送の例を挙げましょう。
ニコニコ生放送にはプレーヤーの番組コメント投稿フォームのコマンド入力欄にフォーカスすると表示される、番組コマンドパレットというコンポーネントがあります。
構成は以下のようなもので、ProgramCommandPalette
は言い換えると ProgramCommandSettingPanel
を表していると言えます。しかし、少し前にコメント投稿に関する設定も追加されたので、ProgramCommentPostSettingPanel
にリネームしていったほうが適切であることもわかります。
- コメントの大きさの設定 (実装は
RadioGroup
) - コメントを流す位置の設定 (実装は
RadioGroup
) - コメントの色の設定 (実装は
RadioGroup
) - コメントの投稿設定 (実装は
ToggleButtonField
将来的にSwitchField
に変更予定) - 特定の条件を満たしたときに表示されるリンク動線(画像には表示されていません)
このコンポーネントは内部に RadioGroup
を含んでいますが、RadioGroupPanel
を拡張した延長線上には存在しません。
Panel
内の構成は "番組コメント投稿設定" という関心に依存して決定されていると言えます。
UI 視点からの分析
次に UI の視点から Menu
と Panel
の違いや、関係性に関して分析してみます。
Menu
UI としての Menu
、つまり末尾が Menu
で終わるコンポーネントは、以下を満たしていると明確になります。
- コンポーネント自体が
Menu
というUIそのものである - コンポーネントのルートの要素が
<ul>
またはrole="menu"
である
React Spectrum の Menu はariaを上手に使ってセクションや見出しを加えながらも Menu
の型を保っていると言えます。(コンポーネントのルートとなる要素が role="menu"
になっているため)
Panel
UI としての Panel
、つまり末尾が Panel
で終わるコンポーネントは、以下を満たしていると明確になります。
- コンポーネント自体が
Menu
というUIそのものではない - 関心と組み合わさるまで構成が決まらない
Menu と Panel のベースの見た目が同じ場合
Menu
と Panel
はベースの見た目が同じことがあるので、Panel
をベースに使った Menu
を作れるようにしておくと便利です。
実現方法は色々ありますが、例えば以下のようなイメージになります。
この場合、コンポーネントの型としては Menu
になります。
// Panel をベースに使った Menu の例
<Panel as={Menu}>
<Item>A</Item>
<Item>B</Item>
<Item>C</Item>
</Panel>
型に収まらないメニュー
ときには Menu
にも Panel
にも収まらないメニューが存在します。
例えば、銀行やクレジットカード、ショッピングサイトでメニューを開くと表示される、複数のメニュー等で構成された複合的なUIです。
このようなものには以下のように対処していきます。
- ネストした
Menu
で表現できるならMenu
で表現する - ネストした
Menu
で表現できないならMenuPanel
で表現する
MenuPanel
は Base に抽象的なコンポーネントとして作成しておくことはできません。
なぜなら、Menu
を部品として使用することはわかっていても、何らかの文脈のある関心と組み合わさるまで構成が決められないからです。
そのため、名前が MenuPanel
で終わるコンポーネントは、具体的な関心名と組み合わさるタイミングで始めて、 Common や Domain に誕生することになります。
ユースケースの観点
ユーザーはメニューかパネルかといった部分を意識しないので、ユースケースの観点から問題にならないかどうかを考えてみます。
メニューを開くというユースケースにおいて、実際にはパネルを開くことにはなりますが、メニューを開くためのボタンのテキスト(操作の意味を表す文言)は "メニューを開く" 等になるはずで、パネルの中にメニューも包括されているので、結果的にメニューは開けていることになり、適切に表現できていると言えます。
実装時の観点
実装時にメニューを探してしまい、パネルを探せないという問題があるかどうかを考えてみます。
コンポーネント名の関係上、対象の XxxMenu
を探すときに、アルファベット順でもコード補完でも XxxMenuPanel
が見つかるので問題ありません。
日本語の視点から分析
ここでは日本語の視点を加えることで、さらに理解を深めていきます。
Menu
Menu
は日本語で "一覧" を表します。
ただし Menu
には "利用可能なものの" という意味が含まれるため、単なる一覧であるならば List
で表現されるべきということがわかります。
このあたりの使い分けは、HTMLやariaのレベルでも同様のことが書かれており、単語の意味に対して忠実であることがわかります。
Panel
Panel
は "パネル" ですが、"パネル" は英語です。
ちゃんと日本語の漢字に翻訳すると "板" や "盤" になります。
"板" と "盤" の違いをAIに聞いてみたところ、要約すると以下のような回答が返ってきました。
字 | 意味 |
---|---|
板 | 何かに加工するための材料 |
盤 | 特定の用途で使用された加工済みのもの |
UIの世界で言う Panel
は未加工の板ではなく、切り出して整形され、ページを構成する部品として扱えるものなので "盤" のほうが当てはまります。
また、 "盤" には "ものを乗せる台" としての意味もあるため、他のUIを乗せる台としての役割も一致します。
boardとしての "盤"
将棋盤やチェス盤のように、ボードゲームの盤面を表す場合も "board" という単語が使われます。
これについてもAIに聞いてみたところ、"ものを乗せる台" としての意味の他にゲームの "舞台" としての意味を持っているといった回答が返ってきました。
SettingPanel
Panel
が "盤" であるなら SettingPanel
は "設定盤" になります。
Panel
が "盤" としてどのように使用されるか調べてみると(alc で "panel 盤" を検索) "配電盤" や "操作盤" など色々な "◯◯盤" が出てきます。
すると "設定盤" はちょっとおかしな名前に見えてきます。
"設定"(setting) という単語は名詞であり、 BCD Design の処理される対象(名詞)と処理自体(動詞) の観点では処理される対象になります。
しかし、 "◯◯盤" の "◯◯" にはだいたい処理自体を表せる単語が並んでいることがわかります。
- ✅ 操作盤 console panel → console
- ✅ 配電盤 (power) distribution panel → distribute
- ✅ 給電盤 (power) feeder panel → feed
- 🤔 設定盤 setting panel → set? setup? configure?
たしかに、"設定盤" だと設定をどうするのかが説明されていないため、名前に若干の言葉足らず感があります。
このことから本質的には "設定◯◯盤" となるであろうことが推察できます。
そこで、改めて "panel 盤" で検索した結果 を眺めてみると、まさにそれそのものを表す項目がありました。
"制御盤" です。
WindowsのOSでいうところのコンパネ(ControlPanel
)もまさにそれです。単語の意味を適切に扱っていくと、思わぬところで別のものとぴったり適合するのが面白いところです。
つまり "設定制御盤" SettingControlPanel
がそれを最も正確に表す名前であると言えます。たしかにこれであれば日本語でも名称と意味の間に違和感はありません。
- "番組一覧設定制御盤"
ProgramListingSettingControlPanel
- "番組一覧並び順設定制御盤"
ProgramListingOrderSettingControlPanel
名称 | 日本語 | BCD Design の分類 |
---|---|---|
Program |
番組 | Domain |
ListingOrderSetting |
一覧並び順設定 | Common |
Control |
制御 | Case |
Panel |
盤 | Base |
実際のところ一般的には "設定" に制御の文脈も含んでいるようなものなので SettingControlPanel
ではなく SettingPanel
を使っても問題ないでしょう。
このように本質を理解することで全体像をしっかり理解でき、他の設計をするときにも役立つので、頭の引き出しを増やすことに繋がります。
◯◯盤の総称
少し横道にそれますが、"配電盤" でググってみると "分電盤" "制御盤" などの用語が並んでいるページが見つかります。
そこではそれらの意味を解説しており、それらは "装置" や "設備" と書かれていました。
そこで "装置" と "設備" は何が違うのか気になったので "装置とは" "設備とは" でググってみたところ、以下の結果が表示されました。
要するに "装置" は機械的なもので、備え付けられる対象を意味し、"設備" は装置などが備え付けられたものを意味します。
つまり "設定制御盤" は機械として見れば "設定制御装置" であり、ページに備え付けられたものとして見れば "設定制御設備" であると言えます。
このように現実世界とも整合性が合うことは、高い精度でUIの本質を表現できていることの裏付けと言えます。
MenuMenu の違和感の正体
さて、全容が明らかになってきたところで、冒頭のほうで MenuMenu
がおかしいと書いた部分もスッキリさせてしまいましょう。
以前 共通部分をスマートに管理するディレクトリ構成 で書かれたいたように、 TextBoxField
のようなUI名 + UI名で表現されるコンポーネントの場合、Field
の中の入力部分が抽象化され、そこに具体的な TextBox
を連携させることで成立していると紹介しました。
名称 | 日本語 | BCD Design の分類 |
---|---|---|
TextBox |
テキストボックス(文字列入力機能) | Base |
Field |
フィールド(欄) | Base |
これに Menu
を当てはめてみましょう。もし ButtonMenu
が存在した場合、メニューの項目の部分が抽象化されていて、そこに具体的な Button
を連携させることで成立していることがわかります。当然 LinkMenu
なら Link
と連携することになります。
その前提でいくと、 RadioGroupMenu
にした場合、一つの項目ごとに RadioGroup
が連携されることを意味してしまうので、これは意図した形ではありません。
もし、一つの項目に一つのラジオボタンが連携されることを想定しているのであれば、 RadioMenu
になるべきです。
すると RadioMenu
自体が RadioGroup
相当の単位であることがわかり、Menu
と Group
の部分がどちらも複数項目を束ねる存在である点で一致します。
これが RadioGroup
は実質 RadioMenu
相当で、 RadioGroupMenu
にすると RadioMenuMenu
になり、冗長になると感じた正体だったということになります。
まとめ
RadioGroupMenu
を発端として様々な視点で分析を行った結果、まさかのWindowsのコンパネや、現実世界とも整合性が合うなど、想像以上に広い範囲と繋がっていることに気付くことができました。
単語の意味を知り、適切な単語を選択することは単語自体が持つ意味の型を利用できる絶大な有益性があると考えています。
今回の記事の主なポイントは以下。
- Menu と Panel の違いを認識する
- 入力UIを含んでいる場合は SettingPanel の筋を考えてみる
- 複合的なメニューは MenuPanel を検討する
物事を明らかにするときに大切なことは次の通りです。
- 多角的な視点からそのものが何なのかを考える
- 視点を切り替えても概念が一致すること
- 対称性を意識する
- 単語を取り替えたときにも概念が一致すること
- AI や検索を利用する
- AIに単語 A と B の違いについて尋ねてみる
- "◯◯とは" でググってそれは何なのかを調べてみる
おまけ
記事を書いている途中に、ふと zenn のヘッダーのUIの名前が気になって見てみたところ、ちゃんとメニューとパネルが使い分けられていたので、本質を追求すると自然と名前が一致することの面白さを感じました。
ユーザーメニュー | 通知パネル |
---|---|
参考
- BCD Design
- ニコニコ生放送のBCD Design導入事例
- アンチパターンを理解して package by feature へ
- 共通部分をスマートに管理するディレクトリ構成
- コンポーネント名を明名するときに考えたこと
株式会社ドワンゴでは、様々なサービス、コンテンツを一緒につくるメンバーを募集しています。 ドワンゴに興味がある。または応募しようか迷っている方がいれば、気軽に応募してみてください。
Discussion