section_scrollbar 0.1.1+1
section_scrollbar: ^0.1.1+1 copied to clipboard
A section-aware custom scrollbar with a floating current-section label.
Demo #

section_scrollbar #
section_scrollbar is a pure Flutter package for building a section-aware
custom scrollbar that shows a floating badge for the current section while the
user scrolls.
It is not a platform scrollbar skin. The package measures your declared
sections, tracks the active one with a configurable viewport probe, and overlays
its own thumb + current-section chip on top of a normal SingleChildScrollView.
Why this package exists #
Many scroll experiences are organized into meaningful sections, but a standard scrollbar only communicates raw position. In practice, users often need both: where they are in the scroll range and which logical part of the content they are currently viewing.
section_scrollbar is a general-purpose primitive for any vertically scrolling
surface with structured sections, including:
- landing pages
- portfolio sites
- documentation pages
- dashboards
- reports
- settings screens
- onboarding flows
- long-form content experiences
It keeps the familiar scrollbar interaction model and adds a lightweight, rounded badge containing:
- the active section label
- the active section icon, if provided
- a stable section-aware controller API you can use for custom UI
Features #
- Section definitions with ids, labels, and optional icons
- Explicit section anchors for accurate layout measurement
- Active-section detection with configurable probe strategies
- Right-side custom scrollbar overlay for
SingleChildScrollView - Floating badge that appears while scrolling
scrollTo(id)andrecompute()on aChangeNotifiercontroller- Immutable public state for custom builders and advanced effects
- Pure Flutter implementation for mobile, web, and desktop
Installation #
flutter pub add section_scrollbar
Quick Start #
import 'package:flutter/material.dart';
import 'package:section_scrollbar/section_scrollbar.dart';
final sectionController = SectionScrollbarController();
final scrollController = ScrollController();
SectionScrollbarLayout(
controller: sectionController,
scrollController: scrollController,
sections: const [
SectionData(
id: 'intro',
label: 'Intro',
icon: Icons.waving_hand_rounded,
),
SectionData(
id: 'work',
label: 'Work',
icon: Icons.work_outline_rounded,
),
SectionData(
id: 'metrics',
label: 'Metrics',
icon: Icons.query_stats_rounded,
),
SectionData(
id: 'contact',
label: 'Contact',
icon: Icons.mail_outline_rounded,
),
],
config: const SectionScrollbarConfig(
activationStrategy: SectionActivationStrategy.quarterViewport,
),
child: SingleChildScrollView(
controller: scrollController,
child: Column(
children: const [
SectionAnchor(id: 'intro', child: IntroSection()),
SectionAnchor(id: 'work', child: WorkSection()),
SectionAnchor(id: 'metrics', child: MetricsSection()),
SectionAnchor(id: 'contact', child: ContactSection()),
],
),
),
);
How it works #
- Define your sections with
SectionData. - Wrap each real content section with
SectionAnchor. - Place everything inside
SectionScrollbarLayout. - The controller measures anchors after layout.
- On scroll, the controller resolves the active section and computes:
- page progress
- progress within the active section
- thumb size
- thumb offset
- active badge payload
- The default scrollbar renders a subtle track, a thumb, and a floating badge while scrolling.
Public API #
SectionData #
Declares a logical section.
Fields:
idlabeliconweight
SectionAnchor #
Wraps each measured content section and registers it with the nearest
SectionScrollbarLayout.
SectionScrollbarController #
The main ChangeNotifier that owns:
- section registration
- metric recomputation
- active-section detection
scrollTo(id)- immutable
state
SectionScrollbarConfig #
Controls behavior and default layout values.
Key fields:
activationStrategyscrollAnimationDurationscrollAnimationCurveoverlayWidthtrackThicknessthumbThicknessminThumbExtentbadgeSpacingvisibilityAnimationDurationalwaysShowScrollbar
SectionScrollbarState #
Immutable derived state exposed by the controller.
Key fields:
activeSectionIdactiveSectionLabelactiveSectionIconitemsscrollProgressactiveSectionProgressthumbOffsetFractionthumbExtentFractionhasMetricsisScrollActive
SectionScrollbarVisualItem #
Per-section render data for custom overlays and builders.
SectionScrollbarLayout #
Wraps your scroll view and places the overlay scrollbar on top of it.
SectionScrollbar #
Generic scrollbar shell for custom track/thumb/badge builders.
DefaultSectionScrollbar #
Default implementation that renders:
- a subtle vertical track
- a rounded thumb
- a rounded floating badge containing the active section metadata
Customization #
You can customize at two levels:
1. Config-only customization #
Use SectionScrollbarConfig when you only want to tune sizing, animation, or
visibility behavior.
2. Full overlay customization #
Pass scrollbarBuilder to SectionScrollbarLayout and render your own overlay
from the controller state.
The SectionScrollbarState.items list gives you section-level fractions and
progress values so you can build custom markers, painters, or richer badges.
Example #
The example app in example/lib/main.dart demonstrates:
- four tracked sections
- the default floating badge behavior
- controller-driven
scrollTo - varying section heights
Limitations in v1 #
- Vertical scrolling only
- Designed for one main
ScrollController - Supports
SingleChildScrollView, not slivers or nested scroll views - The default scrollbar is passive; thumb dragging is not implemented in v1
- Requires explicit
SectionAnchorwidgets for measured sections
Roadmap #
- Interactive thumb dragging
- Sliver support
- Nested scroll coordination
- Horizontal mode
- Accessibility improvements for keyboard and semantics
- More default badge and thumb styles
