@qaiddev/thumbs-embed 1.0.10 → 1.0.12
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/console-capture.d.ts +20 -0
- package/dist/dom-utils.d.ts +37 -0
- package/dist/element-selector.d.ts +33 -0
- package/dist/embed.d.ts +109 -0
- package/dist/icons.d.ts +6 -0
- package/dist/index.d.ts +38 -425
- package/dist/modal-positioning.d.ts +46 -0
- package/dist/network-capture.d.ts +13 -0
- package/dist/qaid.js +145 -122
- package/dist/qaid.js.map +1 -1
- package/dist/qaid.umd.cjs +5 -5
- package/dist/qaid.umd.cjs.map +1 -1
- package/dist/screenshot-dom.d.ts +27 -0
- package/dist/screenshot.d.ts +17 -0
- package/dist/styles.d.ts +44 -0
- package/dist/types.d.ts +237 -0
- package/dist/video-capture.d.ts +34 -0
- package/package.json +2 -3
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DOM-based screenshot capture using html2canvas
|
|
3
|
+
* No browser permission dialog required - reconstructs the page from the DOM
|
|
4
|
+
*/
|
|
5
|
+
export interface DomScreenshotOptions {
|
|
6
|
+
/** Quality of WebP compression (0-1). Default: 0.8 */
|
|
7
|
+
quality?: number;
|
|
8
|
+
/** Max width of the screenshot. Default: 1280 */
|
|
9
|
+
maxWidth?: number;
|
|
10
|
+
/** Max height of the screenshot. Default: 800 */
|
|
11
|
+
maxHeight?: number;
|
|
12
|
+
}
|
|
13
|
+
declare global {
|
|
14
|
+
interface Window {
|
|
15
|
+
html2canvas?: (element: HTMLElement, options?: Record<string, unknown>) => Promise<HTMLCanvasElement>;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Check if DOM screenshot capture is supported
|
|
20
|
+
* Requires canvas and basic DOM APIs
|
|
21
|
+
*/
|
|
22
|
+
export declare function isDomScreenshotSupported(): boolean;
|
|
23
|
+
/**
|
|
24
|
+
* Capture a screenshot of the current page using html2canvas
|
|
25
|
+
* Returns a base64-encoded WebP data URL, or null on failure
|
|
26
|
+
*/
|
|
27
|
+
export declare function captureDomScreenshot(options?: DomScreenshotOptions): Promise<string | null>;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Screenshot capture utility using native Screen Capture API
|
|
3
|
+
*/
|
|
4
|
+
export interface ScreenshotOptions {
|
|
5
|
+
/** Quality of WebP compression (0-1). Default: 1.0 */
|
|
6
|
+
quality?: number;
|
|
7
|
+
/** Max width of the screenshot. Default: 1280 */
|
|
8
|
+
maxWidth?: number;
|
|
9
|
+
/** Max height of the screenshot. Default: 800 */
|
|
10
|
+
maxHeight?: number;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Captures a screenshot using the native Screen Capture API
|
|
14
|
+
* Requires user permission but produces accurate results
|
|
15
|
+
* Returns a base64-encoded WebP data URL
|
|
16
|
+
*/
|
|
17
|
+
export declare function captureScreenshot(options?: ScreenshotOptions): Promise<string | null>;
|
package/dist/styles.d.ts
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CSS styles for the feedback embed
|
|
3
|
+
* Uses .qaid- prefix to avoid conflicts
|
|
4
|
+
*/
|
|
5
|
+
export interface BuildCssVarsOptions {
|
|
6
|
+
positiveColor?: string;
|
|
7
|
+
negativeColor?: string;
|
|
8
|
+
/** Color for selected element marker */
|
|
9
|
+
markerColor?: string;
|
|
10
|
+
/** Button size: small (36px), medium (48px), large (64px) */
|
|
11
|
+
buttonSize?: "small" | "medium" | "large";
|
|
12
|
+
/** Modal width in pixels */
|
|
13
|
+
modalWidth?: number;
|
|
14
|
+
/** Backdrop opacity (0-1) */
|
|
15
|
+
backdropOpacity?: number;
|
|
16
|
+
/** Font family */
|
|
17
|
+
fontFamily?: string;
|
|
18
|
+
/** Base font size in pixels */
|
|
19
|
+
fontSize?: number;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Build a map of CSS variable names to values for per-instance scoping
|
|
23
|
+
*/
|
|
24
|
+
export declare function buildCssVars(options?: BuildCssVarsOptions): Record<string, string>;
|
|
25
|
+
/**
|
|
26
|
+
* Apply CSS variables to an element via inline style properties
|
|
27
|
+
*/
|
|
28
|
+
export declare function applyCssVars(el: HTMLElement, vars: Record<string, string>): void;
|
|
29
|
+
/**
|
|
30
|
+
* Get the CSS string to inject into a shadow root
|
|
31
|
+
* Includes base shadow styles + default button styles
|
|
32
|
+
*/
|
|
33
|
+
export declare function getEmbedStyles(): string;
|
|
34
|
+
/**
|
|
35
|
+
* Inject light DOM styles (cursor override + highlight)
|
|
36
|
+
* Reference-counted across instances
|
|
37
|
+
*/
|
|
38
|
+
export declare function injectStyles(): void;
|
|
39
|
+
/**
|
|
40
|
+
* Remove light DOM styles when last instance is destroyed
|
|
41
|
+
*/
|
|
42
|
+
export declare function removeStyles(): void;
|
|
43
|
+
/** Reset internal state — for tests only */
|
|
44
|
+
export declare function _resetStylesState(): void;
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Configuration options for the QaidFeedback
|
|
3
|
+
*/
|
|
4
|
+
export interface FeedbackConfig {
|
|
5
|
+
/** Required: API endpoint URL for submitting feedback */
|
|
6
|
+
endpoint: string;
|
|
7
|
+
/** API key for authenticating with the feedback service */
|
|
8
|
+
apiKey?: string;
|
|
9
|
+
/** CSS selector for user-provided container element. If not provided, creates fixed-position container */
|
|
10
|
+
container?: string;
|
|
11
|
+
/** Custom CSS class to apply to thumb buttons. When provided, default button styles are not applied */
|
|
12
|
+
buttonClass?: string;
|
|
13
|
+
/** Button layout direction. Default: 'horizontal' */
|
|
14
|
+
direction?: "horizontal" | "vertical";
|
|
15
|
+
/** Position of the feedback buttons. Default: 'bottom-right'. Ignored if container is provided */
|
|
16
|
+
position?: "bottom-right" | "bottom-left" | "top-right" | "top-left";
|
|
17
|
+
/** Offset from edge in pixels. Default: { x: 16, y: 16 } */
|
|
18
|
+
offset?: {
|
|
19
|
+
x?: number;
|
|
20
|
+
y?: number;
|
|
21
|
+
};
|
|
22
|
+
/** z-index for the embed elements. Default: 50 */
|
|
23
|
+
zIndex?: number;
|
|
24
|
+
/** When true, skip element targeting and go directly to feedback modal. Default: false */
|
|
25
|
+
skipTargeting?: boolean;
|
|
26
|
+
/** Custom colors for feedback types */
|
|
27
|
+
colors?: {
|
|
28
|
+
/** Color for positive feedback. Default: rgb(0, 200, 83) */
|
|
29
|
+
positive?: string;
|
|
30
|
+
/** Color for negative feedback. Default: rgb(255, 0, 0) */
|
|
31
|
+
negative?: string;
|
|
32
|
+
/** Color for selected element marker. Default: #6366f1 */
|
|
33
|
+
marker?: string;
|
|
34
|
+
};
|
|
35
|
+
/** Button size. Default: 'medium' (48px). Small: 36px, Large: 64px */
|
|
36
|
+
buttonSize?: "small" | "medium" | "large";
|
|
37
|
+
/** Custom text labels */
|
|
38
|
+
text?: {
|
|
39
|
+
/** Tooltip text for buttons */
|
|
40
|
+
tooltip?: string;
|
|
41
|
+
/** Modal title */
|
|
42
|
+
modalTitle?: string;
|
|
43
|
+
/** Modal subtitle */
|
|
44
|
+
modalSubtitle?: string;
|
|
45
|
+
/** Textarea placeholder */
|
|
46
|
+
placeholder?: string;
|
|
47
|
+
/** Submit button text */
|
|
48
|
+
submitButton?: string;
|
|
49
|
+
/** Skip button text */
|
|
50
|
+
skipButton?: string;
|
|
51
|
+
};
|
|
52
|
+
/** Modal width in pixels. Default: 400 */
|
|
53
|
+
modalWidth?: number;
|
|
54
|
+
/** Backdrop opacity (0-1). Default: 0.3 */
|
|
55
|
+
backdropOpacity?: number;
|
|
56
|
+
/** Font family for text elements. Default: system-ui, -apple-system, sans-serif */
|
|
57
|
+
fontFamily?: string;
|
|
58
|
+
/** Base font size in pixels. Default: 16 */
|
|
59
|
+
fontSize?: number;
|
|
60
|
+
/** Enable screenshot capture with feedback. Default: false */
|
|
61
|
+
captureScreenshot?: boolean;
|
|
62
|
+
/** Enable video recording button. Default: false */
|
|
63
|
+
captureVideo?: boolean;
|
|
64
|
+
/** Video recording options */
|
|
65
|
+
videoOptions?: {
|
|
66
|
+
/** Max recording duration in seconds. Default: 15 */
|
|
67
|
+
maxDuration?: number;
|
|
68
|
+
};
|
|
69
|
+
/** Custom SVG string for record button icon */
|
|
70
|
+
recordIcon?: string;
|
|
71
|
+
/** When true, buttons are hidden until hovered. Default: false */
|
|
72
|
+
incognito?: boolean;
|
|
73
|
+
/** Custom SVG string for positive feedback button icon */
|
|
74
|
+
positiveIcon?: string;
|
|
75
|
+
/** Custom SVG string for negative feedback button icon */
|
|
76
|
+
negativeIcon?: string;
|
|
77
|
+
/** When true, hide thumbs up/down buttons (only show video button if enabled). Default: false */
|
|
78
|
+
hideThumbs?: boolean;
|
|
79
|
+
/** Custom CSS to inject into the embed's shadow root for theming */
|
|
80
|
+
css?: string;
|
|
81
|
+
/** Screenshot capture method. "dom" uses html2canvas (no permission), "permission" uses Screen Capture API. Default: "permission" */
|
|
82
|
+
screenshotMethod?: "dom" | "permission";
|
|
83
|
+
/** Screenshot options */
|
|
84
|
+
screenshotOptions?: {
|
|
85
|
+
/** Quality of WebP compression (0-1). Default: 1.0 */
|
|
86
|
+
quality?: number;
|
|
87
|
+
/** Max width of the screenshot. Default: 1280 */
|
|
88
|
+
maxWidth?: number;
|
|
89
|
+
/** Max height of the screenshot. Default: 800 */
|
|
90
|
+
maxHeight?: number;
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Network error captured during the session
|
|
95
|
+
*/
|
|
96
|
+
export interface NetworkError {
|
|
97
|
+
url: string;
|
|
98
|
+
method: string;
|
|
99
|
+
status: number;
|
|
100
|
+
statusText: string;
|
|
101
|
+
requestBody?: string;
|
|
102
|
+
responseBody?: string;
|
|
103
|
+
timestamp: number;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Console message captured during the session
|
|
107
|
+
*/
|
|
108
|
+
export interface ConsoleError {
|
|
109
|
+
message: string;
|
|
110
|
+
timestamp: number;
|
|
111
|
+
level: "error" | "warn" | "log";
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Bounds of the selected element
|
|
115
|
+
*/
|
|
116
|
+
export interface SelectedBounds {
|
|
117
|
+
x: number;
|
|
118
|
+
y: number;
|
|
119
|
+
width: number;
|
|
120
|
+
height: number;
|
|
121
|
+
clickX: number;
|
|
122
|
+
clickY: number;
|
|
123
|
+
visible: boolean;
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Current feedback data being collected
|
|
127
|
+
*/
|
|
128
|
+
export interface FeedbackData {
|
|
129
|
+
feedbackType: "up" | "down" | null;
|
|
130
|
+
elementSelector: string | null;
|
|
131
|
+
elementText: string | null;
|
|
132
|
+
consoleErrors: ConsoleError[];
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* State machine states for the embed
|
|
136
|
+
*/
|
|
137
|
+
export type EmbedState = "IDLE" | "TARGETING" | "SELECTED" | "MODAL_OPEN";
|
|
138
|
+
/**
|
|
139
|
+
* Element bounds for server-side screenshot fallback
|
|
140
|
+
*/
|
|
141
|
+
export interface ElementBounds {
|
|
142
|
+
x: number;
|
|
143
|
+
y: number;
|
|
144
|
+
width: number;
|
|
145
|
+
height: number;
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Payload sent to the feedback API
|
|
149
|
+
*/
|
|
150
|
+
export interface FeedbackPayload {
|
|
151
|
+
feedbackType: "up" | "down";
|
|
152
|
+
pageUrl: string;
|
|
153
|
+
/** API key for authenticating with the feedback service */
|
|
154
|
+
apiKey?: string;
|
|
155
|
+
elementSelector: string | null;
|
|
156
|
+
elementText: string | null;
|
|
157
|
+
consoleErrors: ConsoleError[];
|
|
158
|
+
screenWidth: number;
|
|
159
|
+
screenHeight: number;
|
|
160
|
+
clickX: number;
|
|
161
|
+
clickY: number;
|
|
162
|
+
scrollX: number;
|
|
163
|
+
scrollY: number;
|
|
164
|
+
/** Base64-encoded screenshot image (WebP) */
|
|
165
|
+
screenshot: string | null;
|
|
166
|
+
/** Random UUID stored in visitor's localStorage (for anonymous feedback) */
|
|
167
|
+
visitorId: string;
|
|
168
|
+
/** Element bounds for server-side screenshot fallback when client screenshot fails */
|
|
169
|
+
elementBounds?: ElementBounds | null;
|
|
170
|
+
/** User agent string for server-side rendering consistency */
|
|
171
|
+
userAgent?: string;
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Response from the feedback API
|
|
175
|
+
*/
|
|
176
|
+
export interface FeedbackResponse {
|
|
177
|
+
id: number;
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Payload for updating feedback with a message
|
|
181
|
+
*/
|
|
182
|
+
export interface FeedbackMessagePayload {
|
|
183
|
+
message: string | null;
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Fully resolved configuration with all defaults applied
|
|
187
|
+
* Used internally by the embed after processing user config
|
|
188
|
+
*/
|
|
189
|
+
export interface ResolvedFeedbackConfig {
|
|
190
|
+
endpoint: string;
|
|
191
|
+
apiKey: string;
|
|
192
|
+
container: string;
|
|
193
|
+
buttonClass: string;
|
|
194
|
+
direction: "horizontal" | "vertical";
|
|
195
|
+
position: "bottom-right" | "bottom-left" | "top-right" | "top-left";
|
|
196
|
+
offset: {
|
|
197
|
+
x: number;
|
|
198
|
+
y: number;
|
|
199
|
+
};
|
|
200
|
+
zIndex: number;
|
|
201
|
+
skipTargeting: boolean;
|
|
202
|
+
colors: {
|
|
203
|
+
positive: string;
|
|
204
|
+
negative: string;
|
|
205
|
+
marker: string;
|
|
206
|
+
};
|
|
207
|
+
buttonSize: "small" | "medium" | "large";
|
|
208
|
+
text: {
|
|
209
|
+
tooltip: string;
|
|
210
|
+
modalTitle: string;
|
|
211
|
+
modalSubtitle: string;
|
|
212
|
+
placeholder: string;
|
|
213
|
+
submitButton: string;
|
|
214
|
+
skipButton: string;
|
|
215
|
+
};
|
|
216
|
+
modalWidth: number;
|
|
217
|
+
backdropOpacity: number;
|
|
218
|
+
fontFamily: string;
|
|
219
|
+
fontSize: number;
|
|
220
|
+
captureScreenshot: boolean;
|
|
221
|
+
screenshotMethod: "dom" | "permission";
|
|
222
|
+
screenshotOptions: {
|
|
223
|
+
quality: number;
|
|
224
|
+
maxWidth: number;
|
|
225
|
+
maxHeight: number;
|
|
226
|
+
};
|
|
227
|
+
incognito: boolean;
|
|
228
|
+
positiveIcon: string;
|
|
229
|
+
negativeIcon: string;
|
|
230
|
+
hideThumbs: boolean;
|
|
231
|
+
css: string;
|
|
232
|
+
captureVideo: boolean;
|
|
233
|
+
videoOptions: {
|
|
234
|
+
maxDuration: number;
|
|
235
|
+
};
|
|
236
|
+
recordIcon: string;
|
|
237
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Video capture utilities
|
|
3
|
+
* Uses getDisplayMedia + MediaRecorder for screen recording
|
|
4
|
+
*/
|
|
5
|
+
export interface VideoRecorderOptions {
|
|
6
|
+
/** Max recording duration in seconds. Default: 15 */
|
|
7
|
+
maxDuration?: number;
|
|
8
|
+
/** Video bitrate in bps. Default: 800000 (800kbps) */
|
|
9
|
+
videoBitsPerSecond?: number;
|
|
10
|
+
}
|
|
11
|
+
export interface VideoRecorder {
|
|
12
|
+
/** Start recording. Requests getDisplayMedia if not already started. */
|
|
13
|
+
start(): Promise<void>;
|
|
14
|
+
/** Stop recording and return the video blob. */
|
|
15
|
+
stop(): Promise<Blob>;
|
|
16
|
+
/** Register a callback for each second tick (receives seconds elapsed). */
|
|
17
|
+
onTick(callback: (elapsed: number) => void): void;
|
|
18
|
+
/** Register a callback for when recording stops (e.g., browser stop button, max duration). */
|
|
19
|
+
onStop(callback: (blob: Blob | null) => void): void;
|
|
20
|
+
/** Clean up all resources. */
|
|
21
|
+
destroy(): void;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Check if video recording is supported in this browser
|
|
25
|
+
*/
|
|
26
|
+
export declare function isVideoRecordingSupported(): boolean;
|
|
27
|
+
/**
|
|
28
|
+
* Detect the best supported MIME type for recording
|
|
29
|
+
*/
|
|
30
|
+
export declare function getSupportedMimeType(): string;
|
|
31
|
+
/**
|
|
32
|
+
* Create a video recorder that captures the screen
|
|
33
|
+
*/
|
|
34
|
+
export declare function createVideoRecorder(options?: VideoRecorderOptions): VideoRecorder;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@qaiddev/thumbs-embed",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.12",
|
|
4
4
|
"description": "Precision User Feedback",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/qaid.umd.cjs",
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
},
|
|
27
27
|
"scripts": {
|
|
28
28
|
"dev": "vite build --watch",
|
|
29
|
-
"build": "vite build",
|
|
29
|
+
"build": "vite build && tsc -p tsconfig.build.json",
|
|
30
30
|
"preview": "vite preview",
|
|
31
31
|
"test": "vitest",
|
|
32
32
|
"test:run": "vitest run"
|
|
@@ -36,7 +36,6 @@
|
|
|
36
36
|
"happy-dom": "^20.5.1",
|
|
37
37
|
"typescript": "^5.3.3",
|
|
38
38
|
"vite": "^7.3.1",
|
|
39
|
-
"vite-plugin-dts": "^4.5.4",
|
|
40
39
|
"vitest": "^4.0.18"
|
|
41
40
|
},
|
|
42
41
|
"keywords": [
|