@ewjdev/anyclick-react 0.1.0 → 1.1.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
@@ -25,7 +25,7 @@ npm install @ewjdev/anyclick-react
25
25
  ```tsx
26
26
  'use client';
27
27
 
28
- import { FeedbackProvider } from '@ewjdev/anyclick-react';
28
+ import { AnyclickProvider } from '@ewjdev/anyclick-react';
29
29
  import { createHttpAdapter } from '@ewjdev/anyclick-github';
30
30
 
31
31
  const adapter = createHttpAdapter({
@@ -34,9 +34,9 @@ const adapter = createHttpAdapter({
34
34
 
35
35
  export function Providers({ children }: { children: React.ReactNode }) {
36
36
  return (
37
- <FeedbackProvider adapter={adapter}>
37
+ <AnyclickProvider adapter={adapter}>
38
38
  {children}
39
- </FeedbackProvider>
39
+ </AnyclickProvider>
40
40
  );
41
41
  }
42
42
  ```
@@ -50,6 +50,8 @@ That's it! Users can now right-click any element to submit feedback.
50
50
  - 📸 **Screenshot Capture** - Automatic screenshots of target, container, and page
51
51
  - 🔒 **Role-Based Menu Items** - Show different options based on user roles
52
52
  - 📱 **Submenus** - Organize menu items with nested submenus
53
+ - 🎯 **Scoped Providers** - Limit feedback capture to specific components
54
+ - 🎨 **Nested Theming** - Override themes for specific sections of your app
53
55
 
54
56
  ## Props
55
57
 
@@ -58,12 +60,93 @@ That's it! Users can now right-click any element to submit feedback.
58
60
  | `adapter` | `FeedbackAdapter` | Required. The adapter for submitting feedback |
59
61
  | `menuItems` | `FeedbackMenuItem[]` | Custom menu items |
60
62
  | `metadata` | `Record<string, unknown>` | Additional data included with every submission |
61
- | `highlightConfig` | `HighlightConfig` | Configure element highlighting |
62
- | `screenshotConfig` | `ScreenshotConfig` | Configure screenshot capture |
63
+ | `theme` | `AnyclickTheme \| null` | Theme configuration (inherits from parent) |
64
+ | `scoped` | `boolean` | Limit capture to this provider's children only |
63
65
  | `disabled` | `boolean` | Disable feedback capture |
64
66
  | `onSubmitSuccess` | `(payload) => void` | Success callback |
65
67
  | `onSubmitError` | `(error, payload) => void` | Error callback |
66
68
 
69
+ ## Scoped Providers
70
+
71
+ Limit feedback capture to specific sections of your app:
72
+
73
+ ```tsx
74
+ import { AnyclickProvider } from '@ewjdev/anyclick-react';
75
+
76
+ function App() {
77
+ return (
78
+ <AnyclickProvider adapter={globalAdapter}>
79
+ {/* Global feedback works everywhere */}
80
+ <Header />
81
+
82
+ {/* Scoped provider - separate configuration */}
83
+ <AnyclickProvider
84
+ adapter={dashboardAdapter}
85
+ scoped
86
+ menuItems={dashboardMenuItems}
87
+ >
88
+ <Dashboard />
89
+ </AnyclickProvider>
90
+
91
+ <Footer />
92
+ </AnyclickProvider>
93
+ );
94
+ }
95
+ ```
96
+
97
+ ## Nested Theming
98
+
99
+ Override themes for specific sections:
100
+
101
+ ```tsx
102
+ import { AnyclickProvider } from '@ewjdev/anyclick-react';
103
+
104
+ function App() {
105
+ return (
106
+ <AnyclickProvider
107
+ adapter={adapter}
108
+ theme={{
109
+ highlightConfig: {
110
+ colors: { targetColor: '#3b82f6' }
111
+ }
112
+ }}
113
+ >
114
+ {/* Uses blue highlights */}
115
+ <MainContent />
116
+
117
+ {/* Uses red highlights (overrides parent) */}
118
+ <AnyclickProvider
119
+ scoped
120
+ theme={{
121
+ highlightConfig: {
122
+ colors: { targetColor: '#ef4444' }
123
+ }
124
+ }}
125
+ >
126
+ <WarningSection />
127
+ </AnyclickProvider>
128
+
129
+ {/* Disable anyclick for this section */}
130
+ <AnyclickProvider scoped theme={{ disabled: true }}>
131
+ <SensitiveArea />
132
+ </AnyclickProvider>
133
+ </AnyclickProvider>
134
+ );
135
+ }
136
+ ```
137
+
138
+ ## Theme Configuration
139
+
140
+ ```tsx
141
+ interface AnyclickTheme {
142
+ menuStyle?: CSSProperties;
143
+ menuClassName?: string;
144
+ highlightConfig?: HighlightConfig;
145
+ screenshotConfig?: ScreenshotConfig;
146
+ disabled?: boolean; // Disable anyclick in this subtree
147
+ }
148
+ ```
149
+
67
150
  ## Custom Menu Items
