@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
@@ -7,8 +7,8 @@ import { mx as mx2 } from "@dxos/react-ui-theme";
7
7
 
8
8
  // packages/ui/react-ui-canvas/src/hooks/projection.tsx
9
9
  import * as d3 from "d3";
10
- import { applyToPoints, compose, identity, inverse, scale as scaleMatrix, translate as translateMatrix } from "transformation-matrix";
11
- var defaultOrigin = {
10
+ import { applyToPoints, compose, inverse, translate as translateMatrix, identity, scale as scaleMatrix } from "transformation-matrix";
11
+ var defaultOffset = {
12
12
  x: 0,
13
13
  y: 0
14
14
  };
@@ -19,7 +19,7 @@ var ProjectionMapper = class {
19
19
  height: 0
20
20
  };
21
21
  this._scale = 1;
22
- this._offset = defaultOrigin;
22
+ this._offset = defaultOffset;
23
23
  this._toScreen = identity();
24
24
  this._toModel = identity();
25
25
  if (bounds && scale && offset) {
@@ -30,11 +30,7 @@ var ProjectionMapper = class {
30
30
  this._bounds = bounds;
31
31
  this._scale = scale;
32
32
  this._offset = offset;
33
- this._toScreen = compose(
34
- // NOTE: Order is important.
35
- translateMatrix(this._offset.x, this._offset.y),
36
- scaleMatrix(this._scale)
37
- );
33
+ this._toScreen = compose(translateMatrix(this._offset.x, this._offset.y), scaleMatrix(this._scale));
38
34
  this._toModel = inverse(this._toScreen);
39
35
  return this;
40
36
  }
@@ -75,9 +71,7 @@ var zoomInPlace = (setTransform, pos, offset, current, next, delay = 200) => {
75
71
  }));
76
72
  });
77
73
  };
78
- var noop = () => {
79
- };
80
- var zoomTo = (setTransform, current, next, delay = 200, cb = noop) => {
74
+ var zoomTo = (setTransform, current, next, delay = 200) => {
81
75
  const is = d3.interpolateObject({
82
76
  scale: current.scale,
83
77
  ...current.offset
@@ -94,14 +88,14 @@ var zoomTo = (setTransform, current, next, delay = 200, cb = noop) => {
94
88
  y
95
89
  }
96
90
  });
97
- }).on("end", cb);
91
+ });
98
92
  };
99
93
 
100
- // packages/ui/react-ui-canvas/src/hooks/useCanvasContext.tsx
94
+ // packages/ui/react-ui-canvas/src/hooks/useProjection.tsx
101
95
  import { createContext, useContext } from "react";
102
96
  import { raise } from "@dxos/debug";
103
97
  var CanvasContext = /* @__PURE__ */ createContext(null);
