Skip to content

Commit afb5bff

Browse files
committed
Implement mobile-friendly UI
1 parent 9efc5d1 commit afb5bff

4 files changed

Lines changed: 656 additions & 70 deletions

File tree

index.html

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -75,13 +75,24 @@ <h2>Welcome to SA Crash Data Map</h2>
7575

7676
<button class="toggle-panel-btn" onclick="togglePanel()" aria-label="Open filters panel">☰ Filters</button>
7777

78+
<!-- Backdrop: dims the map when the mobile bottom-sheet panel is open.
79+
Tapping it calls togglePanel() to close the sheet. -->
80+
<div class="mobile-panel-backdrop" onclick="togglePanel()" aria-hidden="true"></div>
81+
7882
<!-- Active Filters Badge -->
7983
<div class="active-filters-bar" id="activeFiltersBar">
80-
<div class="active-filters-bar-header">
84+
<div class="active-filters-bar-header"
85+
onclick="toggleActiveFiltersBar()"
86+
onkeydown="if(event.key==='Enter'||event.key===' '){event.preventDefault();toggleActiveFiltersBar();}"
87+
role="button"
88+
tabindex="0"
89+
aria-expanded="false"
90+
aria-controls="activeFiltersContent">
8191
<span class="active-filters-bar-title">🔍 No filters</span>
92+
<span class="active-filters-bar-chevron" aria-hidden="true"></span>
8293
</div>
8394
<div class="active-filters-bar-content" id="activeFiltersContent">
84-
<div class="no-active-filters">Hover to see filter details</div>
95+
<div class="no-active-filters">No filters applied</div>
8596
</div>
8697
</div>
8798

@@ -98,6 +109,9 @@ <h2>Welcome to SA Crash Data Map</h2>
98109
<button class="collapse-btn" onclick="togglePanelCollapse()" title="Collapse/Expand">
99110
<span id="collapseIcon"></span>
100111
</button>
112+
<!-- Mobile-only: explicit close button since the collapse button
113+
is hidden and the FAB is not visible while the sheet is open -->
114+
<button class="mobile-panel-close-btn" onclick="togglePanel()" aria-label="Close filters panel"></button>
101115
</div>
102116
</div>
103117

@@ -292,7 +306,7 @@ <h2>Welcome to SA Crash Data Map</h2>
292306
<div class="layer-toggle" id="densityToggle" onclick="toggleLayer('density')">
293307
<div class="layer-label-container">
294308
<span>💠 Point Density</span>
295-
<div class="layer-info-icon" onclick="event.stopPropagation()">
309+
<div class="layer-info-icon" onclick="event.stopPropagation()" tabindex="0" role="button" aria-label="Layer info">
296310
297311
<div class="layer-info-tooltip">
298312
Best viewed on <strong>Dark</strong> basemap
@@ -1334,7 +1348,7 @@ <h3 style="margin: 0 0 20px 0; color: #333; font-size: 20px;">Generating PDF Rep
13341348
</div>
13351349
</div>
13361350

1337-
<!-- Footer -->
1351+
<!-- Footer (hidden on mobile via CSS) -->
13381352
<footer class="page-footer">
13391353
<div class="footer-links">
13401354
<a href="#" onclick="openInfoModal('disclaimerModal'); return false;">Disclaimer</a>

src/js/main.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ async function setupGlobalHandlers() {
9191
window.toggleTutorialStep = ui.toggleTutorialStep;
9292
window.searchTutorial = ui.searchTutorial;
9393
window.toggleTheme = ui.toggleTheme;
94+
window.toggleActiveFiltersBar = ui.toggleActiveFiltersBar;
9495
window.togglePanel = ui.togglePanel;
9596
window.togglePanelCollapse = ui.togglePanelCollapse;
9697
window.toggleDataTable = ui.toggleDataTable;

src/js/ui.js

Lines changed: 37 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -101,32 +101,16 @@ function processNotificationQueue() {
101101
// Calculate position based on existing notifications
102102
const topPosition = 80 + (activeNotifications.length * 70);
103103

104-
notification.style.cssText = `
105-
position: fixed;
106-
top: ${topPosition}px;
107-
right: 20px;
108-
padding: 12px 20px;
109-
border-radius: 8px;
110-
background: var(--bg-secondary);
111-
border: 1px solid var(--border);
112-
box-shadow: var(--shadow-lg);
113-
z-index: 10002;
114-
font-size: 14px;
115-
max-width: 350px;
116-
animation: slideInFromRight 0.3s ease-out;
117-
transition: top 0.3s ease-out;
118-
`;
104+
// Static appearance is handled by the .app-notification CSS class so that
105+
// the mobile media query can override layout properties (right/left/max-width).
106+
// Inline styles here are limited to the two truly dynamic values: vertical
107+
// position and type-specific border colour.
108+
notification.classList.add('app-notification');
109+
notification.style.top = `${topPosition}px`;
119110

120-
// Add type-specific styling
121-
if (type === 'warning') {
122-
notification.style.borderLeft = '4px solid #ff9800';
123-
} else if (type === 'error') {
124-
notification.style.borderLeft = '4px solid #f44336';
125-
} else if (type === 'success') {
126-
notification.style.borderLeft = '4px solid #4caf50';
127-
} else {
128-
notification.style.borderLeft = '4px solid #2196f3';
129-
}
111+
// Type-specific left border colour
112+
const borderColors = { warning: '#ff9800', error: '#f44336', success: '#4caf50', info: '#2196f3' };
113+
notification.style.borderLeft = `4px solid ${borderColors[type] || borderColors.info}`;
130114

131115
document.body.appendChild(notification);
132116
activeNotifications.push(notification);
@@ -457,13 +441,37 @@ export function initTheme() {
457441
// ============================================================================
458442

459443
/**
460-
* Toggle control panel visibility (for mobile)
444+
* Toggle active filters bar expanded state.
445+
* On desktop this pins the bar open alongside hover; on mobile (where
446+
* :hover doesn't persist) this is the sole expand/collapse mechanism.
447+
*/
448+
export function toggleActiveFiltersBar() {
449+
const bar = document.getElementById('activeFiltersBar');
450+
if (!bar) return;
451+
const expanded = bar.classList.toggle('expanded');
452+
const header = bar.querySelector('.active-filters-bar-header');
453+
if (header) header.setAttribute('aria-expanded', String(expanded));
454+
}
455+
456+
/**
457+
* Toggle control panel visibility (for mobile).
458+
* On mobile this shows/hides the bottom-sheet panel. It also:
459+
* - Toggles the backdrop overlay so the map is dimmed while open.
460+
* - Sets data-panel-open on the FAB so CSS can hide it while the sheet is up.
461461
*/
462462
export function togglePanel() {
463463
const panel = document.getElementById('controlsPanel');
464-
if (panel) {
465-
panel.classList.toggle('visible');
466-
}
464+
if (!panel) return;
465+
466+
const isOpen = panel.classList.toggle('visible');
467+
468+
// Show/hide the semi-transparent backdrop behind the bottom sheet
469+
const backdrop = document.querySelector('.mobile-panel-backdrop');
470+
if (backdrop) backdrop.classList.toggle('active', isOpen);
471+
472+
// Let CSS know the panel state so the FAB can be hidden while open
473+
const fab = document.querySelector('.toggle-panel-btn');
474+
if (fab) fab.dataset.panelOpen = isOpen;
467475
}
468476

469477
/**

0 commit comments

Comments
 (0)