@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/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/image.js
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", __iconNode8);
751
+ var Image = createLucideIcon("image", __iconNode9);
741
752
 
742
753
  // ../../node_modules/lucide-react/dist/esm/icons/loader-circle.js
743
- var __iconNode9 = [["path", { d: "M21 12a9 9 0 1 1-6.219-8.56", key: "13zald" }]];
744
- var LoaderCircle = createLucideIcon("loader-circle", __iconNode9);
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 __iconNode10 = [
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", __iconNode10);
762
+ var Plus = createLucideIcon("plus", __iconNode11);
752
763
 
753
764
  // ../../node_modules/lucide-react/dist/esm/icons/refresh-cw.js
754
- var __iconNode11 = [
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", __iconNode11);
771
+ var RefreshCw = createLucideIcon("refresh-cw", __iconNode12);
761
772
 
762
773
  // ../../node_modules/lucide-react/dist/esm/icons/shrink.js
763
- var __iconNode12 = [
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", __iconNode12);
780
+ var Shrink = createLucideIcon("shrink", __iconNode13);
770
781
 
771
782
  // ../../node_modules/lucide-react/dist/esm/icons/thumbs-up.js
772
- var __iconNode13 = [
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", __iconNode13);
793
+ var ThumbsUp = createLucideIcon("thumbs-up", __iconNode14);
783
794
 
784
795
  // ../../node_modules/lucide-react/dist/esm/icons/x.js
785
- var __iconNode14 = [
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", __iconNode14);
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: () => setIsHovered(false),
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
- ...isHovered ? menuStyles.itemHover : {},
1042
- ...disabled ? { opacity: 0.5, cursor: "not-allowed" } : {}
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: () => setIsHovered(false),
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 && menuRef.current) {
1224
- const rect = menuRef.current.getBoundingClientRect();
1225
- const viewportWidth = window.innerWidth;
1226
- const viewportHeight = window.innerHeight;
1227
- let adjustedX = position.x;
1228
- let adjustedY = position.y;
1229
- if (position.x + rect.width > viewportWidth) {
1230
- adjustedX = viewportWidth - rect.width - 10;
1231
- }
1232
- if (position.y + rect.height > viewportHeight) {
1233
- adjustedY = viewportHeight - rect.height - 10;
1234
- }
1235
- if (adjustedX !== position.x || adjustedY !== position.y) {
1236
- menuRef.current.style.left = `${adjustedX}px`;
1237
- menuRef.current.style.top = `${adjustedY}px`;
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, position]);
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: position.x,
1335
- top: position.y,
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__ */ jsx2("div", { style: menuStyles.header, children: "Send Feedback" }),
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(event, element);
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: