@qaiddev/quests-embed 1.2.0 → 1.3.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 +21 -0
- package/dist/embed.d.ts +4 -0
- package/dist/qaid-quests.js +22 -4
- package/dist/qaid-quests.js.map +1 -1
- package/dist/qaid-quests.umd.cjs +2 -2
- package/dist/qaid-quests.umd.cjs.map +1 -1
- package/dist/types.d.ts +23 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -246,6 +246,27 @@ We offer a Free Plan that hosts both the endpoint and a dashboard for managing y
|
|
|
246
246
|
| `saveDebounceMs` | `number` | `500` | Debounce in ms for autosave on text/currency/range |
|
|
247
247
|
| `autoFocus` | `boolean` | `true` | Auto-focus the input on each step. Set `false` in preview/embedded contexts that shouldn't steal focus |
|
|
248
248
|
|
|
249
|
+
### Host integration
|
|
250
|
+
|
|
251
|
+
For programmatic embedding — e.g. launching a quest from another widget — these hooks let the host pass correlation data in and react to the quest's lifecycle. They're only useful when you construct `QaidQuests` yourself (not via the auto-init `<script>` tag).
|
|
252
|
+
|
|
253
|
+
| Option | Type | Default | Description |
|
|
254
|
+
|--------|------|---------|-------------|
|
|
255
|
+
| `metadata` | `Record<string, unknown>` | — | Extra key/value pairs sent verbatim in the create-response `POST` body. The server decides which keys it persists; unknown keys are ignored. Used, for example, by `@qaiddev/thumbs-embed` to pass `{ feedbackId }` so the QAid backend joins the quest answers to the feedback record. |
|
|
256
|
+
| `onComplete` | `(answers) => void` | — | Called once when the quest is completed and submitted (just after the thank-you screen renders), with a copy of the collected answers. Fires in both modal and inline modes. |
|
|
257
|
+
| `onClose` | `() => void` | — | Called once when the embed is torn down — visitor close, host `destroy()`, or teardown after completion. Lets a host that launched the quest drop its reference. |
|
|
258
|
+
|
|
259
|
+
```typescript
|
|
260
|
+
const quest = new QaidQuests({
|
|
261
|
+
endpoint: 'https://qaid.dev/api/quests/responses',
|
|
262
|
+
configUrl: 'https://qaid.dev/api/quests/<questId>/definition',
|
|
263
|
+
apiKey: 'YOUR_API_KEY',
|
|
264
|
+
metadata: { feedbackId: 'clx…' }, // correlate this response server-side
|
|
265
|
+
onComplete: (answers) => console.log('done', answers),
|
|
266
|
+
onClose: () => { /* drop your reference */ },
|
|
267
|
+
});
|
|
268
|
+
```
|
|
269
|
+
|
|
249
270
|
### Appearance
|
|
250
271
|
|
|
251
272
|
| Option | Type | Default | Description |
|
package/dist/embed.d.ts
CHANGED
|
@@ -40,6 +40,10 @@ export declare class QaidQuests {
|
|
|
40
40
|
private themeUrl;
|
|
41
41
|
private themeDocument;
|
|
42
42
|
private hostCss;
|
|
43
|
+
private metadata;
|
|
44
|
+
private onCompleteCb;
|
|
45
|
+
private onCloseCb;
|
|
46
|
+
private closed;
|
|
43
47
|
constructor(config: QuestsConfig);
|
|
44
48
|
private init;
|
|
45
49
|
private loadTheme;
|
package/dist/qaid-quests.js
CHANGED
|
@@ -487,6 +487,13 @@ class he {
|
|
|
487
487
|
themeUrl;
|
|
488
488
|
themeDocument;
|
|
489
489
|
hostCss;
|
|
490
|
+
// Host integration hooks (see QuestsConfig). Kept off the resolved
|
|
491
|
+
// value-config since they're behaviour, not render tokens.
|
|
492
|
+
metadata;
|
|
493
|
+
onCompleteCb;
|
|
494
|
+
onCloseCb;
|
|
495
|
+
// Guards onClose to fire exactly once even if destroy() runs twice.
|
|
496
|
+
closed = !1;
|
|
490
497
|
constructor(e) {
|
|
491
498
|
this.config = {
|
|
492
499
|
endpoint: e.endpoint,
|
|
@@ -531,7 +538,7 @@ class he {
|
|
|
531
538
|
backdropOpacity: e.backdropOpacity,
|
|
532
539
|
fontFamily: e.fontFamily,
|
|
533
540
|
fontSize: e.fontSize
|
|
534
|
-
}, this.themeUrl = e.themeUrl, this.themeDocument = e.themeDocument, this.hostCss = e.css ?? "", this.inlineQuestionnaire = e.questionnaire, this.configUrl = e.configUrl, this.visitorId = le(), this.boundKeyDown = this.handleKeyDown.bind(this), this.init();
|
|
541
|
+
}, this.themeUrl = e.themeUrl, this.themeDocument = e.themeDocument, this.hostCss = e.css ?? "", this.metadata = e.metadata, this.onCompleteCb = e.onComplete, this.onCloseCb = e.onClose, this.inlineQuestionnaire = e.questionnaire, this.configUrl = e.configUrl, this.visitorId = le(), this.boundKeyDown = this.handleKeyDown.bind(this), this.init();
|
|
535
542
|
}
|
|
536
543
|
async init() {
|
|
537
544
|
this.cssVars = P(this.hostInlineVars), this.mountShell(), this.renderLoading();
|
|
@@ -850,7 +857,8 @@ ${r}
|
|
|
850
857
|
questId: this.questionnaire?.id,
|
|
851
858
|
pageUrl: window.location.href,
|
|
852
859
|
visitorId: this.visitorId,
|
|
853
|
-
userAgent: navigator.userAgent
|
|
860
|
+
userAgent: navigator.userAgent,
|
|
861
|
+
metadata: this.metadata
|
|
854
862
|
})
|
|
855
863
|
});
|
|
856
864
|
if (e.ok) {
|
|
@@ -874,7 +882,12 @@ ${r}
|
|
|
874
882
|
} catch (e) {
|
|
875
883
|
console.error("[quests-embed] failed to submit:", e);
|
|
876
884
|
}
|
|
877
|
-
this.state = "DONE", this.renderDone()
|
|
885
|
+
if (this.state = "DONE", this.renderDone(), this.onCompleteCb)
|
|
886
|
+
try {
|
|
887
|
+
this.onCompleteCb({ ...this.answers });
|
|
888
|
+
} catch (e) {
|
|
889
|
+
console.error("[quests-embed] onComplete handler threw:", e);
|
|
890
|
+
}
|
|
878
891
|
}
|
|
879
892
|
jsonHeaders() {
|
|
880
893
|
const e = {
|
|
@@ -906,7 +919,12 @@ ${r}
|
|
|
906
919
|
}
|
|
907
920
|
/** Destroy the embed and clean up all resources */
|
|
908
921
|
destroy() {
|
|
909
|
-
document.removeEventListener("keydown", this.boundKeyDown), this.pendingSaveTimer && (clearTimeout(this.pendingSaveTimer), this.pendingSaveTimer = null), this.focusTrap && (this.focusTrap.release(), this.focusTrap = null), this.inertRestore && (this.inertRestore(), this.inertRestore = null), !this.isUserContainer && this.savedOpener && re(this.savedOpener), this.savedOpener = null, this.shadowHost && (this.shadowHost.remove(), this.shadowHost = null, this.shadowRoot = null), this.rootEl = null, this.cardEl = null, this.bodyEl = null, this.footerEl = null, this.titleEl = null, this.stepCounterEl = null, this.progressFillEl = null, this.savingEl = null, this.backdropEl = null, this.currentInput = null
|
|
922
|
+
if (document.removeEventListener("keydown", this.boundKeyDown), this.pendingSaveTimer && (clearTimeout(this.pendingSaveTimer), this.pendingSaveTimer = null), this.focusTrap && (this.focusTrap.release(), this.focusTrap = null), this.inertRestore && (this.inertRestore(), this.inertRestore = null), !this.isUserContainer && this.savedOpener && re(this.savedOpener), this.savedOpener = null, this.shadowHost && (this.shadowHost.remove(), this.shadowHost = null, this.shadowRoot = null), this.rootEl = null, this.cardEl = null, this.bodyEl = null, this.footerEl = null, this.titleEl = null, this.stepCounterEl = null, this.progressFillEl = null, this.savingEl = null, this.backdropEl = null, this.currentInput = null, !this.closed && (this.closed = !0, this.onCloseCb))
|
|
923
|
+
try {
|
|
924
|
+
this.onCloseCb();
|
|
925
|
+
} catch (e) {
|
|
926
|
+
console.error("[quests-embed] onClose handler threw:", e);
|
|
927
|
+
}
|
|
910
928
|
}
|
|
911
929
|
/** Read-only snapshot of current answers */
|
|
912
930
|
getAnswers() {
|