Skip to content

Latest commit

 

History

History
598 lines (511 loc) · 28.4 KB

api-reference.md

File metadata and controls

598 lines (511 loc) · 28.4 KB

API Reference

This reference lists the public package subpaths and the primary exports a consumer should reach for first. See README.md for narrative examples, docs/context-quickstart.md for choosing a host context, and docs/integration-recipes.md for longer recipes.

@ponchia/annotations

Small pin and direct-label targets (experimental)

layoutAnnotationPins(items, options) accepts AnnotationPinInput values with an ID, centre point, measured width/height and optional priority. All geometry uses one host-selected coordinate space. AnnotationPinLayoutOptions supplies bounds, protected obstacles, clearance, a capacity limit and optional bounded displacement. AnnotationPinLayout accounts for every input in placements or omitted (bounds, collision, limit). Each AnnotationPinPlacement retains its original anchor. A displaced placement supplies a leader that the host must draw; default zero displacement never invents a new precise target location.

Priority decides admission, while output preserves authored DOM order. Pass the selected target a higher priority. An impossible scene reports omitted targets; the host must expose them through a reader/list. This is a bounded deterministic search, not optimal packing, clustering, visibility detection or a thread store. Keep sizes in screen pixels for fixed-size controls on a zoomed surface; project anchors to that same space before calling. See pin placement.

The root import is DOM-free and has no required React, Vega, Mermaid, D2, React Flow, or @ponchia/ui dependency.

import {
  annotationClassName,
  applyAnnotationEdits,
  assertAnchorAlignmentReport,
  assertAnchorAlignmentReportIfRequested,
  assertAnchorValidationReport,
  assertAnchorValidationReportIfRequested,
  assertAnnotationLayoutQuality,
  evaluateAnchorAlignment,
  evaluateAnnotationLayout,
  formatAnchorAlignmentReport,
  formatLayoutQualityReport,
  generatedSurfaceLayoutDefaults,
  pointCallout,
  renderAnnotationsSvg,
  resolveAnnotationLayout,
  resolvePreparedAnnotationLayout,
  type AnchorAlignmentTarget,
  type Annotation,
  type AnnotationVariant,
  type PreparedAnnotationLayoutOptions,
  type PreparedAnnotationLayoutResult
} from '@ponchia/annotations';

Normal ResolvedLayout objects contain chosen placements, with no ResolvedPlacement.candidates. Use LayoutOptions.diagnostics: { candidates: 8 } or { candidates: 'all' } to request LayoutDiagnostics. Its annotations: AnnotationPlacementDiagnostics[] entries contain IDs and ranked candidates. This does not change the configured refinement search or winners. Low-level allPlacementCandidates(input, { limit: 8 }) has a separate result limit. The old placement.maxCandidates option is rejected.

Annotation IDs must be unique, and equal-priority ID ordering is locale-independent. LayoutQualityReport distinguishes geometryValid, hostContentClear, and ok; a note obscuring a declared obstacle causes ok to fail even when note geometry itself is valid.

The 0.9 source adds optional numericDiagnostics to quality reports when a computed report number is nonfinite. Each entry records a stable field path and the string value "Infinity", "-Infinity", or "NaN"; finite reports omit this property. Preserve these entries when saving a report: native JSON writes nonfinite numeric fields as null, and the diagnostics retain their meaning. They do not change geometry validity, scores or assertion severity, and they do not restore a parsed JSON object into a typed report. See numerical range and saved reports.

const quality = evaluateAnnotationLayout(layout, { readability: true });
const savedEvidence = JSON.stringify(quality); // Keep numericDiagnostics with it.
for (const diagnostic of quality.numericDiagnostics ?? []) {
  console.warn(`${diagnostic.path}: ${diagnostic.value}`);
}

Resolved layouts retain arbitrary source metadata and therefore are not guaranteed JSON-serializable or structured-cloneable. See the 0.7 migration guide.

