Le Block Kit d’EmDash permet aux plugins sandboxés de décrire leur interface d’administration sous forme de JSON. L’hôte effectue le rendu des blocs — aucun JavaScript fourni par le plugin ne s’exécute dans le navigateur.
Comment ça fonctionne
- L’utilisateur navigue vers la page d’administration d’un plugin.
- L’admin envoie une interaction
page_loadà la route d’administration du plugin. - Le plugin renvoie une
BlockResponsecontenant un tableau de blocs. - L’admin effectue le rendu des blocs à l’aide du composant
BlockRenderer. - Lorsque l’utilisateur interagit (clique sur un bouton, soumet un formulaire), l’admin renvoie l’interaction au plugin.
- Le plugin renvoie de nouveaux blocs et le cycle se répète.
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: [] };
},
},
},
});
Le gestionnaire de route au format standard prend deux arguments : routeCtx (avec input, request, requestMeta) et ctx (le PluginContext).
Types de blocs
| Type | Description |
|---|---|
header | Grand titre en gras |
section | Texte avec élément accessoire optionnel |
divider | Ligne horizontale |
fields | Grille étiquette/valeur à deux colonnes |
table | Tableau de données avec formatage, tri, pagination |
actions | Rangée horizontale de boutons et de contrôles |
stats | Cartes de métriques de tableau de bord avec indicateurs de tendance |
form | Champs de saisie avec visibilité conditionnelle et soumission |
image | Image au niveau du bloc avec légende |
context | Petit texte d’aide atténué |
columns | Mise en page à 2–3 colonnes avec blocs imbriqués |
empty | Espace réservé d’état vide avec icône, titre, description, ligne de commande optionnelle et boutons d’action |
accordion | Section réductible enveloppant des blocs imbriqués |
Types d’éléments
| Type | Description |
|---|---|
button | Bouton d’action avec dialogue de confirmation optionnel |
text_input | Saisie de texte sur une ou plusieurs lignes |
number_input | Saisie numérique avec min/max |
select | Sélection déroulante |
toggle | Interrupteur marche/arrêt |
secret_input | Saisie masquée pour clés API et jetons |
Assistants de construction
Le package @emdash-cms/blocks exporte des assistants de construction pour un code plus propre :
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" },
}),
],
};
Champs conditionnels
Les champs de formulaire peuvent être affichés conditionnellement en fonction des valeurs d’autres champs :
{
"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 }
}
Le champ api_key n’apparaît que lorsque auth_enabled est activé. Les conditions sont évaluées côté client sans aller-retour.
Essayez-le
Utilisez le Block Playground pour construire et tester des mises en page de blocs de manière interactive.