Scrollable Block
The Scrollable block is a layout container whose content scrolls when it outgrows the available space. Like a Stack, it arranges children in a row or column with alignment and spacing — but it adds scroll-specific capabilities: methods to scroll to a position or specific child, an event that fires when a child enters or leaves view, and on mobile: pull-to-refresh and block snapping.
Note: Scrollable vs. Stack with overflow: For most scrolling needs, simply set Overflow in a Stack's Styles. Use Scrollable when you specifically need scroll methods (scrollToComponent, scrollToPosition), scroll visibility events, pull-to-refresh, or page snapping — these are Scrollable-only features.
Scrollable — Content Properties
| Property | Type | Default | Description |
| snapping | boolean | false | Enables page-by-page snapping. Mobile native only — no effect on web |
| interactions | event list | — | On Pull Down (mobile native) and On Scroll Visibility Change handlers |
Scrollable — Appearance Properties
| Property | Type | Default | Description |
| direction | "column" | "row" | column | Which way children flow — and which way the container scrolls |
| justifyContent | flex-start | center | flex-end | space-between | flex-start | Spacing of children along the scroll direction |
| alignItems | flex-start | center | flex-end | stretch | stretch | Alignment of children across the scroll direction |
| wrapContent | boolean | false | Let children wrap onto the next line instead of overflowing |
| reverseOrder | boolean | false | Render children in reverse visual order |
| styles | style set | gap md, transparent bg | Width/min/max, height/min/max, margin, padding, gap, rotation, color, stroke, radius |
| theme | inherit | light | dark | inherit | Force light or dark theme inside the container |
| visibility | conditions | — | Show/hide the whole block |
Scrollable Events
| Event | Trigger | Payload | Platform |
| On Pull Down | User pulls content down from the top (pull-to-refresh gesture) | — | Native mobile apps only |
| On Scroll Visibility Change | A tracked child block scrolls into or out of view | targetBlockId, visibilityState (in_view | above_view | below_view) | All platforms |
Scrollable Methods
Warning: Scroll methods are native mobile only. Calling them on web does nothing (a warning is logged). Design web pages around anchor-style navigation instead.
| Method | Parameters | Description | Platform |
scrollToComponent | Component (direct child), Position (top|bottom|center), Offset (px) | Smooth-scrolls until the chosen child sits at the specified position. Never overshoots content edges | Native mobile only |
scrollToPosition | Position (top|bottom|center), Offset (px) | Smooth-scrolls to the top, bottom, or middle of the content | Native mobile only |
Scrollable Behaviors & Gotchas
Warning: Pull-to-refresh spinner hides after ~1 second regardless: The spinner shown by the pull-down gesture disappears roughly 1 second after On Pull Down fires — not when your actions finish. A slow data refresh keeps running after the spinner is gone. Show your own loading state if needed.
Warning: Snapping snaps by full pages, not individual blocks: Scrolling stops at whole-viewport pages. For clean per-block snapping, size each child to fill the entire container (e.g., height 100%).
Note: Scrollbars are invisible on mobile: Native mobile apps never show a scroll indicator. Web apps hide the scrollbar in mobile layouts. Make "there's more below" visible through design (a peeking next card, a fade).
Note: Visibility events fire only for configured children: On Scroll Visibility Change tracks only child blocks referenced by a configured handler. Nothing fires at page load; the first event comes from an actual scroll that changes a tracked child's state.
Note: scrollToComponent only reaches direct children: The Component picker lists only this Scrollable's own children. You cannot target blocks nested deeper inside a child.
Scrollable — Examples
Divider Block
The Divider block draws a separator line — horizontal or vertical, solid, dashed, or dotted — between parts of a layout. It can optionally hold content in the middle of the line (a Body slot) — the classic "— OR —" pattern. It is purely visual: no events, no methods, no state.
Divider — Content Properties
| Property | Type | Default | Appears When | Description |
| orientation | "horizontal" | "vertical" | horizontal | Always | The direction of the separator line |
| height (thickness) | pixels | 1 px | orientation = horizontal | Thickness of a horizontal divider |
| width (thickness) | pixels | 1 px | orientation = vertical | Thickness of a vertical divider |
| dividerStyle | "solid" | "dashed" | "dotted" | solid | Always | The line's stroke pattern |
| slots.body | slot (one block) | empty | Always | Optional content rendered in the middle of the line (text label, icon, button) |
Divider — Appearance Properties
| Property | Type | Default | Description |
| styles | style set | line color border-tertiary | Length (Width group for horizontal; Height group for vertical), Stroke (line color), flex layout, margin, visibility |
| theme | inherit | light | dark | inherit | Follows or overrides the page's color scheme |
| visibility | conditions | — | Show/hide the block |
| permissions | permission rule | — | Restrict who sees the block. Note: permissions live under Appearance, not Content |
Note: Thickness and length live in different panels and swap names with orientation:Horizontal divider: thickness = Content → Height; length = Appearance → Styles → Width groupVertical divider: thickness = Content → Width; length = Appearance → Styles → Height group
Note: Line color = Stroke style: To recolor the divider, set Stroke in Appearance → Styles. Background-style settings have no effect on the line itself.
Divider — Examples
Frequently Asked Questions
What is the difference between a Scrollable and a Stack with Overflow set to scroll?
Both create scrolling containers, but Scrollable adds scroll-specific features: the scrollToComponent and scrollToPosition methods, an On Scroll Visibility Change event for tracking when children enter/leave view, pull-to-refresh (mobile), and page snapping (mobile). Use a Stack with overflow for simple scroll needs and Scrollable when you need any of these extra capabilities.
My pull-to-refresh spinner disappears before my data finishes loading. Why?
By design, the built-in spinner shown by the On Pull Down gesture hides after approximately 1 second regardless of whether your actions have completed. The data refresh continues running after the spinner is gone. To give users a loading signal, add your own loading state (e.g., a Loader block visible while your data source's isLoading is true).
Why doesn't scrollToComponent work in my web app?
The scrollToComponent and scrollToPosition methods are native mobile app-only features. They have no effect in web apps — a warning is logged to the developer console. For web scroll navigation, use anchor links or CSS scroll-behavior instead.
How do I change the color of a Divider line?
Set the Stroke style in Appearance → Styles. Background-color settings do not affect the line. The default color is the border-tertiary theme token.
Can I put content (like a label or button) in the middle of a Divider?
Yes — use the Divider's Body slot (Inspector → Content → Slots → Body). Drop a Text block or any block into the Body slot, and it renders centered in the line with the separator running to either side. This is the "— OR —" pattern.
Related Blocks
| Block | Relationship |
| Stack | Same layout controls as Scrollable without dedicated scroll behavior |
| Repeatable | Renders a list from data; place inside a Scrollable to scroll it |
| Swipeable Stack | Card-deck swiping vs. Scrollable's page snapping |
| Container | Hosts dividers between children; use gap for invisible spacing |
| Text / Typography | Common content for the Divider's Body slot |