@dxos/react-ui-canvas 0.8.1 → 0.8.2-main.10c050d

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.
@@ -54,19 +54,23 @@ __export(node_exports, {
54
54
  zoomTo: () => zoomTo
55
55
  });
56
56
  module.exports = __toCommonJS(node_exports);
57
+ var import_tracking = require("@preact-signals/safe-react/tracking");
57
58
  var import_react = __toESM(require("react"));
58
59
  var import_react_resize_detector = require("react-resize-detector");
59
60
  var import_react_ui_theme = require("@dxos/react-ui-theme");
60
- var d3 = __toESM(require("d3"));
61
+ var import_d3 = require("d3");
61
62
  var import_transformation_matrix = require("transformation-matrix");
62
63
  var import_react2 = require("react");
63
64
  var import_debug = require("@dxos/debug");
64
65
  var import_bind_event_listener = require("bind-event-listener");
65
66
  var import_react3 = require("react");
67
+ var import_tracking2 = require("@preact-signals/safe-react/tracking");
66
68
  var import_react4 = __toESM(require("react"));
67
69
  var import_react_ui_theme2 = require("@dxos/react-ui-theme");
70
+ var import_tracking3 = require("@preact-signals/safe-react/tracking");
68
71
  var import_react5 = __toESM(require("react"));
69
72
  var import_react_ui_theme3 = require("@dxos/react-ui-theme");
73
+ var import_tracking4 = require("@preact-signals/safe-react/tracking");
70
74
  var import_react6 = __toESM(require("react"));
71
75
  var import_react_ui = require("@dxos/react-ui");
72
76
  var import_react_ui_theme4 = require("@dxos/react-ui-theme");
@@ -127,8 +131,8 @@ var getZoomTransform = ({ scale, offset, pos, newScale }) => {
127
131
  };
128
132
  };
