Field Kit

Nesta página

O tipo de campo json do EmDash armazena dados estruturados arbitrários, mas o editor padrão é uma entrada de texto de linha única onde você precisa digitar JSON bruto manualmente. Field Kit é um plugin de primeira parte que fornece quatro widgets combináveis para campos json, configurados inteiramente através de options de seed — sem necessidade de React para os construtores de sites.

Instalação

npm i @emdash-cms/plugin-field-kit

Registre o plugin em astro.config.mjs:

import { defineConfig } from "astro/config";
import emdash from "emdash";
import { fieldKitPlugin } from "@emdash-cms/plugin-field-kit";

export default defineConfig({
	integrations: [
		emdash({
			plugins: [fieldKitPlugin()],
		}),
	],
});

Em seguida, anexe um widget a qualquer campo json definindo widget como field-kit:<name>:

{
	"slug": "ingredients",
	"type": "json",
	"widget": "field-kit:list",
	"options": { "fields": [...] }
}

Widgets

WidgetUsar paraValor armazenado
object-formFormulário inline para objetos JSON planos{ key: value, ... }
listEditor de array ordenado com adicionar / remover / reordenar[{ ... }, ...]
gridMatriz linhas × colunas{ rowKey: { colKey: value } }
tagsEntrada de chip/tag em formato livre["tag1", "tag2"]

Se um widget estiver sem suas options necessárias (por exemplo, fields para object-form/list, ou rows/columns para grid), o editor renderiza um aviso inline “Widget mal configurado” em vez de uma entrada quebrada — útil ao iterar em esquemas de seed.

object-form

Renderiza um grupo de subcampos tipados que são armazenados como um único objeto JSON. Bom para dados estruturados de forma fixa, como informações nutricionais ou informações de contato.

{
	"slug": "nutrition",
	"type": "json",
	"widget": "field-kit:object-form",
	"options": {
		"collapsed": false,
		"fields": [
			{ "key": "calories", "label": "Calories", "type": "number", "suffix": "kcal" },
			{ "key": "protein", "label": "Protein", "type": "number", "suffix": "g" },
			{ "key": "fat", "label": "Fat", "type": "number", "suffix": "g" },
			{ "key": "carbs", "label": "Carbs", "type": "number", "suffix": "g" }
		]
	}
}

Valor armazenado: { "calories": 250, "protein": 12.5, "fat": 8, "carbs": 30 }.

OpçãoTipoPadrãoDescrição
fieldsSubFieldDef[](obrigatório)Definições de subcampos — veja Subcampos.
collapsedbooleanfalseRenderizar o grupo recolhido por padrão.
helpTextstringTexto de ajuda mostrado abaixo do widget.

list

Um editor de array ordenado com controles de adicionar, remover e reordenar. Cada linha é um objeto JSON cuja forma é definida por fields. O cabeçalho da linha mostra um resumo renderizado a partir de um template estilo Mustache.

{
	"slug": "ingredients",
	"type": "json",
	"widget": "field-kit:list",
	"options": {
		"itemLabel": "Ingredient",
		"min": 1,
		"max": 50,
		"sortable": true,
		"summary": "{{name}} — {{amount}}",
		"fields": [
			{ "key": "name", "label": "Name", "type": "text", "required": true },
			{ "key": "amount", "label": "Amount", "type": "text" },
			{ "key": "optional", "label": "Optional", "type": "boolean" }
		]
	}
}

Valor armazenado:

[
	{ "name": "Flour", "amount": "500g", "optional": false },
	{ "name": "Butter", "amount": "200g", "optional": false }
]
OpçãoTipoPadrãoDescrição
fieldsSubFieldDef[](obrigatório)Definições de subcampos para cada linha.
itemLabelstring"Item"Rótulo singular para uma linha (usado no botão “Adicionar” e títulos de linha de fallback).
minnumberNúmero mínimo de itens. Abaixo disso, o botão de remover fica oculto.
maxnumberNúmero máximo de itens. Nesta contagem, o botão de adicionar fica oculto.
sortablebooleantrueMostrar botões de reordenação para cima/para baixo.
summarystringTemplate Mustache renderizado como título de linha recolhida. Veja Templates de resumo.
helpTextstringTexto de ajuda mostrado abaixo do widget.

grid

Uma matriz bidimensional de linhas × colunas. Cada célula pode ser um toggle, entrada de texto, entrada numérica ou seleção. Útil para matrizes como disponibilidade sazonal, tabelas de preços ou comparações de recursos.

