iT邦幫忙

2026 iThome 鐵人賽

DAY 17
0
Vibe Coding

別再只叫 AI 做漂亮一點:30 天 Vibe Coding UI 元件驗收實驗系列 第 17

Day 17|資料有層級時,別只用縮排:Tree View、Nested List、Treegrid 與 Expandable Row

  • 分享至 

  • xImage
  •  

Day 17|資料有層級時,別只用縮排:Tree View、Nested List、Treegrid 與 Expandable Row

安安~我是ChiYu~

昨天把資料值和命令分開後,我從 Command Palette 執行「檢視專案結構」。AI 很快交出一張有箭頭、有縮排,點下去也會展開的畫面。

昨天結尾先停在這個錯誤現場。這張圖是依照第一版問題重建的畫面,不含真實資料:

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

圖 1:和昨天結尾是同一張畫面。元件盤點計畫、專案備註與附件共用相同箭頭和縮排,全被算成設計系統組的孩子。

乍看就是一棵樹。

再看仔細一點,子專案、附件、檢核紀錄和備註全部都住在下一層。只要往右縮排兩格,任何資料突然都能變成孩子。

原始需求確實留了很大的發揮空間:

「請把部門、專案和任務做成樹狀,點開後可以看細節。」

部門底下有專案,這是父子關係;任務底下顯示一段備註,卻只是同一筆資料的補充。兩者都能使用箭頭展開,操作意義完全不同。Vibe Coding 若只說「做成樹狀」,AI 多半會先完成箭頭和縮排,至於展開後到底是下一層還是更多明細,就看畫面怎麼塞得下。

今天要把 Tree View、Nested List、Treegrid 與 Expandable Row 分開。它們都能表達某種層次,選型依據不是箭頭長什麼樣,而是資料之間到底有沒有父子關係。

我把四種做法放進 Vibe UI Atlas 的階層資料比較頁。先看同樣的縮排和展開動作,在不同資料關係下會變成什麼元件。

階層資料元件比較頁:先判斷展開的是子節點、內容層次、多欄資料或同列明細

圖 2:箭頭只說「這裡可以展開」,沒有回答展開的是孩子資料,還是目前這列的補充。

這一題沒有先講清楚,後面不管叫 AI 做 Tree View 還是 Treegrid,都只是在替錯的資料關係挑造型。

展開項目有自己的身分,還是只在解釋目前這列?

我會先拿 LumenDesk 的「產品與設計中心」做測試。它底下有產品策略組、設計系統組,每個組別再包含各自的專案。展開設計系統組後,才看得到「元件盤點計畫」。這些資料有真正的父子關係,適合 Tree View。

另一邊,專案任務表裡有一筆「活動頁無障礙檢查」。按下「檢核明細」後出現完成項目、備註與附件。那些內容無法離開這筆任務獨立存在,它們只是同一列的更多資訊,Expandable Row 會比較直白。

判斷時,我不再只問「刪掉目前這列後,展開內容還在不在」。有些系統會連孩子一起刪除,光靠刪除結果,很容易把真正的父子資料也誤判成明細。

我會改問兩件事:展開項目有沒有自己的識別、狀態與生命週期?它能不能在其他流程中被搜尋、選取或移動?如果答案是可以,而且確實隸屬於目前節點,通常是父子資料。若內容只用來解釋這筆任務,離開目前列就沒有獨立意義,多半是明細。

刪除測試仍可當輔助證據,只是不再一題定生死。資料模型如果本來就設定串聯刪除,它可不會好心提醒我「孩子其實有身分」。

再加上「需不需要比較多欄資料」,四種元件就能排回自己的位置:

資料關係 使用者真正要做的事 適合的元件
部門底下有小組,小組底下有專案 逐層走進真正的孩子資料 Tree View
文件有章節、子章節與條列內容 順著閱讀順序理解內容層次 Nested List
專案有子任務,也要比較負責人、狀態與截止日 展開階層,同時對齊多欄資料 Treegrid
任務列下面顯示附件、備註與檢核紀錄 暫時查看同一筆資料的補充 Expandable Row

