Guides
Specs de formulaire
Tout dans FormKrafter commence ici. Un formulaire est un spec : un simple arbre JSON que vous pouvez stocker en base, comparer dans une pull request, envoyer sur le réseau et confier à n’importe lequel des renderers, web ou natif. Rien n’y est spécifique à un framework, et rien n’y exige FormKrafter pour être lisible.
La forme d’un BrickSpec
Section intitulée « La forme d’un BrickSpec »Chaque nœud de l’arbre — un champ, un panel, une étape de wizard — est un
BrickSpec. Seules trois propriétés sont obligatoires :
interface BrickSpec { type: 'panel' | 'input' | 'collection' | 'output' | 'action' // obligatoire id: string // quelle brick enregistrée rend ce nœud name: string // libellé humain, affiché dans le builder
dataType?: 'string' | 'number' | 'integer' | 'boolean' | 'object' | 'array' | 'null' | 'void' configs?: { key?: string } & Record<string, unknown> styles?: Record<string, unknown> validations?: Validation[] rules?: Rule[] children?: BrickSpec[]
category?: string editable?: boolean isPrivate?: boolean}La propriété que vous manipulez le plus vit dans configs : key, le nom du
champ dans les données du formulaire. C’est ce qui se retrouve dans votre
payload, et une brick sans key ne porte aucune donnée.
Un spec complet
Section intitulée « Un spec complet »Un formulaire avec un champ texte et un select, tous deux obligatoires :
{ "type": "panel", "id": "column", "name": "Contact", "configs": { "key": "contact" }, "children": [ { "type": "input", "dataType": "string", "id": "text", "name": "Text", "configs": { "key": "fullName", "label": "Nom complet" }, "validations": [{ "validator": "required" }] }, { "type": "input", "dataType": "string", "id": "select", "name": "Select", "configs": { "key": "role", "label": "Rôle", "optionsSource": "static", "options": "Développeur\nDesigner\nManager" }, "validations": [{ "validator": "required" }] } ]}Ce spec produit ces données :
{ "fullName": "Ada Lovelace", "role": "Développeur" }Les données du formulaire sont plates — une entrée par key, quelle que
soit la profondeur d’imbrication de la brick dans des panels, des étapes de
wizard ou des onglets. La seule exception est une brick collection (comme
data-grid), où chaque ligne constitue son propre enregistrement scopé :
{ "fullName": "Ada", "contacts": [{ "email": "a@b.c" }, { "email": "d@e.f" }] }Éditer un spec
Section intitulée « Éditer un spec »Ne mutez jamais un spec sur place. Chaque opération renvoie un nouveau spec plus les patches pour y aller et en revenir :
import { moveBrick, addBrick, SpecHistory } from '@streamline-pulse/formkrafter-core'
const update = moveBrick(spec, '0.0', '0.2.0')// update.spec → le nouveau spec// update.patches → les opérations RFC 6902 qui ont appliqué le changement// update.inverse → les opérations RFC 6902 qui l'annulentLes chemins sont des chaînes pointées enracinées en "0", exprimées en
coordonnées d’avant suppression : "0.2.0" est le premier enfant du troisième
enfant de la racine.
Opérations disponibles
Section intitulée « Opérations disponibles »| Opération | Signature | Comportement de fusion |
|---|---|---|
addBrick |
(spec, brick, parentPath, index?) |
— |
removeBrick |
(spec, path) |
lève une erreur sur le chemin racine "0" |
moveBrick |
(spec, from, to) |
lève une erreur si l’on déplace une brick dans son propre sous-arbre |
duplicateBrick |
(spec, path) |
— |
updateBrickConfigs |
(spec, path, configs) |
fusionné dans les configs existantes |
updateBrickStyles |
(spec, path, styles) |
fusionné |
updateBrickValidations |
(spec, path, validations) |
remplacé intégralement |
updateBrickRules |
(spec, path, rules) |
remplacé intégralement |
Toutes les opérations adressent les bricks de la même façon, par chemin. Un chemin qui ne résout vers aucune brick lève une erreur au lieu de retomber sur la racine : une faute de frappe ne peut donc jamais modifier le mauvais nœud.
Undo et redo
Section intitulée « Undo et redo »SpecHistory enregistre les mises à jour et rejoue leurs inverses :
-
Enregistrez chaque mise à jour au fil de l’eau.
const history = new SpecHistory()history.record(update) -
Vérifiez si un pas est possible — pratique pour désactiver les boutons de la barre d’outils.
history.canUndo // booleanhistory.canRedo // boolean -
Reculez ou avancez d’un pas, en passant le spec courant.
spec = history.undo(spec) ?? specspec = history.redo(spec) ?? spec
Le builder fait exactement cela en interne, et c’est pourquoi son événement
specChange transporte { spec, patches, inverse } — vous pouvez persister les
patches, les rejouer sur un serveur, ou piloter votre propre pile d’historique.
Parcourir un spec
Section intitulée « Parcourir un spec »import { iterateBricks, getBrickAt, pointerFromPath } from '@streamline-pulse/formkrafter-core'
for (const { brick, path } of iterateBricks(spec)) { console.log(path, brick.configs?.key)}
getBrickAt(spec, '0.1') // la brick au chemin pointé, ou undefinedpointerFromPath('0.1') // le JSON Pointer correspondantÉtapes suivantes
Section intitulée « Étapes suivantes »Un projet de Streamline Pulse