UNPKG

@blocklet/ui-react

Version:

Some useful front-end web components that can be used in Blocklets.

413 lines (314 loc) 15.2 kB
# 操作指南 本節提供了實用的逐步指南,用於完成常見任務和使用該函式庫的元件實作特定工作流程。每個指南都設計為一組獨立的說明,旨在幫助您高效地達成特定成果。 <x-cards data-columns="2"> <x-card data-title="為 Header 新增自訂元素" data-icon="lucide:layout-template" data-href="#how-to-add-custom-elements-to-the-header"> 了解如何使用 `addons` render prop 來擴展 `Header` 元件,新增自訂按鈕、導覽或其他互動元素。 </x-card> <x-card data-title="處理可選元件依賴" data-icon="lucide:puzzle" data-href="#how-to-handle-optional-component-dependencies"> 實作一個工作流程,提示管理員按需安裝必要的元件,確保您的 blocklet 功能順暢執行。 </x-card> <x-card data-title="實作即時使用者通知" data-icon="lucide:bell-ring" data-href="#how-to-implement-real-time-user-notifications"> 使用 WebSockets 設定一個即時通知系統,讓使用者隨時了解您應用程式中的重要事件。 </x-card> <x-card data-title="使用 BlockletStudio 發布資源" data-icon="lucide:rocket" data-href="#how-to-publish-resources-with-blockletstudio"> 整合 `BlockletStudio` 元件,提供一個用於發布和管理資源及依賴元件的使用者介面。 </x-card> </x-cards> --- ## 如何為 Header 新增自訂元素 `Header` 元件被設計為可擴展的。您可以利用 `addons` prop,直接將自訂按鈕、搜尋欄或其他 React 元件新增到 Header 中。 ### 目標 在主應用程式 Header 中新增一個自訂的「聊天」按鈕、一個搜尋輸入框以及額外的操作圖示。 ### 先決條件 - 一個已安裝 `@arcblock/ux` 函式庫且功能正常的 React 應用程式。 - 一個現有的 `<Header>` 元件實例。更多資訊,請參閱 [Header 元件文件](./components-layout-header.md)。 ### 步驟 `addons` prop 接受一個 render 函式。此函式會接收預設的插件(如 session 管理器)作為其第一個參數,讓您能夠決定將自訂元素放置在相對於預設插件的位置。 1. **定義 `addons` Render Prop** 在您的 `Header` 元件中,將一個函式傳遞給 `addons` prop。此函式應返回您想要渲染的 JSX。 ```jsx <Header meta={meta} addons={(defaultAddons, { navigation }) => { // 您的自訂元件將放置於此 return ( <> {/* 渲染您的自訂元件 */} {defaultAddons} </> ); }} /> ``` 2. **新增自訂元件** 在 render 函式內部,您可以新增任何您需要的元件。在此範例中,我們將新增一個標準的 Material-UI `Button`、幾個用於圖示的 `AddonButton` 元件以及一個 `Divider`。 3. **與預設插件結合** 標準作法是渲染傳入函式的 `defaultAddons`。這能確保如地區設定切換器和 session 管理器等基本元素仍然顯示。您可以將自訂元件放置在 `defaultAddons` 之前或之後。 ### 完整範例 以下是一個完整的範例,示範如何將多個自訂元素新增到 Header。這包括導覽、按鈕和圖示,並與預設的 session 管理器一同渲染。 ```javascript 如何為 Header 新增自訂元素 icon=logos:react import { Box, Divider, Button } from '@mui/material'; import { SessionContext } from '@arcblock/did-connect-react/lib/Session'; import { AddonButton } from '@arcblock/ux/lib/Header/addon-button'; import NavMenu from '@arcblock/ux/lib/NavMenu'; import SessionManager from '@arcblock/ux/lib/SessionManager'; import Header from '@arcblock/ux/lib/Header'; import { Icon } from '@iconify/react'; // 用於示範的模擬資料 const mockBlockletMeta = { title: 'My App', description: 'A great application', logoUrl: 'https://www.arcblock.io/image-bin/uploads/eb1cf5d60cd85c42362920c49e3768cb.svg' }; const mockSessionContextValue = { session: { user: { fullName: 'Demo User', did: 'z1ex...', role: 'admin', }, // ... 其他 session 屬性 }, }; export default function CustomHeaderGuide() { const meta = { ...mockBlockletMeta, enableConnect: true, enableLocale: true, }; return ( <SessionContext.Provider value={mockSessionContextValue}> <Header meta={meta} homeLink="https://www.arcblock.io" addons={(defaultAddons, { navigation }) => ( <> {/* 1. 新增自訂導覽 */} {navigation.navItems?.length > 0 && ( <NavMenu activeId={navigation.activeId} items={navigation.navItems} className="header-nav" /> )} {/* 2. 新增自訂按鈕 */} <Button variant="contained" color="primary" size="small"> Button </Button> {/* 3. 新增自訂圖示按鈕 */} <AddonButton icon={<Icon icon="tabler:message-circle" />}>Chat</AddonButton> <AddonButton icon={<Icon icon="tabler:bell" />} /> <Divider orientation="vertical" flexItem sx={{ height: 12, alignSelf: 'center' }} /> {/* 4. 渲染預設插件 (包含 session 管理器) */} {defaultAddons} </> )} /> </SessionContext.Provider> ); } ``` --- ## 如何處理可選元件依賴 許多 blocklets 依賴其他元件來提供特定功能。`ComponentInstaller` 讓您能夠建構依賴於可選元件的功能,如果這些元件未被安裝,它會為管理員提供一個友善的介面來安裝它們。 ### 目標 保護一個需要安裝另一個 blocklet 元件才能使用的功能。如果該元件缺失,管理員將會看到一個安裝介面,而其他使用者則不會看到任何內容。 ### 先決條件 - 您的應用程式中有一個依賴其他元件的功能(例如,一個需要「Media Kit」blocklet 的「媒體管理器」)。 - 依賴元件的 DID。 - 熟悉使用者角色(`owner`、`admin`)。 ### 步驟 1. **匯入 `ComponentInstaller`** 首先,從函式庫中匯入該元件。 ```javascript import ComponentInstaller from '@arcblock/ux/lib/ComponentInstaller'; ``` 2. **包裹您的功能** 使用 `ComponentInstaller` 包裹具有依賴項的元件或功能。 3. **提供元件 DID** 將所需元件的 DID 傳遞給 `did` prop。如果有多個依賴項,這可以是一個字串或一個字串陣列。 4. **為非管理員配置行為** 使用 `noPermissionMute` prop。當設定為 `true` 時,沒有權限安裝元件的使用者(即非管理員)將不會看到安裝提示。您可以提供一個 `fallback` 元件來替代顯示。 ### 完整範例 在此情境中,我們有一個 `MyFeatureButton`,只有在 DID 為 `z8ia...` 的元件被安裝後才應渲染。 ```javascript 如何處理可選元件依賴 icon=logos:react import ComponentInstaller from '@arcblock/ux/lib/ComponentInstaller'; import { Button } from '@mui/material'; const REQUIRED_COMPONENT_DID = 'z8ia1mAXo8ZE7ytGF36L5uBf9kD2kenhqFGp9'; // 範例 DID // 這是需要依賴項的元件 function MyFeatureButton() { return <Button variant="contained">Use Awesome Feature</Button>; } export default function OptionalComponentGuide() { return ( <ComponentInstaller // 要檢查的元件的 DID did={REQUIRED_COMPONENT_DID} // 允許查看安裝程式 UI 的角色列表 roles={['owner', 'admin']} // 若為 true,非管理員將看不到安裝程式 UI noPermissionMute // 可選:當元件未安裝時,向非管理員顯示的內容 fallback={<div>This feature is not available.</div>} // 成功安裝後觸發的回呼 onInstalled={() => console.log('Component was installed successfully!')} > {/* 只有在元件已安裝時,才會渲染此子元件 */} <MyFeatureButton /> </ComponentInstaller> ); } ``` 當管理員訪問此頁面且元件未安裝時,他們將看到一個彈出視窗,允許他們安裝。普通使用者將看到備用訊息。一旦安裝完成,所有使用者都將看到 `MyFeatureButton`。 --- ## 如何實作即時使用者通知 您可以透過監聽來自 Blocklet Server 的 WebSocket 事件,為使用者提供即時回饋和通知。`NotificationAddon` 元件是一個現成的解決方案,用於在 Header 中顯示未讀通知計數。 ### 目標 在應用程式 Header 中新增一個通知鈴鐺圖示,該圖示會顯示帶有未讀通知數量的徽章,並即時更新。 ### 先決條件 - 您的 blocklet 必須在支援通知服務的 Blocklet Server 版本(`1.16.42` 或更高)上執行。 - 一個用於放置通知圖示的 `<Header>` 元件。 - 一個提供使用者資訊的 session context。 ### 關鍵概念 - **WebSocket 事件**:當通知被建立或讀取時,Blocklet Server 會廣播事件。 - **`useListenWsClient`**:一個用於獲取特定頻道(例如 'user')的 WebSocket 客戶端實例的 hook。 - **事件命名**:事件的作用域限定於使用者和 blocklet。新通知的格式為 `${blocklet.did}/${user.did}/notification:blocklet:create`。 ### 步驟 `NotificationAddon` 元件封裝了監聽 WebSocket 事件和顯示未讀計數所需的所有邏輯。 1. **匯入 `NotificationAddon`** ```javascript import NotificationAddon from '@arcblock/ux/lib/common/notification-addon'; ``` 2. **新增至 Header `addons`** 最簡單的使用方法是將其新增到 `Header` 的 `addons` render prop 中。 3. **傳遞 Session 物件** `NotificationAddon` 元件需要 `session` 物件來識別目前使用者並管理未讀計數狀態。 ### 完整範例 此範例展示如何將 `NotificationAddon` 整合到 `Header` 中。它將自動連接到 WebSocket、監聽事件並更新徽章計數。 ```javascript 如何實作即時使用者通知 icon=logos:react import { SessionContext } from '@arcblock/did-connect-react/lib/Session'; import Header from '@arcblock/ux/lib/Header'; import NotificationAddon from '@arcblock/ux/lib/common/notification-addon'; // 用於示範的模擬資料 const mockBlockletMeta = { title: 'My App', description: 'A great application', logoUrl: 'https://www.arcblock.io/image-bin/uploads/eb1cf5d60cd85c42362920c49e3768cb.svg' }; const mockSessionContextValue = { session: { user: { fullName: 'Demo User', did: 'z1ex...', role: 'admin', }, unReadCount: 3, // 初始未讀計數 setUnReadCount: () => {}, // 狀態設定函式 // ... 其他 session 屬性 }, }; export default function NotificationGuide() { const meta = { ...mockBlockletMeta, enableConnect: true }; return ( <SessionContext.Provider value={mockSessionContextValue}> <Header meta={meta} addons={(defaultAddons) => ( <> {/* NotificationAddon 將處理即時更新 */} <NotificationAddon session={mockSessionContextValue.session} /> {defaultAddons} </> )} /> </SessionContext.Provider> ); } ``` 當為已登入使用者建立新通知時,鈴鐺圖示上的徽章計數將自動增加。點擊該圖示將導覽使用者至他們的通知頁面。 --- ## 如何使用 BlockletStudio 發布資源 `BlockletStudio` 元件提供了一個完整的、可嵌入的 UI,用於發布資源和元件。它處理使用者連接、資源選擇和發布流程,將一個複雜的工作流程簡化為單一元件。 ### 目標 新增一個按鈕,該按鈕會打開一個對話框,允許使用者從 blocklet 中選擇並發布檔案和依賴元件。 ### 先決條件 - 您的 blocklet 中有一個 API 端點,該端點返回可用資源列表。 - 提供發布 UI 的元件(「工作室」元件)的 DID。 ### 步驟 1. **匯入 `BlockletStudio` 並管理狀態** 您需要使用元件狀態來管理工作室對話框的可見性。 ```javascript import { useState } from 'react'; import { BlockletStudio } from '@arcblock/ux/lib/BlockletStudio'; import { Button, CircularProgress } from '@mui/material'; ``` 2. **渲染元件** 將 `<BlockletStudio />` 元件放置在您的應用程式中,並使用 `open` 和 `setOpen` props 控制其可見性。 3. **配置必要 Props** - `componentDid`:提供發布服務的工作室 blocklet 的 DID。 - `title`, `description`:正在發布的項目的元資料。 - `resourcesParams`:作為查詢參數傳遞給您的資源獲取 API 的物件。 - `components`:一個要預選或必需的元件陣列。 - `resources`:一個指定要預選的資源的物件。 4. **處理生命週期事件** 使用 `onOpened`、`onUploaded` 和 `onReleased` 回呼來回應發布生命週期中的事件,例如隱藏載入指示器或顯示成功訊息。 ### 完整範例 此範例顯示一個按鈕,點擊後會打開 `BlockletStudio` 對話框。它還示範了如何管理載入狀態以提供更好的使用者體驗。 ```javascript 如何使用 BlockletStudio 發布資源 icon=logos:react import { useState } from 'react'; import { Button, CircularProgress } from '@mui/material'; import { BlockletStudio } from '@arcblock/ux/lib/BlockletStudio'; // 提供工作室/發布 UI 的 blocklet 的 DID const AI_STUDIO_COMPONENT_DID = 'z8ia1mAXo8ZE7ytGF36L5uBf9kD2kenhqFGp9'; // 範例 DID export default function PublisherGuide() { const [isStudioOpen, setStudioOpen] = useState(false); const [isOpening, setOpening] = useState(false); const handleShowDialog = () => { setOpening(true); setStudioOpen(true); }; return ( <> <Button variant="contained" onClick={handleShowDialog} disabled={isOpening} startIcon={isOpening ? <CircularProgress size={16} /> : null}> Publish to Studio </Button> <BlockletStudio // 控制對話框的可見性 open={isStudioOpen} setOpen={setStudioOpen} // 已發布項目的基本資訊 title="My Demo Project" description="This is a project published from my blocklet." // 工作室服務元件的 DID componentDid={AI_STUDIO_COMPONENT_DID} // 發送到您的 blocklet 資源 API 的參數 resourcesParams={{ projectId: 'test-project-123' }} // 預選元件 components={[ { did: 'z8ia3xzq2tMq8CRHfaXj1BTYJyYnEcHbqP8cJ', included: true, required: true }, { did: 'z2qZyjnsRffFtn2PDnDwDHTRbAu53RpKqDtFZ', included: true, required: false }, ]} // 預選資源 resources={{ // 鍵值是資源提供者 blocklet 的 DID z8iZpog7mcgcgBZzTiXJCWESvmnRrQmnd3XBB: [ 'template-448698592710885376', 'example-448698592710885376', ], }} // 事件處理常式 onOpened={() => setOpening(false)} onUploaded={() => alert('Upload complete!')} onReleased={() => { alert('Successfully released!'); setStudioOpen(false); }} /> </> ); } ```