如果習慣看流程圖,也可以從這張選型地圖開始:

依資料關係與欄位需求選擇階層資料元件

圖 3:先判斷是不是父子資料,再問要不要對齊多欄;沒有互動需求時,Nested List 已經夠用。

箭頭放左邊還是右邊可以晚點決定。先把這張關係卡交給 AI,畫面才不會把備註硬認成子專案。

Tree View:焦點、選取與展開是三種不同狀態

Tree View 元件頁示範部門、群組與專案的父子關係。父節點可以展開,葉節點則沒有下一層。

Vibe UI Atlas 的 Tree View 實際 Demo:已選取節點、鍵盤焦點與展開狀態分開呈現

圖 4:焦點表示鍵盤目前會操作哪裡,選取表示已保存的節點,展開則控制孩子是否可見。

Tree View 適合資料夾、組織、分類與專案群組。它真正麻煩的地方不是縮排,而是焦點、選取和展開很容易被 AI 合成同一個藍色底。

焦點是鍵盤下一步會作用的位置;選取是使用者已經選定的資料;展開只表示孩子目前看不看得到。W3C 的 Tree View Pattern 把焦點與選取視為不同概念,但也允許部分單選 Tree 使用「焦點跟著選取」;多選 Tree 則必須把兩者分開。W3C WAI-ARIA APG:Tree View Pattern

LumenDesk 這次刻意選擇分離模式,因為管理員要先用方向鍵查看其他節點,再決定是否改變目前專案。方向鍵只移動焦點,Enter 才執行目前節點的預設動作;在這個單選 Demo 裡,葉節點的預設動作是選取,父節點則交給左右方向鍵展開或收合。這是本案例的互動合約,不是所有 Tree View 都必須照抄。

你可以直接到 Tree View 操作 Demo先選一個專案,再按方向鍵。焦點移走後,原本選取的專案應該留下;收合父節點時,焦點也不能掉在已經看不見的孩子身上。

第一輪實測:方向鍵通過,摘要卻只剩一個菱形

2026 年 7 月 24 日,網站初始選取「LumenCore 平台」。我把焦點放到這個節點,再按 Arrow Down,焦點移到下一筆「行動應用程式」,aria-selected 仍留在 LumenCore。

這一段符合預期:焦點只是準備操作的位置,選取才是已保存的結果。

但頁面下方的摘要從「目前選取:LumenCore 平台」變成「目前選取:◇」。它抓到的是圖示文字,不是節點名稱;瀏覽器 Console 同時出現三筆 SVG viewBox 格式錯誤。

所以第一輪只能拆開判斷:

檢查項目 2026 年 7 月 24 日結果 當時判斷
Arrow Down 移動焦點 焦點移到下一個可見節點。 通過。
選取是否跟著焦點改變 LumenCore 仍維持選取。 通過。
選取摘要 顯示成「◇」。 未通過,節點名稱取值錯誤。
Console 出現三筆 SVG viewBox 錯誤。 未通過,圖示輸出需要修正。

如果我只看箭頭有沒有開合,這兩個 bug 都會被放過。寫 Prompt 時除了鍵盤規則,還要交代選取資料從哪個欄位取得、摘要顯示哪個名稱,最後再打開 Console 看一眼。畫面會動,只代表它真的會動。

修正後複測:摘要和 SVG 錯誤已經排除

後續修正把摘要改成讀取真正的節點名稱,也替五個展開圖示補上 viewBox="0 0 24 24"

2026 年 7 月 27 日重新載入後,選取摘要會顯示節點名稱,Console 不再出現 SVG 格式錯誤;用方向鍵移動焦點時,原本的選取狀態也會保留。

目前已通過節點名稱、焦點/選取分離與 Console 複測。正式螢幕閱讀器實聽仍未完成,所以文章不會把「鍵盤操作正常」直接寫成所有輔助科技都通過。摘要顯示「◇」和三筆 Console 錯誤是歷史上曾失敗的結果,並不是目前仍存在的問題。

