-
Shadcn Dialog에서 Textarea 내부 Enter 키가 동작하지 않는다면?Front-end 2025. 1. 10. 09:35반응형
최근 NextJS, Typescript, Shadcn을 이용해서 사내 CRM 프로젝트를 만들고 있다.
CRM이다보니 Dialog 내부에서 여러가지 multi-form 형식의 처리가 많이 들어간다.
우리 팀은 Shadcn을 사용하고 있으므로 Shadcn의 Dialog를 사용했는데 Dialog 내부의 Textarea에서 Enter를 입력해도 아래로 커서가 내려가지 않는 현상이 발생했다.
우선 첫 번째로 든 생각은 Textarea에서 Enter key 사용이 되는지 확인해보는 것이었다.
Textarea에 onKeyDown을 사용해서 콘솔을 찍어보면 Enter가 제대로 먹히고 있는 것은 확인할 수 있다.
그러면 다른 곳에서 인터셉트 해간다는 생각을 해야할 것이다.
나는 Shadcn의 Dialog만 사용하고 내부적인 것들은 다 커스텀해서 사용하고 있다.
그러다보니 Enter 자체가 Dialog 내부 실행에 대한 액션을 한다는 것을 깜빡했다.
문제
Dialog는 Enter key를 Action trigger로 사용한다는 것이다.
물론 설계 자체에서 사용자 접근성과 키보드 사용자를 지원하기 위한 일반적인 패턴일 수 있지만 커스텀을 해서 Modal 형식으로 띄워놓다보니 그 생각을 못했다.
또한, Dialog는 열려 있을 때 Focus가 Dialog 내에서만 이동하도록 제어(focus trapping)된다고 한다. 이런 과정에서 Enter key event 또한 인터셉트 될 수 있는 것이다.
그렇다면 Textarea에 아래와 같이 코드를 사용하면 안될까?
<Textarea onKeyDown={(e) => { if (e.key === 'Enter') { e.stopPropagation(); // Textarea에서 이벤트 전파 차단 } }} />
답은 이걸로 해결할 수 없다 이다. 이렇게 해도 똑같이 Enter key가 Textarea 내부에서 동작하지 않을 것이다.
Shadcn의 Dialog는 React Portal을 사용해서 DialogContent를 렌더링하는데 Textarea는 DialogConent 내부에 렌더링 되지만 DialogContent는 Portal을 통해 다른 DOM 계층에 렌더링된다.
React는 이벤트 버블링 할 때 DOM 계층을 기준으로 이벤트를 전파하는데, Textarea의 onKeyDown은 DialogContent로 전파되지 않을 수 있다.
그러니 React Portal의 부모(Dialog 혹은 Dialogcontent)에서 이벤트가 처리되어야한다.
방법
알고 나면 방법은 간단하다.
Textarea에 onKeyDown을 주는 것이 아니라 DialogContent에 onKeyDown을 주면 되는 것이다.
<Dialog> <DialogContent onKeyDown={(e) => { if (e.key === 'Enter') { e.stopPropagation(); // DialogContent에서 이벤트 전파 중단 } }} > <Textarea /> </DialogContent> </Dialog>
반응형'Front-end' 카테고리의 다른 글
React 프론트엔드 개발자의 상태관리 기법과 이유 (0) 2024.05.23