Skip to main content
VeltPresence, VeltCursor, and VeltReactionTool are the three real-time-collaboration surfaces. This file owns the layer above Props for them: what every prop does at runtime, its default, the state it drives, and how props combine: plus the default behaviors you get with no prop at all (presence avatar list + self, live cursor follow, reaction-tool emoji set). Read this alongside Component definitions (anchored-vs-static classification) and Data models (the PresenceUser / CursorUser entities these surfaces read).
  • Who positions them (the key gotcha):
    • VeltPresence is statically placed: it renders an avatar row exactly where you mount it, like any normal React element; you control its position with your own CSS.
    • VeltCursor is anchored / Velt-positioned: mount it once (typically near the app root) and Velt paints every remote user’s cursor as a fixed-position overlay following each user’s real pointer in viewport coordinates. You do not position individual cursors.
    • VeltReactionTool is a statically-placed trigger button (you place it), but the reactions it can produce on a video timeline are themselves anchored to media position.
    • See Behaviors → Positioning ownership and Component definitions for the anchored-vs-static axis.
  • One mount each: VeltCursor guards against duplicate subscriptions: only the first velt-cursor element in the DOM actually subscribes to the live-cursor stream and renders; additional instances are inert. Mount it once.

Per-prop behavior (exhaustive)

The exhaustive per-prop behavior for the three real-time surfaces is organized per component below: each ## Velt… subsection carries that component’s full prop table (default + runtime behavior + interactions) and its own ### Default behaviors (no prop needed) block. Every prop in Props for these components is covered (plus the source-only props noted inline); see Provable coverage.

VeltPresence

A statically-placed avatar row showing who is currently online on the same document/location. It subscribes to online users for the current document, filters them by location (if scoped), and renders avatars with a hover tooltip. Confirmed against the presence component.

Default behaviors (no prop needed)

  • Avatar row of online users. Out of the box VeltPresence renders a horizontal list of avatars for everyone online on the current document, capped at 5 (maxUsers), with a “+N” overflow count beyond that. Each avatar has a hover tooltip showing the user’s name and active/away status.
  • You are included. self defaults to true, so your own avatar is in the row by default.
  • All users, unless scoped. With no location/locationId, every online user on the document shows; set either to scope to a sub-region.
  • Idle then offline. Users transition online → inactive (after inactivityTime) → offline (after offlineInactivityTime), driving the tooltip’s away-time. The component literals are 5 / 10; the presence service’s real baselines are minute-scale, and the prop values you pass are interpreted as milliseconds.
  • No flock by default. flockMode is off; clicking an avatar only emits onPresenceUserClick and shows the tooltip: it does not start following anyone until you enable flock mode.
  • Style-isolated. shadowDom defaults true.

VeltCursor

An anchored / Velt-positioned surface: mount it once and Velt overlays every other online user’s live cursor on the page, tracking each user’s real pointer position. The local user’s own pointer position is read from window pointer-move events (offset by 2px). Confirmed against the cursor component.

Default behaviors (no prop needed)

  • Live remote cursors follow real pointers. With just <VeltCursor /> mounted, every other online user’s cursor appears as a named pointer that moves in real time, positioned in viewport coordinates (Velt owns placement: you don’t set per-cursor positions). The local user’s position is sampled from window pointer-move (offset −2px / −2px).
  • Name labels, not avatars. avatarMode is false by default → cursors show the user’s name, not their avatar.
  • Mount-once / first-instance-wins. Only the first velt-cursor element subscribes and renders; duplicate mounts are inert (prevents double subscriptions). Mount one near the app root.
  • Idle cursors flush. A cursor that stops updating past inactivityTime is hidden (service baseline 2 minutes).
  • Whole-page by default. allowedElementIds empty → cursors render anywhere; set it to confine them.
  • Always shadow-DOM isolated. The cursor component renders with shadow-DOM encapsulation always on (it is not a toggleable prop here, unlike presence): style it via the cursor CSS variables, not deep selectors. There is no shadowDom prop on VeltCursor; this reference documents no master flag that affects it.

