Astro UI 模式與可攜式元件庫 是做什麼的?
此指南定義了 Astro 網站的可攜式、即用型 UI 元件標準化目錄。
獨立範例使用可攜式元件模型:零外部 npm 依賴、零客戶端框架執行環境(無 React/Vue)、具有內建備援的名稱空間 CSS 代碼,以及漸進式增強。在框架專案中,保留語意和互動需求,同時調整組合和樣式以符合所選合約。在渲染的專案中驗證無障礙性;單純的樣板並不能確保符合 WCAG 標準。
行為合約與框架組合
對於下方索引中的元件,請使用其語意與互動合約: 鍵盤支援、焦點管理、原生元素、可存取名稱、狀態更新 以及漸進式增強。所選的專案/框架合約負責管理樣式、 代碼、匯入和元件組合。使用者指示仍具有權威性。
範例使用下方的獨立可攜式元件模型。在沒有框架組合合約的情況下 新增獨立元件時使用此模型。當專案已有 已建立的函式庫時,請改為使用其適當的基礎元件來調整行為, 而不是複製其按鈕、標題或表單控制項。保留所需的語意 和行為,同時調整範例的包裝器和類別。
對於建構在元件框架(例如 Lumos)上的專案,請使用該框架的 組合與樣式;可以匯入其基礎元件。獨立的零網站匯入 規則和名稱空間備援代碼不會覆蓋所選框架自身的合約。
可攜式元件模型
對於獨立的可攜式元件,請使用這五個規則。在選定的框架上,保留行為要求並遵循其組合/樣式合約,如上所述:
- 零外部/網站匯入:元件檔案不得匯入網站佈局、按鈕或第三方客戶端 UI 函式庫。唯一列出的例外是 SelfHostedMap,它需要地圖渲染器和圖磚讀取器;其規格列出了套件,且僅在獲得擁有者批准後才會安裝。
- 具有備援值的名稱空間 CSS 變數:切勿在元件樣式表中直接引用主機代碼(例如
var(--color-brand))。始終使用var(--comp-property, <fallback>)寫法。 - 作用域 BEM 與 CSS 邏輯屬性:使用 BEM 類別命名(
.c-theme-toggle、.c-accordion__summary)和邏輯屬性(inline-size、block-size、padding-inline、margin-block)。 - 冪等原生漸進式增強:腳本必須在載入時執行,並且在 Astro 視圖轉換啟用時能乾淨地重新附加(
document.addEventListener('astro:after-swap', init))。 - 觸控目標與 ARIA:按鈕和互動控制項必須具有最小
44px(2.75rem)或48px(3rem)的觸控目標、適當的 ARIA 狀態(aria-expanded、aria-selected、aria-pressed、aria-controls)以及鍵盤焦點環。
元件索引
| 元件 | 規格檔案 | 用途 | 主要合約 |
|---|---|---|---|
| 1. ThemeToggle | components/theme-toggle.md | 無 FOUC 且具 SVG 變形的淺色/深色主題切換器 | <head> 內嵌腳本 + OKLCH 代碼映射 |
| 2. MobileNavDrawer | components/mobile-nav-drawer.md | 具有動畫漢堡選單的無障礙滑出式導覽抽屜 | 48px 觸控目標、Escape 鍵關閉、無 GPU 模糊延遲 |
| 3. SearchBar | components/search-bar.md | 具有清除按鈕和即時朗讀器的客戶端搜尋輸入框 | rAF 防抖(最佳 INP)、aria-live、自訂事件協調器 |
| 4. FilterChips | components/filter-chips.md | 具有無障礙按下狀態的多類別膠囊篩選列 | role="group"、aria-pressed、自訂事件協調器 |
| 5. SearchFilterBar | components/search-filter-bar.md | 結合 SearchBar 和 FilterChips 的複合模式 | 預先組合的堆疊工具列、多欄 flex 佈局、共享範圍 |
| 6. AccessibleModal | components/accessible-modal.md | 使用原生 HTML5 <dialog> 的無障礙對話框覆蓋層 | 原生頂層、背景點擊、Escape 鍵、焦點恢復 |
| 7. AccessibleAccordion | components/accessible-accordion.md | 具有平滑 CSS 網格展開的原生常見問題/手風琴 | 原生 <details name="...">、0 KB JavaScript |
| 8. AccessibleTabs | components/accessible-tabs.md | 用於定價層級或多面板檢視的 WAI-ARIA 分頁切換器 | 鍵盤方向鍵導覽(Left/Right/Home/End) |
| 9. SocialShare | components/social-share.md | 使用 Web Share API 的隱私優先社交分享列 | 100% GDPR 安全、0 追蹤器、靜態意圖 URL |
| 10. TableOfContents | components/table-of-contents.md | 具有滾動監測的長篇目錄 | IntersectionObserver 標題追蹤、與文章佈局配對 |
| 11. AccessibleCarousel | components/accessible-carousel.md | 適用於評論、卡片或標誌的原生 CSS 滾動貼齊滑塊 | 原生觸控滑動(0 KB JS)、無障礙的上/下一頁按鈕 |
| 12. InfiniteTicker | components/infinite-ticker.md | 純 CSS 無限標誌/文字跑馬燈,懸停/聚焦時暫停 | 符合 WCAG 2.2.2、使用 aria-hidden 隱藏重複軌道 |
| 13. StatsCounter | components/stats-counter.md | 具有緩出滾動動畫的 HTML 優先統計計數器列 | 0 CLS、靜態 HTML 備援、IntersectionObserver |
| 14. AddToCalendar | components/add-to-calendar.md | 連結到建置時 iCalendar 檔案的「儲存日期」 | 同源靜態 .ics + <a download>、有效的 RFC 5545、0 KB JS |
| 15. SelfHostedMap | components/self-hosted-map.md | 根據自託管 PMTiles 提取的清單中地點地圖;編號圖釘符合清單 | 延遲加載 MapLibre、HTTP 206 圖磚路由、帶文字替代的 aria-hidden 地圖、遵循主題。需要 npm 套件(擁有者批准) |
| 16. ClickableParent | components/clickable-parent.md | 透過一個真實連結或按鈕使整個卡片/列可點擊 | ::after 拉伸點擊區域、次要控制項提升、容器上的焦點環、0 KB JS |
| 17. Card | components/card.md | 帶有媒體、元資料、主體和次要動作的內容卡片 | 標題優先 DOM、headingLevel 屬性、容器查詢佈局、連結時的 ClickableParent 合約 |
未目錄化元件決策關卡(人為決策點)
當專案需求或設計要求一個不屬於上述 17 個目錄化元件的互動式 UI 元件時(例如:前後對比圖片滑塊、日期選擇器、範圍選擇器、步驟精靈或自訂媒體播放器):
[!IMPORTANT] 停止並詢問:代理人絕不能靜默安裝客戶端框架函式庫(React、Vue、Svelte)、匯入未經審查的第三方 npm 套件,或留下暫存文字佔位符區塊(例如
<div class="c-placeholder">)。代理人必須暫停並向專案擁有者呈現三個不同的選項:
- 選項 A:自訂原生元件(推薦):根據下方的自訂元件備援合約,編寫一個無依賴的
.astro元件。- 選項 B:靜態 HTML 基準:實作一個純靜態的語意佈局(例如並排圖片或標準堆疊卡片),使用 0 KB JavaScript,完全省略互動增強。
- 選項 C:目錄模式改編:評估現有的目錄模式是否能滿足需求(例如將
AccessibleModal改編為圖片燈箱,或將AccessibleTabs改編為步驟面板檢視)。
自訂元件備援合約
當專案擁有者批准建構未目錄化元件(選項 A)時,實作必須滿足以下六個規則;對於框架改編,請針對第 3-4 項使用該框架的組合、類別命名和代碼規則:
- 語意 HTML 優先:在編寫 JavaScript 之前,先將介面錨定到標準 HTML 元素(例如滑塊使用
<input type="range">、揭露使用<details>、覆蓋層使用<dialog>)。 - 零外部執行時期依賴:零客戶端框架執行環境(無 React/Vue)和零第三方 UI 小工具套件。僅在真正需要瀏覽器互動時,才編寫原生純 TypeScript/JavaScript。
- 作用域 BEM 與 CSS 邏輯屬性:使用標準 BEM 命名(
.c-block、.c-block__element)和流動相對佈局屬性(inline-size、block-size、padding-block、margin-inline、inset)。 - 具有備援值的名稱空間代碼:切勿硬編碼十六進位值。使用主機語意代碼或具有合理備援的名稱空間自訂屬性(
var(--comp-color, var(--color-primary)))。 - 無 JS 漸進式增強:當客戶端 JavaScript 停用時,元件必須保持清晰可讀、可存取且可操作。使用
@media (scripting: none)或原生 CSS 備援佈局(例如並排或堆疊檢視),以便不隱藏任何內容。 - 符合 WCAG 2.2 AA 標準:維持最小
44px(2.75rem)的觸控目標、高對比度的可見:focus-visible環、清晰的可存取名稱(aria-label、<label>),並確保 0 個 axe-core 違規。
代理人選擇性載入指南
當使用者要求實作或編輯上述元件之一時,不要讀取整個目錄。相反地,僅讀取所需的特定元件檔案(例如 components/accessible-carousel.md)。
整合驗證
在構建/部署的輸出上驗證所選規格:語意和名稱、鍵盤/焦點行為、 狀態轉換、無 JS 處理、重複初始化以及主機代碼映射。獨立 封裝規則僅適用於獨立元件;框架重複使用其基礎元件。 執行專案配置的檢查/建構/測試,並揭露任何不可用的檢查或覆蓋範圍缺口。 44px 是此函式庫的目標大小約定,而非 WCAG AA 門檻本身。
除非擁有者批准自訂組合框的權衡取捨,否則原生 select 彈出視窗仍為瀏覽器/作業系統 UI。