ba36f67371
* 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
2.7 KiB
2.7 KiB
name, description
| name | description |
|---|---|
| medassist-ui-consistency | Enforce non-negotiable MedAssist UI guardrails by reusing existing components, styles, and interaction patterns, including equivalent requests phrased in German. |
Skill Instructions
Use this skill when implementing or editing UI flows, modals, buttons, forms, schedule views, or settings screens.
Scope
This is the guardrail skill for UI work. Use it to enforce consistency and prevent design drift.
Use medassist-frontend-polish only after these guardrails are satisfied.
Do Not Use This Skill For
- Creative visual redesign requests where no product consistency constraints apply.
- Marketing-style one-off pages outside MedAssist product UI conventions.
Rules
- Reuse existing components (for example
ConfirmModal,MedicationAvatar) before creating new primitives. - Keep spacing, typography, and button styles aligned with existing patterns.
- Avoid custom inline modal/button patterns that diverge from project design.
- Prefer extending existing CSS classes/styles instead of introducing parallel styling systems.
Modal requirements (non-negotiable)
Every modal/overlay must follow these rules:
- Escape key: Call
useEscapeKey(active, onClose)fromhooks/useEscapeKey. This registers a document-levelkeydownlistener that works regardless of focus. Never rely ononKeyDownon an overlay div — it only fires when the overlay has focus, which almost never happens. - Scroll lock: Call
useScrollLock(active)fromhooks/useScrollLockif the modal is not already covered by App.tsx's centralizeduseScrollLockcall. Page-local modals (e.g.ReportModal,ExportModal) must call it themselves. - Click-outside close: The overlay div gets
onClick={onClose}, and.modal-contentgetsonClick={(e) => e.stopPropagation()}. - Key event containment:
.modal-contentgetsonKeyDown={(e) => { if (e.key !== "Escape") e.stopPropagation(); }}— this prevents non-Escape keys from leaking out while still allowing Escape to propagate to the document-level handler. - Nested sub-modals (e.g. edit-stock inside MedDetailModal): Use
useEscapeKeywith{ capture: true }so the innermost modal intercepts Escape before the parent's handler fires.
Decision Heuristics
- If an equivalent component exists, reuse it.
- If small variant is needed, extend existing styles minimally.
- If a new component is unavoidable, match existing naming and structure conventions.
Response Format
Provide:
- Reused components/styles
- Any new UI element and why reuse was not possible
- Consistency risks reviewed
- Confirmation that
medassist-frontend-polishconstraints remain compatible (if polish work is also requested)