@dxos/react-ui-canvas 0.7.5-labs.e27f9b9 → 0.7.5-main.2567c87

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 (40) hide show
  1. package/README.md +3 -1
  2. package/dist/lib/browser/index.mjs +34 -114
  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 +33 -115
  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 +34 -114
  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 +0 -1
  14. package/dist/types/src/components/Canvas/Canvas.stories.d.ts.map +1 -1
  15. package/dist/types/src/components/Grid/Grid.d.ts +5 -6
  16. package/dist/types/src/components/Grid/Grid.d.ts.map +1 -1
  17. package/dist/types/src/components/Grid/Grid.stories.d.ts.map +1 -1
  18. package/dist/types/src/hooks/index.d.ts +1 -1
  19. package/dist/types/src/hooks/index.d.ts.map +1 -1
  20. package/dist/types/src/hooks/projection.d.ts +2 -2
  21. package/dist/types/src/hooks/projection.d.ts.map +1 -1
  22. package/dist/types/src/hooks/{useCanvasContext.d.ts → useProjection.d.ts} +2 -3
  23. package/dist/types/src/hooks/useProjection.d.ts.map +1 -0
  24. package/dist/types/src/hooks/useWheel.d.ts +3 -4
  25. package/dist/types/src/hooks/useWheel.d.ts.map +1 -1
  26. package/dist/types/src/util/util.d.ts +0 -1
  27. package/dist/types/src/util/util.d.ts.map +1 -1
  28. package/package.json +14 -14
  29. package/src/components/Canvas/Canvas.stories.tsx +24 -51
  30. package/src/components/Canvas/Canvas.tsx +6 -12
  31. package/src/components/FPS.tsx +1 -1
  32. package/src/components/Grid/Grid.stories.tsx +6 -4
  33. package/src/components/Grid/Grid.tsx +8 -34
  34. package/src/hooks/index.ts +1 -1
  35. package/src/hooks/projection.tsx +9 -16
  36. package/src/hooks/{useCanvasContext.tsx → useProjection.tsx} +1 -2
  37. package/src/hooks/useWheel.tsx +8 -60
  38. package/src/util/svg.tsx +2 -2
  39. package/src/util/util.ts +0 -11
  40. package/dist/types/src/hooks/useCanvasContext.d.ts.map +0 -1
package/README.md CHANGED
@@ -1 +1,3 @@
1
- # @dxos/react-ui-canvas-editor
1
+ # @dxos/react-ui-canvas
2
+
3
+ Basic canvas with pan and zoom.
@@ -5,8 +5,8 @@ import { mx as mx2 } from "@dxos/react-ui-theme";
5
5
 
6
6
  // packages/ui/react-ui-canvas/src/hooks/projection.tsx
7
7
  import * as d3 from "d3";
8
- import { applyToPoints, compose, identity, inverse, scale as scaleMatrix, translate as translateMatrix } from "transformation-matrix";
9
- var defaultOrigin = {
8
+ import { applyToPoints, compose, inverse, translate as translateMatrix, identity, scale as scaleMatrix } from "transformation-matrix";
9
+ var defaultOffset = {
10
10
  x: 0,
11
11
  y: 0
12
12
  };
@@ -17,7 +17,7 @@ var ProjectionMapper = class {
17
17
  height: 0
18
18
  };
19
19
  this._scale = 1;
20
- this._offset = defaultOrigin;
20
+ this._offset = defaultOffset;
21
21
  this._toScreen = identity();
22
22
  this._toModel = identity();
23
23
  if (bounds && scale && offset) {
@@ -28,11 +28,7 @@ var ProjectionMapper = class {
28
28
  this._bounds = bounds;
29
29
  this._scale = scale;
30
30
  this._offset = offset;
31
- this._toScreen = compose(
32
- // NOTE: Order is important.
33
- translateMatrix(this._offset.x, this._offset.y),
34
- scaleMatrix(this._scale)
35
- );
31
+ this._toScreen = compose(translateMatrix(this._offset.x, this._offset.y), scaleMatrix(this._scale));
36
32
  this._toModel = inverse(this._toScreen);
37
33
  return this;
38
34
  }
@@ -73,9 +69,7 @@ var zoomInPlace = (setTransform, pos, offset, current, next, delay = 200) => {
73
69
  }));