104
- var useCanvasContext = () => {
98
+ var useProjection = () => {
105
99
  return useContext(CanvasContext) ?? raise(new Error("Missing CanvasContext"));
106
100
  };
107
101
 
@@ -141,16 +135,16 @@ var Markers = ({ id = "dx-marker", classNames }) => {
141
135
  }), /* @__PURE__ */ React.createElement(Marker, {
142
136
  id: `${id}-circle`,
143
137
  pos: {
144
- x: 8,
145
- y: 8
138
+ x: 6,
139
+ y: 6
146
140
  },
147
141
  size: {
148
- width: 16,
149
- height: 16
142
+ width: 12,
143
+ height: 12
150
144
  }
151
145
  }, /* @__PURE__ */ React.createElement("circle", {
152
- cx: 8,
153
- cy: 8,
146
+ cx: 6,
147
+ cy: 6,
154
148
  r: 5,
155
149
  stroke: "context-stroke",
156
150
  className: mx(classNames)
@@ -258,27 +252,15 @@ var testId = (id, inspect = false) => {
258
252
  [DATA_TEST_ID]: id
259
253
  };
260
254
  };
261
- var inspectElement = (el) => {
262
- window.INSPECT = () => {
263
- window.inspect(el);
264
- window.element = el;
265
- console.log("Open storybook in expanded window;\nthen run INSPECT()");
266
- console.log(el);
267
- };
268
- };
269
255
  var DATA_TEST_ID = "data-test-id";
270
256
 
271
257
  // packages/ui/react-ui-canvas/src/hooks/useWheel.tsx
272
- var defaultOptions = {
273
- zoom: true
274
- };
275
- var useWheel = (options = defaultOptions) => {
276
- const { root, setProjection } = useCanvasContext();
258
+ var useWheel = (el, setProjection) => {
277
259
  useEffect(() => {
278
- if (!root) {
260
+ if (!el) {
279
261
  return;
280
262
  }
281
- return bindAll(root, [
263
+ return bindAll(el, [
282
264
  {
283
265
  type: "wheel",
284
266
  options: {
@@ -286,20 +268,13 @@ var useWheel = (options = defaultOptions) => {
286
268
  passive: false
287
269
  },
288
270
  listener: (ev) => {
289
- const zooming = isWheelZooming(ev);
290
- if (!hasFocus(root) && !zooming) {
291
- return;
292
- }
293
271
  ev.preventDefault();
294
- if (zooming && !options.zoom) {
295
- return;
296
- }
297
272
  if (ev.ctrlKey) {
298
- if (!root) {
273
+ if (!el) {
299
274
  return;
300
275
  }
301
276
  setProjection(({ scale, offset }) => {
302
- const pos = getRelativePoint(root, ev);
277
+ const pos = getRelativePoint(el, ev);
303
278
  const scaleSensitivity = 0.01;
304
279
  const newScale = scale * Math.exp(-ev.deltaY * scaleSensitivity);
305
280
  return getZoomTransform({
@@ -324,44 +299,20 @@ var useWheel = (options = defaultOptions) => {
324
299
  }
325
300
  ]);
326
301
  }, [
327
- root
302
+ el,
303
+ setProjection
328
304
  ]);
329
305
  };
330
- var isWheelZooming = (ev) => {
331
- if (ev.ctrlKey || ev.metaKey) {
332
- return Math.abs(ev.deltaY) > 0 || Math.abs(ev.deltaZ) > 0;
333
- }
334
- return false;
335
- };
336
- var hasFocus = (element) => {
337
- const activeElement = document.activeElement;
338
- if (!activeElement) {
339
- return false;
340
- }
341
- let shadowActive = activeElement;
342
- while (shadowActive?.shadowRoot?.activeElement) {
343
- shadowActive = shadowActive.shadowRoot.activeElement;
344
- }
345
- let current = element;
346
- while (current) {
347
- if (current === activeElement || current === shadowActive) {
348
- return true;
349
- }
350
- current = current.parentElement;
351
- }
352
- return false;
353
- };
354
306
 
355
307
  // packages/ui/react-ui-canvas/src/components/Canvas/Canvas.tsx
356
- var Canvas = /* @__PURE__ */ forwardRef(({ children, classNames, scale: _scale = 1, offset: _offset = defaultOrigin, ...props }, forwardedRef) => {
308
+ var Canvas = /* @__PURE__ */ forwardRef(({ children, classNames, scale: _scale = 1, offset: _offset = defaultOffset, ...props }, forwardedRef) => {
357
309
  const { ref, width = 0, height = 0 } = useResizeDetector();
358
- const [ready, setReady] = useState(false);
359
310
  const [{ scale, offset }, setProjection] = useState({
360
311
  scale: _scale,
361
312
  offset: _offset
362
313
  });
363
314
  useEffect2(() => {
364
- if (width && height && offset === defaultOrigin) {
315
+ if (width && height && offset === defaultOffset) {
365
316
  setProjection({
366
317
  scale,
367
318
  offset: {
@@ -382,9 +333,6 @@ var Canvas = /* @__PURE__ */ forwardRef(({ children, classNames, scale: _scale =
382
333
  width,
383
334
  height
384
335
  }, scale, offset);
385
- if (offset !== defaultOrigin) {
386
- setReady(true);
387
- }
388
336
  }, [
389
337
  projection,
390
338
  scale,
@@ -414,7 +362,6 @@ var Canvas = /* @__PURE__ */ forwardRef(({ children, classNames, scale: _scale =
414
362
  return /* @__PURE__ */ React2.createElement(CanvasContext.Provider, {
415
363
  value: {
416
364
  root: ref.current,
417
- ready,
418
365
  width,
419
366
  height,
420
367
  scale,
@@ -428,7 +375,7 @@ var Canvas = /* @__PURE__ */ forwardRef(({ children, classNames, scale: _scale =
428
375
  ...props,
429
376
  className: mx2("absolute inset-0 overflow-hidden", classNames),
430
377
  ref
431
- }, ready ? children : null));
378
+ }, children));
432
379
  });
433
380
 
434
381
  // packages/ui/react-ui-canvas/src/components/FPS.tsx
@@ -483,7 +430,7 @@ var FPS = ({ classNames, width = 60, height = 30, bar = "bg-cyan-500" }) => {
483
430
  style: {
484
431
  width: width + 6
485
432
  },
486
- className: mx3("relative flex flex-col p-0.5", "bg-baseSurface text-xs text-subdued font-thin pointer-events-none border border-separator", classNames)
433
+ className: mx3("relative flex flex-col p-0.5", "bg-base text-xs text-subdued font-thin pointer-events-none border border-separator", classNames)
487
434
  }, /* @__PURE__ */ React3.createElement("div", null, fps[len - 1], " FPS"), /* @__PURE__ */ React3.createElement("div", {
488
435
  className: "w-full relative",
489
436
  style: {
@@ -503,8 +450,7 @@ var FPS = ({ classNames, width = 60, height = 30, bar = "bg-cyan-500" }) => {
503
450
  };
504
451
 
505
452
  // packages/ui/react-ui-canvas/src/components/Grid/Grid.tsx
506
- import React4, { forwardRef as forwardRef2, useMemo as useMemo2, useId } from "react";
507
- import { useForwardedRef } from "@dxos/react-ui";
453
+ import React4, { forwardRef as forwardRef2, useMemo as useMemo2 } from "react";
508
454
  import { mx as mx4 } from "@dxos/react-ui-theme";
509
455
  var gridRatios = [
510
456
  1 / 4,
@@ -512,15 +458,12 @@ var gridRatios = [
512
458
  4,
513
459
  16
514
460
  ];
515
- var defaultGridSize = 16;
516
- var defaultOffset = {
461
+ var defaultOffset2 = {
517
462
  x: 0,
518
463
  y: 0
519
464
  };
520
465
  var createId = (parent, grid) => `dx-canvas-grid-${parent}-${grid}`;
521
- var GridComponent = /* @__PURE__ */ forwardRef2(({ size: gridSize = defaultGridSize, scale = 1, offset = defaultOffset, showAxes = true, classNames }, forwardedRef) => {
522
- const svgRef = useForwardedRef(forwardedRef);
523
- const instanceId = useId();
466
+ var Grid = /* @__PURE__ */ forwardRef2(({ id: parentId, size: gridSize, scale = 1, offset = defaultOffset2, classNames }, forwardedRef) => {
524
467
  const grids = useMemo2(() => gridRatios.map((ratio) => ({
525
468
  id: ratio,
526
469
  size: ratio * gridSize * scale
@@ -528,44 +471,23 @@ var GridComponent = /* @__PURE__ */ forwardRef2(({ size: gridSize = defaultGridS
528
471
  gridSize,
529
472
  scale
530
473
  ]);
531
- const { width = 0, height = 0 } = svgRef.current?.getBoundingClientRect() ?? {};
532
474
  return /* @__PURE__ */ React4.createElement("svg", {
533
475
  ...testId("dx-canvas-grid"),
534
- ref: svgRef,
476
+ ref: forwardedRef,
535
477
  className: mx4("absolute inset-0 w-full h-full pointer-events-none touch-none select-none", "stroke-neutral-500", classNames)
536
478
  }, /* @__PURE__ */ React4.createElement("defs", null, grids.map(({ id, size }) => /* @__PURE__ */ React4.createElement(GridPattern, {
537
479
  key: id,
538
- id: createId(instanceId, id),
480
+ id: createId(parentId, id),
539
481
  offset,
540
482
  size
541
- }))), showAxes && /* @__PURE__ */ React4.createElement(React4.Fragment, null, /* @__PURE__ */ React4.createElement("line", {
542
- x1: 0,
543
- y1: offset.y,
544
- x2: width,
545
- y2: offset.y,
546
- className: "stroke-neutral-500 opacity-40"
547
- }), /* @__PURE__ */ React4.createElement("line", {
548
- x1: offset.x,
549
- y1: 0,
550
- x2: offset.x,
551
- y2: height,
552
- className: "stroke-neutral-500 opacity-40"
553
- })), /* @__PURE__ */ React4.createElement("g", null, grids.map(({ id }, i) => /* @__PURE__ */ React4.createElement("rect", {
483
+ }))), /* @__PURE__ */ React4.createElement("g", null, grids.map(({ id }, i) => /* @__PURE__ */ React4.createElement("rect", {
554
484
  key: id,
555
485
  opacity: 0.1 + i * 0.05,
556
- fill: `url(#${createId(instanceId, id)})`,
486
+ fill: `url(#${createId(parentId, id)})`,
557
487
  width: "100%",
558
488
  height: "100%"
559
489
  }))));
560
490
  });
561
- var Grid = (props) => {
562
- const { scale, offset } = useCanvasContext();
563
- return /* @__PURE__ */ React4.createElement(GridComponent, {
564
- ...props,
565
- scale,
566
- offset
567
- });
568
- };
569
491
 
570
492
  // packages/ui/react-ui-canvas/src/types.ts
571
493
  import { S } from "@dxos/effect";
@@ -586,7 +508,6 @@ export {
586
508
  Dimension,
587
509
  FPS,
588
510
  Grid,
589
- GridComponent,
590
511
  GridPattern,
591
512
  Marker,
592
513
  Markers,
@@ -594,12 +515,11 @@ export {
594
515
  ProjectionMapper,
595
516
  Rect,
596
517
  createPath,
597
- defaultOrigin,
518
+ defaultOffset,
598
519
  getRelativePoint,
599
520
  getZoomTransform,
600
- inspectElement,
601
521
  testId,
602
- useCanvasContext,
522
+ useProjection,
603
523
  useWheel,
604
524
  zoomInPlace,
605
525
  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/node-esm/index.mjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":35495},"packages/ui/react-ui-canvas/dist/lib/node-esm/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":15656}}}
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/node-esm/index.mjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":30795},"packages/ui/react-ui-canvas/dist/lib/node-esm/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":13401}}}
@@ -1,4 +1,4 @@
1
- import React, { type HTMLAttributes, type PropsWithChildren } from 'react';
1
+ import React, { type PropsWithChildren, type HTMLAttributes } from 'react';
2
2
  import { type ThemedClassName } from '@dxos/react-ui';
3
3
  import { type ProjectionState } from '../../hooks';
4
4
  export interface CanvasController {
@@ -1 +1 @@
1
- {"version":3,"file":"Canvas.d.ts","sourceRoot":"","sources":["../../../../../src/components/Canvas/Canvas.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,EAEZ,KAAK,cAAc,EACnB,KAAK,iBAAiB,EAMvB,MAAM,OAAO,CAAC;AAGf,OAAO,EAAE,KAAK,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAGtD,OAAO,EAAkD,KAAK,eAAe,EAAE,MAAM,aAAa,CAAC;AAEnG,MAAM,WAAW,gBAAgB;IAC/B,aAAa,CAAC,UAAU,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3D;AAED,MAAM,MAAM,WAAW,GAAG,eAAe,CAAC,iBAAiB,CAAC,OAAO,CAAC,eAAe,CAAC,GAAG,cAAc,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC;AAExH;;;GAGG;AACH,eAAO,MAAM,MAAM;;0CAyDlB,CAAC"}
1
+ {"version":3,"file":"Canvas.d.ts","sourceRoot":"","sources":["../../../../../src/components/Canvas/Canvas.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,EAEZ,KAAK,iBAAiB,EAMtB,KAAK,cAAc,EACpB,MAAM,OAAO,CAAC;AAGf,OAAO,EAAE,KAAK,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAGtD,OAAO,EAAkD,KAAK,eAAe,EAAE,MAAM,aAAa,CAAC;AAEnG,MAAM,WAAW,gBAAgB;IAC/B,aAAa,CAAC,UAAU,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3D;AAED,MAAM,MAAM,WAAW,GAAG,eAAe,CAAC,iBAAiB,CAAC,OAAO,CAAC,eAAe,CAAC,GAAG,cAAc,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC;AAExH;;;GAGG;AACH,eAAO,MAAM,MAAM;;0CAmDlB,CAAC"}
@@ -5,5 +5,4 @@ declare const meta: Meta<GridProps>;
5
5
  export default meta;
6
6
  type Story = StoryObj<GridProps>;
7
7
  export declare const Default: Story;
8
- export declare const SideBySide: Story;
9
8
  //# sourceMappingURL=Canvas.stories.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Canvas.stories.d.ts","sourceRoot":"","sources":["../../../../../src/components/Canvas/Canvas.stories.tsx"],"names":[],"mappings":"AAIA,OAAO,aAAa,CAAC;AAErB,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AASvD,OAAO,EAAQ,KAAK,SAAS,EAAE,MAAM,SAAS,CAAC;AA2E/C,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,SAAS,CAKzB,CAAC;AAEF,eAAe,IAAI,CAAC;AAEpB,KAAK,KAAK,GAAG,QAAQ,CAAC,SAAS,CAAC,CAAC;AAEjC,eAAO,MAAM,OAAO,EAAE,KAErB,CAAC;AAEF,eAAO,MAAM,UAAU,EAAE,KAGxB,CAAC"}
1
+ {"version":3,"file":"Canvas.stories.d.ts","sourceRoot":"","sources":["../../../../../src/components/Canvas/Canvas.stories.tsx"],"names":[],"mappings":"AAIA,OAAO,aAAa,CAAC;AAErB,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AASvD,OAAO,EAAQ,KAAK,SAAS,EAAE,MAAM,SAAS,CAAC;AAkD/C,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,SAAS,CAKzB,CAAC;AAEF,eAAe,IAAI,CAAC;AAEpB,KAAK,KAAK,GAAG,QAAQ,CAAC,SAAS,CAAC,CAAC;AAEjC,eAAO,MAAM,OAAO,EAAE,KAKrB,CAAC"}
@@ -2,18 +2,17 @@ import React from 'react';
2
2
  import { type ThemedClassName } from '@dxos/react-ui';
3
3
  import { type Point } from '../../types';
4
4
  export type GridProps = ThemedClassName<{
5
- size?: number;
5
+ id: string;
6
+ size: number;
6
7
  scale?: number;
7
8
  offset?: Point;
8
- showAxes?: boolean;
9
9
  }>;
10
- export declare const GridComponent: React.ForwardRefExoticComponent<Omit<{
11
- size?: number;
10
+ export declare const Grid: React.ForwardRefExoticComponent<Omit<{
11
+ id: string;
12
+ size: number;
12
13
  scale?: number;
13
14
  offset?: Point;
14
- showAxes?: boolean;
15
15
  }, "className"> & {
16
16
  classNames?: import("@dxos/react-ui").ClassNameValue;
17
17
  } & React.RefAttributes<SVGSVGElement>>;
18
- export declare const Grid: (props: GridProps) => React.JSX.Element;
19
18
  //# sourceMappingURL=Grid.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Grid.d.ts","sourceRoot":"","sources":["../../../../../src/components/Grid/Grid.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAqC,MAAM,OAAO,CAAC;AAE1D,OAAO,EAAmB,KAAK,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAIvE,OAAO,EAAE,KAAK,KAAK,EAAE,MAAM,aAAa,CAAC;AAUzC,MAAM,MAAM,SAAS,GAAG,eAAe,CAAC;IACtC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,KAAK,CAAC;IACf,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,CAAC,CAAC;AAEH,eAAO,MAAM,aAAa;WANjB,MAAM;YACL,MAAM;aACL,KAAK;eACH,OAAO;;;uCAwDnB,CAAC;AAGF,eAAO,MAAM,IAAI,UAAW,SAAS,sBAGpC,CAAC"}
1
+ {"version":3,"file":"Grid.d.ts","sourceRoot":"","sources":["../../../../../src/components/Grid/Grid.tsx"],"names":[],"mappings":"AAIA,OAAO,KAA8B,MAAM,OAAO,CAAC;AAEnD,OAAO,EAAE,KAAK,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAGtD,OAAO,EAAE,KAAK,KAAK,EAAE,MAAM,aAAa,CAAC;AASzC,MAAM,MAAM,SAAS,GAAG,eAAe,CAAC;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,KAAK,CAAA;CAAE,CAAC,CAAC;AAEtG,eAAO,MAAM,IAAI;QAF6B,MAAM;UAAQ,MAAM;YAAU,MAAM;aAAW,KAAK;;;uCA0CjG,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"Grid.stories.d.ts","sourceRoot":"","sources":["../../../../../src/components/Grid/Grid.stories.tsx"],"names":[],"mappings":"AAIA,OAAO,aAAa,CAAC;AAErB,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAKvD,OAAO,EAAiB,KAAK,SAAS,EAAE,MAAM,QAAQ,CAAC;AAcvD,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,SAAS,CAKzB,CAAC;AAEF,eAAe,IAAI,CAAC;AAEpB,KAAK,KAAK,GAAG,QAAQ,CAAC,SAAS,CAAC,CAAC;AAEjC,eAAO,MAAM,OAAO,EAAE,KAIrB,CAAC"}
1
+ {"version":3,"file":"Grid.stories.d.ts","sourceRoot":"","sources":["../../../../../src/components/Grid/Grid.stories.tsx"],"names":[],"mappings":"AAIA,OAAO,aAAa,CAAC;AAErB,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAKvD,OAAO,EAAQ,KAAK,SAAS,EAAE,MAAM,QAAQ,CAAC;AAgB9C,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,SAAS,CAKzB,CAAC;AAEF,eAAe,IAAI,CAAC;AAEpB,KAAK,KAAK,GAAG,QAAQ,CAAC,SAAS,CAAC,CAAC;AAEjC,eAAO,MAAM,OAAO,EAAE,KAIrB,CAAC"}