@ewjdev/anyclick-react 1.1.0 → 1.2.0

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.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
- import { FeedbackAdapter, FeedbackType, FeedbackPayload, ScreenshotConfig, ScreenshotData } from '@ewjdev/anyclick-core';
3
- export { DEFAULT_SCREENSHOT_CONFIG, DEFAULT_SENSITIVE_SELECTORS, ElementContext, FeedbackAdapter, FeedbackPayload, FeedbackType, PageContext, ScreenshotCapture, ScreenshotCaptureMode, ScreenshotConfig, ScreenshotData, captureAllScreenshots, captureScreenshot, estimateTotalSize, formatBytes, isScreenshotSupported } from '@ewjdev/anyclick-core';
2
+ import { AnyclickAdapter, AnyclickTriggerEvent, AnyclickType, AnyclickPayload, ScreenshotConfig, ScreenshotData, AnyclickMenuEvent } from '@ewjdev/anyclick-core';
3
+ export { AnyclickAdapter, AnyclickPayload, AnyclickType, DEFAULT_SCREENSHOT_CONFIG, DEFAULT_SENSITIVE_SELECTORS, ElementContext, PageContext, ScreenshotCapture, ScreenshotCaptureMode, ScreenshotConfig, ScreenshotData, captureAllScreenshots, captureScreenshot, estimateTotalSize, formatBytes, isScreenshotSupported } from '@ewjdev/anyclick-core';
4
4
  import * as react from 'react';
5
5
  import { ReactNode, CSSProperties } from 'react';
6
6
  import * as zustand from 'zustand';
@@ -20,7 +20,30 @@ interface AnyclickTheme {
20
20
  screenshotConfig?: ScreenshotConfig;
21
21
  /** Whether anyclick functionality is disabled in this theme */
22
22
  disabled?: boolean;
23
+ /**
24
+ * Enable fun mode (go-kart cursor) within this scoped provider.
25
+ * When true/configured, a FunModeBridge can hand off the track to the pointer.
26
+ */
27
+ funMode?: boolean | FunModeThemeConfig;
28
+ }
29
+ /**
30
+ * Optional fun mode configuration (forwarded to pointer fun mode)
31
+ */
32
+ interface FunModeThemeConfig {
33
+ /** Whether fun mode is enabled (default: true) */
34
+ enabled?: boolean;
35
+ /** Optional max speed override for this provider */
36
+ maxSpeed?: number;
37
+ /** Optional acceleration override */
38
+ acceleration?: number;
23
39
  }
40
+ /**
41
+ * Menu positioning modes
42
+ * - static: Menu stays at exact click position (may go off-screen)
43
+ * - inView: Menu adjusts position to stay fully visible in viewport
44
+ * - dynamic: User can drag the menu to reposition it
45
+ */
46
+ type MenuPositionMode = "static" | "inView" | "dynamic";
24
47
  /**
25
48
  * Configuration for highlight colors
26
49
  */
@@ -48,11 +71,11 @@ interface HighlightConfig {
48
71
  minChildrenForContainer?: number;
49
72
  }
50
73
  /**
51
- * Menu item displayed in the feedback context menu
74
+ * Menu item displayed in the Anyclick context menu
52
75
  */
