iT邦幫忙

2026 iThome 鐵人賽

DAY 16
0
Vibe Coding

看得懂、叫得出、驗得過:30 天 VibeCoding UI 元件實戰系列 第 16

Day 16|選一個值,還是執行命令?Select、Menu、Overflow Menu 與 Command Palette

  • 分享至 

  • xImage
  •  

安安~我是ChiYu~

工作區設定整理完後,我回到專案列表。最後一欄只放了一顆三點按鈕,展開後依序出現:

進行中、編輯、刪除。

畫面排得很整齊,行為卻像一道突襲測驗。

「進行中」會保存任務狀態;「編輯」應該開啟編輯介面;「刪除」則可能讓整筆資料消失。三個項目住在同一份清單裡,使用者按下 Enter 前,還得先猜這次是在填欄位,還是在下命令。

下面是依照第一版問題重建的錯誤現場,不含真實資料:

專案列表的錯誤第一版:任務狀態、編輯與刪除全部被放進同一顆三點按鈕

圖 1:「進行中」會留下資料值,「編輯」與「刪除」則會立刻執行命令;第一版卻讓三者共用同一種外觀與操作承諾。

問題來自原始需求:

在資料表每一列加一個下拉選單,讓使用者選擇編輯、刪除和狀態。

「下拉選單」四個字一次包辦資料選擇、列操作和危險命令,AI 當然會照著排成一列。元件名稱講得越模糊,按下去之後的後果就越容易由 AI 自由發揮。

今天先把兩件事分開:

  • 選一個值: 系統會留下目前狀態、角色或篩選條件。
  • 執行一個命令: 系統會開始編輯、匯出、複製或刪除。

外觀都可能是一張浮動清單,但操作後果完全不同。

我把這組差異放進 Menu、Select 與 Command Palette 完整比較頁

命令元件比較頁:先分清楚是在保存資料值,還是立即執行工作

圖 2:Menu、Select 與 Command Palette 都可能展開一列文字;按下項目後,有的保存資料,有的立刻執行工作。

原始 Prompt 重跑後,AI 真的把「刪除」當成選項

原始實驗在 2026 年 7 月 24 日使用 Codex Desktop 進行。當時保留了需求缺口,卻沒有留下第一張畫面;為了讓問題仍然能被檢查,我在 7 月 27 日用當日 GPT-5 系列模型重跑同一句 Prompt,沒有補上資料值、命令或危險確認規則。

模糊 Prompt 讓 AI 把狀態、編輯與刪除放進同一個下拉選單

圖 3:第一版把進行中、編輯與刪除排在同一份選項裡,沒有交代每個項目按下後會留下資料,還是直接執行工作。

第一版完整照著文字做了,問題也完整留下來了。

「進行中」是任務資料值,可以被保存、篩選與重新讀取;「刪除」則是會造成後果的命令。相同控制項同時承諾兩種行為,使用者無法從外觀預測 Enter 之後會發生什麼。

我的判斷是:

  • 狀態篩選與狀態編輯使用 Select。
  • 一組目的明確的命令使用 Menu Button。
  • 資料列的次級命令使用 Overflow Menu。
  • 跟目前物件有關的操作可以提供 Context Menu,但不能只靠右鍵。
  • 高頻、跨區域的熟手操作才進 Command Palette。

第一個問題不是選單長什麼樣,而是「會不會留下目前值」

遇到 Dropdown 需求時,我會先問:

使用者選完項目後,系統裡會留下哪一個目前值嗎?

如果答案是會,例如任務狀態、成員角色或篩選條件,那是在選資料。原生 <select> 有目前值,可以和 Label 關聯,也能隨表單提交,很適合「待處理、進行中、已完成」這類內容。MDN:<select>

如果按下後會開始匯出、開啟編輯或刪除資料,那是在下命令。命令名稱最好用動詞開頭,例如「匯出 CSV」「建立分享連結」「刪除任務」,讓使用者在執行以前就知道會發生什麼。

命令若需要等待,還要交代執行中、成功、失敗與能否重試。選單在點擊後收起,不代表工作已經完成;長時間匯出若沒有狀態回饋,使用者很容易再按一次,最後得到兩份報表和一份困惑。

接著才判斷命令應從哪裡被找到:

