diff --git a/app/globals.css b/app/globals.css index 50694ff..7011baa 100644 --- a/app/globals.css +++ b/app/globals.css @@ -602,7 +602,13 @@ body { overflow-y: auto; padding-bottom: 8px; } -.wizard-answer-area::after { +/* El fade SOLO se pinta cuando .wizard-answer-area mide overflow real + (clase has-overflow agregada por JS — ver wizard-form.tsx). CSS no tiene + forma de detectar scrollHeight > clientHeight por sí solo: un ::after + incondicional (o un mask-image fijo) se pinta igual sobre el final de la + caja aunque el contenido entre completo, mostrando una franja/degradado + fantasma en preguntas cortas. */ +.wizard-answer-area.has-overflow::after { content: ''; position: sticky; bottom: 0; diff --git a/components/wizard-form.tsx b/components/wizard-form.tsx index 4f4210a..3a472bc 100644 --- a/components/wizard-form.tsx +++ b/components/wizard-form.tsx @@ -1,5 +1,5 @@ 'use client' -import { useEffect, useState } from 'react' +import { useEffect, useLayoutEffect, useRef, useState } from 'react' import type { BrandConfig, Survey } from '@/lib/types' import type { AnswerValue, FormAnswers, FormSchema, Screen } from '@/lib/form-engine.types' import { @@ -52,6 +52,8 @@ export function WizardForm({ survey, schema }: WizardFormProps) { const [errors, setErrors] = useState>({}) const [hydrated, setHydrated] = useState(false) const [a11yAnnounce, setA11yAnnounce] = useState('') + const answerAreaRef = useRef(null) + const [hasOverflow, setHasOverflow] = useState(false) useEffect(() => { const draft = loadDraft(survey.id) @@ -78,6 +80,24 @@ export function WizardForm({ survey, schema }: WizardFormProps) { else setA11yAnnounce('Fin del formulario') }, [screen?.id]) + // El fade de wizard-answer-area solo debe aparecer si hay overflow real — + // CSS no puede expresar esa condición (no hay selector para "este elemento + // scrollea"), así que se mide el DOM. Se remide al cambiar de pantalla + // (cambia todo el contenido) y al resize (puede cambiar cuántas opciones entran). + useLayoutEffect(() => { + const el = answerAreaRef.current + setHasOverflow(el ? el.scrollHeight > el.clientHeight : false) + }, [screen?.id]) + + useEffect(() => { + function recalc() { + const el = answerAreaRef.current + setHasOverflow(el ? el.scrollHeight > el.clientHeight : false) + } + window.addEventListener('resize', recalc) + return () => window.removeEventListener('resize', recalc) + }, []) + if (stage === 'consent') { return ( {screen.question.prompt} {screen.question.hint &&

{screen.question.hint}

} -
+