Auto-Scroll Implementado en Drag & Drop

Frontend v1.0.75
Nueva Funcionalidad:

 Auto-scroll automático cuando arrastras cerca de los bordes del modal
 Zona de activación: 100 pixeles desde arriba/abajo
 Scroll suave: 10 pixeles cada 16ms (~60fps)
 Limpieza automática: Detiene el scroll cuando sueltas o sales del área
Cómo Funciona:

Arrastras una pregunta cerca del borde superior → scroll automático hacia arriba
Arrastras cerca del borde inferior → scroll automático hacia abajo
Alejas del borde → scroll se detiene
Sueltas la pregunta → scroll se limpia
This commit is contained in:
2025-11-27 16:52:35 -03:00
parent ce151631ab
commit 1c9d7348ed
2 changed files with 57 additions and 1 deletions

View File

@@ -1,7 +1,7 @@
{ {
"name": "checklist-frontend", "name": "checklist-frontend",
"private": true, "private": true,
"version": "1.0.74", "version": "1.0.75",
"type": "module", "type": "module",
"scripts": { "scripts": {
"dev": "vite", "dev": "vite",

View File

@@ -930,6 +930,8 @@ function QuestionsManagerModal({ checklist, onClose }) {
const [loadingAudit, setLoadingAudit] = useState(false) const [loadingAudit, setLoadingAudit] = useState(false)
const [draggedQuestion, setDraggedQuestion] = useState(null) const [draggedQuestion, setDraggedQuestion] = useState(null)
const [dragOverQuestion, setDragOverQuestion] = useState(null) const [dragOverQuestion, setDragOverQuestion] = useState(null)
const scrollContainerRef = useRef(null)
const autoScrollIntervalRef = useRef(null)
const [formData, setFormData] = useState({ const [formData, setFormData] = useState({
section: '', section: '',
text: '', text: '',
@@ -1225,6 +1227,12 @@ function QuestionsManagerModal({ checklist, onClose }) {
e.currentTarget.style.opacity = '1' e.currentTarget.style.opacity = '1'
setDraggedQuestion(null) setDraggedQuestion(null)
setDragOverQuestion(null) setDragOverQuestion(null)
// Limpiar auto-scroll
if (autoScrollIntervalRef.current) {
clearInterval(autoScrollIntervalRef.current)
autoScrollIntervalRef.current = null
}
} }
const handleDragOver = (e, question) => { const handleDragOver = (e, question) => {
@@ -1250,10 +1258,58 @@ function QuestionsManagerModal({ checklist, onClose }) {
e.dataTransfer.dropEffect = 'move' e.dataTransfer.dropEffect = 'move'
setDragOverQuestion(question) setDragOverQuestion(question)
// Auto-scroll cuando está cerca de los bordes
if (scrollContainerRef.current) {
const container = scrollContainerRef.current
const rect = container.getBoundingClientRect()
const scrollThreshold = 100 // Pixeles desde el borde para activar scroll
const scrollSpeed = 10 // Velocidad de scroll
const mouseY = e.clientY
const distanceFromTop = mouseY - rect.top
const distanceFromBottom = rect.bottom - mouseY
// Limpiar intervalo anterior si existe
if (autoScrollIntervalRef.current) {
clearInterval(autoScrollIntervalRef.current)
autoScrollIntervalRef.current = null
}
// Scroll hacia arriba
if (distanceFromTop < scrollThreshold && container.scrollTop > 0) {
autoScrollIntervalRef.current = setInterval(() => {
if (container.scrollTop > 0) {
container.scrollTop -= scrollSpeed
} else {
clearInterval(autoScrollIntervalRef.current)
autoScrollIntervalRef.current = null
}
}, 16) // ~60fps
}
// Scroll hacia abajo
else if (distanceFromBottom < scrollThreshold &&
container.scrollTop < container.scrollHeight - container.clientHeight) {
autoScrollIntervalRef.current = setInterval(() => {
if (container.scrollTop < container.scrollHeight - container.clientHeight) {
container.scrollTop += scrollSpeed
} else {
clearInterval(autoScrollIntervalRef.current)
autoScrollIntervalRef.current = null
}
}, 16) // ~60fps
}
}
} }
const handleDragLeave = (e) => { const handleDragLeave = (e) => {
setDragOverQuestion(null) setDragOverQuestion(null)
// Limpiar auto-scroll si sale del área
if (autoScrollIntervalRef.current) {
clearInterval(autoScrollIntervalRef.current)
autoScrollIntervalRef.current = null
}
} }
const handleDrop = async (e, targetQuestion) => { const handleDrop = async (e, targetQuestion) => {