層級如果深到使用者一直展開、展開、再展開,也別急著繼續美化 Tree View。那可能是資訊架構需要搜尋、篩選、Breadcrumb 或獨立詳細頁,不是再多縮排兩格就能救回來。

Nested List:內容有層次,不代表一定要操作一棵樹

文件目錄、條款清單與靜態分類說明也有層次,但讀者通常只想順著內容往下讀。Nested List 元件頁保留標題與縮排,不另外加入展開控制。

Vibe UI Atlas 的 Nested List 實際 Demo:保留內容層次,不額外加入展開控制

圖 5:整個內容結構一次呈現,沒有目前選取、展開狀態與方向鍵走訪。

原生巢狀 <ul> 已經能表達未排序內容的階層關係。沒有「逐層操作資料」的需求時,清單語意與視覺縮排就足夠。MDN:<ul> HTML element

你可以在 Nested List 操作區看到它幾乎沒有什麼好操作。這反而是它的優點:少一個展開按鈕,就少一組狀態、焦點和例外狀況。

當 AI 自動替每個章節加上箭頭時,先問使用者是否真的需要收合。若目的只是讓段落看得出層級,Nested List 已經完成工作,不用強迫一份靜態目錄學會走路。

Treegrid:階層之外,還要同時比較多欄資料

如果使用者除了專案名稱,還要比較負責人、狀態與截止日,單純的 Tree View 就不夠用了。Treegrid 元件頁把階層放在第一欄,其餘欄位維持對齊。

Vibe UI Atlas 的 Treegrid 操作區:第一欄管理階層,其他欄用來比較資料

圖 6:第一欄展開專案與子任務,負責人、狀態和截止日仍能沿欄位比較。

Treegrid 的功能很完整,維護成本也最高。它同時處理表格、焦點移動、列選取、展開收合與手機欄位策略。W3C 將 Treegrid 定義為具有階層關係的資料格狀介面,鍵盤焦點可能停在列或儲存格上,互動規則得先決定清楚。W3C WAI-ARIA APG:Treegrid Pattern

若需求只是找到某個資料夾,我不會因為 Treegrid 看起來很像企業系統就選它。反過來,真的需要比較多欄時,也不要把狀態和日期全塞進 Tree View 的節點名稱。

Treegrid 操作 Demo裡,只有第一欄縮排。窄螢幕時,表格可以在自己的容器內橫向閱讀,整張頁面卻不能跟著左右漂移;若欄位真的太多,摘要或獨立詳細頁往往比把字壓碎更實用。

Expandable Row:展開的是這一列,不是下一代

平面資料表裡,使用者有時只想多看一點目前任務的資訊。Expandable Row 元件頁用「活動頁無障礙檢查」示範檢核進度、備註和下一步。

Vibe UI Atlas 的 Expandable Row 實際 Demo:展開同一筆任務的檢核明細與下一步

圖 7:展開後仍是「活動頁無障礙檢查」這筆任務的內容,沒有憑空長出三個子任務。

Tree View 的箭頭表示往下一層走;Expandable Row 的按鈕則是把這筆資料說得更完整。按鈕名稱、展開狀態與被控制的明細區塊都要能對得起來。Expandable Row 操作 Demo裡的控制項因此會直接說明是在查看這一列的明細。

資料表本身仍要保留表格語意。HTML <table> 用於有列與欄的資料,<caption> 也能幫助使用者理解這張表的用途。MDN:<table> HTML element

收合之後,任務沒有失去孩子,因為它從頭到尾都沒有孩子。它只是把備註收回去了。

改寫 Prompt:先交代資料關係,再決定箭頭怎麼動

這份 Prompt 一次列出 Tree View、Treegrid 與 Expandable Row 的分界,是為了讓 AI 先理解關係。實際畫面只需要其中一種時,就刪掉其餘段落:

請為 LumenDesk 製作「產品與設計中心」的階層資料畫面。

