> ## Documentation Index
> Fetch the complete documentation index at: https://velt.dev/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Comment Bubble Wireframe Variables

> Template variables exposed by the Comment Bubble wireframe — read them with velt-data, velt-if, and velt-class to drive dynamic content, conditional rendering, and class toggling.

<Note>
  New to wireframes? Start with [UI Customization Concepts](/ui-customization/overview) and the [Template Variables](/ui-customization/template-variables) overview.
</Note>

## Overview

The **Comment Bubble** wireframe exposes the variables below. Use them inside any `<velt-comment-bubble-...-wireframe>` tag via three forms:

| You want to…              | Use                         | Example                                         |
| ------------------------- | --------------------------- | ----------------------------------------------- |
| Display a value as text   | `<velt-data field="var" />` | `<velt-data field="annotation.from.name" />`    |
| Hide / show conditionally | `velt-if="{var}"`           | `velt-if="{annotation.unread}"`                 |
| Toggle a CSS class        | `velt-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.

<Note>
  **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 name        | Use this in Comment Bubble                                                                |
  | ----------------------- | ----------------------------------------------------------------------------------------- |
  | `customStatusesShown`   | `globalConfigSignal.featureState.customStatusesShown`                                     |
  | `resolvedCommentsOnDom` | `globalConfigSignal.featureState.resolvedCommentsOnDom`                                   |
  | `readOnly`              | `globalConfigSignal.featureState.readOnly` (workspace) or `{readOnly}` (per-render local) |
</Note>

## App State

App-wide values resolved from the shared global signal.

| Variable                           | Type                                                           | Description                    | Example                                                       |
| ---------------------------------- | -------------------------------------------------------------- | ------------------------------ | ------------------------------------------------------------- |
| `globalConfigSignal.appState.user` | [`User`](/api-reference/sdk/models/data-models#user) \| `null` | Currently 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.

| Variable                     | Type                                                                                     | Description                                           | Example                                               |
| ---------------------------- | ---------------------------------------------------------------------------------------- | ----------------------------------------------------- | ----------------------------------------------------- |
| `annotation`                 | [`CommentAnnotation`](/api-reference/sdk/models/data-models#commentannotation) \| `null` | Annotation this bubble represents.                    | `velt-if="{annotation}"`                              |
| `annotation.from`            | [`User`](/api-reference/sdk/models/data-models#user)                                     | Author of the annotation's first comment.             | `<velt-data field="annotation.from.name" />`          |
| `annotation.comments`        | [`Comment`](/api-reference/sdk/models/data-models#comment)`[]`                           | Comments in the thread.                               | `<velt-data field="annotation.comments.length" />`    |
| `annotation.status.id`       | `string`                                                                                 | Current status id (e.g. `"open"`, `"resolved"`).      | `velt-class="'status-{annotation.status.id}': true"`  |
| `annotation.unread`          | `boolean`                                                                                | Annotation 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'"` |
| `annotations`                | [`CommentAnnotation`](/api-reference/sdk/models/data-models#commentannotation)`[]`       | All annotations currently in scope.                   | `<velt-data field="annotations.length" />`            |
| `unresolvedAnnotationsCount` | `number`                                                                                 | Number of unresolved annotations across the document. | `<velt-data field="unresolvedAnnotationsCount" />`    |
| `unreadCount`                | `number`                                                                                 | Unread-comment count for this bubble's annotation.    | `<velt-data field="unreadCount" />`                   |
| `data.folderId`              | `string`                                                                                 | Folder id this bubble's annotation belongs to.        | `<velt-data field="data.folderId" />`                 |
| `data.context`               | `Record<string, any>`                                                                    | Free-form annotation context.                         | `<velt-data field="data.context.key" />`              |

## UI State

Per-bubble UI flags driven by the bubble itself.

| Variable                         | Type                             | Description                                                                     | Example                                                                      |
| -------------------------------- | -------------------------------- | ------------------------------------------------------------------------------- | ---------------------------------------------------------------------------- |
| `uiState.commentPinSelected`     | `boolean`                        | Pin associated with this bubble is currently selected.                          | `velt-class="'pin-selected': {uiState.commentPinSelected}"`                  |
| `selectedAnnotationsMap`         | `SelectedAnnotationsMap`         | Map keyed by `annotationId` → `boolean`; `true` if that annotation is selected. | `velt-class="'selected': {selectedAnnotationsMap[annotation.annotationId]}"` |
| `selectedAnnotationsLocationMap` | `SelectedAnnotationsLocationMap` | Internal selection bookkeeping by location.                                     | *Internal — read individual entries via bracket notation if needed.*         |
| `darkMode`                       | `boolean`                        | Dark mode is active for this bubble.                                            | `velt-class="'dark': {darkMode}"`                                            |
| `variant`                        | `string`                         | Per-instance variant tag set on the host element.                               | `<velt-data field="variant" />`                                              |
| `parentLocalUIState.shadowDom`   | `boolean`                        | Shadow-DOM rendering is enabled for this instance.                              | *Host config — set via element attribute.*                                   |
| `commentBubbleTargetPinHover`    | `boolean`                        | The bubble's anchor pin is currently hovered.                                   | `velt-class="'hover': {commentBubbleTargetPinHover}"`                        |
| `openDialog`                     | `boolean`                        | A comment dialog is open for this bubble's annotation.                          | `velt-if="{openDialog}"`                                                     |
| `readOnly`                       | `boolean`                        | Per-render read-only flag.                                                      | `velt-class="'readonly': {readOnly}"`                                        |
| `showAvatar`                     | `boolean`                        | Avatar 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.

| Variable                                                | Type      | Description                                        | Example                                                                             |
| ------------------------------------------------------- | --------- | -------------------------------------------------- | ----------------------------------------------------------------------------------- |
| `globalConfigSignal.featureState.customStatusesShown`   | `boolean` | Custom-status decoration enabled on bubbles.       | `velt-class="'show-status': {globalConfigSignal.featureState.customStatusesShown}"` |
| `globalConfigSignal.featureState.groupMatchedComments`  | `boolean` | Matched comments are grouped together on the page. | `velt-class="'grouped': {globalConfigSignal.featureState.groupMatchedComments}"`    |
| `globalConfigSignal.featureState.resolvedCommentsOnDom` | `boolean` | Resolved annotations still render bubbles.         | `velt-if="{globalConfigSignal.featureState.resolvedCommentsOnDom}"`                 |
| `globalConfigSignal.featureState.readOnly`              | `boolean` | Workspace read-only mode is active.                | `velt-class="'readonly': {globalConfigSignal.featureState.readOnly}"`               |

## Common Props

Every Comment Bubble primitive accepts:

| React Prop         | HTML Attribute      | Type                           | Default | Description                                                              |
| ------------------ | ------------------- | ------------------------------ | ------- | ------------------------------------------------------------------------ |
| `defaultCondition` | `default-condition` | `boolean \| "true" \| "false"` | `true`  | When `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](/api-reference/sdk/models/data-models):

| Type                                                                                               | Description                                                                                  |
| -------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------- |
| [`CommentAnnotation`](/api-reference/sdk/models/data-models#commentannotation)                     | The annotation thread (id, status, comments, from, unread, iam, etc.).                       |
| [`Comment`](/api-reference/sdk/models/data-models#comment)                                         | A single message inside an annotation thread.                                                |
| [`User`](/api-reference/sdk/models/data-models#user)                                               | Identified end-user object.                                                                  |
| [`CommentVisibilityOptionType`](/api-reference/sdk/models/data-models#commentvisibilityoptiontype) | Annotation visibility mode (`'public'`, `'private'`, `'organization'`, `'selected_people'`). |

## Subcomponents

Each subcomponent below has its own wireframe tag. The annotation root supports nested access — see [`CommentAnnotation`](/api-reference/sdk/models/data-models#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`

| Property        | Value                                                                                                                                                                       |
| --------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Extra variables | None — root only sees common variables.                                                                                                                                     |
| `shouldShow`    | One bubble renders per non-resolved annotation on the current document. Resolved bubbles render only when `globalConfigSignal.featureState.resolvedCommentsOnDom === true`. |

<Tabs>
  <Tab title="React / Next.js">
    ```jsx theme={null}
    <VeltCommentBubbleWireframe
      veltClass="'unread': {annotation.unread}, 'selected': {selectedAnnotationsMap[annotation.annotationId]}">
      <div className="my-bubble">
        <VeltCommentBubbleWireframe.Avatar />
        <VeltCommentBubbleWireframe.CommentsCount />
        <VeltCommentBubbleWireframe.UnreadIcon />
      </div>
    </VeltCommentBubbleWireframe>
    ```
  </Tab>

  <Tab title="Other Frameworks">
    ```html theme={null}
    <velt-comment-bubble-wireframe
      velt-class="'unread': {annotation.unread}, 'selected': {selectedAnnotationsMap[annotation.annotationId]}">
      <div class="my-bubble">
        <velt-comment-bubble-avatar-wireframe></velt-comment-bubble-avatar-wireframe>
        <velt-comment-bubble-comments-count-wireframe></velt-comment-bubble-comments-count-wireframe>
        <velt-comment-bubble-unread-icon-wireframe></velt-comment-bubble-unread-icon-wireframe>
      </div>
    </velt-comment-bubble-wireframe>
    ```
  </Tab>
</Tabs>

***

### `comment-bubble-avatar`

The avatar of the annotation's author.

* **Public element:** `<velt-comment-bubble-avatar>`
* **Wireframe tag:** `<velt-comment-bubble-avatar-wireframe>`

| Property        | Value                                                                                                              |
| --------------- | ------------------------------------------------------------------------------------------------------------------ |
| Extra variables | None beyond common variables. Read `annotation.from.photoUrl` / `annotation.from.name` from the parent annotation. |

<Tabs>
  <Tab title="React / Next.js">
    ```jsx theme={null}
    <VeltCommentBubbleWireframe.Avatar>
      <img className="my-avatar" src="{annotation.from.photoUrl}" />
    </VeltCommentBubbleWireframe.Avatar>
    ```
  </Tab>

  <Tab title="Other Frameworks">
    ```html theme={null}
    <velt-comment-bubble-avatar-wireframe>
      <img class="my-avatar" [src]="annotation.from.photoUrl" />
    </velt-comment-bubble-avatar-wireframe>
    ```
  </Tab>
</Tabs>

***

### `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>`

| Property        | Value                                                   |
| --------------- | ------------------------------------------------------- |
| Extra variables | None beyond common variables.                           |
| `shouldShow`    | Renders only when the thread has more than one comment. |

<Tabs>
  <Tab title="React / Next.js">
    ```jsx theme={null}
    <VeltCommentBubbleWireframe.CommentsCount>
      <VeltIf condition="{annotation.comments.length} > 1">
        <span>
          <VeltData field="annotation.comments.length" />
        </span>
      </VeltIf>
    </VeltCommentBubbleWireframe.CommentsCount>
    ```
  </Tab>

  <Tab title="Other Frameworks">
    ```html theme={null}
    <velt-comment-bubble-comments-count-wireframe>
      <span velt-if="{annotation.comments.length} > 1">
        <velt-data field="annotation.comments.length"></velt-data>
      </span>
    </velt-comment-bubble-comments-count-wireframe>
    ```
  </Tab>
</Tabs>

***

### `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>`

| Property        | Value                                                                                 |
| --------------- | ------------------------------------------------------------------------------------- |
| Extra variables | None beyond common variables.                                                         |
| `shouldShow`    | `unreadCount > 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

| Tag                                                      | Notes                                                                       | Example                                                  |
| -------------------------------------------------------- | --------------------------------------------------------------------------- | -------------------------------------------------------- |
| `<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}"`                    |

## Related

* [Comment Bubble Wireframes](./wireframes) — composition reference for the wireframe tags themselves.
* [Comment Bubble Primitives](./primitives) — granular components if you don't need a full wireframe.
* [Template Variables](/ui-customization/template-variables) — overview of the `velt-data` / `velt-if` / `velt-class` system.
