Props tells you a prop’s name, type, and default. This page tells you what it actually does: how Velt behaves with no props at all, which props fight each other, and what you take over when you leave wireframes.
Generated from the Velt SDK. A name that isn’t listed here doesn’t exist: don’t guess.
Per-component behavior: every prop (exhaustive)
Every prop’s runtime effect, per component. These pages are source-derived, so they win on any conflict with other docs.
Events are in
Events; data fields in Data models.
Default behaviors (no prop needed)
What Velt does out of the box. These are the baseline a prop modifies.Prop-interaction matrix
collapsedComments × collapsedRepliesPreview
The most misunderstood pair. Which comment cards render depends on three things: whether the dialog is selected, showAllComments (default true), and collapsedRepliesPreview.
sortBy × sortOrder
sortBy picks the field ('createdAt' | 'lastUpdated'), sortOrder the direction ('asc' | 'desc'). They apply together to the comment list in the dialog and inline section. With neither set, comments render in creation order. They only reorder; they don’t hide cards.
On the inline section, the older sortData is deprecated: pass sortBy + sortOrder instead.
visibilityOptions (requires isPrivateCommentsEnabled)
visibilityOptions (default false) shows the per-comment visibility picker. It’s gated: the banner renders only when the SDK’s private-comments capability is also on. Turning it on without that shows nothing. privateCommentMode makes comments private by default.
shadowDom vs dialogShadowDom
shadowDom is the master wrap for VeltComments. The per-surface flags (dialogShadowDom, pinShadowDom, textCommentToolShadowDom, …) default true and isolate each surface independently.
To style a surface with your own CSS, turn off the shadow DOM that wraps it: dialogShadowDom={false} reaches dialog internals, pinShadowDom={false} reaches the pin. Master shadowDom={false} drops isolation everywhere. A per-surface true keeps that surface isolated even when others are off. See CSS classes for what becomes selectable.
defaultMinimalFilter (overridden by saved state)
Sets the sidebar’s initial quick-filter ('all' | 'unread' | 'resolved' | 'open' | 'assignedToMe' | …). Saved session state wins, so this is a first-run default, not a forced value. To force a filter on every open, set it programmatically with setCommentSidebarFilters (Layout config).
embedMode / pageMode (sidebar)
embedModerenders the sidebar inline in your layout instead of docked. The type differs by version:booleanon V1,stringon V2. It makespositionandfloatingModemoot, since you own placement.pageModeswitches to page-level comments: no pins on the DOM, and the composer lives at the sidebar level (pageModePlaceholder,pageModeComposerVariant). Mutually exclusive with pin-based commenting.
fullExpanded vs default
fullExpanded (default false) forces threads fully expanded, with message text untruncated. It’s the opposite of collapsedComments: don’t set both. messageTruncation (+ messageTruncationLines, default 4) is a separate axis that truncates long single messages, independent of how many cards show.
commentPlaceholder vs replyPlaceholder priority
The composer’s placeholder resolves in this order:
- Generic
placeholderoverrides everything. - Otherwise the thread’s comment count decides: no comments →
commentPlaceholder, has comments →replyPlaceholder. - Otherwise a built-in default that varies with
userMentions.
editPlaceholder → editCommentPlaceholder / editReplyPlaceholder, again with generic placeholder on top.
Dialog state machine
Selection state and composer state are tracked per dialog instance, so the sidebar list, a focused thread, and a floating pin dialog for the same annotation don’t leak state into each other. Dialog selection:- unselected → selected: clicking the pin, or via
dialogOnHover/dialogOnTargetElementClick. - selected → expanded: automatic when
expandOnSelectionis true. Set itfalseand selection won’t expand: the dialog stays a preview and the composer stays hidden. - any → unselected: deselect, close, or
forceCloseAllOnEsc.
- collapsed → open: focusing the composer. With
composerMode: 'expanded'it starts open and never collapses. - open → recording: a recorder config is active. Recording takes precedence over open.
- open → collapsed: on submit or clear (text, attachments, recordings, and tagged users all reset).
Variant → context scoping
The same dialog renders in several contexts, and each has its own variant prop. This is how you make the sidebar-opened dialog look different from the floating pin dialog.
Register a named wireframe variant and point only the relevant prop at it. Setting the base
variant on VeltComments changes the floating pin dialog only; the other contexts keep their defaults.
Positioning ownership (anchored surfaces)
VeltComments owns pin placement and dialog anchoring. The dialog component takes no position or coordinate prop and doesn’t place itself: it asks the host to re-anchor when its size changes (composer expands, recording starts), and the host does the placement. targetElementId names an anchor element, not a coordinate.
What each approach forfeits:
Which surfaces Velt positions:

