跳至主要内容

元件總覽

:::info 內容來源 本頁依 appfuse-web/lib/components/README.md 與套件公開 barrel exports 整理。若名稱或型別有差異,以該版本安裝後的 TypeScript 宣告為準。 :::

AppFuse Web 提供 React 19 元件、react-hook-form 整合層、訊息服務、Hooks 與工具函數。 升級前請先閱讀 Web Changelog;以下清單描述目前發布線的公開介面。

匯入原則

使用功能所屬的公開 subpath,避免依賴套件內部檔案:

import { Button, DataTable, DatePicker, FileDownloadLink } from '@appfuse/appfuse-web/components'
import { Input, Select, validatorResolver } from '@appfuse/appfuse-web/form'
import { schema } from '@appfuse/appfuse-web/form/validator'
import { prompt, MessageToast, MessageDialog } from '@appfuse/appfuse-web/messaging'
import { useTimeout, useInfiniteList } from '@appfuse/appfuse-web/hooks'
import { cn, getApiErrorMessage, time } from '@appfuse/appfuse-web/utils'
  • components:不依賴 react-hook-form 的 UI primitive。
  • form:綁定 controlname 與欄位錯誤的 react-hook-form wrapper。
  • messaging:應用層全域訊息服務與容器。
  • hooksutils:跨元件使用的 Hooks 與工具。

資料輸入與表單

SelectMenuOptionRow 等低階組裝元件外,下表元件同時提供 @appfuse/appfuse-web/components 的 UI 版,以及 @appfuse/appfuse-web/form 的 react-hook-form 版。

元件用途與值契約
Input / Textarea單行與多行文字輸入
Checkbox / CheckboxGroup布林值或多選集合
Radio / RadioGroup單選集合
Switch布林開關
Select單選、多選、搜尋與建立選項
SelectMenu / OptionRow可獨立組裝的選單與 rich option;由 components 匯入
TagInput可建立的多值標籤輸入
RichTextEditor基於 Tiptap v3 / ProseMirror 的富文字編輯器
FileInput / MediaInput檔案與媒體選擇、驗證及預覽
DatePickertype="local-date" 使用 ISO 日期字串;type="instant" 使用 Date
TimePickerLocalTime 語意;表單值為無時區的時間字串
DateTimePickertype="local-date-time" 使用無時區字串;type="instant" 使用 Date

兩個 picker 的 type 都是必填辨識欄位,讓 TypeScript 直接約束 valueonChange 的型別。 Instant 模式預設採瀏覽器時區,時區控制位於月曆標題;LocalDate(Time) 模式不顯示時區。 DatePicker 的 Instant 模式在未提供 instantTime 時正式預設為 start-of-day;改用 end-of-day 或自訂鐘面時間,必須由人類指定,或由 AI 建議並經人類確認。DateTimePicker 編輯後 以分鐘或秒精度重建 Instant,因此不保留毫秒。非法時區、非法 instantTime 與非法 DayStatus.date 會顯示欄位錯誤。

表單驗證

匯入路徑:@appfuse/appfuse-web/form/validator

匯出說明
schema輕量 Schema 建構器
validatorResolverreact-hook-form resolver
mapViolationsToFormErrors將後端 violations 映射為欄位錯誤
createServerErrorHandler建立一致的 Server error handler

詳細用法請參閱表單元件指南

動作與資料顯示

匯入路徑:@appfuse/appfuse-web/components

分類元件說明
ActionsButtonvariant、color、density、loading 與 confirmation
ActionsFileDownloadLink透過應用 HTTP client 下載受保護檔案
Data DisplayBadge狀態或標籤 chip
Data DisplayDataTable傳統分頁與欄位操作
Data DisplayVirtualTable虛擬化表格與無限捲動
Data DisplayVirtualList自訂複合列的虛擬化清單
Data DisplayIconLucide React 圖示包裝
Data DisplayMediaViewer圖片與影片檢視
Data DisplayPdfViewerPDF 預覽、翻頁與縮放
Data DisplayAuthImage透過 HTTP client 載入需授權的圖片

下載受保護檔案

應用層不應直接以 <a href> 下載需要 Bearer token 的 API 檔案;瀏覽器原生導覽不會沿用 AppFuse HTTP client 的 base URL、認證與 401 refresh。改用 FileDownloadLink

import { FileDownloadLink } from '@appfuse/appfuse-web/components'

<FileDownloadLink source={attachment.url} filename={attachment.filename}>
下載附件
</FileDownloadLink>

內部 API URL 會透過應用程式根節點 HttpClientProvider 注入的 client 取得 Blob,再觸發瀏覽器 下載。外部、presigned、blob:data: URL 則直接交由瀏覽器處理,不會附加應用程式的 Authorization header。元件下載期間會自動禁止重複操作,失敗時預設顯示後端錯誤訊息。