VeltReactionTool

A statically-placed trigger button that opens an emoji/reaction picker panel. Documented props in Props are videoPlayerId and onReactionToolClick; the component also accepts several additional inputs/outputs present in source (noted below and marked where not listed in Props). Confirmed against the reaction-tool component.

Default behaviors (no prop needed)

  • A button that opens an emoji panel. Out of the box the tool renders an “Add reaction” trigger (role=button, aria-haspopup); clicking it opens a positioned overlay panel of emojis.
  • The default emoji set. With no customization the picker shows Velt’s built-in SVG emoji set: confirmed keys: RAISED_HANDS, THUMBS_DOWN, THUMBS_UP, HEART_FACE, TEARS_OF_JOY, EYES, FIRE. The rendered ordering follows the emoji-map iteration order; this reference does not guarantee it as a stable display order.
  • Emit-only unless bound to video. With no videoPlayerId, selecting an emoji just fires emojiSelected and closes the panel: nothing is persisted; the host wires up the effect. Bind videoPlayerId to make selection write a reaction at the current media position (and pause playback).
  • Custom emoji set is an SDK-level concern. The picker’s contents come from the emoji service, which is overridden via the app-level customReactions / ReactionMap configuration (see Component config), not via a prop on this component. excludeReactionIds only subtracts from whatever set is active.
  • Style-isolated. shadowDom defaults true.

Default behaviors (no prop needed)

Each component’s zero-prop baseline is documented in its ### Default behaviors (no prop needed) block above. In brief:
  • VeltPresence: renders a horizontal avatar row of everyone online on the document (cap maxUsers 5, “+N” overflow, hover tooltips), includes the current user (self true), shows all users unless scoped by location/locationId, transitions online → inactive → offline, no flock by default, shadow-DOM isolated.
  • VeltCursor: paints every other online user’s live cursor as a name-labeled pointer in viewport coordinates (Velt owns placement); only the first mounted instance subscribes; idle cursors flush after the inactivity window; always shadow-DOM isolated.
  • VeltReactionTool: renders an “Add reaction” button that opens Velt’s default emoji set, emits emojiSelected only (no persistence) unless bound to a videoPlayerId, shadow-DOM isolated.

Prop-interaction matrix

No separate multi-prop matrix for this group: pairwise effects live in each prop’s Interactions & gotchas column above. The interactions worth restating:
  • VeltPresence: offlineInactivityTime must be inactivityTime (a smaller value is rejected); locationId takes precedence over location; flockMode gates onNavigate/defaultFlockNavigation and pairs with onPresenceUserClick (a click sets the flock leader only when flock mode is on); the current user counts toward maxUsers when self is on.
  • Deprecated callbacks fire/write alongside their replacements: onUsersChangedonPresenceUserChange, onCursorUsersChangedonCursorUserChange, disableFlockNavigationdefaultFlockNavigation.
  • VeltReactionTool: videoPlayerId switches selection from emit-only to writing a media-anchored reaction; excludeReactionIds only subtracts from the active set (customReactions is the SDK-level way to add).

Positioning & composition

Mixed: VeltPresence and VeltReactionTool are statically placed: they render where you mount them and you control position with your own CSS (the video reactions a reaction tool can produce are themselves anchored to media-timeline position). VeltCursor is anchored / Velt-positioned: mount it once near the app root and Velt paints each remote cursor as a fixed-position overlay tracking that user’s real pointer; you do not position individual cursors. See Behaviors → Positioning ownership and the anchored-vs-static classification in Component definitions.

Provable coverage

Coverage notes: documentParams is not documented as a live presence input; no master shadowDom flag is documented for VeltCursor; the default emoji display order is not guaranteed as stable. Everything else is stated as covered behavior.