table형태로 정보를 보여주고 한 행을 선택할 수 있는 select를 만들어보기로 했다.

popper를 사용함

 

1. import

import Box from "@mui/material/Box";
import Popper from "@mui/material/Popper";

 

2. return에서 사용

<div onClick={(e: React.MouseEvent<HTMLElement>) => {
	setOpenTable((prev) => !prev);
	setAnchorEl(e.currentTarget);
}}>
	<Popper open={openTable} anchorEl={anchorEl} placement="bottom-end" sx={{ zIndex: "1500", position: "absolute" }}>
		<Box sx={{ bgcolor: "background.paper", overflowY: "auto", maxHeight: "250px", width: "fit-content" }}>
			<table>원하는 테이블 작성</table>
		</Box>
	</Popper>
</div>

div에 anchorEl를 걸고, 클릭할때 table을 open할 state를 따로 설정해서 open에 적어줍니다(openTable)

MUI의 Tooltip은 hover시에만 유지되고 요구사항에 맞지않는 점이 있어서 popper로 변경해보기로 하였다.

 

내가 원하는 모습 : 클릭으로  toggle하고, 유지되었다가 닫기 상호작용이 가능한 tooltip


1. import

import Popper from "@mui/material/Popper";
import CloseIcon from "@mui/icons-material/Close";

 

2. 사용하기

const [anchorEl, setAnchorEl] = useState<null | HTMLElement>(null);
const tooltipOpen = Boolean(anchorEl);
...
<div onClick={(e) => setAnchorEl(anchorEl ? null : e.currentTarget)}>
	<Popper open={tooltipOpen} anchorEl={anchorEl} sx={{ zIndex: "1500", position: "absolute" }} placement="bottom-start">
		<div className="flex flex-row text-xs w-[200px] bg-white rounded-md shadow-md p-2 border border-solid mt-2">
			<div className="flex items-center justify-center p-1">{코멘트코멘트코멘트}</div>
				<div className="flex pl-2 text-gray-500 cursor-pointer hover:text-gray-700" onClick={() => setAnchorEl(null)}>
				<CloseIcon fontSize="small"/>
			</div>
		</div>
	</Popper>
</div>

 

주의할점은 popper가 나타날 주체인 아이콘이던 div던에 anchorEl을 걸어줘야 작동합니다.

 

저는 zIndex가 높은 div에서 작업했기때문에 별도로 z index를 보다 높게 지정했습니다.

MUI Tooltip을 커스텀없이 사용했을때의 모습

 

내가 필요한것 : 흰바탕에 검정글씨 툴팁

 

1. import

import Tooltip, { TooltipProps, tooltipClasses } from "@mui/material/Tooltip";
import { styled } from "@mui/material/styles";

 

2. lightTooltip 별도 선언

- 함수 컴포넌트 외부에 선언해도 괜찮습니다

const LightTooltip = styled(({ className, ...props }: TooltipProps) => <Tooltip {...props} classes={{ popper : className }} />)(({ theme }) => ({
	[`& .${tooltipClasses.tooltip}`]: {
    	backgroundColor : theme.palette.common.white,
        color: "rgba(0,0,0,0.87)",
        boxShadow: theme.shadows[1],
        fontSize: 11,
        width: 150,
        lineHeight: 1.5,
       },
 }));

 

3. return 절에서 사용

<LightTooltip title ={툴팁에 들어갈 내용}></LightTooltip>

 

MUI의 Modal 컴포넌트는 해당 div 외부 클릭시에 닫히는 기능이 지원되는데, 해당 기능을 컨트롤 하려고 한다.

 

일단, Modal

<Modal open={isToggle} onClose={onClose}>

open은 열고 닫기를 조절하는 state이고,(bool)

onClose는 모달이 닫힐때 실행하는 함수이다.

보통은 내용 초기화 등을 진행하였다.

 

그러나 외부 클릭을 조작하려면 일단, onClose에 매개변수를 하나 더 받아야 한다.

<Modal open={isPiggeryToggle} onClose={(_, reason) => onClose(reason)}>

이렇게 넘겨주고 함수 작성하기.

 

type CloseReason = "backdropClick" | "escapeKeyDown" | "closeButtonClick";

const onClose = (value: CloseReason) => {
    // 뒷배경 클릭이나 esc 키로는 닫기가 작동하지 않도록
    if (value === "backdropClick" || value === "escapeKeyDown") {
      return;
    } else {
      setIsToggle(false)
    }
  };