129
133
  var zoomInPlace = (setTransform, pos, offset, current, next, delay = 200) => {
130
- const is = d3.interpolate(current, next);
131
- d3.transition().ease(d3.easeSinOut).duration(delay).tween("zoom", () => (t) => {
134
+ const is = (0, import_d3.interpolate)(current, next);
135
+ (0, import_d3.transition)().ease(import_d3.easeSinOut).duration(delay).tween("zoom", () => (t) => {
132
136
  const newScale = is(t);
133
137
  setTransform(getZoomTransform({
134
138
  scale: current,
@@ -141,14 +145,14 @@ var zoomInPlace = (setTransform, pos, offset, current, next, delay = 200) => {
141
145
  var noop = () => {
142
146
  };
143
147
  var zoomTo = (setTransform, current, next, delay = 200, cb = noop) => {
144
- const is = d3.interpolateObject({
148
+ const is = (0, import_d3.interpolateObject)({
145
149
  scale: current.scale,
146
150
  ...current.offset
147
151
  }, {
148
152
  scale: next.scale,
149
153
  ...next.offset
150
154
  });
151
- d3.transition().ease(d3.easeSinOut).duration(delay).tween("zoom", () => (t) => {
155
+ (0, import_d3.transition)().ease(import_d3.easeSinOut).duration(delay).tween("zoom", () => (t) => {
152
156
  const { scale, x, y } = is(t);
153
157
  setTransform({
154
158
  scale,
@@ -171,118 +175,144 @@ var createPath = (points, join = false) => {
171
175
  ].join(" ");
172
176
  };
173
177
  var Markers = ({ id = "dx-marker", classNames }) => {
174
- return /* @__PURE__ */ import_react4.default.createElement(import_react4.default.Fragment, null, /* @__PURE__ */ import_react4.default.createElement(Arrow, {
175
- id: `${id}-arrow-start`,
176
- dir: "start",
177
- classNames
178
- }), /* @__PURE__ */ import_react4.default.createElement(Arrow, {
179
- id: `${id}-arrow-end`,
180
- dir: "end",
181
- classNames
182
- }), /* @__PURE__ */ import_react4.default.createElement(Arrow, {
183
- id: `${id}-triangle-start`,
184
- dir: "start",
185
- closed: true,
186
- classNames
187
- }), /* @__PURE__ */ import_react4.default.createElement(Arrow, {
188
- id: `${id}-triangle-end`,
189
- dir: "end",
190
- closed: true,
191
- classNames
192
- }), /* @__PURE__ */ import_react4.default.createElement(Marker, {
193
- id: `${id}-circle`,
194
- pos: {
195
- x: 8,
196
- y: 8
197
- },
198
- size: {
199
- width: 16,
200
- height: 16
201
- }
202
- }, /* @__PURE__ */ import_react4.default.createElement("circle", {
203
- cx: 8,
204
- cy: 8,
205
- r: 5,
206
- stroke: "context-stroke",
207
- className: (0, import_react_ui_theme2.mx)(classNames)
208
- })));
178
+ var _effect = (0, import_tracking2.useSignals)();
179
+ try {
180
+ return /* @__PURE__ */ import_react4.default.createElement(import_react4.default.Fragment, null, /* @__PURE__ */ import_react4.default.createElement(Arrow, {
181
+ id: `${id}-arrow-start`,
182
+ dir: "start",
183
+ classNames
184
+ }), /* @__PURE__ */ import_react4.default.createElement(Arrow, {
185
+ id: `${id}-arrow-end`,
186
+ dir: "end",
187
+ classNames
188
+ }), /* @__PURE__ */ import_react4.default.createElement(Arrow, {
189
+ id: `${id}-triangle-start`,
190
+ dir: "start",
191
+ closed: true,
192
+ classNames
193
+ }), /* @__PURE__ */ import_react4.default.createElement(Arrow, {
194
+ id: `${id}-triangle-end`,
195
+ dir: "end",
196
+ closed: true,
197
+ classNames
198
+ }), /* @__PURE__ */ import_react4.default.createElement(Marker, {
199
+ id: `${id}-circle`,
200
+ pos: {
201
+ x: 8,
202
+ y: 8
203
+ },
204
+ size: {
205
+ width: 16,
206
+ height: 16
207
+ }
208
+ }, /* @__PURE__ */ import_react4.default.createElement("circle", {
209
+ cx: 8,
210
+ cy: 8,
211
+ r: 5,
212
+ stroke: "context-stroke",
213
+ className: (0, import_react_ui_theme2.mx)(classNames)
214
+ })));
215
+ } finally {
216
+ _effect.f();
217
+ }
209
218
  };
210
- var Marker = ({ id, className, children, pos: { x: refX, y: refY }, size: { width: markerWidth, height: markerHeight }, fill, ...rest }) => /* @__PURE__ */ import_react4.default.createElement("marker", {
211
- id,
212
- className,
213
- refX,
214
- refY,
215
- markerWidth,
216
- markerHeight,
217
- markerUnits: "strokeWidth",
218
- orient: "auto",
219
- ...rest
220
- }, children);
221
- var Arrow = ({ classNames, id, size = 16, dir = "end", closed = false }) => /* @__PURE__ */ import_react4.default.createElement(Marker, {
222
- id,
223
- size: {
224
- width: size,
225
- height: size
226
- },
227
- pos: dir === "end" ? {
228
- x: size,
229
- y: size / 2
230
- } : {
231
- x: 0,
232
- y: size / 2
219
+ var Marker = ({ id, className, children, pos: { x: refX, y: refY }, size: { width: markerWidth, height: markerHeight }, fill, ...rest }) => {
220
+ var _effect = (0, import_tracking2.useSignals)();
221
+ try {
222
+ return /* @__PURE__ */ import_react4.default.createElement("marker", {
223
+ id,
224
+ className,
225
+ refX,
226
+ refY,
227
+ markerWidth,
228
+ markerHeight,
229
+ markerUnits: "strokeWidth",
230
+ orient: "auto",
231
+ ...rest
232
+ }, children);
233
+ } finally {
234
+ _effect.f();
233
235
  }
234
- }, /* @__PURE__ */ import_react4.default.createElement("path", {
235
- fill: closed ? void 0 : "none",
236
- stroke: "context-stroke",
237
- className: (0, import_react_ui_theme2.mx)(classNames),
238
- d: createPath(dir === "end" ? [
239
- {
240
- x: 1,
241
- y: 1
242
- },
243
- {
244
- x: size,
245
- y: size / 2
246
- },
247
- {
248
- x: 1,
249
- y: size - 1
250
- }
251
- ] : [
252
- {
253
- x: size - 1,
254
- y: 1
255
- },
256
- {
257
- x: 0,
258
- y: size / 2
259
- },
260
- {
261
- x: size - 1,
262
- y: size - 1
263
- }
264
- ], closed)
265
- }));
266
- var GridPattern = ({ classNames, id, size, offset }) => /* @__PURE__ */ import_react4.default.createElement("pattern", {
267
- id,
268
- x: (size / 2 + offset.x) % size,
269
- y: (size / 2 + offset.y) % size,
270
- width: size,
271
- height: size,
272
- patternUnits: "userSpaceOnUse"
273
- }, /* @__PURE__ */ import_react4.default.createElement("g", {
274
- className: (0, import_react_ui_theme2.mx)(classNames)
275
- }, /* @__PURE__ */ import_react4.default.createElement("line", {
276
- x1: 0,
277
- y1: size / 2,
278
- x2: size,
279
- y2: size / 2
280
- }), /* @__PURE__ */ import_react4.default.createElement("line", {
281
- x1: size / 2,
282
- y1: 0,
283
- x2: size / 2,
284
- y2: size
285
- })));
236
+ };
237
+ var Arrow = ({ classNames, id, size = 16, dir = "end", closed = false }) => {
238
+ var _effect = (0, import_tracking2.useSignals)();
239
+ try {
240
+ return /* @__PURE__ */ import_react4.default.createElement(Marker, {
241
+ id,
242
+ size: {
243
+ width: size,
244
+ height: size
245
+ },
246
+ pos: dir === "end" ? {
247
+ x: size,
248
+ y: size / 2
249
+ } : {
250
+ x: 0,
251
+ y: size / 2
252
+ }
253
+ }, /* @__PURE__ */ import_react4.default.createElement("path", {
254
+ fill: closed ? void 0 : "none",
255
+ stroke: "context-stroke",
256
+ className: (0, import_react_ui_theme2.mx)(classNames),
257
+ d: createPath(dir === "end" ? [
258
+ {
259
+ x: 1,
260
+ y: 1
261
+ },
262
+ {
263
+ x: size,
264
+ y: size / 2
265
+ },
266
+ {
267
+ x: 1,
268
+ y: size - 1
269
+ }
270
+ ] : [
271
+ {
272
+ x: size - 1,
273
+ y: 1
274
+ },
275
+ {
276
+ x: 0,
277
+ y: size / 2
278
+ },
279
+ {
280
+ x: size - 1,
281
+ y: size - 1
282
+ }
283
+ ], closed)
284
+ }));
285
+ } finally {
286
+ _effect.f();
287
+ }
288
+ };
289
+ var GridPattern = ({ classNames, id, size, offset }) => {
290
+ var _effect = (0, import_tracking2.useSignals)();
291
+ try {
292
+ return /* @__PURE__ */ import_react4.default.createElement("pattern", {
293
+ id,
294
+ x: (size / 2 + offset.x) % size,
295
+ y: (size / 2 + offset.y) % size,
296
+ width: size,
297
+ height: size,
298
+ patternUnits: "userSpaceOnUse"
299
+ }, /* @__PURE__ */ import_react4.default.createElement("g", {
300
+ className: (0, import_react_ui_theme2.mx)(classNames)
301
+ }, /* @__PURE__ */ import_react4.default.createElement("line", {
302
+ x1: 0,
303
+ y1: size / 2,
304
+ x2: size,
305
+ y2: size / 2
306
+ }), /* @__PURE__ */ import_react4.default.createElement("line", {
307
+ x1: size / 2,
308
+ y1: 0,
309
+ x2: size / 2,
310
+ y2: size
311
+ })));
312
+ } finally {
313
+ _effect.f();
314
+ }
315
+ };
286
316
  var logged = false;
287
317
  var getRelativePoint = (el, ev) => {
288
318
  const rect = el.getBoundingClientRect();
@@ -399,148 +429,158 @@ var hasFocus = (element) => {
399
429
  return false;
400
430
  };
401
431
  var Canvas = /* @__PURE__ */ (0, import_react.forwardRef)(({ children, classNames, scale: _scale = 1, offset: _offset = defaultOrigin, ...props }, forwardedRef) => {
402
- const { ref, width = 0, height = 0 } = (0, import_react_resize_detector.useResizeDetector)();
403
- const [ready, setReady] = (0, import_react.useState)(false);
404
- const [{ scale, offset }, setProjection] = (0, import_react.useState)({
405
- scale: _scale,
406
- offset: _offset
407
- });
408
- (0, import_react.useEffect)(() => {
409
- if (width && height && offset === defaultOrigin) {
410
- setProjection({
411
- scale,
412
- offset: {
413
- x: width / 2,
414
- y: height / 2
415
- }
416
- });
417
- }
418
- }, [
419
- width,
420
- height,
421
- scale,
422
- offset
423
- ]);
424
- const projection = (0, import_react.useMemo)(() => new ProjectionMapper(), []);
425
- (0, import_react.useEffect)(() => {
426
- projection.update({
427
- width,
428
- height
429
- }, scale, offset);
430
- if (offset !== defaultOrigin) {
431
- setReady(true);
432
- }
433
- }, [
434
- projection,
435
- scale,
436
- offset,
437
- width,
438
- height
439
- ]);
440
- const styles = (0, import_react.useMemo)(() => {
441
- return {
442
- // NOTE: Order is important.
443
- transform: `translate(${offset.x}px, ${offset.y}px) scale(${scale})`,
444
- visibility: width && height ? "visible" : "hidden"
445
- };
446
- }, [
447
- scale,
448
- offset
449
- ]);
450
- (0, import_react.useImperativeHandle)(forwardedRef, () => {
451
- return {
452
- setProjection: async (projection2) => {
453
- setProjection(projection2);
432
+ var _effect = (0, import_tracking.useSignals)();
433
+ try {
434
+ const { ref, width = 0, height = 0 } = (0, import_react_resize_detector.useResizeDetector)();
435
+ const [ready, setReady] = (0, import_react.useState)(false);
436
+ const [{ scale, offset }, setProjection] = (0, import_react.useState)({
437
+ scale: _scale,
438
+ offset: _offset
439
+ });
440
+ (0, import_react.useEffect)(() => {
441
+ if (width && height && offset === defaultOrigin) {
442
+ setProjection({
443
+ scale,
444
+ offset: {
445
+ x: width / 2,
446
+ y: height / 2
447
+ }
448
+ });
454
449
  }
455
- };
456
- }, [
457
- ref
458
- ]);
459
- return /* @__PURE__ */ import_react.default.createElement(CanvasContext.Provider, {
460
- value: {
461
- root: ref.current,
462
- ready,
450
+ }, [
463
451
  width,
464
452
  height,
465
453
  scale,
466
- offset,
467
- styles,
454
+ offset
455
+ ]);
456
+ const projection = (0, import_react.useMemo)(() => new ProjectionMapper(), []);
457
+ (0, import_react.useEffect)(() => {
458
+ projection.update({
459
+ width,
460
+ height
461
+ }, scale, offset);
462
+ if (offset !== defaultOrigin) {
463
+ setReady(true);
464
+ }
465
+ }, [
468
466
  projection,
469
- setProjection
470
- }
471
- }, /* @__PURE__ */ import_react.default.createElement("div", {
472
- role: "none",
473
- ...props,
474
- className: (0, import_react_ui_theme.mx)("absolute inset-0 overflow-hidden", classNames),
475
- ref
476
- }, ready ? children : null));
477
- });
478
- var SEC = 1e3;
479
- var FPS = ({ classNames, width = 60, height = 30, bar = "bg-cyan-500" }) => {
480
- const [{ fps, max, len }, dispatch] = (0, import_react5.useReducer)((state) => {
481
- const currentTime = Date.now();
482
- if (currentTime > state.prevTime + SEC) {
483
- const nextFPS = [
484
- ...new Array(Math.floor((currentTime - state.prevTime - SEC) / SEC)).fill(0),
485
- Math.max(1, Math.round(state.frames * SEC / (currentTime - state.prevTime)))
486
- ];
467
+ scale,
468
+ offset,
469
+ width,
470
+ height
471
+ ]);
472
+ const styles = (0, import_react.useMemo)(() => {
487
473
  return {
488
- max: Math.max(state.max, ...nextFPS),
489
- len: Math.min(state.len + nextFPS.length, width),
490
- fps: [
491
- ...state.fps,
492
- ...nextFPS
493
- ].slice(-width),
494
- frames: 1,
495
- prevTime: currentTime
474
+ // NOTE: Order is important.
475
+ transform: `translate(${offset.x}px, ${offset.y}px) scale(${scale})`,
476
+ visibility: width && height ? "visible" : "hidden"
496
477
  };
497
- } else {
478
+ }, [
479
+ scale,
480
+ offset
481
+ ]);
482
+ (0, import_react.useImperativeHandle)(forwardedRef, () => {
498
483
  return {
499
- ...state,
500
- frames: state.frames + 1
484
+ setProjection: async (projection2) => {
485
+ setProjection(projection2);
486
+ }
501
487
  };
502
- }
503
- }, {
504
- max: 0,
505
- len: 0,
506
- fps: [],
507
- frames: 0,
508
- prevTime: Date.now()
509
- });
510
- const requestRef = (0, import_react5.useRef)();
511
- const tick = () => {
512
- dispatch();
513
- requestRef.current = requestAnimationFrame(tick);
514
- };
515
- (0, import_react5.useEffect)(() => {
516
- requestRef.current = requestAnimationFrame(tick);
517
- return () => {
518
- if (requestRef.current) {
519
- cancelAnimationFrame(requestRef.current);
488
+ }, [
489
+ ref
490
+ ]);
491
+ return /* @__PURE__ */ import_react.default.createElement(CanvasContext.Provider, {
492
+ value: {
493
+ root: ref.current,
494
+ ready,
495
+ width,
496
+ height,
497
+ scale,
498
+ offset,
499
+ styles,
500
+ projection,
501
+ setProjection
502
+ }
503
+ }, /* @__PURE__ */ import_react.default.createElement("div", {
504
+ role: "none",
505
+ ...props,
506
+ className: (0, import_react_ui_theme.mx)("absolute inset-0 overflow-hidden", classNames),
507
+ ref
508
+ }, ready ? children : null));
509
+ } finally {
510
+ _effect.f();
511
+ }
512
+ });
513
+ var SEC = 1e3;
514
+ var FPS = ({ classNames, width = 60, height = 30, bar = "bg-cyan-500" }) => {
515
+ var _effect = (0, import_tracking3.useSignals)();
516
+ try {
517
+ const [{ fps, max, len }, dispatch] = (0, import_react5.useReducer)((state) => {
518
+ const currentTime = Date.now();
519
+ if (currentTime > state.prevTime + SEC) {
520
+ const nextFPS = [
521
+ ...new Array(Math.floor((currentTime - state.prevTime - SEC) / SEC)).fill(0),
522
+ Math.max(1, Math.round(state.frames * SEC / (currentTime - state.prevTime)))
523
+ ];
524
+ return {
525
+ max: Math.max(state.max, ...nextFPS),
526
+ len: Math.min(state.len + nextFPS.length, width),
527
+ fps: [
528
+ ...state.fps,
529
+ ...nextFPS
530
+ ].slice(-width),
531
+ frames: 1,
532
+ prevTime: currentTime
533
+ };
534
+ } else {
535
+ return {
536
+ ...state,
537
+ frames: state.frames + 1
538
+ };
520
539
  }
540
+ }, {
541
+ max: 0,
542
+ len: 0,
543
+ fps: [],
544
+ frames: 0,
545
+ prevTime: Date.now()
546
+ });
547
+ const requestRef = (0, import_react5.useRef)();
548
+ const tick = () => {
549
+ dispatch();
550
+ requestRef.current = requestAnimationFrame(tick);
521
551
  };
522
- }, []);
523
- return /* @__PURE__ */ import_react5.default.createElement("div", {
524
- style: {
525
- width: width + 6
526
- },
527
- className: (0, import_react_ui_theme3.mx)("relative flex flex-col p-0.5", "bg-baseSurface text-xs text-subdued font-thin pointer-events-none border border-separator", classNames)
528
- }, /* @__PURE__ */ import_react5.default.createElement("div", null, fps[len - 1], " FPS"), /* @__PURE__ */ import_react5.default.createElement("div", {
529
- className: "w-full relative",
530
- style: {
531
- height
532
- }
533
- }, fps.map((frame, i) => /* @__PURE__ */ import_react5.default.createElement("div", {
534
- key: `fps-${i}`,
535
- className: bar,
536
- style: {
537
- position: "absolute",
538
- bottom: 0,
539
- right: `${len - 1 - i}px`,
540
- height: `${height * frame / max}px`,
541
- width: 1
542
- }
543
- }))));
552
+ (0, import_react5.useEffect)(() => {
553
+ requestRef.current = requestAnimationFrame(tick);
554
+ return () => {
555
+ if (requestRef.current) {
556
+ cancelAnimationFrame(requestRef.current);
557
+ }
558
+ };
559
+ }, []);
560
+ return /* @__PURE__ */ import_react5.default.createElement("div", {
561
+ style: {
562
+ width: width + 6
563
+ },
564
+ className: (0, import_react_ui_theme3.mx)("relative flex flex-col p-0.5", "bg-baseSurface text-xs text-subdued font-thin pointer-events-none border border-separator", classNames)
565
+ }, /* @__PURE__ */ import_react5.default.createElement("div", null, fps[len - 1], " FPS"), /* @__PURE__ */ import_react5.default.createElement("div", {
566
+ className: "w-full relative",
567
+ style: {
568
+ height
569
+ }
570
+ }, fps.map((frame, i) => /* @__PURE__ */ import_react5.default.createElement("div", {
571
+ key: `fps-${i}`,
572
+ className: bar,
573
+ style: {
574
+ position: "absolute",
575
+ bottom: 0,
576
+ right: `${len - 1 - i}px`,
577
+ height: `${height * frame / max}px`,
578
+ width: 1
579
+ }
580
+ }))));
581
+ } finally {
582
+ _effect.f();
583
+ }
544
584
  };
545
585
  var gridRatios = [
546
586
  1 / 4,
@@ -555,52 +595,62 @@ var defaultOffset = {
555
595
  };
556
596
  var createId = (parent, grid) => `dx-canvas-grid-${parent}-${grid}`;
557
597
  var GridComponent = /* @__PURE__ */ (0, import_react6.forwardRef)(({ size: gridSize = defaultGridSize, scale = 1, offset = defaultOffset, showAxes = true, classNames }, forwardedRef) => {
558
- const svgRef = (0, import_react_ui.useForwardedRef)(forwardedRef);
559
- const instanceId = (0, import_react6.useId)();
560
- const grids = (0, import_react6.useMemo)(() => gridRatios.map((ratio) => ({
561
- id: ratio,
562
- size: ratio * gridSize * scale
563
- })).filter(({ size }) => size >= gridSize && size <= 256), [
564
- gridSize,
565
- scale
566
- ]);
567
- const { width = 0, height = 0 } = svgRef.current?.getBoundingClientRect() ?? {};
568
- return /* @__PURE__ */ import_react6.default.createElement("svg", {
569
- ...testId("dx-canvas-grid"),
570
- ref: svgRef,
571
- className: (0, import_react_ui_theme4.mx)("absolute inset-0 w-full h-full pointer-events-none touch-none select-none", "stroke-neutral-500", classNames)
572
- }, /* @__PURE__ */ import_react6.default.createElement("defs", null, grids.map(({ id, size }) => /* @__PURE__ */ import_react6.default.createElement(GridPattern, {
573
- key: id,
574
- id: createId(instanceId, id),
575
- offset,
576
- size
577
- }))), showAxes && /* @__PURE__ */ import_react6.default.createElement(import_react6.default.Fragment, null, /* @__PURE__ */ import_react6.default.createElement("line", {
578
- x1: 0,
579
- y1: offset.y,
580
- x2: width,
581
- y2: offset.y,
582
- className: "stroke-neutral-500 opacity-40"
583
- }), /* @__PURE__ */ import_react6.default.createElement("line", {
584
- x1: offset.x,
585
- y1: 0,
586
- x2: offset.x,
587
- y2: height,
588
- className: "stroke-neutral-500 opacity-40"
589
- })), /* @__PURE__ */ import_react6.default.createElement("g", null, grids.map(({ id }, i) => /* @__PURE__ */ import_react6.default.createElement("rect", {
590
- key: id,
591
- opacity: 0.1 + i * 0.05,
592
- fill: `url(#${createId(instanceId, id)})`,
593
- width: "100%",
594
- height: "100%"
595
- }))));
598
+ var _effect = (0, import_tracking4.useSignals)();
599
+ try {
600
+ const svgRef = (0, import_react_ui.useForwardedRef)(forwardedRef);
601
+ const instanceId = (0, import_react6.useId)();
602
+ const grids = (0, import_react6.useMemo)(() => gridRatios.map((ratio) => ({
603
+ id: ratio,
604
+ size: ratio * gridSize * scale
605
+ })).filter(({ size }) => size >= gridSize && size <= 256), [
606
+ gridSize,
607
+ scale
608
+ ]);
609
+ const { width = 0, height = 0 } = svgRef.current?.getBoundingClientRect() ?? {};
610
+ return /* @__PURE__ */ import_react6.default.createElement("svg", {
611
+ ...testId("dx-canvas-grid"),
612
+ ref: svgRef,
613
+ className: (0, import_react_ui_theme4.mx)("absolute inset-0 w-full h-full pointer-events-none touch-none select-none", "stroke-neutral-500", classNames)
614
+ }, /* @__PURE__ */ import_react6.default.createElement("defs", null, grids.map(({ id, size }) => /* @__PURE__ */ import_react6.default.createElement(GridPattern, {
615
+ key: id,
616
+ id: createId(instanceId, id),
617
+ offset,
618
+ size
619
+ }))), showAxes && /* @__PURE__ */ import_react6.default.createElement(import_react6.default.Fragment, null, /* @__PURE__ */ import_react6.default.createElement("line", {
620
+ x1: 0,
621
+ y1: offset.y,
622
+ x2: width,
623
+ y2: offset.y,
624
+ className: "stroke-neutral-500 opacity-40"
625
+ }), /* @__PURE__ */ import_react6.default.createElement("line", {
626
+ x1: offset.x,
627
+ y1: 0,
628
+ x2: offset.x,
629
+ y2: height,
630
+ className: "stroke-neutral-500 opacity-40"
631
+ })), /* @__PURE__ */ import_react6.default.createElement("g", null, grids.map(({ id }, i) => /* @__PURE__ */ import_react6.default.createElement("rect", {
632
+ key: id,
633
+ opacity: 0.1 + i * 0.05,
634
+ fill: `url(#${createId(instanceId, id)})`,
635
+ width: "100%",
636
+ height: "100%"
637
+ }))));
638
+ } finally {
639
+ _effect.f();
640
+ }
596
641
  });
597
642
  var Grid = (props) => {
598
- const { scale, offset } = useCanvasContext();
599
- return /* @__PURE__ */ import_react6.default.createElement(GridComponent, {
600
- ...props,
601
- scale,
602
- offset
603
- });
643
+ var _effect = (0, import_tracking4.useSignals)();
644
+ try {
645
+ const { scale, offset } = useCanvasContext();
646
+ return /* @__PURE__ */ import_react6.default.createElement(GridComponent, {
647
+ ...props,
648
+ scale,
649
+ offset
650
+ });
651
+ } finally {
652
+ _effect.f();
653
+ }
604
654
  };
605
655
  var Point = import_effect.Schema.Struct({
606
656
  x: import_effect.Schema.Number,