EmDash 的 Block Kit 允許沙箱外掛程式將其管理介面描述為 JSON。宿主負責渲染這些區塊——外掛程式提供的 JavaScript 永遠不會在瀏覽器中執行。
運作原理
- 使用者導覽至外掛程式的管理頁面。
- 管理器向外掛程式的管理路由發送
page_load互動。 - 外掛程式返回包含區塊陣列的
BlockResponse。 - 管理器使用
BlockRenderer元件渲染這些區塊。 - 當使用者互動時(點擊按鈕、提交表單),管理器將互動發送回外掛程式。
- 外掛程式返回新的區塊,循環重複。
import type { SandboxedPlugin } from "emdash/plugin";
interface BlockInteraction {
type: "page_load" | "block_action" | "form_submit";
page?: string;
action_id?: string;
values?: Record<string, unknown>;
}
export default {
routes: {
admin: {
handler: async (routeCtx, ctx) => {
const interaction = routeCtx.input as BlockInteraction;
if (interaction.type === "page_load") {
return {
blocks: [
{ type: "header", text: "My Plugin Settings" },
{
type: "form",
block_id: "settings",
fields: [
{ type: "text_input", action_id: "api_url", label: "API URL" },
{ type: "toggle", action_id: "enabled", label: "Enabled", initial_value: true },
],
submit: { label: "Save", action_id: "save" },
},
],
};
}
if (interaction.type === "form_submit" && interaction.action_id === "save") {
await ctx.kv.set("settings", interaction.values);
return {
blocks: [/* ... updated blocks ... */],
toast: { message: "Settings saved", type: "success" },
};
}
return { blocks: [] };
},
},
},
} satisfies SandboxedPlugin;
路由處理器接受兩個參數:routeCtx(包含 input、request、requestMeta)和 ctx(PluginContext)。satisfies SandboxedPlugin 會推斷這兩者。
區塊類型
| 類型 | 說明 |
|---|---|
header | 大號粗體標題 |
section | 帶有可選附屬元素的文字 |
divider | 水平分隔線 |
fields | 雙欄標籤/值網格 |
table | 帶格式化、排序、分頁的資料表格 |
actions | 水平排列的按鈕和控制項列 |
stats | 帶趨勢指示器的儀表板指標卡片 |
form | 帶條件可見性和提交的輸入欄位 |
image | 帶標題的區塊級圖片 |
context | 小號柔和的說明文字 |
columns | 2-3 欄佈局,帶巢狀區塊 |
empty | 空狀態佔位符,包含圖示、標題、說明、可選命令列和操作按鈕 |
accordion | 包裹巢狀區塊的可摺疊區域 |
元素類型
| 類型 | 說明 |
|---|---|
button | 帶可選確認對話框的操作按鈕 |
text_input | 單行或多行文字輸入 |
number_input | 帶最小/最大值的數字輸入 |
select | 下拉選擇 |
toggle | 開/關開關 |
secret_input | 用於 API 金鑰和權杖的遮罩輸入 |
建構器輔助函式
@emdash-cms/blocks 套件匯出建構器輔助函式,使程式碼更簡潔:
import { blocks, elements } from "@emdash-cms/blocks";
const { header, form, section, stats } = blocks;
const { textInput, toggle, select, button } = elements;
return {
blocks: [
header("SEO Settings"),
form({
blockId: "settings",
fields: [
textInput("site_title", "Site Title", { initialValue: "My Site" }),
toggle("generate_sitemap", "Generate Sitemap", { initialValue: true }),
select("robots", "Default Robots", [
{ label: "Index, Follow", value: "index,follow" },
{ label: "No Index", value: "noindex,follow" },
]),
],
submit: { label: "Save", actionId: "save" },
}),
],
};
條件欄位
表單欄位可以根據其他欄位的值有條件地顯示:
{
"type": "toggle",
"action_id": "auth_enabled",
"label": "Enable Authentication"
}
{
"type": "secret_input",
"action_id": "api_key",
"label": "API Key",
"condition": { "field": "auth_enabled", "eq": true }
}
api_key 欄位僅在 auth_enabled 開啟時顯示。條件在客戶端評估,無需往返。
試用
使用 Block Playground 互動式地建構和測試區塊佈局。