feat: improve mobile responsiveness

- Add mobile navigation drawer with hamburger menu
- Sidebar slides in as overlay on mobile (<768px)
- Close button inside sidebar for mobile
- Ensure touch targets are at least 44px on mobile
- Make modals full-screen on mobile
- Editor toolbar scrolls horizontally on mobile
- Improve spacing and typography for small screens
- Keep dark theme consistent across breakpoints
- Projects page cards stack vertically on mobile
- Document cards full-width on mobile
This commit is contained in:
Hiro
2026-03-28 14:00:05 +00:00
parent c090cd3a71
commit 8f7ad3f673
5 changed files with 468 additions and 76 deletions

View File

@@ -77,29 +77,33 @@ export async function renderDashboard(app) {
appEl.innerHTML = `
<header class="app-header">
<button class="mobile-nav-btn" onclick="toggleMobileSidebar()" title="Menu">☰</button>
<div class="logo">📝 SimpleNote</div>
<div class="search-box">
<span class="icon">🔍</span>
<input type="text" id="search-input" placeholder="Search documents..." value="${searchQuery}">
</div>
<div class="header-actions">
<button class="btn btn-primary" onclick="window.showNewDocModal()">+ New Document</button>
<button class="btn btn-ghost" onclick="window.showNewLibraryModal()">📁 New Library</button>
<button class="btn btn-primary" onclick="window.showNewDocModal()">+ New</button>
</div>
</header>
<div class="sidebar-overlay" onclick="closeMobileSidebar()"></div>
<div class="app-layout">
${renderSidebar({
libraries,
tags,
selectedLibrary,
selectedTag,
...sidebarCallbacks
})}
<aside class="sidebar" id="sidebar">
<button class="sidebar-close-btn" onclick="closeMobileSidebar()">✕</button>
${renderSidebar({
libraries,
tags,
selectedLibrary,
selectedTag,
...sidebarCallbacks
})}
</aside>
<main class="main-content">
<div class="content-header">
<h1>${selectedLibrary ? getLibraryName(libraries, selectedLibrary) : selectedTag ? `#${selectedTag}` : 'All Documents'}</h1>
<div class="header-actions">
<button class="btn btn-primary" onclick="window.showNewDocModal()">+ New Document</button>
<button class="btn btn-primary" onclick="window.showNewDocModal()">+ New</button>
</div>
</div>
<div class="content-body">
@@ -120,12 +124,54 @@ export async function renderDashboard(app) {
</div>
`;
// Mobile sidebar functions
window.toggleMobileSidebar = function() {
const sidebar = document.getElementById('sidebar');
const overlay = document.querySelector('.sidebar-overlay');
if (sidebar) {
sidebar.classList.toggle('mobile-open');
if (overlay) overlay.classList.toggle('active');
}
};
window.closeMobileSidebar = function() {
const sidebar = document.getElementById('sidebar');
const overlay = document.querySelector('.sidebar-overlay');
if (sidebar) {
sidebar.classList.remove('mobile-open');
if (overlay) overlay.classList.remove('active');
}
};
// Event listeners
const searchInput = document.getElementById('search-input');
searchInput.oninput = (e) => {
searchQuery = e.target.value;
render();
};
// Sidebar item listeners
document.querySelectorAll('[data-action="home"]').forEach(el => {
el.addEventListener('click', (e) => {
e.stopPropagation();
sidebarCallbacks.onHome();
closeMobileSidebar();
});
});
document.querySelectorAll('[data-action="library"]').forEach(el => {
el.addEventListener('click', (e) => {
e.stopPropagation();
sidebarCallbacks.onSelectLibrary(el.getAttribute('data-library-id'));
closeMobileSidebar();
});
});
document.querySelectorAll('[data-action="tag"]').forEach(el => {
el.addEventListener('click', (e) => {
e.stopPropagation();
sidebarCallbacks.onSelectTag(el.getAttribute('data-tag'));
closeMobileSidebar();
});
});
}
render();