跳到主要內容

無障礙存取

@lh-ui/react 與家族其他庫共享同一套無障礙契約:語義化標籤、ARIA 屬性、鍵盤互動全部在 @lh-ui/share/core 內定義,各端實作一致。本庫額外保證 React 生態的常見 a11y 陷阱不出現。

語義與 ARIA​

  • LhSwitch 渲染 <div role="switch" aria-checked>,而非視覺偽裝的 checkbox
  • LhSelect 觸發器為 role="combobox",展開面板為 role="listbox",選項為 role="option",並用 aria-activedescendant 同步鍵盤高亮
  • LhDialog 為 role="dialog" aria-modal,標題同時提供 aria-label 兜底與 aria-labelledby 精確關聯
  • LhTooltip 用 aria-describedby 把提示關聯到觸發器
  • LhTag 可點選時升級為 role="button",並回應 Enter / Space
  • LhFormItem 驗證失敗渲染 role="alert" 錯誤提示,並設定 aria-invalid

鍵盤互動​

元件鍵位
LhButton / LhTagEnter / Space 觸發點選
LhSwitchEnter / Space 切換
LhSelectArrowUp / ArrowDown 高亮選項,Enter 選取,Escape 收起
LhDialogEscape 關閉(僅棧頂彈層回應)
LhTooltipEscape 關閉

多彈層疊加時用 useLhOverlayStack 維護開啟順序棧,Escape 只關棧頂,避免一次按鍵帶走全部彈層。

焦點管理​

  • LhDialog 開啟時用 useLhFocusTrap 把焦點限制在對話框內(Tab / Shift+Tab 不外逃),關閉後焦點歸還觸發器
  • LhFormItem 點選 label 時聚焦內容區首個可聚焦元素(focusControl),原生 label 包裹行為在複合控制項上不可靠

裝飾性圖示​

LhIcon 預設 decorative:輸出 aria-hidden="true",對螢幕閱讀器不可見。需要語義時傳 decorative={false} + ariaLabel:

<LhIcon name="search" decorative={false} ariaLabel="搜索" />

此時渲染 <svg role="img" aria-label="搜索">。

StrictMode 安全​

所有元件在 React StrictMode 下安全:effect 的 cleanup 與重複掛載都做了冪等處理(彈層棧註冊 / 卸載、捲動鎖的持鎖者校驗、focus trap 的釋放)。

家族一致性​

無障礙行為登記在 docs/设计语言基线.md,是雙血脈(web / 原生)的統一契約。各端按同一份 @lh-ui/share/core 邏輯實作,aria 屬性與鍵位語義一致。