若使用者操作的目的其實是頁面導航,仍應使用真正的 <a> 或路由元件。

圖表

匯入路徑:@appfuse/appfuse-web/components

圖表基於 Nivo 並使用 AppFuse 主題配色:

  • LineChartAreaChart
  • BarChartPieChart
  • RadarChartScatterPlot
  • FunnelChartParallelCoordinates

版面、導航與覆蓋層

匯入路徑:@appfuse/appfuse-web/components

分類元件說明
LayoutCard標頭、內文、表面層級與可折疊內容
LayoutFieldset語意化 fieldset / legend 表單分組
NavigationTabs受控或非受控的鍵盤可操作分頁
OverlaysDropdownCompound Component 下拉選單
OverlaysDialog任務型對話框外殼——title / description / children / footer 皆為 slot,承載表單、上傳與多步驟流程
OverlaysPopover非模態互動浮層,支援 click/hover 與任意內容
OverlaysSheet貼邊任務外殼,支援 right/bottom responsive placement
OverlaysTooltip浮動提示與位置控制

回饋與訊息

低階元件由 @appfuse/appfuse-web/components 匯入:

元件說明
Alert頁面內的語意化狀態訊息
Toast / ToastContainer非阻塞式通知與定位容器
PromptDialog系統訊息對話框——severity 彩色標題列、字串內容與字串動作陣列
UnderConstruction尚未完成頁面的標準提示
MswHealthGuardPrototype 的 MSW 攔截健康守衛(探測失效並自動恢復)

應用程式通常改用 @appfuse/appfuse-web/messagingpromptMessageToastMessageDialog 管理全域訊息。詳見訊息系統指南

Dialog 還是 PromptDialog

兩支都是模態對話框,但服務不同角色,不可互換

PromptDialog(Feedback)Dialog(Overlays)
角色系統訊息任務介面
標題列severity 驅動的彩色列中性列(可帶 icon
內容content: stringchildren: ReactNode + 選用 description
動作actions: string[](資料陣列)footer: ReactNode(自由 slot)
驅動來源prompt.*() / MessageDialog呼叫端自行持有 open 狀態

判斷句:需要顯示一則訊息、或要一個是/否的答案 → PromptDialog;需要放一個表單、 一份摘要、或任何自訂動作鍵(含送出中鎖定)→ Dialog

PromptDialogcontent / actions 形狀直接對應 prompt 佇列的資料,刻意不接 ReactNode—— 需要結構化內容時答案一律是 Dialog,而非擴充 PromptDialog。命名沿革見 ADR-010

<Dialog
open={open}
onClose={close}
title="停用商品分類"
description="停用後,此分類將不再出現在新商品的選單中。"
closeDisabled={submitting}
footer={
<>
<Button variant="outline" color="neutral" onClick={close} disabled={submitting}>
取消
</Button>
<Button color="error" loading={submitting} onClick={deactivate}>
確認停用
</Button>
</>
}
>
<AffectedProductSummary products={products} />
</Dialog>

無障礙由框架吸收:focus trap、初始焦點與關閉後焦點還原皆內建,title 關聯 aria-labelledbydescription 關聯 aria-describedbycloseDisabled 一次擋掉 關閉鈕、點擊背景與 ESC 三條途徑,用於送出期間防止半途關閉。

Hooks 與工具

Hooks

匯入路徑:@appfuse/appfuse-web/hooks

Hook說明
useTimeout / useInterval自動清理的計時器
useFloatingPortal浮動定位與 Portal
useInfiniteListTanStack Query 無限清單

工具

匯入路徑:@appfuse/appfuse-web/utils

匯出說明
createHttpClient / HttpClientProvider / useHttpClientHTTP client 與 React context
getApiErrorMessage從 RFC 7807 / violations 萃取可顯示的錯誤訊息
i18n / useTranslation / I18nProvider國際化
time / toDateString日期時間工具
logger日誌
cnclsx + tailwind-merge 類別合併
cookie / environ / browser瀏覽器與環境工具
numeral / template / filter格式化、模板與查詢建構

詳細用法請參閱工具函數指南

互動式 API 探索

元件的 props、狀態、設計語言矩陣與使用情境以 Storybook 為準。若本頁清單、Storybook 與安裝版本的 .d.ts 不一致,先確認網站與套件是否為同一次發布,再以安裝版本的型別宣告作為消費端契約。

共用設計原則

  1. 使用 DaisyUI 語意色與主題,不硬編碼 Tailwind 顏色。
  2. 資料輸入元件以 compactcomfortable 密度維持一致尺寸。
  3. 公開 props 與鍵盤互動以 WCAG 2.1 AA 為基線。
  4. 只從 package.json#exports 定義的 subpath 匯入,不使用 dist/lib/ 內部路徑。