@dxos/react-ui-canvas 0.7.5-main.ff8607b → 0.7.5-staging.b81e783

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.
Files changed (44) hide show
  1. package/README.md +1 -3
  2. package/dist/lib/browser/index.mjs +113 -33
  3. package/dist/lib/browser/index.mjs.map +4 -4
  4. package/dist/lib/browser/meta.json +1 -1
  5. package/dist/lib/node/index.cjs +114 -32
  6. package/dist/lib/node/index.cjs.map +4 -4
  7. package/dist/lib/node/meta.json +1 -1
  8. package/dist/lib/node-esm/index.mjs +113 -33
  9. package/dist/lib/node-esm/index.mjs.map +4 -4
  10. package/dist/lib/node-esm/meta.json +1 -1
  11. package/dist/types/src/components/Canvas/Canvas.d.ts +1 -1
  12. package/dist/types/src/components/Canvas/Canvas.d.ts.map +1 -1
  13. package/dist/types/src/components/Canvas/Canvas.stories.d.ts +1 -0
  14. package/dist/types/src/components/Canvas/Canvas.stories.d.ts.map +1 -1
  15. package/dist/types/src/components/FPS.d.ts +1 -2
  16. package/dist/types/src/components/FPS.d.ts.map +1 -1
  17. package/dist/types/src/components/Grid/Grid.d.ts +6 -5
  18. package/dist/types/src/components/Grid/Grid.d.ts.map +1 -1
  19. package/dist/types/src/components/Grid/Grid.stories.d.ts.map +1 -1
  20. package/dist/types/src/hooks/index.d.ts +1 -1
  21. package/dist/types/src/hooks/index.d.ts.map +1 -1
  22. package/dist/types/src/hooks/projection.d.ts +2 -2
  23. package/dist/types/src/hooks/projection.d.ts.map +1 -1
  24. package/dist/types/src/hooks/{useProjection.d.ts → useCanvasContext.d.ts} +3 -2
  25. package/dist/types/src/hooks/useCanvasContext.d.ts.map +1 -0
  26. package/dist/types/src/hooks/useWheel.d.ts +4 -3
  27. package/dist/types/src/hooks/useWheel.d.ts.map +1 -1
  28. package/dist/types/src/util/svg.d.ts +5 -5
  29. package/dist/types/src/util/svg.d.ts.map +1 -1
  30. package/dist/types/src/util/util.d.ts +1 -0
  31. package/dist/types/src/util/util.d.ts.map +1 -1
  32. package/package.json +14 -13
  33. package/src/components/Canvas/Canvas.stories.tsx +51 -24
  34. package/src/components/Canvas/Canvas.tsx +12 -6
  35. package/src/components/Grid/Grid.stories.tsx +4 -6
  36. package/src/components/Grid/Grid.tsx +34 -8
  37. package/src/hooks/index.ts +1 -1
  38. package/src/hooks/projection.tsx +16 -9
  39. package/src/hooks/{useProjection.tsx → useCanvasContext.tsx} +2 -1
  40. package/src/hooks/useWheel.tsx +60 -8
  41. package/src/util/svg.stories.tsx +1 -1
  42. package/src/util/svg.tsx +2 -2
  43. package/src/util/util.ts +11 -0
  44. package/dist/types/src/hooks/useProjection.d.ts.map +0 -1
@@ -35,6 +35,7 @@ __export(node_exports, {
35
35
  Dimension: () => Dimension,
36
36
  FPS: () => FPS,
37
37
  Grid: () => Grid,
38
+ GridComponent: () => GridComponent,
38
39
  GridPattern: () => GridPattern,
39
40
  Marker: () => Marker,
40
41
  Markers: () => Markers,
@@ -42,11 +43,12 @@ __export(node_exports, {
42
43
  ProjectionMapper: () => ProjectionMapper,
43
44
  Rect: () => Rect,
44
45
  createPath: () => createPath,
45
- defaultOffset: () => defaultOffset,
46
+ defaultOrigin: () => defaultOrigin,
46
47
  getRelativePoint: () => getRelativePoint,
47
48
  getZoomTransform: () => getZoomTransform,
49
+ inspectElement: () => inspectElement,
48
50
  testId: () => testId,
49
- useProjection: () => useProjection,
51
+ useCanvasContext: () => useCanvasContext,
50
52
  useWheel: () => useWheel,
51
53
  zoomInPlace: () => zoomInPlace,
52
54
  zoomTo: () => zoomTo
@@ -66,9 +68,10 @@ var import_react_ui_theme2 = require("@dxos/react-ui-theme");
66
68
  var import_react5 = __toESM(require("react"));
67
69
  var import_react_ui_theme3 = require("@dxos/react-ui-theme");
68
70
  var import_react6 = __toESM(require("react"));
71
+ var import_react_ui = require("@dxos/react-ui");
69
72
  var import_react_ui_theme4 = require("@dxos/react-ui-theme");
70
73
  var import_effect = require("@dxos/effect");
71
- var defaultOffset = {
74
+ var defaultOrigin = {
72
75
  x: 0,
73
76
  y: 0
74
77
  };
@@ -79,7 +82,7 @@ var ProjectionMapper = class {
79
82
  height: 0
80
83
  };
81
84
  this._scale = 1;
82
- this._offset = defaultOffset;
85
+ this._offset = defaultOrigin;
83
86
  this._toScreen = (0, import_transformation_matrix.identity)();
84
87
  this._toModel = (0, import_transformation_matrix.identity)();
85
88
  if (bounds && scale && offset) {
@@ -90,7 +93,11 @@ var ProjectionMapper = class {
90
93
  this._bounds = bounds;
91
94
  this._scale = scale;
92
95
  this._offset = offset;
93
- this._toScreen = (0, import_transformation_matrix.compose)((0, import_transformation_matrix.translate)(this._offset.x, this._offset.y), (0, import_transformation_matrix.scale)(this._scale));
96
+ this._toScreen = (0, import_transformation_matrix.compose)(
97
+ // NOTE: Order is important.
98
+ (0, import_transformation_matrix.translate)(this._offset.x, this._offset.y),
99
+ (0, import_transformation_matrix.scale)(this._scale)
100
+ );
94
101
  this._toModel = (0, import_transformation_matrix.inverse)(this._toScreen);
95
102
  return this;
96
103
  }
@@ -131,7 +138,9 @@ var zoomInPlace = (setTransform, pos, offset, current, next, delay = 200) => {
131
138
  }));
132
139
  });
133
140
  };
134
- var zoomTo = (setTransform, current, next, delay = 200) => {
141
+ var noop = () => {
142
+ };
143
+ var zoomTo = (setTransform, current, next, delay = 200, cb = noop) => {
135
144
  const is = d3.interpolateObject({
136
145
  scale: current.scale,
137
146
  ...current.offset
@@ -148,10 +157,10 @@ var zoomTo = (setTransform, current, next, delay = 200) => {
148
157
  y
149
158
  }
150
159
  });
151
- });
160
+ }).on("end", cb);
152
161
  };
153
162
  var CanvasContext = /* @__PURE__ */ (0, import_react2.createContext)(null);
