From db80d2e0903b6bfa9fcdac756317951f434abc46 Mon Sep 17 00:00:00 2001 From: seonghobae <8172694+seonghobae@users.noreply.github.com> Date: Sat, 5 Sep 2026 17:44:55 +0000 Subject: [PATCH 1/2] =?UTF-8?q?=F0=9F=8E=A8=20Palette:=20=EB=93=9C?= =?UTF-8?q?=EB=9E=98=EA=B7=B8=20=EC=95=A4=20=EB=93=9C=EB=A1=AD=20=EA=B9=9C?= =?UTF-8?q?=EB=B0=95=EC=9E=84(Flickering)=20=EB=AC=B8=EC=A0=9C=20=EA=B0=9C?= =?UTF-8?q?=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .jules/palette.md | 4 ++++ saas_web.py | 23 +++++++++++++++++++---- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/.jules/palette.md b/.jules/palette.md index 2dcd639e..814398f6 100644 --- a/.jules/palette.md +++ b/.jules/palette.md @@ -81,3 +81,7 @@ ## 2024-08-04 - 숫자 입력 필드 빈 문자열 상태 초기화 처리 **학습:** 숫자 입력 필드에서 빈 문자열('')을 입력할 때 브라우저는 이전의 유효하지 않은 상태를 암시적으로 유지하므로, 사용자 정의 검증을 명시적으로 초기화하지 않으면 네이티브 HTML5 유효성 검사가 정상 작동하지 않을 수 있음을 확인했습니다. **실행:** 인라인 검증 스크립트 작성 시 빈 문자열 상태를 별도로 확인하여 this.setCustomValidity('') 및 this.removeAttribute('aria-invalid')를 명시적으로 호출하는 로직을 추가해야 합니다. + +## 2024-09-05 - Fix Drag and Drop Flickering +**Learning:** Adding a `.dragover` CSS class on `dragenter` and removing it on `dragleave` directly causes the styling to flicker violently when the user drags a file over child elements (like text or inputs) inside the drop zone, because the parent receives a `dragleave` event followed immediately by a bubbling `dragenter` from the child. +**Action:** Always implement a `dragCounter` variable for drop zones. Increment it on `dragenter` and decrement it on `dragleave`, only removing the `.dragover` class when the counter reaches `0`. diff --git a/saas_web.py b/saas_web.py index 63265e94..1fb7bc90 100644 --- a/saas_web.py +++ b/saas_web.py @@ -368,14 +368,29 @@ async def add_security_headers(request: Request, call_next): [dropZone, batchDropZone].forEach(zone => { if (!zone) return; + zone.dragCounter = 0; ['dragenter', 'dragover', 'dragleave', 'drop'].forEach(eventName => { zone.addEventListener(eventName, preventDefaults, false); }); - ['dragenter', 'dragover'].forEach(eventName => { - zone.addEventListener(eventName, () => zone.classList.add('dragover'), false); + ['dragenter'].forEach(eventName => { + zone.addEventListener(eventName, () => { + zone.dragCounter++; + zone.classList.add('dragover'); + }, false); }); - ['dragleave', 'drop'].forEach(eventName => { - zone.addEventListener(eventName, () => zone.classList.remove('dragover'), false); + ['dragleave'].forEach(eventName => { + zone.addEventListener(eventName, () => { + zone.dragCounter--; + if (zone.dragCounter === 0) { + zone.classList.remove('dragover'); + } + }, false); + }); + ['drop'].forEach(eventName => { + zone.addEventListener(eventName, () => { + zone.dragCounter = 0; + zone.classList.remove('dragover'); + }, false); }); }); ['dragenter', 'dragover', 'dragleave', 'drop'].forEach(eventName => { From 2793248abed72a3c0accd0c584ff77f793395dd8 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Sun, 6 Sep 2026 03:10:55 +0900 Subject: [PATCH 2/2] chore(ui): keep drag-state repair out of repository-wide Palette doctrine --- .jules/palette.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.jules/palette.md b/.jules/palette.md index 814398f6..2dcd639e 100644 --- a/.jules/palette.md +++ b/.jules/palette.md @@ -81,7 +81,3 @@ ## 2024-08-04 - 숫자 입력 필드 빈 문자열 상태 초기화 처리 **학습:** 숫자 입력 필드에서 빈 문자열('')을 입력할 때 브라우저는 이전의 유효하지 않은 상태를 암시적으로 유지하므로, 사용자 정의 검증을 명시적으로 초기화하지 않으면 네이티브 HTML5 유효성 검사가 정상 작동하지 않을 수 있음을 확인했습니다. **실행:** 인라인 검증 스크립트 작성 시 빈 문자열 상태를 별도로 확인하여 this.setCustomValidity('') 및 this.removeAttribute('aria-invalid')를 명시적으로 호출하는 로직을 추가해야 합니다. - -## 2024-09-05 - Fix Drag and Drop Flickering -**Learning:** Adding a `.dragover` CSS class on `dragenter` and removing it on `dragleave` directly causes the styling to flicker violently when the user drags a file over child elements (like text or inputs) inside the drop zone, because the parent receives a `dragleave` event followed immediately by a bubbling `dragenter` from the child. -**Action:** Always implement a `dragCounter` variable for drop zones. Increment it on `dragenter` and decrement it on `dragleave`, only removing the `.dragover` class when the counter reaches `0`.