Add back to top button

This commit is contained in:
DariusIII
2026-02-10 12:41:30 +01:00
parent a636adf432
commit e9dbe1c4ee
8 changed files with 51 additions and 3 deletions
+1
View File
@@ -14,6 +14,7 @@ import './stores/cart.js';
// --- Core UI components ---
import './components/theme-toggle.js';
import './components/back-to-top.js';
import './components/dropdown.js';
import './components/sidebar-toggle.js';
import './components/admin-submenu.js';
+2
View File
@@ -109,6 +109,8 @@
@yield('content')
</div>
@include('partials.back-to-top-forum')
<script>
new Vue({
el: '.v-navbar',
+4 -1
View File
@@ -64,7 +64,7 @@
</header>
<!-- Page Content - Scrollable Area -->
<main class="flex-1 overflow-y-auto p-6">
<main class="flex-1 overflow-y-auto p-6" data-scroll-container>
@if(session('success'))
<div class="mb-4 p-4 bg-green-50 dark:bg-green-900 border-l-4 border-green-500 dark:border-green-600 text-green-800 dark:text-green-200 rounded">
<i class="fas fa-check-circle mr-2"></i>{{ session('success') }}
@@ -92,6 +92,9 @@
</div>
</div>
<!-- Back to Top -->
@include('partials.back-to-top')
<!-- Theme Toggle -->
<button id="theme-toggle" class="fixed z-50 bg-gray-200 dark:bg-gray-700 text-gray-800 dark:text-gray-200 px-4 py-3 rounded-full shadow-lg hover:bg-gray-300 dark:hover:bg-gray-600 transition-all duration-200 flex items-center gap-2 touch-target bottom-[max(1rem,env(safe-area-inset-bottom))] left-[max(1rem,env(safe-area-inset-left))]"
title="{{ ucfirst(auth()->check() ? (auth()->user()->theme_preference ?? 'light') : 'light') }} Mode">
+3 -1
View File
@@ -20,7 +20,7 @@
@vite(['resources/css/app.css', 'resources/js/app.js'])
</head>
<body>
<div id="app" class="h-screen overflow-y-auto">
<div id="app" class="h-screen overflow-y-auto" data-scroll-container>
<nav class="navbar navbar-expand-md navbar-light bg-white dark:bg-gray-800 shadow-sm">
<div class="container">
<a class="navbar-brand" href="{{ url('/') }}">
@@ -78,5 +78,7 @@
@yield('content')
</main>
</div>
@include('partials.back-to-top')
</body>
</html>
+2
View File
@@ -35,6 +35,8 @@
<body class="font-sans antialiased pt-[env(safe-area-inset-top)] pr-[env(safe-area-inset-right)] pb-[env(safe-area-inset-bottom)] pl-[env(safe-area-inset-left)]">
@yield('content')
@include('partials.back-to-top')
<!-- Scripts -->
@stack('scripts')
</body>
+4 -1
View File
@@ -57,7 +57,7 @@
@endauth
<!-- Page Content - This is the scrollable area -->
<main class="flex-1 overflow-y-auto">
<main class="flex-1 overflow-y-auto" data-scroll-container>
<div class="container mx-auto px-4 py-6 pb-[max(1.5rem,env(safe-area-inset-bottom))]">
@if(session('success'))
<div class="mb-4 p-4 bg-green-100 dark:bg-green-900 border border-green-400 dark:border-green-700 text-green-700 dark:text-green-200 rounded-lg">
@@ -96,6 +96,9 @@
<i class="fas fa-bars text-lg"></i>
</button>
<!-- Back to Top -->
@include('partials.back-to-top')
<!-- Theme Toggle -->
<button id="theme-toggle" class="fixed z-50 bg-gray-200 dark:bg-gray-700 text-gray-800 dark:text-gray-200 px-4 py-3 rounded-full shadow-lg hover:bg-gray-300 dark:hover:bg-gray-600 transition-all duration-200 flex items-center gap-2 touch-target bottom-[max(1rem,env(safe-area-inset-bottom))] left-[max(1rem,env(safe-area-inset-left))]"
title="{{ ucfirst(auth()->check() ? (auth()->user()->theme_preference ?? 'light') : 'light') }} Mode">
@@ -0,0 +1,17 @@
{{-- Back to top button for forum (Vue layout - no Alpine) --}}
<button type="button" id="back-to-top-forum" class="hidden fixed bottom-6 right-6 z-40 bg-blue-600 text-white p-3 rounded-full shadow-lg hover:bg-blue-700 transition-colors" aria-label="Back to top">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6">
<path stroke-linecap="round" stroke-linejoin="round" d="M4.5 15.75l7.5-7.5 7.5 7.5" />
</svg>
</button>
<script>
(function() {
const btn = document.getElementById('back-to-top-forum');
if (!btn) return;
const threshold = 300;
function toggle() { btn.classList.toggle('hidden', window.scrollY <= threshold); }
window.addEventListener('scroll', toggle, { passive: true });
toggle();
btn.addEventListener('click', function() { window.scrollTo({ top: 0, behavior: 'smooth' }); });
})();
</script>
@@ -0,0 +1,18 @@
{{-- Back to top button - appears when user scrolls down (Alpine backToTop component) --}}
<button type="button"
x-data="backToTop()"
x-show="visible"
x-transition:enter="transition ease-out duration-200"
x-transition:enter-start="opacity-0 translate-y-4"
x-transition:enter-end="opacity-100 translate-y-0"
x-transition:leave="transition ease-in duration-150"
x-transition:leave-start="opacity-100 translate-y-0"
x-transition:leave-end="opacity-0 translate-y-4"
x-cloak
@click="scrollToTop()"
class="fixed z-40 bg-blue-600 dark:bg-blue-700 text-white p-3 rounded-full shadow-lg hover:bg-blue-700 dark:hover:bg-blue-800 transition-colors touch-target
bottom-[max(5.5rem,calc(env(safe-area-inset-bottom)+5rem))] right-[max(1rem,env(safe-area-inset-right))]
md:bottom-[max(1rem,env(safe-area-inset-bottom))] md:right-[max(1rem,env(safe-area-inset-right))]"
aria-label="Back to top">
<i class="fas fa-chevron-up text-lg"></i>
</button>