Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

모달에서 ScrollSnapContainer의 스와이프가 동작하는 오류 수정 #517

Merged
merged 6 commits into from
Oct 5, 2023
4 changes: 3 additions & 1 deletion client/src/components/CafeDetailBottomSheet.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Suspense, useEffect } from 'react';
import { BsBoxArrowUpRight, BsGeoAlt, BsX } from 'react-icons/bs';
import { styled } from 'styled-components';
import useCafeMenus from '../hooks/useCafeMenus';
import useScrollSnapGuard from '../hooks/useScrollSnapGuard';
import type { Theme } from '../styles/theme';
import type { Cafe } from '../types';
import CafeMenuMiniList from './CafeMenuMiniList';
Expand All @@ -14,6 +15,7 @@ type CafeDetailBottomSheetProps = {

const CafeDetailBottomSheet = (props: CafeDetailBottomSheetProps) => {
const { cafe, onClose } = props;
const scrollSnapGuardHandlers = useScrollSnapGuard();

useEffect(() => {
document.addEventListener('click', onClose);
Expand All @@ -26,7 +28,7 @@ const CafeDetailBottomSheet = (props: CafeDetailBottomSheetProps) => {
};

return (
<Container onClick={handlePreventClickPropagation} role="dialog" aria-modal="true">
<Container onClick={handlePreventClickPropagation} role="dialog" aria-modal="true" {...scrollSnapGuardHandlers}>
<CloseButton>
<CloseIcon onClick={onClose} />
</CloseButton>
Expand Down
4 changes: 3 additions & 1 deletion client/src/components/CafeMenuBottomSheet.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { createPortal } from 'react-dom';
import { BsX } from 'react-icons/bs';
import { styled } from 'styled-components';
import useCafeMenus from '../hooks/useCafeMenus';
import useScrollSnapGuard from '../hooks/useScrollSnapGuard';
import type { Theme } from '../styles/theme';
import type { Cafe } from '../types';
import Resource from '../utils/Resource';
Expand All @@ -20,6 +21,7 @@ const CafeMenuBottomSheet = (props: CafeMenuBottomSheetProps) => {
data: { menus, menuBoards },
} = useCafeMenus(cafe.id);
const [isImageModalOpen, setIsImageModalOpen] = useState(false);
const scrollSnapGuardHandlers = useScrollSnapGuard();

useEffect(() => {
document.addEventListener('click', onClose);
Expand All @@ -37,7 +39,7 @@ const CafeMenuBottomSheet = (props: CafeMenuBottomSheetProps) => {
return (
<>
{createPortal(
<Container onClick={handlePreventClickPropagation}>
<Container onClick={handlePreventClickPropagation} {...scrollSnapGuardHandlers}>
<CloseButton>
<CloseIcon onClick={onClose} />
</CloseButton>
Expand Down
4 changes: 3 additions & 1 deletion client/src/components/ImageModal.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type { MouseEventHandler } from 'react';
import { useState } from 'react';
import { styled } from 'styled-components';
import useScrollSnapGuard from '../hooks/useScrollSnapGuard';
import Resource from '../utils/Resource';

type ImageModalProps = {
Expand All @@ -11,6 +12,7 @@ type ImageModalProps = {
const ImageModal = (props: ImageModalProps) => {
const { imageUrls, onClose } = props;
const [activeImage, setActiveImage] = useState(imageUrls[0]);
const scrollSnapGuardHandlers = useScrollSnapGuard();

const handleContainerClick: MouseEventHandler = (event) => {
if (event.currentTarget !== event.target) return;
Expand All @@ -19,7 +21,7 @@ const ImageModal = (props: ImageModalProps) => {
};

return (
<Container>
<Container {...scrollSnapGuardHandlers}>
<ActiveImageContainer onClick={handleContainerClick}>
<ActiveImage src={Resource.getImageUrl({ size: 'original', filename: activeImage })} />
</ActiveImageContainer>
Expand Down
31 changes: 31 additions & 0 deletions client/src/hooks/useScrollSnapGuard.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import type { EventHandler, SyntheticEvent } from 'react';
import { useCallback, useMemo } from 'react';

/**
* ScrollSnapContainer의 하위 요소에서 열린 모달에서 스크롤 혹은 스와이프를 할 시
* ScrollSnapContainer에 전파되어 스와이프가 동작하는 문제가 발생합니다.
* ScrollSnapContainer의 스와이프가 동작하지 않도록 갖가지 이벤트의 propagation을 막아주는 훅입니다.
*/
const useScrollSnapGuard = () => {
const preventPropagation: EventHandler<SyntheticEvent> = useCallback((event) => {
event.stopPropagation();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ㅋㅋㅋㅋ event.stopPropagation()으로 모달에서 스와이프가 동작하는 오류를 수정하셨군여!

좋습니당

}, []);

const handlers = useMemo(
() => ({
onTouchStart: preventPropagation,
onTouchMove: preventPropagation,
onTouchEnd: preventPropagation,
onMouseDown: preventPropagation,
onMouseMove: preventPropagation,
onMouseUp: preventPropagation,
onMouseLeave: preventPropagation,
onWheel: preventPropagation,
}),
[preventPropagation],
);

return handlers;
};

export default useScrollSnapGuard;
Loading