이렇게 작성해서 예외처리 해주면 끝!

MUI의 accordion 컴포넌트에서 헤맸던 부분을 정리하기 위함!

https://mui.com/material-ui/api/accordion/

 

Accordion API - Material UI

API reference docs for the React Accordion component. Learn about the props, CSS, and other APIs of this exported module.

mui.com

MUI 사이트에서 정보를 찾아볼때, 예시코드가 있는 페이지도 좋지만 상세 컨트롤을 원할땐 API가 별도 서술되어 있는 페이지가 원하는 기능을 찾기에 적합하다.

 

1. 한 항목을 클릭하면 다른항목 자동 접기

<Accordion expanded={o.id === selectedNumber} >

expanded 옵션을 사용하면 state 값으로 accordion을 조절 할수 있다!

한번에 모두 접기 + 펼치기 옵션도 해당 버튼 true false 값을 state로 지정하고 expanded에 넣어주면 구현 가능하다.

나 같은 경우는 해당 accordion 클릭시 정보의 id가 선택된 값에 들어가는데, expanded에 해당 값일때만 expanded가 되도록 설정 해두었고, 이렇게 하면 다른 accordion을 클릭하면 이전에 열었던 부분은 자동으로 닫힌다!

 

-) 이렇게 설정하면 해당 아코디언을 다시 눌렀을때 닫혔다 열렸다 하는 부분이 지원되지 않는다ㅠㅠ 여러개를 동시에 여는 동작도 불가함

 

2. 체크박스 이용시에 accordion 동작 막기

소박하게 그려보았따...그림판으로

체크박스가 들어간 아코디언을 만들었는데,

1. (핑크) 체크박스 + 라벨(이름) 클릭시에는 클릭한 이름 state에 해당값을 넣으나 아코디언은 움직이지 않기

2. (하늘) 핑크 부분 외의 여백 누르면 아코디언 열고 닫기가 작동, 체크박스 반응 없음

이런 로직을 원했음

<Accordion>
	<AccordionSummary>
		<div>
			<input
			value={o.id}
			id={o.id}
			type="checkbox"
			// 체크박스를 클릭해도 아코디언이 움직이지 않게 설정
			onClick={(e) => e.stopPropagation()}
			/>
			{/* 라벨 클릭시에는 체크박스 체크되고 아코디언 움직임 비활성화 */}
			<label htmlFor={o.id} onClick={(e) => e.stopPropagation()}>
				{o.name}
			</label>
		</div>
	</AccordionSummary>
	<AccordionDetails>
	// accordion deatils...
	</AccordionDetails>
</Accordion>

input:checkbox와 label에 각각 e.stopPropagation()으로 이벤트 전파를 막아주면 된다!

이미 모달이 뜬 상태에서 또 그위에 Modal 기능을 쓰고싶었다
생각보다 간단했음!

 

일단 상단에 모달 선언하기
(모달을 사용하고 있는 컴포넌트)

<DetailModal isDetailToggle={isDetailToggle} setIsDetailToggle={setIsDetailToggle} />
.
.
.
<span onClick={() => setIsDetailToggle(true)}>
모달열기
</span>

그리고 onClick으로 state만 변경해주면 된다

생각보다 검색으로는 답이 명확하게 안나왔었다...

단점은 이게 해당 id의 보고서로 들어가는 버튼이라 새 모달에 id버튼이 있으면 무한으로 계속 열린다는 것
나중에 열리는 횟수를 제한한다던가 하는 다른 방식으로 바꿔야겠다


그리고 Modal위에 Popper를 띄울때!

Modal에 Tooltip이 필요했으나,
닫기 버튼이 포함된 툴팁이어야해서 Tooltip 컴포넌트가 아닌 Popper를 사용하였다

처음에 계속 클릭해도 안떠서 내가 Popper를 잘못 사용한줄 알았었는데,

Modal 자체의 zindex를 넘기지 못해서 Modal 아래에 Popper가 떴던것이었다

 {/* 모달의 zindex가 1300임 */}
<Popper open={tooltipOpen} anchorEl={anchorEl} sx={{ zIndex: "1500", position: "absolute" }} placement="bottom-start">

모달의 zindex인 1300보다 크게 지정해주면 됨!

둘다 간단하지만 조금 오래 헤맸던 기억이 있어서 같이 작성해보았다