@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.js
CHANGED
|
@@ -773,45 +773,56 @@ var __iconNode7 = [
|
|
|
773
773
|
];
|
|
774
774
|
var Flag = createLucideIcon("flag", __iconNode7);
|
|
775
775
|
|
|
776
|
-
// ../../node_modules/lucide-react/dist/esm/icons/
|
|
776
|
+
// ../../node_modules/lucide-react/dist/esm/icons/grip-vertical.js
|
|
777
777
|
var __iconNode8 = [
|
|
778
|
+
["circle", { cx: "9", cy: "12", r: "1", key: "1vctgf" }],
|
|
779
|
+
["circle", { cx: "9", cy: "5", r: "1", key: "hp0tcf" }],
|
|
780
|
+
["circle", { cx: "9", cy: "19", r: "1", key: "fkjjf6" }],
|
|
781
|
+
["circle", { cx: "15", cy: "12", r: "1", key: "1tmaij" }],
|
|
782
|
+
["circle", { cx: "15", cy: "5", r: "1", key: "19l28e" }],
|
|
783
|
+
["circle", { cx: "15", cy: "19", r: "1", key: "f4zoj3" }]
|
|
784
|
+
];
|
|
785
|
+
var GripVertical = createLucideIcon("grip-vertical", __iconNode8);
|
|
786
|
+
|
|
787
|
+
// ../../node_modules/lucide-react/dist/esm/icons/image.js
|
|
788
|
+
var __iconNode9 = [
|
|
778
789
|
["rect", { width: "18", height: "18", x: "3", y: "3", rx: "2", ry: "2", key: "1m3agn" }],
|
|
779
790
|
["circle", { cx: "9", cy: "9", r: "2", key: "af1f0g" }],
|
|
780
791
|
["path", { d: "m21 15-3.086-3.086a2 2 0 0 0-2.828 0L6 21", key: "1xmnt7" }]
|
|
781
792
|
];
|
|
782
|
-
var Image = createLucideIcon("image",
|
|
793
|
+
var Image = createLucideIcon("image", __iconNode9);
|
|
783
794
|
|
|
784
795
|
// ../../node_modules/lucide-react/dist/esm/icons/loader-circle.js
|
|
785
|
-
var
|
|
786
|
-
var LoaderCircle = createLucideIcon("loader-circle",
|
|
796
|
+
var __iconNode10 = [["path", { d: "M21 12a9 9 0 1 1-6.219-8.56", key: "13zald" }]];
|
|
797
|
+
var LoaderCircle = createLucideIcon("loader-circle", __iconNode10);
|
|
787
798
|
|
|
788
799
|
// ../../node_modules/lucide-react/dist/esm/icons/plus.js
|
|
789
|
-
var
|
|
800
|
+
var __iconNode11 = [
|
|
790
801
|
["path", { d: "M5 12h14", key: "1ays0h" }],
|
|
791
802
|
["path", { d: "M12 5v14", key: "s699le" }]
|
|
792
803
|
];
|
|
793
|
-
var Plus = createLucideIcon("plus",
|
|
804
|
+
var Plus = createLucideIcon("plus", __iconNode11);
|
|
794
805
|
|
|
795
806
|
// ../../node_modules/lucide-react/dist/esm/icons/refresh-cw.js
|
|
796
|
-
var
|
|
807
|
+
var __iconNode12 = [
|
|
797
808
|
["path", { d: "M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8", key: "v9h5vc" }],
|
|
798
809
|
["path", { d: "M21 3v5h-5", key: "1q7to0" }],
|
|
799
810
|
["path", { d: "M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16", key: "3uifl3" }],
|
|
800
811
|
["path", { d: "M8 16H3v5", key: "1cv678" }]
|
|
801
812
|
];
|
|
802
|
-
var RefreshCw = createLucideIcon("refresh-cw",
|
|
813
|
+
var RefreshCw = createLucideIcon("refresh-cw", __iconNode12);
|
|
803
814
|
|
|
804
815
|
// ../../node_modules/lucide-react/dist/esm/icons/shrink.js
|
|
805
|
-
var
|
|
816
|
+
var __iconNode13 = [
|
|
806
817
|
["path", { d: "m15 15 6 6m-6-6v4.8m0-4.8h4.8", key: "17vawe" }],
|
|
807
818
|
["path", { d: "M9 19.8V15m0 0H4.2M9 15l-6 6", key: "chjx8e" }],
|
|
808
819
|
["path", { d: "M15 4.2V9m0 0h4.8M15 9l6-6", key: "lav6yq" }],
|
|
809
820
|
["path", { d: "M9 4.2V9m0 0H4.2M9 9 3 3", key: "1pxi2q" }]
|
|
810
821
|
];
|
|
811
|
-
var Shrink = createLucideIcon("shrink",
|
|
822
|
+
var Shrink = createLucideIcon("shrink", __iconNode13);
|
|
812
823
|
|
|
813
824
|
// ../../node_modules/lucide-react/dist/esm/icons/thumbs-up.js
|
|
814
|
-
var
|
|
825
|
+
var __iconNode14 = [
|
|
815
826
|
["path", { d: "M7 10v12", key: "1qc93n" }],
|
|
816
827
|
[
|
|
817
828
|
"path",
|
|
@@ -821,14 +832,14 @@ var __iconNode13 = [
|
|
|
821
832
|
}
|
|
822
833
|
]
|
|
823
834
|
];
|
|
824
|
-
var ThumbsUp = createLucideIcon("thumbs-up",
|
|
835
|
+
var ThumbsUp = createLucideIcon("thumbs-up", __iconNode14);
|
|
825
836
|
|
|
826
837
|
// ../../node_modules/lucide-react/dist/esm/icons/x.js
|
|
827
|
-
var
|
|
838
|
+
var __iconNode15 = [
|
|
828
839
|
["path", { d: "M18 6 6 18", key: "1bl5f8" }],
|
|
829
840
|
["path", { d: "m6 6 12 12", key: "d8bk6v" }]
|
|
830
841
|
];
|
|
831
|
-
var X = createLucideIcon("x",
|
|
842
|
+
var X = createLucideIcon("x", __iconNode15);
|
|
832
843
|
|
|
833
844
|
// src/ScreenshotPreview.tsx
|
|
834
845
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
@@ -1058,6 +1069,17 @@ function ScreenshotPreview({
|
|
|
1058
1069
|
|
|
1059
1070
|
// src/ContextMenu.tsx
|
|
1060
1071
|
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
1072
|
+
var VIEWPORT_PADDING = 10;
|
|
1073
|
+
var screenshotIndicatorStyle = {
|
|
1074
|
+
display: "flex",
|
|
1075
|
+
alignItems: "center",
|
|
1076
|
+
gap: "6px",
|
|
1077
|
+
padding: "8px 12px",
|
|
1078
|
+
fontSize: "11px",
|
|
1079
|
+
color: "var(--anyclick-menu-text-muted, #9ca3af)",
|
|
1080
|
+
borderTop: "1px solid var(--anyclick-menu-border, #f3f4f6)",
|
|
1081
|
+
marginTop: "4px"
|
|
1082
|
+
};
|
|
1061
1083
|
var defaultIcons = {
|
|
1062
1084
|
issue: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Flag, { className: "w-4 h-4" }),
|
|
1063
1085
|
feature: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Plus, { className: "w-4 h-4" }),
|
|
@@ -1070,6 +1092,7 @@ function MenuItem({
|
|
|
1070
1092
|
hasChildren
|
|
1071
1093
|
}) {
|
|
1072
1094
|
const [isHovered, setIsHovered] = (0, import_react5.useState)(false);
|
|
1095
|
+
const [isPressed, setIsPressed] = (0, import_react5.useState)(false);
|
|
1073
1096
|
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
1074
1097
|
"button",
|
|
1075
1098
|
{
|
|
@@ -1077,11 +1100,25 @@ function MenuItem({
|
|
|
1077
1100
|
onClick,
|
|
1078
1101
|
disabled,
|
|
1079
1102
|
onMouseEnter: () => setIsHovered(true),
|
|
1080
|
-
onMouseLeave: () =>
|
|
1103
|
+
onMouseLeave: () => {
|
|
1104
|
+
setIsHovered(false);
|
|
1105
|
+
setIsPressed(false);
|
|
1106
|
+
},
|
|
1107
|
+
onTouchStart: () => setIsPressed(true),
|
|
1108
|
+
onTouchEnd: () => setIsPressed(false),
|
|
1109
|
+
onTouchCancel: () => setIsPressed(false),
|
|
1081
1110
|
style: {
|
|
1082
1111
|
...menuStyles.item,
|
|
1083
|
-
|
|
1084
|
-
...
|
|
1112
|
+
// Apply hover/pressed state for both mouse and touch
|
|
1113
|
+
...isHovered || isPressed ? menuStyles.itemHover : {},
|
|
1114
|
+
...disabled ? { opacity: 0.5, cursor: "not-allowed" } : {},
|
|
1115
|
+
// Ensure minimum touch target size (44px is recommended)
|
|
1116
|
+
minHeight: "44px",
|
|
1117
|
+
// Prevent text selection on touch
|
|
1118
|
+
WebkitUserSelect: "none",
|
|
1119
|
+
userSelect: "none",
|
|
1120
|
+
// Prevent touch callout on iOS
|
|
1121
|
+
WebkitTouchCallout: "none"
|
|
1085
1122
|
},
|
|
1086
1123
|
children: [
|
|
1087
1124
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: menuStyles.itemIcon, children: item.icon ?? defaultIcons[item.type] }),
|
|
@@ -1099,18 +1136,31 @@ function MenuItem({
|
|
|
1099
1136
|
}
|
|
1100
1137
|
function BackButton({ onClick }) {
|
|
1101
1138
|
const [isHovered, setIsHovered] = (0, import_react5.useState)(false);
|
|
1139
|
+
const [isPressed, setIsPressed] = (0, import_react5.useState)(false);
|
|
1102
1140
|
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
1103
1141
|
"button",
|
|
1104
1142
|
{
|
|
1105
1143
|
type: "button",
|
|
1106
1144
|
onClick,
|
|
1107
1145
|
onMouseEnter: () => setIsHovered(true),
|
|
1108
|
-
onMouseLeave: () =>
|
|
1146
|
+
onMouseLeave: () => {
|
|
1147
|
+
setIsHovered(false);
|
|
1148
|
+
setIsPressed(false);
|
|
1149
|
+
},
|
|
1150
|
+
onTouchStart: () => setIsPressed(true),
|
|
1151
|
+
onTouchEnd: () => setIsPressed(false),
|
|
1152
|
+
onTouchCancel: () => setIsPressed(false),
|
|
1109
1153
|
style: {
|
|
1110
1154
|
...menuStyles.item,
|
|
1111
|
-
...isHovered ? menuStyles.itemHover : {},
|
|
1155
|
+
...isHovered || isPressed ? menuStyles.itemHover : {},
|
|
1112
1156
|
borderBottom: "1px solid #e5e5e5",
|
|
1113
|
-
marginBottom: "4px"
|
|
1157
|
+
marginBottom: "4px",
|
|
1158
|
+
// Ensure minimum touch target size
|
|
1159
|
+
minHeight: "44px",
|
|
1160
|
+
// Prevent text selection on touch
|
|
1161
|
+
WebkitUserSelect: "none",
|
|
1162
|
+
userSelect: "none",
|
|
1163
|
+
WebkitTouchCallout: "none"
|
|
1114
1164
|
},
|
|
1115
1165
|
children: [
|
|
1116
1166
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ChevronLeft, { className: "w-4 h-4", style: { opacity: 0.5 } }),
|
|
@@ -1180,6 +1230,25 @@ function CommentForm({
|
|
|
1180
1230
|
] })
|
|
1181
1231
|
] });
|
|
1182
1232
|
}
|
|
1233
|
+
function calculateInViewPosition(requestedX, requestedY, menuWidth, menuHeight) {
|
|
1234
|
+
const viewportWidth = window.innerWidth;
|
|
1235
|
+
const viewportHeight = window.innerHeight;
|
|
1236
|
+
let x = requestedX;
|
|
1237
|
+
let y = requestedY;
|
|
1238
|
+
if (x + menuWidth > viewportWidth - VIEWPORT_PADDING) {
|
|
1239
|
+
x = viewportWidth - menuWidth - VIEWPORT_PADDING;
|
|
1240
|
+
}
|
|
1241
|
+
if (x < VIEWPORT_PADDING) {
|
|
1242
|
+
x = VIEWPORT_PADDING;
|
|
1243
|
+
}
|
|
1244
|
+
if (y + menuHeight > viewportHeight - VIEWPORT_PADDING) {
|
|
1245
|
+
y = viewportHeight - menuHeight - VIEWPORT_PADDING;
|
|
1246
|
+
}
|
|
1247
|
+
if (y < VIEWPORT_PADDING) {
|
|
1248
|
+
y = VIEWPORT_PADDING;
|
|
1249
|
+
}
|
|
1250
|
+
return { x, y };
|
|
1251
|
+
}
|
|
1183
1252
|
function ContextMenu({
|
|
1184
1253
|
visible,
|
|
1185
1254
|
position,
|
|
@@ -1192,7 +1261,8 @@ function ContextMenu({
|
|
|
1192
1261
|
style,
|
|
1193
1262
|
className,
|
|
1194
1263
|
highlightConfig,
|
|
1195
|
-
screenshotConfig
|
|
1264
|
+
screenshotConfig,
|
|
1265
|
+
positionMode = "inView"
|
|
1196
1266
|
}) {
|
|
1197
1267
|
const [selectedType, setSelectedType] = (0, import_react5.useState)(null);
|
|
1198
1268
|
const [currentView, setCurrentView] = (0, import_react5.useState)("menu");
|
|
@@ -1201,6 +1271,13 @@ function ContextMenu({
|
|
|
1201
1271
|
const [screenshots, setScreenshots] = (0, import_react5.useState)(null);
|
|
1202
1272
|
const [isCapturing, setIsCapturing] = (0, import_react5.useState)(false);
|
|
1203
1273
|
const menuRef = (0, import_react5.useRef)(null);
|
|
1274
|
+
const [adjustedPosition, setAdjustedPosition] = (0, import_react5.useState)(position);
|
|
1275
|
+
const [isDragging, setIsDragging] = (0, import_react5.useState)(false);
|
|
1276
|
+
const [dragOffset, setDragOffset] = (0, import_react5.useState)({
|
|
1277
|
+
x: 0,
|
|
1278
|
+
y: 0
|
|
1279
|
+
});
|
|
1280
|
+
const dragStartRef = (0, import_react5.useRef)(null);
|
|
1204
1281
|
const mergedScreenshotConfig = {
|
|
1205
1282
|
...import_anyclick_core2.DEFAULT_SCREENSHOT_CONFIG,
|
|
1206
1283
|
...screenshotConfig
|
|
@@ -1232,6 +1309,9 @@ function ContextMenu({
|
|
|
1232
1309
|
setSubmenuStack([]);
|
|
1233
1310
|
setScreenshots(null);
|
|
1234
1311
|
setIsCapturing(false);
|
|
1312
|
+
setIsDragging(false);
|
|
1313
|
+
setDragOffset({ x: 0, y: 0 });
|
|
1314
|
+
dragStartRef.current = null;
|
|
1235
1315
|
}
|
|
1236
1316
|
}, [visible]);
|
|
1237
1317
|
(0, import_react5.useEffect)(() => {
|
|
@@ -1252,6 +1332,9 @@ function ContextMenu({
|
|
|
1252
1332
|
const handlePointerDown = (event) => {
|
|
1253
1333
|
if (!menuRef.current) return;
|
|
1254
1334
|
const target = event.target;
|
|
1335
|
+
if (target.closest?.("[data-drag-handle]")) {
|
|
1336
|
+
return;
|
|
1337
|
+
}
|
|
1255
1338
|
if (!menuRef.current.contains(target)) {
|
|
1256
1339
|
onClose();
|
|
1257
1340
|
}
|
|
@@ -1262,24 +1345,71 @@ function ContextMenu({
|
|
|
1262
1345
|
};
|
|
1263
1346
|
}, [visible, onClose]);
|
|
1264
1347
|
(0, import_react5.useEffect)(() => {
|
|
1265
|
-
if (visible
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
if (
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1348
|
+
if (visible) {
|
|
1349
|
+
setAdjustedPosition(position);
|
|
1350
|
+
setDragOffset({ x: 0, y: 0 });
|
|
1351
|
+
}
|
|
1352
|
+
}, [visible, position.x, position.y]);
|
|
1353
|
+
(0, import_react5.useEffect)(() => {
|
|
1354
|
+
if (!visible || !menuRef.current) return;
|
|
1355
|
+
const updatePosition = () => {
|
|
1356
|
+
const menuElement = menuRef.current;
|
|
1357
|
+
if (!menuElement) return;
|
|
1358
|
+
const rect = menuElement.getBoundingClientRect();
|
|
1359
|
+
const baseX = position.x + dragOffset.x;
|
|
1360
|
+
const baseY = position.y + dragOffset.y;
|
|
1361
|
+
if (positionMode === "static") {
|
|
1362
|
+
setAdjustedPosition({ x: baseX, y: baseY });
|
|
1363
|
+
} else if (positionMode === "inView" || positionMode === "dynamic") {
|
|
1364
|
+
const adjusted = calculateInViewPosition(
|
|
1365
|
+
baseX,
|
|
1366
|
+
baseY,
|
|
1367
|
+
rect.width,
|
|
1368
|
+
rect.height
|
|
1369
|
+
);
|
|
1370
|
+
setAdjustedPosition(adjusted);
|
|
1280
1371
|
}
|
|
1372
|
+
};
|
|
1373
|
+
requestAnimationFrame(updatePosition);
|
|
1374
|
+
window.addEventListener("resize", updatePosition);
|
|
1375
|
+
return () => window.removeEventListener("resize", updatePosition);
|
|
1376
|
+
}, [visible, position, positionMode, dragOffset, currentView]);
|
|
1377
|
+
(0, import_react5.useEffect)(() => {
|
|
1378
|
+
if (!visible || positionMode !== "dynamic") return;
|
|
1379
|
+
const handlePointerMove = (event) => {
|
|
1380
|
+
if (!isDragging || !dragStartRef.current) return;
|
|
1381
|
+
const deltaX = event.clientX - dragStartRef.current.x;
|
|
1382
|
+
const deltaY = event.clientY - dragStartRef.current.y;
|
|
1383
|
+
setDragOffset((prev) => ({
|
|
1384
|
+
x: prev.x + deltaX,
|
|
1385
|
+
y: prev.y + deltaY
|
|
1386
|
+
}));
|
|
1387
|
+
dragStartRef.current = { x: event.clientX, y: event.clientY };
|
|
1388
|
+
};
|
|
1389
|
+
const handlePointerUp = () => {
|
|
1390
|
+
setIsDragging(false);
|
|
1391
|
+
dragStartRef.current = null;
|
|
1392
|
+
};
|
|
1393
|
+
if (isDragging) {
|
|
1394
|
+
document.addEventListener("pointermove", handlePointerMove);
|
|
1395
|
+
document.addEventListener("pointerup", handlePointerUp);
|
|
1396
|
+
document.addEventListener("pointercancel", handlePointerUp);
|
|
1397
|
+
return () => {
|
|
1398
|
+
document.removeEventListener("pointermove", handlePointerMove);
|
|
1399
|
+
document.removeEventListener("pointerup", handlePointerUp);
|
|
1400
|
+
document.removeEventListener("pointercancel", handlePointerUp);
|
|
1401
|
+
};
|
|
1281
1402
|
}
|
|
1282
|
-
}, [visible,
|
|
1403
|
+
}, [visible, positionMode, isDragging]);
|
|
1404
|
+
const handleDragStart = (0, import_react5.useCallback)(
|
|
1405
|
+
(event) => {
|
|
1406
|
+
if (positionMode !== "dynamic") return;
|
|
1407
|
+
event.preventDefault();
|
|
1408
|
+
setIsDragging(true);
|
|
1409
|
+
dragStartRef.current = { x: event.clientX, y: event.clientY };
|
|
1410
|
+
},
|
|
1411
|
+
[positionMode]
|
|
1412
|
+
);
|
|
1283
1413
|
(0, import_react5.useEffect)(() => {
|
|
1284
1414
|
const handleKeyDown = (e) => {
|
|
1285
1415
|
if (e.key === "Escape") {
|
|
@@ -1301,6 +1431,23 @@ function ContextMenu({
|
|
|
1301
1431
|
return () => document.removeEventListener("keydown", handleKeyDown);
|
|
1302
1432
|
}
|
|
1303
1433
|
}, [visible, currentView, submenuStack.length, onClose]);
|
|
1434
|
+
(0, import_react5.useEffect)(() => {
|
|
1435
|
+
const menuElement = menuRef.current;
|
|
1436
|
+
if (!visible || !menuElement) return;
|
|
1437
|
+
const preventTouchDefault = (e) => {
|
|
1438
|
+
const target = e.target;
|
|
1439
|
+
if (target.tagName === "TEXTAREA" || target.tagName === "INPUT" || target.isContentEditable) {
|
|
1440
|
+
return;
|
|
1441
|
+
}
|
|
1442
|
+
e.preventDefault();
|
|
1443
|
+
};
|
|
1444
|
+
menuElement.addEventListener("touchmove", preventTouchDefault, {
|
|
1445
|
+
passive: false
|
|
1446
|
+
});
|
|
1447
|
+
return () => {
|
|
1448
|
+
menuElement.removeEventListener("touchmove", preventTouchDefault);
|
|
1449
|
+
};
|
|
1450
|
+
}, [visible]);
|
|
1304
1451
|
if (!visible || !targetElement) {
|
|
1305
1452
|
return null;
|
|
1306
1453
|
}
|
|
@@ -1373,15 +1520,61 @@ function ContextMenu({
|
|
|
1373
1520
|
className,
|
|
1374
1521
|
style: {
|
|
1375
1522
|
...menuStyles.container,
|
|
1376
|
-
left:
|
|
1377
|
-
top:
|
|
1523
|
+
left: adjustedPosition.x,
|
|
1524
|
+
top: adjustedPosition.y,
|
|
1378
1525
|
...containerWidth ? { width: containerWidth, minWidth: containerWidth } : {},
|
|
1526
|
+
// Touch-specific styles
|
|
1527
|
+
WebkitUserSelect: "none",
|
|
1528
|
+
userSelect: "none",
|
|
1529
|
+
WebkitTouchCallout: "none",
|
|
1530
|
+
touchAction: "none",
|
|
1531
|
+
// Prevent default touch behaviors
|
|
1532
|
+
// Cursor style for dragging
|
|
1533
|
+
...isDragging ? { cursor: "grabbing" } : {},
|
|
1379
1534
|
...style
|
|
1380
1535
|
},
|
|
1381
1536
|
role: "menu",
|
|
1382
1537
|
"aria-label": "Feedback options",
|
|
1383
1538
|
children: [
|
|
1384
|
-
currentView !== "screenshot-preview" && /* @__PURE__ */ (0, import_jsx_runtime2.
|
|
1539
|
+
currentView !== "screenshot-preview" && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
1540
|
+
"div",
|
|
1541
|
+
{
|
|
1542
|
+
style: {
|
|
1543
|
+
...menuStyles.header,
|
|
1544
|
+
display: "flex",
|
|
1545
|
+
alignItems: "center",
|
|
1546
|
+
justifyContent: "space-between"
|
|
1547
|
+
},
|
|
1548
|
+
children: [
|
|
1549
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children: "Send Feedback" }),
|
|
1550
|
+
positionMode === "dynamic" && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
1551
|
+
"div",
|
|
1552
|
+
{
|
|
1553
|
+
"data-drag-handle": true,
|
|
1554
|
+
onPointerDown: handleDragStart,
|
|
1555
|
+
style: {
|
|
1556
|
+
cursor: isDragging ? "grabbing" : "grab",
|
|
1557
|
+
padding: "4px",
|
|
1558
|
+
marginRight: "-4px",
|
|
1559
|
+
borderRadius: "4px",
|
|
1560
|
+
display: "flex",
|
|
1561
|
+
alignItems: "center",
|
|
1562
|
+
opacity: 0.5,
|
|
1563
|
+
transition: "opacity 0.15s"
|
|
1564
|
+
},
|
|
1565
|
+
onMouseEnter: (e) => {
|
|
1566
|
+
e.currentTarget.style.opacity = "1";
|
|
1567
|
+
},
|
|
1568
|
+
onMouseLeave: (e) => {
|
|
1569
|
+
e.currentTarget.style.opacity = "0.5";
|
|
1570
|
+
},
|
|
1571
|
+
title: "Drag to move",
|
|
1572
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(GripVertical, { className: "w-4 h-4" })
|
|
1573
|
+
}
|
|
1574
|
+
)
|
|
1575
|
+
]
|
|
1576
|
+
}
|
|
1577
|
+
),
|
|
1385
1578
|
currentView === "menu" && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: menuStyles.itemList, children: [
|
|
1386
1579
|
submenuStack.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(BackButton, { onClick: handleBack }),
|
|
1387
1580
|
currentItems.map((item) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
@@ -1422,16 +1615,6 @@ function ContextMenu({
|
|
|
1422
1615
|
}
|
|
1423
1616
|
);
|
|
1424
1617
|
}
|
|
1425
|
-
var screenshotIndicatorStyle = {
|
|
1426
|
-
display: "flex",
|
|
1427
|
-
alignItems: "center",
|
|
1428
|
-
gap: "6px",
|
|
1429
|
-
padding: "8px 12px",
|
|
1430
|
-
fontSize: "11px",
|
|
1431
|
-
color: "var(--anyclick-menu-text-muted, #9ca3af)",
|
|
1432
|
-
borderTop: "1px solid var(--anyclick-menu-border, #f3f4f6)",
|
|
1433
|
-
marginTop: "4px"
|
|
1434
|
-
};
|
|
1435
1618
|
|
|
1436
1619
|
// src/store.ts
|
|
1437
1620
|
var import_zustand = require("zustand");
|
|
@@ -1577,17 +1760,45 @@ var useProviderStore = (0, import_zustand.create)((set, get) => ({
|
|
|
1577
1760
|
}
|
|
1578
1761
|
}
|
|
1579
1762
|
return false;
|
|
1763
|
+
},
|
|
1764
|
+
isElementInAnyScopedProvider: (element) => {
|
|
1765
|
+
const { providers } = get();
|
|
1766
|
+
for (const provider of providers.values()) {
|
|
1767
|
+
if (!provider.scoped) continue;
|
|
1768
|
+
const container = provider.containerRef.current;
|
|
1769
|
+
if (!container) continue;
|
|
1770
|
+
if (container.contains(element)) {
|
|
1771
|
+
if (process.env.NODE_ENV === "development") {
|
|
1772
|
+
console.log(
|
|
1773
|
+
`[Store:isElementInAnyScopedProvider] Element is in scoped provider: ${provider.id}`,
|
|
1774
|
+
{
|
|
1775
|
+
elementTag: element.tagName,
|
|
1776
|
+
providerId: provider.id,
|
|
1777
|
+
providerDisabled: provider.disabled
|
|
1778
|
+
}
|
|
1779
|
+
);
|
|
1780
|
+
}
|
|
1781
|
+
return true;
|
|
1782
|
+
}
|
|
1783
|
+
}
|
|
1784
|
+
return false;
|
|
1580
1785
|
}
|
|
1581
1786
|
}));
|
|
1582
1787
|
function dispatchContextMenuEvent(event, element) {
|
|
1583
1788
|
const store = useProviderStore.getState();
|
|
1584
1789
|
const providers = store.findProvidersForElement(element);
|
|
1790
|
+
const menuEvent = {
|
|
1791
|
+
clientX: event.clientX,
|
|
1792
|
+
clientY: event.clientY,
|
|
1793
|
+
originalEvent: event,
|
|
1794
|
+
isTouch: false
|
|
1795
|
+
};
|
|
1585
1796
|
for (const provider of providers) {
|
|
1586
1797
|
if (store.isDisabledByAncestor(provider.id)) {
|
|
1587
1798
|
continue;
|
|
1588
1799
|
}
|
|
1589
1800
|
if (provider.onContextMenu) {
|
|
1590
|
-
provider.onContextMenu(
|
|
1801
|
+
provider.onContextMenu(menuEvent, element);
|
|
1591
1802
|
break;
|
|
1592
1803
|
}
|
|
1593
1804
|
}
|
|
@@ -1619,7 +1830,9 @@ function AnyclickProvider({
|
|
|
1619
1830
|
highlightConfig,
|
|
1620
1831
|
screenshotConfig,
|
|
1621
1832
|
scoped = false,
|
|
1622
|
-
theme
|
|
1833
|
+
theme,
|
|
1834
|
+
touchHoldDurationMs,
|
|
1835
|
+
touchMoveThreshold
|
|
1623
1836
|
}) {
|
|
1624
1837
|
const [isSubmitting, setIsSubmitting] = (0, import_react6.useState)(false);
|
|
1625
1838
|
const [menuVisible, setMenuVisible] = (0, import_react6.useState)(false);
|
|
@@ -1666,7 +1879,8 @@ function AnyclickProvider({
|
|
|
1666
1879
|
getMergedTheme,
|
|
1667
1880
|
isDisabledByAncestor,
|
|
1668
1881
|
findParentProvider,
|
|
1669
|
-
isElementInDisabledScope
|
|
1882
|
+
isElementInDisabledScope,
|
|
1883
|
+
isElementInAnyScopedProvider
|
|
1670
1884
|
} = useProviderStore();
|
|
1671
1885
|
const parentId = parentContext?.providerId ?? null;
|
|
1672
1886
|
const depth = parentContext ? parentContext.scoped ? 1 : 0 : 0;
|
|
@@ -1712,6 +1926,17 @@ function AnyclickProvider({
|
|
|
1712
1926
|
}
|
|
1713
1927
|
return false;
|
|
1714
1928
|
}
|
|
1929
|
+
if (!scoped && event.isTouch && isElementInAnyScopedProvider(element)) {
|
|
1930
|
+
if (process.env.NODE_ENV === "development") {
|
|
1931
|
+
console.log(
|
|
1932
|
+
`[AnyclickProvider:${providerId}] Deferring to scoped provider for touch event`,
|
|
1933
|
+
{
|
|
1934
|
+
targetTag: element.tagName
|
|
1935
|
+
}
|
|
1936
|
+
);
|
|
1937
|
+
}
|
|
1938
|
+
return false;
|
|
1939
|
+
}
|
|
1715
1940
|
const mergedTheme2 = getMergedTheme(providerId);
|
|
1716
1941
|
if (process.env.NODE_ENV === "development") {
|
|
1717
1942
|
console.log(
|
|
@@ -1720,7 +1945,8 @@ function AnyclickProvider({
|
|
|
1720
1945
|
scoped,
|
|
1721
1946
|
targetTag: element.tagName,
|
|
1722
1947
|
mergedThemeColors: mergedTheme2.highlightConfig?.colors,
|
|
1723
|
-
position: { x: event.clientX, y: event.clientY }
|
|
1948
|
+
position: { x: event.clientX, y: event.clientY },
|
|
1949
|
+
isTouch: event.isTouch
|
|
1724
1950
|
}
|
|
1725
1951
|
);
|
|
1726
1952
|
}
|
|
@@ -1739,7 +1965,8 @@ function AnyclickProvider({
|
|
|
1739
1965
|
getMergedTheme,
|
|
1740
1966
|
highlightConfig,
|
|
1741
1967
|
scoped,
|
|
1742
|
-
isElementInDisabledScope
|
|
1968
|
+
isElementInDisabledScope,
|
|
1969
|
+
isElementInAnyScopedProvider
|
|
1743
1970
|
]
|
|
1744
1971
|
);
|
|
1745
1972
|
(0, import_react6.useLayoutEffect)(() => {
|
|
@@ -1820,7 +2047,9 @@ function AnyclickProvider({
|
|
|
1820
2047
|
cooldownMs,
|
|
1821
2048
|
stripAttributes,
|
|
1822
2049
|
// For scoped providers, pass the container
|
|
1823
|
-
container: scoped ? containerRef.current : null
|
|
2050
|
+
container: scoped ? containerRef.current : null,
|
|
2051
|
+
touchHoldDurationMs,
|
|
2052
|
+
touchMoveThreshold
|
|
1824
2053
|
});
|
|
1825
2054
|
client.onSubmitSuccess = onSubmitSuccess;
|
|
1826
2055
|
client.onSubmitError = onSubmitError;
|
|
@@ -1847,7 +2076,9 @@ function AnyclickProvider({
|
|
|
1847
2076
|
containerReady,
|
|
1848
2077
|
providerId,
|
|
1849
2078
|
isDisabledByAncestor,
|
|
1850
|
-
handleContextMenu
|
|
2079
|
+
handleContextMenu,
|
|
2080
|
+
touchHoldDurationMs,
|
|
2081
|
+
touchMoveThreshold
|
|
1851
2082
|
]);
|
|
1852
2083
|
const submitFeedback = (0, import_react6.useCallback)(
|
|
1853
2084
|
async (element, type, comment, screenshots) => {
|
|
@@ -2043,6 +2274,7 @@ lucide-react/dist/esm/icons/chevron-right.js:
|
|
|
2043
2274
|
lucide-react/dist/esm/icons/circle-alert.js:
|
|
2044
2275
|
lucide-react/dist/esm/icons/expand.js:
|
|
2045
2276
|
lucide-react/dist/esm/icons/flag.js:
|
|
2277
|
+
lucide-react/dist/esm/icons/grip-vertical.js:
|
|
2046
2278
|
lucide-react/dist/esm/icons/image.js:
|
|
2047
2279
|
lucide-react/dist/esm/icons/loader-circle.js:
|
|
2048
2280
|
lucide-react/dist/esm/icons/plus.js:
|