@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/README.md CHANGED
@@ -23,21 +23,17 @@ npm install @ewjdev/anyclick-react
23
23
  ## Quick Start
24
24
 
25
25
  ```tsx
26
- 'use client';
26
+ "use client";
27
27
 
28
- import { AnyclickProvider } from '@ewjdev/anyclick-react';
29
- import { createHttpAdapter } from '@ewjdev/anyclick-github';
28
+ import { AnyclickProvider } from "@ewjdev/anyclick-react";
29
+ import { createHttpAdapter } from "@ewjdev/anyclick-github";
30
30
 
31
31
  const adapter = createHttpAdapter({
32
- endpoint: '/api/feedback',
32
+ endpoint: "/api/feedback",
33
33
  });
34
34
 
35
35
  export function Providers({ children }: { children: React.ReactNode }) {
36
- return (
37
- <AnyclickProvider adapter={adapter}>
38
- {children}
39
- </AnyclickProvider>
40
- );
36
+ return <AnyclickProvider adapter={adapter}>{children}</AnyclickProvider>;
41
37
  }
42
38
  ```
43
39
 
@@ -55,39 +51,39 @@ That's it! Users can now right-click any element to submit feedback.
55
51
 
56
52
  ## Props
57
53
 
58
- | Prop | Type | Description |
59
- |------|------|-------------|
60
- | `adapter` | `FeedbackAdapter` | Required. The adapter for submitting feedback |
61
- | `menuItems` | `FeedbackMenuItem[]` | Custom menu items |
62
- | `metadata` | `Record<string, unknown>` | Additional data included with every submission |
63
- | `theme` | `AnyclickTheme \| null` | Theme configuration (inherits from parent) |
64
- | `scoped` | `boolean` | Limit capture to this provider's children only |
65
- | `disabled` | `boolean` | Disable feedback capture |
66
- | `onSubmitSuccess` | `(payload) => void` | Success callback |
67
- | `onSubmitError` | `(error, payload) => void` | Error callback |
54
+ | Prop | Type | Description |
55
+ | ----------------- | -------------------------- | ---------------------------------------------- |
56
+ | `adapter` | `FeedbackAdapter` | Required. The adapter for submitting feedback |
57
+ | `menuItems` | `FeedbackMenuItem[]` | Custom menu items |
58
+ | `metadata` | `Record<string, unknown>` | Additional data included with every submission |
59
+ | `theme` | `AnyclickTheme \| null` | Theme configuration (inherits from parent) |
60
+ | `scoped` | `boolean` | Limit capture to this provider's children only |
61
+ | `disabled` | `boolean` | Disable feedback capture |
62
+ | `onSubmitSuccess` | `(payload) => void` | Success callback |
63
+ | `onSubmitError` | `(error, payload) => void` | Error callback |
68
64
 
69
65
  ## Scoped Providers
70
66
 
71
67
  Limit feedback capture to specific sections of your app:
72
68
 
73
69
  ```tsx
74
- import { AnyclickProvider } from '@ewjdev/anyclick-react';
70
+ import { AnyclickProvider } from "@ewjdev/anyclick-react";
75
71
 
76
72
  function App() {
77
73
  return (
78
74
  <AnyclickProvider adapter={globalAdapter}>
79
75
  {/* Global feedback works everywhere */}
80
76
  <Header />
81
-
77
+
82
78
  {/* Scoped provider - separate configuration */}
83
- <AnyclickProvider
79
+ <AnyclickProvider
84
80
  adapter={dashboardAdapter}
85
81
  scoped
86
82
  menuItems={dashboardMenuItems}
87
83
  >
88
84
  <Dashboard />
89
85
  </AnyclickProvider>
90
-
86
+
91
87
  <Footer />
92
88
  </AnyclickProvider>
93
89
  );
@@ -99,33 +95,33 @@ function App() {
99
95
  Override themes for specific sections:
100
96
 
101
97
  ```tsx
102
- import { AnyclickProvider } from '@ewjdev/anyclick-react';
98
+ import { AnyclickProvider } from "@ewjdev/anyclick-react";
103
99
 
104
100
  function App() {
105
101
  return (
106
- <AnyclickProvider
102
+ <AnyclickProvider
107
103
  adapter={adapter}
108
104
  theme={{
109
105
  highlightConfig: {
110
- colors: { targetColor: '#3b82f6' }
111
- }
106
+ colors: { targetColor: "#3b82f6" },
107
+ },
112
108
  }}
113
109
  >
114
110
  {/* Uses blue highlights */}
115
111
  <MainContent />
116
-
112
+
117
113
  {/* Uses red highlights (overrides parent) */}
118
- <AnyclickProvider
114
+ <AnyclickProvider
119
115
  scoped
120
116
  theme={{
121
117
  highlightConfig: {
122
- colors: { targetColor: '#ef4444' }
123
- }
118
+ colors: { targetColor: "#ef4444" },
119
+ },
124
120
  }}
125
121
  >
