@qaiddev/thumbs-embed 1.1.1 → 1.2.1

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
@@ -173,6 +173,29 @@ new QaidEmbed({
173
173
 
174
174
  Screenshots use the browser's Screen Capture API. The user will see a permission dialog. If they decline or the API is unavailable, the feedback is still submitted without a screenshot.
175
175
 
176
+ ### Linking buttons to quests
177
+
178
+ Instead of the optional message box, a button can open a **quest** — a short questionnaire powered by [`@qaiddev/quests-embed`](https://www.npmjs.com/package/@qaiddev/quests-embed). You can ask one set of questions after a thumbs-up, a different set after a thumbs-down, and another after a video recording is sent. The quest widget is loaded on demand from a CDN the first time it's needed, so the thumbs bundle stays zero-dependency; if it can't load, the classic message box is shown instead.
179
+
180
+ ```typescript
181
+ new QaidEmbed({
182
+ endpoint: 'https://qaid.dev/api/feedback',
183
+ apiKey: 'YOUR_API_KEY',
184
+ captureVideo: true,
185
+ quests: {
186
+ // Base URL of the quest service. Required to enable the feature.
187
+ base: 'https://qaid.dev/api/quests',
188
+ up: 'QUEST_ID_FOR_THUMBS_UP', // optional, per button
189
+ down: 'QUEST_ID_FOR_THUMBS_DOWN',
190
+ video: 'QUEST_ID_AFTER_VIDEO',
191
+ // apiKey defaults to the top-level apiKey; override only if different.
192
+ // moduleUrl overrides where the quests widget is loaded from.
193
+ },
194
+ });
195
+ ```
196
+
197
+ `base` is the only required field — omit a button's id to keep the normal message box for that button. The embed derives the quest definition URL (`{base}/{questId}/definition`) and the response endpoint (`{base}/responses`) from it, and passes the created feedback record's id to the quest so its answers are joined back to that feedback on the server.
198
+
176
199
  ## Script Tag Data Attributes
177
200
 
178
201
  When using the script tag method, all config options are available as `data-*` attributes:
@@ -207,6 +230,12 @@ When using the script tag method, all config options are available as `data-*` a
207
230
  | `data-skip-button` | `text.skipButton` |
208
231
  | `data-positive-icon` | `positiveIcon` |
209
232
  | `data-negative-icon` | `negativeIcon` |
233
+ | `data-quest-base` | `quests.base` |
234
+ | `data-quest-up` | `quests.up` |
235
+ | `data-quest-down` | `quests.down` |
236
+ | `data-quest-video` | `quests.video` |
237
+ | `data-quest-api-key` | `quests.apiKey` |
238
+ | `data-quest-module-url` | `quests.moduleUrl` |
210
239
 
211
240
  ## Custom Button Container
212
241
 
package/dist/embed.d.ts CHANGED
@@ -14,6 +14,7 @@ export declare class QaidFeedback {
14
14
  private feedbackData;
15
15
  private selectedBounds;
16
16
  private feedbackId;
17
+ private activeQuest;
17
18
  private mousePos;
18
19
  private isMobile;
19
20
  private visitorId;
@@ -52,6 +53,9 @@ export declare class QaidFeedback {
52
53
  private boundKeyDown;
53
54
  private boundMouseMove;
54
55
  private boundClick;
56
+ private boundTouchStart;
57
+ private boundTouchEnd;
58
+ private touchStartPos;
55
59
  private boundResize;
56
60
  private _startDismissed;
57
61
  private destroyed;
@@ -114,12 +118,42 @@ export declare class QaidFeedback {
114
118
  private createTargetingOverlay;
115
119
  private handleKeyDown;
116
120
  private handleMouseMove;
121
+ /** Move the crosshair/scope reticle and highlight the element under (x, y).
122
+ * Shared by the mouse (hover) and touch (drag) targeting paths. */
123
+ private updateReticleAt;
117
124
  private handleClick;
125
+ private handleTouchStart;
126
+ private handleTouchEnd;
127
+ /** Select the element under (x, y) and tear down targeting.
128
+ * Shared by the mouse (click) and touch (touchend) targeting paths. */
129
+ private selectAt;
130
+ /** Remove the targeting overlay and every mouse/touch/keyboard listener the
131
+ * pointer-targeting flow attaches to the document. */
132
+ private stopTargetingListeners;
118
133
  private cancelTargeting;
119
134
  private removeTargetingOverlay;
120
135
  private showSelectedMarker;
121
136
  private hideSelectedMarker;
122
137
  private submitFeedback;
138
+ /**
139
+ * Quest id linked to `type`, or "" when quest launching is disabled
140
+ * (no `base`) or this button has no quest configured.
141
+ */
142
+ private questIdFor;
143
+ /**
144
+ * Launch the quest linked to `type`, if any. Resolves `true` when a quest
145
+ * was configured and the widget launched; `false` when no quest is
146
+ * configured or the widget failed to load (caller falls back to its
147
+ * normal UI). The created feedback record id is passed through so the
148
+ * quest response can be joined back to it server-side.
149
+ */
150
+ private tryLaunchQuest;
151
+ /**
152
+ * Reset the thumbs targeting/marker UI back to idle without opening or
153
+ * closing the message modal. Shared by closeModal() and the quest-launch
154
+ * path (which bypasses the modal entirely).
155
+ */
156
+ private resetFeedbackUi;
123
157
  private showModal;
124
158
  private showBottomSheet;
125
159
  private showPositionedModal;
package/dist/index.d.ts CHANGED
@@ -29,7 +29,7 @@
29
29
  */
30
30
  import { QaidFeedback } from "./embed";
31
31
  export { QaidFeedback };
32
- export type { FeedbackConfig, ResolvedFeedbackConfig, ConsoleError, NetworkError, FeedbackData, SelectedBounds, FeedbackPayload, FeedbackResponse, FeedbackMessagePayload, } from "./types";
32
+ export type { FeedbackConfig, QuestsLaunchConfig, ResolvedFeedbackConfig, ConsoleError, NetworkError, FeedbackData, SelectedBounds, FeedbackPayload, FeedbackResponse, FeedbackMessagePayload, } from "./types";
33
33
  export { captureNetworkErrors } from "./network-capture";
34
34
  export type { NetworkCapture } from "./network-capture";
35
35
  export { createVideoRecorder, isVideoRecordingSupported, getSupportedMimeType } from "./video-capture";