74
70
  });
75
71
  };
76
- var noop = () => {
77
- };
78
- var zoomTo = (setTransform, current, next, delay = 200, cb = noop) => {
72
+ var zoomTo = (setTransform, current, next, delay = 200) => {
79
73
  const is = d3.interpolateObject({
80
74
  scale: current.scale,
81
75
  ...current.offset
@@ -92,14 +86,14 @@ var zoomTo = (setTransform, current, next, delay = 200, cb = noop) => {
92
86
  y
93
87
  }
94
88
  });
95
- }).on("end", cb);
89
+ });
96
90
  };
97
91
 
98
- // packages/ui/react-ui-canvas/src/hooks/useCanvasContext.tsx
92
+ // packages/ui/react-ui-canvas/src/hooks/useProjection.tsx
99
93
  import { createContext, useContext } from "react";
100
94
  import { raise } from "@dxos/debug";
101
95
  var CanvasContext = /* @__PURE__ */ createContext(null);
102
- var useCanvasContext = () => {
96
+ var useProjection = () => {
103
97
  return useContext(CanvasContext) ?? raise(new Error("Missing CanvasContext"));
104
98
  };
105
99
 
@@ -139,16 +133,16 @@ var Markers = ({ id = "dx-marker", classNames }) => {
139
133
  }), /* @__PURE__ */ React.createElement(Marker, {
140
134
  id: `${id}-circle`,
141
135
  pos: {
142
- x: 8,
143
- y: 8
136
+ x: 6,
137
+ y: 6
144
138
  },
145
139
  size: {
146
- width: 16,
147
- height: 16
140
+ width: 12,
141
+ height: 12
148
142
  }
149
143
  }, /* @__PURE__ */ React.createElement("circle", {
150
- cx: 8,
151
- cy: 8,
144
+ cx: 6,
145
+ cy: 6,
152
146
  r: 5,
153
147
  stroke: "context-stroke",
154
148
  className: mx(classNames)
@@ -256,27 +250,15 @@ var testId = (id, inspect = false) => {
256
250
  [DATA_TEST_ID]: id
257
251
  };
258
252
  };
259
- var inspectElement = (el) => {
260
- window.INSPECT = () => {
261
- window.inspect(el);
262
- window.element = el;
263
- console.log("Open storybook in expanded window;\nthen run INSPECT()");
264
- console.log(el);
265
- };
266
- };
267
253
  var DATA_TEST_ID = "data-test-id";
268
254
 
269
255
  // packages/ui/react-ui-canvas/src/hooks/useWheel.tsx
270
- var defaultOptions = {
271
- zoom: true
272
- };
273
- var useWheel = (options = defaultOptions) => {
274
- const { root, setProjection } = useCanvasContext();
256
+ var useWheel = (el, setProjection) => {
275
257
  useEffect(() => {
276
- if (!root) {
258
+ if (!el) {
277
259
  return;
278
260
  }
279
- return bindAll(root, [
261
+ return bindAll(el, [
280
262
  {
281
263
  type: "wheel",
282
264
  options: {
@@ -284,20 +266,13 @@ var useWheel = (options = defaultOptions) => {
284
266
  passive: false
285
267
  },
286
268
  listener: (ev) => {
287
- const zooming = isWheelZooming(ev);
288
- if (!hasFocus(root) && !zooming) {
289
- return;
290
- }
291
269
  ev.preventDefault();
292
- if (zooming && !options.zoom) {
293
- return;
294
- }
295
270
  if (ev.ctrlKey) {
296
- if (!root) {
271
+ if (!el) {
297
272
  return;
298
273
  }
299
274
  setProjection(({ scale, offset }) => {
300
- const pos = getRelativePoint(root, ev);
275
+ const pos = getRelativePoint(el, ev);
301
276
  const scaleSensitivity = 0.01;
302
277
  const newScale = scale * Math.exp(-ev.deltaY * scaleSensitivity);
303
278
  return getZoomTransform({
@@ -322,44 +297,20 @@ var useWheel = (options = defaultOptions) => {
322
297
  }
323
298
  ]);
324
299
  }, [
325
- root
300
+ el,
301
+ setProjection
326
302
  ]);
327
303
  };
328
- var isWheelZooming = (ev) => {
329
- if (ev.ctrlKey || ev.metaKey) {
330
- return Math.abs(ev.deltaY) > 0 || Math.abs(ev.deltaZ) > 0;
331
- }
332
- return false;
333
- };
334
- var hasFocus = (element) => {
335
- const activeElement = document.activeElement;
336
- if (!activeElement) {
337
- return false;
338
- }
339
- let shadowActive = activeElement;
340
- while (shadowActive?.shadowRoot?.activeElement) {
341
- shadowActive = shadowActive.shadowRoot.activeElement;
342
- }
343
- let current = element;
344
- while (current) {
345
- if (current === activeElement || current === shadowActive) {
346
- return true;
347
- }
348
- current = current.parentElement;
349
- }
350
- return false;
351
- };
352
304
 
353
305
  // packages/ui/react-ui-canvas/src/components/Canvas/Canvas.tsx
354
- var Canvas = /* @__PURE__ */ forwardRef(({ children, classNames, scale: _scale = 1, offset: _offset = defaultOrigin, ...props }, forwardedRef) => {
306
+ var Canvas = /* @__PURE__ */ forwardRef(({ children, classNames, scale: _scale = 1, offset: _offset = defaultOffset, ...props }, forwardedRef) => {
355
307
  const { ref, width = 0, height = 0 } = useResizeDetector();
356
- const [ready, setReady] = useState(false);
357
308
  const [{ scale, offset }, setProjection] = useState({
358
309
  scale: _scale,
359
310
  offset: _offset
360
311
  });
361
312
  useEffect2(() => {
362
- if (width && height && offset === defaultOrigin) {
313
+ if (width && height && offset === defaultOffset) {
363
314
  setProjection({
364
315
  scale,
365
316
  offset: {
@@ -380,9 +331,6 @@ var Canvas = /* @__PURE__ */ forwardRef(({ children, classNames, scale: _scale =
380
331
  width,
381
332
  height
382
333
  }, scale, offset);
383
- if (offset !== defaultOrigin) {
384
- setReady(true);
385
- }
386
334
  }, [
387
335
  projection,
388
336
  scale,
@@ -412,7 +360,6 @@ var Canvas = /* @__PURE__ */ forwardRef(({ children, classNames, scale: _scale =
412
360
  return /* @__PURE__ */ React2.createElement(CanvasContext.Provider, {
413
361
  value: {
414
362
  root: ref.current,
415
- ready,
416
363
  width,
417
364
  height,
418
365
  scale,
@@ -426,7 +373,7 @@ var Canvas = /* @__PURE__ */ forwardRef(({ children, classNames, scale: _scale =
426
373
  ...props,
427
374
  className: mx2("absolute inset-0 overflow-hidden", classNames),
428
375
  ref
429
- }, ready ? children : null));
376
+ }, children));
430
377
  });
431
378
 
432
379
  // packages/ui/react-ui-canvas/src/components/FPS.tsx
@@ -481,7 +428,7 @@ var FPS = ({ classNames, width = 60, height = 30, bar = "bg-cyan-500" }) => {
481
428
  style: {
482
429
  width: width + 6
483
430
  },
484
- className: mx3("relative flex flex-col p-0.5", "bg-baseSurface text-xs text-subdued font-thin pointer-events-none border border-separator", classNames)
431
+ className: mx3("relative flex flex-col p-0.5", "bg-base text-xs text-subdued font-thin pointer-events-none border border-separator", classNames)
485
432
  }, /* @__PURE__ */ React3.createElement("div", null, fps[len - 1], " FPS"), /* @__PURE__ */ React3.createElement("div", {
486
433
  className: "w-full relative",
487
434
  style: {
@@ -501,8 +448,7 @@ var FPS = ({ classNames, width = 60, height = 30, bar = "bg-cyan-500" }) => {
501
448
  };
502
449
 
503
450
  // packages/ui/react-ui-canvas/src/components/Grid/Grid.tsx
504
- import React4, { forwardRef as forwardRef2, useMemo as useMemo2, useId } from "react";
505
- import { useForwardedRef } from "@dxos/react-ui";
451
+ import React4, { forwardRef as forwardRef2, useMemo as useMemo2 } from "react";
506
452
  import { mx as mx4 } from "@dxos/react-ui-theme";
507
453
  var gridRatios = [
508
454
  1 / 4,
@@ -510,15 +456,12 @@ var gridRatios = [
510
456
  4,
511
457
  16
512
458
  ];
513
- var defaultGridSize = 16;
514
- var defaultOffset = {
459
+ var defaultOffset2 = {
515
460
  x: 0,
516
461
  y: 0
517
462
  };
518
463
  var createId = (parent, grid) => `dx-canvas-grid-${parent}-${grid}`;
519
- var GridComponent = /* @__PURE__ */ forwardRef2(({ size: gridSize = defaultGridSize, scale = 1, offset = defaultOffset, showAxes = true, classNames }, forwardedRef) => {
520
- const svgRef = useForwardedRef(forwardedRef);
521
- const instanceId = useId();
464
+ var Grid = /* @__PURE__ */ forwardRef2(({ id: parentId, size: gridSize, scale = 1, offset = defaultOffset2, classNames }, forwardedRef) => {
522
465
  const grids = useMemo2(() => gridRatios.map((ratio) => ({
523
466
  id: ratio,
524
467
  size: ratio * gridSize * scale
@@ -526,44 +469,23 @@ var GridComponent = /* @__PURE__ */ forwardRef2(({ size: gridSize = defaultGridS
526
469
  gridSize,
527
470
  scale
528
471
  ]);
529
- const { width = 0, height = 0 } = svgRef.current?.getBoundingClientRect() ?? {};
530
472
  return /* @__PURE__ */ React4.createElement("svg", {
531
473
  ...testId("dx-canvas-grid"),
532
- ref: svgRef,
474
+ ref: forwardedRef,
533
475
  className: mx4("absolute inset-0 w-full h-full pointer-events-none touch-none select-none", "stroke-neutral-500", classNames)
534
476
  }, /* @__PURE__ */ React4.createElement("defs", null, grids.map(({ id, size }) => /* @__PURE__ */ React4.createElement(GridPattern, {
535
477
  key: id,
536
- id: createId(instanceId, id),
478
+ id: createId(parentId, id),
537
479
  offset,
538
480
  size
539
- }))), showAxes && /* @__PURE__ */ React4.createElement(React4.Fragment, null, /* @__PURE__ */ React4.createElement("line", {
540
- x1: 0,
541
- y1: offset.y,
542
- x2: width,
543
- y2: offset.y,
544
- className: "stroke-neutral-500 opacity-40"
545
- }), /* @__PURE__ */ React4.createElement("line", {
546
- x1: offset.x,
547
- y1: 0,
548
- x2: offset.x,
549
- y2: height,
550
- className: "stroke-neutral-500 opacity-40"
551
- })), /* @__PURE__ */ React4.createElement("g", null, grids.map(({ id }, i) => /* @__PURE__ */ React4.createElement("rect", {
481
+ }))), /* @__PURE__ */ React4.createElement("g", null, grids.map(({ id }, i) => /* @__PURE__ */ React4.createElement("rect", {
552
482
  key: id,
553
483
  opacity: 0.1 + i * 0.05,
554
- fill: `url(#${createId(instanceId, id)})`,
484
+ fill: `url(#${createId(parentId, id)})`,
555
485
  width: "100%",
556
486
  height: "100%"
557
487
  }))));
558
488
  });
559
- var Grid = (props) => {
560
- const { scale, offset } = useCanvasContext();
561
- return /* @__PURE__ */ React4.createElement(GridComponent, {
562
- ...props,
563
- scale,
564
- offset
565
- });
566
- };
567
489
 
568
490
  // packages/ui/react-ui-canvas/src/types.ts
569
491
  import { S } from "@dxos/effect";
@@ -584,7 +506,6 @@ export {
584
506
  Dimension,
585
507
  FPS,
586
508
  Grid,
587
- GridComponent,
588
509
  GridPattern,
589
510
  Marker,
590
511
  Markers,
@@ -592,12 +513,11 @@ export {
592
513
  ProjectionMapper,
593
514
  Rect,
594
515
  createPath,
595
- defaultOrigin,
516
+ defaultOffset,
596
517
  getRelativePoint,
597
518
  getZoomTransform,
598
- inspectElement,
599
519
  testId,
600
- useCanvasContext,
520
+ useProjection,
601
521
  useWheel,
602
522
  zoomInPlace,
603
523
  zoomTo
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
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": ["React", "forwardRef", "useEffect", "useImperativeHandle", "useMemo", "useState", "useResizeDetector", "mx", "d3", "applyToPoints", "compose", "identity", "inverse", "scale", "scaleMatrix", "translate", "translateMatrix", "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", "d3", "transition", "ease", "easeSinOut", "duration", "tween", "t", "noop", "zoomTo", "cb", "interpolateObject", "on", "createContext", "useContext", "raise", "CanvasContext", "createContext", "useCanvasContext", "useContext", "raise", "Error", "bindAll", "useEffect", "React", "mx", "createPath", "points", "join", "map", "x", "y", "Markers", "id", "classNames", "Arrow", "dir", "closed", "Marker", "pos", "size", "width", "height", "circle", "cx", "cy", "r", "stroke", "className", "mx", "children", "refX", "refY", "markerWidth", "markerHeight", "fill", "rest", "marker", "markerUnits", "orient", "path", "undefined", "d", "GridPattern", "offset", "pattern", "patternUnits", "g", "line", "x1", "y1", "x2", "y2", "logged", "getRelativePoint", "el", "ev", "rect", "getBoundingClientRect", "x", "clientX", "y", "clientY", "top", "testId", "id", "inspect", "console", "log", "window", "INSPECT", "document", "querySelector", "DATA_TEST_ID", "inspectElement", "element", "defaultOptions", "zoom", "useWheel", "options", "root", "setProjection", "useCanvasContext", "useEffect", "bindAll", "type", "capture", "passive", "listener", "ev", "zooming", "isWheelZooming", "hasFocus", "preventDefault", "ctrlKey", "scale", "offset", "pos", "getRelativePoint", "scaleSensitivity", "newScale", "Math", "exp", "deltaY", "getZoomTransform", "x", "y", "deltaX", "metaKey", "abs", "deltaZ", "element", "activeElement", "document", "shadowActive", "shadowRoot", "current", "parentElement", "Canvas", "forwardRef", "children", "classNames", "scale", "_scale", "offset", "_offset", "defaultOrigin", "props", "forwardedRef", "ref", "width", "height", "useResizeDetector", "ready", "setReady", "useState", "setProjection", "useEffect", "x", "y", "projection", "useMemo", "ProjectionMapper", "update", "styles", "transform", "visibility", "useImperativeHandle", "React", "CanvasContext", "Provider", "value", "root", "current", "div", "role", "className", "mx", "React", "useEffect", "useReducer", "useRef", "mx", "SEC", "FPS", "classNames", "width", "height", "bar", "fps", "max", "len", "dispatch", "useReducer", "state", "currentTime", "Date", "now", "prevTime", "nextFPS", "Array", "Math", "floor", "fill", "round", "frames", "min", "length", "slice", "requestRef", "useRef", "tick", "current", "requestAnimationFrame", "useEffect", "cancelAnimationFrame", "React", "div", "style", "className", "mx", "map", "frame", "i", "key", "position", "bottom", "right", "React", "forwardRef", "useMemo", "useId", "useForwardedRef", "mx", "gridRatios", "defaultGridSize", "defaultOffset", "x", "y", "createId", "parent", "grid", "GridComponent", "forwardRef", "size", "gridSize", "scale", "offset", "showAxes", "classNames", "forwardedRef", "svgRef", "useForwardedRef", "instanceId", "useId", "grids", "useMemo", "map", "ratio", "id", "filter", "width", "height", "current", "getBoundingClientRect", "React", "svg", "testId", "ref", "className", "mx", "defs", "GridPattern", "key", "line", "x1", "y1", "x2", "y2", "g", "i", "rect", "opacity", "fill", "Grid", "props", "useCanvasContext", "S", "Point", "S", "Struct", "x", "Number", "y", "Dimension", "width", "height", "Rect", "extend"]
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-base 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": ["React", "forwardRef", "useEffect", "useImperativeHandle", "useMemo", "useState", "useResizeDetector", "mx", "d3", "applyToPoints", "compose", "inverse", "translate", "translateMatrix", "identity", "scale", "scaleMatrix", "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", "d3", "transition", "ease", "easeSinOut", "duration", "tween", "t", "zoomTo", "interpolateObject", "createContext", "useContext", "raise", "CanvasContext", "createContext", "useProjection", "useContext", "raise", "Error", "bindAll", "useEffect", "React", "mx", "createPath", "points", "join", "map", "x", "y", "Markers", "id", "classNames", "Arrow", "dir", "closed", "Marker", "pos", "size", "width", "height", "circle", "cx", "cy", "r", "stroke", "className", "mx", "children", "refX", "refY", "markerWidth", "markerHeight", "fill", "rest", "marker", "markerUnits", "orient", "path", "undefined", "d", "GridPattern", "offset", "pattern", "patternUnits", "g", "line", "x1", "y1", "x2", "y2", "logged", "getRelativePoint", "el", "ev", "rect", "getBoundingClientRect", "x", "clientX", "y", "clientY", "top", "testId", "id", "inspect", "console", "log", "window", "INSPECT", "document", "querySelector", "DATA_TEST_ID", "useWheel", "el", "setProjection", "useEffect", "bindAll", "type", "options", "capture", "passive", "listener", "ev", "preventDefault", "ctrlKey", "scale", "offset", "pos", "getRelativePoint", "scaleSensitivity", "newScale", "Math", "exp", "deltaY", "getZoomTransform", "x", "y", "deltaX", "Canvas", "forwardRef", "children", "classNames", "scale", "_scale", "offset", "_offset", "defaultOffset", "props", "forwardedRef", "ref", "width", "height", "useResizeDetector", "setProjection", "useState", "useEffect", "x", "y", "projection", "useMemo", "ProjectionMapper", "update", "styles", "transform", "visibility", "useImperativeHandle", "React", "CanvasContext", "Provider", "value", "root", "current", "div", "role", "className", "mx", "React", "useEffect", "useReducer", "useRef", "mx", "SEC", "FPS", "classNames", "width", "height", "bar", "fps", "max", "len", "dispatch", "useReducer", "state", "currentTime", "Date", "now", "prevTime", "nextFPS", "Array", "Math", "floor", "fill", "round", "frames", "min", "length", "slice", "requestRef", "useRef", "tick", "current", "requestAnimationFrame", "useEffect", "cancelAnimationFrame", "React", "div", "style", "className", "mx", "map", "frame", "i", "key", "position", "bottom", "right", "React", "forwardRef", "useMemo", "mx", "gridRatios", "defaultOffset", "x", "y", "createId", "parent", "grid", "Grid", "forwardRef", "id", "parentId", "size", "gridSize", "scale", "offset", "classNames", "forwardedRef", "grids", "useMemo", "map", "ratio", "filter", "React", "svg", "testId", "ref", "className", "mx", "defs", "GridPattern", "key", "g", "i", "rect", "opacity", "fill", "width", "height", "S", "Point", "S", "Struct", "x", "Number", "y", "Dimension", "width", "height", "Rect", "extend"]
7
7
  }
@@ -1 +1 @@
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/browser/index.mjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":35493},"packages/ui/react-ui-canvas/dist/lib/browser/index.mjs":{"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}}}
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":9035,"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/browser/index.mjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":30793},"packages/ui/react-ui-canvas/dist/lib/browser/index.mjs":{"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":2064},"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":13308}}}