Primary groups:

  • Models: Point, Box, Anchor, Annotation, AnnotationNote, AnnotationMetadata, AnnotationVariant, AnnotationTone, AnnotationMotion, PlacementPreference, ManualPlacement, ResolvedLayout, ResolvedAnnotation, PlacementCandidate, AnnotationSubjectGeometry, AnnotationConnectorOptions, GeneratedSurfaceLayoutDefaults, GeneratedSurfaceLayoutDefaultsOptions.
  • Layout: resolveAnnotationLayout, estimateNoteSize, allPlacementCandidates, scorePlacementCandidate, evaluateAnnotationLayout, assertAnnotationLayoutQuality, formatLayoutQualityReport, formatLayoutQualityIssue, resolvePreparedAnnotationLayout, generatedSurfaceLayoutDefaults, PreparedAnnotationLayoutOptions, PreparedAnnotationLayoutResult. resolvePreparedAnnotationLayout can also take targetAlignmentTargets, targetAlignmentOptions, targetAlignmentFormat, and assertTargetAlignment so generated chart and diagram integrations prove the prepared anchor still matches the generated mark, node, handle, edge, or route in the same call as validation and layout quality. Note-size overrides in LayoutOptions.noteSizes are keyed by opaque annotation IDs: only an own property of the supplied dictionary counts. Inherited properties are ignored even for IDs such as constructor or __proto__; use Object.fromEntries or a null-prototype object if you need to provide an explicit size for one of those IDs.
  • Geometry: anchorPoint, anchorSubject, boxCenter, boxFromPoints, boxUnion, expandBox, insetBox, overlapArea, resolvePadding.
  • Connectors: connectorPath, connectorPathD, nearestPointOnBox, polylinePathD.
  • SVG helpers: annotationParts, annotationTransform, notePlacement, noteTransform, circleSubjectPath, rectSubjectPath, thresholdPath, axisThresholdPath, bracketSubjectPath, bandSubjectPath, slopeSubjectPath, comparisonBracePath, outlierClusterPath, encircleSubjectPath, timelineEventPath, evidenceMarkerPath, connectorLine, connectorElbow, connectorCurve, connectorEndDot, connectorEndArrow, declutterLabels, directLabels, subjectPath.
  • Rendering: renderAnnotationsSvg, renderAnnotationSubjectsSvg, SvgRenderOptions. SvgRenderOptions.noteTabIndex makes visible SVG notes keyboard-focusable for host-provided note navigation, and editHandleTabIndex can do the same for static SVG edit handles when the host wires authoring behavior. includeQualityIssues renders opt-in layout-quality issue boxes from evaluateAnnotationLayout() so manual placement and collision problems can be inspected visually.
  • Edit helpers: annotationEditHandles, annotationEditPatch, createAnnotationEditEvent, createAnnotationEditDelta, createAnnotationEditSession, applyAnnotationEdit, applyAnnotationEdits, translateAnchor.
  • Adapter diagnostics: formatAnchorValidationReport, assertAnchorValidationReport, assertAnchorValidationReportIfRequested, formatAnchorDiagnostic, evaluateAnchorAlignment, formatAnchorAlignmentReport, assertAnchorAlignmentReport, assertAnchorAlignmentReportIfRequested, formatAnchorAlignmentDiagnostic, AnchorSpecValidationReport, AnchorValidationAssertInput, AnchorAlignmentTarget, AnchorAlignmentReport, AnchorAlignmentOptions, AnchorAlignmentAssertInput.
  • Styling helpers: annotationClassName, brontoAnnotationClassName, annotationStyleVariables.
  • Presets: pointCallout, regionCallout, pathCallout, encircleCallout, thresholdAnnotation, badgeAnnotation.

Boundary: the root package does not render charts, parse diagram languages, mutate D3 selections, own app state, persist annotations, or provide a design system.

@ponchia/annotations/d3

Migration-only helpers are separate from normal layout and presets.