68
151
 
69
152
  ```tsx
@@ -90,9 +173,9 @@ const menuItems = [
90
173
  },
91
174
  ];
92
175
 
93
- <FeedbackProvider adapter={adapter} menuItems={menuItems}>
176
+ <AnyclickProvider adapter={adapter} menuItems={menuItems}>
94
177
  {children}
95
- </FeedbackProvider>
178
+ </AnyclickProvider>
96
179
  ```
97
180
 
98
181
  ## Role-Based Filtering
@@ -112,30 +195,39 @@ const menuItems = filterMenuItemsByRole(allMenuItems, userContext);
112
195
  ## Highlight Configuration
113
196
 
114
197
  ```tsx
115
- <FeedbackProvider
198
+ <AnyclickProvider
116
199
  adapter={adapter}
117
- highlightConfig={{
118
- enabled: true,
119
- colors: {
120
- targetColor: '#3b82f6',
121
- containerColor: '#8b5cf6',
200
+ theme={{
201
+ highlightConfig: {
202
+ enabled: true,
203
+ colors: {
204
+ targetColor: '#3b82f6',
205
+ containerColor: '#8b5cf6',
206
+ },
207
+ containerSelectors: ['[data-component]', '.card'],
122
208
  },
123
- containerSelectors: ['[data-component]', '.card'],
124
209
  }}
125
210
  >
126
211
  {children}
127
- </FeedbackProvider>
212
+ </AnyclickProvider>
128
213
  ```
129
214
 
130
- ## useFeedback Hook
215
+ ## useAnyclick Hook
131
216
 
132
- Access feedback context from child components:
217
+ Access anyclick context from child components:
133
218
 
134
219
  ```tsx
135
- import { useFeedback } from '@ewjdev/anyclick-react';
220
+ import { useAnyclick } from '@ewjdev/anyclick-react';
136
221
 
137
222
  function MyComponent() {
138
- const { isSubmitting, openMenu, closeMenu } = useFeedback();
223
+ const {
224
+ isSubmitting,
225
+ openMenu,
226
+ closeMenu,
227
+ theme,
228
+ scoped,
229
+ providerId,
230
+ } = useAnyclick();
139
231
 
140
232
  // Open menu programmatically
141
233
  const handleClick = (event) => {
@@ -146,6 +238,18 @@ function MyComponent() {
146
238
  }
147
239
  ```
148
240
 
241
+ ## Migration from FeedbackProvider
242
+
243
+ The `FeedbackProvider` component has been renamed to `AnyclickProvider`. The old name is still exported for backward compatibility but is deprecated:
244
+
245
+ ```tsx
246
+ // Old (deprecated)
247
+ import { FeedbackProvider, useFeedback } from '@ewjdev/anyclick-react';
248
+
249
+ // New (recommended)
250
+ import { AnyclickProvider, useAnyclick } from '@ewjdev/anyclick-react';
251
+ ```
252
+
149
253
  ## Documentation
