Skip to content

Add stickyScrollSidebar() to make the sidebar co-scroll with the page - #20245

Open
the14thsky wants to merge 1 commit into
filamentphp:4.xfrom
the14thsky:4.x
Open

Add stickyScrollSidebar() to make the sidebar co-scroll with the page#20245
the14thsky wants to merge 1 commit into
filamentphp:4.xfrom
the14thsky:4.x

Conversation

@the14thsky

Copy link
Copy Markdown

Description

By default the desktop sidebar has a fixed height and its navigation scrolls independently inside it (a nested scrollbar). For panels with long navigation this results in two separate scroll contexts on one screen, and lower nav groups sit behind a subtle inner scrollbar.

This PR adds an opt-in panel option, stickyScrollSidebar(), that makes the desktop sidebar scroll together with the page instead. When the menu is taller than the viewport, the sidebar's bottom pins to the bottom of the viewport, so scrolling the page reveals the rest of the menu — no nested scrollbar.

use Filament\Panel;

public function panel(Panel $panel): Panel
{
    return $panel
        // ...
        ->stickyScrollSidebar();
}

It is off by default, so existing behavior is unchanged.

Behavior when enabled:

  • Desktop (lg+): the sidebar grows to its content height (no inner scroll) and is position: sticky.
    • Fits within the viewport → pins just below the topbar.
    • Taller than the viewport → its bottom pins to the viewport bottom, so every nav item stays reachable by scrolling the page.
  • Mobile / collapsed: unchanged.

The topbar offset is measured at runtime (from .fi-topbar-ctn) and published as the --fi-sidebar-sticky-scroll-offset custom property, so the sidebar adapts to any header height — a taller brand logo, a notification bar, a wrapped header — rather than assuming a fixed height.

Implementation: a stickyScrollSidebar() setter + hasStickyScrollSidebar() getter on the HasSidebar concern (delegated through FilamentManager and the Filament facade); the sidebar Blade adds a fi-sidebar-sticky-scroll class; CSS makes the desktop sidebar tall/sticky with a page-scrolling nav; and sticky-scroll-sidebar.js measures the topbar and sets the sticky top (pinning the bottom when the sidebar is taller than the viewport). There is no per-scroll JS — CSS position: sticky handles the scrolling; the script only runs on resize, a ResizeObserver (sidebar + topbar), and livewire:navigated, and is inert for panels that don't enable the option.

Visual changes

sticky-scroll-sidebar-demo.mov

Before (default — nav scrolls inside a fixed-height sidebar):

After (stickyScrollSidebar() — sidebar co-scrolls with the page; bottom groups revealed on scroll):

Functional changes

  • Code style has been fixed by running the composer cs command.
  • Changes have been tested to not break existing functionality.
  • Documentation is up-to-date.

@danharrin danharrin added enhancement New feature or request pending review labels Jul 22, 2026
@danharrin danharrin added this to the v4 milestone Jul 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request pending review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants