Fix modal scrolling
This commit is contained in:
parent
bc4b0e2df7
commit
683cd039e7
6 changed files with 27 additions and 0 deletions
|
|
@ -2,6 +2,7 @@ import React, { useState } from 'react';
|
||||||
import { motion } from 'framer-motion';
|
import { motion } from 'framer-motion';
|
||||||
import { X, Plus, Trash2, Triangle, Diamond, Circle, Square, Clock } from 'lucide-react';
|
import { X, Plus, Trash2, Triangle, Diamond, Circle, Square, Clock } from 'lucide-react';
|
||||||
import { Question, AnswerOption } from '../types';
|
import { Question, AnswerOption } from '../types';
|
||||||
|
import { useBodyScrollLock } from '../hooks/useBodyScrollLock';
|
||||||
|
|
||||||
interface QuestionEditModalProps {
|
interface QuestionEditModalProps {
|
||||||
question: Question;
|
question: Question;
|
||||||
|
|
@ -39,6 +40,8 @@ export const QuestionEditModal: React.FC<QuestionEditModalProps> = ({
|
||||||
const [options, setOptions] = useState<AnswerOption[]>(question.options);
|
const [options, setOptions] = useState<AnswerOption[]>(question.options);
|
||||||
const [timeLimit, setTimeLimit] = useState(question.timeLimit);
|
const [timeLimit, setTimeLimit] = useState(question.timeLimit);
|
||||||
|
|
||||||
|
useBodyScrollLock(true);
|
||||||
|
|
||||||
const handleOptionTextChange = (index: number, newText: string) => {
|
const handleOptionTextChange = (index: number, newText: string) => {
|
||||||
setOptions(prev => prev.map((opt, i) =>
|
setOptions(prev => prev.map((opt, i) =>
|
||||||
i === index ? { ...opt, text: newText } : opt
|
i === index ? { ...opt, text: newText } : opt
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ import { arrayMove, SortableContext, sortableKeyboardCoordinates, verticalListSo
|
||||||
import { Quiz, Question } from '../types';
|
import { Quiz, Question } from '../types';
|
||||||
import { SortableQuestionCard } from './SortableQuestionCard';
|
import { SortableQuestionCard } from './SortableQuestionCard';
|
||||||
import { QuestionEditModal } from './QuestionEditModal';
|
import { QuestionEditModal } from './QuestionEditModal';
|
||||||
|
import { useBodyScrollLock } from '../hooks/useBodyScrollLock';
|
||||||
import { v4 as uuidv4 } from 'uuid';
|
import { v4 as uuidv4 } from 'uuid';
|
||||||
|
|
||||||
interface QuizEditorProps {
|
interface QuizEditorProps {
|
||||||
|
|
@ -31,6 +32,8 @@ export const QuizEditor: React.FC<QuizEditorProps> = ({
|
||||||
const [showDeleteConfirm, setShowDeleteConfirm] = useState<string | null>(null);
|
const [showDeleteConfirm, setShowDeleteConfirm] = useState<string | null>(null);
|
||||||
const [titleEditing, setTitleEditing] = useState(false);
|
const [titleEditing, setTitleEditing] = useState(false);
|
||||||
|
|
||||||
|
useBodyScrollLock(!!showDeleteConfirm);
|
||||||
|
|
||||||
const sensors = useSensors(
|
const sensors = useSensors(
|
||||||
useSensor(PointerSensor, {
|
useSensor(PointerSensor, {
|
||||||
activationConstraint: { distance: 8 }
|
activationConstraint: { distance: 8 }
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ import React, { useState } from 'react';
|
||||||
import { motion, AnimatePresence } from 'framer-motion';
|
import { motion, AnimatePresence } from 'framer-motion';
|
||||||
import { X, Trash2, Play, BrainCircuit, PenTool, Loader2, Calendar } from 'lucide-react';
|
import { X, Trash2, Play, BrainCircuit, PenTool, Loader2, Calendar } from 'lucide-react';
|
||||||
import { QuizListItem } from '../types';
|
import { QuizListItem } from '../types';
|
||||||
|
import { useBodyScrollLock } from '../hooks/useBodyScrollLock';
|
||||||
|
|
||||||
interface QuizLibraryProps {
|
interface QuizLibraryProps {
|
||||||
isOpen: boolean;
|
isOpen: boolean;
|
||||||
|
|
@ -31,6 +32,8 @@ export const QuizLibrary: React.FC<QuizLibraryProps> = ({
|
||||||
const [confirmDeleteId, setConfirmDeleteId] = useState<string | null>(null);
|
const [confirmDeleteId, setConfirmDeleteId] = useState<string | null>(null);
|
||||||
const isAnyOperationInProgress = loading || !!loadingQuizId || !!deletingQuizId;
|
const isAnyOperationInProgress = loading || !!loadingQuizId || !!deletingQuizId;
|
||||||
|
|
||||||
|
useBodyScrollLock(isOpen);
|
||||||
|
|
||||||
const handleDeleteClick = (e: React.MouseEvent, id: string) => {
|
const handleDeleteClick = (e: React.MouseEvent, id: string) => {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
setConfirmDeleteId(id);
|
setConfirmDeleteId(id);
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { motion } from 'framer-motion';
|
import { motion } from 'framer-motion';
|
||||||
import { Save, Copy, X } from 'lucide-react';
|
import { Save, Copy, X } from 'lucide-react';
|
||||||
|
import { useBodyScrollLock } from '../hooks/useBodyScrollLock';
|
||||||
|
|
||||||
interface SaveOptionsModalProps {
|
interface SaveOptionsModalProps {
|
||||||
isOpen: boolean;
|
isOpen: boolean;
|
||||||
|
|
@ -17,6 +18,8 @@ export const SaveOptionsModal: React.FC<SaveOptionsModalProps> = ({
|
||||||
onOverwrite,
|
onOverwrite,
|
||||||
isSaving
|
isSaving
|
||||||
}) => {
|
}) => {
|
||||||
|
useBodyScrollLock(isOpen);
|
||||||
|
|
||||||
if (!isOpen) return null;
|
if (!isOpen) return null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
import React, { useState } from 'react';
|
import React, { useState } from 'react';
|
||||||
import { motion, AnimatePresence } from 'framer-motion';
|
import { motion, AnimatePresence } from 'framer-motion';
|
||||||
import { Save, X, Loader2, BrainCircuit } from 'lucide-react';
|
import { Save, X, Loader2, BrainCircuit } from 'lucide-react';
|
||||||
|
import { useBodyScrollLock } from '../hooks/useBodyScrollLock';
|
||||||
|
|
||||||
interface SaveQuizPromptProps {
|
interface SaveQuizPromptProps {
|
||||||
isOpen: boolean;
|
isOpen: boolean;
|
||||||
|
|
@ -17,6 +18,8 @@ export const SaveQuizPrompt: React.FC<SaveQuizPromptProps> = ({
|
||||||
}) => {
|
}) => {
|
||||||
const [isSaving, setIsSaving] = useState(false);
|
const [isSaving, setIsSaving] = useState(false);
|
||||||
|
|
||||||
|
useBodyScrollLock(isOpen);
|
||||||
|
|
||||||
const handleSave = async () => {
|
const handleSave = async () => {
|
||||||
setIsSaving(true);
|
setIsSaving(true);
|
||||||
try {
|
try {
|
||||||
|
|
|
||||||
12
hooks/useBodyScrollLock.ts
Normal file
12
hooks/useBodyScrollLock.ts
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
import { useEffect } from 'react';
|
||||||
|
|
||||||
|
export const useBodyScrollLock = (isLocked: boolean) => {
|
||||||
|
useEffect(() => {
|
||||||
|
if (isLocked) {
|
||||||
|
document.body.style.overflow = 'hidden';
|
||||||
|
}
|
||||||
|
return () => {
|
||||||
|
document.body.style.overflow = '';
|
||||||
|
};
|
||||||
|
}, [isLocked]);
|
||||||
|
};
|
||||||
Loading…
Add table
Add a link
Reference in a new issue