- Getting Started
- Architecture
- The Basics
- Digging Deeper
-
EDGE Components
- Introduction
- Accordion
- Activity Indicator
- Badge
- Bottom Navigation
- Bottom Sheet
- Button
- Button Group
- Canvas
- Carousel
- Checkbox
- Chip
- Column
- Divider
- Floating Action Button
- Gesture Area
- Icon
- Image
- Lazy Grid
- Layout & Styling
- List
- Menus
- Modal
- Pressable
- Progress Bar
- Radio Group
- Refreshable
- Row
- Scroll View
- Select
- Shapes
- Side Navigation
- Slider
- Spacer
- Stack
- Tab Row
- Text
- Text Input
- Toggle
- Top Bar
- Virtual List
- Web View
- Plugins
- Testing
- Publishing Your App
Scroll View
Get the Jump app
You'll need the free Jump app to preview this page on your device. Install it, then scan the code again.
Overview#
A scrollable container for content that exceeds the available screen space. By default it scrolls vertically, but can
be configured for horizontal or two-axis (2D pan) scrolling. On the native side, this uses LazyColumn/LazyRow on
Android and ScrollView on iOS for efficient rendering.
<native:scroll-view class="w-full h-[240] rounded-xl border border-theme-outline"> <native:column class="w-full p-4 gap-3"> @foreach (range(1, 20) as $i) <native:text class="text-theme-on-surface-variant">Scrollable row {{ $i }}</native:text> @endforeach </native:column></native:scroll-view>
The fixed h-[240] here just gives the preview a bounded viewport so the content overflows and scrolls. On a real
screen you'd typically let the scroll view fill the page instead:
<native:scroll-view fill> <native:column :padding="16" :gap="12"> @foreach($items as $item) <native:text>{{ $item->name }}</native:text> @endforeach </native:column></native:scroll-view>
Props#
All shared layout and style attributes are supported, plus:
axis- Scroll direction:vertical,horizontal, orboth(optional, default:vertical).bothenables 2D panning for content that's larger than the viewport in both dimensions — give the inner content explicit dimensions larger than the viewport for there to be anything to pan tohorizontal- Scroll horizontally instead of vertically (optional, boolean, default:false).axis="horizontal"is the modern equivalentshows-indicators- Show scroll indicators (optional, boolean, default:true) [iOS]scroll-anchor- Set tobottomfor chat-style behavior: the view opens at the latest item and auto-scrolls on new content while the user is near the bottom (optional)
Children#
Accepts any EDGE elements as children. Typically wraps a single <native:column> or <native:row> that contains the
scrollable content.
Examples#
Vertical list#
A full-screen list of posts. safe-area keeps the content clear of the notch and home indicator, so this one is
meant for a real page root — run it in your app to see it edge-to-edge:
<native:scroll-view fill class="bg-theme-background"> <native:column class="w-full gap-3 p-4 safe-area"> @foreach($posts as $post) <native:column class="w-full p-4 gap-2 bg-theme-surface rounded-xl"> <native:text class="text-lg font-semibold">{{ $post->title }}</native:text> <native:text class="text-base text-theme-on-surface-variant">{{ $post->excerpt }}</native:text> </native:column> @endforeach </native:column></native:scroll-view>
Horizontal carousel#
<native:scroll-view horizontal :shows-indicators="false"> <native:row :gap="12" :padding="16"> @foreach($categories as $category) <native:column :width="120" :height="80" center class="bg-theme-surface-variant rounded-xl" > <native:text class="text-sm font-medium text-theme-on-surface-variant">{{ $category->name }}</native:text> </native:column> @endforeach </native:row></native:scroll-view>
Full-page scrollable layout#
Another page-root pattern — h-full and safe-area only make sense against a real screen, so try this one in your
app:
<native:scroll-view class="w-full h-full bg-theme-background"> <native:column class="w-full gap-4 safe-area p-4"> <native:text class="text-3xl font-bold">Welcome</native:text> <native:text class="text-base text-theme-on-surface-variant"> Scroll down to see more content. </native:text> {{-- Long content here --}} </native:column></native:scroll-view>
Chat-style stick-to-bottom#
The view opens at the latest message and stays pinned to the bottom as new content arrives. The fixed h-[200]
bounds the preview so there's something to scroll — in a real chat screen you'd use fill instead:
<native:scroll-view scroll-anchor="bottom" class="w-full h-[100] rounded-xl border border-theme-outline"> <native:column class="w-full gap-2 p-4"> @foreach($messages as $message) <native:text class="text-base text-theme-on-surface-variant">{{ $message->body }}</native:text> @endforeach </native:column></native:scroll-view>
Centering short content#
A login screen, an empty state, a confirmation — content that should sit in the middle of the page but must still scroll once the keyboard appears or the content grows.
Give the scroll view's child fill. It then stretches to at least the height of the scroll view's visible area, which
is what gives justify-center room to work:
<native:scroll-view fill class="bg-theme-background"> <native:column fill class="w-full items-center justify-center p-6 gap-4"> <native:column class="w-full max-w-[360px] bg-theme-surface rounded-2xl p-6 gap-4"> <native:text class="text-2xl font-bold">Welcome back</native:text> <native:outlined-text-input native:model="email" label="Email" keyboard="email" /> <native:outlined-text-input native:model="password" label="Password" secure /> <native:button class="w-full">Sign in</native:button> </native:column> </native:column></native:scroll-view>
Element#
use Native\Mobile\Edge\Elements\ScrollView; ScrollView::make() ->horizontal() ->both() ->showsIndicators(false) ->autoScrollTo(0);
make(Element ...$children)- Create a scroll view with childrenhorizontal(bool $value = true)- Scroll horizontally instead of verticallyboth()- Enable 2D panning on both axesshowsIndicators(bool $value = true)- Toggle scroll indicators [iOS]autoScrollTo(int $index)- Programmatically scroll to the child at$index
in no time