import { annotationFromD3Style, createD3StyleAnnotationBuilder }
  from '@ponchia/annotations/d3';
  • d3-style bridge: annotationFromD3Style, annotationsFromD3Style, prepareD3StyleAnnotationCollection, annotationsFromD3StyleCollection, createD3StyleAnnotationBuilder, defineD3StyleAnnotationType, annotationsFromD3StyleType, d3StyleAnnotationCollectionEditPatch, applyD3StyleAnnotationCollectionEdit, d3StyleAnnotationEditPatch, applyD3StyleAnnotationEdit, D3StyleAnnotationInput, D3StyleAnnotationOptions, D3StyleAnnotationCollectionInput, D3StyleAnnotationBuilder, D3StyleCustomAnnotationDefinition, D3StyleAnnotationEditPatch. D3StyleAnnotationInput.data is the accessor datum; use annotationData when migrated d3-style annotations need rendered annotation-layer data-* attributes.

@ponchia/annotations/react

Use the React subpath for SVG/HTML overlays that should measure notes, render custom React note content, and emit edit suggestions.

import {
  AnnotationLayer,
  useAnnotations,
  type AnnotationLayerEditEvent,
  type AnnotationLayerProps,
  type AnnotationLayerQualityEvent,
  type AnnotationLayerTargetAlignmentEvent
} from '@ponchia/annotations/react';

Exports:

  • AnnotationLayer
  • AnnotationPin
  • AnnotationPinProps
  • useAnnotations
  • AnnotationLayerProps
  • AnnotationLayerEditOptions
  • AnnotationLayerEditEvent
  • AnnotationLayerQualityEvent
  • AnnotationLayerTargetAlignmentEvent
  • UseAnnotationsOptions

AnnotationLayerProps.noteTabIndex makes visible notes keyboard-focusable in the rendered React layer while keeping navigation state in the host app. editHandleTabIndex does the same for React edit handles; it defaults to 0 for editable layers and can be set to -1 when the host wants programmatic focus only. The optional previewEdits renderer coalesces high-frequency pointer movements to the latest provisional visual update within one browser animation frame, while retaining immediate onEdit movement notifications. Unfinished preview frames are discarded at pointer release, cancellation or component unmount. The opt-in previewEdits property renders only the actively edited annotation's provisional geometry during pointer movement, with the full layout and quality callbacks remaining stable until onEditEnd persists a patch. Pointer cancellation restores the previous appearance without committing. A host replacement of the authoritative layout (or a change to previewEdits) also cancels an in-flight pointer gesture: releasing that original pointer does not emit onEditEnd for now-stale geometry. The host may begin a new gesture against the updated layout. Non-React hosts can use the experimental DOM-free previewAnnotationEdit from the root package for the same visual-only geometry; its previous candidate scores and diagnostics are not recomputed.

The root package also exposes experimental createIncrementalAnnotationLayoutSession and AnnotationLayoutSession. A session has a read-only layout property and update(nextLayoutOptions) returning a fully resolved layout. It reuses only unchanged priority-ordered prefix winners for unrefined layouts, including added or removed suffix notes. For changed obstacles, an unaffected prefix may be reused only when connectors do not depend on obstacle routing and every potential candidate geometry is disjoint from the changed boxes. Global bounds/placement changes, affected candidates, orthogonal routing dependencies and iterative refinement trigger appropriate suffix or full recomputation. Hosts control lifecycle and authoritative update timing; no workers or subscriptions are created. The public synchronous resolveAnnotationLayout behavior is unchanged. See the README authoring recipe and docs/performance.md.

assertQuality, qualityFormat, and onQuality use the same layout-quality reporting path as the DOM-free core after each resolved React layout. qualityDebug renders the same opt-in layout-quality issue boxes in the React SVG layer for authoring and manual-placement review.

Layout, quality and target-alignment notifications are independent: onLayout runs when the authoritative layout changes or the callback subscription changes, not merely because the host toggles the debug overlay, reformats quality reports or enables an unrelated diagnostic assertion. The quality and alignment callbacks still receive their own updated reports.

