Scroll area

v0.0.10

v0.0.10StableMobStatelessApache-2.0
Installation mix mishka.ui.gen.mob scroll_area
Source View Source

The Mishka Chelekom Mob Scroll Area is a bounded region whose content scrolls vertically or horizontally on iOS and Android. It is the native port of the headless Scroll Area and runs on Mob.

Overview of the Mob Scroll Area component for iOS and Android

Scroll Area wraps Mob's native Scroll, so the platform supplies momentum, overscroll, rubber banding and the scrollbar. The web component exists mainly to replace the browser scrollbar with a styled one. A phone has nothing to replace, and a hand-drawn scrollbar would be worse than the real one.

A scroll area needs a bound. Content scrolls only when the viewport is smaller than it, so a vertical scroll area inside a page that already scrolls needs a height. Without one it grows to fit its content and never scrolls. The showcase app always sets height.

The Scroll itself takes no size or decoration. With no height, background, padding or corner_radius, Scroll Area is a single Scroll node. Otherwise it is a Box with fill_width around the Scroll.

Scroll Area keeps no state and sends no events, because the native view owns the scroll position. An id registers the native scroll view so a screen can move it without a finger. See MishkaScroller.nudge/3 on the Mob Scroller page, which is what the scroller arrows call.

Generate the scroll area component

Run this from your Mob app's root to add the component to lib/<app>/components/:

bash
mix mishka.ui.gen.mob scroll_area

The generator registers the <ScrollArea> tag so you can use it in ~MOB markup. The examples on this page use the mishka_ prefix of the showcase app (--module-prefix mishka_), so the tag is <MishkaScrollArea>. Without a prefix the tag is <ScrollArea>.

Vertical scroll area

height bounds the viewport. Without it, nothing scrolls. The showcase app also sets a raised background, rounded corners and padding on the area.

Vertical scroll area

Vertical card with a white rounded scroll area listing Row 1 to Row 6, in the MishkaMob showcase app on Android
heex
<MishkaScrollArea height={200} background={:surface_raised}>{rows()}</MishkaScrollArea>

Horizontal scroll area

orientation: :horizontal scrolls a wide row. Flick sideways to move through the tiles.

Horizontal scroll area

Horizontal card with a white rounded scroll area holding three tiles, gray, near black and gray, the last cut short, in the MishkaMob showcase app on Android
heex
<MishkaScrollArea orientation={:horizontal}>{wide_row()}</MishkaScrollArea>

Scroll area without props

With no height or styling, Scroll Area is a single Scroll node. In the showcase app, a box 120 dp tall around it supplies the bound.

Scroll area without props

Undecorated card with a white rounded scroll area showing Row 1 to Row 3 and a fourth row cut off at the bottom, in the MishkaMob showcase app on Android
heex
<MishkaScrollArea>{content}</MishkaScrollArea>

Props

PropTypeDefaultDescription
orientation:vertical or :horizontal:verticalScroll axis.
heightnumbernilViewport height. Required for a vertical scroll area to scroll at all.
idstringnilRegisters the native scroll view so a screen can scroll it by id.
backgroundcolor token or ARGB intnilViewport fill.
paddingspacing token or numbernilPadding inside the viewport.
corner_radiusradius token or numbernilRounds the viewport.

Differences from the web component

  • orientation: "both" is not ported. Compose's Scroll scrolls one axis, and two-axis content needs a horizontal scroller nested inside a vertical one. You write that nesting yourself. The web component's third value is dropped so it never silently behaves like :vertical.
  • The *_class attributes are not ported, because they style a scrollbar that the platform owns.