From 1a9307485cbef78594adb0006f3de866d8c92e21 Mon Sep 17 00:00:00 2001 From: Bruno Charest Date: Thu, 19 Feb 2026 13:12:44 -0500 Subject: [PATCH] =?UTF-8?q?feat:=20impl=C3=A9menter=20refonte=20responsive?= =?UTF-8?q?=20globale=20avec=20sidebar=20mobile=20coulissante=20(overlay?= =?UTF-8?q?=20+=20transform),=20menu=20hamburger=20adaptatif,=20breakpoint?= =?UTF-8?q?s=20optimis=C3=A9s=201100px/768px/640px/480px,=20grille=20links?= =?UTF-8?q?=20adaptative=20single-column=20mobile,=20toolbar=20empil=C3=A9?= =?UTF-8?q?=20vertical,=20modales=20plein=20=C3=A9cran,=20calendrier=20dai?= =?UTF-8?q?ly=20en=20modal=20fixe,=20actions=20bulk=20wrap=20100%,=20badge?= =?UTF-8?q?s=20repositionn=C3=A9s,=20player=20m=C3=A9dia=20compact,=20tabl?= =?UTF-8?q?es=20scrollables=20horizontales,=20et=20masquage=20s=C3=A9lecti?= =?UTF-8?q?f=20d'=C3=A9l=C3=A9ments=20header=20selon=20largeur=20=C3=A9cra?= =?UTF-8?q?n?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- shaarli-pro/css/style.css | 497 ++++++++++++++++++++++++++++++++++++++ shaarli-pro/js/script.js | 59 ++++- 2 files changed, 550 insertions(+), 6 deletions(-) diff --git a/shaarli-pro/css/style.css b/shaarli-pro/css/style.css index b2329e7..1503758 100644 --- a/shaarli-pro/css/style.css +++ b/shaarli-pro/css/style.css @@ -3545,4 +3545,501 @@ flex: 1 1 calc(50% - 0.4rem); border-color: #314564; background: #122039; color: #eaf2ff; +} + +/* ===== Global Responsive Overhaul ===== */ +.sidebar-overlay { + position: fixed; + inset: 0; + background: rgba(15, 23, 42, 0.55); + opacity: 0; + visibility: hidden; + transition: opacity 0.2s ease, visibility 0.2s ease; + z-index: 180; +} + +.sidebar-overlay.show { + opacity: 1; + visibility: visible; +} + +@media (max-width: 1100px) { + .header-nav { + display: none; + } + + .mobile-menu-btn { + display: inline-flex; + align-items: center; + justify-content: center; + width: 38px; + height: 38px; + border-radius: 10px; + background: rgba(255, 255, 255, 0.14); + } + + .mobile-menu-btn:hover { + background: rgba(255, 255, 255, 0.22); + } + + .sidebar { + transform: translateX(-100%); + width: min(86vw, 320px); + max-width: 320px; + border-right: 0; + box-shadow: 0 24px 50px rgba(2, 6, 23, 0.45); + z-index: 220; + } + + .sidebar.show { + transform: translateX(0); + } + + .main-content, + .media-player-bar, + .bulk-actions-bar { + margin-left: 0; + left: 0; + } + + .header-main { + padding: 0 0.9rem; + } + + .content-container { + padding: 0.85rem 0.9rem; + } + + .content-toolbar { + flex-direction: column; + align-items: stretch; + gap: 0.8rem; + } + + .toolbar-left, + .toolbar-right { + width: 100%; + justify-content: space-between; + flex-wrap: wrap; + } + + .links-list.view-grid { + grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); + } + + .paging { + gap: 0.6rem; + } + + .paging-current { + order: 2; + } + + .paging-links, + .paging-plugin { + order: 3; + } + + .bulk-actions-bar { + flex-direction: column; + align-items: stretch; + gap: 0.8rem; + padding: 0.8rem 0.9rem; + } + + .bulk-info, + .bulk-buttons { + width: 100%; + justify-content: space-between; + } + + .bulk-buttons { + flex-wrap: wrap; + } + + .bulk-btn { + flex: 1 1 calc(50% - 0.35rem); + } + + .daily-nav-left { + width: 100%; + justify-content: center; + } + + .daily-nav-tabs { + width: 100%; + overflow-x: auto; + justify-content: flex-start; + } +} + +@media (max-width: 768px) { + body { + -webkit-text-size-adjust: 100%; + } + + .header-main { + height: 52px; + } + + .header-inner { + gap: 0.6rem; + } + + .header-actions { + gap: 0.35rem; + } + + .header-action-btn, + .header-nav-link { + width: 34px; + height: 34px; + border-radius: 0.45rem; + font-size: 1rem; + } + + .filter-panel { + position: fixed; + top: auto; + right: 0.5rem; + left: 0.5rem; + bottom: 0.6rem; + width: auto; + max-height: 78vh; + overflow: auto; + border-radius: 14px; + animation: none; + } + + .search-overlay { + padding: 1rem 0.6rem; + align-items: flex-start; + } + + .search-modal { + width: 100%; + max-width: none; + border-radius: 12px; + } + + .search-modal-header { + flex-wrap: wrap; + } + + .search-modal-actions { + width: 100%; + } + + .search-pill-btn { + flex: 1; + justify-content: center; + } + + .links-list, + .links-list.view-grid { + grid-template-columns: minmax(0, 1fr); + gap: 0.8rem; + } + + .link-outer { + padding: 3.1rem 0.9rem 0.95rem; + border-radius: 0.7rem; + } + + .link-title { + padding-right: 2.2rem; + font-size: 0.97rem; + } + + .link-description { + margin: 0.55rem 0; + font-size: 0.86rem; + } + + .link-footer, + .view-grid .link-footer { + margin-top: 0.7rem; + padding-top: 0.65rem; + align-items: stretch; + } + + .view-grid .link-tag-list, + .link-tag-list { + justify-content: flex-start; + } + + .link-actions, + .view-grid .link-actions { + justify-content: flex-start; + margin-left: 0; + width: 100%; + } + + .link-actions a, + .link-actions button { + width: 34px; + height: 34px; + } + + .view-list .link-outer { + display: block; + padding: 2.9rem 0.9rem 0.95rem; + margin-bottom: 0.75rem; + } + + .view-list .link-thumbnail { + position: absolute; + top: 0; + left: 0; + right: 0; + width: 100%; + height: 42%; + mask-image: linear-gradient(to bottom, black 35%, transparent 100%); + -webkit-mask-image: linear-gradient(to bottom, black 35%, transparent 100%); + } + + .view-list .link-select-checkbox, + .view-list .link-visibility-badge, + .view-list .link-readlater-badge { + top: 0.65rem; + } + + .view-list .link-select-checkbox { + left: 0.65rem; + } + + .view-list .link-visibility-badge { + right: 0.65rem; + } + + .view-list .link-readlater-badge { + right: 3rem; + } + + .modal-overlay, + .qrcode-modal-overlay { + padding: 0.65rem; + } + + .modal-content, + .qrcode-modal-content { + width: 100%; + max-height: 90vh; + border-radius: 0.65rem; + } + + .card-header, + .card-body, + .card-footer { + padding-left: 1rem; + padding-right: 1rem; + } + + .card-footer { + flex-wrap: wrap; + justify-content: stretch; + } + + .card-footer .btn { + width: 100%; + } + + .list-group-item { + padding: 0.85rem 0.9rem; + align-items: flex-start; + gap: 0.65rem; + } + + .list-sortable-handle { + padding: 0.2rem; + } + + .key-value-item { + flex-direction: column; + align-items: flex-start; + gap: 0.25rem; + } + + .key-value-data { + text-align: left; + } + + .bookmarklet-actions, + .third-party-links { + display: flex; + flex-direction: column; + gap: 0.65rem; + } + + .bookmarklet-actions .btn, + .third-party-links .btn { + width: 100%; + } + + .daily { + padding-top: 1rem; + } + + .daily-nav-unified { + gap: 0.9rem; + border-radius: 14px; + padding: 0.85rem; + } + + .daily-nav-center { + width: 100%; + } + + .daily-nav-btn, + .daily-date-pill, + .daily-calendar-btn { + min-height: 38px; + } + + .daily-calendar-panel { + position: fixed; + inset: 0; + z-index: 600; + padding: 0.9rem; + background: rgba(15, 23, 42, 0.58); + display: none; + align-items: center; + justify-content: center; + } + + .daily-calendar-panel.is-open { + display: flex; + } + + .daily-calendar-shell { + width: 100%; + max-width: 560px; + max-height: 90vh; + overflow: auto; + border-radius: 14px; + } + + .daily-calendar-sidebar, + .daily-calendar-main { + width: 100%; + padding: 1rem; + } + + .daily-calendar-sidebar { + border-right: 0; + border-bottom: 1px solid var(--border-light); + } + + .daily-calendar-day { + width: 36px; + height: 36px; + font-size: 0.85rem; + } + + .media-player-inner { + grid-template-columns: auto minmax(0, 1fr) auto; + } + + .media-player-title { + font-size: 0.8rem; + } + + .media-player-time { + min-width: auto; + font-size: 0.74rem; + } + + table { + display: block; + width: 100%; + overflow-x: auto; + -webkit-overflow-scrolling: touch; + } + + .row { + margin-left: 0; + margin-right: 0; + } + + .row > [class*="col-"] { + width: 100%; + max-width: 100%; + float: none; + padding-left: 0; + padding-right: 0; + } +} + +@media (max-width: 640px) { + .content-container { + padding: 0.75rem; + } + + .header-actions a[aria-label="Flux RSS"], + .header-actions a[aria-label="Outils"] { + display: none; + } + + .toolbar-left, + .toolbar-right, + .view-toggle { + width: 100%; + } + + .view-toggle { + justify-content: space-between; + } + + .view-toggle-btn { + flex: 1; + width: auto; + } + + .bulk-btn { + flex: 1 1 100%; + } + + .paging { + padding: 0.6rem; + } + + .daily-tab { + font-size: 0.72rem; + padding-inline: 0.8rem; + } + + .picwall-size-controls { + width: 100%; + justify-content: center; + } + + .picwall-size-slider { + width: 100%; + max-width: 180px; + } +} + +@media (max-width: 480px) { + .sidebar { + width: 92vw; + } + + .header-main { + padding: 0 0.65rem; + } + + .header-action-btn, + .mobile-menu-btn { + width: 32px; + height: 32px; + border-radius: 0.4rem; + } + + .link-tag { + font-size: 0.7rem; + } + + .daily-item-header { + font-size: 0.94rem; + } } \ No newline at end of file diff --git a/shaarli-pro/js/script.js b/shaarli-pro/js/script.js index c25f4b9..02a768c 100644 --- a/shaarli-pro/js/script.js +++ b/shaarli-pro/js/script.js @@ -36,13 +36,53 @@ document.addEventListener('DOMContentLoaded', () => { const sidebarOverlay = document.getElementById('sidebar-overlay'); const mobileMenuBtn = document.getElementById('mobile-menu-btn'); + function isMobileViewport() { + return window.matchMedia('(max-width: 1100px)').matches; + } + + function openSidebar() { + if (!sidebar || !sidebarOverlay) return; + sidebar.classList.add('show'); + sidebarOverlay.classList.add('show'); + mobileMenuBtn?.setAttribute('aria-expanded', 'true'); + sidebarOverlay.setAttribute('aria-hidden', 'false'); + if (isMobileViewport()) { + document.body.style.overflow = 'hidden'; + } + } + + function closeSidebar() { + if (!sidebar || !sidebarOverlay) return; + sidebar.classList.remove('show'); + sidebarOverlay.classList.remove('show'); + mobileMenuBtn?.setAttribute('aria-expanded', 'false'); + sidebarOverlay.setAttribute('aria-hidden', 'true'); + document.body.style.overflow = ''; + } + function toggleSidebar() { - sidebar?.classList.toggle('show'); - sidebarOverlay?.classList.toggle('show'); + if (sidebar?.classList.contains('show')) { + closeSidebar(); + return; + } + openSidebar(); } mobileMenuBtn?.addEventListener('click', toggleSidebar); - sidebarOverlay?.addEventListener('click', toggleSidebar); + sidebarOverlay?.addEventListener('click', closeSidebar); + sidebar?.querySelectorAll('a').forEach((link) => { + link.addEventListener('click', () => { + if (isMobileViewport()) { + closeSidebar(); + } + }); + }); + + window.addEventListener('resize', () => { + if (!isMobileViewport()) { + closeSidebar(); + } + }); // ===== Search Overlay (Spotlight Style) ===== const searchOverlay = document.getElementById('search-overlay'); @@ -397,11 +437,17 @@ document.addEventListener('DOMContentLoaded', () => { const filterUntagged = document.getElementById('filter-untagged'); function toggleFilterPanel() { - filterPanel?.classList.toggle('show'); + if (!filterPanel) return; + const isOpen = filterPanel.classList.toggle('show'); + filterPanel.setAttribute('aria-hidden', String(!isOpen)); + filterToggleBtn?.setAttribute('aria-expanded', String(isOpen)); } function closeFilterPanel() { - filterPanel?.classList.remove('show'); + if (!filterPanel) return; + filterPanel.classList.remove('show'); + filterPanel.setAttribute('aria-hidden', 'true'); + filterToggleBtn?.setAttribute('aria-expanded', 'false'); } filterToggleBtn?.addEventListener('click', (e) => { @@ -414,7 +460,8 @@ document.addEventListener('DOMContentLoaded', () => { // Close filter when clicking outside document.addEventListener('click', (e) => { if (filterPanel?.classList.contains('show')) { - if (!filterPanel.contains(e.target) && e.target !== filterToggleBtn) { + const clickedToggle = filterToggleBtn && (e.target === filterToggleBtn || filterToggleBtn.contains(e.target)); + if (!filterPanel.contains(e.target) && !clickedToggle) { closeFilterPanel(); } }