Skip to main content
New to wireframes? Start with UI Customization Concepts and the Template Variables overview.

Overview

The Comment Bubble wireframe exposes the variables below. Use them inside any <velt-comment-bubble-...-wireframe> tag via three forms:
You want to…UseExample
Display a value as text<velt-data field="var" /><velt-data field="annotation.from.name" />
Hide / show conditionallyvelt-if="{var}"velt-if="{annotation.unread}"
Toggle a CSS classvelt-class="'cls': {var}"velt-class="'is-unread': {annotation.unread}"
All variables are mapped — reference them by their short name. You do not need the componentConfig. prefix.
Naming conflicts — use full path. A few names collide with mappings used elsewhere. Inside a Comment Bubble wireframe, prefer the explicit path on the right when reading these values:
Conflicting nameUse this in Comment Bubble
customStatusesShownglobalConfigSignal.featureState.customStatusesShown
resolvedCommentsOnDomglobalConfigSignal.featureState.resolvedCommentsOnDom
readOnlyglobalConfigSignal.featureState.readOnly (workspace) or {readOnly} (per-render local)

App State

App-wide values resolved from the shared global signal.
VariableTypeDescriptionExample
globalConfigSignal.appState.userUser | nullCurrently identified end-user.<velt-data field="globalConfigSignal.appState.user.name" />

Data State

Per-bubble data: the annotation this bubble previews, the surrounding annotation list, and unread / unresolved counts.
VariableTypeDescriptionExample
annotationCommentAnnotation | nullAnnotation this bubble represents.velt-if="{annotation}"
annotation.fromUserAuthor of the annotation’s first comment.<velt-data field="annotation.from.name" />
annotation.commentsComment[]Comments in the thread.<velt-data field="annotation.comments.length" />
annotation.status.idstringCurrent status id (e.g. "open", "resolved").velt-class="'status-{annotation.status.id}': true"
annotation.unreadbooleanAnnotation has unread comments for the current user.velt-class="'is-unread': {annotation.unread}"
annotation.iam.accessMode'public' | 'private'Visibility mode.velt-if="{annotation.iam.accessMode} === 'private'"
annotationsCommentAnnotation[]All annotations currently in scope.<velt-data field="annotations.length" />
unresolvedAnnotationsCountnumberNumber of unresolved annotations across the document.<velt-data field="unresolvedAnnotationsCount" />
unreadCountnumberUnread-comment count for this bubble’s annotation.<velt-data field="unreadCount" />
data.folderIdstringFolder id this bubble’s annotation belongs to.<velt-data field="data.folderId" />
data.contextRecord<string, any>Free-form annotation context.<velt-data field="data.context.key" />

UI State

Per-bubble UI flags driven by the bubble itself.
VariableTypeDescriptionExample
uiState.commentPinSelectedbooleanPin associated with this bubble is currently selected.velt-class="'pin-selected': {uiState.commentPinSelected}"
selectedAnnotationsMapSelectedAnnotationsMapMap keyed by annotationIdboolean; true if that annotation is selected.velt-class="'selected': {selectedAnnotationsMap[annotation.annotationId]}"
selectedAnnotationsLocationMapSelectedAnnotationsLocationMapInternal selection bookkeeping by location.Internal — read individual entries via bracket notation if needed.
darkModebooleanDark mode is active for this bubble.velt-class="'dark': {darkMode}"
variantstringPer-instance variant tag set on the host element.<velt-data field="variant" />
parentLocalUIState.shadowDombooleanShadow-DOM rendering is enabled for this instance.Host config — set via element attribute.
commentBubbleTargetPinHoverbooleanThe bubble’s anchor pin is currently hovered.velt-class="'hover': {commentBubbleTargetPinHover}"
openDialogbooleanA comment dialog is open for this bubble’s annotation.velt-if="{openDialog}"
readOnlybooleanPer-render read-only flag.velt-class="'readonly': {readOnly}"
showAvatarbooleanAvatar should be rendered.velt-if="{showAvatar}"
commentCountType'total' | 'unread'Which count drives the badge.velt-class="'count-{commentCountType}': true"

Feature State

Capability flags toggled at the workspace level. These are documented under the explicit globalConfigSignal.featureState.<name> path because the bare names collide with other mappings.
VariableTypeDescriptionExample
globalConfigSignal.featureState.customStatusesShownbooleanCustom-status decoration enabled on bubbles.velt-class="'show-status': {globalConfigSignal.featureState.customStatusesShown}"
globalConfigSignal.featureState.groupMatchedCommentsbooleanMatched comments are grouped together on the page.velt-class="'grouped': {globalConfigSignal.featureState.groupMatchedComments}"
globalConfigSignal.featureState.resolvedCommentsOnDombooleanResolved annotations still render bubbles.velt-if="{globalConfigSignal.featureState.resolvedCommentsOnDom}"
globalConfigSignal.featureState.readOnlybooleanWorkspace read-only mode is active.velt-class="'readonly': {globalConfigSignal.featureState.readOnly}"

