跳至主要内容

元件總覽

:::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:綁定 control、name 與欄位錯誤的 react-hook-form wrapper。
  • messaging:應用層全域訊息服務與容器。
  • hooks、utils:跨元件使用的 Hooks 與工具。

資料輸入與表單​

除 SelectMenu、OptionRow 等低階組裝元件外,下表元件同時提供 @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檔案與媒體選擇、驗證及預覽
SignatureInput手寫簽名;受控 SignatureValue 向量值,支援空白判定與 PNG Blob/File 匯出
DatePickertype="local-date" 使用 ISO 日期字串;type="instant" 使用 Date;type="year-month" 使用 ISO YYYY-MM 字串
TimePickerLocalTime 語意;表單值為無時區的時間字串
DateTimePickertype="local-date-time" 使用無時區字串;type="instant" 使用 Date

兩個 picker 的 type 都是必填辨識欄位,讓 TypeScript 直接約束 value/onChange 的型別。 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 主題配色:

  • LineChart、AreaChart
  • BarChart、PieChart
  • RadarChart、ScatterPlot
  • FunnelChart、ParallelCoordinates

版面、導航與覆蓋層​

匯入路徑:@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/messaging 的 prompt、 MessageToast 與 MessageDialog 管理全域訊息。詳見訊息系統指南。

Dialog 還是 PromptDialog?​

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

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

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

PromptDialog 的 content / 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-labelledby、description 關聯 aria-describedby。closeDisabled 一次擋掉 關閉鈕、點擊背景與 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. 資料輸入元件以 compact、comfortable 密度維持一致尺寸。
  3. 公開 props 與鍵盤互動以 WCAG 2.1 AA 為基線。
  4. 只從 package.json#exports 定義的 subpath 匯入,不使用 dist/ 或 lib/ 內部路徑。