fix(rails): LLM 응답 텍스트 드래그/복사 가능하게 + drawer drag-select 보호
자기야 요청: 대시보드의 LLM 응답 본문을 드래그해서 복사하고 싶음. 수정: - LlmOutput 에 user-select: text + cursor: text 를 명시. 부모 어딘가에서 상속받을 가능성을 차단. ::selection 색상도 추가해 선택 영역이 가시적 - LlmOutput 내부의 button (더보기 토글) 만 user-select: none 로 예외 처리 - Backdrop click 핸들러 개선: 사용자가 drawer 내부에서 drag-select 시작 하다가 mouseup 이 backdrop 위에서 끝나면 기존 코드는 drawer 를 닫아 버려 selection 이 사라졌음. 이제 mousedown 도 backdrop 에서 시작했을 때만 close 를 실행 (data-backdrop-down attr 로 추적)
This commit is contained in:
@@ -329,6 +329,24 @@ const LlmOutput = styled.div<{ $ok: boolean }>`
|
|||||||
line-height: 1.75;
|
line-height: 1.75;
|
||||||
color: var(--text-primary);
|
color: var(--text-primary);
|
||||||
|
|
||||||
|
/* 텍스트 드래그/복사 가능하게 강제 + 가시적 selection 색 */
|
||||||
|
user-select: text;
|
||||||
|
-webkit-user-select: text;
|
||||||
|
-moz-user-select: text;
|
||||||
|
cursor: text;
|
||||||
|
|
||||||
|
*::selection,
|
||||||
|
&::selection {
|
||||||
|
background: rgba(95, 175, 255, 0.35);
|
||||||
|
color: var(--text-primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 내부 button (더보기 토글) 은 다시 not-allowed 가 아니라 pointer 로 */
|
||||||
|
button {
|
||||||
|
cursor: pointer;
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
|
||||||
& > *:first-child { margin-top: 0; }
|
& > *:first-child { margin-top: 0; }
|
||||||
& > *:last-child { margin-bottom: 0; }
|
& > *:last-child { margin-bottom: 0; }
|
||||||
|
|
||||||
@@ -701,7 +719,26 @@ export default function SubTaskDetailDrawer({ subTaskId, onClose }: Props) {
|
|||||||
}, [onClose]);
|
}, [onClose]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Backdrop onClick={onClose}>
|
<Backdrop
|
||||||
|
onMouseDown={(e) => {
|
||||||
|
// Only register a backdrop close if the user actually started
|
||||||
|
// their click ON the backdrop (not on the drawer content). This
|
||||||
|
// prevents the drawer from closing when a user drag-selects
|
||||||
|
// text inside and accidentally lifts the mouse on the backdrop.
|
||||||
|
if (e.target === e.currentTarget) {
|
||||||
|
(e.currentTarget as HTMLDivElement).dataset.backdropDown = '1';
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
onClick={(e) => {
|
||||||
|
const el = e.currentTarget as HTMLDivElement;
|
||||||
|
if (e.target === e.currentTarget && el.dataset.backdropDown === '1') {
|
||||||
|
delete el.dataset.backdropDown;
|
||||||
|
onClose();
|
||||||
|
} else {
|
||||||
|
delete el.dataset.backdropDown;
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
<Drawer onClick={(e) => e.stopPropagation()}>
|
<Drawer onClick={(e) => e.stopPropagation()}>
|
||||||
{loading || !detail ? (
|
{loading || !detail ? (
|
||||||
<Loading>로딩 중...</Loading>
|
<Loading>로딩 중...</Loading>
|
||||||
|
|||||||
Reference in New Issue
Block a user