fix(ui): let the desktop sidebar scroll on short screens

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Andras Bacsai
2026-10-16 22:41:15 +02:00
co-authored by Claude Opus 5.5
parent 449d099bd3
commit 3aa6ff1fdd
3 changed files with 68 additions and 2 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
@props(['deploymentsIndicator' => false])
<nav class="flex flex-col flex-1 bg-white border-r border-neutral-200 dark:border-white/[0.06] dark:bg-panel pt-2"
<nav class="flex min-h-0 flex-col flex-1 bg-white border-r border-neutral-200 dark:border-white/[0.06] dark:bg-panel pt-2"
:class="collapsed ? 'px-2 lg:px-3 sidebar-collapsed' : 'px-2 lg:px-3'"
@mouseover="
if (!collapsed) return;
+1 -1
View File
@@ -142,7 +142,7 @@
{{-- ============ DESKTOP SIDEBAR (below top bar) ============ --}}
<div class="hidden lg:fixed lg:top-12 lg:bottom-0 lg:left-0 lg:z-40 lg:flex lg:flex-col min-w-0"
:class="[collapsed ? 'lg:w-16' : 'lg:w-56', sidebarReady ? 'transition-[width] duration-200' : '']">
<div class="flex grow min-w-0 flex-col overflow-visible">
<div class="flex min-h-0 grow min-w-0 flex-col overflow-visible">
<x-navbar deployments-indicator />
</div>
</div>
+66
View File
@@ -0,0 +1,66 @@
<?php
use Illuminate\Foundation\Testing\RefreshDatabase;
uses(RefreshDatabase::class);
beforeEach(function () {
$this->stack = seedBrowserResourceStack();
$this->application = createBrowserApplication($this->stack, [
'uuid' => 'app-sidebar-scroll',
'name' => 'Sidebar Scroll App',
]);
});
/**
* @return array{bottom: float, viewport: int, overflows: bool, scrolled: bool}
*/
function measureSidebarScroll(mixed $page, string $scrollerSelector, string $frameSelector): array
{
return $page->script(sprintf(<<<'JS'
() => {
const scroller = document.querySelector(%s);
const frame = document.querySelector(%s);
scroller.scrollTop = scroller.scrollHeight;
return {
bottom: frame.getBoundingClientRect().bottom,
viewport: window.innerHeight,
overflows: scroller.scrollHeight > scroller.clientHeight,
scrolled: scroller.scrollTop > 0,
};
}
JS, json_encode($scrollerSelector), json_encode($frameSelector)));
}
it('scrolls the main sidebar inside a short viewport', function () {
loginAndSkipBoarding();
$page = visit('/')->resize(1440, 420)->assertSee('Dashboard');
$sidebar = measureSidebarScroll($page, 'div.lg\\:fixed nav > ul[role="list"]', 'div.lg\\:fixed nav');
$page->screenshot(filename: 'main-sidebar-scroll');
expect($sidebar['bottom'])->toBeLessThanOrEqual($sidebar['viewport'])
->and($sidebar['overflows'])->toBeTrue()
->and($sidebar['scrolled'])->toBeTrue();
});
it('scrolls the resource settings sidebar inside a short viewport', function () {
loginAndSkipBoarding();
$page = visit(applicationConfigurationUrl(
$this->stack['project'],
$this->stack['environment'],
$this->application
))->resize(1440, 420)->assertSee('Sidebar Scroll App');
$sidebar = measureSidebarScroll($page, '.application-settings-navigation', '.application-settings-navigation');
$page->screenshot(filename: 'settings-sidebar-scroll');
expect($sidebar['bottom'])->toBeLessThanOrEqual($sidebar['viewport'])
->and($sidebar['overflows'])->toBeTrue()
->and($sidebar['scrolled'])->toBeTrue();
});