canvu-react 0.4.12 → 0.4.14
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/dist/react.cjs +85 -21
- package/dist/react.cjs.map +1 -1
- package/dist/react.js +85 -21
- package/dist/react.js.map +1 -1
- package/package.json +1 -1
package/dist/react.cjs
CHANGED
|
@@ -3655,7 +3655,7 @@ function ColorPalette({ value, onChange }) {
|
|
|
3655
3655
|
"button",
|
|
3656
3656
|
{
|
|
3657
3657
|
type: "button",
|
|
3658
|
-
"aria-label": "
|
|
3658
|
+
"aria-label": "Custom color",
|
|
3659
3659
|
"aria-pressed": showCustom || !inPalette,
|
|
3660
3660
|
onClick: () => setShowCustom((v) => !v),
|
|
3661
3661
|
onPointerDown: (e) => {
|
|
@@ -3716,14 +3716,14 @@ function ColorPalette({ value, onChange }) {
|
|
|
3716
3716
|
}
|
|
3717
3717
|
function DashTabs({ value, onChange }) {
|
|
3718
3718
|
const tabs = [
|
|
3719
|
-
{ id: "solid", label: "
|
|
3720
|
-
{ id: "dashed", label: "
|
|
3719
|
+
{ id: "solid", label: "Solid" },
|
|
3720
|
+
{ id: "dashed", label: "Dashed" }
|
|
3721
3721
|
];
|
|
3722
3722
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
3723
3723
|
"div",
|
|
3724
3724
|
{
|
|
3725
3725
|
role: "radiogroup",
|
|
3726
|
-
"aria-label": "
|
|
3726
|
+
"aria-label": "Stroke style",
|
|
3727
3727
|
style: {
|
|
3728
3728
|
display: "flex",
|
|
3729
3729
|
background: "rgba(24,24,27,0.06)",
|
|
@@ -3806,7 +3806,7 @@ function FontSizeTabs({ value, onChange }) {
|
|
|
3806
3806
|
"div",
|
|
3807
3807
|
{
|
|
3808
3808
|
role: "radiogroup",
|
|
3809
|
-
"aria-label": "
|
|
3809
|
+
"aria-label": "Text size",
|
|
3810
3810
|
style: {
|
|
3811
3811
|
display: "flex",
|
|
3812
3812
|
background: "rgba(24,24,27,0.06)",
|
|
@@ -3870,7 +3870,7 @@ function viewModelFromActiveTool(activeToolStyle) {
|
|
|
3870
3870
|
...isText ? { textFontSize } : {}
|
|
3871
3871
|
};
|
|
3872
3872
|
return {
|
|
3873
|
-
label: activeToolStyle.label ?? "
|
|
3873
|
+
label: activeToolStyle.label ?? "Tool style",
|
|
3874
3874
|
count: 0,
|
|
3875
3875
|
hex,
|
|
3876
3876
|
strokeWidth,
|
|
@@ -3929,7 +3929,7 @@ function viewModelFromSelection(stylable) {
|
|
|
3929
3929
|
...showFontSize ? { textFontSize } : {}
|
|
3930
3930
|
};
|
|
3931
3931
|
return {
|
|
3932
|
-
label: "
|
|
3932
|
+
label: "Selection style",
|
|
3933
3933
|
count: stylable.length,
|
|
3934
3934
|
hex,
|
|
3935
3935
|
strokeWidth,
|
|
@@ -3992,18 +3992,18 @@ function VectorSelectionInspector({
|
|
|
3992
3992
|
children: [
|
|
3993
3993
|
vm.count > 1 ? /* @__PURE__ */ jsxRuntime.jsxs("p", { style: { margin: 0, fontSize: 11, color: "#71717a" }, children: [
|
|
3994
3994
|
vm.count,
|
|
3995
|
-
"
|
|
3995
|
+
" objects selected"
|
|
3996
3996
|
] }) : null,
|
|
3997
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { role: "group", "aria-label": "
|
|
3997
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { role: "group", "aria-label": "Color", style: sectionLabelStyle, children: [
|
|
3998
3998
|
/* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
|
|
3999
|
-
"
|
|
4000
|
-
vm.mixedStroke ? /* @__PURE__ */ jsxRuntime.jsx("span", { style: mixedHintStyle, children: " (
|
|
3999
|
+
"Color",
|
|
4000
|
+
vm.mixedStroke ? /* @__PURE__ */ jsxRuntime.jsx("span", { style: mixedHintStyle, children: " (mixed values)" }) : null
|
|
4001
4001
|
] }),
|
|
4002
4002
|
/* @__PURE__ */ jsxRuntime.jsx(ColorPalette, { value: vm.hex, onChange: (h) => apply({ stroke: h }) })
|
|
4003
4003
|
] }),
|
|
4004
4004
|
vm.showStrokeWidth ? /* @__PURE__ */ jsxRuntime.jsxs("label", { style: sectionLabelStyle, children: [
|
|
4005
|
-
"
|
|
4006
|
-
vm.mixedWidth ? /* @__PURE__ */ jsxRuntime.jsx("span", { style: mixedHintStyle, children: " (
|
|
4005
|
+
"Thickness",
|
|
4006
|
+
vm.mixedWidth ? /* @__PURE__ */ jsxRuntime.jsx("span", { style: mixedHintStyle, children: " (mixed)" }) : null,
|
|
4007
4007
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4008
4008
|
"input",
|
|
4009
4009
|
{
|
|
@@ -4017,10 +4017,10 @@ function VectorSelectionInspector({
|
|
|
4017
4017
|
] }) : null,
|
|
4018
4018
|
vm.showDash ? (
|
|
4019
4019
|
// biome-ignore lint/a11y/useSemanticElements: fieldset would impose default browser styling that breaks the inspector layout
|
|
4020
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { role: "group", "aria-label": "
|
|
4020
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { role: "group", "aria-label": "Stroke", style: sectionLabelStyle, children: [
|
|
4021
4021
|
/* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
|
|
4022
|
-
"
|
|
4023
|
-
vm.mixedDash ? /* @__PURE__ */ jsxRuntime.jsx("span", { style: mixedHintStyle, children: " (
|
|
4022
|
+
"Stroke",
|
|
4023
|
+
vm.mixedDash ? /* @__PURE__ */ jsxRuntime.jsx("span", { style: mixedHintStyle, children: " (mixed)" }) : null
|
|
4024
4024
|
] }),
|
|
4025
4025
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4026
4026
|
DashTabs,
|
|
@@ -4033,10 +4033,10 @@ function VectorSelectionInspector({
|
|
|
4033
4033
|
) : null,
|
|
4034
4034
|
vm.showFontSize ? (
|
|
4035
4035
|
// biome-ignore lint/a11y/useSemanticElements: fieldset would impose default browser styling that breaks the inspector layout
|
|
4036
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { role: "group", "aria-label": "
|
|
4036
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { role: "group", "aria-label": "Size", style: sectionLabelStyle, children: [
|
|
4037
4037
|
/* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
|
|
4038
|
-
"
|
|
4039
|
-
vm.mixedFontSize ? /* @__PURE__ */ jsxRuntime.jsx("span", { style: mixedHintStyle, children: " (
|
|
4038
|
+
"Size",
|
|
4039
|
+
vm.mixedFontSize ? /* @__PURE__ */ jsxRuntime.jsx("span", { style: mixedHintStyle, children: " (mixed)" }) : null
|
|
4040
4040
|
] }),
|
|
4041
4041
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4042
4042
|
FontSizeTabs,
|
|
@@ -4048,8 +4048,8 @@ function VectorSelectionInspector({
|
|
|
4048
4048
|
] })
|
|
4049
4049
|
) : null,
|
|
4050
4050
|
vm.showMarkerOpacity ? /* @__PURE__ */ jsxRuntime.jsxs("label", { style: sectionLabelStyle, children: [
|
|
4051
|
-
"
|
|
4052
|
-
vm.mixedOpacity ? /* @__PURE__ */ jsxRuntime.jsx("span", { style: mixedHintStyle, children: " (
|
|
4051
|
+
"Opacity",
|
|
4052
|
+
vm.mixedOpacity ? /* @__PURE__ */ jsxRuntime.jsx("span", { style: mixedHintStyle, children: " (mixed)" }) : null,
|
|
4053
4053
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4054
4054
|
"input",
|
|
4055
4055
|
{
|
|
@@ -8050,6 +8050,7 @@ var VectorViewport = react.forwardRef(
|
|
|
8050
8050
|
const wrapperRef = react.useRef(null);
|
|
8051
8051
|
const interactionRootRef = react.useRef(null);
|
|
8052
8052
|
const sceneContainerRef = react.useRef(null);
|
|
8053
|
+
const lastPointerScreenRef = react.useRef(null);
|
|
8053
8054
|
const activeInteractionPointerIdRef = react.useRef(null);
|
|
8054
8055
|
const activeInteractionPointerTargetRef = react.useRef(null);
|
|
8055
8056
|
const activeInteractionTouchIdRef = react.useRef(null);
|
|
@@ -8776,6 +8777,24 @@ var VectorViewport = react.forwardRef(
|
|
|
8776
8777
|
root.removeEventListener("pointerleave", leave);
|
|
8777
8778
|
};
|
|
8778
8779
|
}, [onWorldPointerMove]);
|
|
8780
|
+
react.useEffect(() => {
|
|
8781
|
+
const root = wrapperRef.current;
|
|
8782
|
+
if (!root) return;
|
|
8783
|
+
const record = (e) => {
|
|
8784
|
+
lastPointerScreenRef.current = { x: e.clientX, y: e.clientY };
|
|
8785
|
+
};
|
|
8786
|
+
const clear = () => {
|
|
8787
|
+
lastPointerScreenRef.current = null;
|
|
8788
|
+
};
|
|
8789
|
+
root.addEventListener("pointermove", record, { passive: true });
|
|
8790
|
+
root.addEventListener("pointerdown", record, { passive: true });
|
|
8791
|
+
root.addEventListener("pointerleave", clear);
|
|
8792
|
+
return () => {
|
|
8793
|
+
root.removeEventListener("pointermove", record);
|
|
8794
|
+
root.removeEventListener("pointerdown", record);
|
|
8795
|
+
root.removeEventListener("pointerleave", clear);
|
|
8796
|
+
};
|
|
8797
|
+
}, []);
|
|
8779
8798
|
react.useEffect(() => {
|
|
8780
8799
|
if (directRemoteStrokePreviewRef.current && placementPreview === null) {
|
|
8781
8800
|
return;
|
|
@@ -9495,6 +9514,50 @@ var VectorViewport = react.forwardRef(
|
|
|
9495
9514
|
},
|
|
9496
9515
|
[screenToWorld, placeImageFilesAtWorld]
|
|
9497
9516
|
);
|
|
9517
|
+
const handleWrapperPaste = react.useCallback(
|
|
9518
|
+
async (e) => {
|
|
9519
|
+
if (!interactiveRef.current || !onItemsChangeRef.current) return;
|
|
9520
|
+
const t = e.target;
|
|
9521
|
+
if (t instanceof HTMLTextAreaElement || t instanceof HTMLInputElement || t instanceof HTMLElement && t.isContentEditable) {
|
|
9522
|
+
return;
|
|
9523
|
+
}
|
|
9524
|
+
if (editingTextIdRef.current) return;
|
|
9525
|
+
const dt = e.clipboardData;
|
|
9526
|
+
if (!dt) return;
|
|
9527
|
+
const files = [];
|
|
9528
|
+
for (const file of Array.from(dt.files)) {
|
|
9529
|
+
if (file.type.startsWith("image/")) files.push(file);
|
|
9530
|
+
}
|
|
9531
|
+
if (files.length === 0) {
|
|
9532
|
+
for (const item of Array.from(dt.items)) {
|
|
9533
|
+
if (item.kind === "file" && item.type.startsWith("image/")) {
|
|
9534
|
+
const file = item.getAsFile();
|
|
9535
|
+
if (file) files.push(file);
|
|
9536
|
+
}
|
|
9537
|
+
}
|
|
9538
|
+
}
|
|
9539
|
+
if (files.length === 0) return;
|
|
9540
|
+
e.preventDefault();
|
|
9541
|
+
const last = lastPointerScreenRef.current;
|
|
9542
|
+
let target;
|
|
9543
|
+
if (last) {
|
|
9544
|
+
target = screenToWorld(last.x, last.y);
|
|
9545
|
+
} else {
|
|
9546
|
+
const el = sceneContainerRef.current;
|
|
9547
|
+
const cam = cameraRef.current;
|
|
9548
|
+
if (el && cam) {
|
|
9549
|
+
const rect = el.getBoundingClientRect();
|
|
9550
|
+
target = cam.screenToWorld(rect.width / 2, rect.height / 2);
|
|
9551
|
+
} else {
|
|
9552
|
+
target = { worldX: 0, worldY: 0 };
|
|
9553
|
+
}
|
|
9554
|
+
}
|
|
9555
|
+
await placeImageFilesAtWorld(files, target.worldX, target.worldY, {
|
|
9556
|
+
stackBelowExistingItems: false
|
|
9557
|
+
});
|
|
9558
|
+
},
|
|
9559
|
+
[screenToWorld, placeImageFilesAtWorld]
|
|
9560
|
+
);
|
|
9498
9561
|
const handleOverlayDoubleClick = react.useCallback(
|
|
9499
9562
|
(e) => {
|
|
9500
9563
|
const cam = cameraRef.current;
|
|
@@ -10764,6 +10827,7 @@ var VectorViewport = react.forwardRef(
|
|
|
10764
10827
|
"aria-label": ariaLabel,
|
|
10765
10828
|
"aria-describedby": liveId,
|
|
10766
10829
|
onKeyDown,
|
|
10830
|
+
onPaste: handleWrapperPaste,
|
|
10767
10831
|
onDragOver: handleWrapperDragOver,
|
|
10768
10832
|
onDrop: handleWrapperDrop,
|
|
10769
10833
|
children: [
|