Vanilla Breeze

review-surface

Pin-based annotation overlay for collaborative design review — wraps any content and adds interactive comment pins with pluggable persistence.

Overview

A web component that wraps any HTML content and adds a transparent overlay for placing review comment pins. Click anywhere in annotate mode to drop a numbered pin, then add a comment and replies. Supports pluggable persistence via memory, localStorage, or REST adapters. Designed for design reviews, sprint demos, and stakeholder presentations.

Attributes

Attribute Type Default Description
src string (URL) Path to a JSON file containing pin data
editable boolean Enables the annotate toolbar, pin creation, and reply input
adapter string "memory" Persistence backend: memory, local, or rest
endpoint string (URL) REST endpoint URL (required when adapter="rest")
storage-key string "review-surface" localStorage key (when adapter="local")
author string "Anonymous" Default author name for new pins and replies
compact boolean Reduces pin size, popover width, and toolbar spacing
show-resolved boolean Display resolved pins (hidden by default)
pin-count number 0 Reflected count of visible pins (read-only)

Annotate Mode

Add the editable attribute to show the review toolbar. Click the Annotate button to enter annotate mode — the cursor changes to a crosshair and clicking the content area places a new pin. The pin's popover opens immediately so you can type your comment.

Press Escape to exit annotate mode or close an open popover. Pins are always clickable in both view and annotate modes.

Data Mode

Load pin data from a JSON file via the src attribute, or set the .pins property programmatically.

Adapters

Adapters control how pins are persisted. Three built-in adapters are available, or provide a custom one via the .adapter property.

Adapter Persistence Use Case
memory Ephemeral (lost on page refresh) Demos, throwaway reviews
local Browser localStorage Solo dev review, prototyping
rest Server via REST API Team collaboration, persistent reviews

The REST adapter expects standard REST endpoints: GET / to list, POST / to create, PATCH /:id to update, and DELETE /:id to remove.

Events

Event Detail When
review-surface:ready { pinCount } After the component finishes rendering
review-surface:add { pin } A pin is created (via click or addPin())
review-surface:update { pin, changes } A pin is modified (reply added, text changed, un-resolved)
review-surface:remove { pin } A pin is deleted
review-surface:resolve { pin } A pin is marked as resolved
review-surface:select { pin } A pin's popover is opened
review-surface:mode { mode } View/annotate mode is toggled ("view" or "annotate")

CSS Custom Properties

Variable Default Description
--review-surface-bg #ffffff Popover and input background
--review-surface-card #f8f9fa Toolbar and input area background
--review-surface-text #1a1a1a Primary text color
--review-surface-muted #666666 Secondary text (timestamps, pin count)
--review-surface-border #e0e0e0 Popover, toolbar, and input borders
--review-surface-accent #0066cc Focus rings, submit button, annotate mode toggle
--review-surface-pin-bg #0066cc Pin marker background color
--review-surface-pin-text #ffffff Pin marker text/number color
--review-surface-pin-size 28px Pin marker diameter
--review-surface-resolved #16a34a Resolved pin and badge color

Accessibility

  • Pin markers are <button> elements with aria-label, aria-expanded, and aria-haspopup="dialog"
  • Comment popovers use role="dialog" with aria-labelledby
  • Toolbar uses role="toolbar" with aria-label
  • Annotate toggle uses aria-pressed to communicate state
  • An aria-live="polite" region announces pin creation, deletion, and resolution
  • Keyboard: Tab navigates pins, Enter/Space opens popover, Escape closes popover or exits annotate mode
  • All transitions respect prefers-reduced-motion: reduce
  • Print styles hide pins, overlay, and toolbar — only the wrapped content prints

Related