126
122
  <WarningSection />
127
123
  </AnyclickProvider>
128
-
124
+
129
125
  {/* Disable anyclick for this section */}
130
126
  <AnyclickProvider scoped theme={{ disabled: true }}>
131
127
  <SensitiveArea />
@@ -150,24 +146,24 @@ interface AnyclickTheme {
150
146
  ## Custom Menu Items
151
147
 
152
148
  ```tsx
153
- import { Bug, Lightbulb, Heart } from 'lucide-react';
149
+ import { Bug, Lightbulb, Heart } from "lucide-react";
154
150
 
155
151
  const menuItems = [
156
- {
157
- type: 'bug',
158
- label: 'Report Bug',
152
+ {
153
+ type: "bug",
154
+ label: "Report Bug",
159
155
  icon: <Bug className="w-4 h-4" />,
160
156
  showComment: true,
161
157
  },
162
- {
163
- type: 'feature',
164
- label: 'Suggest Feature',
158
+ {
159
+ type: "feature",
160
+ label: "Suggest Feature",
165
161
  icon: <Lightbulb className="w-4 h-4" />,
166
162
  showComment: true,
167
163
  },
168
- {
169
- type: 'love',
170
- label: 'Love It!',
164
+ {
165
+ type: "love",
166
+ label: "Love It!",
171
167
  icon: <Heart className="w-4 h-4" />,
172
168
  showComment: false,
173
169
  },
@@ -175,20 +171,20 @@ const menuItems = [
175
171
 
176
172
  <AnyclickProvider adapter={adapter} menuItems={menuItems}>
177
173
  {children}
178
- </AnyclickProvider>
174
+ </AnyclickProvider>;
179
175
  ```
180
176
 
181
177
  ## Role-Based Filtering
182
178
 
183
179
  ```tsx
184
- import { filterMenuItemsByRole } from '@ewjdev/anyclick-react';
180
+ import { filterMenuItemsByRole } from "@ewjdev/anyclick-react";
185
181
 
186
182
  const allMenuItems = [
187
- { type: 'bug', label: 'Report Bug' },
188
- { type: 'debug', label: 'Debug Info', requiredRoles: ['developer'] },
183
+ { type: "bug", label: "Report Bug" },
184
+ { type: "debug", label: "Debug Info", requiredRoles: ["developer"] },
189
185
  ];
190
186
 
191
- const userContext = { roles: ['user', 'developer'] };
187
+ const userContext = { roles: ["user", "developer"] };
192
188
  const menuItems = filterMenuItemsByRole(allMenuItems, userContext);
193
189
  ```
194
190
 
@@ -201,10 +197,10 @@ const menuItems = filterMenuItemsByRole(allMenuItems, userContext);
201
197
  highlightConfig: {
202
198
  enabled: true,
203
199
  colors: {
204
- targetColor: '#3b82f6',
205
- containerColor: '#8b5cf6',
200
+ targetColor: "#3b82f6",
201
+ containerColor: "#8b5cf6",
206
202
  },
207
- containerSelectors: ['[data-component]', '.card'],
203
+ containerSelectors: ["[data-component]", ".card"],
208
204
  },
209
205
  }}
210
206
  >
@@ -217,23 +213,17 @@ const menuItems = filterMenuItemsByRole(allMenuItems, userContext);
217
213
  Access anyclick context from child components:
218
214
 
219
215
  ```tsx
220
- import { useAnyclick } from '@ewjdev/anyclick-react';
216
+ import { useAnyclick } from "@ewjdev/anyclick-react";
221
217
 
222
218
  function MyComponent() {
223
- const {
224
- isSubmitting,
225
- openMenu,
226
- closeMenu,
227
- theme,
228
- scoped,
229
- providerId,
230
- } = useAnyclick();
231
-
219
+ const { isSubmitting, openMenu, closeMenu, theme, scoped, providerId } =
220
+ useAnyclick();
221
+
232
222
  // Open menu programmatically
233
223
  const handleClick = (event) => {
234
224
  openMenu(event.currentTarget, { x: event.clientX, y: event.clientY });
235
225
  };
236
-
226
+
237
227
  return <button onClick={handleClick}>Open Feedback</button>;
238
228
  }
239
229
  ```
@@ -244,10 +234,10 @@ The `FeedbackProvider` component has been renamed to `AnyclickProvider`. The old
244
234
 
245
235
  ```tsx
246
236
  // Old (deprecated)
247
- import { FeedbackProvider, useFeedback } from '@ewjdev/anyclick-react';
237
+ import { FeedbackProvider, useFeedback } from "@ewjdev/anyclick-react";
248
238
 
249
239
  // New (recommended)
250
- import { AnyclickProvider, useAnyclick } from '@ewjdev/anyclick-react';
240
+ import { AnyclickProvider, useAnyclick } from "@ewjdev/anyclick-react";
251
241
  ```
252
242
 
253
243
  ## Documentation
package/dist/index.d.mts 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 };