Quality diagnostics in the React layer are demand-driven: the underlying evaluateAnnotationLayout pass runs when onQuality, assertQuality, or qualityDebug is supplied. Passive layers and hosts using only onLayout avoid the otherwise unnecessary quadratic report cost. If requested, quality callbacks, blocking assertions and visual debug boxes use the unchanged full-quality semantics; qualityFormat changes only the report formatting.

For measure="dom", the initial size measurement and changes to the annotation collection reconcile all visible note copies. Subsequent ResizeObserver notifications measure only their changed elements, using computed local CSS sizes under zoom and the client rect as fallback. Duplicate observer entries for one note are batched, and unchanged values preserve React state identity.

AnnotationLayerProps has two mutually exclusive modes. Input mode requires annotations and bounds and can use measure="dom". Render-only mode requires layout and rejects duplicate solver inputs or any measure prop. The latter derives sources and geometry from the host result without another solve or measurement pass. Edit callbacks let the host commit updated inputs and layouts. The obsolete resolvedLayout prop fails explicitly. A render-only debug overlay uses only diagnostics already present in the layout. targetAlignmentTargets, targetAlignmentOptions, targetAlignmentFormat, assertTargetAlignment, and onTargetAlignment use the same generated-target alignment diagnostics as prepared layouts, which is useful when React renders an annotation layer over generated chart, diagram, or graph geometry.

AnnotationPin renders a native button at point in its host overlay. Give it a meaningful label, an onClick handler, and optionally selected, controls, children, className, or style. It stops pointer-down and click propagation and uses a 44px target with the optional Bronto CSS. The host controls focus, visibility, clipping, pin grouping, and the fallback list of discussions.

Boundary: the React adapter is a renderer/measurement adapter. Host apps still own annotation state, persistence, routing, and workflow actions.

@ponchia/annotations/dom

Use the DOM subpath when a host surface already rendered elements or SVG marks and you need anchors or obstacles from measured geometry.

import {
  anchorFromSelector,
  annotationFrameFromSvg,
  boxFromSvgElement,
  extractedAnchorFromElement,
  prepareDomAnnotations,
  validateDomAnchors,
  type DomAnnotationSpec
} from '@ponchia/annotations/dom';

Exports:

  • Types: AnchorKind, ElementAnchorOptions, SelectorAnchorSpec, SelectorObstacleSpec, DomAnnotationSpec, DomAnchorValidationReport, DomAnnotationLayerInput, DomAnnotationLayerOptions, ExtractedAnchor, RectLike.
  • DOMRect and element helpers: boxFromDOMRect, anchorFromDOMRect, boxFromElement, anchorFromElement, extractedAnchorFromElement, anchorFromBox.
  • Selector helpers: anchorFromSelector, anchorFromId, anchorsFromSelectors, annotationsFromDomSelectors, validateDomAnchors, prepareDomAnnotations.
  • Obstacles: obstaclesFromElements, obstaclesFromSelector, obstaclesFromSelectors.
  • SVG conversion: svgPointFromClient, clientBoxToSvgBox, boxFromSvgElement, annotationFrameFromSvg.
  • Diagnostics: formatAnchorValidationReport, assertAnchorValidationReport, evaluateAnchorAlignment, formatAnchorAlignmentReport, assertAnchorAlignmentReport. prepareDomAnnotations accepts assert: true or assert: { label, failOnWarnings }.

clientBoxToSvgBox(svg, box) transforms all four client-rectangle corners through one captured screen matrix and returns their axis-aligned enclosure in SVG user coordinates. It supports affine rotation, skew and reflection as well as translation and scale; the enclosure does not reconstruct an element's original shape from its screen bounding box. A later call reads a fresh mapping.

When the screen matrix is unavailable, the existing viewport/viewBox and preserveAspectRatio fallback is used. That fallback describes an axis-aligned viewport, not arbitrary CSS transforms; with no usable fallback, client coordinates are retained. An available but non-invertible matrix is never replaced with that approximation: host inversion/transform exceptions propagate, and nonfinite results remain nonfinite. Check geometry before using it. No general 3D or perspective inversion is provided. Measure rendered surfaces: these helpers rely on the host's reported matrix and do not detect an invertible placeholder returned by a browser for a collapsed or non-rendered surface.

