Sites Breadcrumbs
Visual basis: vortex-1.0 — verify behavior / copy / structure, not pixel style.
Why we're building this
Several surfaces must show where a device lives — its site and area path — in a space too narrow for the full path: a Device Picker result row, a Customized View edit-mode camera, the Alarm source list. They should answer it the same way: a single-line breadcrumb, truncated by one shared rule when it doesn't fit.
Documenting that rule once, as a convention keeps every consumer consistent and gives QA one contract to verify.
截斷規則
一個 device 的所在位置以 site 路徑呈現:從根層一路接到最末層(該 device 所屬的 site / area)。當容器夠寬就完整顯示;不夠時,依固定優先序逐步截斷,直到放得下。
真實範例(以 Device Picker 結果列為例)—— 裝置依所屬 site 分組,每組上方一條 breadcrumb 標頭:
優先序 Priority
由高到低(越高越不會被截斷):
- 最後一層(當前 site / 葉) — 永遠完整顯示,不截斷。
- 第一層(root branch) — 盡量完整顯示。
- 倒數第二層 — 次優先。
- 中間層級 — 最先被截斷。
截斷步驟 Steps
逐步執行,直到內容放得下容器寬度:
| 步驟 | 動作 | 範例 |
|---|---|---|
| 0 | 全部顯示 | USA branch > San Francisco > East area > Building-A > Basement |
| 1 | 中間層級名稱以 ellipsis 截斷(每個上層最小寬度 40px) | USA branch > San Fran… > East a… > Building-A > Basement |
| 2 | 將最低優先的中間層折疊為「…」(從第二層開始折疊) | USA branch > … > East area > Building-A > Basement |
| 3 | 繼續折疊更多中間層 | USA branch > … > Building-A > Basement |
| 4 | 極端情況:只保留 root + 當前 | USA branch > … > Basement |
細節 Details
- 步驟 1 的 40px 是下限,不是上限。 中間層按比例壓縮——各層依「自身自然寬與 40px 的差距」分攤需要縮減的量,任何一層都不低於 40px。所以同一個狀態下各層寬度通常不同(上表步驟 1 的
San Fran…與East a…長度不同,即為此)。把每個被壓縮的層硬切成固定 40px 會讓它們一樣寬,是錯的:那會在空間還夠時就把名稱砍到只剩四個字。 - 壓縮是連續的:從自然寬一路壓到 40px 下限都屬於步驟 1。只有在所有中間層都已觸底、仍放不下時才進入步驟 2 的折疊。
- 最末層(葉) 永遠以粗體白色顯示、不設寬度上限、永不截斷(葉的區別在顏色,不是更粗)。
- 根層與中間層為灰色,以「>」分隔符相接。
- 折疊符「…」不可點擊。折疊符本身與短名稱不受 40px 下限約束(下限只約束「被壓縮的層」)。
完整路徑 tooltip Full-path tooltip
由整條 breadcrumb 承載。 hover 該區域任一處都顯示完整路徑——包含各層、分隔符「>」、片段之間的空隙,以及該區域右側的留白。
內容一律是整條路徑,不因游標落在哪一段而不同。不採「hover 單一層只顯示該層名稱」——那會讓同一個動作依落點給出不同結果。
完全沒有被縮寫時不顯示。 顯示一份與畫面上完全相同的內容是噪音。
「被縮寫」有兩種,兩者都要顯示 tooltip:中間層被折疊成「…」,或未折疊但有層級被壓縮到窄於自然寬。
tooltip 本身是共用元件,所有場景的樣式與定位一致:
surface/07底、text/01白字、12px Regular(400)、1pxoutline/04邊框、4px 圓角、內距 8×12、最大寬度 320px(超出即換行)、不吃滑鼠事件。定位在游標下方 24px、水平居中,並向視窗兩側各留 8px 邊界。不使用瀏覽器原生title—— 那的長相由作業系統決定,且有數百毫秒延遲,與產品樣式無關。
觸發範圍之所以是整條而非折疊符:折疊符只有約 12px 寬,是整條 breadcrumb 裡最難命中的目標,而它恰好是唯一能讀到完整路徑的入口;只有壓縮、沒有折疊時更是完全沒有入口。
- 分隔符「>」為 12×12 的 icon,不隨空間壓縮。
- 整條不換行;超出容器範圍即依上表逐步截斷。
驗收條件 QA · Given-When-Then
- Given 容器寬度足夠,Then 完整顯示整條 site 路徑,不截斷。
- Given 空間不足,Then 依優先序截斷:最末層與根層保留最久,中間層最先被縮短 / 折疊。
- Given 空間略微不足且有多個長度不同的中間層,Then 各層按比例壓縮、寬度彼此不同,且都寬於 40px(不是全部切成 40px)。
- Given 空間持續縮小,Then 中間層寬度單調遞減至 40px 為止;所有中間層都觸底後才折疊為「…」。
- Given 倒數第二層,Then 在尚未進入折疊前不被壓縮(次優先於根層與葉)。
- Given 最末層(葉),Then 永遠完整、以粗體白色顯示、不設寬度上限。
- Given 中間層被折疊為「…」,Then 該符號不可點擊。
- Given breadcrumb 有任何縮寫(折疊或壓縮),Then hover 該區域任一處都顯示完整路徑 tooltip,內容不隨游標位置改變。
- Given breadcrumb 完整顯示得下,Then hover 不顯示 tooltip。
- Given 任何情況,Then 整條不換行。
使用場景
同一條截斷規則(見 Section 01)套用在五個需要以 breadcrumb 顯示 site/area 路徑的地方。場景 1、2、5 有 key screen;場景 3、4 沒有出圖,開發時直接沿用其他場景的規則實作。
1 · Customized View(編輯模式)
在自訂 View 的編輯模式裡,每個 Camera 以 breadcrumb 標示它所屬的 site 路徑,方便使用者 在多站環境下辨識來源。
2 · Device Picker 結果列
Device Picker 右側結果清單依所屬 site 分組,每組上方一條 breadcrumb 標頭(見 Section 01 的截圖)。這是本規則最完整、可直接對照的實例。
詳細結構見 Design Pattern: Device Picker 的「結果清單」一節。
3 · Alarm · Select sources(無 key screen)
System > Alarm > Select sources 透過 Device Picker 挑選來源,選定後的裝置清單同樣以 by-site breadcrumb 呈現。此頁沒有專屬 key screen;開發時直接沿用場景 1、2 的規則。 因此 QA 驗收此頁時,以 Section 01 的截斷規則為準,而非比對截圖。
以截斷規則為準:本頁無 key screen,行為以 Section 01 的規則定義為契約。
4 · User 權限的 Site 清單(Manage Device Access dialog 開啟前,無 key screen)
從 VORTEX Users 進入某位 User 的 detail 頁,此頁列出該 User 有權限的 site 清單,每個 site 以 by-site breadcrumb 標示其所屬路徑。有權限的 device 不在此層顯示——需再進入下一層(點擊展開顯示或開啟 dialog,以當前實作版本為準)才列出。此畫面出現在 Manage Device Access(MDA)dialog 開啟之前。此頁沒有專屬 key screen;開發與 QA 驗收皆以 Section 01 的截斷規則為準,而非比對截圖。
dialog 內部也套用 Section 01 的截斷規則(2026-08-08 更新):MDA dialog 右面板的 site / area 列名與 drill-in 的 area header 都顯示完整路徑並依可用寬度漸進式截斷,連續被折疊的層合併成單一折疊符。唯一例外是 dialog 內的
Review Changes清單——它的Site / Area欄刻意維持「只顯示最末層 + hover 看完整路徑」,因為該欄與Device type欄共用寬度,放 breadcrumb 會被截到失去意義。細節見 Manage Device Access by Site。前一版此處記的是「dialog 內部不一樣(只顯 leaf)、與 Section 01 無關」,那是 dialog 尚未採用本規則時的狀態,已不成立。
以截斷規則為準:本頁無 key screen,行為以 Section 01 的規則定義為契約。
5 · Manage Device Access dialog 內部(2026-08-10 新增)
MDA dialog 內有兩處採用本規則、兩處刻意不採用。這是本規則第一次用在「使用者正在編輯的那一列」 上,而不是唯讀的清單。
採用(都遵循 Section 01 的截斷規則):
- 右面板的 site / area 列名 —— 每一列顯示該節點的完整路徑。理由是不同分支常有同名節點
(
Floor 1、Lobby),而這一列就是實際指派權限的地方,挑錯節點的代價最高;左側 sidemenu 雖然 呈現階層,但只對游標所在的那一個節點有效,不是正在編輯的這一列。 - drill-in 的 area header 列 —— 規則與右面板列名相同(共用同一個實作),差別只有可用寬度,而且差距很大:drill-in 會把整個左側 sidemenu 收掉、單欄佔滿 body,該列本身就從 716px 變成約 1036px;再加上此處沒有 chevron 欄 (省下 32px 按鈕 + 16px 間距),breadcrumb 的可用寬度大約從 420px 變成 790px。因此同一個節點在 drill-in 往往完整顯示,在右面板卻已被折疊 —— 依本 deck 推算截斷階梯時要用各自的可用寬度,不能共用一個數字。
刻意不採用(Review Changes 內的兩處):
Site / Area欄 —— 維持「只顯示最末層 + hover 看完整路徑」。該欄與Device type欄共用寬度, 放 breadcrumb 會被截到失去意義,而 hover 的完整路徑已提供同樣的資訊。- device 群組的 sub-header —— 同樣只顯示最末層 + hover 路徑(游標變 help)。
兩處都是有意的差異,不是遺漏。
完整規格(含各列尺寸、dropdown、chevron)見 Manage Device Access by Site; 本節只記錄「哪裡套用本規則、哪裡不套用」。
hover 目標範圍在所有場景一致: 由整條 breadcrumb 承載完整路徑 tooltip、未縮寫時不顯示,規則見 Section 01。本節各場景沒有例外。
Site 階層的另一種呈現
Breadcrumb 是壓成一行的線性路徑。Site 階層還有可展開的樹狀呈現(初始展開層級、 全部展開 / 收合、搜尋自動展開匹配路徑),其唯一權威定義在 Design Pattern: Tree View,此處不重述。
驗收條件 QA · Given-When-Then
- Given Customized View 編輯模式,Then 每個 Camera 以 by-site breadcrumb 標示來源,且套用 Section 01 的截斷規則。
- Given Device Picker 結果列,Then 裝置依 site 分組、每組一條 breadcrumb 標頭,套用 Section 01 的截斷規則。
- Given Alarm · Select sources 的裝置清單,Then 以 by-site breadcrumb 呈現,行為以 Section 01 的規則為準(無 key screen)。
- Given User detail 頁(Users → 某位 User,Manage Device Access dialog 開啟前)的有權限 site 清單,Then 每個 site 以 by-site breadcrumb 標示路徑,套用 Section 01 的截斷規則;有權限的 device 於下一層(點擊展開顯示或開啟 dialog)才顯示(無 key screen)。
- (場景 5)Given MDA dialog 右面板的 site / area 列名,Then 顯示完整路徑並套用 Section 01 的截斷規則;連續被折疊的層合併成單一折疊符。
- (場景 5)Given MDA dialog 的 drill-in area header,Then 規則與右面板列名相同,僅可用寬度較寬(該處無 chevron 欄)。
- (場景 5)Given MDA dialog 的
Review Changes清單,ThenSite / Area欄只顯示最末層、路徑改由 hover 提供——這是本規則在 dialog 內唯一的刻意例外。 - (場景 5)Given MDA dialog 內某列的路徑被縮寫,Then hover 該 breadcrumb 的任一處都顯示完整路徑;完全未縮寫時不顯示(與 Section 01 現行的「折疊符承載 tooltip」不同,該差異待決,見 Section 01)。