Skip to main content
Before you reach for wireframes or CSS, check whether a prop already gives you the layout/mode you want. Velt components expose many layout/variant props: flipping one is the cheapest customization of all. These are real props on the React components.
Use these with primitives (and they apply to the same components in any framework as kebab-case attributes). For trimming features on/off (reactions, status, …) see Primitives.

The most layout-rich component. Key props (present on both unless noted):
PropValuesWhat it does
filterPanelLayout'menu' · 'bottomSheet'Filter UI as a dropdown panel vs a mobile bottom-sheet
filterOptionLayout'checkbox' · 'dropdown'Filter options as checkboxes vs a dropdown
position'right' · 'left'Which side the sidebar docks
embedModeV1: boolean · V2: stringEmbed the sidebar inline in your layout (note the type differs by version)
floatingModebooleanFloating overlay vs docked
pageModebooleanPage-mode (anchored to page elements)
focusedThreadModebooleanEnable focused single-thread view
fullScreen / fullExpandedbooleanFullscreen / fully-expanded layout
variantstringSelects which wireframe variant renders (register variants with variant="…" on the Velt…Wireframe; see wireframe variants)
dialogVariant / focusedThreadDialogVariant / pageModeComposerVariantstringWireframe variant the embedded dialog uses in each context (sidebar / focused thread / page composer)
sidebarButtonCountType'default' · 'filter'What the sidebar button counts
sortData'asc' · 'desc' · 'none'Default sort
systemFiltersOperator / filterOperator (V2)'and' · 'or' (V1 caps)How multiple filters combine
filterCountbooleanShow counts on filters
defaultMinimalFilter (V2)'all'·'read'·'unread'·'resolved'·'open'·'assignedToMe'·'reset'·nullInitial minimal filter
darkMode / shadowDombooleanTheme / shadow-DOM
The sidebar has three filter surfaces: the minimal filter (the quick all/unread/resolved bar), the main filter panel (the full dropdown of categories), and custom filters you define. All are customizable. 1. Choose which filters appear + add your own: the filters prop (a CommentSidebarFilterConfig). It’s a map of filter keys → a FilterTypeConfig:
type FilterTypeConfig = {
  name?: string;            // label shown in the panel
  enable?: boolean;         // show/hide this filter
  multiSelection?: boolean; // allow multiple values
  enableGrouping?: boolean; // group the sidebar list by this filter
  order?: string[];         // option order
  placeholder?: string;
  id?: string;
  type?: 'system' | 'custom';   // 'custom' = your own filter
  options?: { id: string; name: string }[];   // the selectable values
};
Built-in keys: location, document, people, assigned, tagged, involved, priority, status, category, commentType, version. Toggle/relabel/reorder them, and add a custom filter by adding your own key with type: 'custom' + options:
<VeltCommentsSidebarV2
  shadowDom={false}
  filters={{
    status:   { enable: true,  name: "Status", multiSelection: true },
    priority: { enable: false },                         // hide a built-in filter
    severity: {                                          // ← your custom filter
      type: "custom", name: "Severity", multiSelection: true,
      options: [
        { id: "sev1", name: "Sev 1" },
        { id: "sev2", name: "Sev 2" },
      ],
    },
  }}
/>
(miniFilters / minimalFilters configure the quick-bar the same way; groupConfig controls list grouping.) A custom filter matches annotations by the option id you set on them (via customListDataOnAnnotation / annotation metadata). Set filter values programmatically with client.getCommentElement().setCommentSidebarFilters({ status: ["OPEN"], severity: ["sev1"] }). 2. Choose the filter layout (props above): filterPanelLayout ('menu' panel vs 'bottomSheet'), filterOptionLayout ('checkbox' vs 'dropdown'), filterOperator ('and'/'or'), filterCount, defaultMinimalFilter. 3. Fully restyle the filter UI with wireframe slots (Wireframe components). The V2 sidebar exposes: FilterButton (+ AppliedIcon), FilterDropdown (Trigger, Content → List → Item / Category), and FilterContainer (Title, CloseButton, GroupBy, ResetButton, ApplyButton, SectionList → Section → Label / Field → Control(Value, ChipList→Chip, Search, Chevron) / OptionList → Option(Checkbox, Name, Count)). Fill these to build a fully custom filter dropdown / panel while Velt keeps the filtering logic. In wireframes you can read {appliedFiltersCount} and {filterState} to drive your own filter UI. (See Wireframe variables.)
Same trade as everywhere: config props for which filters + layout (cheapest); wireframe slots to restructure the filter dropdown/panel; the filtering behavior stays Velt’s.

Notifications: VeltNotificationsPanel

PropValuesWhat it does
panelOpenMode'popover' · 'sidebar'Render as a popover vs a docked sidebar panel
settingsLayout'accordion' · 'dropdown'Settings UI layout
settingsbooleanShow the settings view
tabConfig{ forYou?, documents?, all?, people? } (each { name?, enable? })Show/label/reorder tabs
enableSettingsAtOrganizationLevelbooleanOrg-level settings
enableCrossOrganizationboolean | string | CrossOrganizationConfigCross-org notifications
panelVariantstringWireframe variant the embedded panel uses (on the Tool)
variant / darkMode / shadowDomNoneStyle / theme / shadow-DOM

Comment Dialog: VeltCommentDialog

