off_topic
Tip: Hover the links for short summaries!
Starting apps
application, component, script
Making subscriptions
none, from, element, batch, dep, map, watch
Keyboard
on_key_press, on_key_down, on_key_up
Pointer
on_click, on_pointer_move, on_pointer_down, on_pointer_up, on_pointer_cancel, on_wheel
Browser
window_size, screen_orientation, window_scroll, scroll_to, page_state, window_hover, title, meta, body_class, prevent_unload
DOM
element_size, element_scroll, element_scroll_to, scroll_into_view, element_visible focus, blur, on
Component
aria, pseudo_state, form_value
Preferences
colour_scheme, contrast, reduced_motion, breakpoints, tailwind_breakpoints, language, local_storage, session_storage, set_local_storage, set_session_storage
Time
now, here, after, every, on_idle
Connections
online, server_sent_events, websocket, websocket_send
Advanced
init, update, view remote, command, watching, including, throttle, delay, root
Types
The user’s preferred color scheme.
pub type ColourScheme {
Dark
Light
}
Constructors
-
Dark -
Light
The user’s preferred contrast level.
pub type ContrastPreference {
MoreContrast
LessContrast
ForcedContrast
NoContrastPreference
}
Constructors
-
MoreContrast -
LessContrast -
ForcedContrast -
NoContrastPreference
An opaque value off_topic uses to detect when a subscription’s inputs have changed and it needs to be restarted.
Create one with dep.
pub type Dependency =
@internal Dependency
A keyboard event payload.
pub type Key {
Key(
key: String,
code: String,
ctrl: Bool,
alt: Bool,
meta: Bool,
shift: Bool,
)
}
Constructors
-
Key( key: String, code: String, ctrl: Bool, alt: Bool, meta: Bool, shift: Bool, )
The subscription runtime’s wrapper around your application message type.
Use with init, update, and view when wiring up off_topic manually instead of through application.
pub type Message(message) =
@internal Message(message)
The subscription runtime’s wrapper around your application model.
Use with init, update, and view when wiring up off_topic manually instead of through application.
pub type Model(model, message) =
@internal Model(model, message)
The user’s motion sensitivity preference.
pub type MotionPreference {
ReduceMotion
NoMotionPreference
}
Constructors
-
ReduceMotion -
NoMotionPreference
The current browser page lifecycle state.
Transitions follow the Page Lifecycle API.
Frozen pages may resume or be silently discarded by the browser;
Terminated is always final. The Discarded lifecycle state is absent
because the browser unloads discarded pages without firing any events.
pub type PageState {
Active
Passive
Hidden
Frozen
Terminated
}
Constructors
-
ActiveVisible and has input focus.
-
PassiveVisible but does not have input focus.
-
HiddenNot visible, and not frozen, discarded, or terminated.
-
FrozenBrowser has suspended execution to conserve resources; may resume or be discarded silently.
-
TerminatedPage has started unloading and will not resume.
A pointer event payload.
pub type Pointer {
Pointer(
x: Int,
y: Int,
button: Int,
pointer_type: PointerType,
pointer_id: Int,
is_primary: Bool,
pressure: Float,
tilt_x: Int,
tilt_y: Int,
ctrl: Bool,
alt: Bool,
meta: Bool,
shift: Bool,
)
}
Constructors
-
Pointer( x: Int, y: Int, button: Int, pointer_type: PointerType, pointer_id: Int, is_primary: Bool, pressure: Float, tilt_x: Int, tilt_y: Int, ctrl: Bool, alt: Bool, meta: Bool, shift: Bool, )
The pointing device type reported by a pointer event.
pub type PointerType {
Mouse
Pen
Touch
}
Constructors
-
MouseStandard mouse or trackpad.
-
PenStylus or digital pen.
-
TouchTouchscreen finger contact.
The screen orientation reported by the browser.
pub type ScreenOrientation {
PortraitPrimary
PortraitSecondary
LandscapePrimary
LandscapeSecondary
}
Constructors
-
PortraitPrimaryPortrait with the top of the device facing up.
-
PortraitSecondaryPortrait with the top of the device facing down (upside-down).
-
LandscapePrimaryLandscape with the top of the device facing right.
-
LandscapeSecondaryLandscape with the top of the device facing left.
The block or inline alignment for scroll_into_view.
pub type ScrollAlignment {
Start
Center
End
Nearest
}
Constructors
-
Start -
Center -
End -
Nearest
The scroll animation style.
pub type ScrollBehaviour {
Smooth
Instant
Auto
}
Constructors
-
Smooth -
Instant -
Auto
An active listener that dispatches messages to your Lustre application.
Build subscriptions with the functions in this module and return them from
your application’s subscriptions callback. Use batch to combine
multiple subscriptions, and none to return an empty one.
pub type Subscription(message) =
@internal Subscription(message)
A Tailwind CSS responsive breakpoint.
pub type TailwindBreakpoint {
Xs
Sm
Md
Lg
Xl
Xxl
}
Constructors
-
Xs -
Sm -
Md -
Lg -
Xl -
Xxl
A frame received from a WebSocket connection.
pub type WebsocketMessage {
TextFrame(data: String)
BinaryFrame(data: BitArray)
}
Constructors
-
TextFrame(data: String) -
BinaryFrame(data: BitArray)
A wheel event payload.
pub type Wheel {
Wheel(
delta_x: Float,
delta_y: Float,
delta_z: Float,
delta_mode: WheelDeltaMode,
ctrl: Bool,
alt: Bool,
meta: Bool,
shift: Bool,
)
}
Constructors
-
Wheel( delta_x: Float, delta_y: Float, delta_z: Float, delta_mode: WheelDeltaMode, ctrl: Bool, alt: Bool, meta: Bool, shift: Bool, )
Scroll-wheel delta units reported by the browser.
The browser decides which unit it uses; the most common is Pixel.
Never assume the delta is in Pixel mode without checking delta_mode.
pub type WheelDeltaMode {
Pixel
Line
Page
}
Constructors
-
Pixel -
Line -
Page
Values
pub fn after(
duration: duration.Duration,
send message: message,
) -> effect.Effect(message)
pub fn application(
init init: fn(flags) -> #(model, effect.Effect(message)),
update update: fn(model, message) -> #(
model,
effect.Effect(message),
),
subscriptions subscriptions: fn(model) -> Subscription(message),
view view: fn(model) -> element.Element(message),
) -> lustre.App(flags, Model(model, message), Message(message))
pub fn aria(
name name: String,
value value: String,
) -> Subscription(message)
Sync a single ARIA property on the component host’s ElementInternals.
name is attribute-style ("role", "aria-expanded", "aria-label", …);
off_topic converts it to the camelCase ElementInternals property and sets
it on the host’s ElementInternals. Does nothing outside a component context.
See also: pseudo_state, form_value
pub fn batch(
list: List(Subscription(message)),
) -> Subscription(message)
Combine a list of subscriptions into one.
See also: none
pub fn blur() -> effect.Effect(message)
Blur (unfocus) the currently focused element.
See also: focus
pub fn body_class(class_name: String) -> Subscription(message)
Add a CSS class to the document body.
The class is removed when the subscription stops or the class name changes.
See also: title
pub fn breakpoints(
fallback fallback: String,
breakpoints pairs: List(#(Int, String)),
send message: fn(String) -> message,
) -> Subscription(message)
Dispatch the current active breakpoint label, then again whenever it changes.
Pairs are matched largest-first, returning the label whose min_width the
window satisfies, or fallback when none match.
See also: window_size, tailwind_breakpoints
pub fn colour_scheme(
send message: fn(ColourScheme) -> msg,
) -> Subscription(msg)
Dispatch the current color scheme preference, then again whenever it changes.
See also: contrast, reduced_motion
pub fn command(
name: String,
params: List(json.Json),
) -> effect.Effect(message)
Dispatch a named browser command through the off_topic client runtime. SC
The server-component counterpart to effect.from: dispatches an
off-topic:command event that the ot-client-runtime web component
routes to the registered window.OffTopic.commands[name] handler on the
client.
For the built-in commands (set_local_storage, scroll_to, etc.) both
paths are handled automatically — use those directly. Reserve command
for custom handlers you register yourself.
See also: remote
pub fn component(
init init: fn(Nil) -> #(model, effect.Effect(message)),
update update: fn(model, message) -> #(
model,
effect.Effect(message),
),
subscriptions subscriptions: fn(model) -> Subscription(message),
view view: fn(model) -> element.Element(message),
options options: List(component.Option(message)),
) -> lustre.App(Nil, Model(model, message), Message(message))
Create a Lustre component that runs the off_topic subscription runtime. This is the component equivalent of application.
If you’re using component options, swap your import to off_topic/component,
offering the same API.
See also: application
pub fn contrast(
send message: fn(ContrastPreference) -> msg,
) -> Subscription(msg)
Dispatch the current contrast preference, then again whenever it changes.
See also: colour_scheme, reduced_motion
pub fn delay(
subscription: Subscription(message),
wait duration: duration.Duration,
) -> Subscription(message)
pub fn dep(value: any) -> Dependency
pub fn element(
watching dependencies: List(Dependency),
run callback: fn(fn(message) -> Nil, dynamic.Dynamic) -> fn() -> Nil,
) -> Subscription(message)
pub fn element_scroll(
selector selector: String,
send message: fn(Int, Int) -> msg,
) -> Subscription(msg)
Dispatch the scroll position of an element, then again whenever it changes.
Pass root to observe the component mount point, or any CSS selector for a descendant.
See also: window_scroll, element_size, element_visible
pub fn element_scroll_to(
selector selector: String,
x x: Int,
y y: Int,
behaviour behaviour: ScrollBehaviour,
) -> effect.Effect(message)
Scroll an element to a specific position.
x and y are pixel offsets within the scrollable element. Pass root
to target the component mount point, or any CSS selector for a descendant.
See also: element_scroll, scroll_to
pub fn element_size(
selector selector: String,
send message: fn(Int, Int) -> msg,
) -> Subscription(msg)
Dispatch the size of an element, then again whenever it changes.
Pass root to observe the component mount point, or any CSS selector for a descendant.
See also: window_size, tailwind_breakpoints, element_scroll, element_visible
pub fn element_visible(
selector selector: String,
send message: fn(Bool) -> msg,
) -> Subscription(msg)
Dispatch whether an element intersects the viewport, then again whenever it changes.
Useful for infinite scroll sentinels and lazy load / pause-on-hide patterns.
See also: element_size, element_scroll
pub fn every(
every interval: duration.Duration,
immediate immediate: Bool,
on_elapsed handle_elapsed: fn(timestamp.Timestamp) -> message,
) -> Subscription(message)
Dispatch a message on a repeating interval.
The callback receives the current timestamp at each tick. When
immediate is True, the first tick fires immediately on subscribe;
otherwise the first tick fires after the first interval has elapsed.
See also: after
pub fn focus(selector selector: String) -> effect.Effect(message)
Focus the first element matching selector.
See also: blur
pub fn form_value(
value value: option.Option(String),
) -> Subscription(message)
Sync the form-associated element’s submitted value.
The component has to have the form_associated option set.
Does nothing outside a component context.
See also: aria, pseudo_state
pub fn from(
watching dependencies: List(Dependency),
run callback: fn(fn(message) -> Nil) -> fn() -> Nil,
) -> Subscription(message)
Build a subscription from an arbitrary setup callback.
The callback receives a dispatch function and must return a cleanup
function that will be called when the subscription is torn down. off_topic
restarts the subscription whenever any value in dependencies changes.
For the exact rules on when and how subscriptions and their cleanup functions fire, see the guide.
pub fn here(
on_timezone_offset handle_timezone_offset: fn(duration.Duration) -> message,
) -> Subscription(message)
Dispatch the current timezone offset, then again whenever it changes.
Always dispatches the browser’s local timezone offset, even in server components — the server’s timezone is never used.
See also: now
pub fn including(
subscription: Subscription(message),
paths: List(String),
) -> Subscription(message)
Specify which fields are forwarded from a remote subscription’s events.
Remote subscriptions have to explicitely list all fields they want to
forward to the server. Has no effect on non-Remote subscriptions.
See also: remote
pub fn init(
flags flags: flags,
init init: fn(flags) -> #(model, effect.Effect(message)),
) -> #(Model(model, message), effect.Effect(Message(message)))
The low-level counterpart to application, for use when you
need to compose off_topic into an existing lustre.application manually.
See also: update, view, application
pub fn language(
send message: fn(String) -> msg,
) -> Subscription(msg)
Dispatch the current navigator language, then again whenever it changes.
Dispatches a BCP 47 language tag such as "en-US".
pub fn local_storage(
key key: String,
send message: fn(option.Option(String)) -> msg,
) -> Subscription(msg)
Dispatch the current value of a localStorage key, then again whenever it changes.
Dispatches None when the key is absent and Some(value) otherwise. Only
detects changes made in other tabs or windows — updates made in the current
page are not forwarded by the browser’s storage event unless
set_local_storage is called with notify: True.
See also: session_storage, set_local_storage
pub fn map(
subscription: Subscription(a),
with tagger: fn(a) -> b,
) -> Subscription(b)
Transform the messages a subscription dispatches.
pub fn meta(
name name: String,
content content: String,
) -> Subscription(message)
Update or insert a <meta name="…" content="…"> tag.
See also: title
pub fn now(
send message: fn(timestamp.Timestamp) -> message,
) -> effect.Effect(message)
pub fn on(
on target: Target,
event name: String,
run decoder: decode.Decoder(message),
) -> Subscription(message)
Subscribe to a DOM event on a target element.
pub fn on_click(
send message: fn(Pointer) -> message,
) -> Subscription(message)
Subscribe to click events on the document.
See also: on_pointer_down, on_pointer_up
pub fn on_idle(
after timeout: duration.Duration,
send message: fn(Bool) -> msg,
) -> Subscription(msg)
Dispatch a message when the user becomes idle or active.
Starts a timer that resets on any interaction with the current document.
Dispatches True when the timer elapses with no activity, and False when
activity resumes.
See also: page_state, window_hover
pub fn on_key_down(
send message: fn(Key) -> message,
) -> Subscription(message)
Subscribe to keydown events on the document.
See also: on_key_press, on_key_up
pub fn on_key_press(
send message: fn(Key) -> message,
) -> Subscription(message)
Subscribe to keypress events on the document.
See also: on_key_down, on_key_up
pub fn on_key_up(
send message: fn(Key) -> message,
) -> Subscription(message)
Subscribe to keyup events on the document.
See also: on_key_press, on_key_down
pub fn on_pointer_cancel(
send message: fn(Pointer) -> message,
) -> Subscription(message)
Subscribe to pointer cancel events on the document.
Fires when the browser interrupts a pointer sequence — for example when a touch is cancelled by an incoming phone call or the pointer leaves the browser window mid-drag.
See also: on_pointer_down, on_pointer_up
pub fn on_pointer_down(
send message: fn(Pointer) -> message,
) -> Subscription(message)
Subscribe to pointer down events on the document.
See also: on_pointer_up, on_click
pub fn on_pointer_move(
send message: fn(Pointer) -> message,
) -> Subscription(message)
Subscribe to pointer move events on the document.
See also: on_pointer_down, on_pointer_up
pub fn on_pointer_up(
send message: fn(Pointer) -> message,
) -> Subscription(message)
Subscribe to pointer up events on the document.
See also: on_pointer_down, on_click
pub fn on_wheel(
send message: fn(Wheel) -> message,
) -> Subscription(message)
Subscribe to wheel events on the document.
See also: window_scroll
pub fn online(send message: fn(Bool) -> msg) -> Subscription(msg)
Dispatch the current network status, then again whenever it changes.
Dispatches True when online and False when offline.
pub fn page_state(
send handle_page_state: fn(PageState) -> message,
) -> Subscription(message)
Dispatch the current page lifecycle state, then again whenever it changes.
No initial dispatch fires when the page starts in the Active state, which
is the common case on load. If the page is already Passive or Hidden at
subscription setup, the current state dispatches immediately.
pub fn prevent_unload(
prevent enabled: Bool,
send message: message,
) -> Subscription(message)
Block the user from immediately leaving the page when enabled, showing a simple popup instead.
Useful for when your page has unsaved changes that you don’t want users to accidentily lose.
pub fn pseudo_state(
name name: String,
checked checked: Bool,
) -> Subscription(message)
Sync a single CSS custom state on the component host. Does nothing outside a component context.
See also: aria, form_value
pub fn reduced_motion(
send message: fn(MotionPreference) -> msg,
) -> Subscription(msg)
Dispatch the current motion preference, then again whenever it changes.
See also: colour_scheme, contrast
pub fn remote(
name name: String,
with params: List(json.Json),
run decoder: decode.Decoder(message),
) -> Subscription(message)
Build a subscription that runs on the server component client.
See also: including
pub const root: String
CSS selector for the component mount point.
Pass root as the selector argument to any element-scoped subscription
to target the Lustre component mount element.
See also: target, element_size, element_scroll, element_visible
pub fn screen_orientation(
send message: fn(ScreenOrientation) -> msg,
) -> Subscription(msg)
Dispatch the current screen orientation, then again whenever it changes.
pub fn script() -> element.Element(msg)
Inline the server component runtime as a <script> tag.
Prefer serving the pre-built file from off_topic’s priv/static directory
when possible. This inline version is useful for development or when you
do not control the HTML document.
pub fn scroll_into_view(
selector selector: String,
block block: ScrollAlignment,
inline inline: ScrollAlignment,
behaviour behaviour: ScrollBehaviour,
) -> effect.Effect(message)
Scroll the first element matching selector into view.
See also: scroll_to
pub fn scroll_to(
x x: Int,
y y: Int,
behaviour behaviour: ScrollBehaviour,
) -> effect.Effect(message)
Scroll the window to a specific position.
x and y are pixel offsets from the top-left corner of the document.
See also: window_scroll, scroll_into_view
pub fn server_sent_events(
url url: String,
on_open opened: msg,
on_message message: fn(String, String) -> msg,
on_error errored: msg,
) -> Subscription(msg)
Subscribe to a Server-Sent Events stream. JS
Opens an EventSource at url and sends on_message(id, data) to your update
function for each incoming message. The connection is closed when the
subscription is torn down and reopened whenever url changes.
on_open fires on the initial connection and on every successful reconnect.
on_error fires when the connection is lost, before the next retry.
pub fn session_storage(
key key: String,
send message: fn(option.Option(String)) -> msg,
) -> Subscription(msg)
Dispatch the current value of a sessionStorage key, then again whenever it changes.
Dispatches None when the key is absent and Some(value) otherwise. Only
detects changes made in other tabs or windows — updates made in the current
page are not forwarded by the browser’s storage event unless
set_session_storage is called with notify: True.
See also: local_storage
pub fn set_local_storage(
key key: String,
value value: option.Option(String),
notify notify: Bool,
) -> effect.Effect(message)
Write a value to localStorage, or remove the key when value is None.
When notify is True, a synthetic storage event is dispatched so that
local_storage subscriptions are notified of the change
immediately.
See also: local_storage, set_session_storage
pub fn set_session_storage(
key key: String,
value value: option.Option(String),
notify notify: Bool,
) -> effect.Effect(message)
Write a value to sessionStorage, or remove the key when value is None.
When notify is True, a synthetic storage event is dispatched so that
session_storage subscriptions are notified of the
change immediately.
See also: session_storage, set_local_storage
pub fn tailwind_breakpoints(
send message: fn(TailwindBreakpoint) -> message,
) -> Subscription(message)
Dispatch the current Tailwind CSS breakpoint, then again whenever it changes.
See also: breakpoints, window_size
pub fn throttle(
subscription: Subscription(message),
wait duration: duration.Duration,
) -> Subscription(message)
Limit how often a subscription dispatches messages.
When a subscription fires more frequently than duration, intermediate
messages are dropped. The first message always passes through immediately.
See also: delay
pub fn title(value value: String) -> Subscription(message)
Update the document <title>.
See also: meta
pub fn update(
model: Model(model, message),
message: Message(message),
subscriptions: fn(model) -> Subscription(message),
update: fn(model, message) -> #(model, effect.Effect(message)),
) -> #(Model(model, message), effect.Effect(Message(message)))
Handle a message in the subscription runtime.
The low-level counterpart to application, for use when you
need to compose off_topic into an existing lustre.application manually.
See also: init, view, application
pub fn view(
model: Model(model, message),
view: fn(model) -> element.Element(message),
) -> element.Element(Message(message))
Render the application view through the subscription runtime.
The low-level counterpart to application, for use when you
need to compose off_topic into an existing lustre.application manually.
On the server target, this also injects the ot-client-runtime web
component into the rendered output.
See also: init, update, application
pub fn watch(
watching dependencies: List(Dependency),
run callback: fn() -> Nil,
) -> Subscription(message)
pub fn watching(
subscription: Subscription(message),
watching dependencies: List(Dependency),
) -> Subscription(message)
pub fn websocket(
url url: String,
on_open opened: msg,
on_message message: fn(WebsocketMessage) -> msg,
on_error errored: fn(String) -> msg,
) -> Subscription(msg)
Subscribe to a WebSocket connection. JS
Connects to url and dispatches messages for each event. Connections are
shared — multiple subscriptions to the same URL reuse a single socket.
The socket reconnects automatically it drops, as long as the subscription
is alive. The connection is closed when the last subscriber unsubscribes.
on_open fires on the initial connection and on every successful reconnect.
on_error fires when the connection is lost, before the next retry.
See also: websocket_send
pub fn websocket_send(
url url: String,
data data: WebsocketMessage,
) -> effect.Effect(msg)
Send a frame over an open WebSocket connection. JS
Does nothing if there is no active connection for url or if the socket
is not yet open.
See also: websocket
pub fn window_hover(
send message: fn(Bool) -> msg,
) -> Subscription(msg)
Dispatch the current window hover state, then again whenever it changes.
Only reliable when the window has focus; browsers do not consistently deliver pointer events to unfocused windows.
pub fn window_scroll(
send message: fn(Int, Int) -> msg,
) -> Subscription(msg)
Dispatch the current scroll position, then again whenever it changes.
pub fn window_size(
send message: fn(Int, Int) -> msg,
) -> Subscription(msg)
Dispatch the current window size, then again whenever it changes.
See also: breakpoints, tailwind_breakpoints