VeltCommentPin, VeltCommentBubble, and VeltCommentTool are the three anchored / Velt-positioned comment surfaces: they drop where the user clicks, attach to a target element, or sit inside Velt’s own comment host, and Velt owns their placement. This file owns the layer above Props for these three: what every prop does at runtime, its default, and how it combines with the others, plus the default click/hover/drag/index behaviors you get with no prop at all.
- Who positions them: see
Behaviors→ Positioning ownership. Pins drop where clicked, the dialog anchors to its pin and re-anchors on resize, bubbles attach to their target element: all for free as long as you stay in wireframes. Drop to primitives/headless and you take over positioning. - Anchored-vs-static classification: see
Component definitions. Pins, the pin dialog, and bubbles are anchored; the sidebar, inline comments section, and notifications panel are statically placed.
context / contextOptions / locationId / documentId / folderId scoping props with identical semantics, documented once here per component.
Per-prop behavior (exhaustive)
The exhaustive per-prop behavior for the three anchored comment 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; see Provable coverage.
VeltCommentPin
The pin marks an existing comment annotation’s anchor point and opens its dialog. In React,VeltCommentPin renders one pin for a known annotation (you pass annotationId); the auto-managed pins that VeltComments drops on click are the same underlying element driven by the host. Pin placement, drag, dialog open/close, and the index/number badge are default behaviors (global feature state), not per-instance props: see Default behaviors below.
Default behaviors (no prop needed)
- Pin placement (anchored): the pin is positioned by the host at the annotation’s resolved anchor: where the user clicked, or on the target element. The pin element itself takes no
x/y/positioninput. Default pin marker size is 40px (34px when the comment was added on a different device type and the device indicator is on). - Click opens the dialog: pointer-up on the pin toggles selection. If the pin is not selected, the click selects it and opens its anchored dialog; if already selected, it toggles closed. This is
togglePinSelection, emitted on pointer-up. (Pointer-up on the dialog itself also selects the pin if it wasn’t already, so interacting with the dialog keeps it open.) - Drag to reposition: pins are draggable by default (
pinDragdefaultstruein global feature state). Dragging sets anannotationDraggingstate and, on drop, re-anchors the annotation. There is no per-pin prop to disable drag onVeltCommentPin; it is governed by the global comment feature config. - Hover / bubble-on-pin:
bubbleOnPinandbubbleOnPinHover(global feature state, both defaultfalse) control whether a preview bubble shows on the pin permanently or on hover. Off by default: the bare pin shows the avatar marker only. - Index / number badge:
showCommentIndex(global, defaultfalse) toggles a numeric index badge on pins (thecomment-pin-number/comment-pin-indexprimitives). Off by default, so pins show the author avatar, not a number. Unread, private, ghost, and agent-comment states each swap in their own marker primitive (agent comments render a distinct blue lego-bot marker instead of an avatar). - Shadow DOM: the pin’s own shadow-DOM isolation comes from global
pinShadowDOM(defaultfalse), not from a per-pin prop:VeltCommentPinexposes noshadowDomprop. (Confirmed: the pin marker defaultspinShadowDOM: false, while the pin dialog defaultsdialogShadowDom: true: the two surfaces isolate independently; seeBehaviors.)
VeltCommentBubble
The bubble is a chip that attaches to a target element (or an annotation) and, on click, opens that annotation’s comment dialog. It is the “comment count on a row/card” surface. Unlike the pin, the bubble fetches its own annotation from the scope you give it (targetElementId / annotationId / context+scope).
Default behaviors (no prop needed)
- Anchored placement: the bubble attaches to its
targetElementIdand is positioned by Velt relative to that element; you don’t pass coordinates. - Click → dialog (default on): with default
openDialog={true}, clicking the bubble selects the annotation and opens its dialog, resetting any other selected annotation first and scrolling drafts into view. Clicking again toggles it closed. - Click event always fires: the
commentBubbleClickevent is emitted on every click regardless ofopenDialog, so evenopenDialog={false}bubbles are usable as click targets. - Count + avatar shown: by default the bubble shows the author avatar and the total comment count, plus an unread indicator when there are unread comments.
- Shadow-DOM wrapped: default
shadowDom={true}isolates styles; if you register a full bubble wireframe and don’t pass shadow DOM, the root still resolves its own wireframe so it doesn’t auto-wrap unexpectedly.
VeltCommentTool
The tool is the button that starts a new comment. Clicking it either enters “click anywhere to place a pin” add-comment mode, attaches a comment directly to a target element (popover mode), or opens the sidebar’s page-mode composer: depending on configuration. It carries no avatar/count; its job is to begin the flow.Default behaviors (no prop needed)
- Default button when no custom slot: if you don’t fill the tool’s button slot, Velt renders its default comment-tool button. Provide your own element in the slot to replace it (the tool detects an empty slot and shows the default only then).
- Click → add-comment mode (default): with no
targetElementId/popover config, clicking the tool enables add-comment mode: the next click on the page drops a pin. Clicking the tool again while in add-comment mode disables it (toggle). The host adds acomment-tool-activeclass while mode is on. - Direct attach in popover mode: when popover mode is on and a
targetElementId/context/scope is provided, the click attaches the comment straight to that element (carryingsourceIdand folder/document/location metadata) rather than entering placement mode. - Auto-hide when the target already has a comment: in popover mode, the tool subscribes to annotation availability for its target; if a (visible, unresolved unless resolved-on-DOM is on) comment already exists there,
commentAnnotationAvailablebecomes true and the tool hides, so you don’t stack a second tool over an existing comment. - Permission & auth gates: the click is a no-op (with a console note) for anonymous/read-only users, when the SDK isn’t authenticated, when the plan is expired, or when the user lacks an ADMIN/COMMENTER role. These gates are in addition to the
disabledprop and the global tool-enabled flag. - Analytics: every tool click emits a
COMMENT_TOOL_CLICKEDanalytics event taggedcustomordefaultdepending on whether a custom button slot was supplied.
Default behaviors (no prop needed)
Each component’s zero-prop baseline is documented in its### Default behaviors (no prop needed) block above. In brief:
- Pin: placed by the host at the annotation’s resolved anchor (no
x/yinput), opens its dialog on click, draggable by default (pinDragglobal,true), shows the author avatar (no index/bubble unless the global flags are on), isolates via globalpinShadowDOM(defaultfalse). - Bubble: anchors to its
targetElementId, opens the dialog on click (defaultopenDialog={true}) while always emittingcommentBubbleClick, shows the avatar + total count, shadow-DOM wrapped. - Tool: renders Velt’s default button (unless you fill its slot), enters add-comment mode on click (or direct-attaches in popover mode), auto-hides when its target already has a comment, gated by auth/permission checks plus the global tool-enabled flag.
Prop-interaction matrix
No separate multi-prop matrix for this group: pairwise effects live in each prop’s Interactions & gotchas column above. The recurring cross-prop notes: the scoping set (context + contextOptions + locationId + documentId + folderId) resolves together, and locationId only narrows when a folderId/documentId is also present; the deprecated aliases (showAvatar→avatar, targetCommentElementId→targetElementId) write the same flag as their replacement (last setter wins); disabled on the tool AND-combines with the global tool-enabled state; and contextInPageModeComposer forces the tool’s own context/contextOptions to undefined for its availability subscription. Pin/bubble/dialog shadow-DOM isolation is covered in the behaviors index.
Positioning & composition
All three surfaces are anchored / Velt-positioned: the pin drops where the user clicked (or on its target element), the bubble attaches to itstargetElementId, and the tool/its resulting pin are placed by Velt’s comment host: none take a coordinate input. You keep this anchoring for free while you stay in wireframes; dropping to primitives or headless means you take over positioning. See Behaviors → Positioning ownership and the anchored-vs-static classification in Component definitions.
Provable coverage
Counted againstProps ### VeltCommentBubble / ### VeltCommentPin / ### VeltCommentTool:
- VeltCommentBubble: 18/18: targetCommentElementId, targetElementId, showAvatar, avatar, commentBubbleTargetPinHover, shadowDom, variant, darkMode, readOnly, commentCountType, context, contextOptions, locationId, documentId, folderId, annotationId, openDialog: plus the two deprecated aliases counted inline (showAvatar→avatar, targetCommentElementId→targetElementId). Every row in the props.md table is covered.
- VeltCommentPin: 9/9: annotationId, multiThreadAnnotationId, variant, context, contextOptions, locationId, documentId, folderId, defaultCondition. (props.md lists 9 rows; “~10” estimate included.)
- VeltCommentTool: 14/14: targetCommentElementId, targetElementId, onCommentModeChange, sourceId, darkMode, disabled, variant, shadowDom, context, contextOptions, locationId, documentId, folderId, contextInPageModeComposer. Every row covered.
shadowDom flag for VeltCommentPin (the pin exposes no shadowDom prop; isolation is global pinShadowDOM, default false).