{
	"slug": "availability",
	"type": "json",
	"widget": "field-kit:grid",
	"options": {
		"cell": "toggle",
		"rows": [
			{ "key": "berries", "label": "Berries" },
			{ "key": "stoneFruit", "label": "Stone fruit" },
			{ "key": "citrus", "label": "Citrus" }
		],
		"columns": [
			{ "key": "spring", "label": "Spring" },
			{ "key": "summer", "label": "Summer" },
			{ "key": "autumn", "label": "Autumn" },
			{ "key": "winter", "label": "Winter" }
		]
	}
}

Valor armazenado:

{
	"berries": { "spring": false, "summer": true, "autumn": false, "winter": false },
	"stoneFruit": { "spring": false, "summer": true, "autumn": true, "winter": false },
	"citrus": { "spring": false, "summer": false, "autumn": true, "winter": true }
}
OpçãoTipoPadrãoDescrição
rowsGridAxisDef[](obrigatório)Definições de linha: { key, label, image? }.
columnsGridAxisDef[](obrigatório)Definições de coluna: { key, label, image? }.
cell"toggle" | "text" | "number" | "select""toggle"Tipo de entrada de célula, aplicado uniformemente a cada célula.
cellOptionsstring[] | Array<{ label, value }>[]Obrigatório quando cell é "select".
helpTextstringTexto de ajuda mostrado abaixo do widget.

tags

Uma entrada estilo chip para arrays de strings. Suporta uma lista fixa de suggestions, valores personalizados em formato livre (alternáveis), transformações de maiúsculas/minúsculas e um max opcional.

{
	"slug": "keywords",
	"type": "json",
	"widget": "field-kit:tags",
	"options": {
		"placeholder": "Add a keyword…",
		"max": 10,
		"transform": "lowercase",
		"allowCustom": true,
		"suggestions": ["vegan", "vegetarian", "gluten-free", "dairy-free", "nut-free"]
	}
}

Valor armazenado: ["vegan", "gluten-free"].

Pressione Enter ou , para confirmar uma tag. Backspace em uma entrada vazia remove a última tag. Tags duplicadas são silenciosamente ignoradas.

OpçãoTipoPadrãoDescrição
placeholderstring"Add..."Placeholder de entrada mostrado quando não há tags presentes.
maxnumberNúmero máximo de tags. A entrada fica oculta no limite.
suggestionsstring[][]Sugestões de autocompletar exibidas via <datalist>.
allowCustombooleantrueQuando false, apenas valores de suggestions podem ser adicionados.
transform"none" | "lowercase" | "uppercase" | "trim""none"Normalizar tags à medida que são adicionadas.
helpTextstringTexto de ajuda mostrado abaixo do widget.

Subcampos

object-form e list aceitam um array options.fields de definições de subcampos tipados. Cada entrada tem uma key (a chave do objeto JSON em que escreve), um label, um type e extras específicos do tipo.

Tipo de subcampoRenderizado comoExtras notáveis
textEntrada de linha únicaplaceholder
textareaEntrada de várias linhasrows (padrão 3), placeholder
numberEntrada numéricamin, max, step, prefix, suffix, placeholder
booleanInterruptor toggle
selectDropdownoptions: string[] | Array<{ label, value }>, placeholder
dateEntrada de data
colorSeletor de cores nativo emparelhado com entrada de texto hexadecimal
urlEntrada de URL (HTML5 type="url")placeholder

Props comuns em cada subcampo: required, helpText, defaultValue.

Templates de resumo

O widget list renderiza cada linha recolhida usando um template estilo Mustache em options.summary. {{key}} é substituído pelo valor da linha para essa chave (convertido para string). Valores falsy voltam para "{itemLabel} {n}".

"summary": "{{name}} — {{amount}}"

Renderiza linhas como Flour — 500g. O template é uma substituição de string simples — sem HTML, sem expressões aninhadas.

Durabilidade de dados

Os widgets do Field Kit armazenam JSON simples na coluna existente do campo. Não há tabelas específicas do plugin, sem chaves estrangeiras, sem mutação de esquema. Se você remover @emdash-cms/plugin-field-kit da sua configuração, os dados permanecem válidos — apenas a UI de edição volta para a entrada de texto json padrão.

Isso se aplica mesmo quando você altera a forma do widget: chaves desconhecidas em objetos armazenados são preservadas na próxima escrita, para que você possa evoluir um esquema sem perder dados capturados sob um conjunto de campos mais antigo.

Veja também