Block Kit

Auf dieser Seite

Das Block Kit von EmDash ermöglicht es Sandbox-Plugins, ihre Admin-UI als JSON zu beschreiben. Der Host rendert die Blöcke – vom Plugin bereitgestelltes JavaScript wird niemals im Browser ausgeführt.

Wie es funktioniert

  1. Der Benutzer navigiert zur Admin-Seite eines Plugins.
  2. Der Admin sendet eine page_load-Interaktion an die Admin-Route des Plugins.
  3. Das Plugin gibt eine BlockResponse zurück, die ein Array von Blöcken enthält.
  4. Der Admin rendert die Blöcke mit der BlockRenderer-Komponente.
  5. Wenn der Benutzer interagiert (einen Button klickt, ein Formular absendet), sendet der Admin die Interaktion zurück an das Plugin.
  6. Das Plugin gibt neue Blöcke zurück, und der Zyklus wiederholt sich.
import { definePlugin } from "emdash";
import type { PluginContext } from "emdash";

interface BlockInteraction {
	type: "page_load" | "block_action" | "form_submit";
	page?: string;
	action_id?: string;
	values?: Record<string, unknown>;
}

export default definePlugin({
	routes: {
		admin: {
			handler: async (routeCtx, ctx: PluginContext) => {
				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: [] };
			},
		},
	},
});

Der Standard-Format-Route-Handler nimmt zwei Argumente: routeCtx (mit input, request, requestMeta) und ctx (der PluginContext).

Block-Typen

TypeDescription
headerGroße fette Überschrift
sectionText mit optionalem Accessory-Element
dividerHorizontale Linie
fieldsZweispaltige Label/Wert-Tabelle
tableDatentabelle mit Formatierung, Sortierung, Paginierung
actionsHorizontale Reihe von Buttons und Steuerelementen
statsDashboard-Metrik-Karten mit Trendindikatoren
formEingabefelder mit bedingter Sichtbarkeit und Absenden
imageBlock-Level-Bild mit Beschriftung
contextKleiner gedämpfter Hilfetext
columns2–3 Spalten-Layout mit verschachtelten Blöcken
emptyLeerzustands-Platzhalter mit Icon, Titel, Beschreibung, optionaler Befehlszeile und Action-Buttons
accordionZusammenklappbarer Abschnitt, der verschachtelte Blöcke umschließt

Element-Typen

TypeDescription
buttonAction-Button mit optionalem Bestätigungsdialog
text_inputEinzeilige oder mehrzeilige Texteingabe
number_inputNumerische Eingabe mit Min/Max
selectDropdown-Auswahl
toggleEin/Aus-Schalter
secret_inputMaskierte Eingabe für API-Schlüssel und Tokens

Builder-Helfer

Das @emdash-cms/blocks-Paket exportiert Builder-Helfer für saubereren Code:

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" },
		}),
	],
};

Bedingte Felder

Formularfelder können basierend auf anderen Feldwerten bedingt angezeigt werden:

{
	"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 }
}

Das api_key-Feld erscheint nur, wenn auth_enabled eingeschaltet ist. Bedingungen werden clientseitig ohne Round-Trip ausgewertet.

Ausprobieren

Verwenden Sie den Block Playground, um Block-Layouts interaktiv zu erstellen und zu testen.