Skip to main content
Live example: app/demo/order-ticket.tsx in the example app.
Regular scrubbing is ephemeral — the crosshair follows your finger and vanishes on release. scrubAction turns it into a placed interaction: tap to drop a locked reticle, drag to fine-tune a price, then press the action badge to fire a callback. The driving use case is order entry — pick a limit price on the chart and open an order ticket.

Tap to drop a price reticle, drag to fine-tune, press + to fire the ticket

The badge reports the price at the reticle’s Y position — a free level you choose, the inverse of the value→pixel mapping — not the line/candle value at that X. That’s what makes it an order tool: a limit order is a horizontal price level, so the locked reticle reads the price under the crosshair, exactly like the crosshair badge in pro charting tools. It works the same in line and candle mode (price-from-Y is mode-agnostic); LiveChartSeries is not supported. scrubAction coexists with scrub/onScrub, disambiguated by a press-hold: a quick tap places or acts on the reticle, while a deliberate press-and-hold starts a drag — live-scrub with no reticle placed, or fine-tune once one is locked. The hold means a tap never flashes the crosshair; tune it with scrub.panGestureDelay (defaults to a short hold in this mode). (Set scrub={{ dimOpacity: 1 }} to keep working-order lines un-dimmed while a reticle is down.)

Reading the press (onScrubAction)

onScrubAction fires on the JS thread when the badge is pressed, with a ScrubActionPoint. The library asserts no buy/sell semantics — derive the side from price versus your own current price:

Persisting the working order

The mode is callback-only — it owns the transient reticle, not your order state. To keep a placed order on the chart, push a reference line with a badge from the callback — the same primitive used for price alerts and targets:

Configuring the badge

Pass a ScrubActionConfig to set the glyph, colors, price snapping, or dismissal behavior:
Set text: false for an icon-only badge — just the circular action button, attached to the level line with no price pill:

Time badge (timeBadge)

timeBadge adds a date/time pill where the reticle’s vertical line meets the x-axis (formatted by the chart’s formatTime). It’s off by default — for order entry the reticle’s X is incidental (a limit order is a horizontal price level, and the reported price comes from the reticle’s Y, not its time). Turn it on when the time under the reticle is meaningful — annotations, time-relevant actions, or a full crosshair readout:
For an exact date + time (not just the clock), pass a formatTime that includes the date. The pill sizes itself to the string and stays centered on the reticle, clamping into the axis gutter near the edges — so a longer label just makes a wider pill (the same way the x-axis tick labels widen).
formatTime runs on the UI thread (axis labels, tooltip, and the time badge all call it inside worklets), so a custom formatter must be a worklet and use worklet-safe ops — new Date getters with manual formatting, not toLocaleString / Intl (which aren’t available on the UI runtime and throw “tried to call a non-worklet function”).
See ScrubActionConfig and ScrubActionPoint for every field.