PropValuesWhat it does
commentPinType'bubble' · 'pin' · 'chart' · 'text'Pin rendering style
composerPositionstringComposer placement
sidebarMode / dialogMode / inboxMode / inlineCommentMode / inlineCommentSectionMode / commentComposerMode / focusedThreadMode / multiThread / pageModeComposerbooleanRender-mode flags
messageTruncation / messageTruncationLinesboolean / numberTruncate long messages
dialogSelection / expandOnSelection / openAnnotationInFocusMode / isFocusedThreadEnabledbooleanSelection/expansion behavior
variant / fullExpanded / darkMode / shadowDomNoneStyle / layout / theme / shadow-DOM
All <VeltComments> props (the full 129-prop table with types, defaults, and descriptions) are in Props. This page focuses on the layout/mode props for the sidebar, dialog, and notifications.

Comments host: VeltComments

Mostly feature toggles (see Primitives), plus layout/mode flags: floatingCommentDialog, inboxMode, inlineCommentMode, privateCommentMode, persistentCommentMode, multiThread, composerMode ('default'|'expanded'), unreadIndicatorMode ('minimal'|'verbose'), minimap / minimapPosition, and granular shadow-DOM / dark-mode flags (pinShadowDom, dialogShadowDom, dialogDarkMode, pinDarkMode, …).

Recorder: VeltRecorderControlPanel & VeltRecorderPlayer

PropValuesWhat it does
mode'floating' · 'thread'Control-panel layout mode (RecorderLayoutMode, on VeltRecorderControlPanel)
variant'default' · 'embed'Player layout variant (RecorderVariant, on VeltRecorderPlayer)

Transcription: VeltTranscription & VeltSubtitles

PropValuesWhat it does
mode (transcription)'floating' · 'embed' · 'summaryMode'Transcription layout mode (TranscriptionMode)
mode (subtitles)'floating' · 'embed'Subtitles layout mode (SubtitlesMode)

Presence: VeltPresence

PropValuesWhat it does
flockModebooleanFlock-mode (group/follow) layout
variantstringWireframe variant the presence list renders

Cursor: VeltCursor

PropValuesWhat it does
avatarModebooleanRender cursors as user avatars vs plain pointers

Custom data: your own statuses, priorities, categories, reactions

These props let you replace Velt’s default option sets with your own. They’re a core part of customization: the values flow into the UI (status/priority dropdowns, chips), into the wireframe variables (statusOptions, priorityOptions, customStatusesShown, …), and into the primitive dropdown items (so your custom dialog dropdown shows your statuses). Pass them on VeltComments:
<VeltComments
  customStatus={[
    { id: "OPEN",  name: "Open",  color: "#625DF5", type: "default",  lightColor: "#EEF" },
    { id: "WIP",   name: "In progress", color: "#ECB000", type: "ongoing" },
    { id: "DONE",  name: "Done",  color: "#00C48C", type: "terminal" },
  ]}
  customPriority={[
    { id: "P0", name: "Urgent", color: "#FF7162", lightColor: "#FFF4F2" },
    { id: "P1", name: "Normal", color: "#625DF5" },
  ]}
  customCategory={[{ id: "bug", name: "Bug", color: "#FF7162" }]}
  customReactions={{ "👍": { label: "Thumbs up", emoji: "👍" } }}
/>
Exact shapes:
  • customStatus: { id, name, color, type: 'default' | 'ongoing' | 'terminal', lightColor?, svg?, iconUrl? }[]: type controls semantics (terminal = resolved-like).
  • customPriority: { id, name, color, lightColor? }[].
  • customCategory: { id, name, color }[].
  • customReactions: a map of emoji → { label, emoji } (a ReactionMap).
  • customListDataOnAnnotation (a CustomAnnotationDropdownData): the custom chip/dropdown on a thread (powers the CustomAnnotationDropdown slot). Shape:
    {
      type: 'single' | 'multi';               // single- vs multi-select
      placeholder?: string;                   // default 'Select'
      data: { id: string; label: string }[];  // the selectable options
    }
    
    The option id is what a custom sidebar filter matches against (see the filters example above): set the option on annotations via this prop, filter by the same id.
  • customListDataOnComment (an AutocompleteData): custom list on a comment (autocomplete-style). Shape:
    {
      hotkey: string;                          // trigger char, e.g. '#'
      description?: string;
      type: 'custom' | 'contact' | 'group';    // default 'custom'
      data: {                                  // AutocompleteItem[]
        id: string; name: string;
        description?: string;
        icon?: { url?: string; svg?: string };
        link?: string; groupId?: string;       // groupId ties an item to a group
      }[];
      groups?: { id: string; name: string }[]; // optional groups
    }
    
When you build a custom status/priority dropdown with primitives (Primitives), this is where the statuses you map over come from. When you read {statusOptions} / {priorityOptions} in a wireframe (Wireframe variables), these are the values.

Notes

  • Prop before wireframe. If a prop gets you the layout (e.g. filterPanelLayout="bottomSheet", panelOpenMode="sidebar"), use it: it’s far less work than a wireframe.
  • Version differences: embedMode is boolean on V1 sidebar but string on V2: match the type to the component version you’re using.
  • Framework-agnostic: in vanilla/other frameworks these are kebab-case attributes on the <velt-*> element (e.g. filter-panel-layout="bottomSheet").