DOM selector validation inspects the selected anchor geometry, including sampled path coordinates and finite rectangle edges. prepareDomAnnotations measures each selector specification once and uses that result for both its report and returned annotation. Separate specifications and requested obstacles retain their own measurements; this is not an atomic snapshot of the whole document. Re-run preparation after host changes. Extraction remains permissive, while assert rejects invalid selected geometry; malformed selectors and host measurement exceptions still propagate.

measureRangeAnchor(range, options?) returns a RangeAnchorMeasurement: status (resolved, empty, or unsupported), line rects, their union box, a truncated flag, and an optional reason. RangeAnchorOptions.maxRects defaults to 512 and accepts integers from 1 through 4096. Collapsed or invisible ranges return empty.

Coordinates default to viewport pixels. Set coordinateSpace to a containing HTML element to get its local padding-space coordinates, accounting for borders, scroll, translation and positive axis-aligned scale. Both transform and the individual CSS translate, rotate and scale properties are checked, including rendered ancestors through shadow hosts and assigned slots. Rotations other than identity turns, reflections, skew, motion paths, nonidentity 3D transforms and invisible local spaces are explicitly unsupported. No cross-shadow selection or 3D coordinate inversion is provided. Viewport measurement remains available without local conversion. Re-measure after content, layout, scroll, or zoom changes. Geometry is transient: persist host-owned text selectors and quotations instead of browser Range objects or measured rectangles.

Boundary: this subpath measures existing rendered geometry. It does not render the host surface or own application state.

@ponchia/annotations/vega

vegaViewOrigin(view) returns the plot origin plus padding, without requiring fake data or scales. vegaScaleCoordinate(scale, value, { band, coerce }) resolves one axis with start (default), center, or end band alignment. Set coerce explicitly for JSON date strings or numeric categories; exact values take priority. vegaScaleInterval(scale, from, to, { coerce }) covers both entire bands even when endpoints or the scale range are reversed. Unresolvable coordinates return undefined. These structural helpers do not import Vega or own chart state.

Use the Vega subpath after a Vega View has data/scales/scenegraph output, or after the host has rendered/exported Vega SVG. Vega-Lite consumers compile or render through public Vega-Lite/Vega APIs first, then use this adapter against the resulting Vega View or SVG.

import {
  prepareVegaScenegraphAnnotations,
  prepareVegaSvgAnnotations,
  validateVegaScenegraphAnchors,
  type VegaScenegraphAnchorSpec
} from '@ponchia/annotations/vega';

Exports:

  • View data: anchorsFromVegaView, annotationsFromVegaView, prepareVegaViewAnnotations, validateVegaViewAnchors, obstaclesFromVegaView, anchorFromVegaDatum, VegaViewAnchorSpec, VegaViewObstacleOptions, VegaViewLike.
  • Scales: anchorsFromVegaScales, annotationsFromVegaScales, prepareVegaScaleAnnotations, obstaclesFromVegaScales, validateVegaScaleAnchors, VegaScaleAnchorSpec, VegaScaleObstacleOptions, VegaScaleViewLike, VegaScaleFunction.
  • Scenegraph: anchorsFromVegaScenegraph, annotationsFromVegaScenegraph, prepareVegaScenegraphAnnotations, obstaclesFromVegaScenegraph, validateVegaScenegraphAnchors, VegaScenegraphAnchorSpec, VegaScenegraphObstacleOptions, VegaScenegraphItem, VegaScenegraphViewLike.
  • Rendered SVG: anchorsFromVegaSvg, annotationsFromVegaSvg, prepareVegaSvgAnnotations, obstaclesFromVegaSvg, validateVegaSvgAnchors, findVegaSvgElement, VegaSvgAnchorSpec, VegaSvgAnnotationSpec, VegaSvgObstacleOptions.
  • Shared: VegaAnnotationAuthoring, VegaAnchorResult, VegaAnchorValidationReport, VegaAnnotationLayerInput, formatAnchorValidationReport, assertAnchorValidationReport, evaluateAnchorAlignment, formatAnchorAlignmentReport, assertAnchorAlignmentReport. Every prepareVega*Annotations helper accepts assert: true or assert: { label, failOnWarnings }.

