@ewjdev/anyclick-react 1.1.0 → 1.1.1
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/README.md +53 -63
- package/dist/index.d.mts +28 -6
- package/dist/index.d.ts +28 -6
- package/dist/index.js +289 -57
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +289 -57
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -3
package/dist/index.mjs
CHANGED
|
@@ -731,45 +731,56 @@ var __iconNode7 = [
|
|
|
731
731
|
];
|
|
732
732
|
var Flag = createLucideIcon("flag", __iconNode7);
|
|
733
733
|
|
|
734
|
-
// ../../node_modules/lucide-react/dist/esm/icons/
|
|
734
|
+
// ../../node_modules/lucide-react/dist/esm/icons/grip-vertical.js
|
|
735
735
|
var __iconNode8 = [
|
|
736
|
+
["circle", { cx: "9", cy: "12", r: "1", key: "1vctgf" }],
|
|
737
|
+
["circle", { cx: "9", cy: "5", r: "1", key: "hp0tcf" }],
|
|
738
|
+
["circle", { cx: "9", cy: "19", r: "1", key: "fkjjf6" }],
|
|
739
|
+
["circle", { cx: "15", cy: "12", r: "1", key: "1tmaij" }],
|
|
740
|
+
["circle", { cx: "15", cy: "5", r: "1", key: "19l28e" }],
|
|
741
|
+
["circle", { cx: "15", cy: "19", r: "1", key: "f4zoj3" }]
|
|
742
|
+
];
|
|
743
|
+
var GripVertical = createLucideIcon("grip-vertical", __iconNode8);
|
|
744
|
+
|
|
745
|
+
// ../../node_modules/lucide-react/dist/esm/icons/image.js
|
|
746
|
+
var __iconNode9 = [
|
|
736
747
|
["rect", { width: "18", height: "18", x: "3", y: "3", rx: "2", ry: "2", key: "1m3agn" }],
|
|
737
748
|
["circle", { cx: "9", cy: "9", r: "2", key: "af1f0g" }],
|
|
738
749
|
["path", { d: "m21 15-3.086-3.086a2 2 0 0 0-2.828 0L6 21", key: "1xmnt7" }]
|
|
739
750
|
];
|
|
740
|
-
var Image = createLucideIcon("image",
|
|
751
|
+
var Image = createLucideIcon("image", __iconNode9);
|
|
741
752
|
|
|
742
753
|
// ../../node_modules/lucide-react/dist/esm/icons/loader-circle.js
|
|
743
|
-
var
|
|
744
|
-
var LoaderCircle = createLucideIcon("loader-circle",
|
|
754
|
+
var __iconNode10 = [["path", { d: "M21 12a9 9 0 1 1-6.219-8.56", key: "13zald" }]];
|
|
755
|
+
var LoaderCircle = createLucideIcon("loader-circle", __iconNode10);
|
|
745
756
|
|
|
746
757
|
// ../../node_modules/lucide-react/dist/esm/icons/plus.js
|
|
747
|
-
var
|
|
758
|
+
var __iconNode11 = [
|
|
748
759
|
["path", { d: "M5 12h14", key: "1ays0h" }],
|
|
749
760
|
["path", { d: "M12 5v14", key: "s699le" }]
|
|
750
761
|
];
|
|
751
|
-
var Plus = createLucideIcon("plus",
|
|
762
|
+
var Plus = createLucideIcon("plus", __iconNode11);
|
|
752
763
|
|
|
753
764
|
// ../../node_modules/lucide-react/dist/esm/icons/refresh-cw.js
|
|
754
|
-
var
|
|
765
|
+
var __iconNode12 = [
|
|
755
766
|
["path", { d: "M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8", key: "v9h5vc" }],
|
|
756
767
|
["path", { d: "M21 3v5h-5", key: "1q7to0" }],
|
|
757
768
|
["path", { d: "M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16", key: "3uifl3" }],
|
|
758
769
|
["path", { d: "M8 16H3v5", key: "1cv678" }]
|
|
759
770
|
];
|
|
760
|
-
var RefreshCw = createLucideIcon("refresh-cw",
|
|
771
|
+
var RefreshCw = createLucideIcon("refresh-cw", __iconNode12);
|
|
761
772
|
|
|
762
773
|
// ../../node_modules/lucide-react/dist/esm/icons/shrink.js
|
|
763
|
-
var
|
|
774
|
+
var __iconNode13 = [
|
|
764
775
|
["path", { d: "m15 15 6 6m-6-6v4.8m0-4.8h4.8", key: "17vawe" }],
|
|
765
776
|
["path", { d: "M9 19.8V15m0 0H4.2M9 15l-6 6", key: "chjx8e" }],
|
|
766
777
|
["path", { d: "M15 4.2V9m0 0h4.8M15 9l6-6", key: "lav6yq" }],
|
|
767
778
|
["path", { d: "M9 4.2V9m0 0H4.2M9 9 3 3", key: "1pxi2q" }]
|
|
768
779
|
];
|
|
769
|
-
var Shrink = createLucideIcon("shrink",
|
|
780
|
+
var Shrink = createLucideIcon("shrink", __iconNode13);
|
|
770
781
|
|
|
771
782
|
// ../../node_modules/lucide-react/dist/esm/icons/thumbs-up.js
|
|
772
|
-
var
|
|
783
|
+
var __iconNode14 = [
|
|
773
784
|
["path", { d: "M7 10v12", key: "1qc93n" }],
|
|
774
785
|
[
|
|
775
786
|
"path",
|
|
@@ -779,14 +790,14 @@ var __iconNode13 = [
|
|
|
779
790
|
}
|
|
780
791
|
]
|
|
781
792
|
];
|
|
782
|
-
var ThumbsUp = createLucideIcon("thumbs-up",
|
|
793
|
+
var ThumbsUp = createLucideIcon("thumbs-up", __iconNode14);
|
|
783
794
|
|
|
784
795
|
// ../../node_modules/lucide-react/dist/esm/icons/x.js
|
|
785
|
-
var
|
|
796
|
+
var __iconNode15 = [
|
|
786
797
|
["path", { d: "M18 6 6 18", key: "1bl5f8" }],
|
|
787
798
|
["path", { d: "m6 6 12 12", key: "d8bk6v" }]
|
|
788
799
|
];
|
|
789
|
-
var X = createLucideIcon("x",
|
|
800
|
+
var X = createLucideIcon("x", __iconNode15);
|
|
790
801
|
|
|
791
802
|
// src/ScreenshotPreview.tsx
|
|
792
803
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
@@ -1016,6 +1027,17 @@ function ScreenshotPreview({
|
|
|
1016
1027
|
|
|
1017
1028
|
// src/ContextMenu.tsx
|
|
1018
1029
|
import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
1030
|
+
var VIEWPORT_PADDING = 10;
|
|
1031
|
+
var screenshotIndicatorStyle = {
|
|
1032
|
+
display: "flex",
|
|
1033
|
+
alignItems: "center",
|
|
1034
|
+
gap: "6px",
|
|
1035
|
+
padding: "8px 12px",
|
|
1036
|
+
fontSize: "11px",
|
|
1037
|
+
color: "var(--anyclick-menu-text-muted, #9ca3af)",
|
|
1038
|
+
borderTop: "1px solid var(--anyclick-menu-border, #f3f4f6)",
|
|
1039
|
+
marginTop: "4px"
|
|
1040
|
+
};
|
|
1019
1041
|
var defaultIcons = {
|
|
1020
1042
|
issue: /* @__PURE__ */ jsx2(Flag, { className: "w-4 h-4" }),
|
|
1021
1043
|
feature: /* @__PURE__ */ jsx2(Plus, { className: "w-4 h-4" }),
|
|
@@ -1028,6 +1050,7 @@ function MenuItem({
|
|
|
1028
1050
|
hasChildren
|
|
1029
1051
|
}) {
|
|
1030
1052
|
const [isHovered, setIsHovered] = useState2(false);
|
|
1053
|
+
const [isPressed, setIsPressed] = useState2(false);
|
|
1031
1054
|
return /* @__PURE__ */ jsxs2(
|
|
1032
1055
|
"button",
|
|
1033
1056
|
{
|
|
@@ -1035,11 +1058,25 @@ function MenuItem({
|
|
|
1035
1058
|
onClick,
|
|
1036
1059
|
disabled,
|
|
1037
1060
|
onMouseEnter: () => setIsHovered(true),
|
|
1038
|
-
onMouseLeave: () =>
|
|
1061
|
+
onMouseLeave: () => {
|
|
1062
|
+
setIsHovered(false);
|
|
1063
|
+
setIsPressed(false);
|
|
1064
|
+
},
|
|
1065
|
+
onTouchStart: () => setIsPressed(true),
|
|
1066
|
+
onTouchEnd: () => setIsPressed(false),
|
|
1067
|
+
onTouchCancel: () => setIsPressed(false),
|
|
1039
1068
|
style: {
|
|
1040
1069
|
...menuStyles.item,
|
|
1041
|
-
|
|
1042
|
-
...
|
|
1070
|
+
// Apply hover/pressed state for both mouse and touch
|
|
1071
|
+
...isHovered || isPressed ? menuStyles.itemHover : {},
|
|
1072
|
+
...disabled ? { opacity: 0.5, cursor: "not-allowed" } : {},
|
|
1073
|
+
// Ensure minimum touch target size (44px is recommended)
|
|
1074
|
+
minHeight: "44px",
|
|
1075
|
+
// Prevent text selection on touch
|
|
1076
|
+
WebkitUserSelect: "none",
|
|
1077
|
+
userSelect: "none",
|
|
1078
|
+
// Prevent touch callout on iOS
|
|
1079
|
+
WebkitTouchCallout: "none"
|
|
1043
1080
|
},
|
|
1044
1081
|
children: [
|
|
1045
1082
|
/* @__PURE__ */ jsx2("span", { style: menuStyles.itemIcon, children: item.icon ?? defaultIcons[item.type] }),
|
|
@@ -1057,18 +1094,31 @@ function MenuItem({
|
|
|
1057
1094
|
}
|
|
1058
1095
|
function BackButton({ onClick }) {
|
|
1059
1096
|
const [isHovered, setIsHovered] = useState2(false);
|
|
1097
|
+
const [isPressed, setIsPressed] = useState2(false);
|
|
1060
1098
|
return /* @__PURE__ */ jsxs2(
|
|
1061
1099
|
"button",
|
|
1062
1100
|
{
|
|
1063
1101
|
type: "button",
|
|
1064
1102
|
onClick,
|
|
1065
1103
|
onMouseEnter: () => setIsHovered(true),
|
|
1066
|
-
onMouseLeave: () =>
|
|
1104
|
+
onMouseLeave: () => {
|
|
1105
|
+
setIsHovered(false);
|
|
1106
|
+
setIsPressed(false);
|
|
1107
|
+
},
|
|
1108
|
+
onTouchStart: () => setIsPressed(true),
|
|
1109
|
+
onTouchEnd: () => setIsPressed(false),
|
|
1110
|
+
onTouchCancel: () => setIsPressed(false),
|
|
1067
1111
|
style: {
|
|
1068
1112
|
...menuStyles.item,
|
|
1069
|
-
...isHovered ? menuStyles.itemHover : {},
|
|
1113
|
+
...isHovered || isPressed ? menuStyles.itemHover : {},
|
|
1070
1114
|
borderBottom: "1px solid #e5e5e5",
|
|
1071
|
-
marginBottom: "4px"
|
|
1115
|
+
marginBottom: "4px",
|
|
1116
|
+
// Ensure minimum touch target size
|
|
1117
|
+
minHeight: "44px",
|
|
1118
|
+
// Prevent text selection on touch
|
|
1119
|
+
WebkitUserSelect: "none",
|
|
1120
|
+
userSelect: "none",
|
|
1121
|
+
WebkitTouchCallout: "none"
|
|
1072
1122
|
},
|
|
1073
1123
|
children: [
|
|
1074
1124
|
/* @__PURE__ */ jsx2(ChevronLeft, { className: "w-4 h-4", style: { opacity: 0.5 } }),
|
|
@@ -1138,6 +1188,25 @@ function CommentForm({
|
|
|
1138
1188
|
] })
|
|
1139
1189
|
] });
|
|
1140
1190
|
}
|
|
1191
|
+
function calculateInViewPosition(requestedX, requestedY, menuWidth, menuHeight) {
|
|
1192
|
+
const viewportWidth = window.innerWidth;
|
|
1193
|
+
const viewportHeight = window.innerHeight;
|
|
1194
|
+
let x = requestedX;
|
|
1195
|
+
let y = requestedY;
|
|
1196
|
+
if (x + menuWidth > viewportWidth - VIEWPORT_PADDING) {
|
|
1197
|
+
x = viewportWidth - menuWidth - VIEWPORT_PADDING;
|
|
1198
|
+
}
|
|
1199
|
+
if (x < VIEWPORT_PADDING) {
|
|
1200
|
+
x = VIEWPORT_PADDING;
|
|
1201
|
+
}
|
|
1202
|
+
if (y + menuHeight > viewportHeight - VIEWPORT_PADDING) {
|
|
1203
|
+
y = viewportHeight - menuHeight - VIEWPORT_PADDING;
|
|
1204
|
+
}
|
|
1205
|
+
if (y < VIEWPORT_PADDING) {
|
|
1206
|
+
y = VIEWPORT_PADDING;
|
|
1207
|
+
}
|
|
1208
|
+
return { x, y };
|
|
1209
|
+
}
|
|
1141
1210
|
function ContextMenu({
|
|
1142
1211
|
visible,
|
|
1143
1212
|
position,
|
|
@@ -1150,7 +1219,8 @@ function ContextMenu({
|
|
|
1150
1219
|
style,
|
|
1151
1220
|
className,
|
|
1152
1221
|
highlightConfig,
|
|
1153
|
-
screenshotConfig
|
|
1222
|
+
screenshotConfig,
|
|
1223
|
+
positionMode = "inView"
|
|
1154
1224
|
}) {
|
|
1155
1225
|
const [selectedType, setSelectedType] = useState2(null);
|
|
1156
1226
|
const [currentView, setCurrentView] = useState2("menu");
|
|
@@ -1159,6 +1229,13 @@ function ContextMenu({
|
|
|
1159
1229
|
const [screenshots, setScreenshots] = useState2(null);
|
|
1160
1230
|
const [isCapturing, setIsCapturing] = useState2(false);
|
|
1161
1231
|
const menuRef = useRef(null);
|
|
1232
|
+
const [adjustedPosition, setAdjustedPosition] = useState2(position);
|
|
1233
|
+
const [isDragging, setIsDragging] = useState2(false);
|
|
1234
|
+
const [dragOffset, setDragOffset] = useState2({
|
|
1235
|
+
x: 0,
|
|
1236
|
+
y: 0
|
|
1237
|
+
});
|
|
1238
|
+
const dragStartRef = useRef(null);
|
|
1162
1239
|
const mergedScreenshotConfig = {
|
|
1163
1240
|
...DEFAULT_SCREENSHOT_CONFIG,
|
|
1164
1241
|
...screenshotConfig
|
|
@@ -1190,6 +1267,9 @@ function ContextMenu({
|
|
|
1190
1267
|
setSubmenuStack([]);
|
|
1191
1268
|
setScreenshots(null);
|
|
1192
1269
|
setIsCapturing(false);
|
|
1270
|
+
setIsDragging(false);
|
|
1271
|
+
setDragOffset({ x: 0, y: 0 });
|
|
1272
|
+
dragStartRef.current = null;
|
|
1193
1273
|
}
|
|
1194
1274
|
}, [visible]);
|
|
1195
1275
|
useEffect(() => {
|
|
@@ -1210,6 +1290,9 @@ function ContextMenu({
|
|
|
1210
1290
|
const handlePointerDown = (event) => {
|
|
1211
1291
|
if (!menuRef.current) return;
|
|
1212
1292
|
const target = event.target;
|
|
1293
|
+
if (target.closest?.("[data-drag-handle]")) {
|
|
1294
|
+
return;
|
|
1295
|
+
}
|
|
1213
1296
|
if (!menuRef.current.contains(target)) {
|
|
1214
1297
|
onClose();
|
|
1215
1298
|
}
|
|
@@ -1220,24 +1303,71 @@ function ContextMenu({
|
|
|
1220
1303
|
};
|
|
1221
1304
|
}, [visible, onClose]);
|
|
1222
1305
|
useEffect(() => {
|
|
1223
|
-
if (visible
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
if (
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1306
|
+
if (visible) {
|
|
1307
|
+
setAdjustedPosition(position);
|
|
1308
|
+
setDragOffset({ x: 0, y: 0 });
|
|
1309
|
+
}
|
|
1310
|
+
}, [visible, position.x, position.y]);
|
|
1311
|
+
useEffect(() => {
|
|
1312
|
+
if (!visible || !menuRef.current) return;
|
|
1313
|
+
const updatePosition = () => {
|
|
1314
|
+
const menuElement = menuRef.current;
|
|
1315
|
+
if (!menuElement) return;
|
|
1316
|
+
const rect = menuElement.getBoundingClientRect();
|
|
1317
|
+
const baseX = position.x + dragOffset.x;
|
|
1318
|
+
const baseY = position.y + dragOffset.y;
|
|
1319
|
+
if (positionMode === "static") {
|
|
1320
|
+
setAdjustedPosition({ x: baseX, y: baseY });
|
|
1321
|
+
} else if (positionMode === "inView" || positionMode === "dynamic") {
|
|
1322
|
+
const adjusted = calculateInViewPosition(
|
|
1323
|
+
baseX,
|
|
1324
|
+
baseY,
|
|
1325
|
+
rect.width,
|
|
1326
|
+
rect.height
|
|
1327
|
+
);
|
|
1328
|
+
setAdjustedPosition(adjusted);
|
|
1238
1329
|
}
|
|
1330
|
+
};
|
|
1331
|
+
requestAnimationFrame(updatePosition);
|
|
1332
|
+
window.addEventListener("resize", updatePosition);
|
|
1333
|
+
return () => window.removeEventListener("resize", updatePosition);
|
|
1334
|
+
}, [visible, position, positionMode, dragOffset, currentView]);
|
|
1335
|
+
useEffect(() => {
|
|
1336
|
+
if (!visible || positionMode !== "dynamic") return;
|
|
1337
|
+
const handlePointerMove = (event) => {
|
|
1338
|
+
if (!isDragging || !dragStartRef.current) return;
|
|
1339
|
+
const deltaX = event.clientX - dragStartRef.current.x;
|
|
1340
|
+
const deltaY = event.clientY - dragStartRef.current.y;
|
|
1341
|
+
setDragOffset((prev) => ({
|
|
1342
|
+
x: prev.x + deltaX,
|
|
1343
|
+
y: prev.y + deltaY
|
|
1344
|
+
}));
|
|
1345
|
+
dragStartRef.current = { x: event.clientX, y: event.clientY };
|
|
1346
|
+
};
|
|
1347
|
+
const handlePointerUp = () => {
|
|
1348
|
+
setIsDragging(false);
|
|
1349
|
+
dragStartRef.current = null;
|
|
1350
|
+
};
|
|
1351
|
+
if (isDragging) {
|
|
1352
|
+
document.addEventListener("pointermove", handlePointerMove);
|
|
1353
|
+
document.addEventListener("pointerup", handlePointerUp);
|
|
1354
|
+
document.addEventListener("pointercancel", handlePointerUp);
|
|
1355
|
+
return () => {
|
|
1356
|
+
document.removeEventListener("pointermove", handlePointerMove);
|
|
1357
|
+
document.removeEventListener("pointerup", handlePointerUp);
|
|
1358
|
+
document.removeEventListener("pointercancel", handlePointerUp);
|
|
1359
|
+
};
|
|
1239
1360
|
}
|
|
1240
|
-
}, [visible,
|
|
1361
|
+
}, [visible, positionMode, isDragging]);
|
|
1362
|
+
const handleDragStart = useCallback(
|
|
1363
|
+
(event) => {
|
|
1364
|
+
if (positionMode !== "dynamic") return;
|
|
1365
|
+
event.preventDefault();
|
|
1366
|
+
setIsDragging(true);
|
|
1367
|
+
dragStartRef.current = { x: event.clientX, y: event.clientY };
|
|
1368
|
+
},
|
|
1369
|
+
[positionMode]
|
|
1370
|
+
);
|
|
1241
1371
|
useEffect(() => {
|
|
1242
1372
|
const handleKeyDown = (e) => {
|
|
1243
1373
|
if (e.key === "Escape") {
|
|
@@ -1259,6 +1389,23 @@ function ContextMenu({
|
|
|
1259
1389
|
return () => document.removeEventListener("keydown", handleKeyDown);
|
|
1260
1390
|
}
|
|
1261
1391
|
}, [visible, currentView, submenuStack.length, onClose]);
|
|
1392
|
+
useEffect(() => {
|
|
1393
|
+
const menuElement = menuRef.current;
|
|
1394
|
+
if (!visible || !menuElement) return;
|
|
1395
|
+
const preventTouchDefault = (e) => {
|
|
1396
|
+
const target = e.target;
|
|
1397
|
+
if (target.tagName === "TEXTAREA" || target.tagName === "INPUT" || target.isContentEditable) {
|
|
1398
|
+
return;
|
|
1399
|
+
}
|
|
1400
|
+
e.preventDefault();
|
|
1401
|
+
};
|
|
1402
|
+
menuElement.addEventListener("touchmove", preventTouchDefault, {
|
|
1403
|
+
passive: false
|
|
1404
|
+
});
|
|
1405
|
+
return () => {
|
|
1406
|
+
menuElement.removeEventListener("touchmove", preventTouchDefault);
|
|
1407
|
+
};
|
|
1408
|
+
}, [visible]);
|
|
1262
1409
|
if (!visible || !targetElement) {
|
|
1263
1410
|
return null;
|
|
1264
1411
|
}
|
|
@@ -1331,15 +1478,61 @@ function ContextMenu({
|
|
|
1331
1478
|
className,
|
|
1332
1479
|
style: {
|
|
1333
1480
|
...menuStyles.container,
|
|
1334
|
-
left:
|
|
1335
|
-
top:
|
|
1481
|
+
left: adjustedPosition.x,
|
|
1482
|
+
top: adjustedPosition.y,
|
|
1336
1483
|
...containerWidth ? { width: containerWidth, minWidth: containerWidth } : {},
|
|
1484
|
+
// Touch-specific styles
|
|
1485
|
+
WebkitUserSelect: "none",
|
|
1486
|
+
userSelect: "none",
|
|
1487
|
+
WebkitTouchCallout: "none",
|
|
1488
|
+
touchAction: "none",
|
|
1489
|
+
// Prevent default touch behaviors
|
|
1490
|
+
// Cursor style for dragging
|
|
1491
|
+
...isDragging ? { cursor: "grabbing" } : {},
|
|
1337
1492
|
...style
|
|
1338
1493
|
},
|
|
1339
1494
|
role: "menu",
|
|
1340
1495
|
"aria-label": "Feedback options",
|
|
1341
1496
|
children: [
|
|
1342
|
-
currentView !== "screenshot-preview" && /* @__PURE__ */
|
|
1497
|
+
currentView !== "screenshot-preview" && /* @__PURE__ */ jsxs2(
|
|
1498
|
+
"div",
|
|
1499
|
+
{
|
|
1500
|
+
style: {
|
|
1501
|
+
...menuStyles.header,
|
|
1502
|
+
display: "flex",
|
|
1503
|
+
alignItems: "center",
|
|
1504
|
+
justifyContent: "space-between"
|
|
1505
|
+
},
|
|
1506
|
+
children: [
|
|
1507
|
+
/* @__PURE__ */ jsx2("span", { children: "Send Feedback" }),
|
|
1508
|
+
positionMode === "dynamic" && /* @__PURE__ */ jsx2(
|
|
1509
|
+
"div",
|
|
1510
|
+
{
|
|
1511
|
+
"data-drag-handle": true,
|
|
1512
|
+
onPointerDown: handleDragStart,
|
|
1513
|
+
style: {
|
|
1514
|
+
cursor: isDragging ? "grabbing" : "grab",
|
|
1515
|
+
padding: "4px",
|
|
1516
|
+
marginRight: "-4px",
|
|
1517
|
+
borderRadius: "4px",
|
|
1518
|
+
display: "flex",
|
|
1519
|
+
alignItems: "center",
|
|
1520
|
+
opacity: 0.5,
|
|
1521
|
+
transition: "opacity 0.15s"
|
|
1522
|
+
},
|
|
1523
|
+
onMouseEnter: (e) => {
|
|
1524
|
+
e.currentTarget.style.opacity = "1";
|
|
1525
|
+
},
|
|
1526
|
+
onMouseLeave: (e) => {
|
|
1527
|
+
e.currentTarget.style.opacity = "0.5";
|
|
1528
|
+
},
|
|
1529
|
+
title: "Drag to move",
|
|
1530
|
+
children: /* @__PURE__ */ jsx2(GripVertical, { className: "w-4 h-4" })
|
|
1531
|
+
}
|
|
1532
|
+
)
|
|
1533
|
+
]
|
|
1534
|
+
}
|
|
1535
|
+
),
|
|
1343
1536
|
currentView === "menu" && /* @__PURE__ */ jsxs2("div", { style: menuStyles.itemList, children: [
|
|
1344
1537
|
submenuStack.length > 0 && /* @__PURE__ */ jsx2(BackButton, { onClick: handleBack }),
|
|
1345
1538
|
currentItems.map((item) => /* @__PURE__ */ jsx2(
|
|
@@ -1380,16 +1573,6 @@ function ContextMenu({
|
|
|
1380
1573
|
}
|
|
1381
1574
|
);
|
|
1382
1575
|
}
|
|
1383
|
-
var screenshotIndicatorStyle = {
|
|
1384
|
-
display: "flex",
|
|
1385
|
-
alignItems: "center",
|
|
1386
|
-
gap: "6px",
|
|
1387
|
-
padding: "8px 12px",
|
|
1388
|
-
fontSize: "11px",
|
|
1389
|
-
color: "var(--anyclick-menu-text-muted, #9ca3af)",
|
|
1390
|
-
borderTop: "1px solid var(--anyclick-menu-border, #f3f4f6)",
|
|
1391
|
-
marginTop: "4px"
|
|
1392
|
-
};
|
|
1393
1576
|
|
|
1394
1577
|
// src/store.ts
|
|
1395
1578
|
import { create } from "zustand";
|
|
@@ -1535,17 +1718,45 @@ var useProviderStore = create((set, get) => ({
|
|
|
1535
1718
|
}
|
|
1536
1719
|
}
|
|
1537
1720
|
return false;
|
|
1721
|
+
},
|
|
1722
|
+
isElementInAnyScopedProvider: (element) => {
|
|
1723
|
+
const { providers } = get();
|
|
1724
|
+
for (const provider of providers.values()) {
|
|
1725
|
+
if (!provider.scoped) continue;
|
|
1726
|
+
const container = provider.containerRef.current;
|
|
1727
|
+
if (!container) continue;
|
|
1728
|
+
if (container.contains(element)) {
|
|
1729
|
+
if (process.env.NODE_ENV === "development") {
|
|
1730
|
+
console.log(
|
|
1731
|
+
`[Store:isElementInAnyScopedProvider] Element is in scoped provider: ${provider.id}`,
|
|
1732
|
+
{
|
|
1733
|
+
elementTag: element.tagName,
|
|
1734
|
+
providerId: provider.id,
|
|
1735
|
+
providerDisabled: provider.disabled
|
|
1736
|
+
}
|
|
1737
|
+
);
|
|
1738
|
+
}
|
|
1739
|
+
return true;
|
|
1740
|
+
}
|
|
1741
|
+
}
|
|
1742
|
+
return false;
|
|
1538
1743
|
}
|
|
1539
1744
|
}));
|
|
1540
1745
|
function dispatchContextMenuEvent(event, element) {
|
|
1541
1746
|
const store = useProviderStore.getState();
|
|
1542
1747
|
const providers = store.findProvidersForElement(element);
|
|
1748
|
+
const menuEvent = {
|
|
1749
|
+
clientX: event.clientX,
|
|
1750
|
+
clientY: event.clientY,
|
|
1751
|
+
originalEvent: event,
|
|
1752
|
+
isTouch: false
|
|
1753
|
+
};
|
|
1543
1754
|
for (const provider of providers) {
|
|
1544
1755
|
if (store.isDisabledByAncestor(provider.id)) {
|
|
1545
1756
|
continue;
|
|
1546
1757
|
}
|
|
1547
1758
|
if (provider.onContextMenu) {
|
|
1548
|
-
provider.onContextMenu(
|
|
1759
|
+
provider.onContextMenu(menuEvent, element);
|
|
1549
1760
|
break;
|
|
1550
1761
|
}
|
|
1551
1762
|
}
|
|
@@ -1577,7 +1788,9 @@ function AnyclickProvider({
|
|
|
1577
1788
|
highlightConfig,
|
|
1578
1789
|
screenshotConfig,
|
|
1579
1790
|
scoped = false,
|
|
1580
|
-
theme
|
|
1791
|
+
theme,
|
|
1792
|
+
touchHoldDurationMs,
|
|
1793
|
+
touchMoveThreshold
|
|
1581
1794
|
}) {
|
|
1582
1795
|
const [isSubmitting, setIsSubmitting] = useState3(false);
|
|
1583
1796
|
const [menuVisible, setMenuVisible] = useState3(false);
|
|
@@ -1624,7 +1837,8 @@ function AnyclickProvider({
|
|
|
1624
1837
|
getMergedTheme,
|
|
1625
1838
|
isDisabledByAncestor,
|
|
1626
1839
|
findParentProvider,
|
|
1627
|
-
isElementInDisabledScope
|
|
1840
|
+
isElementInDisabledScope,
|
|
1841
|
+
isElementInAnyScopedProvider
|
|
1628
1842
|
} = useProviderStore();
|
|
1629
1843
|
const parentId = parentContext?.providerId ?? null;
|
|
1630
1844
|
const depth = parentContext ? parentContext.scoped ? 1 : 0 : 0;
|
|
@@ -1670,6 +1884,17 @@ function AnyclickProvider({
|
|
|
1670
1884
|
}
|
|
1671
1885
|
return false;
|
|
1672
1886
|
}
|
|
1887
|
+
if (!scoped && event.isTouch && isElementInAnyScopedProvider(element)) {
|
|
1888
|
+
if (process.env.NODE_ENV === "development") {
|
|
1889
|
+
console.log(
|
|
1890
|
+
`[AnyclickProvider:${providerId}] Deferring to scoped provider for touch event`,
|
|
1891
|
+
{
|
|
1892
|
+
targetTag: element.tagName
|
|
1893
|
+
}
|
|
1894
|
+
);
|
|
1895
|
+
}
|
|
1896
|
+
return false;
|
|
1897
|
+
}
|
|
1673
1898
|
const mergedTheme2 = getMergedTheme(providerId);
|
|
1674
1899
|
if (process.env.NODE_ENV === "development") {
|
|
1675
1900
|
console.log(
|
|
@@ -1678,7 +1903,8 @@ function AnyclickProvider({
|
|
|
1678
1903
|
scoped,
|
|
1679
1904
|
targetTag: element.tagName,
|
|
1680
1905
|
mergedThemeColors: mergedTheme2.highlightConfig?.colors,
|
|
1681
|
-
position: { x: event.clientX, y: event.clientY }
|
|
1906
|
+
position: { x: event.clientX, y: event.clientY },
|
|
1907
|
+
isTouch: event.isTouch
|
|
1682
1908
|
}
|
|
1683
1909
|
);
|
|
1684
1910
|
}
|
|
@@ -1697,7 +1923,8 @@ function AnyclickProvider({
|
|
|
1697
1923
|
getMergedTheme,
|
|
1698
1924
|
highlightConfig,
|
|
1699
1925
|
scoped,
|
|
1700
|
-
isElementInDisabledScope
|
|
1926
|
+
isElementInDisabledScope,
|
|
1927
|
+
isElementInAnyScopedProvider
|
|
1701
1928
|
]
|
|
1702
1929
|
);
|
|
1703
1930
|
useLayoutEffect(() => {
|
|
@@ -1778,7 +2005,9 @@ function AnyclickProvider({
|
|
|
1778
2005
|
cooldownMs,
|
|
1779
2006
|
stripAttributes,
|
|
1780
2007
|
// For scoped providers, pass the container
|
|
1781
|
-
container: scoped ? containerRef.current : null
|
|
2008
|
+
container: scoped ? containerRef.current : null,
|
|
2009
|
+
touchHoldDurationMs,
|
|
2010
|
+
touchMoveThreshold
|
|
1782
2011
|
});
|
|
1783
2012
|
client.onSubmitSuccess = onSubmitSuccess;
|
|
1784
2013
|
client.onSubmitError = onSubmitError;
|
|
@@ -1805,7 +2034,9 @@ function AnyclickProvider({
|
|
|
1805
2034
|
containerReady,
|
|
1806
2035
|
providerId,
|
|
1807
2036
|
isDisabledByAncestor,
|
|
1808
|
-
handleContextMenu
|
|
2037
|
+
handleContextMenu,
|
|
2038
|
+
touchHoldDurationMs,
|
|
2039
|
+
touchMoveThreshold
|
|
1809
2040
|
]);
|
|
1810
2041
|
const submitFeedback = useCallback2(
|
|
1811
2042
|
async (element, type, comment, screenshots) => {
|
|
@@ -2008,6 +2239,7 @@ lucide-react/dist/esm/icons/chevron-right.js:
|
|
|
2008
2239
|
lucide-react/dist/esm/icons/circle-alert.js:
|
|
2009
2240
|
lucide-react/dist/esm/icons/expand.js:
|
|
2010
2241
|
lucide-react/dist/esm/icons/flag.js:
|
|
2242
|
+
lucide-react/dist/esm/icons/grip-vertical.js:
|
|
2011
2243
|
lucide-react/dist/esm/icons/image.js:
|
|
2012
2244
|
lucide-react/dist/esm/icons/loader-circle.js:
|
|
2013
2245
|
lucide-react/dist/esm/icons/plus.js:
|