使用者當下正在做什麼 適合的入口 需要守住的規則
第一次使用後台,從看得見的操作開始 Menu Button/清楚命名的 Dropdown Menu 觸發按鈕先交代這組命令的目的。
正在處理某一筆任務 Overflow Menu/Context Menu 命令貼著目前物件,不能讓人猜作用對象。
每天反覆使用跨區域功能 Command Palette 快捷鍵負責加速,畫面仍保留可發現入口。
正在設定狀態或篩選條件 Select 選取後留下目前值,不會立即執行列命令。

命令元件與資料選擇元件的選型地圖

圖 4:先分資料值與命令,再判斷命令屬於明確目的、目前物件、次級操作,還是高頻跨區域工作。

這張圖不是要把五種 Menu 全部裝進同一頁。它的作用是排除:先確認操作結果,再選最接近使用情境的入口。

有明確目的的一組命令:Menu Button 與 Dropdown Menu

Menu Button 先說明目的,打開後才列命令

Menu Button 元件頁使用一顆寫著「匯出」的按鈕。使用者還沒打開選單,就知道裡面是一組匯出命令。

Vibe UI Atlas 的 Menu Button 實際 Demo:由匯出按鈕開啟一組立即執行的指令

圖 5:「匯出」先交代命令目的,打開後才列出 CSV、PDF 等操作。

W3C 將 Menu Button 定義為會開啟 Menu 的 Button。Enter 或 Space 可以打開選單,焦點接著進入項目;按 Escape 關閉後,再回到原本按鈕。觸發按鈕、展開狀態、焦點與選單得一起工作,不是多畫一顆向下箭頭就算完成。W3C WAI:Menu Button Pattern

CSV、PDF 和建立分享連結在這裡都是一次性命令。按下後會開始工作,不會留下「目前選取 CSV」作為表單值。產品若真的要保存預設匯出格式,那是另一個設定欄位,不要順手混進命令清單。

Dropdown Menu 只是外觀稱呼,不能代替內容語意

Dropdown Menu 元件頁示範一張從觸發按鈕附近展開的清單。問題是,Dropdown 只描述外觀和展開方式。

Vibe UI Atlas 的 Dropdown Menu 實際 Demo:從觸發按鈕下方展開相關命令

圖 6:Dropdown Menu 會從按鈕附近展開;需求仍要補上裡面是命令、導覽,還是資料選項。

「幫我做一個 Dropdown」幾乎等於只告訴 AI 盒子怎麼出現。裡面可能是導覽連結、表單選項,也可能是一組命令;三種內容的語意與鍵盤行為都不同。

我會把需求改成:

這是一組立即執行的報表命令,包含匯出 CSV、匯出 PDF 和建立分享連結,不會寫回表單欄位。

多說這一句,AI 就不用從外觀反推功能。若內容其實是前往不同頁面的 Link,也不該硬套命令 Menu,只因為畫面同樣向下展開。

跟著目前物件走的命令:Context Menu 與 Overflow Menu

Context Menu 可以加速,但不能只躲在右鍵裡

Context Menu 元件頁把命令綁在目前任務。對「完成活動頁的無障礙檢查」這筆資料,可以指派負責人、移至封存或複製連結;換到另一個物件,選單內容也可能不同。

Vibe UI Atlas 的 Context Menu 實際 Demo:針對目前任務提供可見與右鍵兩種入口

圖 7:右鍵與可見的「管理此任務」都能開啟相同操作,不用先知道祕密手勢。

瀏覽器的 contextmenu 事件通常由右鍵或 Context Menu 鍵觸發,但不同環境的相容性並不完全一致;觸控裝置與不知道右鍵功能的人,也不會自然發現這條路。MDN:contextmenu event

因此 Demo 保留兩種入口:對任務列按右鍵,或按畫面上看得見的「管理此任務」。在 Windows 測試中,鍵盤使用者聚焦任務列後還能以 Shift + F10 開啟;其他平台就算沒有相同快捷鍵,仍有不靠祕密手勢的路。W3C WAI:Menu and Menubar Pattern

Context Menu 的作用對象也必須明確。使用者從哪一列打開,標題、命令與危險確認就要指向同一筆資料,不能右鍵林子安,最後確認框卻準備刪除上一列。

