@dxos/react-ui-canvas 0.8.4-main.03d5cd7b56 → 0.8.4-main.05e74ebcff
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +102 -5
- package/dist/lib/browser/index.mjs +777 -18
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/node-esm/index.mjs +777 -18
- package/dist/lib/node-esm/index.mjs.map +4 -4
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/types/src/components/CellGrid/CellGrid.d.ts +21 -0
- package/dist/types/src/components/CellGrid/CellGrid.d.ts.map +1 -0
- package/dist/types/src/components/CellGrid/CellGrid.stories.d.ts +21 -0
- package/dist/types/src/components/CellGrid/CellGrid.stories.d.ts.map +1 -0
- package/dist/types/src/components/CellGrid/headers/Ruler.d.ts +15 -0
- package/dist/types/src/components/CellGrid/headers/Ruler.d.ts.map +1 -0
- package/dist/types/src/components/CellGrid/headers/TrackHeader.d.ts +19 -0
- package/dist/types/src/components/CellGrid/headers/TrackHeader.d.ts.map +1 -0
- package/dist/types/src/components/CellGrid/headers/index.d.ts +3 -0
- package/dist/types/src/components/CellGrid/headers/index.d.ts.map +1 -0
- package/dist/types/src/components/CellGrid/index.d.ts +6 -0
- package/dist/types/src/components/CellGrid/index.d.ts.map +1 -0
- package/dist/types/src/components/CellGrid/input/index.d.ts +3 -0
- package/dist/types/src/components/CellGrid/input/index.d.ts.map +1 -0
- package/dist/types/src/components/CellGrid/input/pointer.d.ts +29 -0
- package/dist/types/src/components/CellGrid/input/pointer.d.ts.map +1 -0
- package/dist/types/src/components/CellGrid/input/wheel.d.ts +14 -0
- package/dist/types/src/components/CellGrid/input/wheel.d.ts.map +1 -0
- package/dist/types/src/components/CellGrid/render/index.d.ts +3 -0
- package/dist/types/src/components/CellGrid/render/index.d.ts.map +1 -0
- package/dist/types/src/components/CellGrid/render/overlay-layer.d.ts +21 -0
- package/dist/types/src/components/CellGrid/render/overlay-layer.d.ts.map +1 -0
- package/dist/types/src/components/CellGrid/render/static-layer.d.ts +36 -0
- package/dist/types/src/components/CellGrid/render/static-layer.d.ts.map +1 -0
- package/dist/types/src/components/CellGrid/state/atoms.d.ts +23 -0
- package/dist/types/src/components/CellGrid/state/atoms.d.ts.map +1 -0
- package/dist/types/src/components/CellGrid/state/index.d.ts +4 -0
- package/dist/types/src/components/CellGrid/state/index.d.ts.map +1 -0
- package/dist/types/src/components/CellGrid/state/types.d.ts +39 -0
- package/dist/types/src/components/CellGrid/state/types.d.ts.map +1 -0
- package/dist/types/src/components/CellGrid/state/viewport.d.ts +52 -0
- package/dist/types/src/components/CellGrid/state/viewport.d.ts.map +1 -0
- package/dist/types/src/components/CellGrid/state/viewport.test.d.ts +2 -0
- package/dist/types/src/components/CellGrid/state/viewport.test.d.ts.map +1 -0
- package/dist/types/src/components/index.d.ts +1 -0
- package/dist/types/src/components/index.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +14 -13
- package/src/components/CellGrid/CellGrid.stories.tsx +238 -0
- package/src/components/CellGrid/CellGrid.tsx +266 -0
- package/src/components/CellGrid/headers/Ruler.tsx +71 -0
- package/src/components/CellGrid/headers/TrackHeader.tsx +58 -0
- package/src/components/CellGrid/headers/index.ts +6 -0
- package/src/components/CellGrid/index.ts +9 -0
- package/src/components/CellGrid/input/index.ts +6 -0
- package/src/components/CellGrid/input/pointer.ts +208 -0
- package/src/components/CellGrid/input/wheel.ts +68 -0
- package/src/components/CellGrid/render/index.ts +6 -0
- package/src/components/CellGrid/render/overlay-layer.ts +66 -0
- package/src/components/CellGrid/render/static-layer.ts +112 -0
- package/src/components/CellGrid/state/atoms.ts +43 -0
- package/src/components/CellGrid/state/index.ts +7 -0
- package/src/components/CellGrid/state/types.ts +40 -0
- package/src/components/CellGrid/state/viewport.test.ts +50 -0
- package/src/components/CellGrid/state/viewport.ts +94 -0
- package/src/components/index.ts +1 -0
|
@@ -477,9 +477,751 @@ var Canvas = /* @__PURE__ */ forwardRef(({ children, classNames, scale: scalePro
|
|
|
477
477
|
}, ready ? children : null));
|
|
478
478
|
});
|
|
479
479
|
|
|
480
|
-
// src/components/
|
|
481
|
-
import
|
|
480
|
+
// src/components/CellGrid/CellGrid.tsx
|
|
481
|
+
import { RegistryContext } from "@effect-atom/atom-react";
|
|
482
|
+
import React5, { useContext as useContext2, useEffect as useEffect4, useMemo as useMemo3, useRef as useRef2, useState as useState2 } from "react";
|
|
483
|
+
import { useResizeDetector as useResizeDetector2 } from "react-resize-detector";
|
|
484
|
+
import { mx as mx5 } from "@dxos/ui-theme";
|
|
485
|
+
|
|
486
|
+
// src/components/CellGrid/headers/Ruler.tsx
|
|
487
|
+
import React3, { useMemo as useMemo2 } from "react";
|
|
482
488
|
import { mx as mx3 } from "@dxos/ui-theme";
|
|
489
|
+
|
|
490
|
+
// src/components/CellGrid/state/viewport.ts
|
|
491
|
+
var cellKey = (col, row) => `${col},${row}`;
|
|
492
|
+
var cellWidth = (viewport) => viewport.baseCellWidth * viewport.zoomX;
|
|
493
|
+
var worldToScreen = (viewport, headers, coord) => {
|
|
494
|
+
const w = cellWidth(viewport);
|
|
495
|
+
return {
|
|
496
|
+
x: headers.left + coord.col * w - viewport.scrollX,
|
|
497
|
+
y: headers.top + coord.row * viewport.cellHeight - viewport.scrollY,
|
|
498
|
+
w: (coord.length ?? 1) * w,
|
|
499
|
+
h: viewport.cellHeight
|
|
500
|
+
};
|
|
501
|
+
};
|
|
502
|
+
var screenToWorld = (viewport, headers, point) => {
|
|
503
|
+
const w = cellWidth(viewport);
|
|
504
|
+
return {
|
|
505
|
+
col: (point.x - headers.left + viewport.scrollX) / w,
|
|
506
|
+
row: (point.y - headers.top + viewport.scrollY) / viewport.cellHeight
|
|
507
|
+
};
|
|
508
|
+
};
|
|
509
|
+
var hitTestCell = (viewport, headers, point) => {
|
|
510
|
+
if (point.x < headers.left || point.y < headers.top) {
|
|
511
|
+
return null;
|
|
512
|
+
}
|
|
513
|
+
const { col, row } = screenToWorld(viewport, headers, point);
|
|
514
|
+
if (col < 0 || row < 0) {
|
|
515
|
+
return null;
|
|
516
|
+
}
|
|
517
|
+
return {
|
|
518
|
+
col: Math.floor(col),
|
|
519
|
+
row: Math.floor(row)
|
|
520
|
+
};
|
|
521
|
+
};
|
|
522
|
+
var visibleCellRange = (viewport, headers, size) => {
|
|
523
|
+
const w = cellWidth(viewport);
|
|
524
|
+
const innerW = Math.max(0, size.width - headers.left);
|
|
525
|
+
const innerH = Math.max(0, size.height - headers.top);
|
|
526
|
+
const minCol = Math.max(0, Math.floor(viewport.scrollX / w));
|
|
527
|
+
const maxCol = Math.floor((viewport.scrollX + innerW) / w);
|
|
528
|
+
const minRow = Math.max(0, Math.floor(viewport.scrollY / viewport.cellHeight));
|
|
529
|
+
const maxRow = Math.floor((viewport.scrollY + innerH) / viewport.cellHeight);
|
|
530
|
+
return {
|
|
531
|
+
minCol,
|
|
532
|
+
maxCol,
|
|
533
|
+
minRow,
|
|
534
|
+
maxRow
|
|
535
|
+
};
|
|
536
|
+
};
|
|
537
|
+
var visibleCells = function* (cells, range) {
|
|
538
|
+
for (const cell of cells.values()) {
|
|
539
|
+
if (cell.row < range.minRow || cell.row > range.maxRow) {
|
|
540
|
+
continue;
|
|
541
|
+
}
|
|
542
|
+
const start = cell.col;
|
|
543
|
+
const end = cell.col + cell.length - 1;
|
|
544
|
+
if (end < range.minCol || start > range.maxCol) {
|
|
545
|
+
continue;
|
|
546
|
+
}
|
|
547
|
+
yield cell;
|
|
548
|
+
}
|
|
549
|
+
};
|
|
550
|
+
|
|
551
|
+
// src/components/CellGrid/headers/Ruler.tsx
|
|
552
|
+
var Ruler = ({ viewport, headers, width, majorEvery = 4, classNames }) => {
|
|
553
|
+
const safeMajorEvery = Math.max(1, Math.floor(majorEvery));
|
|
554
|
+
const ticks = useMemo2(() => {
|
|
555
|
+
const w = cellWidth(viewport);
|
|
556
|
+
if (w < 1 || width <= headers.left) {
|
|
557
|
+
return [];
|
|
558
|
+
}
|
|
559
|
+
const innerWidth = width - headers.left;
|
|
560
|
+
const startCol = Math.floor(viewport.scrollX / w);
|
|
561
|
+
const endCol = Math.ceil((viewport.scrollX + innerWidth) / w);
|
|
562
|
+
const result = [];
|
|
563
|
+
for (let col = startCol; col <= endCol; col++) {
|
|
564
|
+
result.push({
|
|
565
|
+
col,
|
|
566
|
+
x: headers.left + col * w - viewport.scrollX,
|
|
567
|
+
major: col % safeMajorEvery === 0
|
|
568
|
+
});
|
|
569
|
+
}
|
|
570
|
+
return result;
|
|
571
|
+
}, [
|
|
572
|
+
viewport,
|
|
573
|
+
headers.left,
|
|
574
|
+
width,
|
|
575
|
+
safeMajorEvery
|
|
576
|
+
]);
|
|
577
|
+
return /* @__PURE__ */ React3.createElement("div", {
|
|
578
|
+
className: mx3("absolute top-0 left-0 right-0 border-b border-neutral-200 dark:border-neutral-700 bg-baseSurface select-none overflow-hidden", classNames),
|
|
579
|
+
style: {
|
|
580
|
+
height: headers.top
|
|
581
|
+
}
|
|
582
|
+
}, ticks.map(({ col, x, major }) => /* @__PURE__ */ React3.createElement("div", {
|
|
583
|
+
key: col,
|
|
584
|
+
className: mx3("absolute top-0 bottom-0 text-[10px] text-neutral-500 dark:text-neutral-400", major ? "border-l border-neutral-400 dark:border-neutral-500" : "border-l border-neutral-200 dark:border-neutral-700"),
|
|
585
|
+
style: {
|
|
586
|
+
transform: `translateX(${x}px)`
|
|
587
|
+
}
|
|
588
|
+
}, major ? /* @__PURE__ */ React3.createElement("span", {
|
|
589
|
+
className: "absolute left-1 top-0"
|
|
590
|
+
}, col) : null)));
|
|
591
|
+
};
|
|
592
|
+
|
|
593
|
+
// src/components/CellGrid/headers/TrackHeader.tsx
|
|
594
|
+
import React4 from "react";
|
|
595
|
+
import { mx as mx4 } from "@dxos/ui-theme";
|
|
596
|
+
var TrackHeader = ({ viewport, headers, rows, height, classNames }) => {
|
|
597
|
+
return /* @__PURE__ */ React4.createElement("div", {
|
|
598
|
+
className: mx4("absolute left-0 border-r border-neutral-200 dark:border-neutral-700 select-none overflow-hidden", classNames),
|
|
599
|
+
style: {
|
|
600
|
+
top: headers.top,
|
|
601
|
+
width: headers.left,
|
|
602
|
+
height: Math.max(0, height - headers.top)
|
|
603
|
+
}
|
|
604
|
+
}, /* @__PURE__ */ React4.createElement("div", {
|
|
605
|
+
style: {
|
|
606
|
+
transform: `translateY(${-viewport.scrollY}px)`
|
|
607
|
+
}
|
|
608
|
+
}, rows.map((row, index) => /* @__PURE__ */ React4.createElement("div", {
|
|
609
|
+
key: row.id,
|
|
610
|
+
className: "flex items-center px-2 text-xs text-neutral-700 dark:text-neutral-300",
|
|
611
|
+
style: {
|
|
612
|
+
height: viewport.cellHeight,
|
|
613
|
+
// Match the canvas's row-band: a translucent gray overlay on odd rows,
|
|
614
|
+
// transparent on even rows. The container's overall background bleeds
|
|
615
|
+
// through, so the labels stay legible in both themes.
|
|
616
|
+
backgroundColor: index % 2 === 0 ? "transparent" : "rgba(128, 128, 128, 0.08)",
|
|
617
|
+
// Match the canvas gridline color (rgba(128, 128, 128, 0.25)). Use a
|
|
618
|
+
// half-pixel inset to keep crisp single-pixel rendering on retina.
|
|
619
|
+
boxShadow: "inset 0 -1px 0 rgba(128, 128, 128, 0.25)"
|
|
620
|
+
}
|
|
621
|
+
}, row.label ?? row.id))));
|
|
622
|
+
};
|
|
623
|
+
|
|
624
|
+
// src/components/CellGrid/input/pointer.ts
|
|
625
|
+
var attachPointerHandlers = (element, { registry, atoms, headers, handlers }) => {
|
|
626
|
+
let drag = null;
|
|
627
|
+
const local = (event) => {
|
|
628
|
+
const rect = element.getBoundingClientRect();
|
|
629
|
+
return {
|
|
630
|
+
x: event.clientX - rect.left,
|
|
631
|
+
y: event.clientY - rect.top
|
|
632
|
+
};
|
|
633
|
+
};
|
|
634
|
+
const tryCapture = (pointerId) => {
|
|
635
|
+
try {
|
|
636
|
+
element.setPointerCapture(pointerId);
|
|
637
|
+
} catch {
|
|
638
|
+
}
|
|
639
|
+
};
|
|
640
|
+
const onPointerDown = (event) => {
|
|
641
|
+
if (event.button === 1 || event.button === 0 && event.altKey) {
|
|
642
|
+
drag = {
|
|
643
|
+
kind: "pan",
|
|
644
|
+
lastX: event.clientX,
|
|
645
|
+
lastY: event.clientY
|
|
646
|
+
};
|
|
647
|
+
tryCapture(event.pointerId);
|
|
648
|
+
event.preventDefault();
|
|
649
|
+
return;
|
|
650
|
+
}
|
|
651
|
+
if (event.button !== 0) {
|
|
652
|
+
return;
|
|
653
|
+
}
|
|
654
|
+
const viewport = registry.get(atoms.viewport);
|
|
655
|
+
const point = local(event);
|
|
656
|
+
const coord = hitTestCell(viewport, headers, point);
|
|
657
|
+
if (!coord) {
|
|
658
|
+
return;
|
|
659
|
+
}
|
|
660
|
+
const tool = registry.get(atoms.tool);
|
|
661
|
+
tryCapture(event.pointerId);
|
|
662
|
+
switch (tool) {
|
|
663
|
+
case "toggle":
|
|
664
|
+
case "resize": {
|
|
665
|
+
const cells = registry.get(atoms.cells);
|
|
666
|
+
const key = cellKey(coord.col, coord.row);
|
|
667
|
+
const mode = cells.has(key) ? "unset" : "set";
|
|
668
|
+
handlers.onCellToggle?.(coord, mode);
|
|
669
|
+
drag = {
|
|
670
|
+
kind: "toggle",
|
|
671
|
+
mode,
|
|
672
|
+
touched: /* @__PURE__ */ new Set([
|
|
673
|
+
key
|
|
674
|
+
])
|
|
675
|
+
};
|
|
676
|
+
break;
|
|
677
|
+
}
|
|
678
|
+
case "select": {
|
|
679
|
+
drag = {
|
|
680
|
+
kind: "select",
|
|
681
|
+
origin: coord
|
|
682
|
+
};
|
|
683
|
+
registry.set(atoms.selection, {
|
|
684
|
+
range: {
|
|
685
|
+
col0: coord.col,
|
|
686
|
+
row0: coord.row,
|
|
687
|
+
col1: coord.col,
|
|
688
|
+
row1: coord.row
|
|
689
|
+
}
|
|
690
|
+
});
|
|
691
|
+
break;
|
|
692
|
+
}
|
|
693
|
+
}
|
|
694
|
+
};
|
|
695
|
+
const onPointerMove = (event) => {
|
|
696
|
+
if (!drag) {
|
|
697
|
+
return;
|
|
698
|
+
}
|
|
699
|
+
if (drag.kind === "pan") {
|
|
700
|
+
const dx = event.clientX - drag.lastX;
|
|
701
|
+
const dy = event.clientY - drag.lastY;
|
|
702
|
+
drag.lastX = event.clientX;
|
|
703
|
+
drag.lastY = event.clientY;
|
|
704
|
+
registry.update(atoms.viewport, (current) => ({
|
|
705
|
+
...current,
|
|
706
|
+
scrollX: Math.max(0, current.scrollX - dx),
|
|
707
|
+
scrollY: Math.max(0, current.scrollY - dy)
|
|
708
|
+
}));
|
|
709
|
+
return;
|
|
710
|
+
}
|
|
711
|
+
const viewport = registry.get(atoms.viewport);
|
|
712
|
+
const coord = hitTestCell(viewport, headers, local(event));
|
|
713
|
+
if (!coord) {
|
|
714
|
+
return;
|
|
715
|
+
}
|
|
716
|
+
if (drag.kind === "toggle") {
|
|
717
|
+
const key = cellKey(coord.col, coord.row);
|
|
718
|
+
if (!drag.touched.has(key)) {
|
|
719
|
+
drag.touched.add(key);
|
|
720
|
+
handlers.onCellToggle?.(coord, drag.mode);
|
|
721
|
+
}
|
|
722
|
+
} else if (drag.kind === "select") {
|
|
723
|
+
registry.set(atoms.selection, {
|
|
724
|
+
range: {
|
|
725
|
+
col0: drag.origin.col,
|
|
726
|
+
row0: drag.origin.row,
|
|
727
|
+
col1: coord.col,
|
|
728
|
+
row1: coord.row
|
|
729
|
+
}
|
|
730
|
+
});
|
|
731
|
+
}
|
|
732
|
+
};
|
|
733
|
+
const releaseCapture = (event) => {
|
|
734
|
+
if (element.hasPointerCapture(event.pointerId)) {
|
|
735
|
+
element.releasePointerCapture(event.pointerId);
|
|
736
|
+
}
|
|
737
|
+
};
|
|
738
|
+
const onPointerUp = (event) => {
|
|
739
|
+
if (!drag) {
|
|
740
|
+
return;
|
|
741
|
+
}
|
|
742
|
+
if (drag.kind === "select") {
|
|
743
|
+
const range = registry.get(atoms.selection).range;
|
|
744
|
+
if (range) {
|
|
745
|
+
handlers.onSelectionCommit?.(range);
|
|
746
|
+
}
|
|
747
|
+
}
|
|
748
|
+
drag = null;
|
|
749
|
+
releaseCapture(event);
|
|
750
|
+
};
|
|
751
|
+
const onPointerCancel = (event) => {
|
|
752
|
+
drag = null;
|
|
753
|
+
releaseCapture(event);
|
|
754
|
+
};
|
|
755
|
+
element.addEventListener("pointerdown", onPointerDown);
|
|
756
|
+
element.addEventListener("pointermove", onPointerMove);
|
|
757
|
+
element.addEventListener("pointerup", onPointerUp);
|
|
758
|
+
element.addEventListener("pointercancel", onPointerCancel);
|
|
759
|
+
return () => {
|
|
760
|
+
element.removeEventListener("pointerdown", onPointerDown);
|
|
761
|
+
element.removeEventListener("pointermove", onPointerMove);
|
|
762
|
+
element.removeEventListener("pointerup", onPointerUp);
|
|
763
|
+
element.removeEventListener("pointercancel", onPointerCancel);
|
|
764
|
+
};
|
|
765
|
+
};
|
|
766
|
+
var toggleCell = (registry, atoms, coord, factory, mode = "toggle") => {
|
|
767
|
+
registry.update(atoms.cells, (current) => {
|
|
768
|
+
const next = new Map(current);
|
|
769
|
+
const key = cellKey(coord.col, coord.row);
|
|
770
|
+
const exists = next.has(key);
|
|
771
|
+
if (mode === "set" || mode === "toggle" && !exists) {
|
|
772
|
+
next.set(key, factory(coord));
|
|
773
|
+
} else if (mode === "unset" || mode === "toggle" && exists) {
|
|
774
|
+
next.delete(key);
|
|
775
|
+
}
|
|
776
|
+
return next;
|
|
777
|
+
});
|
|
778
|
+
};
|
|
779
|
+
|
|
780
|
+
// src/components/CellGrid/input/wheel.ts
|
|
781
|
+
var MIN_ZOOM = 0.25;
|
|
782
|
+
var MAX_ZOOM = 8;
|
|
783
|
+
var attachWheelHandlers = (element, { registry, atoms, headers }) => {
|
|
784
|
+
const onWheel = (event) => {
|
|
785
|
+
if (event.ctrlKey || event.metaKey) {
|
|
786
|
+
event.preventDefault();
|
|
787
|
+
const rect = element.getBoundingClientRect();
|
|
788
|
+
const x = event.clientX - rect.left;
|
|
789
|
+
const factor = Math.exp(-event.deltaY / 200);
|
|
790
|
+
registry.update(atoms.viewport, (current2) => {
|
|
791
|
+
const nextZoom = Math.max(MIN_ZOOM, Math.min(MAX_ZOOM, current2.zoomX * factor));
|
|
792
|
+
if (nextZoom === current2.zoomX) {
|
|
793
|
+
return current2;
|
|
794
|
+
}
|
|
795
|
+
const w = cellWidth(current2);
|
|
796
|
+
const worldX = (x - headers.left + current2.scrollX) / w;
|
|
797
|
+
const nextW = current2.baseCellWidth * nextZoom;
|
|
798
|
+
const nextScrollX2 = Math.max(0, worldX * nextW - (x - headers.left));
|
|
799
|
+
return {
|
|
800
|
+
...current2,
|
|
801
|
+
zoomX: nextZoom,
|
|
802
|
+
scrollX: nextScrollX2
|
|
803
|
+
};
|
|
804
|
+
});
|
|
805
|
+
return;
|
|
806
|
+
}
|
|
807
|
+
const dx = event.shiftKey ? event.deltaY : event.deltaX;
|
|
808
|
+
const dy = event.shiftKey ? 0 : event.deltaY;
|
|
809
|
+
const current = registry.get(atoms.viewport);
|
|
810
|
+
const nextScrollX = Math.max(0, current.scrollX + dx);
|
|
811
|
+
const nextScrollY = Math.max(0, current.scrollY + dy);
|
|
812
|
+
if (nextScrollX === current.scrollX && nextScrollY === current.scrollY) {
|
|
813
|
+
return;
|
|
814
|
+
}
|
|
815
|
+
event.preventDefault();
|
|
816
|
+
registry.set(atoms.viewport, {
|
|
817
|
+
...current,
|
|
818
|
+
scrollX: nextScrollX,
|
|
819
|
+
scrollY: nextScrollY
|
|
820
|
+
});
|
|
821
|
+
};
|
|
822
|
+
element.addEventListener("wheel", onWheel, {
|
|
823
|
+
passive: false
|
|
824
|
+
});
|
|
825
|
+
return () => element.removeEventListener("wheel", onWheel);
|
|
826
|
+
};
|
|
827
|
+
|
|
828
|
+
// src/components/CellGrid/render/overlay-layer.ts
|
|
829
|
+
var drawOverlay = ({ ctx, size, viewport, headers, selection, playhead, style }) => {
|
|
830
|
+
ctx.clearRect(0, 0, size.width, size.height);
|
|
831
|
+
ctx.save();
|
|
832
|
+
ctx.beginPath();
|
|
833
|
+
ctx.rect(headers.left, headers.top, size.width - headers.left, size.height - headers.top);
|
|
834
|
+
ctx.clip();
|
|
835
|
+
if (selection.range) {
|
|
836
|
+
const { col0, row0, col1, row1 } = selection.range;
|
|
837
|
+
const minCol = Math.min(col0, col1);
|
|
838
|
+
const maxCol = Math.max(col0, col1);
|
|
839
|
+
const minRow = Math.min(row0, row1);
|
|
840
|
+
const maxRow = Math.max(row0, row1);
|
|
841
|
+
const tl = worldToScreen(viewport, headers, {
|
|
842
|
+
col: minCol,
|
|
843
|
+
row: minRow
|
|
844
|
+
});
|
|
845
|
+
const br = worldToScreen(viewport, headers, {
|
|
846
|
+
col: maxCol + 1,
|
|
847
|
+
row: maxRow + 1
|
|
848
|
+
});
|
|
849
|
+
ctx.fillStyle = style.selectionFill;
|
|
850
|
+
ctx.fillRect(tl.x, tl.y, br.x - tl.x, br.y - tl.y);
|
|
851
|
+
ctx.strokeStyle = style.selectionStroke;
|
|
852
|
+
ctx.setLineDash([
|
|
853
|
+
4,
|
|
854
|
+
3
|
|
855
|
+
]);
|
|
856
|
+
ctx.lineWidth = 1;
|
|
857
|
+
ctx.strokeRect(tl.x + 0.5, tl.y + 0.5, br.x - tl.x - 1, br.y - tl.y - 1);
|
|
858
|
+
ctx.setLineDash([]);
|
|
859
|
+
}
|
|
860
|
+
if (playhead !== null) {
|
|
861
|
+
const w = cellWidth(viewport);
|
|
862
|
+
const x = headers.left + playhead * w - viewport.scrollX;
|
|
863
|
+
if (x >= headers.left && x <= size.width) {
|
|
864
|
+
ctx.strokeStyle = style.playhead;
|
|
865
|
+
ctx.lineWidth = 2;
|
|
866
|
+
ctx.beginPath();
|
|
867
|
+
ctx.moveTo(x, headers.top);
|
|
868
|
+
ctx.lineTo(x, size.height);
|
|
869
|
+
ctx.stroke();
|
|
870
|
+
}
|
|
871
|
+
}
|
|
872
|
+
ctx.restore();
|
|
873
|
+
};
|
|
874
|
+
|
|
875
|
+
// src/components/CellGrid/render/static-layer.ts
|
|
876
|
+
var drawCells = ({ ctx, size, viewport, headers, rows, cells, renderCell, style }) => {
|
|
877
|
+
ctx.clearRect(0, 0, size.width, size.height);
|
|
878
|
+
if (style.background) {
|
|
879
|
+
ctx.fillStyle = style.background;
|
|
880
|
+
ctx.fillRect(0, 0, size.width, size.height);
|
|
881
|
+
}
|
|
882
|
+
const range = visibleCellRange(viewport, headers, size);
|
|
883
|
+
const w = cellWidth(viewport);
|
|
884
|
+
const h = viewport.cellHeight;
|
|
885
|
+
if (style.rowBand) {
|
|
886
|
+
ctx.fillStyle = style.rowBand;
|
|
887
|
+
for (let row = range.minRow; row <= Math.min(range.maxRow, rows.length - 1); row++) {
|
|
888
|
+
if (row % 2 === 0) {
|
|
889
|
+
continue;
|
|
890
|
+
}
|
|
891
|
+
const y = headers.top + row * h - viewport.scrollY;
|
|
892
|
+
ctx.fillRect(headers.left, y, size.width - headers.left, h);
|
|
893
|
+
}
|
|
894
|
+
}
|
|
895
|
+
ctx.strokeStyle = style.gridLine;
|
|
896
|
+
ctx.lineWidth = 1;
|
|
897
|
+
ctx.beginPath();
|
|
898
|
+
for (let col = range.minCol; col <= range.maxCol + 1; col++) {
|
|
899
|
+
const x = Math.floor(headers.left + col * w - viewport.scrollX) + 0.5;
|
|
900
|
+
if (x < headers.left) {
|
|
901
|
+
continue;
|
|
902
|
+
}
|
|
903
|
+
ctx.moveTo(x, headers.top);
|
|
904
|
+
ctx.lineTo(x, size.height);
|
|
905
|
+
}
|
|
906
|
+
for (let row = range.minRow; row <= Math.min(range.maxRow + 1, rows.length); row++) {
|
|
907
|
+
const y = Math.floor(headers.top + row * h - viewport.scrollY) + 0.5;
|
|
908
|
+
if (y < headers.top) {
|
|
909
|
+
continue;
|
|
910
|
+
}
|
|
911
|
+
ctx.moveTo(headers.left, y);
|
|
912
|
+
ctx.lineTo(size.width, y);
|
|
913
|
+
}
|
|
914
|
+
ctx.stroke();
|
|
915
|
+
ctx.save();
|
|
916
|
+
ctx.beginPath();
|
|
917
|
+
ctx.rect(headers.left, headers.top, size.width - headers.left, size.height - headers.top);
|
|
918
|
+
ctx.clip();
|
|
919
|
+
for (const cell of visibleCells(cells, range)) {
|
|
920
|
+
if (cell.row >= rows.length) {
|
|
921
|
+
continue;
|
|
922
|
+
}
|
|
923
|
+
const rect = worldToScreen(viewport, headers, cell);
|
|
924
|
+
renderCell({
|
|
925
|
+
ctx,
|
|
926
|
+
...rect,
|
|
927
|
+
cell
|
|
928
|
+
});
|
|
929
|
+
}
|
|
930
|
+
ctx.restore();
|
|
931
|
+
};
|
|
932
|
+
|
|
933
|
+
// src/components/CellGrid/CellGrid.tsx
|
|
934
|
+
var defaultHeaders = {
|
|
935
|
+
left: 80,
|
|
936
|
+
top: 24
|
|
937
|
+
};
|
|
938
|
+
var defaultStaticStyle = {
|
|
939
|
+
gridLine: "rgba(128,128,128,0.25)",
|
|
940
|
+
rowBand: "rgba(128,128,128,0.06)"
|
|
941
|
+
};
|
|
942
|
+
var defaultOverlayStyle = {
|
|
943
|
+
playhead: "rgb(220, 38, 38)",
|
|
944
|
+
selectionFill: "rgba(59, 130, 246, 0.15)",
|
|
945
|
+
selectionStroke: "rgb(59, 130, 246)"
|
|
946
|
+
};
|
|
947
|
+
var setupCanvas = (canvas, width, height) => {
|
|
948
|
+
const dpr = window.devicePixelRatio || 1;
|
|
949
|
+
canvas.width = Math.max(1, Math.floor(width * dpr));
|
|
950
|
+
canvas.height = Math.max(1, Math.floor(height * dpr));
|
|
951
|
+
canvas.style.width = `${width}px`;
|
|
952
|
+
canvas.style.height = `${height}px`;
|
|
953
|
+
const ctx = canvas.getContext("2d");
|
|
954
|
+
if (!ctx) {
|
|
955
|
+
return null;
|
|
956
|
+
}
|
|
957
|
+
ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
|
|
958
|
+
return ctx;
|
|
959
|
+
};
|
|
960
|
+
var CellGrid = ({ atoms, rows, renderCell, headers: headersProp, staticStyle: staticStyleProp, overlayStyle: overlayStyleProp, classNames, onCellToggle, onSelectionCommit }) => {
|
|
961
|
+
const registry = useContext2(RegistryContext);
|
|
962
|
+
const headers = useMemo3(() => {
|
|
963
|
+
if (headersProp === false) {
|
|
964
|
+
return {
|
|
965
|
+
left: 0,
|
|
966
|
+
top: 0
|
|
967
|
+
};
|
|
968
|
+
}
|
|
969
|
+
return {
|
|
970
|
+
...defaultHeaders,
|
|
971
|
+
...headersProp ?? {}
|
|
972
|
+
};
|
|
973
|
+
}, [
|
|
974
|
+
headersProp
|
|
975
|
+
]);
|
|
976
|
+
const staticStyle = useMemo3(() => ({
|
|
977
|
+
...defaultStaticStyle,
|
|
978
|
+
...staticStyleProp ?? {}
|
|
979
|
+
}), [
|
|
980
|
+
staticStyleProp
|
|
981
|
+
]);
|
|
982
|
+
const overlayStyle = useMemo3(() => ({
|
|
983
|
+
...defaultOverlayStyle,
|
|
984
|
+
...overlayStyleProp ?? {}
|
|
985
|
+
}), [
|
|
986
|
+
overlayStyleProp
|
|
987
|
+
]);
|
|
988
|
+
const { ref: containerRef, width = 0, height = 0 } = useResizeDetector2();
|
|
989
|
+
const staticCanvasRef = useRef2(null);
|
|
990
|
+
const overlayCanvasRef = useRef2(null);
|
|
991
|
+
const overlayInputRef = useRef2(null);
|
|
992
|
+
const [staticCtx, setStaticCtx] = useState2(null);
|
|
993
|
+
const [overlayCtx, setOverlayCtx] = useState2(null);
|
|
994
|
+
const [viewportState, setViewportState] = useState2(() => registry.get(atoms.viewport));
|
|
995
|
+
useEffect4(() => {
|
|
996
|
+
if (!width || !height) {
|
|
997
|
+
return;
|
|
998
|
+
}
|
|
999
|
+
if (staticCanvasRef.current) {
|
|
1000
|
+
const ctx = setupCanvas(staticCanvasRef.current, width, height);
|
|
1001
|
+
setStaticCtx(ctx);
|
|
1002
|
+
}
|
|
1003
|
+
if (overlayCanvasRef.current) {
|
|
1004
|
+
const ctx = setupCanvas(overlayCanvasRef.current, width, height);
|
|
1005
|
+
setOverlayCtx(ctx);
|
|
1006
|
+
}
|
|
1007
|
+
}, [
|
|
1008
|
+
width,
|
|
1009
|
+
height
|
|
1010
|
+
]);
|
|
1011
|
+
useEffect4(() => registry.subscribe(atoms.viewport, (next) => setViewportState(next)), [
|
|
1012
|
+
registry,
|
|
1013
|
+
atoms.viewport
|
|
1014
|
+
]);
|
|
1015
|
+
useEffect4(() => {
|
|
1016
|
+
if (!staticCtx || !width || !height) {
|
|
1017
|
+
return;
|
|
1018
|
+
}
|
|
1019
|
+
let raf = null;
|
|
1020
|
+
const schedule = () => {
|
|
1021
|
+
if (raf !== null) {
|
|
1022
|
+
return;
|
|
1023
|
+
}
|
|
1024
|
+
raf = requestAnimationFrame(() => {
|
|
1025
|
+
raf = null;
|
|
1026
|
+
drawCells({
|
|
1027
|
+
ctx: staticCtx,
|
|
1028
|
+
size: {
|
|
1029
|
+
width,
|
|
1030
|
+
height
|
|
1031
|
+
},
|
|
1032
|
+
viewport: registry.get(atoms.viewport),
|
|
1033
|
+
headers,
|
|
1034
|
+
rows,
|
|
1035
|
+
cells: registry.get(atoms.cells),
|
|
1036
|
+
renderCell,
|
|
1037
|
+
style: staticStyle
|
|
1038
|
+
});
|
|
1039
|
+
});
|
|
1040
|
+
};
|
|
1041
|
+
schedule();
|
|
1042
|
+
const unsubCells = registry.subscribe(atoms.cells, schedule);
|
|
1043
|
+
const unsubViewport = registry.subscribe(atoms.viewport, schedule);
|
|
1044
|
+
return () => {
|
|
1045
|
+
if (raf !== null) {
|
|
1046
|
+
cancelAnimationFrame(raf);
|
|
1047
|
+
}
|
|
1048
|
+
unsubCells();
|
|
1049
|
+
unsubViewport();
|
|
1050
|
+
};
|
|
1051
|
+
}, [
|
|
1052
|
+
staticCtx,
|
|
1053
|
+
width,
|
|
1054
|
+
height,
|
|
1055
|
+
registry,
|
|
1056
|
+
atoms.cells,
|
|
1057
|
+
atoms.viewport,
|
|
1058
|
+
headers,
|
|
1059
|
+
rows,
|
|
1060
|
+
renderCell,
|
|
1061
|
+
staticStyle
|
|
1062
|
+
]);
|
|
1063
|
+
useEffect4(() => {
|
|
1064
|
+
if (!overlayCtx || !width || !height) {
|
|
1065
|
+
return;
|
|
1066
|
+
}
|
|
1067
|
+
let raf = null;
|
|
1068
|
+
let stopped = false;
|
|
1069
|
+
const paint = () => {
|
|
1070
|
+
drawOverlay({
|
|
1071
|
+
ctx: overlayCtx,
|
|
1072
|
+
size: {
|
|
1073
|
+
width,
|
|
1074
|
+
height
|
|
1075
|
+
},
|
|
1076
|
+
viewport: registry.get(atoms.viewport),
|
|
1077
|
+
headers,
|
|
1078
|
+
selection: registry.get(atoms.selection),
|
|
1079
|
+
playhead: registry.get(atoms.playhead),
|
|
1080
|
+
style: overlayStyle
|
|
1081
|
+
});
|
|
1082
|
+
};
|
|
1083
|
+
const isAnimating = () => registry.get(atoms.playhead) !== null;
|
|
1084
|
+
const loop = () => {
|
|
1085
|
+
if (stopped) {
|
|
1086
|
+
return;
|
|
1087
|
+
}
|
|
1088
|
+
paint();
|
|
1089
|
+
if (isAnimating()) {
|
|
1090
|
+
raf = requestAnimationFrame(loop);
|
|
1091
|
+
} else {
|
|
1092
|
+
raf = null;
|
|
1093
|
+
}
|
|
1094
|
+
};
|
|
1095
|
+
const kick = () => {
|
|
1096
|
+
paint();
|
|
1097
|
+
if (raf === null && isAnimating()) {
|
|
1098
|
+
raf = requestAnimationFrame(loop);
|
|
1099
|
+
}
|
|
1100
|
+
};
|
|
1101
|
+
kick();
|
|
1102
|
+
const unsubSelection = registry.subscribe(atoms.selection, () => paint());
|
|
1103
|
+
const unsubPlayhead = registry.subscribe(atoms.playhead, kick);
|
|
1104
|
+
const unsubViewport = registry.subscribe(atoms.viewport, () => paint());
|
|
1105
|
+
return () => {
|
|
1106
|
+
stopped = true;
|
|
1107
|
+
if (raf !== null) {
|
|
1108
|
+
cancelAnimationFrame(raf);
|
|
1109
|
+
}
|
|
1110
|
+
unsubSelection();
|
|
1111
|
+
unsubPlayhead();
|
|
1112
|
+
unsubViewport();
|
|
1113
|
+
};
|
|
1114
|
+
}, [
|
|
1115
|
+
overlayCtx,
|
|
1116
|
+
width,
|
|
1117
|
+
height,
|
|
1118
|
+
registry,
|
|
1119
|
+
atoms.selection,
|
|
1120
|
+
atoms.playhead,
|
|
1121
|
+
atoms.viewport,
|
|
1122
|
+
headers,
|
|
1123
|
+
overlayStyle
|
|
1124
|
+
]);
|
|
1125
|
+
const callbacksRef = useRef2({
|
|
1126
|
+
onCellToggle,
|
|
1127
|
+
onSelectionCommit
|
|
1128
|
+
});
|
|
1129
|
+
callbacksRef.current = {
|
|
1130
|
+
onCellToggle,
|
|
1131
|
+
onSelectionCommit
|
|
1132
|
+
};
|
|
1133
|
+
useEffect4(() => {
|
|
1134
|
+
const element = overlayInputRef.current;
|
|
1135
|
+
if (!element) {
|
|
1136
|
+
return;
|
|
1137
|
+
}
|
|
1138
|
+
const detachPointer = attachPointerHandlers(element, {
|
|
1139
|
+
registry,
|
|
1140
|
+
atoms,
|
|
1141
|
+
headers,
|
|
1142
|
+
handlers: {
|
|
1143
|
+
onCellToggle: (coord, mode) => callbacksRef.current.onCellToggle?.(coord, mode),
|
|
1144
|
+
onSelectionCommit: (range) => callbacksRef.current.onSelectionCommit?.(range)
|
|
1145
|
+
}
|
|
1146
|
+
});
|
|
1147
|
+
const detachWheel = attachWheelHandlers(element, {
|
|
1148
|
+
registry,
|
|
1149
|
+
atoms,
|
|
1150
|
+
headers
|
|
1151
|
+
});
|
|
1152
|
+
return () => {
|
|
1153
|
+
detachPointer();
|
|
1154
|
+
detachWheel();
|
|
1155
|
+
};
|
|
1156
|
+
}, [
|
|
1157
|
+
registry,
|
|
1158
|
+
atoms,
|
|
1159
|
+
headers
|
|
1160
|
+
]);
|
|
1161
|
+
return /* @__PURE__ */ React5.createElement("div", {
|
|
1162
|
+
ref: containerRef,
|
|
1163
|
+
className: mx5("relative w-full h-full overflow-hidden bg-baseSurface", classNames)
|
|
1164
|
+
}, /* @__PURE__ */ React5.createElement("canvas", {
|
|
1165
|
+
ref: staticCanvasRef,
|
|
1166
|
+
className: "absolute inset-0 pointer-events-none",
|
|
1167
|
+
style: {
|
|
1168
|
+
top: -1,
|
|
1169
|
+
left: -1
|
|
1170
|
+
}
|
|
1171
|
+
}), /* @__PURE__ */ React5.createElement("canvas", {
|
|
1172
|
+
ref: overlayCanvasRef,
|
|
1173
|
+
className: "absolute inset-0 pointer-events-none",
|
|
1174
|
+
style: {
|
|
1175
|
+
top: -1,
|
|
1176
|
+
left: -1
|
|
1177
|
+
}
|
|
1178
|
+
}), /* @__PURE__ */ React5.createElement("div", {
|
|
1179
|
+
ref: overlayInputRef,
|
|
1180
|
+
className: "absolute inset-0 touch-none",
|
|
1181
|
+
style: {
|
|
1182
|
+
paddingLeft: headers.left,
|
|
1183
|
+
paddingTop: headers.top
|
|
1184
|
+
}
|
|
1185
|
+
}), headers.top > 0 && /* @__PURE__ */ React5.createElement(Ruler, {
|
|
1186
|
+
viewport: viewportState,
|
|
1187
|
+
headers,
|
|
1188
|
+
width
|
|
1189
|
+
}), headers.left > 0 && /* @__PURE__ */ React5.createElement(TrackHeader, {
|
|
1190
|
+
viewport: viewportState,
|
|
1191
|
+
headers,
|
|
1192
|
+
rows,
|
|
1193
|
+
height
|
|
1194
|
+
}), headers.top > 0 && headers.left > 0 && /* @__PURE__ */ React5.createElement("div", {
|
|
1195
|
+
className: "absolute top-0 left-0 border-b border-r border-neutral-200 dark:border-neutral-700 bg-baseSurface",
|
|
1196
|
+
style: {
|
|
1197
|
+
width: headers.left,
|
|
1198
|
+
height: headers.top
|
|
1199
|
+
}
|
|
1200
|
+
}));
|
|
1201
|
+
};
|
|
1202
|
+
|
|
1203
|
+
// src/components/CellGrid/state/atoms.ts
|
|
1204
|
+
import { Atom } from "@effect-atom/atom-react";
|
|
1205
|
+
var defaultViewport = (options = {}) => ({
|
|
1206
|
+
scrollX: 0,
|
|
1207
|
+
scrollY: 0,
|
|
1208
|
+
baseCellWidth: options.cellWidth ?? 24,
|
|
1209
|
+
cellHeight: options.cellHeight ?? 24,
|
|
1210
|
+
zoomX: 1
|
|
1211
|
+
});
|
|
1212
|
+
var createCellGridAtoms = (options = {}) => ({
|
|
1213
|
+
cells: Atom.keepAlive(Atom.make(/* @__PURE__ */ new Map())),
|
|
1214
|
+
viewport: Atom.keepAlive(Atom.make(defaultViewport(options))),
|
|
1215
|
+
selection: Atom.keepAlive(Atom.make({
|
|
1216
|
+
range: null
|
|
1217
|
+
})),
|
|
1218
|
+
playhead: Atom.keepAlive(Atom.make(null)),
|
|
1219
|
+
tool: Atom.keepAlive(Atom.make("toggle"))
|
|
1220
|
+
});
|
|
1221
|
+
|
|
1222
|
+
// src/components/FPS.tsx
|
|
1223
|
+
import React6, { useEffect as useEffect5, useReducer, useRef as useRef3 } from "react";
|
|
1224
|
+
import { mx as mx6 } from "@dxos/ui-theme";
|
|
483
1225
|
var SEC = 1e3;
|
|
484
1226
|
var FPS = ({ classNames, width = 60, height = 30, bar = "bg-cyan-500" }) => {
|
|
485
1227
|
const [{ fps, max, len }, dispatch] = useReducer((state) => {
|
|
@@ -512,12 +1254,12 @@ var FPS = ({ classNames, width = 60, height = 30, bar = "bg-cyan-500" }) => {
|
|
|
512
1254
|
frames: 0,
|
|
513
1255
|
prevTime: Date.now()
|
|
514
1256
|
});
|
|
515
|
-
const requestRef =
|
|
1257
|
+
const requestRef = useRef3(null);
|
|
516
1258
|
const tick = () => {
|
|
517
1259
|
dispatch();
|
|
518
1260
|
requestRef.current = requestAnimationFrame(tick);
|
|
519
1261
|
};
|
|
520
|
-
|
|
1262
|
+
useEffect5(() => {
|
|
521
1263
|
requestRef.current = requestAnimationFrame(tick);
|
|
522
1264
|
return () => {
|
|
523
1265
|
if (requestRef.current) {
|
|
@@ -525,17 +1267,17 @@ var FPS = ({ classNames, width = 60, height = 30, bar = "bg-cyan-500" }) => {
|
|
|
525
1267
|
}
|
|
526
1268
|
};
|
|
527
1269
|
}, []);
|
|
528
|
-
return /* @__PURE__ */
|
|
1270
|
+
return /* @__PURE__ */ React6.createElement("div", {
|
|
529
1271
|
style: {
|
|
530
1272
|
width: width + 6
|
|
531
1273
|
},
|
|
532
|
-
className:
|
|
533
|
-
}, /* @__PURE__ */
|
|
1274
|
+
className: mx6("relative flex flex-col p-0.5", "bg-base-surface text-xs text-subdued font-thin pointer-events-none border border-separator", classNames)
|
|
1275
|
+
}, /* @__PURE__ */ React6.createElement("div", null, fps[len - 1], " FPS"), /* @__PURE__ */ React6.createElement("div", {
|
|
534
1276
|
className: "w-full relative",
|
|
535
1277
|
style: {
|
|
536
1278
|
height
|
|
537
1279
|
}
|
|
538
|
-
}, fps.map((frame, i) => /* @__PURE__ */
|
|
1280
|
+
}, fps.map((frame, i) => /* @__PURE__ */ React6.createElement("div", {
|
|
539
1281
|
key: `fps-${i}`,
|
|
540
1282
|
className: bar,
|
|
541
1283
|
style: {
|
|
@@ -549,9 +1291,9 @@ var FPS = ({ classNames, width = 60, height = 30, bar = "bg-cyan-500" }) => {
|
|
|
549
1291
|
};
|
|
550
1292
|
|
|
551
1293
|
// src/components/Grid/Grid.tsx
|
|
552
|
-
import
|
|
1294
|
+
import React7, { forwardRef as forwardRef2, useId, useMemo as useMemo4 } from "react";
|
|
553
1295
|
import { useForwardedRef } from "@dxos/react-ui";
|
|
554
|
-
import { mx as
|
|
1296
|
+
import { mx as mx7 } from "@dxos/ui-theme";
|
|
555
1297
|
var gridRatios = [
|
|
556
1298
|
1 / 4,
|
|
557
1299
|
1,
|
|
@@ -566,7 +1308,7 @@ var defaultOffset = {
|
|
|
566
1308
|
var createId = (parent, grid) => `dx-canvas-grid-${parent}-${grid}`;
|
|
567
1309
|
var Grid = (props) => {
|
|
568
1310
|
const { scale, offset } = useCanvasContext();
|
|
569
|
-
return /* @__PURE__ */
|
|
1311
|
+
return /* @__PURE__ */ React7.createElement(GridComponent, {
|
|
570
1312
|
...props,
|
|
571
1313
|
scale,
|
|
572
1314
|
offset
|
|
@@ -576,35 +1318,35 @@ var GridComponent = /* @__PURE__ */ forwardRef2(({ size: gridSize = defaultGridS
|
|
|
576
1318
|
const svgRef = useForwardedRef(forwardedRef);
|
|
577
1319
|
const { width = 0, height = 0 } = svgRef.current?.getBoundingClientRect() ?? {};
|
|
578
1320
|
const instanceId = useId();
|
|
579
|
-
const grids =
|
|
1321
|
+
const grids = useMemo4(() => gridRatios.map((ratio) => ({
|
|
580
1322
|
id: ratio,
|
|
581
1323
|
size: ratio * gridSize * scale
|
|
582
1324
|
})).filter(({ size }) => size >= gridSize && size <= 128), [
|
|
583
1325
|
gridSize,
|
|
584
1326
|
scale
|
|
585
1327
|
]);
|
|
586
|
-
return /* @__PURE__ */
|
|
1328
|
+
return /* @__PURE__ */ React7.createElement("svg", {
|
|
587
1329
|
...testId("dx-canvas-grid"),
|
|
588
1330
|
ref: svgRef,
|
|
589
|
-
className:
|
|
590
|
-
}, /* @__PURE__ */
|
|
1331
|
+
className: mx7("dx-fullscreen pointer-events-none touch-none select-none", "stroke-neutral-500", classNames)
|
|
1332
|
+
}, /* @__PURE__ */ React7.createElement("defs", null, grids.map(({ id, size }) => /* @__PURE__ */ React7.createElement(GridPattern, {
|
|
591
1333
|
key: id,
|
|
592
1334
|
id: createId(instanceId, id),
|
|
593
1335
|
offset,
|
|
594
1336
|
size
|
|
595
|
-
}))), showAxes && /* @__PURE__ */
|
|
1337
|
+
}))), showAxes && /* @__PURE__ */ React7.createElement(React7.Fragment, null, /* @__PURE__ */ React7.createElement("line", {
|
|
596
1338
|
x1: 0,
|
|
597
1339
|
y1: offset.y,
|
|
598
1340
|
x2: width,
|
|
599
1341
|
y2: offset.y,
|
|
600
1342
|
className: "stroke-neutral-500 opacity-40"
|
|
601
|
-
}), /* @__PURE__ */
|
|
1343
|
+
}), /* @__PURE__ */ React7.createElement("line", {
|
|
602
1344
|
x1: offset.x,
|
|
603
1345
|
y1: 0,
|
|
604
1346
|
x2: offset.x,
|
|
605
1347
|
y2: height,
|
|
606
1348
|
className: "stroke-neutral-500 opacity-40"
|
|
607
|
-
})), /* @__PURE__ */
|
|
1349
|
+
})), /* @__PURE__ */ React7.createElement("g", null, grids.map(({ id }, i) => /* @__PURE__ */ React7.createElement("rect", {
|
|
608
1350
|
key: id,
|
|
609
1351
|
opacity: 0.1 + i * 0.05,
|
|
610
1352
|
fill: `url(#${createId(instanceId, id)})`,
|
|
@@ -628,6 +1370,7 @@ export {
|
|
|
628
1370
|
Arrow,
|
|
629
1371
|
Canvas,
|
|
630
1372
|
CanvasContext,
|
|
1373
|
+
CellGrid,
|
|
631
1374
|
DATA_TEST_ID,
|
|
632
1375
|
Dimension,
|
|
633
1376
|
FPS,
|
|
@@ -639,15 +1382,31 @@ export {
|
|
|
639
1382
|
Point,
|
|
640
1383
|
ProjectionMapper,
|
|
641
1384
|
Rect,
|
|
1385
|
+
Ruler,
|
|
1386
|
+
TrackHeader,
|
|
1387
|
+
attachPointerHandlers,
|
|
1388
|
+
attachWheelHandlers,
|
|
1389
|
+
cellKey,
|
|
1390
|
+
cellWidth,
|
|
1391
|
+
createCellGridAtoms,
|
|
642
1392
|
createPath,
|
|
643
1393
|
defaultOrigin,
|
|
1394
|
+
defaultViewport,
|
|
1395
|
+
drawCells,
|
|
1396
|
+
drawOverlay,
|
|
644
1397
|
getRelativePoint,
|
|
645
1398
|
getZoomTransform,
|
|
1399
|
+
hitTestCell,
|
|
646
1400
|
inspectElement,
|
|
1401
|
+
screenToWorld,
|
|
647
1402
|
testId,
|
|
1403
|
+
toggleCell,
|
|
648
1404
|
useCanvasContext,
|
|
649
1405
|
useDrag,
|
|
650
1406
|
useWheel,
|
|
1407
|
+
visibleCellRange,
|
|
1408
|
+
visibleCells,
|
|
1409
|
+
worldToScreen,
|
|
651
1410
|
zoomInPlace,
|
|
652
1411
|
zoomTo
|
|
653
1412
|
};
|