154
- var useProjection = () => {
163
+ var useCanvasContext = () => {
155
164
  return (0, import_react2.useContext)(CanvasContext) ?? (0, import_debug.raise)(new Error("Missing CanvasContext"));
156
165
  };
157
166
  var createPath = (points, join = false) => {
@@ -183,16 +192,16 @@ var Markers = ({ id = "dx-marker", classNames }) => {
183
192
  }), /* @__PURE__ */ import_react4.default.createElement(Marker, {
184
193
  id: `${id}-circle`,
185
194
  pos: {
186
- x: 6,
187
- y: 6
195
+ x: 8,
196
+ y: 8
188
197
  },
189
198
  size: {
190
- width: 12,
191
- height: 12
199
+ width: 16,
200
+ height: 16
192
201
  }
193
202
  }, /* @__PURE__ */ import_react4.default.createElement("circle", {
194
- cx: 6,
195
- cy: 6,
203
+ cx: 8,
204
+ cy: 8,
196
205
  r: 5,
197
206
  stroke: "context-stroke",
198
207
  className: (0, import_react_ui_theme2.mx)(classNames)
@@ -298,13 +307,25 @@ var testId = (id, inspect = false) => {
298
307
  [DATA_TEST_ID]: id
299
308
  };
300
309
  };
310
+ var inspectElement = (el) => {
311
+ window.INSPECT = () => {
312
+ window.inspect(el);
313
+ window.element = el;
314
+ console.log("Open storybook in expanded window;\nthen run INSPECT()");
315
+ console.log(el);
316
+ };
317
+ };
301
318
  var DATA_TEST_ID = "data-test-id";
302
- var useWheel = (el, setProjection) => {
319
+ var defaultOptions = {
320
+ zoom: true
321
+ };
322
+ var useWheel = (options = defaultOptions) => {
323
+ const { root, setProjection } = useCanvasContext();
303
324
  (0, import_react3.useEffect)(() => {
304
- if (!el) {
325
+ if (!root) {
305
326
  return;
306
327
  }
307
- return (0, import_bind_event_listener.bindAll)(el, [
328
+ return (0, import_bind_event_listener.bindAll)(root, [
308
329
  {
309
330
  type: "wheel",
310
331
  options: {
@@ -312,13 +333,20 @@ var useWheel = (el, setProjection) => {
312
333
  passive: false
313
334
  },
314
335
  listener: (ev) => {
336
+ const zooming = isWheelZooming(ev);
337
+ if (!hasFocus(root) && !zooming) {
338
+ return;
339
+ }
315
340
  ev.preventDefault();
341
+ if (zooming && !options.zoom) {
342
+ return;
343
+ }
316
344
  if (ev.ctrlKey) {
317
- if (!el) {
345
+ if (!root) {
318
346
  return;
319
347
  }
320
348
  setProjection(({ scale, offset }) => {
321
- const pos = getRelativePoint(el, ev);
349
+ const pos = getRelativePoint(root, ev);
322
350
  const scaleSensitivity = 0.01;
323
351
  const newScale = scale * Math.exp(-ev.deltaY * scaleSensitivity);
324
352
  return getZoomTransform({
@@ -343,18 +371,42 @@ var useWheel = (el, setProjection) => {
343
371
  }
344
372
  ]);
345
373
  }, [
346
- el,
347
- setProjection
374
+ root
348
375
  ]);
349
376
  };
350
- var Canvas = /* @__PURE__ */ (0, import_react.forwardRef)(({ children, classNames, scale: _scale = 1, offset: _offset = defaultOffset, ...props }, forwardedRef) => {
377
+ var isWheelZooming = (ev) => {
378
+ if (ev.ctrlKey || ev.metaKey) {
379
+ return Math.abs(ev.deltaY) > 0 || Math.abs(ev.deltaZ) > 0;
380
+ }
381
+ return false;
382
+ };
383
+ var hasFocus = (element) => {
384
+ const activeElement = document.activeElement;
385
+ if (!activeElement) {
386
+ return false;
387
+ }
388
+ let shadowActive = activeElement;
389
+ while (shadowActive?.shadowRoot?.activeElement) {
390
+ shadowActive = shadowActive.shadowRoot.activeElement;
391
+ }
392
+ let current = element;
393
+ while (current) {
394
+ if (current === activeElement || current === shadowActive) {
395
+ return true;
396
+ }
397
+ current = current.parentElement;
398
+ }
399
+ return false;
400
+ };
401
+ var Canvas = /* @__PURE__ */ (0, import_react.forwardRef)(({ children, classNames, scale: _scale = 1, offset: _offset = defaultOrigin, ...props }, forwardedRef) => {
351
402
  const { ref, width = 0, height = 0 } = (0, import_react_resize_detector.useResizeDetector)();
403
+ const [ready, setReady] = (0, import_react.useState)(false);
352
404
  const [{ scale, offset }, setProjection] = (0, import_react.useState)({
353
405
  scale: _scale,
354
406
  offset: _offset
355
407
  });
356
408
  (0, import_react.useEffect)(() => {
357
- if (width && height && offset === defaultOffset) {
409
+ if (width && height && offset === defaultOrigin) {
358
410
  setProjection({
359
411
  scale,
360
412
  offset: {
@@ -375,6 +427,9 @@ var Canvas = /* @__PURE__ */ (0, import_react.forwardRef)(({ children, className
375
427
  width,
376
428
  height
377
429
  }, scale, offset);
430
+ if (offset !== defaultOrigin) {
431
+ setReady(true);
432
+ }
378
433
  }, [
379
434
  projection,
380
435
  scale,
@@ -404,6 +459,7 @@ var Canvas = /* @__PURE__ */ (0, import_react.forwardRef)(({ children, className
404
459
  return /* @__PURE__ */ import_react.default.createElement(CanvasContext.Provider, {
405
460
  value: {
406
461
  root: ref.current,
462
+ ready,
407
463
  width,
408
464
  height,
409
465
  scale,
@@ -417,7 +473,7 @@ var Canvas = /* @__PURE__ */ (0, import_react.forwardRef)(({ children, className
417
473
  ...props,
418
474
  className: (0, import_react_ui_theme.mx)("absolute inset-0 overflow-hidden", classNames),
419
475
  ref
420
- }, children));
476
+ }, ready ? children : null));
421
477
  });
422
478
  var SEC = 1e3;
423
479
  var FPS = ({ classNames, width = 60, height = 30, bar = "bg-cyan-500" }) => {
@@ -492,12 +548,15 @@ var gridRatios = [
492
548
  4,
493
549
  16
494
550
  ];
495
- var defaultOffset2 = {
551
+ var defaultGridSize = 16;
552
+ var defaultOffset = {
496
553
  x: 0,
497
554
  y: 0
498
555
  };
499
556
  var createId = (parent, grid) => `dx-canvas-grid-${parent}-${grid}`;
500
- var Grid = /* @__PURE__ */ (0, import_react6.forwardRef)(({ id: parentId, size: gridSize, scale = 1, offset = defaultOffset2, classNames }, forwardedRef) => {
557
+ var GridComponent = /* @__PURE__ */ (0, import_react6.forwardRef)(({ size: gridSize = defaultGridSize, scale = 1, offset = defaultOffset, showAxes = true, classNames }, forwardedRef) => {
558
+ const svgRef = (0, import_react_ui.useForwardedRef)(forwardedRef);
559
+ const instanceId = (0, import_react6.useId)();
501
560
  const grids = (0, import_react6.useMemo)(() => gridRatios.map((ratio) => ({
502
561
  id: ratio,
503
562
  size: ratio * gridSize * scale
@@ -505,23 +564,44 @@ var Grid = /* @__PURE__ */ (0, import_react6.forwardRef)(({ id: parentId, size:
505
564
  gridSize,
506
565
  scale
507
566
  ]);
567
+ const { width = 0, height = 0 } = svgRef.current?.getBoundingClientRect() ?? {};
508
568
  return /* @__PURE__ */ import_react6.default.createElement("svg", {
509
569
  ...testId("dx-canvas-grid"),
510
- ref: forwardedRef,
570
+ ref: svgRef,
511
571
  className: (0, import_react_ui_theme4.mx)("absolute inset-0 w-full h-full pointer-events-none touch-none select-none", "stroke-neutral-500", classNames)
512
572
  }, /* @__PURE__ */ import_react6.default.createElement("defs", null, grids.map(({ id, size }) => /* @__PURE__ */ import_react6.default.createElement(GridPattern, {
513
573
  key: id,
514
- id: createId(parentId, id),
574
+ id: createId(instanceId, id),
515
575
  offset,
516
576
  size
517
- }))), /* @__PURE__ */ import_react6.default.createElement("g", null, grids.map(({ id }, i) => /* @__PURE__ */ import_react6.default.createElement("rect", {
577
+ }))), showAxes && /* @__PURE__ */ import_react6.default.createElement(import_react6.default.Fragment, null, /* @__PURE__ */ import_react6.default.createElement("line", {
578
+ x1: 0,
579
+ y1: offset.y,
580
+ x2: width,
581
+ y2: offset.y,
582
+ className: "stroke-neutral-500 opacity-40"
583
+ }), /* @__PURE__ */ import_react6.default.createElement("line", {
584
+ x1: offset.x,
585
+ y1: 0,
586
+ x2: offset.x,
587
+ y2: height,
588
+ className: "stroke-neutral-500 opacity-40"
589
+ })), /* @__PURE__ */ import_react6.default.createElement("g", null, grids.map(({ id }, i) => /* @__PURE__ */ import_react6.default.createElement("rect", {
518
590
  key: id,
519
591
  opacity: 0.1 + i * 0.05,
520
- fill: `url(#${createId(parentId, id)})`,
592
+ fill: `url(#${createId(instanceId, id)})`,
521
593
  width: "100%",
522
594
  height: "100%"
523
595
  }))));
524
596
  });
597
+ var Grid = (props) => {
598
+ const { scale, offset } = useCanvasContext();
599
+ return /* @__PURE__ */ import_react6.default.createElement(GridComponent, {
600
+ ...props,
601
+ scale,
602
+ offset
603
+ });
604
+ };
525
605
  var Point = import_effect.S.Struct({
526
606
  x: import_effect.S.Number,
527
607
  y: import_effect.S.Number
@@ -540,6 +620,7 @@ var Rect = import_effect.S.extend(Point, Dimension);
540
620
  Dimension,
541
621
  FPS,
542
622
  Grid,
623
+ GridComponent,
543
624
  GridPattern,
544
625
  Marker,
545
626
  Markers,
@@ -547,11 +628,12 @@ var Rect = import_effect.S.extend(Point, Dimension);
547
628
  ProjectionMapper,
548
629
  Rect,
549
630
  createPath,
550
- defaultOffset,
631
+ defaultOrigin,
551
632
  getRelativePoint,
552
633
  getZoomTransform,
634
+ inspectElement,
553
635
  testId,
554
- useProjection,
636
+ useCanvasContext,
555
637
  useWheel,
556
638
  zoomInPlace,
557
639
  zoomTo
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../../../src/components/Canvas/Canvas.tsx", "../../../src/hooks/projection.tsx", "../../../src/hooks/useProjection.tsx", "../../../src/hooks/useWheel.tsx", "../../../src/util/svg.tsx", "../../../src/util/util.ts", "../../../src/components/FPS.tsx", "../../../src/components/Grid/Grid.tsx", "../../../src/types.ts"],
4
- "sourcesContent": ["//\n// Copyright 2024 DXOS.org\n//\n\nimport React, {\n type CSSProperties,\n type PropsWithChildren,\n forwardRef,\n useEffect,\n useImperativeHandle,\n useMemo,\n useState,\n type HTMLAttributes,\n} from 'react';\nimport { useResizeDetector } from 'react-resize-detector';\n\nimport { type ThemedClassName } from '@dxos/react-ui';\nimport { mx } from '@dxos/react-ui-theme';\n\nimport { defaultOffset, CanvasContext, ProjectionMapper, type ProjectionState } from '../../hooks';\n\nexport interface CanvasController {\n setProjection(projection: ProjectionState): Promise<void>;\n}\n\nexport type CanvasProps = ThemedClassName<PropsWithChildren<Partial<ProjectionState> & HTMLAttributes<HTMLDivElement>>>;\n\n/**\n * Root canvas component.\n * Manages CSS projection.\n */\nexport const Canvas = forwardRef<CanvasController, CanvasProps>(\n ({ children, classNames, scale: _scale = 1, offset: _offset = defaultOffset, ...props }, forwardedRef) => {\n // Size.\n const { ref, width = 0, height = 0 } = useResizeDetector();\n\n // Projection.\n const [{ scale, offset }, setProjection] = useState<ProjectionState>({ scale: _scale, offset: _offset });\n useEffect(() => {\n if (width && height && offset === defaultOffset) {\n setProjection({ scale, offset: { x: width / 2, y: height / 2 } });\n }\n }, [width, height, scale, offset]);\n\n // Projection mapper.\n const projection = useMemo(() => new ProjectionMapper(), []);\n useEffect(() => {\n projection.update({ width, height }, scale, offset);\n }, [projection, scale, offset, width, height]);\n\n // CSS transforms.\n const styles = useMemo<CSSProperties>(() => {\n return {\n // NOTE: Order is important.\n transform: `translate(${offset.x}px, ${offset.y}px) scale(${scale})`,\n visibility: width && height ? 'visible' : 'hidden',\n };\n }, [scale, offset]);\n\n // Controller.\n useImperativeHandle(\n forwardedRef,\n () => {\n return {\n setProjection: async (projection: ProjectionState) => {\n setProjection(projection);\n },\n };\n },\n [ref],\n );\n\n return (\n <CanvasContext.Provider\n value={{ root: ref.current, width, height, scale, offset, styles, projection, setProjection }}\n >\n <div role='none' {...props} className={mx('absolute inset-0 overflow-hidden', classNames)} ref={ref}>\n {children}\n </div>\n </CanvasContext.Provider>\n );\n },\n);\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport * as d3 from 'd3';\nimport {\n type Matrix,\n applyToPoints,\n compose,\n inverse,\n translate as translateMatrix,\n identity,\n scale as scaleMatrix,\n} from 'transformation-matrix';\n\nimport { type Point, type Dimension } from '../types';\n\nexport const defaultOffset: Point = { x: 0, y: 0 };\n\n// TODO(burdon): Rotation also?\nexport type ProjectionState = {\n scale: number;\n offset: Point;\n};\n\n// TODO(burdon): Tradeoff between stable ProjectionMapping object that can be used with live values within a closure,\n// vs. a reactive object that can trigger updates?\n\n/**\n * Maps between screen and model coordinates.\n */\nexport interface Projection {\n get bounds(): Dimension;\n get scale(): number;\n get offset(): Point;\n\n /**\n * Maps the model space to the screen offset (from the top-left of the element).\n */\n toScreen(points: Point[]): Point[];\n\n /**\n * Maps the pointer coordinate (from the top-left of the element) to the model space.\n */\n toModel(points: Point[]): Point[];\n}\n\nexport class ProjectionMapper implements Projection {\n private _bounds: Dimension = { width: 0, height: 0 };\n private _scale: number = 1;\n private _offset: Point = defaultOffset;\n private _toScreen: Matrix = identity();\n private _toModel: Matrix = identity();\n\n constructor(bounds?: Dimension, scale?: number, offset?: Point) {\n if (bounds && scale && offset) {\n this.update(bounds, scale, offset);\n }\n }\n\n update(bounds: Dimension, scale: number, offset: Point) {\n this._bounds = bounds;\n this._scale = scale;\n this._offset = offset;\n this._toScreen = compose(translateMatrix(this._offset.x, this._offset.y), scaleMatrix(this._scale));\n this._toModel = inverse(this._toScreen);\n return this;\n }\n\n get bounds() {\n return this._bounds;\n }\n\n get scale() {\n return this._scale;\n }\n\n get offset() {\n return this._offset;\n }\n\n toScreen(points: Point[]): Point[] {\n return applyToPoints(this._toScreen, points);\n }\n\n toModel(points: Point[]): Point[] {\n return applyToPoints(this._toModel, points);\n }\n}\n\n/**\n * Maintain position while zooming.\n */\nexport const getZoomTransform = ({\n scale,\n offset,\n pos,\n newScale,\n}: ProjectionState & { pos: Point; newScale: number }): ProjectionState => {\n return {\n scale: newScale,\n offset: {\n x: pos.x - (pos.x - offset.x) * (newScale / scale),\n y: pos.y - (pos.y - offset.y) * (newScale / scale),\n },\n };\n};\n\n/**\n * Zoom while keeping the specified position in place.\n */\n// TODO(burdon): Convert to object.\nexport const zoomInPlace = (\n setTransform: (state: ProjectionState) => void,\n pos: Point,\n offset: Point,\n current: number,\n next: number,\n delay = 200,\n) => {\n const is = d3.interpolate(current, next);\n d3.transition()\n .ease(d3.easeSinOut)\n .duration(delay)\n .tween('zoom', () => (t) => {\n const newScale = is(t);\n setTransform(getZoomTransform({ scale: current, newScale, offset, pos }));\n });\n};\n\n/**\n * Zoom to new scale and position.\n */\n// TODO(burdon): Convert to object.\nexport const zoomTo = (\n setTransform: (state: ProjectionState) => void,\n current: ProjectionState,\n next: ProjectionState,\n delay = 200,\n) => {\n const is = d3.interpolateObject({ scale: current.scale, ...current.offset }, { scale: next.scale, ...next.offset });\n d3.transition()\n .ease(d3.easeSinOut)\n .duration(delay)\n .tween('zoom', () => (t) => {\n const { scale, x, y } = is(t);\n setTransform({ scale, offset: { x, y } });\n });\n};\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { type CSSProperties, type Dispatch, type SetStateAction, createContext, useContext } from 'react';\n\nimport { raise } from '@dxos/debug';\n\nimport { type Projection, type ProjectionState } from './projection';\n\nexport type CanvasContext = ProjectionState & {\n root: HTMLDivElement;\n width: number;\n height: number;\n styles: CSSProperties;\n projection: Projection;\n setProjection: Dispatch<SetStateAction<ProjectionState>>;\n};\n\n/**\n * @internal\n */\n// TODO(burdon): Use radix?\nexport const CanvasContext = createContext<CanvasContext | null>(null);\n\nexport const useProjection = (): CanvasContext => {\n return useContext(CanvasContext) ?? raise(new Error('Missing CanvasContext'));\n};\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { bindAll } from 'bind-event-listener';\nimport { type Dispatch, type SetStateAction, useEffect } from 'react';\n\nimport { getZoomTransform, type ProjectionState } from './projection';\nimport { getRelativePoint } from '../util';\n\n/**\n * Handle wheel events to update the transform state (zoom and offset).\n */\nexport const useWheel = (el: HTMLDivElement | null, setProjection: Dispatch<SetStateAction<ProjectionState>>) => {\n useEffect(() => {\n if (!el) {\n return;\n }\n\n return bindAll(el, [\n {\n type: 'wheel',\n options: { capture: true, passive: false },\n listener: (ev: WheelEvent) => {\n ev.preventDefault();\n\n // Zoom or pan.\n if (ev.ctrlKey) {\n if (!el) {\n return;\n }\n\n // Keep centered while zooming.\n setProjection(({ scale, offset }) => {\n const pos = getRelativePoint(el, ev);\n const scaleSensitivity = 0.01;\n const newScale = scale * Math.exp(-ev.deltaY * scaleSensitivity);\n return getZoomTransform({ scale, offset, newScale, pos });\n });\n } else {\n setProjection(({ scale, offset: { x, y } }) => {\n return {\n scale,\n offset: {\n x: x - ev.deltaX,\n y: y - ev.deltaY,\n },\n };\n });\n }\n },\n },\n ]);\n }, [el, setProjection]);\n};\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport React, { type PropsWithChildren, type SVGProps } from 'react';\n\nimport { type ThemedClassName } from '@dxos/react-ui';\nimport { mx } from '@dxos/react-ui-theme';\n\nimport { type Dimension, type Point } from '../types';\n\n// Refs\n// - https://airbnb.io/visx/gallery\n// - https://github.com/tldraw/tldraw/blob/main/packages/editor/src/lib/primitives/Vec.ts\n\nexport const createPath = (points: Point[], join = false) => {\n return ['M', points.map(({ x, y }) => `${x},${y}`).join(' L '), join ? 'Z' : ''].join(' ');\n};\n\n/**\n * https://developer.mozilla.org/en-US/docs/Web/SVG/Tutorial/Paths\n * NOTE: Leave space around shape for line width.\n */\nexport const Markers = ({ id = 'dx-marker', classNames }: ThemedClassName<{ id?: string }>) => {\n return (\n <>\n <Arrow id={`${id}-arrow-start`} dir='start' classNames={classNames} />\n <Arrow id={`${id}-arrow-end`} dir='end' classNames={classNames} />\n <Arrow id={`${id}-triangle-start`} dir='start' closed classNames={classNames} />\n <Arrow id={`${id}-triangle-end`} dir='end' closed classNames={classNames} />\n <Marker id={`${id}-circle`} pos={{ x: 6, y: 6 }} size={{ width: 12, height: 12 }}>\n <circle cx={6} cy={6} r={5} stroke={'context-stroke'} className={mx(classNames)} />\n </Marker>\n </>\n );\n};\n\nexport type MarkerProps = SVGProps<SVGMarkerElement> &\n PropsWithChildren<\n ThemedClassName<{\n id: string;\n pos: Point;\n size: Dimension;\n fill?: boolean;\n }>\n >;\n\n/**\n * https://www.w3.org/TR/SVG2/painting.html#Markers\n */\nexport const Marker = ({\n id,\n className,\n children,\n pos: { x: refX, y: refY },\n size: { width: markerWidth, height: markerHeight },\n fill,\n ...rest\n}: MarkerProps) => (\n <marker\n id={id}\n className={className}\n {...{\n refX,\n refY,\n markerWidth,\n markerHeight,\n markerUnits: 'strokeWidth',\n orient: 'auto',\n ...rest,\n }}\n >\n {children}\n </marker>\n);\n\nexport const Arrow = ({\n classNames,\n id,\n size = 16,\n dir = 'end',\n closed = false,\n}: ThemedClassName<{ id: string; size?: number; dir?: 'start' | 'end'; closed?: boolean }>) => (\n <Marker\n id={id}\n size={{ width: size, height: size }}\n pos={dir === 'end' ? { x: size, y: size / 2 } : { x: 0, y: size / 2 }}\n >\n <path\n fill={closed ? undefined : 'none'}\n stroke={'context-stroke'}\n className={mx(classNames)}\n d={createPath(\n dir === 'end'\n ? [\n { x: 1, y: 1 },\n { x: size, y: size / 2 },\n { x: 1, y: size - 1 },\n ]\n : [\n { x: size - 1, y: 1 },\n { x: 0, y: size / 2 },\n { x: size - 1, y: size - 1 },\n ],\n closed,\n )}\n />\n </Marker>\n);\n\nexport const GridPattern = ({\n classNames,\n id,\n size,\n offset,\n}: ThemedClassName<{ id: string; size: number; offset: Point }>) => (\n <pattern\n id={id}\n x={(size / 2 + offset.x) % size}\n y={(size / 2 + offset.y) % size}\n width={size}\n height={size}\n patternUnits='userSpaceOnUse'\n >\n {/* TODO(burdon): vars. */}\n <g className={mx(classNames)}>\n <line x1={0} y1={size / 2} x2={size} y2={size / 2} />\n <line x1={size / 2} y1={0} x2={size / 2} y2={size} />\n </g>\n </pattern>\n);\n", "//\n// Copyright 2024 DXOS.org\n//\n\nlet logged = false;\n\n/**\n * Get the relative point of the cursor.\n * NOTE: ev.offset returns the position relative to the target.\n */\nexport const getRelativePoint = (el: HTMLElement, ev: MouseEvent) => {\n const rect = el.getBoundingClientRect();\n return { x: ev.clientX - rect.x, y: ev.clientY - rect.top };\n};\n\n/**\n *\n */\n// TODO(burdon): Factor out.\nexport const testId = <ID = string>(id: ID, inspect = false) => {\n if (inspect) {\n if (!logged) {\n // eslint-disable-next-line no-console\n console.log('Open storybook in expanded window;\\nthen run INSPECT()');\n logged = true;\n }\n\n (window as any).INSPECT = () => {\n const el = document.querySelector(`[data-test-id=\"${id}\"]`);\n (window as any).inspect(el);\n // eslint-disable-next-line no-console\n console.log(el);\n };\n }\n\n return { [DATA_TEST_ID]: id };\n};\n\nexport const DATA_TEST_ID = 'data-test-id';\n", "//\n// Copyright 2024 DXOS.org\n// Adapted from: https://github.com/smplrspace/react-fps-stats\n//\n\nimport React, { useEffect, useReducer, useRef } from 'react';\n\nimport { type ThemedClassName } from '@dxos/react-ui';\nimport { mx } from '@dxos/react-ui-theme';\n\nexport type FPSProps = ThemedClassName<{\n width?: number;\n height?: number;\n bar?: string;\n}>;\n\ntype State = {\n max: number;\n len: number;\n fps: number[];\n frames: number;\n prevTime: number;\n};\n\nconst SEC = 1_000;\n\nexport const FPS = ({ classNames, width = 60, height = 30, bar = 'bg-cyan-500' }: FPSProps) => {\n const [{ fps, max, len }, dispatch] = useReducer(\n (state: State) => {\n const currentTime = Date.now();\n if (currentTime > state.prevTime + SEC) {\n const nextFPS = [\n ...new Array(Math.floor((currentTime - state.prevTime - SEC) / SEC)).fill(0),\n Math.max(1, Math.round((state.frames * SEC) / (currentTime - state.prevTime))),\n ];\n return {\n max: Math.max(state.max, ...nextFPS),\n len: Math.min(state.len + nextFPS.length, width),\n fps: [...state.fps, ...nextFPS].slice(-width),\n frames: 1,\n prevTime: currentTime,\n };\n } else {\n return { ...state, frames: state.frames + 1 };\n }\n },\n {\n max: 0,\n len: 0,\n fps: [],\n frames: 0,\n prevTime: Date.now(),\n },\n );\n\n const requestRef = useRef<number>();\n const tick = () => {\n dispatch();\n requestRef.current = requestAnimationFrame(tick);\n };\n\n useEffect(() => {\n requestRef.current = requestAnimationFrame(tick);\n return () => {\n if (requestRef.current) {\n cancelAnimationFrame(requestRef.current);\n }\n };\n }, []);\n\n return (\n <div\n style={{ width: width + 6 }}\n className={mx(\n 'relative flex flex-col p-0.5',\n 'bg-baseSurface text-xs text-subdued font-thin pointer-events-none border border-separator',\n classNames,\n )}\n >\n <div>{fps[len - 1]} FPS</div>\n <div className='w-full relative' style={{ height }}>\n {fps.map((frame, i) => (\n <div\n key={`fps-${i}`}\n className={bar}\n style={{\n position: 'absolute',\n bottom: 0,\n right: `${len - 1 - i}px`,\n height: `${(height * frame) / max}px`,\n width: 1,\n }}\n />\n ))}\n </div>\n </div>\n );\n};\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport React, { forwardRef, useMemo } from 'react';\n\nimport { type ThemedClassName } from '@dxos/react-ui';\nimport { mx } from '@dxos/react-ui-theme';\n\nimport { type Point } from '../../types';\nimport { GridPattern, testId } from '../../util';\n\nconst gridRatios = [1 / 4, 1, 4, 16];\n\nconst defaultOffset: Point = { x: 0, y: 0 };\n\nconst createId = (parent: string, grid: number) => `dx-canvas-grid-${parent}-${grid}`;\n\nexport type GridProps = ThemedClassName<{ id: string; size: number; scale?: number; offset?: Point }>;\n\nexport const Grid = forwardRef<SVGSVGElement, GridProps>(\n ({ id: parentId, size: gridSize, scale = 1, offset = defaultOffset, classNames }, forwardedRef) => {\n const grids = useMemo(\n () =>\n gridRatios\n .map((ratio) => ({ id: ratio, size: ratio * gridSize * scale }))\n .filter(({ size }) => size >= gridSize && size <= 256),\n [gridSize, scale],\n );\n\n return (\n <svg\n {...testId('dx-canvas-grid')}\n ref={forwardedRef}\n className={mx(\n 'absolute inset-0 w-full h-full pointer-events-none touch-none select-none',\n 'stroke-neutral-500',\n classNames,\n )}\n >\n {/* NOTE: The pattern is offset so that the middle of the pattern aligns with the grid. */}\n <defs>\n {grids.map(({ id, size }) => (\n <GridPattern key={id} id={createId(parentId, id)} offset={offset} size={size} />\n ))}\n </defs>\n <g>\n {grids.map(({ id }, i) => (\n <rect\n key={id}\n opacity={0.1 + i * 0.05}\n fill={`url(#${createId(parentId, id)})`}\n width='100%'\n height='100%'\n />\n ))}\n </g>\n </svg>\n );\n },\n);\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { S } from '@dxos/effect';\n\nexport const Point = S.Struct({ x: S.Number, y: S.Number });\nexport const Dimension = S.Struct({ width: S.Number, height: S.Number });\nexport const Rect = S.extend(Point, Dimension);\n\nexport type Point = S.Schema.Type<typeof Point>;\nexport type Dimension = S.Schema.Type<typeof Dimension>;\nexport type Rect = S.Schema.Type<typeof Rect>;\n"],
5
- "mappings": "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",
6
- "names": ["import_react", "import_react_ui_theme", "defaultOffset", "x", "y", "ProjectionMapper", "constructor", "bounds", "scale", "offset", "_bounds", "width", "height", "_scale", "_offset", "_toScreen", "identity", "_toModel", "update", "compose", "translateMatrix", "scaleMatrix", "inverse", "toScreen", "points", "applyToPoints", "toModel", "getZoomTransform", "pos", "newScale", "zoomInPlace", "setTransform", "current", "next", "delay", "is", "interpolate", "transition", "ease", "easeSinOut", "duration", "tween", "t", "zoomTo", "interpolateObject", "CanvasContext", "createContext", "useProjection", "useContext", "raise", "Error", "createPath", "join", "map", "Markers", "id", "classNames", "React", "Arrow", "dir", "closed", "Marker", "size", "circle", "cx", "cy", "r", "stroke", "className", "mx", "children", "refX", "refY", "markerWidth", "markerHeight", "fill", "rest", "marker", "markerUnits", "orient", "path", "undefined", "d", "GridPattern", "pattern", "patternUnits", "g", "line", "x1", "y1", "x2", "y2", "logged", "getRelativePoint", "el", "ev", "rect", "getBoundingClientRect", "clientX", "clientY", "top", "testId", "inspect", "console", "log", "window", "INSPECT", "document", "querySelector", "DATA_TEST_ID", "useWheel", "setProjection", "useEffect", "bindAll", "type", "options", "capture", "passive", "listener", "preventDefault", "ctrlKey", "scaleSensitivity", "Math", "exp", "deltaY", "deltaX", "Canvas", "forwardRef", "props", "forwardedRef", "ref", "useResizeDetector", "useState", "projection", "useMemo", "styles", "transform", "visibility", "useImperativeHandle", "Provider", "value", "root", "div", "role", "SEC", "FPS", "bar", "fps", "max", "len", "dispatch", "useReducer", "state", "currentTime", "Date", "now", "prevTime", "nextFPS", "Array", "floor", "round", "frames", "min", "length", "slice", "requestRef", "useRef", "tick", "requestAnimationFrame", "cancelAnimationFrame", "style", "frame", "i", "key", "position", "bottom", "right", "gridRatios", "createId", "parent", "grid", "Grid", "parentId", "gridSize", "grids", "ratio", "filter", "svg", "defs", "opacity", "Point", "S", "Struct", "Number", "Dimension", "Rect", "extend"]
3
+ "sources": ["../../../src/components/Canvas/Canvas.tsx", "../../../src/hooks/projection.tsx", "../../../src/hooks/useCanvasContext.tsx", "../../../src/hooks/useWheel.tsx", "../../../src/util/svg.tsx", "../../../src/util/util.ts", "../../../src/components/FPS.tsx", "../../../src/components/Grid/Grid.tsx", "../../../src/types.ts"],
4
+ "sourcesContent": ["//\n// Copyright 2024 DXOS.org\n//\n\nimport React, {\n type CSSProperties,\n type HTMLAttributes,\n type PropsWithChildren,\n forwardRef,\n useEffect,\n useImperativeHandle,\n useMemo,\n useState,\n} from 'react';\nimport { useResizeDetector } from 'react-resize-detector';\n\nimport { type ThemedClassName } from '@dxos/react-ui';\nimport { mx } from '@dxos/react-ui-theme';\n\nimport { defaultOrigin, CanvasContext, ProjectionMapper, type ProjectionState } from '../../hooks';\n\nexport interface CanvasController {\n setProjection(projection: ProjectionState): Promise<void>;\n}\n\nexport type CanvasProps = ThemedClassName<PropsWithChildren<Partial<ProjectionState> & HTMLAttributes<HTMLDivElement>>>;\n\n/**\n * Root canvas component.\n * Manages CSS projection.\n */\nexport const Canvas = forwardRef<CanvasController, CanvasProps>(\n ({ children, classNames, scale: _scale = 1, offset: _offset = defaultOrigin, ...props }, forwardedRef) => {\n // Size.\n const { ref, width = 0, height = 0 } = useResizeDetector();\n\n // Ready when initially resized.\n const [ready, setReady] = useState(false);\n\n // Projection.\n const [{ scale, offset }, setProjection] = useState<ProjectionState>({ scale: _scale, offset: _offset });\n useEffect(() => {\n if (width && height && offset === defaultOrigin) {\n setProjection({ scale, offset: { x: width / 2, y: height / 2 } });\n }\n }, [width, height, scale, offset]);\n\n // Projection mapper.\n const projection = useMemo(() => new ProjectionMapper(), []);\n useEffect(() => {\n projection.update({ width, height }, scale, offset);\n if (offset !== defaultOrigin) {\n setReady(true);\n }\n }, [projection, scale, offset, width, height]);\n\n // CSS transforms.\n const styles = useMemo<CSSProperties>(() => {\n return {\n // NOTE: Order is important.\n transform: `translate(${offset.x}px, ${offset.y}px) scale(${scale})`,\n visibility: width && height ? 'visible' : 'hidden',\n };\n }, [scale, offset]);\n\n // Controller.\n useImperativeHandle(\n forwardedRef,\n () => {\n return {\n setProjection: async (projection: ProjectionState) => {\n setProjection(projection);\n },\n };\n },\n [ref],\n );\n\n return (\n <CanvasContext.Provider\n value={{ root: ref.current, ready, width, height, scale, offset, styles, projection, setProjection }}\n >\n <div role='none' {...props} className={mx('absolute inset-0 overflow-hidden', classNames)} ref={ref}>\n {ready ? children : null}\n </div>\n </CanvasContext.Provider>\n );\n },\n);\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport * as d3 from 'd3';\nimport {\n type Matrix,\n applyToPoints,\n compose,\n identity,\n inverse,\n scale as scaleMatrix,\n translate as translateMatrix,\n} from 'transformation-matrix';\n\nimport { type Point, type Dimension } from '../types';\n\nexport const defaultOrigin: Point = { x: 0, y: 0 };\n\n// TODO(burdon): Rotation also?\nexport type ProjectionState = {\n scale: number;\n offset: Point;\n};\n\n/**\n * Maps between screen and model coordinates.\n */\nexport interface Projection {\n get bounds(): Dimension;\n get scale(): number;\n get offset(): Point;\n\n /**\n * Maps the model space to the screen offset (from the top-left of the element).\n */\n toScreen(points: Point[]): Point[];\n\n /**\n * Maps the pointer coordinate (from the top-left of the element) to the model space.\n */\n toModel(points: Point[]): Point[];\n}\n\nexport class ProjectionMapper implements Projection {\n private _bounds: Dimension = { width: 0, height: 0 };\n private _scale: number = 1;\n private _offset: Point = defaultOrigin;\n private _toScreen: Matrix = identity();\n private _toModel: Matrix = identity();\n\n constructor(bounds?: Dimension, scale?: number, offset?: Point) {\n if (bounds && scale && offset) {\n this.update(bounds, scale, offset);\n }\n }\n\n update(bounds: Dimension, scale: number, offset: Point) {\n this._bounds = bounds;\n this._scale = scale;\n this._offset = offset;\n this._toScreen = compose(\n // NOTE: Order is important.\n translateMatrix(this._offset.x, this._offset.y),\n scaleMatrix(this._scale),\n // TODO(burdon): Flip.\n // flipX(),\n );\n this._toModel = inverse(this._toScreen);\n return this;\n }\n\n get bounds() {\n return this._bounds;\n }\n\n get scale() {\n return this._scale;\n }\n\n get offset() {\n return this._offset;\n }\n\n toScreen(points: Point[]): Point[] {\n return applyToPoints(this._toScreen, points);\n }\n\n toModel(points: Point[]): Point[] {\n return applyToPoints(this._toModel, points);\n }\n}\n\n/**\n * Maintain position while zooming.\n */\nexport const getZoomTransform = ({\n scale,\n offset,\n pos,\n newScale,\n}: ProjectionState & { pos: Point; newScale: number }): ProjectionState => {\n return {\n scale: newScale,\n offset: {\n x: pos.x - (pos.x - offset.x) * (newScale / scale),\n y: pos.y - (pos.y - offset.y) * (newScale / scale),\n },\n };\n};\n\n/**\n * Zoom while keeping the specified position in place.\n */\n// TODO(burdon): Convert to object.\nexport const zoomInPlace = (\n setTransform: (state: ProjectionState) => void,\n pos: Point,\n offset: Point,\n current: number,\n next: number,\n delay = 200,\n) => {\n const is = d3.interpolate(current, next);\n d3.transition()\n .ease(d3.easeSinOut)\n .duration(delay)\n .tween('zoom', () => (t) => {\n const newScale = is(t);\n setTransform(getZoomTransform({ scale: current, newScale, offset, pos }));\n });\n};\n\nconst noop = () => {};\n\n/**\n * Zoom to new scale and position.\n */\n// TODO(burdon): Convert to object.\nexport const zoomTo = (\n setTransform: (state: ProjectionState) => void,\n current: ProjectionState,\n next: ProjectionState,\n delay = 200,\n cb = noop,\n) => {\n const is = d3.interpolateObject({ scale: current.scale, ...current.offset }, { scale: next.scale, ...next.offset });\n d3.transition()\n .ease(d3.easeSinOut)\n .duration(delay)\n .tween('zoom', () => (t) => {\n const { scale, x, y } = is(t);\n setTransform({ scale, offset: { x, y } });\n })\n .on('end', cb);\n};\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { type CSSProperties, type Dispatch, type SetStateAction, createContext, useContext } from 'react';\n\nimport { raise } from '@dxos/debug';\n\nimport { type Projection, type ProjectionState } from './projection';\n\nexport type CanvasContext = ProjectionState & {\n root: HTMLDivElement;\n ready: boolean;\n width: number;\n height: number;\n styles: CSSProperties;\n projection: Projection;\n setProjection: Dispatch<SetStateAction<ProjectionState>>;\n};\n\n/**\n * @internal\n */\n// TODO(burdon): Use radix?\nexport const CanvasContext = createContext<CanvasContext | null>(null);\n\nexport const useCanvasContext = (): CanvasContext => {\n return useContext(CanvasContext) ?? raise(new Error('Missing CanvasContext'));\n};\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { bindAll } from 'bind-event-listener';\nimport { useEffect } from 'react';\n\nimport { getZoomTransform } from './projection';\nimport { useCanvasContext } from './useCanvasContext';\nimport { getRelativePoint } from '../util';\n\nexport type WheelOptions = {\n zoom?: boolean;\n};\n\nconst defaultOptions: WheelOptions = {\n zoom: true,\n};\n\n/**\n * Handle wheel events to update the transform state (zoom and offset).\n */\nexport const useWheel = (options: WheelOptions = defaultOptions) => {\n const { root, setProjection } = useCanvasContext();\n useEffect(() => {\n if (!root) {\n return;\n }\n\n return bindAll(root, [\n {\n type: 'wheel',\n options: { capture: true, passive: false },\n listener: (ev: WheelEvent) => {\n const zooming = isWheelZooming(ev);\n if (!hasFocus(root) && !zooming) {\n return;\n }\n\n ev.preventDefault();\n if (zooming && !options.zoom) {\n return;\n }\n\n // Zoom or pan.\n if (ev.ctrlKey) {\n if (!root) {\n return;\n }\n\n // Keep centered while zooming.\n setProjection(({ scale, offset }) => {\n const pos = getRelativePoint(root, ev);\n const scaleSensitivity = 0.01;\n const newScale = scale * Math.exp(-ev.deltaY * scaleSensitivity);\n return getZoomTransform({ scale, offset, newScale, pos });\n });\n } else {\n setProjection(({ scale, offset: { x, y } }) => {\n return {\n scale,\n offset: {\n x: x - ev.deltaX,\n y: y - ev.deltaY,\n },\n };\n });\n }\n },\n },\n ]);\n }, [root]);\n};\n\nconst isWheelZooming = (ev: WheelEvent): boolean => {\n // Check for ctrl/cmd key + wheel action.\n if (ev.ctrlKey || ev.metaKey) {\n // Some browsers use deltaY, others deltaZ for zoom.\n return Math.abs(ev.deltaY) > 0 || Math.abs(ev.deltaZ) > 0;\n }\n\n return false;\n};\n\nconst hasFocus = (element: HTMLElement): boolean => {\n const activeElement = document.activeElement;\n if (!activeElement) {\n return false;\n }\n\n // Handle shadow DOM.\n let shadowActive = activeElement;\n while (shadowActive?.shadowRoot?.activeElement) {\n shadowActive = shadowActive.shadowRoot.activeElement;\n }\n\n // Check if element or any parent has focus.\n let current: HTMLElement | null = element;\n while (current) {\n if (current === activeElement || current === shadowActive) {\n return true;\n }\n current = current.parentElement;\n }\n\n return false;\n};\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport React, { type PropsWithChildren, type SVGProps } from 'react';\n\nimport { type ThemedClassName } from '@dxos/react-ui';\nimport { mx } from '@dxos/react-ui-theme';\n\nimport { type Dimension, type Point } from '../types';\n\n// Refs\n// - https://airbnb.io/visx/gallery\n// - https://github.com/tldraw/tldraw/blob/main/packages/editor/src/lib/primitives/Vec.ts\n\nexport const createPath = (points: Point[], join = false) => {\n return ['M', points.map(({ x, y }) => `${x},${y}`).join(' L '), join ? 'Z' : ''].join(' ');\n};\n\n/**\n * https://developer.mozilla.org/en-US/docs/Web/SVG/Tutorial/Paths\n * NOTE: Leave space around shape for line width.\n */\nexport const Markers = ({ id = 'dx-marker', classNames }: ThemedClassName<{ id?: string }>) => {\n return (\n <>\n <Arrow id={`${id}-arrow-start`} dir='start' classNames={classNames} />\n <Arrow id={`${id}-arrow-end`} dir='end' classNames={classNames} />\n <Arrow id={`${id}-triangle-start`} dir='start' closed classNames={classNames} />\n <Arrow id={`${id}-triangle-end`} dir='end' closed classNames={classNames} />\n <Marker id={`${id}-circle`} pos={{ x: 8, y: 8 }} size={{ width: 16, height: 16 }}>\n <circle cx={8} cy={8} r={5} stroke={'context-stroke'} className={mx(classNames)} />\n </Marker>\n </>\n );\n};\n\nexport type MarkerProps = SVGProps<SVGMarkerElement> &\n PropsWithChildren<\n ThemedClassName<{\n id: string;\n pos: Point;\n size: Dimension;\n fill?: boolean;\n }>\n >;\n\n/**\n * https://www.w3.org/TR/SVG2/painting.html#Markers\n */\nexport const Marker = ({\n id,\n className,\n children,\n pos: { x: refX, y: refY },\n size: { width: markerWidth, height: markerHeight },\n fill,\n ...rest\n}: MarkerProps) => (\n <marker\n id={id}\n className={className}\n {...{\n refX,\n refY,\n markerWidth,\n markerHeight,\n markerUnits: 'strokeWidth',\n orient: 'auto',\n ...rest,\n }}\n >\n {children}\n </marker>\n);\n\nexport const Arrow = ({\n classNames,\n id,\n size = 16,\n dir = 'end',\n closed = false,\n}: ThemedClassName<{ id: string; size?: number; dir?: 'start' | 'end'; closed?: boolean }>) => (\n <Marker\n id={id}\n size={{ width: size, height: size }}\n pos={dir === 'end' ? { x: size, y: size / 2 } : { x: 0, y: size / 2 }}\n >\n <path\n fill={closed ? undefined : 'none'}\n stroke={'context-stroke'}\n className={mx(classNames)}\n d={createPath(\n dir === 'end'\n ? [\n { x: 1, y: 1 },\n { x: size, y: size / 2 },\n { x: 1, y: size - 1 },\n ]\n : [\n { x: size - 1, y: 1 },\n { x: 0, y: size / 2 },\n { x: size - 1, y: size - 1 },\n ],\n closed,\n )}\n />\n </Marker>\n);\n\nexport const GridPattern = ({\n classNames,\n id,\n size,\n offset,\n}: ThemedClassName<{ id: string; size: number; offset: Point }>) => (\n <pattern\n id={id}\n x={(size / 2 + offset.x) % size}\n y={(size / 2 + offset.y) % size}\n width={size}\n height={size}\n patternUnits='userSpaceOnUse'\n >\n {/* TODO(burdon): vars. */}\n <g className={mx(classNames)}>\n <line x1={0} y1={size / 2} x2={size} y2={size / 2} />\n <line x1={size / 2} y1={0} x2={size / 2} y2={size} />\n </g>\n </pattern>\n);\n", "//\n// Copyright 2024 DXOS.org\n//\n\nlet logged = false;\n\n/**\n * Get the relative point of the cursor.\n * NOTE: ev.offset returns the position relative to the target.\n */\nexport const getRelativePoint = (el: HTMLElement, ev: MouseEvent) => {\n const rect = el.getBoundingClientRect();\n return { x: ev.clientX - rect.x, y: ev.clientY - rect.top };\n};\n\n/**\n *\n */\n// TODO(burdon): Factor out.\nexport const testId = <ID = string>(id: ID, inspect = false) => {\n if (inspect) {\n if (!logged) {\n // eslint-disable-next-line no-console\n console.log('Open storybook in expanded window;\\nthen run INSPECT()');\n logged = true;\n }\n\n (window as any).INSPECT = () => {\n const el = document.querySelector(`[data-test-id=\"${id}\"]`);\n (window as any).inspect(el);\n // eslint-disable-next-line no-console\n console.log(el);\n };\n }\n\n return { [DATA_TEST_ID]: id };\n};\n\nexport const inspectElement = (el: Element) => {\n (window as any).INSPECT = () => {\n (window as any).inspect(el);\n (window as any).element = el;\n // eslint-disable-next-line no-console\n console.log('Open storybook in expanded window;\\nthen run INSPECT()');\n // eslint-disable-next-line no-console\n console.log(el);\n };\n};\n\nexport const DATA_TEST_ID = 'data-test-id';\n", "//\n// Copyright 2024 DXOS.org\n// Adapted from: https://github.com/smplrspace/react-fps-stats\n//\n\nimport React, { useEffect, useReducer, useRef } from 'react';\n\nimport { type ThemedClassName } from '@dxos/react-ui';\nimport { mx } from '@dxos/react-ui-theme';\n\nexport type FPSProps = ThemedClassName<{\n width?: number;\n height?: number;\n bar?: string;\n}>;\n\ntype State = {\n max: number;\n len: number;\n fps: number[];\n frames: number;\n prevTime: number;\n};\n\nconst SEC = 1_000;\n\nexport const FPS = ({ classNames, width = 60, height = 30, bar = 'bg-cyan-500' }: FPSProps) => {\n const [{ fps, max, len }, dispatch] = useReducer(\n (state: State) => {\n const currentTime = Date.now();\n if (currentTime > state.prevTime + SEC) {\n const nextFPS = [\n ...new Array(Math.floor((currentTime - state.prevTime - SEC) / SEC)).fill(0),\n Math.max(1, Math.round((state.frames * SEC) / (currentTime - state.prevTime))),\n ];\n return {\n max: Math.max(state.max, ...nextFPS),\n len: Math.min(state.len + nextFPS.length, width),\n fps: [...state.fps, ...nextFPS].slice(-width),\n frames: 1,\n prevTime: currentTime,\n };\n } else {\n return { ...state, frames: state.frames + 1 };\n }\n },\n {\n max: 0,\n len: 0,\n fps: [],\n frames: 0,\n prevTime: Date.now(),\n },\n );\n\n const requestRef = useRef<number>();\n const tick = () => {\n dispatch();\n requestRef.current = requestAnimationFrame(tick);\n };\n\n useEffect(() => {\n requestRef.current = requestAnimationFrame(tick);\n return () => {\n if (requestRef.current) {\n cancelAnimationFrame(requestRef.current);\n }\n };\n }, []);\n\n return (\n <div\n style={{ width: width + 6 }}\n className={mx(\n 'relative flex flex-col p-0.5',\n 'bg-baseSurface text-xs text-subdued font-thin pointer-events-none border border-separator',\n classNames,\n )}\n >\n <div>{fps[len - 1]} FPS</div>\n <div className='w-full relative' style={{ height }}>\n {fps.map((frame, i) => (\n <div\n key={`fps-${i}`}\n className={bar}\n style={{\n position: 'absolute',\n bottom: 0,\n right: `${len - 1 - i}px`,\n height: `${(height * frame) / max}px`,\n width: 1,\n }}\n />\n ))}\n </div>\n </div>\n );\n};\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport React, { forwardRef, useMemo, useId } from 'react';\n\nimport { useForwardedRef, type ThemedClassName } from '@dxos/react-ui';\nimport { mx } from '@dxos/react-ui-theme';\n\nimport { useCanvasContext } from '../../hooks';\nimport { type Point } from '../../types';\nimport { GridPattern, testId } from '../../util';\n\nconst gridRatios = [1 / 4, 1, 4, 16];\n\nconst defaultGridSize = 16;\nconst defaultOffset: Point = { x: 0, y: 0 };\n\nconst createId = (parent: string, grid: number) => `dx-canvas-grid-${parent}-${grid}`;\n\nexport type GridProps = ThemedClassName<{\n size?: number;\n scale?: number;\n offset?: Point;\n showAxes?: boolean;\n}>;\n\nexport const GridComponent = forwardRef<SVGSVGElement, GridProps>(\n (\n { size: gridSize = defaultGridSize, scale = 1, offset = defaultOffset, showAxes = true, classNames },\n forwardedRef,\n ) => {\n const svgRef = useForwardedRef(forwardedRef);\n const instanceId = useId();\n const grids = useMemo(\n () =>\n gridRatios\n .map((ratio) => ({ id: ratio, size: ratio * gridSize * scale }))\n .filter(({ size }) => size >= gridSize && size <= 256),\n [gridSize, scale],\n );\n\n const { width = 0, height = 0 } = svgRef.current?.getBoundingClientRect() ?? {};\n\n return (\n <svg\n {...testId('dx-canvas-grid')}\n ref={svgRef}\n className={mx(\n 'absolute inset-0 w-full h-full pointer-events-none touch-none select-none',\n 'stroke-neutral-500',\n classNames,\n )}\n >\n {/* NOTE: The pattern is offset so that the middle of the pattern aligns with the grid. */}\n <defs>\n {grids.map(({ id, size }) => (\n <GridPattern key={id} id={createId(instanceId, id)} offset={offset} size={size} />\n ))}\n </defs>\n {showAxes && (\n <>\n <line x1={0} y1={offset.y} x2={width} y2={offset.y} className='stroke-neutral-500 opacity-40' />\n <line x1={offset.x} y1={0} x2={offset.x} y2={height} className='stroke-neutral-500 opacity-40' />\n </>\n )}\n <g>\n {grids.map(({ id }, i) => (\n <rect\n key={id}\n opacity={0.1 + i * 0.05}\n fill={`url(#${createId(instanceId, id)})`}\n width='100%'\n height='100%'\n />\n ))}\n </g>\n </svg>\n );\n },\n);\n\n// TODO(burdon): Use id of parent canvas.\nexport const Grid = (props: GridProps) => {\n const { scale, offset } = useCanvasContext();\n return <GridComponent {...props} scale={scale} offset={offset} />;\n};\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { S } from '@dxos/effect';\n\nexport const Point = S.Struct({ x: S.Number, y: S.Number });\nexport const Dimension = S.Struct({ width: S.Number, height: S.Number });\nexport const Rect = S.extend(Point, Dimension);\n\nexport type Point = S.Schema.Type<typeof Point>;\nexport type Dimension = S.Schema.Type<typeof Dimension>;\nexport type Rect = S.Schema.Type<typeof Rect>;\n"],
5
+ "mappings": "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",
6
+ "names": ["import_react", "import_react_ui_theme", "defaultOrigin", "x", "y", "ProjectionMapper", "constructor", "bounds", "scale", "offset", "_bounds", "width", "height", "_scale", "_offset", "_toScreen", "identity", "_toModel", "update", "compose", "translateMatrix", "scaleMatrix", "inverse", "toScreen", "points", "applyToPoints", "toModel", "getZoomTransform", "pos", "newScale", "zoomInPlace", "setTransform", "current", "next", "delay", "is", "interpolate", "transition", "ease", "easeSinOut", "duration", "tween", "t", "noop", "zoomTo", "cb", "interpolateObject", "on", "CanvasContext", "createContext", "useCanvasContext", "useContext", "raise", "Error", "createPath", "join", "map", "Markers", "id", "classNames", "React", "Arrow", "dir", "closed", "Marker", "size", "circle", "cx", "cy", "r", "stroke", "className", "mx", "children", "refX", "refY", "markerWidth", "markerHeight", "fill", "rest", "marker", "markerUnits", "orient", "path", "undefined", "d", "GridPattern", "pattern", "patternUnits", "g", "line", "x1", "y1", "x2", "y2", "logged", "getRelativePoint", "el", "ev", "rect", "getBoundingClientRect", "clientX", "clientY", "top", "testId", "inspect", "console", "log", "window", "INSPECT", "document", "querySelector", "DATA_TEST_ID", "inspectElement", "element", "defaultOptions", "zoom", "useWheel", "options", "root", "setProjection", "useEffect", "bindAll", "type", "capture", "passive", "listener", "zooming", "isWheelZooming", "hasFocus", "preventDefault", "ctrlKey", "scaleSensitivity", "Math", "exp", "deltaY", "deltaX", "metaKey", "abs", "deltaZ", "activeElement", "shadowActive", "shadowRoot", "parentElement", "Canvas", "forwardRef", "props", "forwardedRef", "ref", "useResizeDetector", "ready", "setReady", "useState", "projection", "useMemo", "styles", "transform", "visibility", "useImperativeHandle", "Provider", "value", "div", "role", "SEC", "FPS", "bar", "fps", "max", "len", "dispatch", "useReducer", "state", "currentTime", "Date", "now", "prevTime", "nextFPS", "Array", "floor", "round", "frames", "min", "length", "slice", "requestRef", "useRef", "tick", "requestAnimationFrame", "cancelAnimationFrame", "style", "frame", "i", "key", "position", "bottom", "right", "gridRatios", "defaultGridSize", "defaultOffset", "createId", "parent", "grid", "GridComponent", "gridSize", "showAxes", "svgRef", "useForwardedRef", "instanceId", "useId", "grids", "ratio", "filter", "svg", "defs", "opacity", "Grid", "Point", "S", "Struct", "Number", "Dimension", "Rect", "extend"]
7
7
  }
@@ -1 +1 @@
1
- {"inputs":{"packages/ui/react-ui-canvas/src/hooks/projection.tsx":{"bytes":11640,"imports":[{"path":"d3","kind":"import-statement","external":true},{"path":"transformation-matrix","kind":"import-statement","external":true}],"format":"esm"},"packages/ui/react-ui-canvas/src/hooks/useProjection.tsx":{"bytes":2104,"imports":[{"path":"react","kind":"import-statement","external":true},{"path":"@dxos/debug","kind":"import-statement","external":true}],"format":"esm"},"packages/ui/react-ui-canvas/src/util/svg.tsx":{"bytes":12581,"imports":[{"path":"react","kind":"import-statement","external":true},{"path":"@dxos/react-ui-theme","kind":"import-statement","external":true}],"format":"esm"},"packages/ui/react-ui-canvas/src/util/util.ts":{"bytes":3716,"imports":[],"format":"esm"},"packages/ui/react-ui-canvas/src/util/index.ts":{"bytes":571,"imports":[{"path":"packages/ui/react-ui-canvas/src/util/svg.tsx","kind":"import-statement","original":"./svg"},{"path":"packages/ui/react-ui-canvas/src/util/util.ts","kind":"import-statement","original":"./util"}],"format":"esm"},"packages/ui/react-ui-canvas/src/hooks/useWheel.tsx":{"bytes":6037,"imports":[{"path":"bind-event-listener","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"packages/ui/react-ui-canvas/src/hooks/projection.tsx","kind":"import-statement","original":"./projection"},{"path":"packages/ui/react-ui-canvas/src/util/index.ts","kind":"import-statement","original":"../util"}],"format":"esm"},"packages/ui/react-ui-canvas/src/hooks/index.ts":{"bytes":704,"imports":[{"path":"packages/ui/react-ui-canvas/src/hooks/projection.tsx","kind":"import-statement","original":"./projection"},{"path":"packages/ui/react-ui-canvas/src/hooks/useProjection.tsx","kind":"import-statement","original":"./useProjection"},{"path":"packages/ui/react-ui-canvas/src/hooks/useWheel.tsx","kind":"import-statement","original":"./useWheel"}],"format":"esm"},"packages/ui/react-ui-canvas/src/components/Canvas/Canvas.tsx":{"bytes":8640,"imports":[{"path":"react","kind":"import-statement","external":true},{"path":"react-resize-detector","kind":"import-statement","external":true},{"path":"@dxos/react-ui-theme","kind":"import-statement","external":true},{"path":"packages/ui/react-ui-canvas/src/hooks/index.ts","kind":"import-statement","original":"../../hooks"}],"format":"esm"},"packages/ui/react-ui-canvas/src/components/Canvas/index.ts":{"bytes":511,"imports":[{"path":"packages/ui/react-ui-canvas/src/components/Canvas/Canvas.tsx","kind":"import-statement","original":"./Canvas"}],"format":"esm"},"packages/ui/react-ui-canvas/src/components/FPS.tsx":{"bytes":9050,"imports":[{"path":"react","kind":"import-statement","external":true},{"path":"@dxos/react-ui-theme","kind":"import-statement","external":true}],"format":"esm"},"packages/ui/react-ui-canvas/src/components/Grid/Grid.tsx":{"bytes":6244,"imports":[{"path":"react","kind":"import-statement","external":true},{"path":"@dxos/react-ui-theme","kind":"import-statement","external":true},{"path":"packages/ui/react-ui-canvas/src/util/index.ts","kind":"import-statement","original":"../../util"}],"format":"esm"},"packages/ui/react-ui-canvas/src/components/Grid/index.ts":{"bytes":507,"imports":[{"path":"packages/ui/react-ui-canvas/src/components/Grid/Grid.tsx","kind":"import-statement","original":"./Grid"}],"format":"esm"},"packages/ui/react-ui-canvas/src/components/index.ts":{"bytes":663,"imports":[{"path":"packages/ui/react-ui-canvas/src/components/Canvas/index.ts","kind":"import-statement","original":"./Canvas"},{"path":"packages/ui/react-ui-canvas/src/components/FPS.tsx","kind":"import-statement","original":"./FPS"},{"path":"packages/ui/react-ui-canvas/src/components/Grid/index.ts","kind":"import-statement","original":"./Grid"}],"format":"esm"},"packages/ui/react-ui-canvas/src/types.ts":{"bytes":1632,"imports":[{"path":"@dxos/effect","kind":"import-statement","external":true}],"format":"esm"},"packages/ui/react-ui-canvas/src/index.ts":{"bytes":747,"imports":[{"path":"packages/ui/react-ui-canvas/src/components/index.ts","kind":"import-statement","original":"./components"},{"path":"packages/ui/react-ui-canvas/src/hooks/index.ts","kind":"import-statement","original":"./hooks"},{"path":"packages/ui/react-ui-canvas/src/types.ts","kind":"import-statement","original":"./types"},{"path":"packages/ui/react-ui-canvas/src/util/index.ts","kind":"import-statement","original":"./util"}],"format":"esm"}},"outputs":{"packages/ui/react-ui-canvas/dist/lib/node/index.cjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":30800},"packages/ui/react-ui-canvas/dist/lib/node/index.cjs":{"imports":[{"path":"react","kind":"import-statement","external":true},{"path":"react-resize-detector","kind":"import-statement","external":true},{"path":"@dxos/react-ui-theme","kind":"import-statement","external":true},{"path":"d3","kind":"import-statement","external":true},{"path":"transformation-matrix","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"@dxos/debug","kind":"import-statement","external":true},{"path":"bind-event-listener","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"@dxos/react-ui-theme","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"@dxos/react-ui-theme","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"@dxos/react-ui-theme","kind":"import-statement","external":true},{"path":"@dxos/effect","kind":"import-statement","external":true}],"exports":["Arrow","Canvas","CanvasContext","DATA_TEST_ID","Dimension","FPS","Grid","GridPattern","Marker","Markers","Point","ProjectionMapper","Rect","createPath","defaultOffset","getRelativePoint","getZoomTransform","testId","useProjection","useWheel","zoomInPlace","zoomTo"],"entryPoint":"packages/ui/react-ui-canvas/src/index.ts","inputs":{"packages/ui/react-ui-canvas/src/components/Canvas/Canvas.tsx":{"bytesInOutput":1857},"packages/ui/react-ui-canvas/src/hooks/projection.tsx":{"bytesInOutput":2111},"packages/ui/react-ui-canvas/src/hooks/index.ts":{"bytesInOutput":0},"packages/ui/react-ui-canvas/src/hooks/useProjection.tsx":{"bytesInOutput":257},"packages/ui/react-ui-canvas/src/hooks/useWheel.tsx":{"bytesInOutput":1208},"packages/ui/react-ui-canvas/src/util/svg.tsx":{"bytesInOutput":2736},"packages/ui/react-ui-canvas/src/util/index.ts":{"bytesInOutput":0},"packages/ui/react-ui-canvas/src/util/util.ts":{"bytesInOutput":589},"packages/ui/react-ui-canvas/src/components/Canvas/index.ts":{"bytesInOutput":0},"packages/ui/react-ui-canvas/src/components/index.ts":{"bytesInOutput":0},"packages/ui/react-ui-canvas/src/components/FPS.tsx":{"bytesInOutput":2071},"packages/ui/react-ui-canvas/src/components/Grid/Grid.tsx":{"bytesInOutput":1339},"packages/ui/react-ui-canvas/src/components/Grid/index.ts":{"bytesInOutput":0},"packages/ui/react-ui-canvas/src/index.ts":{"bytesInOutput":0},"packages/ui/react-ui-canvas/src/types.ts":{"bytesInOutput":198}},"bytes":13315}}}
1
+ {"inputs":{"packages/ui/react-ui-canvas/src/hooks/projection.tsx":{"bytes":11859,"imports":[{"path":"d3","kind":"import-statement","external":true},{"path":"transformation-matrix","kind":"import-statement","external":true}],"format":"esm"},"packages/ui/react-ui-canvas/src/hooks/useCanvasContext.tsx":{"bytes":2146,"imports":[{"path":"react","kind":"import-statement","external":true},{"path":"@dxos/debug","kind":"import-statement","external":true}],"format":"esm"},"packages/ui/react-ui-canvas/src/util/svg.tsx":{"bytes":12581,"imports":[{"path":"react","kind":"import-statement","external":true},{"path":"@dxos/react-ui-theme","kind":"import-statement","external":true}],"format":"esm"},"packages/ui/react-ui-canvas/src/util/util.ts":{"bytes":4822,"imports":[],"format":"esm"},"packages/ui/react-ui-canvas/src/util/index.ts":{"bytes":571,"imports":[{"path":"packages/ui/react-ui-canvas/src/util/svg.tsx","kind":"import-statement","original":"./svg"},{"path":"packages/ui/react-ui-canvas/src/util/util.ts","kind":"import-statement","original":"./util"}],"format":"esm"},"packages/ui/react-ui-canvas/src/hooks/useWheel.tsx":{"bytes":10298,"imports":[{"path":"bind-event-listener","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"packages/ui/react-ui-canvas/src/hooks/projection.tsx","kind":"import-statement","original":"./projection"},{"path":"packages/ui/react-ui-canvas/src/hooks/useCanvasContext.tsx","kind":"import-statement","original":"./useCanvasContext"},{"path":"packages/ui/react-ui-canvas/src/util/index.ts","kind":"import-statement","original":"../util"}],"format":"esm"},"packages/ui/react-ui-canvas/src/hooks/index.ts":{"bytes":711,"imports":[{"path":"packages/ui/react-ui-canvas/src/hooks/projection.tsx","kind":"import-statement","original":"./projection"},{"path":"packages/ui/react-ui-canvas/src/hooks/useCanvasContext.tsx","kind":"import-statement","original":"./useCanvasContext"},{"path":"packages/ui/react-ui-canvas/src/hooks/useWheel.tsx","kind":"import-statement","original":"./useWheel"}],"format":"esm"},"packages/ui/react-ui-canvas/src/components/Canvas/Canvas.tsx":{"bytes":9268,"imports":[{"path":"react","kind":"import-statement","external":true},{"path":"react-resize-detector","kind":"import-statement","external":true},{"path":"@dxos/react-ui-theme","kind":"import-statement","external":true},{"path":"packages/ui/react-ui-canvas/src/hooks/index.ts","kind":"import-statement","original":"../../hooks"}],"format":"esm"},"packages/ui/react-ui-canvas/src/components/Canvas/index.ts":{"bytes":511,"imports":[{"path":"packages/ui/react-ui-canvas/src/components/Canvas/Canvas.tsx","kind":"import-statement","original":"./Canvas"}],"format":"esm"},"packages/ui/react-ui-canvas/src/components/FPS.tsx":{"bytes":9050,"imports":[{"path":"react","kind":"import-statement","external":true},{"path":"@dxos/react-ui-theme","kind":"import-statement","external":true}],"format":"esm"},"packages/ui/react-ui-canvas/src/components/Grid/Grid.tsx":{"bytes":9443,"imports":[{"path":"react","kind":"import-statement","external":true},{"path":"@dxos/react-ui","kind":"import-statement","external":true},{"path":"@dxos/react-ui-theme","kind":"import-statement","external":true},{"path":"packages/ui/react-ui-canvas/src/hooks/index.ts","kind":"import-statement","original":"../../hooks"},{"path":"packages/ui/react-ui-canvas/src/util/index.ts","kind":"import-statement","original":"../../util"}],"format":"esm"},"packages/ui/react-ui-canvas/src/components/Grid/index.ts":{"bytes":507,"imports":[{"path":"packages/ui/react-ui-canvas/src/components/Grid/Grid.tsx","kind":"import-statement","original":"./Grid"}],"format":"esm"},"packages/ui/react-ui-canvas/src/components/index.ts":{"bytes":663,"imports":[{"path":"packages/ui/react-ui-canvas/src/components/Canvas/index.ts","kind":"import-statement","original":"./Canvas"},{"path":"packages/ui/react-ui-canvas/src/components/FPS.tsx","kind":"import-statement","original":"./FPS"},{"path":"packages/ui/react-ui-canvas/src/components/Grid/index.ts","kind":"import-statement","original":"./Grid"}],"format":"esm"},"packages/ui/react-ui-canvas/src/types.ts":{"bytes":1632,"imports":[{"path":"@dxos/effect","kind":"import-statement","external":true}],"format":"esm"},"packages/ui/react-ui-canvas/src/index.ts":{"bytes":747,"imports":[{"path":"packages/ui/react-ui-canvas/src/components/index.ts","kind":"import-statement","original":"./components"},{"path":"packages/ui/react-ui-canvas/src/hooks/index.ts","kind":"import-statement","original":"./hooks"},{"path":"packages/ui/react-ui-canvas/src/types.ts","kind":"import-statement","original":"./types"},{"path":"packages/ui/react-ui-canvas/src/util/index.ts","kind":"import-statement","original":"./util"}],"format":"esm"}},"outputs":{"packages/ui/react-ui-canvas/dist/lib/node/index.cjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":35493},"packages/ui/react-ui-canvas/dist/lib/node/index.cjs":{"imports":[{"path":"react","kind":"import-statement","external":true},{"path":"react-resize-detector","kind":"import-statement","external":true},{"path":"@dxos/react-ui-theme","kind":"import-statement","external":true},{"path":"d3","kind":"import-statement","external":true},{"path":"transformation-matrix","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"@dxos/debug","kind":"import-statement","external":true},{"path":"bind-event-listener","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"@dxos/react-ui-theme","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"@dxos/react-ui-theme","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"@dxos/react-ui","kind":"import-statement","external":true},{"path":"@dxos/react-ui-theme","kind":"import-statement","external":true},{"path":"@dxos/effect","kind":"import-statement","external":true}],"exports":["Arrow","Canvas","CanvasContext","DATA_TEST_ID","Dimension","FPS","Grid","GridComponent","GridPattern","Marker","Markers","Point","ProjectionMapper","Rect","createPath","defaultOrigin","getRelativePoint","getZoomTransform","inspectElement","testId","useCanvasContext","useWheel","zoomInPlace","zoomTo"],"entryPoint":"packages/ui/react-ui-canvas/src/index.ts","inputs":{"packages/ui/react-ui-canvas/src/components/Canvas/Canvas.tsx":{"bytesInOutput":1994},"packages/ui/react-ui-canvas/src/hooks/projection.tsx":{"bytesInOutput":2211},"packages/ui/react-ui-canvas/src/hooks/index.ts":{"bytesInOutput":0},"packages/ui/react-ui-canvas/src/hooks/useCanvasContext.tsx":{"bytesInOutput":260},"packages/ui/react-ui-canvas/src/hooks/useWheel.tsx":{"bytesInOutput":2116},"packages/ui/react-ui-canvas/src/util/svg.tsx":{"bytesInOutput":2736},"packages/ui/react-ui-canvas/src/util/index.ts":{"bytesInOutput":0},"packages/ui/react-ui-canvas/src/util/util.ts":{"bytesInOutput":800},"packages/ui/react-ui-canvas/src/components/Canvas/index.ts":{"bytesInOutput":0},"packages/ui/react-ui-canvas/src/components/index.ts":{"bytesInOutput":0},"packages/ui/react-ui-canvas/src/components/FPS.tsx":{"bytesInOutput":2071},"packages/ui/react-ui-canvas/src/components/Grid/Grid.tsx":{"bytesInOutput":2187},"packages/ui/react-ui-canvas/src/components/Grid/index.ts":{"bytesInOutput":0},"packages/ui/react-ui-canvas/src/index.ts":{"bytesInOutput":0},"packages/ui/react-ui-canvas/src/types.ts":{"bytesInOutput":198}},"bytes":15563}}}