Overflow Menu 收納次級操作,不是把重要功能藏起來

資料表每列若同時排出編輯、複製、封存與刪除,很快就會長成按鈕展示牆。Overflow Menu 元件頁把次級操作收進三點按鈕,手機上仍保留完整文字。

360px 手機版的 Overflow Menu 實際操作畫面

圖 8:三點按鈕展開後仍顯示完整命令;刪除使用 Danger token,但不讓整列永遠紅通通。

三點圖示本身沒有說明功能,觸發按鈕需要 Accessible Name,例如「更多操作」或更具體的「林子安的更多操作」。

刪除也不用一開始就在資料列上放一顆巨大紅色按鈕。Demo 在 Overflow Menu 裡以 Danger token 標示「刪除任務」;真正點下去後,再顯示包含任務名稱的確認區,並提供取消。紅色負責提醒,確認流程負責阻止手滑。

不過,高頻或主要操作不該只因為版面塞不下就全部丟進三點選單。若管理員每天都要編輯角色,「編輯」可能值得保留成可見操作;Overflow Menu 更適合低頻、次級或需要收納的命令。

跨區域熟手入口:Command Palette 不能成為唯一入口

當命令很多,而且使用者每天反覆操作時,Command Palette 元件頁提供可搜尋的快速入口。建立任務、切換看板檢視與邀請成員,可以用 Ctrl/Cmd + K 後直接輸入名稱。

UI 元件百科的 Command Palette 實際操作畫面

圖 9:面板打開後焦點進入搜尋框,結果列出可執行命令,不是拿來保存的資料選項。

VS Code 的 Command Palette 是很清楚的參考:同一個互動視窗可以執行命令、開啟檔案或搜尋符號。這是產品層級的模式,不是 HTML 或 ARIA 裡一顆裝上就完成的原生元件。Visual Studio Code:Command Palette

這個 Demo 採用「有名稱的 Dialog+搜尋輸入框+單選 Listbox」:

  • 開啟後焦點進入搜尋框。
  • 輸入時回報結果數量。
  • 方向鍵移動目前命令。
  • Enter 執行。
  • Escape 關閉後,把焦點還給原本位置。
  • 搜尋不到時保留查詢文字,並顯示「找不到相符命令」。

Listbox 是這次的實作選擇,不是所有 Command Palette 的唯一結構。結果若包含按鈕、勾選框或其他可互動元件,就不能再假裝每列只是單純 Option;規格要改用能承載那些互動的模式。W3C WAI:Listbox Pattern

不背快捷鍵,我仍然要能執行「邀請成員」

我先從畫面上的「開啟命令面板」按鈕進入,沒有假設每個人都記得 Ctrl/Cmd + K。面板開啟後,焦點直接落在搜尋框;輸入「邀請」,結果數量顯示 1。按 Enter 後,面板關閉,原頁回報:

已執行示範命令:「邀請成員」。

這次操作讓我保留三個判斷:

  1. 新使用者有看得見的入口,快捷鍵只負責加速。
  2. 搜尋結果是「邀請成員」這個動作,不會把資料欄位改成「邀請」。
  3. 執行後要有回饋,使用者才知道 Enter 已經生效。

目前尚未完成正式螢幕閱讀器實聽,尤其是結果集合、目前命令與零結果訊息。畫面只剩一筆結果,不代表輔助科技一定只會讀到一筆,這項限制不能因為 DOM 看起來合理就直接蓋章。

改寫 Prompt:把資料、命令、危險操作與入口拆開

在 LumenDesk 的任務資料表設計選擇與命令操作,請明確區分資料值和指令。

1. 狀態篩選使用 Select,選項為全部、待處理、進行中、已完成。選取後更新篩選結果與目前值;它不是列操作選單。

2. 每筆任務的次級操作使用 Overflow Menu。三點圖示按鈕要有 Accessible Name「更多操作」,選單項目為「編輯任務」「複製連結」「刪除任務」。Enter、Space 或向下方向鍵可開啟,方向鍵移動項目,Escape 關閉並回到三點按鈕。

3. 「刪除任務」使用 Danger token,但只在選單與確認區出現。點擊後顯示「要刪除『完成活動頁的無障礙檢查』嗎?」並提供取消與確認刪除;確認前不得改變資料。

