Skip to content

Wizard

This content is not available in your language yet.

<co-form-wizard> envuelve <co-form> para soportar multi-page forms con stepper navegable, validación por página, conditional logic a nivel page, y scoring opcional para modo quiz.

Cuando un schema tiene pages: [...], el preview enruta automáticamente al wizard (en lugar del <co-form> flat).

{
"title": "Registro DevConf 2026",
"description": "Únete a la conferencia",
"mode": "form",
"pages": [
{
"name": "personal",
"title": "Datos personales",
"description": "Solo lo esencial",
"fields": {
"full_name": { "type": "String", "required": true, "label": "Nombre" },
"email": { "type": "String", "required": true, "format": "email" }
}
},
{
"name": "preferences",
"title": "Preferencias",
"visibleIf": "{full_name} != ''",
"fields": {
"tracks": { "type": "String", "enum": ["AI/ML", "Frontend"], "multiple": true }
}
}
]
}

Cada page aparece como un step en el header. Click en un step:

  • Hacia atrás → salta directo (ya visitaste esa page).
  • Hacia adelante → valida la page actual y avanza una a la vez (no salta sin validar intermedias).

Los steps marcan is-active y is-done con colores del accent.

Una page entera se oculta si su visibleIf evalúa a falso contra los valores acumulados:

{
"name": "advanced",
"title": "Configuración avanzada",
"visibleIf": "{role} == 'admin'",
"fields": {/* ... */}
}

Sintaxis igual que en fields — operadores ==, !=, >, <, >=, <=, contains, &&, ||.

Siguiente solo avanza si la page actual valida (touched + isValid). Si hay errores, los muestra y queda en la page. AJV se ejecuta scoped a los fields de la page.

El page header (PAGE N pill + título + description) se muestra solo cuando aporta info:

  • Multi-page → siempre se muestra (orientación al usuario).
  • Single-page con título default “Page N” y sin description → se oculta entero (el form title ya da contexto).
  • Single-page con título custom o description → muestra solo lo customizado.

Override explícito por page:

{
"name": "p1",
"title": "Page 1",
"hideTitle": true, // ocultar el h2
"hideDescription": true // ocultar el párrafo
}

mode: "quiz" activa el sistema de scoring. Cada field puede declarar quiz: { correctAnswer, points }:

{
"mode": "quiz",
"pages": [{
"name": "p1",
"title": "Vue 3 quiz",
"fields": {
"q1": {
"type": "String",
"enum": ["ref()", "reactive()", "computed()"],
"label": "¿Cuál crea un proxy reactivo?",
"quiz": { "correctAnswer": "reactive()", "points": 10 }
},
"q2": {
"type": "Boolean",
"label": "Los refs auto-unwrappean en template",
"quiz": { "correctAnswer": true, "points": 5 }
}
}
}],
"scoring": {
"showScore": true,
"passingScore": 70,
"feedbackRules": [
{ "expression": "{_score} >= 80", "message": "Excelente!" },
{ "expression": "{_score} < 50", "message": "Repasar la doc" }
]
}
}

Al hacer Submit, el wizard:

  1. Calcula el score sumando puntos de respuestas correctas vs total.
  2. Compara con passingScorepassed: boolean.
  3. Evalúa cada feedbackRules.expression (con {_score} disponible como % calculado).
  4. Renderiza un panel de resultados con score, pass/fail badge y feedback messages.
  5. Emite coSubmit event con { values, score: ScoreResult }.
  • Escalares: loose equality (==), así "5" == 5 es true.
  • Arrays (multi-select): order-insensitive — ["a","b"] matchea ["b","a"].
┌─ co-form-wizard (data-theme, data-density, ...) ─────────┐
│ │
│ ┌─ Title block card ────────────────────────────────┐ │
│ │ Form title (h1) │ │
│ │ Form description │ │
│ └───────────────────────────────────────────────────┘ │
│ │
│ Stepper: ① Page 1 ② Page 2 ③ Page 3 │
│ │
│ ┌─ Page card (active) ──────────────────────────────┐ │
│ │ ┌─ Page head ─────────────────────────────────┐ │ │
│ │ │ PAGE 2 pill │ │ │
│ │ │ Page title (h2) │ │ │
│ │ │ Page description │ │ │
│ │ └─────────────────────────────────────────────┘ │ │
│ │ │ │
│ │ <co-form> con los fields de esta page │ │
│ │ │ │
│ │ ┌─ Nav ────────────────────────────────────────┐ │ │
│ │ │ [Anterior] [Siguiente] │ │ │
│ │ └─────────────────────────────────────────────┘ │ │
│ └───────────────────────────────────────────────────┘ │
└──────────────────────────────────────────────────────────┘
<co-form-wizard
schema='{ "title": "...", "pages": [...] }'
theme='{ "colorScheme": "dark", "accent": "verde" }'
layout="grid"
columns="1"
></co-form-wizard>
<script>
const wizard = document.querySelector('co-form-wizard');
wizard.addEventListener('coSubmit', (ev) => {
console.log('Values:', ev.detail.values);
console.log('Score:', ev.detail.score); // solo en mode: quiz
});
wizard.addEventListener('coPageChange', (ev) => {
console.log('Now on page', ev.detail.index);
});
</script>
PropTipoDefaultDescripción
schemastring (JSON)requiredPaged schema con pages[].
themestring (JSON)Theme spec — ver Theme.
initial-valuesstring (JSON)'{}'Pre-fill global, distribuye automáticamente por página.
locale'en' | 'es' | 'pt''es'Idioma de errores AJV.
layout'grid' | 'stack''grid'Layout pasado al <co-form> interno.
columns1 | 2 | 3 | 41Columnas del grid.
EventPayloadCuándo
coSubmit{ values, score? }Al completar el último step. score solo en mode: quiz.
coPageChange{ index, page }Cambio de page activa (manual o via stepper).