Common Props

Every Comment Bubble primitive accepts:
React PropHTML AttributeTypeDefaultDescription
defaultConditiondefault-conditionboolean | "true" | "false"trueWhen false, the component always renders regardless of internal state.
Signal inputs (for parent-child component composition):
  • [componentConfigSignal] — shared config signal (annotation, selected-annotations map, unread count).
  • [parentLocalUIState] — per-instance UI state signal (darkMode, variant, shadowDom, readOnly, showAvatar, commentCountType).
The root <velt-comment-bubble> element additionally accepts attributes that map onto config and local UI state values: dark-mode, variant, show-avatar, comment-count-type, etc.

Type Reference

Types referenced by the variables above are documented in Data Models:
TypeDescription
CommentAnnotationThe annotation thread (id, status, comments, from, unread, iam, etc.).
CommentA single message inside an annotation thread.
UserIdentified end-user object.
CommentVisibilityOptionTypeAnnotation visibility mode ('public', 'private', 'organization', 'selected_people').

Subcomponents

Each subcomponent below has its own wireframe tag. The annotation root supports nested access — see CommentAnnotation for the full shape.

comment-bubble (root)

The bubble pin that previews an annotation when the user is not focused on it.
  • Public element: <velt-comment-bubble>
  • Wireframe tag: <velt-comment-bubble-wireframe>
  • Children: *-avatar, *-comments-count, *-unread-icon
PropertyValue
Extra variablesNone — root only sees common variables.
shouldShowOne bubble renders per non-resolved annotation on the current document. Resolved bubbles render only when globalConfigSignal.featureState.resolvedCommentsOnDom === true.
<VeltCommentBubbleWireframe
  veltClass="'unread': {annotation.unread}, 'selected': {selectedAnnotationsMap[annotation.annotationId]}">
  <div className="my-bubble">
    <VeltCommentBubbleWireframe.Avatar />
    <VeltCommentBubbleWireframe.CommentsCount />
    <VeltCommentBubbleWireframe.UnreadIcon />
  </div>
</VeltCommentBubbleWireframe>

comment-bubble-avatar

The avatar of the annotation’s author.
  • Public element: <velt-comment-bubble-avatar>
  • Wireframe tag: <velt-comment-bubble-avatar-wireframe>
PropertyValue
Extra variablesNone beyond common variables. Read annotation.from.photoUrl / annotation.from.name from the parent annotation.
<VeltCommentBubbleWireframe.Avatar>
  <img className="my-avatar" src="{annotation.from.photoUrl}" />
</VeltCommentBubbleWireframe.Avatar>

comment-bubble-comments-count

The “N” badge showing how many comments are in the thread.
  • Public element: <velt-comment-bubble-comments-count>
  • Wireframe tag: <velt-comment-bubble-comments-count-wireframe>
PropertyValue
Extra variablesNone beyond common variables.
shouldShowRenders only when the thread has more than one comment.
<VeltCommentBubbleWireframe.CommentsCount>
  <VeltIf condition="{annotation.comments.length} > 1">
    <span>
      <VeltData field="annotation.comments.length" />
    </span>
  </VeltIf>
</VeltCommentBubbleWireframe.CommentsCount>

comment-bubble-unread-icon

The unread-indicator dot on the bubble.
  • Public element: <velt-comment-bubble-unread-icon>
  • Wireframe tag: <velt-comment-bubble-unread-icon-wireframe>
PropertyValue
Extra variablesNone beyond common variables.
shouldShowunreadCount > 0 (or annotation.unread === true, depending on commentCountType).

Deeply-Nested Wireframe Tags

A separate-but-related set of primitives renders the comment pin (the small marker on the page) — distinct from the bubble (which previews the comment). Each tag below has its own <velt-comment-pin-...-wireframe> registration and reads from the same annotation context.

Comment Pin tags

TagNotesExample
<velt-comment-pin-wireframe>Root pin element.velt-class="'pin-status-{annotation.status.id}': true"
<velt-comment-pin-triangle-wireframe>The pointing-arrow triangle below the pin.Visual only — no data binding.
<velt-comment-pin-index-wireframe>Pin index number (e.g. “3” — order it was placed).<velt-data field="annotation.annotationIndex" />
<velt-comment-pin-number-wireframe>Auto-generated annotation number.<velt-data field="annotation.annotationNumber" />
<velt-comment-pin-unread-comment-indicator-wireframe>Unread dot indicator on the pin.velt-if="{annotation.unread}"
<velt-comment-pin-private-comment-indicator-wireframe>Private-mode lock icon on the pin.velt-if="{annotation.iam.accessMode} === 'private'"
<velt-comment-pin-ghost-comment-indicator-wireframe>Indicator shown when the pin has lost its DOM target (ghost-comment state).velt-if="{annotation.ghostComment}"