fix: smooth mobile edit transition and align modal validation behavior (#286)

* fix: reliable Escape key close for all modals via useEscapeKey hook

- Add useEscapeKey hook (document-level keydown listener)
- Retrofit all 12 modal/overlay components to use it
- Remove redundant overlay onKeyDown Escape handlers
- Simplify modal-content onKeyDown to plain stopPropagation
- Replace MedDetailModal's capture-phase useEffect with 3 useEscapeKey calls
- Replace SharedSchedule's inline useEffect with useEscapeKey
- Add mandatory modal rules to UI Consistency skill
- All 777 frontend + 569 backend tests pass

* fix: smooth mobile edit transition and align modal validation behavior

* fix: keep overlay keydown non-closing for Enter key

* fix: show mobile name error when validation already exists

* fix: restore app-level escape priority handling

* fix: prioritize schedule lightbox on Escape
This commit is contained in:
Daniel Volz
2026-02-23 06:42:06 +01:00
committed by GitHub
parent 2aa6b1f406
commit ba36f67371
21 changed files with 337 additions and 163 deletions
+7 -5
View File
@@ -3,6 +3,7 @@
// =============================================================================
import type { MouseEvent } from "react";
import { useEscapeKey } from "../hooks/useEscapeKey";
export interface LightboxProps {
src: string;
@@ -11,6 +12,8 @@ export interface LightboxProps {
}
export function Lightbox({ src, alt, onClose }: LightboxProps) {
useEscapeKey(true, onClose);
function handleOverlayClick(e: MouseEvent) {
e.stopPropagation();
if (e.target === e.currentTarget) {
@@ -23,10 +26,7 @@ export function Lightbox({ src, alt, onClose }: LightboxProps) {
className="lightbox-overlay"
onClick={handleOverlayClick}
onKeyDown={(e) => {
if (e.key === "Escape") {
e.stopPropagation();
onClose();
}
if (e.key !== "Escape") e.stopPropagation();
}}
>
<div className="lightbox-container">
@@ -38,7 +38,9 @@ export function Lightbox({ src, alt, onClose }: LightboxProps) {
alt={alt}
className="lightbox-image"
onClick={(e) => e.stopPropagation()}
onKeyDown={(e) => e.stopPropagation()}
onKeyDown={(e) => {
if (e.key !== "Escape") e.stopPropagation();
}}
/>
</div>
</div>