1.9 KiB
ShopProQuote UX Conventions
Modal behavior — NEVER close on outside click
User preference: modals should ONLY close via explicit Save/Close/Cancel buttons. Clicking the backdrop (outside the modal) must NOT dismiss the modal.
Files that had click-outside-to-close handlers (all removed):
| File | Modal | Was |
|---|---|---|
quote-tab-manager.js:1379 |
Service edit modal | modal.classList.add('hidden') on e.target === modal |
quote-tab-manager.js:1680 |
Parts availability modal | closeModal() on e.target === modal |
shared/customer-lookup.js:253 |
Customer lookup modal | modal.remove() on e.target === modal |
settings.js:315 |
Site settings modal | closeModal() on e.target === modal |
shared/modal-manager.js:328 |
Confirm dialog overlay | overlay.remove(); resolve(false) on e.target === overlay |
Pattern to recognize
Any modal.addEventListener('click', (e) => { if (e.target === modal) { ... } }); blocks must be removed. If adding a new modal, do NOT add an outside-click handler.
What was NOT changed (correctly)
Dropdown menus (service search, customer search, header menus) still close on outside click. This is expected UX for dropdowns — the rule only applies to modal dialogs.
Toggle checkboxes — always show the icon
Approval/decline checkboxes (green ✓ and red ✕ in the ServiceRow) must always render their SVG icon, not conditionally. When inactive the icon is grayed-out (text-gray-300), when active the icon is white on a colored background (text-white on bg-green-600 or bg-red-600).
Pattern:
// ✓ — always visible, gray when inactive, white when active
<button className={`... ${active ? 'bg-green-600 border-green-600 text-white' : 'border-gray-300 text-gray-300'}`}>
<svg>...</svg> // always rendered, never conditional
</button>
Do NOT wrap the SVG in {active && <svg>...</svg>} — the icon should always be visible as a preview of the action.