@simplex-viz/react 0.2.0 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,5 +1,5 @@
1
1
  <p align="center">
2
- <img src="https://raw.githubusercontent.com/ghackenberg/simplex-viz/main/docs/assets/logo-react.png" width="640" alt="SimplexViz / react — @simplex-viz/react" />
2
+ <img src="https://raw.githubusercontent.com/ghackenberg/simplex-viz/main/docs/assets/logo-react.png" width="525" alt="SimplexViz / react — @simplex-viz/react" />
3
3
  </p>
4
4
 
5
5
  # @simplex-viz/react
@@ -1,5 +1,5 @@
1
1
  import type { ClusterDescriptor, ClusterHoverEvent, ClusterMetaConfig, ContentHoverEvent, ContentLayoutContext, DefaultTaggedItem, HitTarget, ItemIdentityConfig, LayoutMetrics, LayoutSolverOptions, MeshOptions, NodeRenderState, NormalizedPointerEvent, VisualResolver, WheelBehavior } from '@simplex-viz/core';
2
- import { SimplexSvgController, type DefaultClusterPresetVisual, type DefaultContentPresetVisual, type SimplexVisualPreset, type SvgNodeView } from '@simplex-viz/svg';
2
+ import { SimplexSvgController, type DefaultClusterPresetVisual, type DefaultContentPresetVisual, type SimplexTheme, type SimplexVisualPreset, type SvgNodeView } from '@simplex-viz/svg';
3
3
  import { type CSSProperties, type MutableRefObject, type ReactNode } from 'react';
4
4
  /**
5
5
  * Union payload passed to a custom React `tooltip` formatter on `<SimplexTopicGraph />`.
@@ -21,6 +21,8 @@ export type SimplexTopicGraphProps<TItem = DefaultTaggedItem, TContentVisual = D
21
21
  readonly items: readonly TItem[];
22
22
  /** Built-in visual preset used when custom views / `visualResolver` are omitted. Default: `'geometric'`. */
23
23
  readonly preset?: SimplexVisualPreset;
24
+ /** Visual color theme (`'dark'` or `'light'`) for built-in presets and tooltips. Default: `'dark'`. */
25
+ readonly theme?: SimplexTheme;
24
26
  /** Optional label extractor for built-in presets and default hover tooltips. */
25
27
  readonly getLabel?: (item: TItem) => string;
