Esquema de bloques y tipos de campo
Todos los tipos de campo, el builder defineBlock + fields, opciones de campo, repeaters y opciones de select.
Todos los tipos de campo
Define las props editables de un bloque con el builder fields.*() dentro de defineBlock. Cada builder devuelve una definición de campo; la clave que le das en props se convierte en la clave del contenido.
| Builder | Descripción | Tipo de valor |
|---|---|---|
fields.text() | Campo de texto de una línea | string |
fields.textarea() | Área de texto multilínea | string |
fields.richText() | Editor WYSIWYG (Tiptap) | string (HTML) |
fields.markdown() | Editor Markdown | string (Markdown) |
fields.number() | Campo numérico | number |
fields.date() | Selector de fecha | string (ISO date) |
fields.datetime() | Selector de fecha y hora | string (ISO) |
fields.boolean() | Interruptor | boolean |
fields.color() | Selector de color | string (hex) |
fields.media() | Subida de imagen/vídeo | ResolvedMedia o ResolvedMedia[] |
fields.link() | Enlace interno/externo | string |
fields.url() | Campo URL | string |
fields.email() | Campo de correo | string |
fields.select() | Desplegable (selección única) | string |
fields.radio() | Grupo de radio (selección única) | string |
fields.multiselect() | Selección múltiple | string[] |
fields.relation() | Referenciar registros de un modelo | record or record[] |
fields.repeater() | Array de grupos de campos anidados | object[] |
fields.table() | Cuadrícula de tabla editable | { columns, rows } |
fields.json() | Editor de JSON en bruto | JSON value |
fields.form() | Elegir un formulario Cmssy | string (form id) |
fields.pageSelector() | Elegir página(s) | PageRef[] |
La mayoría de los builders solo aceptan las opciones base de abajo. fields.select(), fields.radio() y fields.multiselect() requieren un array options; fields.media() acepta multiple; fields.relation() necesita un model (el slug del modelo referenciado) y, opcionalmente, mode: "all", multiple, sort y limit. Una relación guarda el/los id de registro; la API de delivery los resuelve a registros completos antes de que se renderice tu componente.
Definir un bloque
Un bloque se declara con defineBlock. Sus campos editables viven bajo props:
import { defineBlock, fields } from "@cmssy/react";
import Hero from "./Hero";
export const heroProps = {
heading: fields.text({ label: "Heading", required: true, defaultValue: "Welcome" }),
description: fields.textarea({ label: "Description" }),
};
export const heroBlock = defineBlock({
type: "hero",
label: "Hero",
component: Hero,
props: heroProps,
});
Exporta el objeto de props aparte y tipa el componente desde él - BlockProps<typeof heroProps> - así el esquema sigue siendo el único sitio donde se nombra un campo, y los tipos de valor de la tabla de arriba pasan a ser los que ve tu componente. Consulta Desarrollo de bloques.
Opciones de campo
Todos los builders fields.*() aceptan las mismas opciones base:
fields.text({
label: "Heading",
required: true,
defaultValue: "Welcome",
placeholder: "Enter text",
helperText: "Main heading",
})
Claves disponibles: label, required, defaultValue, placeholder, helperText, localized. Los campos select y repeater añaden algunas más (abajo).
Campos iguales en todos los idiomas
Por defecto cada campo se traduce: cada idioma guarda su propio valor. Un campo que debe tener un solo valor para todo el sitio - un logo, una foto de producto, un color de marca - declara localized: false:
props: {
logo: fields.media({ label: "Logo", localized: false }),
heading: fields.text({ label: "Heading" }),
}
El editor muestra ese campo una sola vez, con un candado, sea cual sea el idioma que estés editando; cambiarlo lo cambia para todos los idiomas. La API de delivery lo sigue devolviendo dentro del contenido de cada idioma, así que tu componente lee content.logo exactamente igual que antes: nada cambia en el lado del consumidor.
localized es independiente de tab: un campo en la pestaña style o advanced ya es un valor por bloque, así que ahí la bandera no aporta nada. Cambiar la bandera en un campo existente mueve el valor guardado en el siguiente envío del manifiesto. Requiere @cmssy/core 16.4.0 o más reciente.
Select y Multiselect
Las opciones son un simple array de strings:
props: {
layout: fields.select({
label: "Layout",
options: ["grid", "list", "carousel"],
defaultValue: "grid",
}),
tags: fields.multiselect({
label: "Tags",
options: ["featured", "new"],
}),
}
Repeater (arrays)
Usa itemSchema — un mapa de fields.*() anidados — para describir cada fila:
props: {
features: fields.repeater({
label: "Features",
maxItems: 6,
itemSchema: {
icon: fields.text({ label: "Icon Name", defaultValue: "Star" }),
title: fields.text({ label: "Title", required: true }),
description: fields.textarea({ label: "Description" }),
},
}),
}
En tu componente:
export default function Features({ content }) {
return (
<div className="grid grid-cols-3 gap-6">
{(content.features ?? []).map((f, i) => (
<div key={i}><h3>{f.title}</h3><p>{f.description}</p></div>
))}
</div>
);
}
El repeater también admite itemLabel, addButtonLabel, minItems, maxItems y collapsible.