150
254
 
151
255
  For full documentation, visit [anyclick.ewj.dev/docs/react](https://anyclick.ewj.dev/docs/react)
package/dist/index.d.mts CHANGED
@@ -3,7 +3,24 @@ import { FeedbackAdapter, FeedbackType, FeedbackPayload, ScreenshotConfig, Scree
3
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';
4
4
  import * as react from 'react';
5
5
  import { ReactNode, CSSProperties } from 'react';
6
+ import * as zustand from 'zustand';
6
7
 
8
+ /**
9
+ * Theme configuration for AnyclickProvider
10
+ * Supports nested theming with inheritance
11
+ */
12
+ interface AnyclickTheme {
13
+ /** Custom styles for the context menu */
14
+ menuStyle?: CSSProperties;
15
+ /** Custom class name for the context menu */
16
+ menuClassName?: string;
17
+ /** Configuration for element highlighting */
18
+ highlightConfig?: HighlightConfig;
19
+ /** Configuration for screenshot capture */
20
+ screenshotConfig?: ScreenshotConfig;
21
+ /** Whether anyclick functionality is disabled in this theme */
22
+ disabled?: boolean;
23
+ }
7
24
  /**
8
25
  * Configuration for highlight colors
9
26
  */
@@ -63,9 +80,9 @@ interface FeedbackUserContext {
63
80
  */
64
81
  declare function filterMenuItemsByRole(items: FeedbackMenuItem[], userContext?: FeedbackUserContext): FeedbackMenuItem[];
65
82
  /**
66
- * Props for the FeedbackProvider component
83
+ * Props for the AnyclickProvider component
67
84
  */
68
- interface FeedbackProviderProps {
85
+ interface AnyclickProviderProps {
69
86
  /** The adapter to use for submitting feedback */
70
87
  adapter: FeedbackAdapter;
71
88
  /** Child components */
@@ -103,11 +120,27 @@ interface FeedbackProviderProps {
103
120
  highlightConfig?: HighlightConfig;
104
121
  /** Configuration for screenshot capture */
105
122
  screenshotConfig?: ScreenshotConfig;
123
+ /**
124
+ * Whether to scope this provider to its children only.
125
+ * When true, events will only be captured for elements within this provider's subtree.
126
+ * When false (default), events are captured for the entire document.
127
+ */
128
+ scoped?: boolean;
129
+ /**
130
+ * Theme configuration for this provider.
131
+ * Themes are inherited from parent providers and merged (child overrides parent).
132
+ * Set to null or { disabled: true } to disable anyclick in this subtree.
133
+ */
134
+ theme?: AnyclickTheme | null;
106
135
  }
107
136
  /**
108
- * Context value exposed by FeedbackProvider
137
+ * @deprecated Use AnyclickProviderProps instead
138
+ */
139
+ type FeedbackProviderProps = AnyclickProviderProps;
140
+ /**
141
+ * Context value exposed by AnyclickProvider
109
142
  */
110
- interface FeedbackContextValue {
143
+ interface AnyclickContextValue {
111
144
  /** Whether feedback is currently enabled */
112
145
  isEnabled: boolean;
113
146
  /** Whether a submission is in progress */
@@ -121,7 +154,17 @@ interface FeedbackContextValue {
121
154
  }) => void;
122
155
  /** Close the feedback menu */
123
156
  closeMenu: () => void;
157
+ /** The current merged theme (inherited from ancestors) */
158
+ theme: AnyclickTheme;
159
+ /** Whether this provider is scoped */
160
+ scoped: boolean;
161
+ /** The provider's unique ID */
162
+ providerId: string;
124
163
  }
164
+ /**
165
+ * @deprecated Use AnyclickContextValue instead
166
+ */
167
+ type FeedbackContextValue = AnyclickContextValue;
125
168
  /**
126
169
  * Props for the context menu component
127
170
  */
@@ -173,9 +216,14 @@ interface ScreenshotPreviewProps {
173
216
  }
174
217
 
175
218
  /**
176
- * FeedbackProvider component - wraps your app to enable feedback capture
219
+ * AnyclickProvider component - wraps your app to enable feedback capture
220
+ * Supports scoped providers and nested theming
221
+ */
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;
223
+ /**
224
+ * @deprecated Use AnyclickProvider instead
177
225
  */
178
- declare function FeedbackProvider({ adapter, children, targetFilter, menuItems, maxInnerTextLength, maxOuterHTMLLength, maxAncestors, cooldownMs, stripAttributes, metadata, onSubmitSuccess, onSubmitError, menuStyle, menuClassName, disabled, highlightConfig, screenshotConfig, }: FeedbackProviderProps): react_jsx_runtime.JSX.Element;
226
+ declare const FeedbackProvider: typeof AnyclickProvider;
179
227
 
180
228
  /**
181
229
  * Context menu component for selecting feedback type
@@ -188,15 +236,127 @@ declare function ContextMenu({ visible, position, targetElement, containerElemen
188
236
  declare function ScreenshotPreview({ screenshots, isLoading, onConfirm, onCancel, onRetake, isSubmitting, }: ScreenshotPreviewProps): react_jsx_runtime.JSX.Element;
189
237
 
190
238
  /**
191
- * React context for feedback functionality
239
+ * React context for anyclick functionality
240
+ */
241
+ declare const AnyclickContext: react.Context<AnyclickContextValue | null>;
242
+ /**
243
+ * @deprecated Use AnyclickContext instead
244
+ */
245
+ declare const FeedbackContext: react.Context<AnyclickContextValue | null>;
246
+ /**
247
+ * Hook to access anyclick context
248
+ * @throws Error if used outside of AnyclickProvider
249
+ */
250
+ declare function useAnyclick(): AnyclickContextValue;
251
+ /**
252
+ * @deprecated Use useAnyclick instead
253
+ */
254
+ declare function useFeedback(): AnyclickContextValue;
255
+
256
+ /**
257
+ * Registered provider instance
258
+ */
259
+ interface ProviderInstance {
260
+ /** Unique identifier for this provider instance */
261
+ id: string;
262
+ /** Reference to the provider's container element (null if not scoped) */
263
+ containerRef: React.RefObject<Element | null>;
264
+ /** Whether this provider is scoped to its container */
265
+ scoped: boolean;
266
+ /** The provider's theme configuration */
267
+ theme: AnyclickTheme | null;
268
+ /** Whether this provider is disabled */
269
+ disabled: boolean;
270
+ /** Parent provider ID (if nested) */
271
+ parentId: string | null;
272
+ /** Depth in the provider hierarchy (0 = root) */
273
+ depth: number;
274
+ /** Handler to call when an event occurs in this provider's scope */
275
+ onContextMenu?: (event: MouseEvent, element: Element) => void;
276
+ }
277
+ /**
278
+ * Provider registry store state
279
+ */
280
+ interface ProviderStore {
281
+ /** Map of provider ID to provider instance */
282
+ providers: Map<string, ProviderInstance>;
283
+ /**
284
+ * Register a new provider
285
+ */
286
+ registerProvider: (provider: ProviderInstance) => void;
287
+ /**
288
+ * Unregister a provider
289
+ */
290
+ unregisterProvider: (id: string) => void;
291
+ /**
292
+ * Update a provider's configuration
293
+ */
294
+ updateProvider: (id: string, updates: Partial<ProviderInstance>) => void;
295
+ /**
296
+ * Find all providers that contain a given element, sorted by depth (nearest first)
297
+ */
298
+ findProvidersForElement: (element: Element) => ProviderInstance[];
299
+ /**
300
+ * Find the nearest parent provider for a given container
301
+ */
302
+ findParentProvider: (container: Element | null, excludeId?: string) => ProviderInstance | null;
303
+ /**
304
+ * Get merged theme for a provider (includes inherited parent themes)
305
+ */
306
+ getMergedTheme: (providerId: string) => AnyclickTheme;
307
+ /**
308
+ * Check if any ancestor provider has disabled anyclick
309
+ */
310
+ isDisabledByAncestor: (providerId: string) => boolean;
311
+ /**
312
+ * Check if an element is inside a disabled scoped provider's container
313
+ * This is used to prevent the global provider from handling events
314
+ * in areas where a disabled scoped provider should block them
315
+ */
316
+ isElementInDisabledScope: (element: Element) => boolean;
317
+ }
318
+ declare function generateProviderId(): string;
319
+ /**
320
+ * Zustand store for managing provider instances
192
321
  */
193
- declare const FeedbackContext: react.Context<FeedbackContextValue | null>;
322
+ declare const useProviderStore: zustand.UseBoundStore<zustand.StoreApi<ProviderStore>>;
194
323
  /**
195
- * Hook to access feedback context
196
- * @throws Error if used outside of FeedbackProvider
324
+ * Dispatch a context menu event to all matching providers (bubble up)
197
325
  */
198
- declare function useFeedback(): FeedbackContextValue;
326
+ declare function dispatchContextMenuEvent(event: MouseEvent, element: Element): void;
199
327
 
328
+ /**
329
+ * CSS custom properties for menu theming.
330
+ * These can be overridden via the `style` prop on AnyclickProvider.
331
+ *
332
+ * Example:
333
+ * ```tsx
334
+ * <AnyclickProvider
335
+ * theme={{
336
+ * menuStyle: {
337
+ * '--anyclick-menu-bg': 'rgba(0, 0, 0, 0.9)',
338
+ * '--anyclick-menu-text': '#ffffff',
339
+ * '--anyclick-menu-border': 'rgba(255, 255, 255, 0.1)',
340
+ * '--anyclick-menu-hover': 'rgba(255, 255, 255, 0.1)',
341
+ * '--anyclick-menu-accent': '#f59e0b',
342
+ * }
343
+ * }}
344
+ * />
345
+ * ```
346
+ */
347
+ declare const menuCSSVariables: {
348
+ readonly "--anyclick-menu-bg": "#ffffff";
349
+ readonly "--anyclick-menu-hover": "#f5f5f5";
350
+ readonly "--anyclick-menu-text": "#333333";
351
+ readonly "--anyclick-menu-text-muted": "#666666";
352
+ readonly "--anyclick-menu-border": "#e5e5e5";
353
+ readonly "--anyclick-menu-accent": "#0066cc";
354
+ readonly "--anyclick-menu-accent-text": "#ffffff";
355
+ readonly "--anyclick-menu-input-bg": "#ffffff";
356
+ readonly "--anyclick-menu-input-border": "#dddddd";
357
+ readonly "--anyclick-menu-cancel-bg": "#f0f0f0";
358
+ readonly "--anyclick-menu-cancel-text": "#666666";
359
+ };
200
360
  declare const menuStyles: Record<string, CSSProperties>;
201
361
  declare const darkMenuStyles: Record<string, CSSProperties>;
202
362
 
@@ -236,4 +396,4 @@ declare function applyHighlights(targetElement: Element, config?: HighlightConfi
236
396
  container: Element | null;
237
397
  };
238
398
 
239
- export { ContextMenu, type ContextMenuProps, FeedbackContext, type FeedbackContextValue, type FeedbackMenuItem, FeedbackProvider, type FeedbackProviderProps, type FeedbackUserContext, type HighlightColors, type HighlightConfig, ScreenshotPreview, type ScreenshotPreviewProps, applyHighlights, clearHighlights, darkMenuStyles, defaultContainerSelectors, defaultHighlightColors, filterMenuItemsByRole, findContainerParent, highlightContainer, highlightTarget, menuStyles, useFeedback };
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 };
package/dist/index.d.ts CHANGED
@@ -3,7 +3,24 @@ import { FeedbackAdapter, FeedbackType, FeedbackPayload, ScreenshotConfig, Scree
3
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';
4
4
  import * as react from 'react';
5
5
  import { ReactNode, CSSProperties } from 'react';
6
+ import * as zustand from 'zustand';
6
7
 
8
+ /**
9
+ * Theme configuration for AnyclickProvider
10
+ * Supports nested theming with inheritance
11
+ */
12
+ interface AnyclickTheme {
13
+ /** Custom styles for the context menu */
14
+ menuStyle?: CSSProperties;
15
+ /** Custom class name for the context menu */
16
+ menuClassName?: string;
17
+ /** Configuration for element highlighting */
18
+ highlightConfig?: HighlightConfig;
19
+ /** Configuration for screenshot capture */
20
+ screenshotConfig?: ScreenshotConfig;
21
+ /** Whether anyclick functionality is disabled in this theme */
22
+ disabled?: boolean;
23
+ }
7
24
  /**
8
25
  * Configuration for highlight colors
9
26
  */
@@ -63,9 +80,9 @@ interface FeedbackUserContext {
63
80
  */
64
81
  declare function filterMenuItemsByRole(items: FeedbackMenuItem[], userContext?: FeedbackUserContext): FeedbackMenuItem[];
65
82
  /**
66
- * Props for the FeedbackProvider component
83
+ * Props for the AnyclickProvider component
67
84
  */
68
- interface FeedbackProviderProps {
85
+ interface AnyclickProviderProps {
69
86
  /** The adapter to use for submitting feedback */
70
87
  adapter: FeedbackAdapter;
71
88
  /** Child components */
@@ -103,11 +120,27 @@ interface FeedbackProviderProps {
103
120
  highlightConfig?: HighlightConfig;
104
121
  /** Configuration for screenshot capture */
105
122
  screenshotConfig?: ScreenshotConfig;
123
+ /**
124
+ * Whether to scope this provider to its children only.
125
+ * When true, events will only be captured for elements within this provider's subtree.
126
+ * When false (default), events are captured for the entire document.
127
+ */
128
+ scoped?: boolean;
129
+ /**
130
+ * Theme configuration for this provider.
131
+ * Themes are inherited from parent providers and merged (child overrides parent).
132
+ * Set to null or { disabled: true } to disable anyclick in this subtree.
133
+ */
134
+ theme?: AnyclickTheme | null;
106
135
  }
107
136
  /**
108
- * Context value exposed by FeedbackProvider
137
+ * @deprecated Use AnyclickProviderProps instead
138
+ */
139
+ type FeedbackProviderProps = AnyclickProviderProps;
140
+ /**
141
+ * Context value exposed by AnyclickProvider
109
142
  */
110
- interface FeedbackContextValue {
143
+ interface AnyclickContextValue {
111
144
  /** Whether feedback is currently enabled */
112
145
  isEnabled: boolean;
113
146
  /** Whether a submission is in progress */
@@ -121,7 +154,17 @@ interface FeedbackContextValue {
121
154
  }) => void;
122
155
  /** Close the feedback menu */
123
156
  closeMenu: () => void;
157
+ /** The current merged theme (inherited from ancestors) */
158
+ theme: AnyclickTheme;
159
+ /** Whether this provider is scoped */
160
+ scoped: boolean;
161
+ /** The provider's unique ID */
162
+ providerId: string;
124
163
  }
164
+ /**
165
+ * @deprecated Use AnyclickContextValue instead
166
+ */
167
+ type FeedbackContextValue = AnyclickContextValue;
125
168
  /**
126
169
  * Props for the context menu component
127
170
  */
@@ -173,9 +216,14 @@ interface ScreenshotPreviewProps {
173
216
  }
174
217
 
175
218
  /**
176
- * FeedbackProvider component - wraps your app to enable feedback capture
219
+ * AnyclickProvider component - wraps your app to enable feedback capture
220
+ * Supports scoped providers and nested theming
221
+ */
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;
223
+ /**
224
+ * @deprecated Use AnyclickProvider instead
177
225
  */
178
- declare function FeedbackProvider({ adapter, children, targetFilter, menuItems, maxInnerTextLength, maxOuterHTMLLength, maxAncestors, cooldownMs, stripAttributes, metadata, onSubmitSuccess, onSubmitError, menuStyle, menuClassName, disabled, highlightConfig, screenshotConfig, }: FeedbackProviderProps): react_jsx_runtime.JSX.Element;
226
+ declare const FeedbackProvider: typeof AnyclickProvider;
179
227
 
180
228
  /**
181
229
  * Context menu component for selecting feedback type
@@ -188,15 +236,127 @@ declare function ContextMenu({ visible, position, targetElement, containerElemen
188
236
  declare function ScreenshotPreview({ screenshots, isLoading, onConfirm, onCancel, onRetake, isSubmitting, }: ScreenshotPreviewProps): react_jsx_runtime.JSX.Element;
189
237
 
190
238
  /**
191
- * React context for feedback functionality
239
+ * React context for anyclick functionality
240
+ */
241
+ declare const AnyclickContext: react.Context<AnyclickContextValue | null>;
242
+ /**
243
+ * @deprecated Use AnyclickContext instead
244
+ */
245
+ declare const FeedbackContext: react.Context<AnyclickContextValue | null>;
246
+ /**
247
+ * Hook to access anyclick context
248
+ * @throws Error if used outside of AnyclickProvider
249
+ */
250
+ declare function useAnyclick(): AnyclickContextValue;
251
+ /**
252
+ * @deprecated Use useAnyclick instead
253
+ */
254
+ declare function useFeedback(): AnyclickContextValue;
255
+
256
+ /**
257
+ * Registered provider instance
258
+ */
259
+ interface ProviderInstance {
260
+ /** Unique identifier for this provider instance */
261
+ id: string;
262
+ /** Reference to the provider's container element (null if not scoped) */
263
+ containerRef: React.RefObject<Element | null>;
264
+ /** Whether this provider is scoped to its container */
265
+ scoped: boolean;
266
+ /** The provider's theme configuration */
267
+ theme: AnyclickTheme | null;
268
+ /** Whether this provider is disabled */
269
+ disabled: boolean;
270
+ /** Parent provider ID (if nested) */
271
+ parentId: string | null;
272
+ /** Depth in the provider hierarchy (0 = root) */
273
+ depth: number;
274
+ /** Handler to call when an event occurs in this provider's scope */
275
+ onContextMenu?: (event: MouseEvent, element: Element) => void;
276
+ }
277
+ /**
278
+ * Provider registry store state
279
+ */
280
+ interface ProviderStore {
281
+ /** Map of provider ID to provider instance */
282
+ providers: Map<string, ProviderInstance>;
283
+ /**
284
+ * Register a new provider
285
+ */
286
+ registerProvider: (provider: ProviderInstance) => void;
287
+ /**
288
+ * Unregister a provider
289
+ */
290
+ unregisterProvider: (id: string) => void;
291
+ /**
292
+ * Update a provider's configuration
293
+ */
294
+ updateProvider: (id: string, updates: Partial<ProviderInstance>) => void;
295
+ /**
296
+ * Find all providers that contain a given element, sorted by depth (nearest first)
297
+ */
298
+ findProvidersForElement: (element: Element) => ProviderInstance[];
299
+ /**
300
+ * Find the nearest parent provider for a given container
301
+ */
302
+ findParentProvider: (container: Element | null, excludeId?: string) => ProviderInstance | null;
303
+ /**
304
+ * Get merged theme for a provider (includes inherited parent themes)
305
+ */
306
+ getMergedTheme: (providerId: string) => AnyclickTheme;
307
+ /**
308
+ * Check if any ancestor provider has disabled anyclick
309
+ */
310
+ isDisabledByAncestor: (providerId: string) => boolean;
311
+ /**
312
+ * Check if an element is inside a disabled scoped provider's container
313
+ * This is used to prevent the global provider from handling events
314
+ * in areas where a disabled scoped provider should block them
315
+ */
316
+ isElementInDisabledScope: (element: Element) => boolean;
317
+ }
318
+ declare function generateProviderId(): string;
319
+ /**
320
+ * Zustand store for managing provider instances
192
321
  */
193
- declare const FeedbackContext: react.Context<FeedbackContextValue | null>;
322
+ declare const useProviderStore: zustand.UseBoundStore<zustand.StoreApi<ProviderStore>>;
194
323
  /**
195
- * Hook to access feedback context
196
- * @throws Error if used outside of FeedbackProvider
324
+ * Dispatch a context menu event to all matching providers (bubble up)
197
325
  */
198
- declare function useFeedback(): FeedbackContextValue;
326
+ declare function dispatchContextMenuEvent(event: MouseEvent, element: Element): void;
199
327
 
328
+ /**
329
+ * CSS custom properties for menu theming.
330
+ * These can be overridden via the `style` prop on AnyclickProvider.
331
+ *
332
+ * Example:
333
+ * ```tsx
334
+ * <AnyclickProvider
335
+ * theme={{
336
+ * menuStyle: {
337
+ * '--anyclick-menu-bg': 'rgba(0, 0, 0, 0.9)',
338
+ * '--anyclick-menu-text': '#ffffff',
339
+ * '--anyclick-menu-border': 'rgba(255, 255, 255, 0.1)',
340
+ * '--anyclick-menu-hover': 'rgba(255, 255, 255, 0.1)',
341
+ * '--anyclick-menu-accent': '#f59e0b',
342
+ * }
343
+ * }}
344
+ * />
345
+ * ```
346
+ */
347
+ declare const menuCSSVariables: {
348
+ readonly "--anyclick-menu-bg": "#ffffff";
349
+ readonly "--anyclick-menu-hover": "#f5f5f5";
350
+ readonly "--anyclick-menu-text": "#333333";
351
+ readonly "--anyclick-menu-text-muted": "#666666";
352
+ readonly "--anyclick-menu-border": "#e5e5e5";
353
+ readonly "--anyclick-menu-accent": "#0066cc";
354
+ readonly "--anyclick-menu-accent-text": "#ffffff";
355
+ readonly "--anyclick-menu-input-bg": "#ffffff";
356
+ readonly "--anyclick-menu-input-border": "#dddddd";
357
+ readonly "--anyclick-menu-cancel-bg": "#f0f0f0";
358
+ readonly "--anyclick-menu-cancel-text": "#666666";
359
+ };
200
360
  declare const menuStyles: Record<string, CSSProperties>;
201
361
  declare const darkMenuStyles: Record<string, CSSProperties>;
202
362
 
@@ -236,4 +396,4 @@ declare function applyHighlights(targetElement: Element, config?: HighlightConfi
236
396
  container: Element | null;
237
397
  };
238
398
 
239
- export { ContextMenu, type ContextMenuProps, FeedbackContext, type FeedbackContextValue, type FeedbackMenuItem, FeedbackProvider, type FeedbackProviderProps, type FeedbackUserContext, type HighlightColors, type HighlightConfig, ScreenshotPreview, type ScreenshotPreviewProps, applyHighlights, clearHighlights, darkMenuStyles, defaultContainerSelectors, defaultHighlightColors, filterMenuItemsByRole, findContainerParent, highlightContainer, highlightTarget, menuStyles, useFeedback };
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 };