26
28
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"SimplexTopicGraph.d.ts","sourceRoot":"","sources":["../src/SimplexTopicGraph.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"SimplexTopicGraph.d.ts","sourceRoot":"","sources":["../src/SimplexTopicGraph.tsx"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  export * from './ReactJsxSvgView';
2
2
  export * from './useSimplexGraphController';
3
3
  export * from './SimplexTopicGraph';
4
- export { BadgeClusterSvgView, ClusterAnchorSvgView, GeometricShapeSvgView, MultiSectorGlyphSvgView, SimplexSvgController, createSimplexSvg, type BadgeClusterVisual, type ClusterAnchorVisual, type DefaultClusterPresetVisual, type DefaultContentPresetVisual, type GeometricShapeVisual, type MultiSectorGlyphVisual, type SimplexVisualPreset, type SvgNodeView, } from '@simplex-viz/svg';
4
+ export { BadgeClusterSvgView, ClusterAnchorSvgView, GeometricShapeSvgView, MultiSectorGlyphSvgView, SimplexSvgController, createSimplexSvg, type BadgeClusterVisual, type ClusterAnchorVisual, type DefaultClusterPresetVisual, type DefaultContentPresetVisual, type GeometricShapeVisual, type MultiSectorGlyphVisual, type SimplexTheme, type SimplexVisualPreset, type SvgNodeView, } from '@simplex-viz/svg';
5
5
  export { solveSimplexSnapshot, computeConvexHull, rectToConvexPolygon, regularPolygon, starConvexHull, type CameraController, type CameraState, type ClusterDescriptor, type ClusterHoverEvent, type ContentHoverEvent, type ContentLayoutContext, type ConvexGeometry, type DefaultTaggedItem, type HitTarget, type LayoutMetrics, type LayoutSolverOptions, type MeshOptions, type NodeRenderState, type SimplexLayoutSnapshot, type SimplexSnapshotOptions, type VisualResolver, } from '@simplex-viz/core';
6
6
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC;AAClC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,qBAAqB,CAAC;AAGpC,OAAO,EACL,mBAAmB,EACnB,oBAAoB,EACpB,qBAAqB,EACrB,uBAAuB,EACvB,oBAAoB,EACpB,gBAAgB,EAChB,KAAK,kBAAkB,EACvB,KAAK,mBAAmB,EACxB,KAAK,0BAA0B,EAC/B,KAAK,0BAA0B,EAC/B,KAAK,oBAAoB,EACzB,KAAK,sBAAsB,EAC3B,KAAK,mBAAmB,EACxB,KAAK,WAAW,GACjB,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EACL,oBAAoB,EACpB,iBAAiB,EACjB,mBAAmB,EACnB,cAAc,EACd,cAAc,EACd,KAAK,gBAAgB,EACrB,KAAK,WAAW,EAChB,KAAK,iBAAiB,EACtB,KAAK,iBAAiB,EACtB,KAAK,iBAAiB,EACtB,KAAK,oBAAoB,EACzB,KAAK,cAAc,EACnB,KAAK,iBAAiB,EACtB,KAAK,SAAS,EACd,KAAK,aAAa,EAClB,KAAK,mBAAmB,EACxB,KAAK,WAAW,EAChB,KAAK,eAAe,EACpB,KAAK,qBAAqB,EAC1B,KAAK,sBAAsB,EAC3B,KAAK,cAAc,GACpB,MAAM,mBAAmB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC;AAClC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,qBAAqB,CAAC;AAGpC,OAAO,EACL,mBAAmB,EACnB,oBAAoB,EACpB,qBAAqB,EACrB,uBAAuB,EACvB,oBAAoB,EACpB,gBAAgB,EAChB,KAAK,kBAAkB,EACvB,KAAK,mBAAmB,EACxB,KAAK,0BAA0B,EAC/B,KAAK,0BAA0B,EAC/B,KAAK,oBAAoB,EACzB,KAAK,sBAAsB,EAC3B,KAAK,YAAY,EACjB,KAAK,mBAAmB,EACxB,KAAK,WAAW,GACjB,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EACL,oBAAoB,EACpB,iBAAiB,EACjB,mBAAmB,EACnB,cAAc,EACd,cAAc,EACd,KAAK,gBAAgB,EACrB,KAAK,WAAW,EAChB,KAAK,iBAAiB,EACtB,KAAK,iBAAiB,EACtB,KAAK,iBAAiB,EACtB,KAAK,oBAAoB,EACzB,KAAK,cAAc,EACnB,KAAK,iBAAiB,EACtB,KAAK,SAAS,EACd,KAAK,aAAa,EAClB,KAAK,mBAAmB,EACxB,KAAK,WAAW,EAChB,KAAK,eAAe,EACpB,KAAK,qBAAqB,EAC1B,KAAK,sBAAsB,EAC3B,KAAK,cAAc,GACpB,MAAM,mBAAmB,CAAC"}
package/dist/index.js CHANGED
@@ -193,6 +193,7 @@ function SimplexTopicGraph(props) {
193
193
  const resolveEffectiveResolver = () => {
194
194
  const p = latestPropsRef.current;
195
195
  const preset = p.preset ?? "geometric";
196
+ const theme = p.theme ?? "dark";
196
197
  const presetResolver = createPresetVisualResolver(
197
198
  preset,
198
199
  (item) => {
@@ -213,7 +214,8 @@ function SimplexTopicGraph(props) {
213
214
  }
214
215
  }
215
216
  return "";
216
- }
217
+ },
218
+ theme
217
219
  );
218
220
  const base = p.visualResolver;
219
221
  const getKey = (visual) => {
@@ -319,6 +321,7 @@ function SimplexTopicGraph(props) {
319
321
  getLabel: p.getLabel,
320
322
  deriveClusterMeta: p.deriveClusterMeta,
321
323
  preset: p.preset,
324
+ theme: p.theme,
322
325
  visualResolver: effectiveResolver,
323
326
  contentView,
324
327
  clusterView,
@@ -403,12 +406,14 @@ function SimplexTopicGraph(props) {
403
406
  useEffect(() => {
404
407
  const ctrl = ctrlRef.current;
405
408
  if (!ctrl) return;
409
+ ctrl.setTheme(props.theme ?? "dark");
406
410
  const effectiveResolver = resolveEffectiveResolver();
407
411
  const { contentView, clusterView } = resolveActiveViews(effectiveResolver);
408
412
  ctrl.setViews({ contentView, clusterView });
409
413
  ctrl.setVisualResolver(effectiveResolver);
410
414
  }, [
411
415
  props.preset,
416
+ props.theme,
412
417
  props.visualResolver,
413
418
  props.contentView,
414
419
  props.clusterView,
@@ -458,16 +463,17 @@ function SimplexTopicGraph(props) {
458
463
  Math.max(8, Math.round(hoveredTarget.screenPosition.y + 14)),
459
464
  Math.max(8, containerH - 80)
460
465
  );
466
+ const isLight = props.theme === "light";
461
467
  const content = typeof props.tooltip === "function" ? props.tooltip(hoveredTarget) : hoveredTarget.kind === "content" ? /* @__PURE__ */ jsxs("div", { children: [
462
- /* @__PURE__ */ jsx("div", { style: { fontWeight: 600, color: "#f8fafc" }, children: extractDefaultItemLabel(
468
+ /* @__PURE__ */ jsx("div", { style: { fontWeight: 600, color: isLight ? "#0f172a" : "#f8fafc" }, children: extractDefaultItemLabel(
463
469
  hoveredTarget.item,
464
470
  hoveredTarget.layoutContext.id,
465
471
  props.getLabel
466
472
  ) }),
467
- hoveredTarget.layoutContext.tags.length > 0 && /* @__PURE__ */ jsx("div", { style: { marginTop: 3, fontSize: 11, color: "#94a3b8" }, children: hoveredTarget.layoutContext.tags.map((t) => `#${t.tag}`).slice(0, 5).join(" \xB7 ") })
473
+ hoveredTarget.layoutContext.tags.length > 0 && /* @__PURE__ */ jsx("div", { style: { marginTop: 3, fontSize: 11, color: isLight ? "#475569" : "#94a3b8" }, children: hoveredTarget.layoutContext.tags.map((t) => `#${t.tag}`).slice(0, 5).join(" \xB7 ") })
468
474
  ] }) : /* @__PURE__ */ jsxs("div", { children: [
469
475
  /* @__PURE__ */ jsx("div", { style: { fontWeight: 600, color: hoveredTarget.cluster.colorHex }, children: `${hoveredTarget.cluster.code} \xB7 ${hoveredTarget.cluster.defaultLabel}` }),
470
- /* @__PURE__ */ jsx("div", { style: { marginTop: 3, fontSize: 11, color: "#94a3b8" }, children: `${hoveredTarget.cluster.members.length} ${hoveredTarget.cluster.members.length === 1 ? "item" : "items"}` })
476
+ /* @__PURE__ */ jsx("div", { style: { marginTop: 3, fontSize: 11, color: isLight ? "#475569" : "#94a3b8" }, children: `${hoveredTarget.cluster.members.length} ${hoveredTarget.cluster.members.length === 1 ? "item" : "items"}` })
471
477
  ] });
472
478
  return /* @__PURE__ */ jsx(
473
479
  "div",
@@ -481,13 +487,13 @@ function SimplexTopicGraph(props) {
481
487
  maxWidth: 244,
482
488
  padding: "7px 10px",
483
489
  borderRadius: 8,
484
- background: "rgba(9, 13, 22, 0.94)",
485
- border: "1px solid rgba(51, 65, 85, 0.85)",
486
- color: "#f1f5f9",
490
+ background: isLight ? "rgba(255, 255, 255, 0.96)" : "rgba(9, 13, 22, 0.94)",
491
+ border: isLight ? "1px solid rgba(203, 213, 225, 0.95)" : "1px solid rgba(51, 65, 85, 0.85)",
492
+ color: isLight ? "#0f172a" : "#f1f5f9",
487
493
  fontSize: 12,
488
494
  lineHeight: 1.4,
489
495
  pointerEvents: "none",
490
- boxShadow: "0 10px 24px rgba(0, 0, 0, 0.45)"
496
+ boxShadow: isLight ? "0 10px 24px rgba(15, 23, 42, 0.12)" : "0 10px 24px rgba(0, 0, 0, 0.45)"
491
497
  },
492
498
  children: content
493
499
  }
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/ReactJsxSvgView.ts","../src/useSimplexGraphController.ts","../src/SimplexTopicGraph.tsx"],"names":["jsx","useRef"],"mappings":"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","file":"index.js","sourcesContent":["import {\n rectToConvexPolygon,\n type ClusterDescriptor,\n type ContentLayoutContext,\n type ConvexGeometry,\n type NodeRenderState,\n} from '@simplex-viz/core';\nimport { SVG_NS, type SvgNodeView } from '@simplex-viz/svg';\nimport type { ReactNode } from 'react';\nimport { createRoot, type Root } from 'react-dom/client';\nimport { renderToStaticMarkup } from 'react-dom/server';\n\nexport interface ContentDomainRecord<TItem, TTagMeta, TClusterMeta> {\n readonly item: TItem;\n readonly ctx: ContentLayoutContext<TItem, TTagMeta, TClusterMeta>;\n}\n\n/**\n * Bridges a declarative React JSX render function into an `@simplex-viz/svg` `SvgNodeView`\n * with automatic offscreen `getBBox()` convex hull measurement and cached DOM updates.\n */\nexport class ReactJsxSvgView<TVisual, TDomain> implements SvgNodeView<TVisual> {\n private readonly renderFn: (\n domain: TDomain,\n state: NodeRenderState<TVisual>,\n ) => ReactNode;\n private readonly getKey: (visual: TVisual) => string;\n private readonly domainByKey: ReadonlyMap<string, TDomain>;\n private readonly rootsByGroup = new WeakMap<SVGGElement, Root>();\n private readonly activeRoots = new Set<Root>();\n private measureGroup: SVGGElement | null = null;\n\n constructor(params: {\n readonly renderFn: (domain: TDomain, state: NodeRenderState<TVisual>) => ReactNode;\n readonly getKey: (visual: TVisual) => string;\n readonly domainByKey: ReadonlyMap<string, TDomain>;\n }) {\n this.renderFn = params.renderFn;\n this.getKey = params.getKey;\n this.domainByKey = params.domainByKey;\n }\n\n measureConvexHull(visual: TVisual, measureSvg: SVGSVGElement): ConvexGeometry {\n const key = this.getKey(visual);\n const domain = this.domainByKey.get(key);\n if (!domain) {\n return rectToConvexPolygon(48, 28, 6);\n }\n\n const doc = measureSvg.ownerDocument;\n let bin = measureSvg.querySelector<SVGGElement>('g.sv-measure-bin');\n if (!bin) {\n bin = doc.createElementNS(SVG_NS, 'g');\n bin.setAttribute('class', 'sv-measure-bin');\n bin.setAttribute('visibility', 'hidden');\n bin.setAttribute('pointer-events', 'none');\n bin.setAttribute('transform', 'translate(-99999, -99999)');\n measureSvg.appendChild(bin);\n }\n\n if (!this.measureGroup || this.measureGroup.parentNode !== bin) {\n this.measureGroup = doc.createElementNS(SVG_NS, 'g');\n bin.appendChild(this.measureGroup);\n }\n\n const dummyState: NodeRenderState<TVisual> = {\n id: '__measure__',\n x: 0,\n y: 0,\n scale: 1,\n opacity: 1,\n visual,\n hull: { kind: 'circle', radius: 16 },\n cacheKey: key,\n interaction: {\n isHovered: false,\n isPinned: false,\n isDimmed: false,\n isHighlighted: false,\n },\n transition: null,\n };\n\n const jsx = this.renderFn(domain, dummyState);\n const markup = renderToStaticMarkup(jsx);\n // Parse JSX markup into SVG namespace inside the offscreen measurement group\n const wrapperSvg = doc.createElementNS(SVG_NS, 'svg');\n wrapperSvg.innerHTML = markup;\n while (this.measureGroup.firstChild) {\n this.measureGroup.removeChild(this.measureGroup.firstChild);\n }\n while (wrapperSvg.firstChild) {\n this.measureGroup.appendChild(wrapperSvg.firstChild);\n }\n\n let width = 0;\n let height = 0;\n try {\n if (typeof this.measureGroup.getBBox === 'function') {\n const bbox = this.measureGroup.getBBox();\n width = bbox.width;\n height = bbox.height;\n }\n } catch {\n // Headless DOM without layout engine\n }\n\n if (width <= 1 || height <= 1) {\n let maxHalfW = 0;\n let maxHalfH = 0;\n this.measureGroup.querySelectorAll('rect, circle, text').forEach((el) => {\n const tag = el.tagName.toLowerCase();\n if (tag === 'rect') {\n const w = parseFloat(el.getAttribute('width') ?? '0');\n const h = parseFloat(el.getAttribute('height') ?? '0');\n maxHalfW = Math.max(maxHalfW, w / 2);\n maxHalfH = Math.max(maxHalfH, h / 2);\n } else if (tag === 'circle') {\n const r = parseFloat(el.getAttribute('r') ?? '0');\n maxHalfW = Math.max(maxHalfW, r);\n maxHalfH = Math.max(maxHalfH, r);\n } else if (tag === 'text') {\n const len = (el.textContent ?? '').length;\n const fs = parseFloat(el.getAttribute('font-size') ?? '11');\n maxHalfW = Math.max(maxHalfW, (len * fs * 0.56) / 2);\n maxHalfH = Math.max(maxHalfH, fs * 0.75);\n }\n });\n width = Math.max(24, maxHalfW * 2);\n height = Math.max(20, maxHalfH * 2);\n }\n\n return rectToConvexPolygon(width + 4, height + 4, 6);\n }\n\n mountOrUpdate(\n groupEl: SVGGElement,\n visual: TVisual,\n state: NodeRenderState<TVisual>,\n ): void {\n const key = this.getKey(visual);\n const domain = this.domainByKey.get(key);\n if (!domain) return;\n\n let root = this.rootsByGroup.get(groupEl);\n if (!root) {\n while (groupEl.firstChild) groupEl.removeChild(groupEl.firstChild);\n root = createRoot(groupEl);\n this.rootsByGroup.set(groupEl, root);\n this.activeRoots.add(root);\n }\n\n root.render(this.renderFn(domain, state));\n }\n\n dispose(): void {\n const roots = [...this.activeRoots];\n this.activeRoots.clear();\n this.measureGroup = null;\n queueMicrotask(() => {\n for (const r of roots) {\n r.unmount();\n }\n });\n }\n}\n\nexport type ContentJsxRenderFn<TItem, TContentVisual, TTagMeta, TClusterMeta> = (\n item: TItem,\n ctx: ContentLayoutContext<TItem, TTagMeta, TClusterMeta>,\n state: NodeRenderState<TContentVisual>,\n) => ReactNode;\n\nexport type ClusterJsxRenderFn<TItem, TClusterVisual, TTagMeta, TClusterMeta> = (\n cluster: ClusterDescriptor<TItem, TTagMeta, TClusterMeta>,\n state: NodeRenderState<TClusterVisual>,\n) => ReactNode;\n","import type {\n CameraController,\n ClusterDescriptor,\n DefaultTaggedItem,\n LayoutMetrics,\n} from '@simplex-viz/core';\nimport type { SimplexSvgController } from '@simplex-viz/svg';\nimport { useCallback, useRef } from 'react';\n\n/**\n * Imperative handle bound to `<SimplexTopicGraph controllerRef={...} />`.\n */\nexport interface SimplexGraphHandle<\n TItem = DefaultTaggedItem,\n TContentVisual = unknown,\n TClusterVisual = unknown,\n TTagMeta = undefined,\n TClusterMeta = undefined,\n> {\n addItems(items: TItem | readonly TItem[]): void;\n removeItems(ids: string | readonly string[]): void;\n setItems(items: readonly TItem[]): void;\n resetCamera(): void;\n zoomBy(factor: number): void;\n getMetrics(): LayoutMetrics | null;\n getClusters(): readonly ClusterDescriptor<TItem, TTagMeta, TClusterMeta>[];\n getRawController(): SimplexSvgController<\n TItem,\n TContentVisual,\n TClusterVisual,\n TTagMeta,\n TClusterMeta\n > | null;\n}\n\n/**\n * React hook returning a stable `controllerRef` and imperative transaction helpers\n * (`addItems`, `removeItems`, `setItems`, camera controls, and live telemetry getters).\n */\nexport function useSimplexGraphController<\n TItem = DefaultTaggedItem,\n TContentVisual = unknown,\n TClusterVisual = unknown,\n TTagMeta = undefined,\n TClusterMeta = undefined,\n>(): {\n readonly controllerRef: React.MutableRefObject<SimplexSvgController<\n TItem,\n TContentVisual,\n TClusterVisual,\n TTagMeta,\n TClusterMeta\n > | null>;\n readonly handle: SimplexGraphHandle<\n TItem,\n TContentVisual,\n TClusterVisual,\n TTagMeta,\n TClusterMeta\n >;\n} {\n const controllerRef = useRef<SimplexSvgController<\n TItem,\n TContentVisual,\n TClusterVisual,\n TTagMeta,\n TClusterMeta\n > | null>(null);\n\n const addItems = useCallback((items: TItem | readonly TItem[]) => {\n controllerRef.current?.addItems(items);\n }, []);\n\n const removeItems = useCallback((ids: string | readonly string[]) => {\n controllerRef.current?.removeItems(ids);\n }, []);\n\n const setItems = useCallback((items: readonly TItem[]) => {\n controllerRef.current?.setItems(items);\n }, []);\n\n const resetCamera = useCallback(() => {\n controllerRef.current?.camera.reset();\n }, []);\n\n const zoomBy = useCallback((factor: number) => {\n const ctrl = controllerRef.current;\n if (!ctrl) return;\n const svg = ctrl.getSvgElement();\n const rect = svg.getBoundingClientRect();\n const cam: CameraController = ctrl.camera;\n cam.zoomToCursor(rect.width / 2, rect.height / 2, factor);\n }, []);\n\n const getMetrics = useCallback(() => {\n return controllerRef.current?.getMetrics() ?? null;\n }, []);\n\n const getClusters = useCallback(() => {\n return controllerRef.current?.getClusters() ?? [];\n }, []);\n\n const getRawController = useCallback(() => {\n return controllerRef.current;\n }, []);\n\n return {\n controllerRef,\n handle: {\n addItems,\n removeItems,\n setItems,\n resetCamera,\n zoomBy,\n getMetrics,\n getClusters,\n getRawController,\n },\n };\n}\n","import type {\n ClusterDescriptor,\n ClusterHoverEvent,\n ClusterMetaConfig,\n ContentHoverEvent,\n ContentLayoutContext,\n DefaultTaggedItem,\n HitTarget,\n ItemIdentityConfig,\n LayoutMetrics,\n LayoutSolverOptions,\n MeshOptions,\n NodeRenderState,\n NormalizedPointerEvent,\n VisualResolver,\n WheelBehavior,\n} from '@simplex-viz/core';\nimport {\n SimplexSvgController,\n createPresetViews,\n createPresetVisualResolver,\n extractDefaultItemLabel,\n type DefaultClusterPresetVisual,\n type DefaultContentPresetVisual,\n type SimplexVisualPreset,\n type SvgNodeView,\n} from '@simplex-viz/svg';\nimport {\n useEffect,\n useRef,\n useState,\n type CSSProperties,\n type MutableRefObject,\n type ReactNode,\n} from 'react';\nimport {\n ReactJsxSvgView,\n type ContentDomainRecord,\n} from './ReactJsxSvgView';\n\n/**\n * Union payload passed to a custom React `tooltip` formatter on `<SimplexTopicGraph />`.\n */\nexport type SimplexReactTooltipTarget<\n TItem = DefaultTaggedItem,\n TContentVisual = DefaultContentPresetVisual,\n TClusterVisual = DefaultClusterPresetVisual,\n TTagMeta = undefined,\n TClusterMeta = undefined,\n> =\n | ({ readonly kind: 'content' } & ContentHoverEvent<\n TItem,\n TContentVisual,\n TTagMeta,\n TClusterMeta\n >)\n | ({ readonly kind: 'cluster' } & ClusterHoverEvent<\n TItem,\n TClusterVisual,\n TTagMeta,\n TClusterMeta\n >);\n\n/**\n * Props for `<SimplexTopicGraph />`, preserving end-to-end generic inference across\n * `TItem`, `TContentVisual`, `TClusterVisual`, `TTagMeta`, and `TClusterMeta`.\n *\n * Works zero-config with `<SimplexTopicGraph items={items} />` via built-in presets,\n * or with keyless declarative JSX renderers (`renderContentNode` / `renderClusterNode`),\n * or with full `VisualResolver` + `SvgNodeView` customization.\n */\nexport type SimplexTopicGraphProps<\n TItem = DefaultTaggedItem,\n TContentVisual = DefaultContentPresetVisual,\n TClusterVisual = DefaultClusterPresetVisual,\n TTagMeta = undefined,\n TClusterMeta = undefined,\n> = ItemIdentityConfig<TItem> &\n ClusterMetaConfig<TItem, TTagMeta, TClusterMeta> & {\n readonly items: readonly TItem[];\n /** Built-in visual preset used when custom views / `visualResolver` are omitted. Default: `'geometric'`. */\n readonly preset?: SimplexVisualPreset;\n /** Optional label extractor for built-in presets and default hover tooltips. */\n readonly getLabel?: (item: TItem) => string;\n /**\n * Optional `VisualResolver` mapping items and clusters to pure visual descriptors.\n * Optional in both zero-config preset mode and declarative JSX renderer mode.\n */\n readonly visualResolver?: VisualResolver<\n TItem,\n TContentVisual,\n TClusterVisual,\n TTagMeta,\n TClusterMeta\n >;\n /** Optional cache key override when using `renderContentNode` without `visualResolver`. */\n readonly getContentCacheKey?: (\n item: TItem,\n ctx: ContentLayoutContext<TItem, TTagMeta, TClusterMeta>,\n ) => string;\n /** Optional cache key override when using `renderClusterNode` without `visualResolver`. */\n readonly getClusterCacheKey?: (\n cluster: ClusterDescriptor<TItem, TTagMeta, TClusterMeta>,\n ) => string;\n /** Portable `@simplex-viz/svg` view plugin for content items. */\n readonly contentView?: SvgNodeView<TContentVisual>;\n /** Portable `@simplex-viz/svg` view plugin for topic clusters. */\n readonly clusterView?: SvgNodeView<TClusterVisual>;\n /** Optional declarative React JSX renderer for content items (auto-measured via `getBBox()`). */\n readonly renderContentNode?: (\n item: TItem,\n ctx: ContentLayoutContext<TItem, TTagMeta, TClusterMeta>,\n state: NodeRenderState<TContentVisual>,\n ) => ReactNode;\n /** Optional declarative React JSX renderer for topic clusters (auto-measured via `getBBox()`). */\n readonly renderClusterNode?: (\n cluster: ClusterDescriptor<TItem, TTagMeta, TClusterMeta>,\n state: NodeRenderState<TClusterVisual>,\n ) => ReactNode;\n readonly normalizeTag?: (rawTag: string) => string;\n readonly resolveTagMeta?: (normalizedTag: string) => TTagMeta | undefined;\n readonly meshOptions?: MeshOptions;\n readonly layoutOptions?: LayoutSolverOptions;\n readonly sizeMultiplier?: number;\n readonly showHulls?: boolean;\n readonly pinnedIds?: ReadonlySet<string> | readonly string[];\n readonly highlightedIds?: ReadonlySet<string> | readonly string[];\n readonly focusedClusterUid?: string | null;\n /**\n * Enables built-in cluster focus toggle on click when `focusedClusterUid` and `onLeftClick`\n * are not controlled externally. Default: `true`.\n */\n readonly focusOnClusterClick?: boolean;\n /**\n * Enables a built-in floating hover tooltip, or accepts a custom `(target) => ReactNode` formatter.\n * Default: `false`.\n */\n readonly tooltip?:\n | boolean\n | ((\n target: SimplexReactTooltipTarget<\n TItem,\n TContentVisual,\n TClusterVisual,\n TTagMeta,\n TClusterMeta\n >,\n ) => ReactNode);\n readonly onContentHover?: (\n event: ContentHoverEvent<TItem, TContentVisual, TTagMeta, TClusterMeta> | null,\n ) => void;\n readonly onClusterHover?: (\n event: ClusterHoverEvent<TItem, TClusterVisual, TTagMeta, TClusterMeta> | null,\n ) => void;\n readonly onLeftClick?: (\n target: HitTarget<TItem, TContentVisual, TClusterVisual, TTagMeta, TClusterMeta>,\n rawEvent: NormalizedPointerEvent,\n ) => void;\n readonly onRightClick?: (\n target: HitTarget<TItem, TContentVisual, TClusterVisual, TTagMeta, TClusterMeta>,\n rawEvent: NormalizedPointerEvent,\n ) => boolean | void;\n readonly onWheel?: WheelBehavior;\n readonly onMetricsChange?: (metrics: LayoutMetrics) => void;\n readonly onClustersChange?: (\n clusters: readonly ClusterDescriptor<TItem, TTagMeta, TClusterMeta>[],\n ) => void;\n readonly onFpsUpdate?: (fps: number) => void;\n readonly controllerRef?: MutableRefObject<SimplexSvgController<\n TItem,\n TContentVisual,\n TClusterVisual,\n TTagMeta,\n TClusterMeta\n > | null>;\n readonly className?: string;\n readonly style?: CSSProperties;\n };\n\ninterface AutoKeyVisual {\n readonly __svAutoKey: string;\n}\n\nfunction isAutoKeyVisual(v: unknown): v is AutoKeyVisual {\n return (\n typeof v === 'object' &&\n v !== null &&\n '__svAutoKey' in v &&\n typeof (v as AutoKeyVisual).__svAutoKey === 'string'\n );\n}\n\n/**\n * Type-safe React visualization component wrapping `@simplex-viz/core` and `@simplex-viz/svg`.\n */\nexport function SimplexTopicGraph<\n TItem = DefaultTaggedItem,\n TContentVisual = DefaultContentPresetVisual,\n TClusterVisual = DefaultClusterPresetVisual,\n TTagMeta = undefined,\n TClusterMeta = undefined,\n>(\n props: SimplexTopicGraphProps<\n TItem,\n TContentVisual,\n TClusterVisual,\n TTagMeta,\n TClusterMeta\n >,\n) {\n const containerRef = useRef<HTMLDivElement | null>(null);\n const ctrlRef = useRef<SimplexSvgController<\n TItem,\n TContentVisual,\n TClusterVisual,\n TTagMeta,\n TClusterMeta\n > | null>(null);\n\n const [hoveredTarget, setHoveredTarget] = useState<SimplexReactTooltipTarget<\n TItem,\n TContentVisual,\n TClusterVisual,\n TTagMeta,\n TClusterMeta\n > | null>(null);\n\n const internalFocusedUidRef = useRef<string | null>(null);\n\n const contentDomainByKeyRef = useRef(\n new Map<string, ContentDomainRecord<TItem, TTagMeta, TClusterMeta>>(),\n );\n const clusterDomainByKeyRef = useRef(\n new Map<string, ClusterDescriptor<TItem, TTagMeta, TClusterMeta>>(),\n );\n const jsxContentViewRef = useRef<ReactJsxSvgView<\n TContentVisual,\n ContentDomainRecord<TItem, TTagMeta, TClusterMeta>\n > | null>(null);\n const jsxClusterViewRef = useRef<ReactJsxSvgView<\n TClusterVisual,\n ClusterDescriptor<TItem, TTagMeta, TClusterMeta>\n > | null>(null);\n\n const latestPropsRef = useRef(props);\n latestPropsRef.current = props;\n\n const resolveEffectiveResolver = (): VisualResolver<\n TItem,\n TContentVisual,\n TClusterVisual,\n TTagMeta,\n TClusterMeta\n > => {\n const p = latestPropsRef.current;\n const preset: SimplexVisualPreset = p.preset ?? 'geometric';\n const presetResolver = createPresetVisualResolver<TItem, TTagMeta, TClusterMeta>(\n preset,\n (item) => {\n const curGetLabel = latestPropsRef.current.getLabel;\n if (curGetLabel) return curGetLabel(item);\n if (typeof item === 'object' && item !== null) {\n if ('label' in item && typeof item.label === 'string' && item.label.length > 0) {\n return item.label;\n }\n if ('title' in item && typeof item.title === 'string' && item.title.length > 0) {\n return item.title;\n }\n if ('headline' in item && typeof item.headline === 'string' && item.headline.length > 0) {\n return item.headline;\n }\n if ('name' in item && typeof item.name === 'string' && item.name.length > 0) {\n return item.name;\n }\n }\n return '';\n },\n );\n const base = p.visualResolver;\n\n const getKey = (visual: TContentVisual | TClusterVisual): string => {\n if (isAutoKeyVisual(visual)) {\n return visual.__svAutoKey;\n }\n if (base) {\n return base.getVisualCacheKey(visual);\n }\n return presetResolver.getVisualCacheKey(\n visual as unknown as DefaultContentPresetVisual | DefaultClusterPresetVisual,\n );\n };\n\n return {\n resolveContentVisual: (item, ctx) => {\n const cur = latestPropsRef.current;\n let visual: TContentVisual;\n if (base) {\n visual = base.resolveContentVisual(item, ctx);\n } else if (cur.renderContentNode) {\n const autoKey = cur.getContentCacheKey\n ? cur.getContentCacheKey(item, ctx)\n : `${ctx.id}:${ctx.mixedColorHex}:${ctx.tags.map((t) => t.tag).join(',')}`;\n visual = { __svAutoKey: autoKey } as unknown as TContentVisual;\n } else {\n visual = presetResolver.resolveContentVisual(item, ctx) as unknown as TContentVisual;\n }\n const key = getKey(visual);\n contentDomainByKeyRef.current.set(key, { item, ctx });\n return visual;\n },\n resolveClusterVisual: (cluster) => {\n const cur = latestPropsRef.current;\n let visual: TClusterVisual;\n if (base) {\n visual = base.resolveClusterVisual(cluster);\n } else if (cur.renderClusterNode) {\n const autoKey = cur.getClusterCacheKey\n ? cur.getClusterCacheKey(cluster)\n : `${cluster.clusterUid}:${cluster.defaultLabel}:${cluster.members.length}:${cluster.colorHex}`;\n visual = { __svAutoKey: autoKey } as unknown as TClusterVisual;\n } else {\n visual = presetResolver.resolveClusterVisual(cluster) as unknown as TClusterVisual;\n }\n const key = getKey(visual);\n clusterDomainByKeyRef.current.set(key, cluster);\n return visual;\n },\n getVisualCacheKey: getKey,\n };\n };\n\n const resolveActiveViews = (\n activeResolver: VisualResolver<\n TItem,\n TContentVisual,\n TClusterVisual,\n TTagMeta,\n TClusterMeta\n >,\n ): {\n contentView: SvgNodeView<TContentVisual>;\n clusterView: SvgNodeView<TClusterVisual>;\n } => {\n const p = latestPropsRef.current;\n const presetViews = createPresetViews(p.preset ?? 'geometric');\n\n let contentView: SvgNodeView<TContentVisual>;\n if (p.renderContentNode) {\n const renderFn = p.renderContentNode;\n jsxContentViewRef.current?.dispose();\n const jsxView = new ReactJsxSvgView<\n TContentVisual,\n ContentDomainRecord<TItem, TTagMeta, TClusterMeta>\n >({\n renderFn: (domain, state) => renderFn(domain.item, domain.ctx, state),\n getKey: (v) => activeResolver.getVisualCacheKey(v),\n domainByKey: contentDomainByKeyRef.current,\n });\n jsxContentViewRef.current = jsxView;\n contentView = jsxView;\n } else if (p.contentView) {\n jsxContentViewRef.current?.dispose();\n jsxContentViewRef.current = null;\n contentView = p.contentView;\n } else {\n jsxContentViewRef.current?.dispose();\n jsxContentViewRef.current = null;\n contentView = presetViews.contentView as unknown as SvgNodeView<TContentVisual>;\n }\n\n let clusterView: SvgNodeView<TClusterVisual>;\n if (p.renderClusterNode) {\n const renderFn = p.renderClusterNode;\n jsxClusterViewRef.current?.dispose();\n const jsxView = new ReactJsxSvgView<\n TClusterVisual,\n ClusterDescriptor<TItem, TTagMeta, TClusterMeta>\n >({\n renderFn: (cluster, state) => renderFn(cluster, state),\n getKey: (v) => activeResolver.getVisualCacheKey(v),\n domainByKey: clusterDomainByKeyRef.current,\n });\n jsxClusterViewRef.current = jsxView;\n clusterView = jsxView;\n } else if (p.clusterView) {\n jsxClusterViewRef.current?.dispose();\n jsxClusterViewRef.current = null;\n clusterView = p.clusterView;\n } else {\n jsxClusterViewRef.current?.dispose();\n jsxClusterViewRef.current = null;\n clusterView = presetViews.clusterView as unknown as SvgNodeView<TClusterVisual>;\n }\n\n return { contentView, clusterView };\n };\n\n // Mount controller once on container\n useEffect(() => {\n const el = containerRef.current;\n if (!el) return;\n\n const p = latestPropsRef.current;\n const effectiveResolver = resolveEffectiveResolver();\n const { contentView, clusterView } = resolveActiveViews(effectiveResolver);\n\n const ctrl = SimplexSvgController.createFromResolved(el, {\n items: p.items,\n getId: p.getId,\n getTags: p.getTags,\n getLabel: p.getLabel,\n deriveClusterMeta: p.deriveClusterMeta,\n preset: p.preset,\n visualResolver: effectiveResolver,\n contentView,\n clusterView,\n normalizeTag: p.normalizeTag,\n resolveTagMeta: p.resolveTagMeta,\n meshOptions: p.meshOptions,\n layoutOptions: {\n ...p.layoutOptions,\n sizeMultiplier: p.sizeMultiplier ?? p.layoutOptions?.sizeMultiplier ?? 1,\n },\n showHulls: p.showHulls,\n focusOnClusterClick: false,\n interactions: {\n onContentHover: (ev) => {\n latestPropsRef.current.onContentHover?.(ev);\n if (latestPropsRef.current.tooltip) {\n setHoveredTarget(ev ? { kind: 'content', ...ev } : null);\n }\n },\n onClusterHover: (ev) => {\n latestPropsRef.current.onClusterHover?.(ev);\n if (latestPropsRef.current.tooltip) {\n setHoveredTarget(ev ? { kind: 'cluster', ...ev } : null);\n }\n },\n onLeftClick: (target, raw) => {\n const cur = latestPropsRef.current;\n if (cur.onLeftClick) {\n cur.onLeftClick(target, raw);\n return;\n }\n if (cur.focusedClusterUid === undefined && (cur.focusOnClusterClick ?? true)) {\n if (target.kind === 'cluster') {\n const next =\n internalFocusedUidRef.current === target.cluster.clusterUid\n ? null\n : target.cluster.clusterUid;\n internalFocusedUidRef.current = next;\n ctrlRef.current?.setFocusedClusterUid(next);\n } else if (\n target.kind === 'background' &&\n internalFocusedUidRef.current !== null\n ) {\n internalFocusedUidRef.current = null;\n ctrlRef.current?.setFocusedClusterUid(null);\n }\n }\n },\n onRightClick: (t, raw) => latestPropsRef.current.onRightClick?.(t, raw),\n onWheel: (ev, cam) => {\n const policy = latestPropsRef.current.onWheel ?? 'zoom-to-cursor';\n if (policy === 'none') return;\n if (typeof policy === 'function') {\n policy(ev, cam);\n return;\n }\n if (policy === 'pan-vertical') {\n cam.panBy(-ev.deltaX, -ev.deltaY);\n return;\n }\n const factor = Math.exp(-ev.deltaY * 0.0014);\n cam.zoomToCursor(ev.screenX, ev.screenY, factor);\n },\n },\n onMetricsChange: (m) => latestPropsRef.current.onMetricsChange?.(m),\n onClustersChange: (c) => latestPropsRef.current.onClustersChange?.(c),\n onFpsUpdate: (fps) => latestPropsRef.current.onFpsUpdate?.(fps),\n });\n ctrlRef.current = ctrl;\n if (p.controllerRef) {\n p.controllerRef.current = ctrl;\n }\n\n return () => {\n ctrl.destroy();\n ctrlRef.current = null;\n if (latestPropsRef.current.controllerRef) {\n latestPropsRef.current.controllerRef.current = null;\n }\n jsxContentViewRef.current?.dispose();\n jsxClusterViewRef.current?.dispose();\n jsxContentViewRef.current = null;\n jsxClusterViewRef.current = null;\n };\n }, []);\n\n // Sync items\n useEffect(() => {\n ctrlRef.current?.setItems(props.items);\n }, [props.items]);\n\n // Sync views, presets & visual resolver (triggers smooth crossfade / morph!)\n useEffect(() => {\n const ctrl = ctrlRef.current;\n if (!ctrl) return;\n const effectiveResolver = resolveEffectiveResolver();\n const { contentView, clusterView } = resolveActiveViews(effectiveResolver);\n ctrl.setViews({ contentView, clusterView });\n ctrl.setVisualResolver(effectiveResolver);\n }, [\n props.preset,\n props.visualResolver,\n props.contentView,\n props.clusterView,\n props.renderContentNode,\n props.renderClusterNode,\n ]);\n\n // Sync sizeMultiplier\n useEffect(() => {\n if (props.sizeMultiplier !== undefined) {\n ctrlRef.current?.setSizeMultiplier(props.sizeMultiplier);\n }\n }, [props.sizeMultiplier]);\n\n // Sync showHulls\n useEffect(() => {\n if (props.showHulls !== undefined) {\n ctrlRef.current?.setShowHulls(props.showHulls);\n }\n }, [props.showHulls]);\n\n // Sync pinned / highlighted / focused cluster\n useEffect(() => {\n if (props.pinnedIds !== undefined) {\n ctrlRef.current?.setPinnedIds(props.pinnedIds);\n }\n }, [props.pinnedIds]);\n\n useEffect(() => {\n if (props.highlightedIds !== undefined) {\n ctrlRef.current?.setHighlightedIds(props.highlightedIds);\n }\n }, [props.highlightedIds]);\n\n useEffect(() => {\n if (props.focusedClusterUid !== undefined) {\n internalFocusedUidRef.current = props.focusedClusterUid;\n ctrlRef.current?.setFocusedClusterUid(props.focusedClusterUid);\n }\n }, [props.focusedClusterUid]);\n\n // Clear built-in tooltip if prop toggled off\n useEffect(() => {\n if (!props.tooltip) {\n setHoveredTarget(null);\n }\n }, [props.tooltip]);\n\n const renderBuiltInTooltip = () => {\n if (!props.tooltip || !hoveredTarget) return null;\n\n const containerW = containerRef.current?.clientWidth || 960;\n const containerH = containerRef.current?.clientHeight || 600;\n const left = Math.min(\n Math.max(8, Math.round(hoveredTarget.screenPosition.x + 14)),\n Math.max(8, containerW - 256),\n );\n const top = Math.min(\n Math.max(8, Math.round(hoveredTarget.screenPosition.y + 14)),\n Math.max(8, containerH - 80),\n );\n\n const content =\n typeof props.tooltip === 'function' ? (\n props.tooltip(hoveredTarget)\n ) : hoveredTarget.kind === 'content' ? (\n <div>\n <div style={{ fontWeight: 600, color: '#f8fafc' }}>\n {extractDefaultItemLabel(\n hoveredTarget.item,\n hoveredTarget.layoutContext.id,\n props.getLabel,\n )}\n </div>\n {hoveredTarget.layoutContext.tags.length > 0 && (\n <div style={{ marginTop: 3, fontSize: 11, color: '#94a3b8' }}>\n {hoveredTarget.layoutContext.tags\n .map((t) => `#${t.tag}`)\n .slice(0, 5)\n .join(' · ')}\n </div>\n )}\n </div>\n ) : (\n <div>\n <div style={{ fontWeight: 600, color: hoveredTarget.cluster.colorHex }}>\n {`${hoveredTarget.cluster.code} · ${hoveredTarget.cluster.defaultLabel}`}\n </div>\n <div style={{ marginTop: 3, fontSize: 11, color: '#94a3b8' }}>\n {`${hoveredTarget.cluster.members.length} ${\n hoveredTarget.cluster.members.length === 1 ? 'item' : 'items'\n }`}\n </div>\n </div>\n );\n\n return (\n <div\n role=\"tooltip\"\n style={{\n position: 'absolute',\n left,\n top,\n zIndex: 20,\n maxWidth: 244,\n padding: '7px 10px',\n borderRadius: 8,\n background: 'rgba(9, 13, 22, 0.94)',\n border: '1px solid rgba(51, 65, 85, 0.85)',\n color: '#f1f5f9',\n fontSize: 12,\n lineHeight: 1.4,\n pointerEvents: 'none',\n boxShadow: '0 10px 24px rgba(0, 0, 0, 0.45)',\n }}\n >\n {content}\n </div>\n );\n };\n\n return (\n <div\n ref={containerRef}\n className={props.className}\n style={{\n position: 'relative',\n width: '100%',\n height: '100%',\n overflow: 'hidden',\n ...props.style,\n }}\n >\n {renderBuiltInTooltip()}\n </div>\n );\n}\n"]}
1
+ {"version":3,"sources":["../src/ReactJsxSvgView.ts","../src/useSimplexGraphController.ts","../src/SimplexTopicGraph.tsx"],"names":["jsx","useRef"],"mappings":"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","file":"index.js","sourcesContent":["import {\n rectToConvexPolygon,\n type ClusterDescriptor,\n type ContentLayoutContext,\n type ConvexGeometry,\n type NodeRenderState,\n} from '@simplex-viz/core';\nimport { SVG_NS, type SvgNodeView } from '@simplex-viz/svg';\nimport type { ReactNode } from 'react';\nimport { createRoot, type Root } from 'react-dom/client';\nimport { renderToStaticMarkup } from 'react-dom/server';\n\nexport interface ContentDomainRecord<TItem, TTagMeta, TClusterMeta> {\n readonly item: TItem;\n readonly ctx: ContentLayoutContext<TItem, TTagMeta, TClusterMeta>;\n}\n\n/**\n * Bridges a declarative React JSX render function into an `@simplex-viz/svg` `SvgNodeView`\n * with automatic offscreen `getBBox()` convex hull measurement and cached DOM updates.\n */\nexport class ReactJsxSvgView<TVisual, TDomain> implements SvgNodeView<TVisual> {\n private readonly renderFn: (\n domain: TDomain,\n state: NodeRenderState<TVisual>,\n ) => ReactNode;\n private readonly getKey: (visual: TVisual) => string;\n private readonly domainByKey: ReadonlyMap<string, TDomain>;\n private readonly rootsByGroup = new WeakMap<SVGGElement, Root>();\n private readonly activeRoots = new Set<Root>();\n private measureGroup: SVGGElement | null = null;\n\n constructor(params: {\n readonly renderFn: (domain: TDomain, state: NodeRenderState<TVisual>) => ReactNode;\n readonly getKey: (visual: TVisual) => string;\n readonly domainByKey: ReadonlyMap<string, TDomain>;\n }) {\n this.renderFn = params.renderFn;\n this.getKey = params.getKey;\n this.domainByKey = params.domainByKey;\n }\n\n measureConvexHull(visual: TVisual, measureSvg: SVGSVGElement): ConvexGeometry {\n const key = this.getKey(visual);\n const domain = this.domainByKey.get(key);\n if (!domain) {\n return rectToConvexPolygon(48, 28, 6);\n }\n\n const doc = measureSvg.ownerDocument;\n let bin = measureSvg.querySelector<SVGGElement>('g.sv-measure-bin');\n if (!bin) {\n bin = doc.createElementNS(SVG_NS, 'g');\n bin.setAttribute('class', 'sv-measure-bin');\n bin.setAttribute('visibility', 'hidden');\n bin.setAttribute('pointer-events', 'none');\n bin.setAttribute('transform', 'translate(-99999, -99999)');\n measureSvg.appendChild(bin);\n }\n\n if (!this.measureGroup || this.measureGroup.parentNode !== bin) {\n this.measureGroup = doc.createElementNS(SVG_NS, 'g');\n bin.appendChild(this.measureGroup);\n }\n\n const dummyState: NodeRenderState<TVisual> = {\n id: '__measure__',\n x: 0,\n y: 0,\n scale: 1,\n opacity: 1,\n visual,\n hull: { kind: 'circle', radius: 16 },\n cacheKey: key,\n interaction: {\n isHovered: false,\n isPinned: false,\n isDimmed: false,\n isHighlighted: false,\n },\n transition: null,\n };\n\n const jsx = this.renderFn(domain, dummyState);\n const markup = renderToStaticMarkup(jsx);\n // Parse JSX markup into SVG namespace inside the offscreen measurement group\n const wrapperSvg = doc.createElementNS(SVG_NS, 'svg');\n wrapperSvg.innerHTML = markup;\n while (this.measureGroup.firstChild) {\n this.measureGroup.removeChild(this.measureGroup.firstChild);\n }\n while (wrapperSvg.firstChild) {\n this.measureGroup.appendChild(wrapperSvg.firstChild);\n }\n\n let width = 0;\n let height = 0;\n try {\n if (typeof this.measureGroup.getBBox === 'function') {\n const bbox = this.measureGroup.getBBox();\n width = bbox.width;\n height = bbox.height;\n }\n } catch {\n // Headless DOM without layout engine\n }\n\n if (width <= 1 || height <= 1) {\n let maxHalfW = 0;\n let maxHalfH = 0;\n this.measureGroup.querySelectorAll('rect, circle, text').forEach((el) => {\n const tag = el.tagName.toLowerCase();\n if (tag === 'rect') {\n const w = parseFloat(el.getAttribute('width') ?? '0');\n const h = parseFloat(el.getAttribute('height') ?? '0');\n maxHalfW = Math.max(maxHalfW, w / 2);\n maxHalfH = Math.max(maxHalfH, h / 2);\n } else if (tag === 'circle') {\n const r = parseFloat(el.getAttribute('r') ?? '0');\n maxHalfW = Math.max(maxHalfW, r);\n maxHalfH = Math.max(maxHalfH, r);\n } else if (tag === 'text') {\n const len = (el.textContent ?? '').length;\n const fs = parseFloat(el.getAttribute('font-size') ?? '11');\n maxHalfW = Math.max(maxHalfW, (len * fs * 0.56) / 2);\n maxHalfH = Math.max(maxHalfH, fs * 0.75);\n }\n });\n width = Math.max(24, maxHalfW * 2);\n height = Math.max(20, maxHalfH * 2);\n }\n\n return rectToConvexPolygon(width + 4, height + 4, 6);\n }\n\n mountOrUpdate(\n groupEl: SVGGElement,\n visual: TVisual,\n state: NodeRenderState<TVisual>,\n ): void {\n const key = this.getKey(visual);\n const domain = this.domainByKey.get(key);\n if (!domain) return;\n\n let root = this.rootsByGroup.get(groupEl);\n if (!root) {\n while (groupEl.firstChild) groupEl.removeChild(groupEl.firstChild);\n root = createRoot(groupEl);\n this.rootsByGroup.set(groupEl, root);\n this.activeRoots.add(root);\n }\n\n root.render(this.renderFn(domain, state));\n }\n\n dispose(): void {\n const roots = [...this.activeRoots];\n this.activeRoots.clear();\n this.measureGroup = null;\n queueMicrotask(() => {\n for (const r of roots) {\n r.unmount();\n }\n });\n }\n}\n\nexport type ContentJsxRenderFn<TItem, TContentVisual, TTagMeta, TClusterMeta> = (\n item: TItem,\n ctx: ContentLayoutContext<TItem, TTagMeta, TClusterMeta>,\n state: NodeRenderState<TContentVisual>,\n) => ReactNode;\n\nexport type ClusterJsxRenderFn<TItem, TClusterVisual, TTagMeta, TClusterMeta> = (\n cluster: ClusterDescriptor<TItem, TTagMeta, TClusterMeta>,\n state: NodeRenderState<TClusterVisual>,\n) => ReactNode;\n","import type {\n CameraController,\n ClusterDescriptor,\n DefaultTaggedItem,\n LayoutMetrics,\n} from '@simplex-viz/core';\nimport type { SimplexSvgController } from '@simplex-viz/svg';\nimport { useCallback, useRef } from 'react';\n\n/**\n * Imperative handle bound to `<SimplexTopicGraph controllerRef={...} />`.\n */\nexport interface SimplexGraphHandle<\n TItem = DefaultTaggedItem,\n TContentVisual = unknown,\n TClusterVisual = unknown,\n TTagMeta = undefined,\n TClusterMeta = undefined,\n> {\n addItems(items: TItem | readonly TItem[]): void;\n removeItems(ids: string | readonly string[]): void;\n setItems(items: readonly TItem[]): void;\n resetCamera(): void;\n zoomBy(factor: number): void;\n getMetrics(): LayoutMetrics | null;\n getClusters(): readonly ClusterDescriptor<TItem, TTagMeta, TClusterMeta>[];\n getRawController(): SimplexSvgController<\n TItem,\n TContentVisual,\n TClusterVisual,\n TTagMeta,\n TClusterMeta\n > | null;\n}\n\n/**\n * React hook returning a stable `controllerRef` and imperative transaction helpers\n * (`addItems`, `removeItems`, `setItems`, camera controls, and live telemetry getters).\n */\nexport function useSimplexGraphController<\n TItem = DefaultTaggedItem,\n TContentVisual = unknown,\n TClusterVisual = unknown,\n TTagMeta = undefined,\n TClusterMeta = undefined,\n>(): {\n readonly controllerRef: React.MutableRefObject<SimplexSvgController<\n TItem,\n TContentVisual,\n TClusterVisual,\n TTagMeta,\n TClusterMeta\n > | null>;\n readonly handle: SimplexGraphHandle<\n TItem,\n TContentVisual,\n TClusterVisual,\n TTagMeta,\n TClusterMeta\n >;\n} {\n const controllerRef = useRef<SimplexSvgController<\n TItem,\n TContentVisual,\n TClusterVisual,\n TTagMeta,\n TClusterMeta\n > | null>(null);\n\n const addItems = useCallback((items: TItem | readonly TItem[]) => {\n controllerRef.current?.addItems(items);\n }, []);\n\n const removeItems = useCallback((ids: string | readonly string[]) => {\n controllerRef.current?.removeItems(ids);\n }, []);\n\n const setItems = useCallback((items: readonly TItem[]) => {\n controllerRef.current?.setItems(items);\n }, []);\n\n const resetCamera = useCallback(() => {\n controllerRef.current?.camera.reset();\n }, []);\n\n const zoomBy = useCallback((factor: number) => {\n const ctrl = controllerRef.current;\n if (!ctrl) return;\n const svg = ctrl.getSvgElement();\n const rect = svg.getBoundingClientRect();\n const cam: CameraController = ctrl.camera;\n cam.zoomToCursor(rect.width / 2, rect.height / 2, factor);\n }, []);\n\n const getMetrics = useCallback(() => {\n return controllerRef.current?.getMetrics() ?? null;\n }, []);\n\n const getClusters = useCallback(() => {\n return controllerRef.current?.getClusters() ?? [];\n }, []);\n\n const getRawController = useCallback(() => {\n return controllerRef.current;\n }, []);\n\n return {\n controllerRef,\n handle: {\n addItems,\n removeItems,\n setItems,\n resetCamera,\n zoomBy,\n getMetrics,\n getClusters,\n getRawController,\n },\n };\n}\n","import type {\n ClusterDescriptor,\n ClusterHoverEvent,\n ClusterMetaConfig,\n ContentHoverEvent,\n ContentLayoutContext,\n DefaultTaggedItem,\n HitTarget,\n ItemIdentityConfig,\n LayoutMetrics,\n LayoutSolverOptions,\n MeshOptions,\n NodeRenderState,\n NormalizedPointerEvent,\n VisualResolver,\n WheelBehavior,\n} from '@simplex-viz/core';\nimport {\n SimplexSvgController,\n createPresetViews,\n createPresetVisualResolver,\n extractDefaultItemLabel,\n type DefaultClusterPresetVisual,\n type DefaultContentPresetVisual,\n type SimplexTheme,\n type SimplexVisualPreset,\n type SvgNodeView,\n} from '@simplex-viz/svg';\nimport {\n useEffect,\n useRef,\n useState,\n type CSSProperties,\n type MutableRefObject,\n type ReactNode,\n} from 'react';\nimport {\n ReactJsxSvgView,\n type ContentDomainRecord,\n} from './ReactJsxSvgView';\n\n/**\n * Union payload passed to a custom React `tooltip` formatter on `<SimplexTopicGraph />`.\n */\nexport type SimplexReactTooltipTarget<\n TItem = DefaultTaggedItem,\n TContentVisual = DefaultContentPresetVisual,\n TClusterVisual = DefaultClusterPresetVisual,\n TTagMeta = undefined,\n TClusterMeta = undefined,\n> =\n | ({ readonly kind: 'content' } & ContentHoverEvent<\n TItem,\n TContentVisual,\n TTagMeta,\n TClusterMeta\n >)\n | ({ readonly kind: 'cluster' } & ClusterHoverEvent<\n TItem,\n TClusterVisual,\n TTagMeta,\n TClusterMeta\n >);\n\n/**\n * Props for `<SimplexTopicGraph />`, preserving end-to-end generic inference across\n * `TItem`, `TContentVisual`, `TClusterVisual`, `TTagMeta`, and `TClusterMeta`.\n *\n * Works zero-config with `<SimplexTopicGraph items={items} />` via built-in presets,\n * or with keyless declarative JSX renderers (`renderContentNode` / `renderClusterNode`),\n * or with full `VisualResolver` + `SvgNodeView` customization.\n */\nexport type SimplexTopicGraphProps<\n TItem = DefaultTaggedItem,\n TContentVisual = DefaultContentPresetVisual,\n TClusterVisual = DefaultClusterPresetVisual,\n TTagMeta = undefined,\n TClusterMeta = undefined,\n> = ItemIdentityConfig<TItem> &\n ClusterMetaConfig<TItem, TTagMeta, TClusterMeta> & {\n readonly items: readonly TItem[];\n /** Built-in visual preset used when custom views / `visualResolver` are omitted. Default: `'geometric'`. */\n readonly preset?: SimplexVisualPreset;\n /** Visual color theme (`'dark'` or `'light'`) for built-in presets and tooltips. Default: `'dark'`. */\n readonly theme?: SimplexTheme;\n /** Optional label extractor for built-in presets and default hover tooltips. */\n readonly getLabel?: (item: TItem) => string;\n /**\n * Optional `VisualResolver` mapping items and clusters to pure visual descriptors.\n * Optional in both zero-config preset mode and declarative JSX renderer mode.\n */\n readonly visualResolver?: VisualResolver<\n TItem,\n TContentVisual,\n TClusterVisual,\n TTagMeta,\n TClusterMeta\n >;\n /** Optional cache key override when using `renderContentNode` without `visualResolver`. */\n readonly getContentCacheKey?: (\n item: TItem,\n ctx: ContentLayoutContext<TItem, TTagMeta, TClusterMeta>,\n ) => string;\n /** Optional cache key override when using `renderClusterNode` without `visualResolver`. */\n readonly getClusterCacheKey?: (\n cluster: ClusterDescriptor<TItem, TTagMeta, TClusterMeta>,\n ) => string;\n /** Portable `@simplex-viz/svg` view plugin for content items. */\n readonly contentView?: SvgNodeView<TContentVisual>;\n /** Portable `@simplex-viz/svg` view plugin for topic clusters. */\n readonly clusterView?: SvgNodeView<TClusterVisual>;\n /** Optional declarative React JSX renderer for content items (auto-measured via `getBBox()`). */\n readonly renderContentNode?: (\n item: TItem,\n ctx: ContentLayoutContext<TItem, TTagMeta, TClusterMeta>,\n state: NodeRenderState<TContentVisual>,\n ) => ReactNode;\n /** Optional declarative React JSX renderer for topic clusters (auto-measured via `getBBox()`). */\n readonly renderClusterNode?: (\n cluster: ClusterDescriptor<TItem, TTagMeta, TClusterMeta>,\n state: NodeRenderState<TClusterVisual>,\n ) => ReactNode;\n readonly normalizeTag?: (rawTag: string) => string;\n readonly resolveTagMeta?: (normalizedTag: string) => TTagMeta | undefined;\n readonly meshOptions?: MeshOptions;\n readonly layoutOptions?: LayoutSolverOptions;\n readonly sizeMultiplier?: number;\n readonly showHulls?: boolean;\n readonly pinnedIds?: ReadonlySet<string> | readonly string[];\n readonly highlightedIds?: ReadonlySet<string> | readonly string[];\n readonly focusedClusterUid?: string | null;\n /**\n * Enables built-in cluster focus toggle on click when `focusedClusterUid` and `onLeftClick`\n * are not controlled externally. Default: `true`.\n */\n readonly focusOnClusterClick?: boolean;\n /**\n * Enables a built-in floating hover tooltip, or accepts a custom `(target) => ReactNode` formatter.\n * Default: `false`.\n */\n readonly tooltip?:\n | boolean\n | ((\n target: SimplexReactTooltipTarget<\n TItem,\n TContentVisual,\n TClusterVisual,\n TTagMeta,\n TClusterMeta\n >,\n ) => ReactNode);\n readonly onContentHover?: (\n event: ContentHoverEvent<TItem, TContentVisual, TTagMeta, TClusterMeta> | null,\n ) => void;\n readonly onClusterHover?: (\n event: ClusterHoverEvent<TItem, TClusterVisual, TTagMeta, TClusterMeta> | null,\n ) => void;\n readonly onLeftClick?: (\n target: HitTarget<TItem, TContentVisual, TClusterVisual, TTagMeta, TClusterMeta>,\n rawEvent: NormalizedPointerEvent,\n ) => void;\n readonly onRightClick?: (\n target: HitTarget<TItem, TContentVisual, TClusterVisual, TTagMeta, TClusterMeta>,\n rawEvent: NormalizedPointerEvent,\n ) => boolean | void;\n readonly onWheel?: WheelBehavior;\n readonly onMetricsChange?: (metrics: LayoutMetrics) => void;\n readonly onClustersChange?: (\n clusters: readonly ClusterDescriptor<TItem, TTagMeta, TClusterMeta>[],\n ) => void;\n readonly onFpsUpdate?: (fps: number) => void;\n readonly controllerRef?: MutableRefObject<SimplexSvgController<\n TItem,\n TContentVisual,\n TClusterVisual,\n TTagMeta,\n TClusterMeta\n > | null>;\n readonly className?: string;\n readonly style?: CSSProperties;\n };\n\ninterface AutoKeyVisual {\n readonly __svAutoKey: string;\n}\n\nfunction isAutoKeyVisual(v: unknown): v is AutoKeyVisual {\n return (\n typeof v === 'object' &&\n v !== null &&\n '__svAutoKey' in v &&\n typeof (v as AutoKeyVisual).__svAutoKey === 'string'\n );\n}\n\n/**\n * Type-safe React visualization component wrapping `@simplex-viz/core` and `@simplex-viz/svg`.\n */\nexport function SimplexTopicGraph<\n TItem = DefaultTaggedItem,\n TContentVisual = DefaultContentPresetVisual,\n TClusterVisual = DefaultClusterPresetVisual,\n TTagMeta = undefined,\n TClusterMeta = undefined,\n>(\n props: SimplexTopicGraphProps<\n TItem,\n TContentVisual,\n TClusterVisual,\n TTagMeta,\n TClusterMeta\n >,\n) {\n const containerRef = useRef<HTMLDivElement | null>(null);\n const ctrlRef = useRef<SimplexSvgController<\n TItem,\n TContentVisual,\n TClusterVisual,\n TTagMeta,\n TClusterMeta\n > | null>(null);\n\n const [hoveredTarget, setHoveredTarget] = useState<SimplexReactTooltipTarget<\n TItem,\n TContentVisual,\n TClusterVisual,\n TTagMeta,\n TClusterMeta\n > | null>(null);\n\n const internalFocusedUidRef = useRef<string | null>(null);\n\n const contentDomainByKeyRef = useRef(\n new Map<string, ContentDomainRecord<TItem, TTagMeta, TClusterMeta>>(),\n );\n const clusterDomainByKeyRef = useRef(\n new Map<string, ClusterDescriptor<TItem, TTagMeta, TClusterMeta>>(),\n );\n const jsxContentViewRef = useRef<ReactJsxSvgView<\n TContentVisual,\n ContentDomainRecord<TItem, TTagMeta, TClusterMeta>\n > | null>(null);\n const jsxClusterViewRef = useRef<ReactJsxSvgView<\n TClusterVisual,\n ClusterDescriptor<TItem, TTagMeta, TClusterMeta>\n > | null>(null);\n\n const latestPropsRef = useRef(props);\n latestPropsRef.current = props;\n\n const resolveEffectiveResolver = (): VisualResolver<\n TItem,\n TContentVisual,\n TClusterVisual,\n TTagMeta,\n TClusterMeta\n > => {\n const p = latestPropsRef.current;\n const preset: SimplexVisualPreset = p.preset ?? 'geometric';\n const theme: SimplexTheme = p.theme ?? 'dark';\n const presetResolver = createPresetVisualResolver<TItem, TTagMeta, TClusterMeta>(\n preset,\n (item) => {\n const curGetLabel = latestPropsRef.current.getLabel;\n if (curGetLabel) return curGetLabel(item);\n if (typeof item === 'object' && item !== null) {\n if ('label' in item && typeof item.label === 'string' && item.label.length > 0) {\n return item.label;\n }\n if ('title' in item && typeof item.title === 'string' && item.title.length > 0) {\n return item.title;\n }\n if ('headline' in item && typeof item.headline === 'string' && item.headline.length > 0) {\n return item.headline;\n }\n if ('name' in item && typeof item.name === 'string' && item.name.length > 0) {\n return item.name;\n }\n }\n return '';\n },\n theme,\n );\n const base = p.visualResolver;\n\n const getKey = (visual: TContentVisual | TClusterVisual): string => {\n if (isAutoKeyVisual(visual)) {\n return visual.__svAutoKey;\n }\n if (base) {\n return base.getVisualCacheKey(visual);\n }\n return presetResolver.getVisualCacheKey(\n visual as unknown as DefaultContentPresetVisual | DefaultClusterPresetVisual,\n );\n };\n\n return {\n resolveContentVisual: (item, ctx) => {\n const cur = latestPropsRef.current;\n let visual: TContentVisual;\n if (base) {\n visual = base.resolveContentVisual(item, ctx);\n } else if (cur.renderContentNode) {\n const autoKey = cur.getContentCacheKey\n ? cur.getContentCacheKey(item, ctx)\n : `${ctx.id}:${ctx.mixedColorHex}:${ctx.tags.map((t) => t.tag).join(',')}`;\n visual = { __svAutoKey: autoKey } as unknown as TContentVisual;\n } else {\n visual = presetResolver.resolveContentVisual(item, ctx) as unknown as TContentVisual;\n }\n const key = getKey(visual);\n contentDomainByKeyRef.current.set(key, { item, ctx });\n return visual;\n },\n resolveClusterVisual: (cluster) => {\n const cur = latestPropsRef.current;\n let visual: TClusterVisual;\n if (base) {\n visual = base.resolveClusterVisual(cluster);\n } else if (cur.renderClusterNode) {\n const autoKey = cur.getClusterCacheKey\n ? cur.getClusterCacheKey(cluster)\n : `${cluster.clusterUid}:${cluster.defaultLabel}:${cluster.members.length}:${cluster.colorHex}`;\n visual = { __svAutoKey: autoKey } as unknown as TClusterVisual;\n } else {\n visual = presetResolver.resolveClusterVisual(cluster) as unknown as TClusterVisual;\n }\n const key = getKey(visual);\n clusterDomainByKeyRef.current.set(key, cluster);\n return visual;\n },\n getVisualCacheKey: getKey,\n };\n };\n\n const resolveActiveViews = (\n activeResolver: VisualResolver<\n TItem,\n TContentVisual,\n TClusterVisual,\n TTagMeta,\n TClusterMeta\n >,\n ): {\n contentView: SvgNodeView<TContentVisual>;\n clusterView: SvgNodeView<TClusterVisual>;\n } => {\n const p = latestPropsRef.current;\n const presetViews = createPresetViews(p.preset ?? 'geometric');\n\n let contentView: SvgNodeView<TContentVisual>;\n if (p.renderContentNode) {\n const renderFn = p.renderContentNode;\n jsxContentViewRef.current?.dispose();\n const jsxView = new ReactJsxSvgView<\n TContentVisual,\n ContentDomainRecord<TItem, TTagMeta, TClusterMeta>\n >({\n renderFn: (domain, state) => renderFn(domain.item, domain.ctx, state),\n getKey: (v) => activeResolver.getVisualCacheKey(v),\n domainByKey: contentDomainByKeyRef.current,\n });\n jsxContentViewRef.current = jsxView;\n contentView = jsxView;\n } else if (p.contentView) {\n jsxContentViewRef.current?.dispose();\n jsxContentViewRef.current = null;\n contentView = p.contentView;\n } else {\n jsxContentViewRef.current?.dispose();\n jsxContentViewRef.current = null;\n contentView = presetViews.contentView as unknown as SvgNodeView<TContentVisual>;\n }\n\n let clusterView: SvgNodeView<TClusterVisual>;\n if (p.renderClusterNode) {\n const renderFn = p.renderClusterNode;\n jsxClusterViewRef.current?.dispose();\n const jsxView = new ReactJsxSvgView<\n TClusterVisual,\n ClusterDescriptor<TItem, TTagMeta, TClusterMeta>\n >({\n renderFn: (cluster, state) => renderFn(cluster, state),\n getKey: (v) => activeResolver.getVisualCacheKey(v),\n domainByKey: clusterDomainByKeyRef.current,\n });\n jsxClusterViewRef.current = jsxView;\n clusterView = jsxView;\n } else if (p.clusterView) {\n jsxClusterViewRef.current?.dispose();\n jsxClusterViewRef.current = null;\n clusterView = p.clusterView;\n } else {\n jsxClusterViewRef.current?.dispose();\n jsxClusterViewRef.current = null;\n clusterView = presetViews.clusterView as unknown as SvgNodeView<TClusterVisual>;\n }\n\n return { contentView, clusterView };\n };\n\n // Mount controller once on container\n useEffect(() => {\n const el = containerRef.current;\n if (!el) return;\n\n const p = latestPropsRef.current;\n const effectiveResolver = resolveEffectiveResolver();\n const { contentView, clusterView } = resolveActiveViews(effectiveResolver);\n\n const ctrl = SimplexSvgController.createFromResolved(el, {\n items: p.items,\n getId: p.getId,\n getTags: p.getTags,\n getLabel: p.getLabel,\n deriveClusterMeta: p.deriveClusterMeta,\n preset: p.preset,\n theme: p.theme,\n visualResolver: effectiveResolver,\n contentView,\n clusterView,\n normalizeTag: p.normalizeTag,\n resolveTagMeta: p.resolveTagMeta,\n meshOptions: p.meshOptions,\n layoutOptions: {\n ...p.layoutOptions,\n sizeMultiplier: p.sizeMultiplier ?? p.layoutOptions?.sizeMultiplier ?? 1,\n },\n showHulls: p.showHulls,\n focusOnClusterClick: false,\n interactions: {\n onContentHover: (ev) => {\n latestPropsRef.current.onContentHover?.(ev);\n if (latestPropsRef.current.tooltip) {\n setHoveredTarget(ev ? { kind: 'content', ...ev } : null);\n }\n },\n onClusterHover: (ev) => {\n latestPropsRef.current.onClusterHover?.(ev);\n if (latestPropsRef.current.tooltip) {\n setHoveredTarget(ev ? { kind: 'cluster', ...ev } : null);\n }\n },\n onLeftClick: (target, raw) => {\n const cur = latestPropsRef.current;\n if (cur.onLeftClick) {\n cur.onLeftClick(target, raw);\n return;\n }\n if (cur.focusedClusterUid === undefined && (cur.focusOnClusterClick ?? true)) {\n if (target.kind === 'cluster') {\n const next =\n internalFocusedUidRef.current === target.cluster.clusterUid\n ? null\n : target.cluster.clusterUid;\n internalFocusedUidRef.current = next;\n ctrlRef.current?.setFocusedClusterUid(next);\n } else if (\n target.kind === 'background' &&\n internalFocusedUidRef.current !== null\n ) {\n internalFocusedUidRef.current = null;\n ctrlRef.current?.setFocusedClusterUid(null);\n }\n }\n },\n onRightClick: (t, raw) => latestPropsRef.current.onRightClick?.(t, raw),\n onWheel: (ev, cam) => {\n const policy = latestPropsRef.current.onWheel ?? 'zoom-to-cursor';\n if (policy === 'none') return;\n if (typeof policy === 'function') {\n policy(ev, cam);\n return;\n }\n if (policy === 'pan-vertical') {\n cam.panBy(-ev.deltaX, -ev.deltaY);\n return;\n }\n const factor = Math.exp(-ev.deltaY * 0.0014);\n cam.zoomToCursor(ev.screenX, ev.screenY, factor);\n },\n },\n onMetricsChange: (m) => latestPropsRef.current.onMetricsChange?.(m),\n onClustersChange: (c) => latestPropsRef.current.onClustersChange?.(c),\n onFpsUpdate: (fps) => latestPropsRef.current.onFpsUpdate?.(fps),\n });\n ctrlRef.current = ctrl;\n if (p.controllerRef) {\n p.controllerRef.current = ctrl;\n }\n\n return () => {\n ctrl.destroy();\n ctrlRef.current = null;\n if (latestPropsRef.current.controllerRef) {\n latestPropsRef.current.controllerRef.current = null;\n }\n jsxContentViewRef.current?.dispose();\n jsxClusterViewRef.current?.dispose();\n jsxContentViewRef.current = null;\n jsxClusterViewRef.current = null;\n };\n }, []);\n\n // Sync items\n useEffect(() => {\n ctrlRef.current?.setItems(props.items);\n }, [props.items]);\n\n // Sync views, presets, theme & visual resolver (triggers smooth crossfade / morph!)\n useEffect(() => {\n const ctrl = ctrlRef.current;\n if (!ctrl) return;\n ctrl.setTheme(props.theme ?? 'dark');\n const effectiveResolver = resolveEffectiveResolver();\n const { contentView, clusterView } = resolveActiveViews(effectiveResolver);\n ctrl.setViews({ contentView, clusterView });\n ctrl.setVisualResolver(effectiveResolver);\n }, [\n props.preset,\n props.theme,\n props.visualResolver,\n props.contentView,\n props.clusterView,\n props.renderContentNode,\n props.renderClusterNode,\n ]);\n\n // Sync sizeMultiplier\n useEffect(() => {\n if (props.sizeMultiplier !== undefined) {\n ctrlRef.current?.setSizeMultiplier(props.sizeMultiplier);\n }\n }, [props.sizeMultiplier]);\n\n // Sync showHulls\n useEffect(() => {\n if (props.showHulls !== undefined) {\n ctrlRef.current?.setShowHulls(props.showHulls);\n }\n }, [props.showHulls]);\n\n // Sync pinned / highlighted / focused cluster\n useEffect(() => {\n if (props.pinnedIds !== undefined) {\n ctrlRef.current?.setPinnedIds(props.pinnedIds);\n }\n }, [props.pinnedIds]);\n\n useEffect(() => {\n if (props.highlightedIds !== undefined) {\n ctrlRef.current?.setHighlightedIds(props.highlightedIds);\n }\n }, [props.highlightedIds]);\n\n useEffect(() => {\n if (props.focusedClusterUid !== undefined) {\n internalFocusedUidRef.current = props.focusedClusterUid;\n ctrlRef.current?.setFocusedClusterUid(props.focusedClusterUid);\n }\n }, [props.focusedClusterUid]);\n\n // Clear built-in tooltip if prop toggled off\n useEffect(() => {\n if (!props.tooltip) {\n setHoveredTarget(null);\n }\n }, [props.tooltip]);\n\n const renderBuiltInTooltip = () => {\n if (!props.tooltip || !hoveredTarget) return null;\n\n const containerW = containerRef.current?.clientWidth || 960;\n const containerH = containerRef.current?.clientHeight || 600;\n const left = Math.min(\n Math.max(8, Math.round(hoveredTarget.screenPosition.x + 14)),\n Math.max(8, containerW - 256),\n );\n const top = Math.min(\n Math.max(8, Math.round(hoveredTarget.screenPosition.y + 14)),\n Math.max(8, containerH - 80),\n );\n\n const isLight = props.theme === 'light';\n const content =\n typeof props.tooltip === 'function' ? (\n props.tooltip(hoveredTarget)\n ) : hoveredTarget.kind === 'content' ? (\n <div>\n <div style={{ fontWeight: 600, color: isLight ? '#0f172a' : '#f8fafc' }}>\n {extractDefaultItemLabel(\n hoveredTarget.item,\n hoveredTarget.layoutContext.id,\n props.getLabel,\n )}\n </div>\n {hoveredTarget.layoutContext.tags.length > 0 && (\n <div style={{ marginTop: 3, fontSize: 11, color: isLight ? '#475569' : '#94a3b8' }}>\n {hoveredTarget.layoutContext.tags\n .map((t) => `#${t.tag}`)\n .slice(0, 5)\n .join(' · ')}\n </div>\n )}\n </div>\n ) : (\n <div>\n <div style={{ fontWeight: 600, color: hoveredTarget.cluster.colorHex }}>\n {`${hoveredTarget.cluster.code} · ${hoveredTarget.cluster.defaultLabel}`}\n </div>\n <div style={{ marginTop: 3, fontSize: 11, color: isLight ? '#475569' : '#94a3b8' }}>\n {`${hoveredTarget.cluster.members.length} ${\n hoveredTarget.cluster.members.length === 1 ? 'item' : 'items'\n }`}\n </div>\n </div>\n );\n\n return (\n <div\n role=\"tooltip\"\n style={{\n position: 'absolute',\n left,\n top,\n zIndex: 20,\n maxWidth: 244,\n padding: '7px 10px',\n borderRadius: 8,\n background: isLight ? 'rgba(255, 255, 255, 0.96)' : 'rgba(9, 13, 22, 0.94)',\n border: isLight\n ? '1px solid rgba(203, 213, 225, 0.95)'\n : '1px solid rgba(51, 65, 85, 0.85)',\n color: isLight ? '#0f172a' : '#f1f5f9',\n fontSize: 12,\n lineHeight: 1.4,\n pointerEvents: 'none',\n boxShadow: isLight\n ? '0 10px 24px rgba(15, 23, 42, 0.12)'\n : '0 10px 24px rgba(0, 0, 0, 0.45)',\n }}\n >\n {content}\n </div>\n );\n };\n\n return (\n <div\n ref={containerRef}\n className={props.className}\n style={{\n position: 'relative',\n width: '100%',\n height: '100%',\n overflow: 'hidden',\n ...props.style,\n }}\n >\n {renderBuiltInTooltip()}\n </div>\n );\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@simplex-viz/react",
3
- "version": "0.2.0",
3
+ "version": "0.2.1",
4
4
  "description": "End-to-end type-safe React bindings, declarative JSX node renderers, and hooks for @simplex-viz/core and @simplex-viz/svg.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -20,8 +20,8 @@
20
20
  "LICENSE"
21
21
  ],
22
22
  "dependencies": {
23
- "@simplex-viz/core": "^0.2.0",
24
- "@simplex-viz/svg": "^0.2.0"
23
+ "@simplex-viz/core": "^0.2.1",
24
+ "@simplex-viz/svg": "^0.2.1"
25
25
  },
26
26
  "peerDependencies": {
27
27
  "react": ">=18.0.0",