Rendered SVG metadata matching identifies the Vega wrapper/layer. If that wrapper contains exactly one concrete mark element, anchors measure that child mark; multi-mark layers should use a selector or scenegraph datum predicate.

Boundary: the adapter does not create Vega specs, own scales, infer chart semantics, or require a vega-lite peer.

@ponchia/annotations/mermaid

Use the Mermaid subpath after Mermaid has rendered SVG.

import {
  prepareMermaidAnnotations,
  validateMermaidSvgAnchors,
  type MermaidAnchorSpec
} from '@ponchia/annotations/mermaid';

Exports:

  • Anchor extraction: anchorsFromMermaidSvg, annotationsFromMermaidSvg, prepareMermaidAnnotations, validateMermaidSvgAnchors, findMermaidElement, findElementByText.
  • Obstacles: obstaclesFromMermaidSvg.
  • Types: MermaidAnchorSpec, MermaidObstacleOptions, MermaidAnnotationLayerOptions, MermaidAnchorResult, MermaidAnnotationAuthoring, MermaidAnchorDiagnostic, MermaidAnchorValidationReport, MermaidAnnotationLayerInput, MermaidLabelMatch.
  • Diagnostics: formatAnchorValidationReport, assertAnchorValidationReport, evaluateAnchorAlignment, formatAnchorAlignmentReport, assertAnchorAlignmentReport. prepareMermaidAnnotations accepts assert: true or assert: { label, failOnWarnings }.

Boundary: the adapter targets rendered Mermaid SVG ids, labels, nodes, edges, clusters, classes, data attributes, and selectors. It does not parse Mermaid source or own diagram layout.

For rendered edge annotations, use edgeId when the generated edge id is known, or edgeSourceId plus edgeTargetId when the host knows the connected node ids. Requested edge path anchors still prefer the child route <path> over the wrapper edge group.

@ponchia/annotations/d2

Use the D2 subpath with compiled D2 diagram geometry, or rendered D2 SVG when only the SVG is available.

import {
  prepareD2DiagramAnnotations,
  prepareD2SvgAnnotations,
  validateD2DiagramAnchors,
  type D2DiagramAnchorSpec
} from '@ponchia/annotations/d2';

Exports:

  • Compiled diagram: anchorsFromD2Diagram, annotationsFromD2Diagram, prepareD2DiagramAnnotations, validateD2DiagramAnchors, obstaclesFromD2Diagram, allD2Shapes, allD2Connections, D2DiagramAnchorSpec, D2DiagramLike, D2ShapeLike, D2ConnectionLike, D2ObstacleOptions, D2DiagramAnnotationLayerOptions.
  • Rendered SVG: anchorsFromD2Svg, annotationsFromD2Svg, prepareD2SvgAnnotations, validateD2SvgAnchors, obstaclesFromD2Svg, findD2SvgElement, D2SvgAnchorSpec, D2SvgObstacleOptions, D2SvgAnnotationLayerOptions.
  • Shared: D2AnnotationAuthoring, D2AnchorResult, D2LabelMatch, D2AnchorDiagnostic, D2AnchorValidationReport, D2AnnotationLayerInput, formatAnchorValidationReport, assertAnchorValidationReport, evaluateAnchorAlignment, formatAnchorAlignmentReport, assertAnchorAlignmentReport. prepareD2DiagramAnnotations and prepareD2SvgAnnotations accept assert: true or assert: { label, failOnWarnings }.