53
- interface FeedbackMenuItem {
76
+ interface AnyclickMenuItem {
54
77
  /** Feedback type for this option (use unique identifier for parent items with children) */
55
- type: FeedbackType;
78
+ type: AnyclickType;
56
79
  /** Display label */
57
80
  label: string;
58
81
  /** Optional icon */
@@ -62,12 +85,21 @@ interface FeedbackMenuItem {
62
85
  /** Optional role(s) required to see this menu item */
63
86
  requiredRoles?: string[];
64
87
  /** Child menu items (creates a submenu) */
65
- children?: FeedbackMenuItem[];
88
+ children?: AnyclickMenuItem[];
89
+ /**
90
+ * Optional click handler for custom behavior.
91
+ * Return `false` (or a Promise resolving to false) to skip the default submission flow.
92
+ */
93
+ onClick?: (context: {
94
+ targetElement: Element | null;
95
+ containerElement: Element | null;
96
+ closeMenu: () => void;
97
+ }) => void | boolean | Promise<void | boolean>;
66
98
  }
67
99
  /**
68
100
  * User context for role-based menu filtering
69
101
  */
70
- interface FeedbackUserContext {
102
+ interface AnyclickUserContext {
71
103
  /** User's role(s) */
72
104
  roles?: string[];
73
105
  /** User ID */
@@ -78,22 +110,25 @@ interface FeedbackUserContext {
78
110
  /**
79
111
  * Filter menu items based on user context
80
112
  */
81
- declare function filterMenuItemsByRole(items: FeedbackMenuItem[], userContext?: FeedbackUserContext): FeedbackMenuItem[];
113
+ declare function filterMenuItemsByRole(items: AnyclickMenuItem[], userContext?: AnyclickUserContext): AnyclickMenuItem[];
82
114
  /**
83
115
  * Props for the AnyclickProvider component
84
116
  */
85
117
  interface AnyclickProviderProps {
86
- /** The adapter to use for submitting feedback */
87
- adapter: FeedbackAdapter;
118
+ /** Header content */
119
+ header?: ReactNode | null;
120
+ /** The adapter to use for submitting anyclick */
121
+ adapter: AnyclickAdapter;
88
122
  /** Child components */
89
123
  children: ReactNode;
90
124
  /**
91
- * Filter function to determine if feedback should be captured for a target element
92
- * Return true to allow feedback, false to ignore
125
+ * Filter function to determine if anyclick should be captured for a target element
126
+ * Return true to allow anyclick, false to ignore
127
+ * Accepts both MouseEvent (right-click) and TouchEvent (press-and-hold)
93
128
  */
94
- targetFilter?: (event: MouseEvent, target: Element) => boolean;
129
+ targetFilter?: (event: AnyclickTriggerEvent, target: Element) => boolean;
95
130
  /** Custom menu items (defaults to Issue, Feature, Like) */
96
- menuItems?: FeedbackMenuItem[];
131
+ menuItems?: AnyclickMenuItem[];
97
132
  /** Maximum length for innerText capture */
98
133
  maxInnerTextLength?: number;
99
134
  /** Maximum length for outerHTML capture */
@@ -107,9 +142,9 @@ interface AnyclickProviderProps {
107
142
  /** Additional metadata to include with every submission */
108
143
  metadata?: Record<string, unknown>;
109
144
  /** Callback after successful submission */
110
- onSubmitSuccess?: (payload: FeedbackPayload) => void;
145
+ onSubmitSuccess?: (payload: AnyclickPayload) => void;
111
146
  /** Callback after failed submission */
112
- onSubmitError?: (error: Error, payload: FeedbackPayload) => void;
147
+ onSubmitError?: (error: Error, payload: AnyclickPayload) => void;
113
148
  /** Custom styles for the context menu */
114
149
  menuStyle?: CSSProperties;
115
150
  /** Custom class name for the context menu */
@@ -132,27 +167,29 @@ interface AnyclickProviderProps {
132
167
  * Set to null or { disabled: true } to disable anyclick in this subtree.
133
168
  */
134
169
  theme?: AnyclickTheme | null;
170
+ /** Duration in ms to hold touch before triggering context menu (default: 500) */
171
+ touchHoldDurationMs?: number;
172
+ /** Maximum movement in px before touch hold is cancelled (default: 10) */
173
+ touchMoveThreshold?: number;
174
+ /** Menu positioning mode (default: 'inView') */
175
+ menuPositionMode?: MenuPositionMode;
135
176
  }
136
- /**
137
- * @deprecated Use AnyclickProviderProps instead
138
- */
139
- type FeedbackProviderProps = AnyclickProviderProps;
140
177
  /**
141
178
  * Context value exposed by AnyclickProvider
142
179
  */
143
180
  interface AnyclickContextValue {
144
- /** Whether feedback is currently enabled */
181
+ /** Whether anyclick is currently enabled */
145
182
  isEnabled: boolean;
146
183
  /** Whether a submission is in progress */
147
184
  isSubmitting: boolean;
148
- /** Submit feedback for a specific element */
149
- submitFeedback: (element: Element, type: FeedbackType, comment?: string) => Promise<void>;
150
- /** Open the feedback menu programmatically */
185
+ /** Submit anyclick for a specific element */
186
+ submitAnyclick: (element: Element, type: AnyclickType, comment?: string) => Promise<void>;
187
+ /** Open the anyclick menu programmatically */
151
188
  openMenu: (element: Element, position: {
152
189
  x: number;
153
190
  y: number;
154
191
  }) => void;
155
- /** Close the feedback menu */
192
+ /** Close the anyclick menu */
156
193
  closeMenu: () => void;
157
194
  /** The current merged theme (inherited from ancestors) */
158
195
  theme: AnyclickTheme;
@@ -161,10 +198,6 @@ interface AnyclickContextValue {
161
198
  /** The provider's unique ID */
162
199
  providerId: string;
163
200
  }
164
- /**
165
- * @deprecated Use AnyclickContextValue instead
166
- */
167
- type FeedbackContextValue = AnyclickContextValue;
168
201
  /**
169
202
  * Props for the context menu component
170
203
  */
@@ -176,14 +209,14 @@ interface ContextMenuProps {
176
209
  x: number;
177
210
  y: number;
178
211
  };
179
- /** Target element for feedback */
212
+ /** Target element for anyclick */
180
213
  targetElement: Element | null;
181
214
  /** Container element found by highlight logic */
182
215
  containerElement: Element | null;
183
216
  /** Menu items to display */
184
- items: FeedbackMenuItem[];
217
+ items: AnyclickMenuItem[];
185
218
  /** Callback when an item is selected */
186
- onSelect: (type: FeedbackType, comment?: string, screenshots?: ScreenshotData) => void;
219
+ onSelect: (type: AnyclickType, comment?: string, screenshots?: ScreenshotData) => void;
187
220
  /** Callback when menu is closed */
188
221
  onClose: () => void;
189
222
  /** Whether submission is in progress */
@@ -196,6 +229,12 @@ interface ContextMenuProps {
196
229
  highlightConfig?: HighlightConfig;
197
230
  /** Configuration for screenshot capture */
198
231
  screenshotConfig?: ScreenshotConfig;
232
+ /** Menu positioning mode (default: 'inView') */
233
+ positionMode?: MenuPositionMode;
234
+ /** Header content */
235
+ header?: ReactNode;
236
+ /** Footer content */
237
+ footer?: ReactNode;
199
238
  }
200
239
  /**
201
240
  * Props for the screenshot preview component
@@ -219,16 +258,23 @@ interface ScreenshotPreviewProps {
219
258
  * AnyclickProvider component - wraps your app to enable feedback capture
220
259
  * Supports scoped providers and nested theming
221
260
  */
222
- declare function AnyclickProvider({ adapter, children, targetFilter, menuItems, maxInnerTextLength, maxOuterHTMLLength, maxAncestors, cooldownMs, stripAttributes, metadata, onSubmitSuccess, onSubmitError, menuStyle, menuClassName, disabled, highlightConfig, screenshotConfig, scoped, theme, }: AnyclickProviderProps): react_jsx_runtime.JSX.Element;
261
+ declare function AnyclickProvider({ adapter, children, targetFilter, menuItems, maxInnerTextLength, maxOuterHTMLLength, maxAncestors, cooldownMs, stripAttributes, metadata, onSubmitSuccess, onSubmitError, menuStyle, menuClassName, disabled, highlightConfig, header, screenshotConfig, scoped, theme, touchHoldDurationMs, touchMoveThreshold, }: AnyclickProviderProps): react_jsx_runtime.JSX.Element;
223
262
  /**
224
263
  * @deprecated Use AnyclickProvider instead
225
264
  */
226
265
  declare const FeedbackProvider: typeof AnyclickProvider;
227
266
 
267
+ /**
268
+ * FunModeBridge watches Anyclick scoped providers and toggles the pointer
269
+ * into fun mode (go-kart) when the cursor is within a provider with funMode enabled.
270
+ * Requires a PointerProvider higher in the tree.
271
+ */
272
+ declare function FunModeBridge(): null;
273
+
228
274
  /**
229
275
  * Context menu component for selecting feedback type
230
276
  */
231
- declare function ContextMenu({ visible, position, targetElement, containerElement, items, onSelect, onClose, isSubmitting, style, className, highlightConfig, screenshotConfig, }: ContextMenuProps): react_jsx_runtime.JSX.Element | null;
277
+ declare function ContextMenu({ visible, position, targetElement, containerElement, items, onSelect, onClose, isSubmitting, style, className, highlightConfig, screenshotConfig, positionMode, header, footer, }: ContextMenuProps): react_jsx_runtime.JSX.Element | null;
232
278
 
233
279
  /**
234
280
  * Screenshot preview component - shows captured screenshots before sending
@@ -272,7 +318,7 @@ interface ProviderInstance {
272
318
  /** Depth in the provider hierarchy (0 = root) */
273
319
  depth: number;
274
320
  /** Handler to call when an event occurs in this provider's scope */
275
- onContextMenu?: (event: MouseEvent, element: Element) => void;
321
+ onContextMenu?: (event: AnyclickMenuEvent, element: Element) => boolean | void;
276
322
  }
277
323
  /**
278
324
  * Provider registry store state
@@ -314,6 +360,12 @@ interface ProviderStore {
314
360
  * in areas where a disabled scoped provider should block them
315
361
  */
316
362
  isElementInDisabledScope: (element: Element) => boolean;
363
+ /**
364
+ * Check if an element is inside any scoped provider's container (enabled or not)
365
+ * This is used to prevent the global provider from handling touch events
366
+ * that should be handled by a scoped provider instead
367
+ */
368
+ isElementInAnyScopedProvider: (element: Element) => boolean;
317
369
  }
318
370
  declare function generateProviderId(): string;
319
371
  /**
@@ -396,4 +448,4 @@ declare function applyHighlights(targetElement: Element, config?: HighlightConfi
396
448
  container: Element | null;
397
449
  };
398
450
 
399
- export { AnyclickContext, type AnyclickContextValue, AnyclickProvider, type AnyclickProviderProps, type AnyclickTheme, ContextMenu, type ContextMenuProps, FeedbackContext, type FeedbackContextValue, type FeedbackMenuItem, FeedbackProvider, type FeedbackProviderProps, type FeedbackUserContext, type HighlightColors, type HighlightConfig, type ProviderInstance, ScreenshotPreview, type ScreenshotPreviewProps, applyHighlights, clearHighlights, darkMenuStyles, defaultContainerSelectors, defaultHighlightColors, dispatchContextMenuEvent, filterMenuItemsByRole, findContainerParent, generateProviderId, highlightContainer, highlightTarget, menuCSSVariables, menuStyles, useAnyclick, useFeedback, useProviderStore };
451
+ export { AnyclickContext, type AnyclickContextValue, type AnyclickMenuItem, AnyclickProvider, type AnyclickProviderProps, type AnyclickTheme, type AnyclickUserContext, ContextMenu, type ContextMenuProps, FeedbackContext, FeedbackProvider, FunModeBridge, type FunModeThemeConfig, type HighlightColors, type HighlightConfig, type MenuPositionMode, type ProviderInstance, ScreenshotPreview, type ScreenshotPreviewProps, applyHighlights, clearHighlights, darkMenuStyles, defaultContainerSelectors, defaultHighlightColors, dispatchContextMenuEvent, filterMenuItemsByRole, findContainerParent, generateProviderId, highlightContainer, highlightTarget, menuCSSVariables, menuStyles, useAnyclick, useFeedback, useProviderStore };