UNPKG

@blocklet/ui-react

Version:

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

194 lines (172 loc) 10.3 kB
# BlockletStudio `BlockletStudio` 元件提供了一個精簡、可嵌入的使用者介面,用於發佈和管理 blocklet 資源。它透過渲染一個全頁 `iframe` 來運作,該 `iframe` 從指定的 blocklet 服務載入一個專用的發佈介面。這讓您的應用程式能夠提供一致且強大的資源管理體驗,而無需從頭開始建構 UI。 宿主應用程式與 `BlockletStudio` iframe 之間的通訊使用 `window.postMessage` API 進行安全處理,為上傳、發佈和連線等事件啟用回呼。 ## 使用範例 要整合 `BlockletStudio`,您需要管理其可見性狀態(例如,使用 `useState`)。由於 iframe 可能需要一些時間來載入,建議向使用者顯示一個載入指示器。`onOpened` 回呼可用於表示 iframe 內容已準備就緒,此時可以隱藏載入指示器。 以下範例示範如何實作一個按鈕,該按鈕可開啟 `BlockletStudio` 對話方塊並管理載入狀態。 ```tsx icon=logos:react title="Exporter.tsx" import { Icon } from '@iconify-icon/react'; import ArrowUp from '@iconify-icons/tabler/arrow-big-up-line'; import { Box, IconButton, CircularProgress as Spinner, svgIconClasses } from '@mui/material'; import { useState } from 'react'; import { BlockletStudio } from '@arcblock/ux-react'; // 提供工作室服務的 blocklet 的 DID。 const AI_STUDIO_COMPONENT_DID = 'z8ia1mAXo8ZE7ytGF36L5uBf9kD2kenhqFGp9'; export default function Exporter() { const [showCreateResource, setShowCreateResource] = useState(false); const [opening, setOpening] = useState(false); const handleShowDialog = () => { setOpening(true); setShowCreateResource(true); }; return ( <> <IconButton sx={{ position: 'relative', minWidth: 40, minHeight: 40, borderRadius: '100%', [`.${svgIconClasses.root}`]: { color: 'text.secondary', }, }} onClick={handleShowDialog}> {opening ? <Spinner size={16} /> : <Box component={Icon} icon={ArrowUp} style={{ fontSize: 24 }} />} </IconButton> <BlockletStudio open={showCreateResource} setOpen={setShowCreateResource} onOpened={() => setOpening(false)} componentDid={AI_STUDIO_COMPONENT_DID} mode="dialog" title="Demo Project" description="This is a demo project for the 'aigne' blocklet." note='Please review all resources and components before publishing.' introduction="Welcome to the resource publisher." tenantScope="test-tenant-scope-id-2" resourcesParams={{ name: 'test-project', extra: true }} dependentComponentsMode="readonly" componentsTitle="Required Components" resourcesTitle="Add Project Files" onConnected={() => alert('Connected')} onUploaded={() => alert('Uploaded')} onReleased={() => alert('Released')} components={[ { did: 'z8ia3xzq2tMq8CRHfaXj1BTYJyYnEcHbqP8cJ', included: true, required: true }, { did: 'z2qZyjnsRffFtn2PDnDwDHTRbAu53RpKqDtFZ', included: true, required: false }, ]} resources={{ 'z8iZpog7mcgcgBZzTiXJCWESvmnRrQmnd3XBB': [ 'template-448698592710885376', 'template-448696391418511360', ], }} /> </> ); } ``` ## 屬性 `BlockletStudio` 元件接受以下屬性來控制其行為和外觀。 <x-field-group> <x-field data-name="open" data-type="boolean" data-required="true"> <x-field-desc markdown>控制 `BlockletStudio` iframe 的可見性。設定為 `true` 可顯示,`false` 可隱藏。</x-field-desc> </x-field> <x-field data-name="setOpen" data-type="(open: boolean) => void" data-required="true"> <x-field-desc markdown>一個回呼函式,`BlockletStudio` 用於請求關閉。通常,此函式會將與 `open` 屬性相關的狀態變數設定為 `false`。</x-field-desc> </x-field> <x-field data-name="componentDid" data-type="string" data-required="true"> <x-field-desc markdown>提供資源發佈服務的 blocklet 的去中心化識別碼 (DID)。這決定了載入哪個工作室介面。</x-field-desc> </x-field> <x-field data-name="onOpened" data-type="() => void" data-required="false"> <x-field-desc markdown>一個可選的回呼函式,當 `BlockletStudio` iframe 完成載入並準備好進行使用者互動時執行。</x-field-desc> </x-field> <x-field data-name="onUploaded" data-type="(data: unknown) => void" data-required="false"> <x-field-desc markdown>一個可選的回呼函式,在使用者成功上傳新資源後觸發。`data` 參數包含有關上傳項目的元資料。</x-field-desc> </x-field> <x-field data-name="onReleased" data-type="(data: unknown) => void" data-required="false"> <x-field-desc markdown>一個可選的回呼函式,在使用者發佈元件的新版本後觸發。`data` 參數包含有關新版本的資訊。</x-field-desc> </x-field> <x-field data-name="onConnected" data-type="(data: unknown) => void" data-required="false"> <x-field-desc markdown>一個可選的回呼函式,在使用者連線資源或元件後觸發。</x-field-desc> </x-field> <x-field data-name="tenantScope" data-type="string" data-required="false"> <x-field-desc markdown>一個可選的字串,用於將資源範圍限定於特定租戶。這可用於確保多租戶環境中的資料隔離。</x-field-desc> </x-field> <x-field data-name="resourcesParams" data-type="Record<string, any>" data-required="false" data-default="{}"> <x-field-desc markdown>一個包含查詢參數的物件,這些參數將傳遞給 blocklet 的資源擷取 API 端點。這允許對資源進行動態篩選。</x-field-desc> </x-field> <x-field data-name="mode" data-type="string" data-required="false" data-default='"dialog"'> <x-field-desc markdown>決定工作室介面的顯示模式。預設為 `'dialog'`。</x-field-desc> </x-field> <x-field data-name="title" data-type="string" data-required="false"> <x-field-desc markdown>一個可選的標題,顯示在工作室介面的頂部。</x-field-desc> </x-field> <x-field data-name="logo" data-type="string" data-required="false"> <x-field-desc markdown>一個可選的 logo URL,顯示在工作室介面中。</x-field-desc> </x-field> <x-field data-name="description" data-type="string" data-required="false"> <x-field-desc markdown>一個可選的字串,提供簡短描述,顯示在工作室 UI 中。</x-field-desc> </x-field> <x-field data-name="introduction" data-type="string" data-required="false"> <x-field-desc markdown>一個可選的字串,用於更詳細的介紹,顯示在工作室 UI 中。</x-field-desc> </x-field> <x-field data-name="note" data-type="string" data-required="false"> <x-field-desc markdown>一個可選的字串,用於向使用者顯示註釋或重要訊息。</x-field-desc> </x-field> <x-field data-name="componentsTitle" data-type="string" data-required="false"> <x-field-desc markdown>一個可選的字串,用於自訂元件部分的標題。</x-field-desc> </x-field> <x-field data-name="resourcesTitle" data-type="string" data-required="false"> <x-field-desc markdown>一個可選的字串,用於自訂資源部分的標題。</x-field-desc> </x-field> <x-field data-name="components" data-type="Record<string, unknown>[]" data-required="false" data-default="[]"> <x-field-desc markdown>一個物件陣列,代表在工作室中應預設預選的元件。</x-field-desc> </x-field> <x-field data-name="resources" data-type="Record<string, unknown>" data-required="false" data-default="{}"> <x-field-desc markdown>一個物件,代表在工作室中應預設預選的資源。</x-field-desc> </x-field> <x-field data-name="dependentComponentsMode" data-type="'auto' | 'readonly'" data-required="false"> <x-field-desc markdown>控制相依元件的行為。在 `'readonly'` 模式下,使用者無法取消選取作為所選資源的相依性而自動包含的元件。</x-field-desc> </x-field> <x-field data-name="style" data-type="React.CSSProperties" data-required="false" data-default="{}"> <x-field-desc markdown>一個用於將自訂 CSS 樣式應用於 `iframe` 元素的物件。</x-field-desc> </x-field> <x-field data-name="zIndex" data-type="number" data-required="false" data-default="9999"> <x-field-desc markdown>`iframe` 元素的 z-index CSS 屬性,控制其堆疊順序。</x-field-desc> </x-field> </x-field-group> ## 相依元件 為 `BlockletStudio` 提供資源 API 的 Blocklet 可以在資源資料中直接指定元件相依性。當使用者選取一個列出 `dependentComponents` 的資源時,`BlockletStudio` 將在 UI 中自動選取這些元件。 此功能透過確保所有必要的相依性都自動包含在內,簡化了使用者體驗。 要實作此功能,您的 blocklet 的資源 API 應返回一個包含所需元件 DID 的 `dependentComponents` 陣列。 ### API 回應範例 以下是來自資源 API 端點的 JSON 回應範例。「應用程式」和「工具」資源宣告了它們的元件相依性。 ```json 帶有相依性的 API 回應 { "resources": [ { "id": "application-448698592710885376", "name": "My App (as Application)", "dependentComponents": [ "error-did", "z8ia1mAXo8ZE7ytGF36L5uBf9kD2kenhqFGp9", "z2qZyjnsRffFtn2PDnDwDHTRbAu53RpKqDtFZ", "z2qaCNvKMv5GjouKdcDWexv6WqtHbpNPQDnAk" ] }, { "id": "tool-448698592710885376", "name": "My App (as Tool)", "dependentComponents": ["error-did", "z2qaCNvKMv5GjouKdcDWexv6WqtHbpNPQDnAk"] }, { "id": "template-448698592710885376", "name": "My App (as Template)" } ] } ``` ## 總結 `BlockletStudio` 元件提供了一種強大而便利的方式,可將資源和元件管理直接整合到您的應用程式中。透過利用 `iframe` 和一組清晰的屬性,它在簡化開發的同時提供了一致的使用者體驗。有關相依性管理的相關功能,您可能還想查閱 [ComponentInstaller](./components-component-management-component-installer.md) 文件。