Boundary: the adapter does not parse D2 source or execute D2. Hosts provide compiled diagram geometry or rendered SVG. Exact and contains label matching are supported for compiled diagram labels and rendered SVG text. When a rendered SVG connection spec asks for kind: 'path', the adapter prefers a child route <path> over the wrapper group.

@ponchia/annotations/react-flow

Use the React Flow subpath with public node, handle, edge, and viewport state.

import {
  prepareReactFlowAnnotations,
  validateReactFlowAnchors,
  type ReactFlowAnchorSpec
} from '@ponchia/annotations/react-flow';

Exports:

  • Extraction: anchorsFromReactFlow, annotationsFromReactFlow, prepareReactFlowAnnotations, validateReactFlowAnchors, obstaclesFromReactFlow. Obstacles can include nodes, measured handles via includeHandles, and edges.
  • Geometry: nodeBox, handleBox, handlePoint.
  • Types: ReactFlowAnchorSpec, ReactFlowAnchorInput, ReactFlowAnnotationAuthoring, ReactFlowViewportLike, ReactFlowHandleType, ReactFlowHandleLike, ReactFlowHandleBoundsLike, ReactFlowNodeLike, ReactFlowEdgeLike, ReactFlowHandleAnchorSpec, ReactFlowObstacleOptions, ReactFlowAnnotationLayerOptions, ReactFlowAnchorResult, ReactFlowAnchorDiagnostic, ReactFlowAnchorValidationReport, ReactFlowAnnotationLayerInput.
  • Diagnostics: formatAnchorValidationReport, assertAnchorValidationReport, evaluateAnchorAlignment, formatAnchorAlignmentReport, assertAnchorAlignmentReport. prepareReactFlowAnnotations accepts assert: true or assert: { label, failOnWarnings }; use failOnWarnings: true to reject unmeasured handle fallbacks.

Default edge anchors use measured sourceHandle and targetHandle centers when available. Supply edgePoints in ReactFlowAnchorInput when the host wants annotations to follow a custom routed edge path.

Node geometry uses internals.positionAbsolute, then positionAbsolute, then position. Absolute positions are already top-left flow coordinates, including any parent offset; the adapter applies only the viewport pan/zoom to them. For position, it first subtracts the measured node size multiplied by node.origin (when present) or the input nodeOrigin (default [0, 0]). Supply resolved absolute positions for nested nodes: the adapter does not traverse parents. Node anchors, measured handles, default edge endpoints, and obstacles all use this same coordinate conversion.

Boundary: the adapter does not own graph layout, React Flow interaction policy, application state, or persistence.

@ponchia/annotations/bronto.css

Import the CSS bridge when using the built-in SVG/React renderers, package classes, or migrated Bronto static SVG snippets.

import '@ponchia/annotations/bronto.css';

Styled class families:

  • Package classes: .pa-annotation-layer, .pa-annotation, .pa-annotation__subject, .pa-annotation__connector, .pa-annotation__note, .pa-annotation__note-line, .pa-annotation__title, .pa-annotation__label, .pa-annotation__badge, .pa-annotation__quality-issue, .pa-annotation__edit-handle.
  • Legacy Bronto classes: .ui-annotation, .ui-annotation__subject, .ui-annotation__connector, .ui-annotation__connector-end, .ui-annotation__note, .ui-annotation__note-line, .ui-annotation__title, .ui-annotation__label, .ui-annotation__badge.
  • Modifiers: variants such as --callout, --circle, --threshold, --badge, --bracket, --band, --slope, --compare, --cluster, --axis, --timeline, and --evidence; tones such as --accent, --muted, --success, --warning, --danger, and --info; motion hints such as --draw, --reveal, --pulse, and --focus.

Boundary: this subpath is styling only. It does not import @ponchia/ui or provide a design system.

Readability evidence (experimental)

evaluateAnnotationLayout(layout, { readability: true }) additionally returns readability?: LayoutReadabilityReport: polyline crossing-pair count, total route length, bends and explicit coverage counts. It does not redefine the geometry score. refinement: { readability: true } enables the bounded non-regressing editorial pass described in the core guide.