@ewjdev/anyclick-react 0.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 +161 -0
- package/dist/index.d.mts +239 -0
- package/dist/index.d.ts +239 -0
- package/dist/index.js +1491 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +1462 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +64 -0
package/README.md
ADDED
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
# @ewjdev/anyclick-react
|
|
2
|
+
|
|
3
|
+
> React provider and context menu UI for UI feedback capture
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/@ewjdev/anyclick-react)
|
|
6
|
+
[](https://opensource.org/licenses/MIT)
|
|
7
|
+
|
|
8
|
+
## Overview
|
|
9
|
+
|
|
10
|
+
`@ewjdev/anyclick-react` provides a drop-in React component that adds feedback capture to your application. Right-click any element to open a customizable context menu for submitting feedback.
|
|
11
|
+
|
|
12
|
+
## Installation
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
npm install @ewjdev/anyclick-react
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Requirements
|
|
19
|
+
|
|
20
|
+
- React 19+
|
|
21
|
+
- @ewjdev/anyclick-core (included as dependency)
|
|
22
|
+
|
|
23
|
+
## Quick Start
|
|
24
|
+
|
|
25
|
+
```tsx
|
|
26
|
+
'use client';
|
|
27
|
+
|
|
28
|
+
import { FeedbackProvider } from '@ewjdev/anyclick-react';
|
|
29
|
+
import { createHttpAdapter } from '@ewjdev/anyclick-github';
|
|
30
|
+
|
|
31
|
+
const adapter = createHttpAdapter({
|
|
32
|
+
endpoint: '/api/feedback',
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
export function Providers({ children }: { children: React.ReactNode }) {
|
|
36
|
+
return (
|
|
37
|
+
<FeedbackProvider adapter={adapter}>
|
|
38
|
+
{children}
|
|
39
|
+
</FeedbackProvider>
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
That's it! Users can now right-click any element to submit feedback.
|
|
45
|
+
|
|
46
|
+
## Features
|
|
47
|
+
|
|
48
|
+
- 🖱️ **Right-Click Context Menu** - Native feel with customizable items
|
|
49
|
+
- 🎨 **Element Highlighting** - Visual feedback for target and container elements
|
|
50
|
+
- 📸 **Screenshot Capture** - Automatic screenshots of target, container, and page
|
|
51
|
+
- 🔒 **Role-Based Menu Items** - Show different options based on user roles
|
|
52
|
+
- 📱 **Submenus** - Organize menu items with nested submenus
|
|
53
|
+
|
|
54
|
+
## Props
|
|
55
|
+
|
|
56
|
+
| Prop | Type | Description |
|
|
57
|
+
|------|------|-------------|
|
|
58
|
+
| `adapter` | `FeedbackAdapter` | Required. The adapter for submitting feedback |
|
|
59
|
+
| `menuItems` | `FeedbackMenuItem[]` | Custom menu items |
|
|
60
|
+
| `metadata` | `Record<string, unknown>` | Additional data included with every submission |
|
|
61
|
+
| `highlightConfig` | `HighlightConfig` | Configure element highlighting |
|
|
62
|
+
| `screenshotConfig` | `ScreenshotConfig` | Configure screenshot capture |
|
|
63
|
+
| `disabled` | `boolean` | Disable feedback capture |
|
|
64
|
+
| `onSubmitSuccess` | `(payload) => void` | Success callback |
|
|
65
|
+
| `onSubmitError` | `(error, payload) => void` | Error callback |
|
|
66
|
+
|
|
67
|
+
## Custom Menu Items
|
|
68
|
+
|
|
69
|
+
```tsx
|
|
70
|
+
import { Bug, Lightbulb, Heart } from 'lucide-react';
|
|
71
|
+
|
|
72
|
+
const menuItems = [
|
|
73
|
+
{
|
|
74
|
+
type: 'bug',
|
|
75
|
+
label: 'Report Bug',
|
|
76
|
+
icon: <Bug className="w-4 h-4" />,
|
|
77
|
+
showComment: true,
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
type: 'feature',
|
|
81
|
+
label: 'Suggest Feature',
|
|
82
|
+
icon: <Lightbulb className="w-4 h-4" />,
|
|
83
|
+
showComment: true,
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
type: 'love',
|
|
87
|
+
label: 'Love It!',
|
|
88
|
+
icon: <Heart className="w-4 h-4" />,
|
|
89
|
+
showComment: false,
|
|
90
|
+
},
|
|
91
|
+
];
|
|
92
|
+
|
|
93
|
+
<FeedbackProvider adapter={adapter} menuItems={menuItems}>
|
|
94
|
+
{children}
|
|
95
|
+
</FeedbackProvider>
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
## Role-Based Filtering
|
|
99
|
+
|
|
100
|
+
```tsx
|
|
101
|
+
import { filterMenuItemsByRole } from '@ewjdev/anyclick-react';
|
|
102
|
+
|
|
103
|
+
const allMenuItems = [
|
|
104
|
+
{ type: 'bug', label: 'Report Bug' },
|
|
105
|
+
{ type: 'debug', label: 'Debug Info', requiredRoles: ['developer'] },
|
|
106
|
+
];
|
|
107
|
+
|
|
108
|
+
const userContext = { roles: ['user', 'developer'] };
|
|
109
|
+
const menuItems = filterMenuItemsByRole(allMenuItems, userContext);
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
## Highlight Configuration
|
|
113
|
+
|
|
114
|
+
```tsx
|
|
115
|
+
<FeedbackProvider
|
|
116
|
+
adapter={adapter}
|
|
117
|
+
highlightConfig={{
|
|
118
|
+
enabled: true,
|
|
119
|
+
colors: {
|
|
120
|
+
targetColor: '#3b82f6',
|
|
121
|
+
containerColor: '#8b5cf6',
|
|
122
|
+
},
|
|
123
|
+
containerSelectors: ['[data-component]', '.card'],
|
|
124
|
+
}}
|
|
125
|
+
>
|
|
126
|
+
{children}
|
|
127
|
+
</FeedbackProvider>
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
## useFeedback Hook
|
|
131
|
+
|
|
132
|
+
Access feedback context from child components:
|
|
133
|
+
|
|
134
|
+
```tsx
|
|
135
|
+
import { useFeedback } from '@ewjdev/anyclick-react';
|
|
136
|
+
|
|
137
|
+
function MyComponent() {
|
|
138
|
+
const { isSubmitting, openMenu, closeMenu } = useFeedback();
|
|
139
|
+
|
|
140
|
+
// Open menu programmatically
|
|
141
|
+
const handleClick = (event) => {
|
|
142
|
+
openMenu(event.currentTarget, { x: event.clientX, y: event.clientY });
|
|
143
|
+
};
|
|
144
|
+
|
|
145
|
+
return <button onClick={handleClick}>Open Feedback</button>;
|
|
146
|
+
}
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
## Documentation
|
|
150
|
+
|
|
151
|
+
For full documentation, visit [anyclick.ewj.dev/docs/react](https://anyclick.ewj.dev/docs/react)
|
|
152
|
+
|
|
153
|
+
## Related Packages
|
|
154
|
+
|
|
155
|
+
- [`@ewjdev/anyclick-core`](https://www.npmjs.com/package/@ewjdev/anyclick-core) - Core library
|
|
156
|
+
- [`@ewjdev/anyclick-github`](https://www.npmjs.com/package/@ewjdev/anyclick-github) - GitHub Issues integration
|
|
157
|
+
- [`@ewjdev/anyclick-cursor`](https://www.npmjs.com/package/@ewjdev/anyclick-cursor) - Cursor AI integration
|
|
158
|
+
|
|
159
|
+
## License
|
|
160
|
+
|
|
161
|
+
MIT © [anyclick](https://anyclick.ewj.dev)
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,239 @@
|
|
|
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';
|
|
4
|
+
import * as react from 'react';
|
|
5
|
+
import { ReactNode, CSSProperties } from 'react';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Configuration for highlight colors
|
|
9
|
+
*/
|
|
10
|
+
interface HighlightColors {
|
|
11
|
+
/** Color for the target element highlight (default: #3b82f6 - blue) */
|
|
12
|
+
targetColor?: string;
|
|
13
|
+
/** Color for the container element highlight (default: #8b5cf6 - purple) */
|
|
14
|
+
containerColor?: string;
|
|
15
|
+
/** Opacity for the target shadow (default: 0.25) */
|
|
16
|
+
targetShadowOpacity?: number;
|
|
17
|
+
/** Opacity for the container shadow (default: 0.1) */
|
|
18
|
+
containerShadowOpacity?: number;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Configuration for highlight behavior
|
|
22
|
+
*/
|
|
23
|
+
interface HighlightConfig {
|
|
24
|
+
/** Whether to show highlights (default: true) */
|
|
25
|
+
enabled?: boolean;
|
|
26
|
+
/** Custom colors for highlights */
|
|
27
|
+
colors?: HighlightColors;
|
|
28
|
+
/** CSS selectors to identify container elements */
|
|
29
|
+
containerSelectors?: string[];
|
|
30
|
+
/** Minimum number of children for an element to be considered a container (default: 2) */
|
|
31
|
+
minChildrenForContainer?: number;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Menu item displayed in the feedback context menu
|
|
35
|
+
*/
|
|
36
|
+
interface FeedbackMenuItem {
|
|
37
|
+
/** Feedback type for this option (use unique identifier for parent items with children) */
|
|
38
|
+
type: FeedbackType;
|
|
39
|
+
/** Display label */
|
|
40
|
+
label: string;
|
|
41
|
+
/** Optional icon */
|
|
42
|
+
icon?: ReactNode;
|
|
43
|
+
/** Whether to show a comment input for this type */
|
|
44
|
+
showComment?: boolean;
|
|
45
|
+
/** Optional role(s) required to see this menu item */
|
|
46
|
+
requiredRoles?: string[];
|
|
47
|
+
/** Child menu items (creates a submenu) */
|
|
48
|
+
children?: FeedbackMenuItem[];
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* User context for role-based menu filtering
|
|
52
|
+
*/
|
|
53
|
+
interface FeedbackUserContext {
|
|
54
|
+
/** User's role(s) */
|
|
55
|
+
roles?: string[];
|
|
56
|
+
/** User ID */
|
|
57
|
+
id?: string;
|
|
58
|
+
/** User email */
|
|
59
|
+
email?: string;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Filter menu items based on user context
|
|
63
|
+
*/
|
|
64
|
+
declare function filterMenuItemsByRole(items: FeedbackMenuItem[], userContext?: FeedbackUserContext): FeedbackMenuItem[];
|
|
65
|
+
/**
|
|
66
|
+
* Props for the FeedbackProvider component
|
|
67
|
+
*/
|
|
68
|
+
interface FeedbackProviderProps {
|
|
69
|
+
/** The adapter to use for submitting feedback */
|
|
70
|
+
adapter: FeedbackAdapter;
|
|
71
|
+
/** Child components */
|
|
72
|
+
children: ReactNode;
|
|
73
|
+
/**
|
|
74
|
+
* Filter function to determine if feedback should be captured for a target element
|
|
75
|
+
* Return true to allow feedback, false to ignore
|
|
76
|
+
*/
|
|
77
|
+
targetFilter?: (event: MouseEvent, target: Element) => boolean;
|
|
78
|
+
/** Custom menu items (defaults to Issue, Feature, Like) */
|
|
79
|
+
menuItems?: FeedbackMenuItem[];
|
|
80
|
+
/** Maximum length for innerText capture */
|
|
81
|
+
maxInnerTextLength?: number;
|
|
82
|
+
/** Maximum length for outerHTML capture */
|
|
83
|
+
maxOuterHTMLLength?: number;
|
|
84
|
+
/** Maximum number of ancestors to capture */
|
|
85
|
+
maxAncestors?: number;
|
|
86
|
+
/** Cooldown in milliseconds between submissions (rate limiting) */
|
|
87
|
+
cooldownMs?: number;
|
|
88
|
+
/** Attributes to strip from outerHTML for privacy */
|
|
89
|
+
stripAttributes?: string[];
|
|
90
|
+
/** Additional metadata to include with every submission */
|
|
91
|
+
metadata?: Record<string, unknown>;
|
|
92
|
+
/** Callback after successful submission */
|
|
93
|
+
onSubmitSuccess?: (payload: FeedbackPayload) => void;
|
|
94
|
+
/** Callback after failed submission */
|
|
95
|
+
onSubmitError?: (error: Error, payload: FeedbackPayload) => void;
|
|
96
|
+
/** Custom styles for the context menu */
|
|
97
|
+
menuStyle?: CSSProperties;
|
|
98
|
+
/** Custom class name for the context menu */
|
|
99
|
+
menuClassName?: string;
|
|
100
|
+
/** Whether the provider is disabled */
|
|
101
|
+
disabled?: boolean;
|
|
102
|
+
/** Configuration for element highlighting */
|
|
103
|
+
highlightConfig?: HighlightConfig;
|
|
104
|
+
/** Configuration for screenshot capture */
|
|
105
|
+
screenshotConfig?: ScreenshotConfig;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Context value exposed by FeedbackProvider
|
|
109
|
+
*/
|
|
110
|
+
interface FeedbackContextValue {
|
|
111
|
+
/** Whether feedback is currently enabled */
|
|
112
|
+
isEnabled: boolean;
|
|
113
|
+
/** Whether a submission is in progress */
|
|
114
|
+
isSubmitting: boolean;
|
|
115
|
+
/** Submit feedback for a specific element */
|
|
116
|
+
submitFeedback: (element: Element, type: FeedbackType, comment?: string) => Promise<void>;
|
|
117
|
+
/** Open the feedback menu programmatically */
|
|
118
|
+
openMenu: (element: Element, position: {
|
|
119
|
+
x: number;
|
|
120
|
+
y: number;
|
|
121
|
+
}) => void;
|
|
122
|
+
/** Close the feedback menu */
|
|
123
|
+
closeMenu: () => void;
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Props for the context menu component
|
|
127
|
+
*/
|
|
128
|
+
interface ContextMenuProps {
|
|
129
|
+
/** Whether the menu is visible */
|
|
130
|
+
visible: boolean;
|
|
131
|
+
/** Position of the menu */
|
|
132
|
+
position: {
|
|
133
|
+
x: number;
|
|
134
|
+
y: number;
|
|
135
|
+
};
|
|
136
|
+
/** Target element for feedback */
|
|
137
|
+
targetElement: Element | null;
|
|
138
|
+
/** Container element found by highlight logic */
|
|
139
|
+
containerElement: Element | null;
|
|
140
|
+
/** Menu items to display */
|
|
141
|
+
items: FeedbackMenuItem[];
|
|
142
|
+
/** Callback when an item is selected */
|
|
143
|
+
onSelect: (type: FeedbackType, comment?: string, screenshots?: ScreenshotData) => void;
|
|
144
|
+
/** Callback when menu is closed */
|
|
145
|
+
onClose: () => void;
|
|
146
|
+
/** Whether submission is in progress */
|
|
147
|
+
isSubmitting: boolean;
|
|
148
|
+
/** Custom styles */
|
|
149
|
+
style?: CSSProperties;
|
|
150
|
+
/** Custom class name */
|
|
151
|
+
className?: string;
|
|
152
|
+
/** Configuration for element highlighting */
|
|
153
|
+
highlightConfig?: HighlightConfig;
|
|
154
|
+
/** Configuration for screenshot capture */
|
|
155
|
+
screenshotConfig?: ScreenshotConfig;
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Props for the screenshot preview component
|
|
159
|
+
*/
|
|
160
|
+
interface ScreenshotPreviewProps {
|
|
161
|
+
/** Captured screenshot data */
|
|
162
|
+
screenshots: ScreenshotData | null;
|
|
163
|
+
/** Whether screenshots are loading */
|
|
164
|
+
isLoading: boolean;
|
|
165
|
+
/** Callback when user confirms screenshots */
|
|
166
|
+
onConfirm: (screenshots: ScreenshotData) => void;
|
|
167
|
+
/** Callback when user cancels */
|
|
168
|
+
onCancel: () => void;
|
|
169
|
+
/** Callback when user wants to retake screenshots */
|
|
170
|
+
onRetake: () => void;
|
|
171
|
+
/** Whether submission is in progress */
|
|
172
|
+
isSubmitting: boolean;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* FeedbackProvider component - wraps your app to enable feedback capture
|
|
177
|
+
*/
|
|
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;
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* Context menu component for selecting feedback type
|
|
182
|
+
*/
|
|
183
|
+
declare function ContextMenu({ visible, position, targetElement, containerElement, items, onSelect, onClose, isSubmitting, style, className, highlightConfig, screenshotConfig, }: ContextMenuProps): react_jsx_runtime.JSX.Element | null;
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* Screenshot preview component - shows captured screenshots before sending
|
|
187
|
+
*/
|
|
188
|
+
declare function ScreenshotPreview({ screenshots, isLoading, onConfirm, onCancel, onRetake, isSubmitting, }: ScreenshotPreviewProps): react_jsx_runtime.JSX.Element;
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* React context for feedback functionality
|
|
192
|
+
*/
|
|
193
|
+
declare const FeedbackContext: react.Context<FeedbackContextValue | null>;
|
|
194
|
+
/**
|
|
195
|
+
* Hook to access feedback context
|
|
196
|
+
* @throws Error if used outside of FeedbackProvider
|
|
197
|
+
*/
|
|
198
|
+
declare function useFeedback(): FeedbackContextValue;
|
|
199
|
+
|
|
200
|
+
declare const menuStyles: Record<string, CSSProperties>;
|
|
201
|
+
declare const darkMenuStyles: Record<string, CSSProperties>;
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* Highlight utilities for feedback target elements
|
|
205
|
+
*/
|
|
206
|
+
|
|
207
|
+
/**
|
|
208
|
+
* Default highlight colors
|
|
209
|
+
*/
|
|
210
|
+
declare const defaultHighlightColors: Required<HighlightColors>;
|
|
211
|
+
/**
|
|
212
|
+
* Default container selectors
|
|
213
|
+
*/
|
|
214
|
+
declare const defaultContainerSelectors: string[];
|
|
215
|
+
/**
|
|
216
|
+
* Find the closest container parent element
|
|
217
|
+
*/
|
|
218
|
+
declare function findContainerParent(element: Element, config?: HighlightConfig): Element | null;
|
|
219
|
+
/**
|
|
220
|
+
* Apply highlight to target element
|
|
221
|
+
*/
|
|
222
|
+
declare function highlightTarget(element: Element, colors?: HighlightColors): void;
|
|
223
|
+
/**
|
|
224
|
+
* Apply highlight to container element
|
|
225
|
+
*/
|
|
226
|
+
declare function highlightContainer(element: Element, colors?: HighlightColors): void;
|
|
227
|
+
/**
|
|
228
|
+
* Remove all highlights from the document
|
|
229
|
+
*/
|
|
230
|
+
declare function clearHighlights(): void;
|
|
231
|
+
/**
|
|
232
|
+
* Apply highlights to target element and its container parent
|
|
233
|
+
*/
|
|
234
|
+
declare function applyHighlights(targetElement: Element, config?: HighlightConfig): {
|
|
235
|
+
target: Element;
|
|
236
|
+
container: Element | null;
|
|
237
|
+
};
|
|
238
|
+
|
|
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 };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,239 @@
|
|
|
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';
|
|
4
|
+
import * as react from 'react';
|
|
5
|
+
import { ReactNode, CSSProperties } from 'react';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Configuration for highlight colors
|
|
9
|
+
*/
|
|
10
|
+
interface HighlightColors {
|
|
11
|
+
/** Color for the target element highlight (default: #3b82f6 - blue) */
|
|
12
|
+
targetColor?: string;
|
|
13
|
+
/** Color for the container element highlight (default: #8b5cf6 - purple) */
|
|
14
|
+
containerColor?: string;
|
|
15
|
+
/** Opacity for the target shadow (default: 0.25) */
|
|
16
|
+
targetShadowOpacity?: number;
|
|
17
|
+
/** Opacity for the container shadow (default: 0.1) */
|
|
18
|
+
containerShadowOpacity?: number;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Configuration for highlight behavior
|
|
22
|
+
*/
|
|
23
|
+
interface HighlightConfig {
|
|
24
|
+
/** Whether to show highlights (default: true) */
|
|
25
|
+
enabled?: boolean;
|
|
26
|
+
/** Custom colors for highlights */
|
|
27
|
+
colors?: HighlightColors;
|
|
28
|
+
/** CSS selectors to identify container elements */
|
|
29
|
+
containerSelectors?: string[];
|
|
30
|
+
/** Minimum number of children for an element to be considered a container (default: 2) */
|
|
31
|
+
minChildrenForContainer?: number;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Menu item displayed in the feedback context menu
|
|
35
|
+
*/
|
|
36
|
+
interface FeedbackMenuItem {
|
|
37
|
+
/** Feedback type for this option (use unique identifier for parent items with children) */
|
|
38
|
+
type: FeedbackType;
|
|
39
|
+
/** Display label */
|
|
40
|
+
label: string;
|
|
41
|
+
/** Optional icon */
|
|
42
|
+
icon?: ReactNode;
|
|
43
|
+
/** Whether to show a comment input for this type */
|
|
44
|
+
showComment?: boolean;
|
|
45
|
+
/** Optional role(s) required to see this menu item */
|
|
46
|
+
requiredRoles?: string[];
|
|
47
|
+
/** Child menu items (creates a submenu) */
|
|
48
|
+
children?: FeedbackMenuItem[];
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* User context for role-based menu filtering
|
|
52
|
+
*/
|
|
53
|
+
interface FeedbackUserContext {
|
|
54
|
+
/** User's role(s) */
|
|
55
|
+
roles?: string[];
|
|
56
|
+
/** User ID */
|
|
57
|
+
id?: string;
|
|
58
|
+
/** User email */
|
|
59
|
+
email?: string;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Filter menu items based on user context
|
|
63
|
+
*/
|
|
64
|
+
declare function filterMenuItemsByRole(items: FeedbackMenuItem[], userContext?: FeedbackUserContext): FeedbackMenuItem[];
|
|
65
|
+
/**
|
|
66
|
+
* Props for the FeedbackProvider component
|
|
67
|
+
*/
|
|
68
|
+
interface FeedbackProviderProps {
|
|
69
|
+
/** The adapter to use for submitting feedback */
|
|
70
|
+
adapter: FeedbackAdapter;
|
|
71
|
+
/** Child components */
|
|
72
|
+
children: ReactNode;
|
|
73
|
+
/**
|
|
74
|
+
* Filter function to determine if feedback should be captured for a target element
|
|
75
|
+
* Return true to allow feedback, false to ignore
|
|
76
|
+
*/
|
|
77
|
+
targetFilter?: (event: MouseEvent, target: Element) => boolean;
|
|
78
|
+
/** Custom menu items (defaults to Issue, Feature, Like) */
|
|
79
|
+
menuItems?: FeedbackMenuItem[];
|
|
80
|
+
/** Maximum length for innerText capture */
|
|
81
|
+
maxInnerTextLength?: number;
|
|
82
|
+
/** Maximum length for outerHTML capture */
|
|
83
|
+
maxOuterHTMLLength?: number;
|
|
84
|
+
/** Maximum number of ancestors to capture */
|
|
85
|
+
maxAncestors?: number;
|
|
86
|
+
/** Cooldown in milliseconds between submissions (rate limiting) */
|
|
87
|
+
cooldownMs?: number;
|
|
88
|
+
/** Attributes to strip from outerHTML for privacy */
|
|
89
|
+
stripAttributes?: string[];
|
|
90
|
+
/** Additional metadata to include with every submission */
|
|
91
|
+
metadata?: Record<string, unknown>;
|
|
92
|
+
/** Callback after successful submission */
|
|
93
|
+
onSubmitSuccess?: (payload: FeedbackPayload) => void;
|
|
94
|
+
/** Callback after failed submission */
|
|
95
|
+
onSubmitError?: (error: Error, payload: FeedbackPayload) => void;
|
|
96
|
+
/** Custom styles for the context menu */
|
|
97
|
+
menuStyle?: CSSProperties;
|
|
98
|
+
/** Custom class name for the context menu */
|
|
99
|
+
menuClassName?: string;
|
|
100
|
+
/** Whether the provider is disabled */
|
|
101
|
+
disabled?: boolean;
|
|
102
|
+
/** Configuration for element highlighting */
|
|
103
|
+
highlightConfig?: HighlightConfig;
|
|
104
|
+
/** Configuration for screenshot capture */
|
|
105
|
+
screenshotConfig?: ScreenshotConfig;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Context value exposed by FeedbackProvider
|
|
109
|
+
*/
|
|
110
|
+
interface FeedbackContextValue {
|
|
111
|
+
/** Whether feedback is currently enabled */
|
|
112
|
+
isEnabled: boolean;
|
|
113
|
+
/** Whether a submission is in progress */
|
|
114
|
+
isSubmitting: boolean;
|
|
115
|
+
/** Submit feedback for a specific element */
|
|
116
|
+
submitFeedback: (element: Element, type: FeedbackType, comment?: string) => Promise<void>;
|
|
117
|
+
/** Open the feedback menu programmatically */
|
|
118
|
+
openMenu: (element: Element, position: {
|
|
119
|
+
x: number;
|
|
120
|
+
y: number;
|
|
121
|
+
}) => void;
|
|
122
|
+
/** Close the feedback menu */
|
|
123
|
+
closeMenu: () => void;
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Props for the context menu component
|
|
127
|
+
*/
|
|
128
|
+
interface ContextMenuProps {
|
|
129
|
+
/** Whether the menu is visible */
|
|
130
|
+
visible: boolean;
|
|
131
|
+
/** Position of the menu */
|
|
132
|
+
position: {
|
|
133
|
+
x: number;
|
|
134
|
+
y: number;
|
|
135
|
+
};
|
|
136
|
+
/** Target element for feedback */
|
|
137
|
+
targetElement: Element | null;
|
|
138
|
+
/** Container element found by highlight logic */
|
|
139
|
+
containerElement: Element | null;
|
|
140
|
+
/** Menu items to display */
|
|
141
|
+
items: FeedbackMenuItem[];
|
|
142
|
+
/** Callback when an item is selected */
|
|
143
|
+
onSelect: (type: FeedbackType, comment?: string, screenshots?: ScreenshotData) => void;
|
|
144
|
+
/** Callback when menu is closed */
|
|
145
|
+
onClose: () => void;
|
|
146
|
+
/** Whether submission is in progress */
|
|
147
|
+
isSubmitting: boolean;
|
|
148
|
+
/** Custom styles */
|
|
149
|
+
style?: CSSProperties;
|
|
150
|
+
/** Custom class name */
|
|
151
|
+
className?: string;
|
|
152
|
+
/** Configuration for element highlighting */
|
|
153
|
+
highlightConfig?: HighlightConfig;
|
|
154
|
+
/** Configuration for screenshot capture */
|
|
155
|
+
screenshotConfig?: ScreenshotConfig;
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Props for the screenshot preview component
|
|
159
|
+
*/
|
|
160
|
+
interface ScreenshotPreviewProps {
|
|
161
|
+
/** Captured screenshot data */
|
|
162
|
+
screenshots: ScreenshotData | null;
|
|
163
|
+
/** Whether screenshots are loading */
|
|
164
|
+
isLoading: boolean;
|
|
165
|
+
/** Callback when user confirms screenshots */
|
|
166
|
+
onConfirm: (screenshots: ScreenshotData) => void;
|
|
167
|
+
/** Callback when user cancels */
|
|
168
|
+
onCancel: () => void;
|
|
169
|
+
/** Callback when user wants to retake screenshots */
|
|
170
|
+
onRetake: () => void;
|
|
171
|
+
/** Whether submission is in progress */
|
|
172
|
+
isSubmitting: boolean;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* FeedbackProvider component - wraps your app to enable feedback capture
|
|
177
|
+
*/
|
|
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;
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* Context menu component for selecting feedback type
|
|
182
|
+
*/
|
|
183
|
+
declare function ContextMenu({ visible, position, targetElement, containerElement, items, onSelect, onClose, isSubmitting, style, className, highlightConfig, screenshotConfig, }: ContextMenuProps): react_jsx_runtime.JSX.Element | null;
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* Screenshot preview component - shows captured screenshots before sending
|
|
187
|
+
*/
|
|
188
|
+
declare function ScreenshotPreview({ screenshots, isLoading, onConfirm, onCancel, onRetake, isSubmitting, }: ScreenshotPreviewProps): react_jsx_runtime.JSX.Element;
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* React context for feedback functionality
|
|
192
|
+
*/
|
|
193
|
+
declare const FeedbackContext: react.Context<FeedbackContextValue | null>;
|
|
194
|
+
/**
|
|
195
|
+
* Hook to access feedback context
|
|
196
|
+
* @throws Error if used outside of FeedbackProvider
|
|
197
|
+
*/
|
|
198
|
+
declare function useFeedback(): FeedbackContextValue;
|
|
199
|
+
|
|
200
|
+
declare const menuStyles: Record<string, CSSProperties>;
|
|
201
|
+
declare const darkMenuStyles: Record<string, CSSProperties>;
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* Highlight utilities for feedback target elements
|
|
205
|
+
*/
|
|
206
|
+
|
|
207
|
+
/**
|
|
208
|
+
* Default highlight colors
|
|
209
|
+
*/
|
|
210
|
+
declare const defaultHighlightColors: Required<HighlightColors>;
|
|
211
|
+
/**
|
|
212
|
+
* Default container selectors
|
|
213
|
+
*/
|
|
214
|
+
declare const defaultContainerSelectors: string[];
|
|
215
|
+
/**
|
|
216
|
+
* Find the closest container parent element
|
|
217
|
+
*/
|
|
218
|
+
declare function findContainerParent(element: Element, config?: HighlightConfig): Element | null;
|
|
219
|
+
/**
|
|
220
|
+
* Apply highlight to target element
|
|
221
|
+
*/
|
|
222
|
+
declare function highlightTarget(element: Element, colors?: HighlightColors): void;
|
|
223
|
+
/**
|
|
224
|
+
* Apply highlight to container element
|
|
225
|
+
*/
|
|
226
|
+
declare function highlightContainer(element: Element, colors?: HighlightColors): void;
|
|
227
|
+
/**
|
|
228
|
+
* Remove all highlights from the document
|
|
229
|
+
*/
|
|
230
|
+
declare function clearHighlights(): void;
|
|
231
|
+
/**
|
|
232
|
+
* Apply highlights to target element and its container parent
|
|
233
|
+
*/
|
|
234
|
+
declare function applyHighlights(targetElement: Element, config?: HighlightConfig): {
|
|
235
|
+
target: Element;
|
|
236
|
+
container: Element | null;
|
|
237
|
+
};
|
|
238
|
+
|
|
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 };
|