4. 對任務列提供 Context Menu:右鍵可以開啟;Windows 版另外支援 Shift + F10。同時保留可見的「管理此任務」按鈕,讓其他平台、觸控裝置與不知道快捷鍵的人也能進入。

5. 加入 Command Palette。Ctrl/Cmd + K 和「開啟命令面板」按鈕都可開啟有名稱的 Dialog;焦點先進入有 Label 的搜尋框,可搜尋建立任務、切換看板檢視、邀請成員。結果使用單選 Listbox,顯示並宣告結果數量與目前 Option;方向鍵移動目前命令、Enter 執行、Escape 關閉並回到開啟位置。零結果時保留查詢字串並顯示「找不到相符命令」。

6. 命令若需要等待,執行中要阻止重複觸發;成功或失敗後在原工作區提供可理解的結果與重試方式。

360px:整頁不可水平溢出;三點選單保留完整命令文字,不能只剩圖示,也不能只靠右鍵入口。

這份 Prompt 沒有規定三點要橫著還是直著。使用者按下去之後會發生什麼,遠比三點的站姿重要。

第二版不只要能打開選單,還要走完五條路

路徑 實際操作 必須看見的結果
新手路徑 用 Enter 或向下方向鍵打開「匯出」Menu Button,再按 Escape。 選單可讀、方向鍵可移動,焦點回到原按鈕。
目前物件路徑 在 Windows 對任務列按 Shift + F10;再從該列 Overflow Menu 選擇刪除。 不用滑鼠右鍵也能開啟 Context Menu;確認區顯示正確任務名稱與取消按鈕。
熟手路徑 按 Ctrl/Cmd + K 搜尋「邀請」,接著搜尋不存在的命令。 Enter 可執行可讀結果;零結果有訊息,Escape 能離開。
資料值路徑 在狀態 Select 選「進行中」。 只更新篩選值,不執行列操作。
窄螢幕路徑 在 360px 開啟三點選單與 Command Palette。 完整文字可讀,整頁沒有水平捲軸。

實際操作後,Menu Button 可以用方向鍵移動;Windows 測試中的 Context Menu 能以 Shift + F10 開啟,按 Escape 後回到可見入口;Overflow Menu 選刪除時,會先顯示任務名稱與取消;Command Palette 輸入「邀請」後只剩一個命令,Enter 執行並回報結果。狀態 Select 則只更新篩選值,沒有再把「進行中」和「刪除」當成同一類選項。

這些項目在目前操作流程中通過。仍未驗證的是正式螢幕閱讀器實聽結果集合與目前命令,以及 200% 縮放;不能因為畫面有 ARIA 屬性、寬度看起來足夠,就直接補上一個通過。

命令終於分家,下一個箭頭卻把備註也當成孩子

現在,狀態 Select 只保存篩選值;編輯與刪除進入 Overflow Menu;跟著任務走的命令可以從 Context Menu 開啟,也保留可見入口;跨區域的高頻工作才進 Command Palette。危險操作不再混進一般選項,熟手與新手也各自有找得到命令的路。

我接著用 Command Palette 打開「檢視專案結構」。畫面出現箭頭和縮排,展開「設計系統」後,有時看到的是子專案,有時卻只是同一列的備註。

專案結構的錯誤第一版:子專案、備註與附件都被縮排成相同的孩子節點

圖 10:設計系統組展開後有三個「孩子」,其中只有元件盤點計畫是真正的子專案;備註與附件只是同一筆資料的明細。

箭頭沒有壞,縮排也很整齊。麻煩在於畫面把三種不同關係都算成下一層,使用者只能讀完文字後,自己判斷眼前的是子專案、備註還是附件。

明天就來拆開 Tree View、Nested List、Treegrid 與 Expandable Row,看看展開後出現的到底是孩子,還是原本那筆資料的更多明細。

延伸閱讀

資料查閱:2026-08-07。


上一篇
Day 15|同一區域怎麼切換內容?Tabs、Accordion、Disclosure 與 Segmented Control
下一篇
Day 17|資料有層級時,別只用縮排:Tree View、Nested List、Treegrid 與 Expandable Row
系列文
看得懂、叫得出、驗得過:30 天 VibeCoding UI 元件實戰23
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言