Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
Tags
- 공인IP
- Replication
- html #select #option #multiple
- invalid data
- 맥 어드레스
- AntDesign
- mySQL_Replication
- 1883
- mosquitto.conf
- pm2 상태 확인
- map이 undefined가 뜰 때
- datagridview 직접입력
- pm2 확인
- pm2 설치
- 데이터테이블 데이터 넣기
- c# datagridview 데이터 넣기
- listener 1883
- DataGridView 직접 입력
- mosquitto
- pm2 시작
- setInterval 외부 정지
- setInterval 정지
- timepicker
- transfer
- allow_anonymouse
- 서버동기화
- pm2
- setInterval clear
- DatePicker
- setInterval 중지
Archives
- Today
- Total
개발 노트
modal dialog component만들기 본문
1. zustand 에 modal dialog관련 store생성하기
import {create} from 'zustand';
interface ModalState {
isModalOpen: boolean;
openModal: () => void;
closeModal: () => void;
}
// 모달 상태를 관리하는 스토어
export const useModalStore = create<ModalState>((set) => ({
isModalOpen: false, // 모달의 초기 상태는 닫혀있음
openModal: () => set({ isModalOpen: true }), // 모달을 여는 액션
closeModal: () => set({ isModalOpen: false }), // 모달을 닫는 액션
}));
2. Component만들기
- draggable한 modalComponent를 만들기위해 mouseup mousedown mousemove이벤트핸들러 이용
- 뒤쪽 배경을 누르면 종료되게 설정 이벤트 버블링을 막기위해서 e.stopPropagation과 e.preventDefault 적절하게 활용하기
- 배경보다 상위에 노출되기 위해 z-index적용하기
import { useState, useEffect } from 'react';
import { useModalStore } from '@/store/useModalStore';
// 마우스 이벤트 핸들러에서 사용될 위치 타입 정의
interface Position {
x: number;
y: number;
}
const ModalComponent: React.FC = () => {
const { isModalOpen, closeModal } = useModalStore();
const [position, setPosition] = useState<Position>({ x: 0, y: 0 });
const [dragging, setDragging] = useState<boolean>(false);
// 마우스 클릭 위치 저장 변수의 타입도 Position으로 지정
const [rel, setRel] = useState<Position | null>(null);
const { groupedMessages } = useMqttWorkerStore();
//표시될 내용 관련부분 생략
useEffect(() => {
// 화면의 크기를 기반으로 중앙 위치 계산
const updatePosition = () => {
const x = window.innerWidth / 2;
const y = window.innerHeight / 2;
setPosition({ x, y });
};
// 컴포넌트 마운트 시에 위치 업데이트
updatePosition();
}, []); // 빈 의존성 배열로 마운트 시에만 실행
useEffect(() => {
const moveHandler = (e: MouseEvent) => handleMouseMove(e);
const upHandler = (e: MouseEvent) => handleMouseUpDOM(e);
if (dragging) {
document.addEventListener('mousemove', moveHandler);
document.addEventListener('mouseup', upHandler);
} else {
document.removeEventListener('mousemove', moveHandler);
document.removeEventListener('mouseup', upHandler);
}
return () => {
document.removeEventListener('mousemove', moveHandler);
document.removeEventListener('mouseup', upHandler);
};
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [dragging, rel]);
if (!isModalOpen) return null;
const handleMouseDown = (e: React.MouseEvent<HTMLDivElement>) => {
setDragging(true);
setRel({
x: e.pageX - position.x,
y: e.pageY - position.y,
});
e.stopPropagation();
e.preventDefault();
};
const handleMouseMove = (e: MouseEvent) => {
if (!dragging || !rel) return;
setPosition({
x: e.pageX - rel.x,
y: e.pageY - rel.y,
});
e.stopPropagation();
e.preventDefault();
};
// DOM 이벤트를 위한 핸들러
const handleMouseUpDOM = (e: MouseEvent) => {
if (!dragging) return;
setDragging(false);
e.stopPropagation();
e.preventDefault();
};
// 리액트 이벤트를 위한 핸들러
const handleMouseUpReact = (e: React.MouseEvent<HTMLDivElement>) => {
e.stopPropagation();
e.preventDefault();
setDragging(false);
};
return (
<div onClick={closeModal} className="fixed bg-[rgba(167,221,158,0.5)] w-screen h-screen z-[100] top-0">
<div
style={{ left: `${position.x}px`, top: `${position.y}px` }}
className="fixed bg-white border min-w-96 min-h-80 p-5 rounded-lg cursor-move"
onMouseDown={handleMouseDown}
onMouseUp={handleMouseUpReact}
onClick={(e)=>e.stopPropagation()}
>
<p className="text-black">모달창입니다</p>
<button
type="button"
onClick={(e: React.MouseEvent<HTMLButtonElement>) => {
e.stopPropagation();
closeModal();
}}
className="absolute text-lg top-4 right-5"
>
×
</button>
</div>
</div>
);
};
export default ModalComponent;
3. Component호출하기
'React' 카테고리의 다른 글
새 글 정보 알람 기능 (0) | 2024.03.22 |
---|---|
로컬스토리지에 값 저장하기 (0) | 2024.03.22 |
필터기능 구현 (0) | 2024.03.18 |
자료구조 변경 비교 (0) | 2024.03.13 |
Next.js에서 mysql2 연결하기 (net error 해결기) (0) | 2024.02.29 |