資料關係:部門底下有專案,專案是部門的孩子,不是同一列的補充明細。
元件:使用 Tree View。父節點顯示可展開箭頭,沒有孩子的葉節點不要顯示假箭頭。
狀態:展開/收合、鍵盤焦點、已選取節點必須分開呈現;不要只靠顏色區分。
鍵盤:這個單選 Demo 採焦點與選取分離。Up/Down 只在可見節點間移動焦點;Right 展開或進入第一個孩子;Left 收合或回到父節點;Enter 執行目前節點的預設動作,葉節點的預設動作是選取。不要讓方向鍵經過每一筆時就改寫目前選取。
資料:設計系統組可展開,底下有「元件盤點計畫」;所有人名、日期、專案皆為虛構資料。

如果使用者還要比較負責人、狀態、截止日,請改用 Treegrid:只有第一欄縮排,其他欄保持對齊;手機版可讓表格容器局部橫向捲動,但整個頁面不可水平溢出。

如果只是展開同一筆任務的備註和檢核項目,請改用 Expandable Row,不要把明細偽裝成子節點。

Prompt 裡先寫「專案是部門的孩子」,比寫「箭頭使用 16px 灰色圖示」更能決定畫面會不會走偏。視覺可以再調,資料關係一開始寫錯,後面每一次展開都會繼續錯下去。

驗收階層元件,先別被箭頭會轉騙過去

交付前,我會沿著資料關係和鍵盤狀態逐一檢查:

  • 展開後出現的是孩子,還是目前這列的補充?
  • Tree View 的父節點有展開狀態嗎?沒有孩子的葉節點是否拿掉假箭頭?
  • 鍵盤焦點、選取節點與展開狀態能否分辨?方向鍵移動時,選取值有沒有被偷偷改掉?
  • 收合父節點後,焦點是否仍停在看得見的位置?
  • Nested List 是否只呈現內容結構,沒有多做一組用不到的互動?
  • Treegrid 是否真的需要多欄比較?窄螢幕要局部捲動、顯示摘要,還是前往詳細頁?
  • Expandable Row 展開的是不是同一筆資料的明細?

這份清單沒有檢查箭頭轉得夠不夠滑順。關係、狀態和焦點都正確後,動畫才輪得到上場。

專案結構分清楚後,「漂亮彈窗」卻先替我按了確定

現在,真正的部門、專案與任務父子關係進入 Tree View;需要同時比較多欄時才升級 Treegrid;同一筆任務的備註與檢核紀錄則回到 Expandable Row。Nested List 也不用為了看起來有功能,硬背一整套方向鍵操作。

這幾天,我們讓使用者找得到頁面、看得懂位置、切得開內容、執行得到命令,也能閱讀真正的資料階層。下一步,我按下成員列上的「停用帳號」,只留下另一句很熟悉的需求:

「按停用時跳出一個漂亮的彈窗。」

下面這張圖,是我依照第一版問題在網站上重建的錯誤現場,不含真實帳號與個人資料:

停用帳號的錯誤第一版:白色卡片與灰色遮罩已完成,但停用對象不明、危險動作先取得焦點,背景仍可操作

圖 8:彈窗只問「確定要停用嗎」,沒有說停用誰;初始焦點已經落在「確定」,背景卻仍然能點。外觀完成了,安全退出的規則還沒進場。

白色卡片、灰色遮罩和紅色提示全都到齊,看起來的確很像完成品。問題是,使用者不知道要停用誰、會失去什麼;按下 Escape 會不會取消、關閉後焦點回到哪裡,也沒有答案。更尷尬的是,危險操作先取得了焦點,背景卻還能繼續操作。

明天,我們就從這個彈窗開始,拆開 Dialog、Modal Dialog、Alert Dialog 與 Confirmation Dialog,也看看紅色按鈕出現以前,取消路徑到底有沒有先準備好。

延伸閱讀


上一篇
Day 16|選一個值,還是執行命令?Select、Menu、Overflow Menu 與 Command Palette
下一篇
Day 18|彈窗要不要鎖住背景?Modal、Non-modal、Alert Dialog 與危險確認
系列文
別再只叫 AI 做漂亮一點:30 天 Vibe Coding UI 元件驗收實驗20
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言