@qaiddev/quests-embed 1.6.0 → 1.7.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.
@@ -20,13 +20,13 @@ function ee(t) {
20
20
  const e = t.match(/rgb\((\d+),\s*(\d+),\s*(\d+)\)/);
21
21
  return e ? { r: parseInt(e[1]), g: parseInt(e[2]), b: parseInt(e[3]) } : null;
22
22
  }
23
- function T(t) {
23
+ function N(t) {
24
24
  const e = ee(t);
25
25
  return e && Z(e.r, e.g, e.b) > 0.4 ? "black" : "white";
26
26
  }
27
27
  function te(t = {}) {
28
28
  const e = {};
29
- return t.accentColor !== void 0 && (e["--qaid-q-accent"] = t.accentColor, e["--qaid-q-accent-text"] = T(t.accentColor)), t.errorColor !== void 0 && (e["--qaid-q-error"] = t.errorColor), t.focusColor !== void 0 && (e["--qaid-q-focus"] = t.focusColor, e["--qaid-q-focus-text"] = T(t.focusColor)), t.modalWidth !== void 0 && (e["--qaid-modal-width"] = `${t.modalWidth}px`), t.backdropOpacity !== void 0 && (e["--qaid-backdrop-opacity"] = String(t.backdropOpacity)), t.fontFamily !== void 0 && (e["--qaid-font-family"] = t.fontFamily), t.fontSize !== void 0 && (e["--qaid-font-size"] = `${t.fontSize}px`), e;
29
+ return t.accentColor !== void 0 && (e["--qaid-q-accent"] = t.accentColor, e["--qaid-q-accent-text"] = N(t.accentColor)), t.errorColor !== void 0 && (e["--qaid-q-error"] = t.errorColor), t.focusColor !== void 0 && (e["--qaid-q-focus"] = t.focusColor, e["--qaid-q-focus-text"] = N(t.focusColor)), t.modalWidth !== void 0 && (e["--qaid-modal-width"] = `${t.modalWidth}px`), t.backdropOpacity !== void 0 && (e["--qaid-backdrop-opacity"] = String(t.backdropOpacity)), t.fontFamily !== void 0 && (e["--qaid-font-family"] = t.fontFamily), t.fontSize !== void 0 && (e["--qaid-font-size"] = `${t.fontSize}px`), e;
30
30
  }
31
31
  function ie(t, e) {
32
32
  for (const [i, a] of Object.entries(e))
@@ -38,7 +38,7 @@ function ae() {
38
38
  function ne(t) {
39
39
  return X(t);
40
40
  }
41
- function y(t) {
41
+ function v(t) {
42
42
  let e = null;
43
43
  return {
44
44
  setInvalid(i) {
@@ -104,7 +104,7 @@ function se(t, e) {
104
104
  const n = a.value.trim();
105
105
  return !(n.length === 0 || t.minLength && n.length < t.minLength);
106
106
  },
107
- ...y(a)
107
+ ...v(a)
108
108
  };
109
109
  }
110
110
  function oe(t) {
@@ -147,7 +147,7 @@ function de(t, e) {
147
147
  const r = n.value === "" ? null : Number(n.value);
148
148
  return !(t.required && (r === null || Number.isNaN(r)) || r !== null && !Number.isNaN(r) && (typeof t.min == "number" && r < t.min || typeof t.max == "number" && r > t.max));
149
149
  },
150
- ...y(n)
150
+ ...v(n)
151
151
  };
152
152
  }
153
153
  function le(t, e) {
@@ -169,8 +169,8 @@ function ce(t, e) {
169
169
  a.className = "qaid-q-range-value";
170
170
  const n = document.createElement("span");
171
171
  if (a.appendChild(n), t.unit) {
172
- const l = document.createElement("span");
173
- l.className = "qaid-q-range-unit", l.textContent = t.unit, a.appendChild(l);
172
+ const d = document.createElement("span");
173
+ d.className = "qaid-q-range-unit", d.textContent = t.unit, a.appendChild(d);
174
174
  }
175
175
  const r = typeof e.initialValue == "number" ? e.initialValue : t.defaultValue ?? t.min, s = document.createElement("input");
176
176
  s.className = "qaid-q-range", s.type = "range", s.min = String(t.min), s.max = String(t.max), s.step = String(t.step ?? 1), s.value = String(r), s.setAttribute("aria-label", t.label), s.setAttribute("aria-valuemin", String(t.min)), s.setAttribute("aria-valuemax", String(t.max));
@@ -179,20 +179,20 @@ function ce(t, e) {
179
179
  };
180
180
  o(), s.addEventListener("input", () => {
181
181
  o(), e.onChange(Number(s.value));
182
- }), s.addEventListener("keydown", (l) => {
183
- l.key === "Enter" && (l.preventDefault(), e.onSubmit());
182
+ }), s.addEventListener("keydown", (d) => {
183
+ d.key === "Enter" && (d.preventDefault(), e.onSubmit());
184
184
  });
185
185
  const u = document.createElement("div");
186
186
  u.className = "qaid-q-range-bounds";
187
187
  const q = document.createElement("span");
188
188
  q.textContent = `${t.min}${t.unit ?? ""}`;
189
- const m = document.createElement("span");
190
- return m.textContent = `${t.max}${t.unit ?? ""}`, u.appendChild(q), u.appendChild(m), i.appendChild(a), i.appendChild(s), i.appendChild(u), queueMicrotask(() => e.onChange(Number(s.value))), {
189
+ const f = document.createElement("span");
190
+ return f.textContent = `${t.max}${t.unit ?? ""}`, u.appendChild(q), u.appendChild(f), i.appendChild(a), i.appendChild(s), i.appendChild(u), queueMicrotask(() => e.onChange(Number(s.value))), {
191
191
  element: i,
192
192
  focus: () => s.focus(),
193
193
  getValue: () => Number(s.value),
194
194
  isValid: () => !0,
195
- ...y(s)
195
+ ...v(s)
196
196
  };
197
197
  }
198
198
  function ue(t, e) {
@@ -206,112 +206,112 @@ function ue(t, e) {
206
206
  focus: () => i.focus(),
207
207
  getValue: () => i.value || null,
208
208
  isValid: () => t.required ? i.value !== "" : !0,
209
- ...y(i)
209
+ ...v(i)
210
210
  };
211
211
  }
212
212
  function he(t, e) {
213
- const i = document.createElement("div"), a = t.imageAlignment ?? "horizontal", r = t.options.some((l) => !!l.image) ? a === "vertical" ? " qaid-q-options--image-vertical" : " qaid-q-options--image-horizontal" : "";
213
+ const i = document.createElement("div"), a = t.imageAlignment ?? "horizontal", r = t.options.some((d) => !!d.image) ? a === "vertical" ? " qaid-q-options--image-vertical" : " qaid-q-options--image-horizontal" : "";
214
214
  i.className = `qaid-q-options${r}`, i.setAttribute("role", t.multiple ? "group" : "radiogroup"), i.setAttribute("aria-label", t.label), t.required && i.setAttribute("aria-required", "true");
215
215
  const s = /* @__PURE__ */ new Set();
216
216
  if (t.multiple && Array.isArray(e.initialValue))
217
- for (const l of e.initialValue) s.add(l);
217
+ for (const d of e.initialValue) s.add(d);
218
218
  else !t.multiple && typeof e.initialValue == "string" && s.add(e.initialValue);
219
219
  const o = [];
220
- t.options.forEach((l, h) => {
221
- const c = document.createElement("button");
222
- c.type = "button", c.className = `qaid-q-option${t.multiple ? " qaid-q-multi" : ""}`, c.dataset.value = l.value, c.setAttribute("role", t.multiple ? "checkbox" : "radio"), c.setAttribute("aria-checked", s.has(l.value) ? "true" : "false"), s.has(l.value) && c.classList.add("qaid-q-selected");
223
- const p = document.createElement("span");
224
- p.className = "qaid-q-option-marker", p.setAttribute("aria-hidden", "true");
225
- const f = document.createElement("span");
226
- if (f.className = "qaid-q-option-body", l.image) {
227
- const d = document.createElement("img");
228
- d.className = "qaid-q-option-image", d.src = l.image, d.alt = "", d.loading = "lazy", d.decoding = "async", f.appendChild(d);
229
- }
220
+ t.options.forEach((d, h) => {
221
+ const l = document.createElement("button");
222
+ l.type = "button", l.className = `qaid-q-option${t.multiple ? " qaid-q-multi" : ""}`, l.dataset.value = d.value, l.setAttribute("role", t.multiple ? "checkbox" : "radio"), l.setAttribute("aria-checked", s.has(d.value) ? "true" : "false"), s.has(d.value) && l.classList.add("qaid-q-selected");
223
+ const m = document.createElement("span");
224
+ m.className = "qaid-q-option-marker", m.setAttribute("aria-hidden", "true");
230
225
  const g = document.createElement("span");
231
- if (g.className = "qaid-q-option-label", g.textContent = l.label, f.appendChild(g), l.description) {
232
- const d = document.createElement("span");
233
- d.className = "qaid-q-option-desc", d.textContent = l.description, f.appendChild(d);
226
+ if (g.className = "qaid-q-option-body", d.image) {
227
+ const c = document.createElement("img");
228
+ c.className = "qaid-q-option-image", c.src = d.image, c.alt = "", c.loading = "lazy", c.decoding = "async", g.appendChild(c);
229
+ }
230
+ const p = document.createElement("span");
231
+ if (p.className = "qaid-q-option-label", p.textContent = d.label, g.appendChild(p), d.description) {
232
+ const c = document.createElement("span");
233
+ c.className = "qaid-q-option-desc", c.textContent = d.description, g.appendChild(c);
234
234
  }
235
- if (c.appendChild(p), c.appendChild(f), h < 9) {
236
- const d = document.createElement("span");
237
- d.className = "qaid-q-option-key", d.textContent = String(h + 1), d.setAttribute("aria-hidden", "true"), c.appendChild(d);
235
+ if (l.appendChild(m), l.appendChild(g), h < 9) {
236
+ const c = document.createElement("span");
237
+ c.className = "qaid-q-option-key", c.textContent = String(h + 1), c.setAttribute("aria-hidden", "true"), l.appendChild(c);
238
238
  }
239
- c.addEventListener("click", () => q(h)), c.addEventListener("keydown", (d) => {
240
- if (d.key === "ArrowDown" || d.key === "ArrowRight") {
241
- d.preventDefault(), u((h + 1) % o.length);
239
+ l.addEventListener("click", () => q(h)), l.addEventListener("keydown", (c) => {
240
+ if (c.key === "ArrowDown" || c.key === "ArrowRight") {
241
+ c.preventDefault(), u((h + 1) % o.length);
242
242
  return;
243
243
  }
244
- if (d.key === "ArrowUp" || d.key === "ArrowLeft") {
245
- d.preventDefault(), u((h - 1 + o.length) % o.length);
244
+ if (c.key === "ArrowUp" || c.key === "ArrowLeft") {
245
+ c.preventDefault(), u((h - 1 + o.length) % o.length);
246
246
  return;
247
247
  }
248
- !t.multiple && d.key === "Enter" && s.size > 0 && (d.preventDefault(), e.onSubmit());
249
- }), o.push(c), i.appendChild(c);
250
- }), i.addEventListener("keydown", (l) => {
251
- const h = l.key;
248
+ !t.multiple && c.key === "Enter" && s.size > 0 && (c.preventDefault(), e.onSubmit());
249
+ }), o.push(l), i.appendChild(l);
250
+ }), i.addEventListener("keydown", (d) => {
251
+ const h = d.key;
252
252
  if (h.length === 1 && h >= "1" && h <= "9") {
253
- const c = parseInt(h, 10) - 1;
254
- c < o.length && (l.preventDefault(), q(c), u(c));
253
+ const l = parseInt(h, 10) - 1;
254
+ l < o.length && (d.preventDefault(), q(l), u(l));
255
255
  }
256
256
  });
257
- function u(l) {
258
- o[l]?.focus();
257
+ function u(d) {
258
+ o[d]?.focus();
259
259
  }
260
- function q(l) {
261
- const h = t.options[l].value;
262
- t.multiple ? s.has(h) ? s.delete(h) : s.add(h) : (s.clear(), s.add(h)), o.forEach((c) => {
263
- const p = c.dataset.value, f = s.has(p);
264
- c.classList.toggle("qaid-q-selected", f), c.setAttribute("aria-checked", f ? "true" : "false");
265
- }), e.onChange(m()), !t.multiple && e.autoAdvance && setTimeout(() => e.onAutoAdvance(), 180);
260
+ function q(d) {
261
+ const h = t.options[d].value;
262
+ t.multiple ? s.has(h) ? s.delete(h) : s.add(h) : (s.clear(), s.add(h)), o.forEach((l) => {
263
+ const m = l.dataset.value, g = s.has(m);
264
+ l.classList.toggle("qaid-q-selected", g), l.setAttribute("aria-checked", g ? "true" : "false");
265
+ }), e.onChange(f()), !t.multiple && e.autoAdvance && setTimeout(() => e.onAutoAdvance(), 180);
266
266
  }
267
- function m() {
267
+ function f() {
268
268
  if (t.multiple) return Array.from(s);
269
- const l = s.values().next();
270
- return l.done ? null : l.value;
269
+ const d = s.values().next();
270
+ return d.done ? null : d.value;
271
271
  }
272
272
  return {
273
273
  element: i,
274
274
  focus: () => {
275
275
  (o.find((h) => h.classList.contains("qaid-q-selected")) ?? o[0])?.focus();
276
276
  },
277
- getValue: () => m(),
277
+ getValue: () => f(),
278
278
  isValid: () => t.required ? s.size > 0 : !0,
279
- ...y(i)
279
+ ...v(i)
280
280
  };
281
281
  }
282
- function C(t, e) {
282
+ function w(t, e) {
283
283
  const i = /* @__PURE__ */ Object.create(null), a = [];
284
284
  for (const n of t.questions)
285
- n.visibleIf && !k(n.visibleIf, i) || (a.push(n), Object.prototype.hasOwnProperty.call(e, n.id) && (i[n.id] = e[n.id]));
285
+ n.visibleIf && !C(n.visibleIf, i) || (a.push(n), Object.prototype.hasOwnProperty.call(e, n.id) && (i[n.id] = e[n.id]));
286
286
  return a;
287
287
  }
288
288
  function pe(t, e) {
289
289
  const i = {};
290
- for (const a of C(t, e))
290
+ for (const a of w(t, e))
291
291
  Object.prototype.hasOwnProperty.call(e, a.id) && (i[a.id] = e[a.id]);
292
292
  return i;
293
293
  }
294
- function k(t, e) {
294
+ function C(t, e) {
295
295
  if ("allOf" in t) {
296
296
  for (const n of t.allOf)
297
- if (!k(n, e)) return !1;
297
+ if (!C(n, e)) return !1;
298
298
  return !0;
299
299
  }
300
300
  if ("anyOf" in t) {
301
301
  for (const n of t.anyOf)
302
- if (k(n, e)) return !0;
302
+ if (C(n, e)) return !0;
303
303
  return !1;
304
304
  }
305
305
  const i = e[t.questionId], a = i != null && !(typeof i == "string" && i.trim() === "") && !(Array.isArray(i) && i.length === 0);
306
- return "answered" in t ? t.answered ? a : !a : a ? "equals" in t ? x(i, t.equals) : "notEquals" in t ? !x(i, t.notEquals) : "in" in t ? t.in.some((n) => x(i, n)) : !1 : !1;
306
+ return "answered" in t ? t.answered ? a : !a : a ? "equals" in t ? y(i, t.equals) : "notEquals" in t ? !y(i, t.notEquals) : "in" in t ? t.in.some((n) => y(i, n)) : !1 : !1;
307
307
  }
308
- function x(t, e) {
308
+ function y(t, e) {
309
309
  return Array.isArray(t) ? t.some((i) => i === e) : t === e;
310
310
  }
311
- const qe = 360, E = 2;
311
+ const qe = 360, x = 2;
312
312
  function me(t) {
313
313
  const e = t.scrollHeight - t.clientHeight;
314
- return e <= E ? "none" : t.scrollTop <= E ? "top" : t.scrollTop >= e - E ? "bottom" : "middle";
314
+ return e <= x ? "none" : t.scrollTop <= x ? "top" : t.scrollTop >= e - x ? "bottom" : "middle";
315
315
  }
316
316
  function fe(t, e) {
317
317
  const i = me(t);
@@ -338,7 +338,7 @@ function be(t, e, i) {
338
338
  }
339
339
  };
340
340
  }
341
- const L = "data-qaid-a11y-live", ve = "position:absolute;width:1px;height:1px;margin:-1px;padding:0;border:0;overflow:hidden;clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap;", ye = [
341
+ const T = "data-qaid-a11y-live", ve = "position:absolute;width:1px;height:1px;margin:-1px;padding:0;border:0;overflow:hidden;clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap;", ye = [
342
342
  "a[href]",
343
343
  "button",
344
344
  "input",
@@ -351,13 +351,13 @@ function xe(t) {
351
351
  }
352
352
  function Ee(t, e) {
353
353
  const i = e ? "assertive" : "polite", a = t.querySelector(
354
- `[${L}="${i}"]`
354
+ `[${T}="${i}"]`
355
355
  );
356
356
  if (a) return a;
357
357
  const r = xe(t).createElement("div");
358
- return r.setAttribute(L, i), r.setAttribute("role", e ? "alert" : "status"), r.setAttribute("aria-live", e ? "assertive" : "polite"), r.setAttribute("aria-atomic", "true"), r.style.cssText = ve, t.appendChild(r), r;
358
+ return r.setAttribute(T, i), r.setAttribute("role", e ? "alert" : "status"), r.setAttribute("aria-live", e ? "assertive" : "polite"), r.setAttribute("aria-atomic", "true"), r.style.cssText = ve, t.appendChild(r), r;
359
359
  }
360
- function v(t, e, i = {}) {
360
+ function b(t, e, i = {}) {
361
361
  const a = Ee(t, !!i.assertive);
362
362
  a.textContent = "", a.textContent = e;
363
363
  }
@@ -375,12 +375,12 @@ function Ce(t) {
375
375
  }
376
376
  return !1;
377
377
  }
378
- function O(t) {
378
+ function L(t) {
379
379
  return Array.from(
380
380
  t.querySelectorAll(ye)
381
381
  ).filter((i) => !(i.getAttribute("tabindex") === "-1" || i instanceof HTMLInputElement && i.type === "hidden" || i instanceof HTMLAnchorElement && !i.getAttribute("href") || we(i) || Ce(i)));
382
382
  }
383
- function j(t) {
383
+ function D(t) {
384
384
  let e = t.activeElement;
385
385
  for (; e && e.shadowRoot && e.shadowRoot.activeElement; )
386
386
  e = e.shadowRoot.activeElement;
@@ -391,16 +391,16 @@ function ke(t) {
391
391
  let i = !1;
392
392
  const a = (r) => {
393
393
  if (r.key !== "Tab") return;
394
- const s = O(t);
394
+ const s = L(t);
395
395
  if (s.length === 0) {
396
396
  r.preventDefault(), t.focus();
397
397
  return;
398
398
  }
399
- const o = s[0], u = s[s.length - 1], q = j(e), m = q ? s.indexOf(q) !== -1 : !1;
400
- r.shiftKey ? (!m || q === o) && (r.preventDefault(), u.focus()) : (!m || q === u) && (r.preventDefault(), o.focus());
399
+ const o = s[0], u = s[s.length - 1], q = D(e), f = q ? s.indexOf(q) !== -1 : !1;
400
+ r.shiftKey ? (!f || q === o) && (r.preventDefault(), u.focus()) : (!f || q === u) && (r.preventDefault(), o.focus());
401
401
  };
402
402
  t.addEventListener("keydown", a);
403
- const n = O(t);
403
+ const n = L(t);
404
404
  return n.length > 0 ? n[0].focus() : (t.hasAttribute("tabindex") || (t.setAttribute("tabindex", "-1"), i = !0), t.focus()), {
405
405
  release() {
406
406
  t.removeEventListener("keydown", a), i && (t.removeAttribute("tabindex"), i = !1);
@@ -408,7 +408,7 @@ function ke(t) {
408
408
  };
409
409
  }
410
410
  function Ae() {
411
- return j(document);
411
+ return D(document);
412
412
  }
413
413
  function Se(t) {
414
414
  if (!(!t || typeof t.focus != "function"))
@@ -450,8 +450,8 @@ function Te(t) {
450
450
  }
451
451
  };
452
452
  }
453
- const P = "qaid_visitor_id";
454
- function z() {
453
+ const O = "qaid_visitor_id";
454
+ function P() {
455
455
  const t = typeof crypto < "u" ? crypto : void 0;
456
456
  if (t && typeof t.randomUUID == "function") return t.randomUUID();
457
457
  const e = new Uint8Array(16);
@@ -465,14 +465,19 @@ function z() {
465
465
  }
466
466
  function Le() {
467
467
  try {
468
- let t = localStorage.getItem(P);
469
- return t || (t = z(), localStorage.setItem(P, t)), t;
468
+ let t = localStorage.getItem(O);
469
+ return t || (t = P(), localStorage.setItem(O, t)), t;
470
470
  } catch {
471
- return z();
471
+ return P();
472
472
  }
473
473
  }
474
474
  const Oe = '<svg width="14" height="14" viewBox="0 0 14 14" aria-hidden="true"><path d="M2 2l10 10M12 2L2 12" stroke="currentColor" stroke-width="2" stroke-linecap="round" fill="none"/></svg>', Pe = '<svg width="24" height="24" viewBox="0 0 24 24" aria-hidden="true"><path d="M5 12l4 4L19 7" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" fill="none"/></svg>';
475
475
  class ze {
476
+ /**
477
+ * What this build accepts, for hosts that load it at runtime and may get
478
+ * an older copy. asyncMetadata: `metadata` may be a promise.
479
+ */
480
+ static supports = { asyncMetadata: !0 };
476
481
  config;
477
482
  questionnaire = null;
478
483
  inlineQuestionnaire;
@@ -535,6 +540,9 @@ class ze {
535
540
  scrollCueEl = null;
536
541
  overflow = null;
537
542
  footerEl = null;
543
+ // The step's primary (Next / Submit) button. Kept so an answer can relabel
544
+ // it in place, see `syncPrimaryLabel`.
545
+ primaryBtn = null;
538
546
  savingEl = null;
539
547
  backdropEl = null;
540
548
  currentInput = null;
@@ -728,7 +736,7 @@ ${s}
728
736
  if (!this.cardEl) return;
729
737
  this.cardEl.replaceChildren();
730
738
  const e = document.createElement("p");
731
- e.className = "qaid-q-description", e.textContent = "Loading…", this.cardEl.appendChild(e), this.shadowRoot && v(this.shadowRoot, "Loading");
739
+ e.className = "qaid-q-description", e.textContent = "Loading…", this.cardEl.appendChild(e), this.shadowRoot && b(this.shadowRoot, "Loading");
732
740
  }
733
741
  renderError(e) {
734
742
  if (!this.cardEl) return;
@@ -736,7 +744,7 @@ ${s}
736
744
  const i = document.createElement("h3");
737
745
  i.className = "qaid-q-title", i.textContent = "Couldn't load form";
738
746
  const a = e instanceof Error ? e.message : String(e), n = document.createElement("p");
739
- n.className = "qaid-q-description", n.textContent = a, this.cardEl.appendChild(i), this.cardEl.appendChild(n), this.shadowRoot && v(this.shadowRoot, `Couldn't load form. ${a}`, {
747
+ n.className = "qaid-q-description", n.textContent = a, this.cardEl.appendChild(i), this.cardEl.appendChild(n), this.shadowRoot && b(this.shadowRoot, `Couldn't load form. ${a}`, {
740
748
  assertive: !0
741
749
  });
742
750
  }
@@ -752,25 +760,25 @@ ${s}
752
760
  u.className = "qaid-q-saving-dot";
753
761
  const q = document.createElement("span");
754
762
  q.textContent = "Saving…", this.savingEl.appendChild(u), this.savingEl.appendChild(q), this.stepCounterEl = document.createElement("div"), this.stepCounterEl.className = "qaid-q-step-counter", this.progressEl = document.createElement("div"), this.progressEl.className = i ? "qaid-q-progress qaid-q-progress--inline" : "qaid-q-progress", this.progressFillEl = document.createElement("div"), this.progressFillEl.className = "qaid-q-progress-fill", this.progressEl.appendChild(this.progressFillEl);
755
- const m = n || o;
756
- if (m) {
757
- const l = document.createElement("div");
758
- l.className = "qaid-q-header";
763
+ const f = n || o;
764
+ if (f) {
765
+ const d = document.createElement("div");
766
+ d.className = "qaid-q-header";
759
767
  const h = document.createElement("div");
760
768
  n && (this.titleEl = document.createElement("h2"), this.titleEl.className = "qaid-q-title", this.titleEl.textContent = this.questionnaire.title, h.appendChild(this.titleEl));
761
- const c = document.createElement("div");
762
- if (c.style.display = "flex", c.style.alignItems = "center", c.style.gap = "0.5rem", i || (c.appendChild(this.savingEl), e || c.appendChild(this.stepCounterEl)), s) {
763
- const p = document.createElement("button");
764
- p.type = "button", p.className = "qaid-q-close", p.setAttribute("aria-label", "Close form"), p.innerHTML = Oe, p.addEventListener("click", () => this.close()), c.appendChild(p);
769
+ const l = document.createElement("div");
770
+ if (l.style.display = "flex", l.style.alignItems = "center", l.style.gap = "0.5rem", i || (l.appendChild(this.savingEl), e || l.appendChild(this.stepCounterEl)), s) {
771
+ const m = document.createElement("button");
772
+ m.type = "button", m.className = "qaid-q-close", m.setAttribute("aria-label", "Close form"), m.innerHTML = Oe, m.addEventListener("click", () => this.close()), l.appendChild(m);
765
773
  }
766
- l.appendChild(h), l.appendChild(c), this.cardEl.appendChild(l);
774
+ d.appendChild(h), d.appendChild(l), this.cardEl.appendChild(d);
767
775
  }
768
776
  if (!this.isUserContainer && this.cardEl && (this.titleEl ? (this.titleEl.id = this.titleEl.id || "qaid-q-dialog-title", this.cardEl.setAttribute("aria-labelledby", this.titleEl.id), this.cardEl.removeAttribute("aria-label")) : (this.cardEl.removeAttribute("aria-labelledby"), this.cardEl.setAttribute(
769
777
  "aria-label",
770
778
  this.questionnaire.title ?? "Questionnaire"
771
779
  ))), r) {
772
- const l = document.createElement("p");
773
- l.className = "qaid-q-description", l.textContent = this.questionnaire.description, l.style.marginTop = m ? "-0.5rem" : "0", l.style.marginBottom = "0.75rem", this.cardEl.appendChild(l);
780
+ const d = document.createElement("p");
781
+ d.className = "qaid-q-description", d.textContent = this.questionnaire.description, d.style.marginTop = f ? "-0.5rem" : "0", d.style.marginBottom = "0.75rem", this.cardEl.appendChild(d);
774
782
  }
775
783
  !i && !e && this.cardEl.appendChild(this.progressEl), this.bodyEl = document.createElement("div"), this.bodyEl.className = "qaid-q-body", this.cardEl.appendChild(this.bodyEl), this.footerEl = document.createElement("div"), this.footerEl.className = "qaid-q-footer", this.cardEl.appendChild(this.footerEl), this.scrollCueEl = document.createElement("div"), this.scrollCueEl.className = "qaid-q-scroll-cue", this.scrollCueEl.setAttribute("aria-hidden", "true"), this.scrollCueEl.hidden = !0, this.scrollCueEl.innerHTML = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><path d="M6 9l6 6 6-6"/></svg>', this.bodyEl.appendChild(this.scrollCueEl), this.overflow = be(this.bodyEl, this.cardEl, this.scrollCueEl);
776
784
  }
@@ -788,56 +796,56 @@ ${s}
788
796
  this.stepIndex >= i && (this.stepIndex = i - 1);
789
797
  const a = this.stepIndex, n = this.visibleQuestions[a];
790
798
  if (this.stepCounterEl && (this.stepCounterEl.textContent = `${a + 1} / ${i}`), this.progressFillEl) {
791
- const d = (a + 1) / i * 100;
792
- this.progressFillEl.style.width = `${d}%`;
799
+ const p = (a + 1) / i * 100;
800
+ this.progressFillEl.style.width = `${p}%`;
793
801
  }
794
802
  this.progressEl && (this.progressEl.setAttribute("role", "progressbar"), this.progressEl.setAttribute("aria-label", "Progress"), this.progressEl.setAttribute("aria-valuemin", "0"), this.progressEl.setAttribute("aria-valuemax", String(i)), this.progressEl.setAttribute("aria-valuenow", String(a + 1)), this.progressEl.setAttribute(
795
803
  "aria-valuetext",
796
804
  `Question ${a + 1} of ${i}`
797
- )), this.shadowRoot && i > 1 && v(this.shadowRoot, `Step ${a + 1} of ${i}`);
805
+ )), this.shadowRoot && i > 1 && b(this.shadowRoot, `Step ${a + 1} of ${i}`);
798
806
  const r = document.createElement("div");
799
807
  r.className = "qaid-q-step", r.setAttribute("role", "group"), r.setAttribute("aria-labelledby", `qaid-q-label-${a}`);
800
808
  const s = document.createElement("label");
801
809
  if (s.id = `qaid-q-label-${a}`, s.className = "qaid-q-label", s.textContent = n.label, n.required) {
802
- const d = document.createElement("span");
803
- d.className = "qaid-q-required", d.textContent = "*", d.setAttribute("aria-label", "required"), s.appendChild(d);
810
+ const p = document.createElement("span");
811
+ p.className = "qaid-q-required", p.textContent = "*", p.setAttribute("aria-label", "required"), s.appendChild(p);
804
812
  }
805
813
  if (r.appendChild(s), n.description) {
806
- const d = document.createElement("p");
807
- d.className = "qaid-q-description", d.textContent = n.description, r.appendChild(d);
814
+ const p = document.createElement("p");
815
+ p.className = "qaid-q-description", p.textContent = n.description, r.appendChild(p);
808
816
  }
809
817
  const o = document.createElement("p");
810
818
  o.className = "qaid-q-error", o.id = `qaid-q-error-${a}`, o.setAttribute("aria-live", "polite");
811
- const u = this.answers[n.id] ?? null, q = a === i - 1, m = re({
819
+ const u = this.answers[n.id] ?? null, q = re({
812
820
  question: n,
813
821
  initialValue: u,
814
- onChange: (d) => {
815
- this.handleAnswerChange(n, d), o.textContent && (o.textContent = "", this.currentInput?.clearInvalid());
822
+ onChange: (p) => {
823
+ this.handleAnswerChange(n, p), o.textContent && (o.textContent = "", this.currentInput?.clearInvalid());
816
824
  },
817
825
  onSubmit: () => this.advance(n, o),
818
826
  onAutoAdvance: () => this.advance(n, o),
819
827
  autoAdvance: this.config.autoAdvance
820
828
  });
821
- this.currentInput = m, r.appendChild(m.element), r.appendChild(o), this.bodyEl.replaceChildren(r), this.scrollCueEl && this.bodyEl.appendChild(this.scrollCueEl), this.bodyEl.scrollTop = 0, this.overflow?.refresh(), this.footerEl.replaceChildren();
822
- const h = !(!!this.questionnaire.hideProgress || this.questionnaire.questions.length <= 1) && this.effectiveProgressPosition() === "bottom", c = a > 0 ? (() => {
823
- const d = document.createElement("button");
824
- return d.type = "button", d.className = "qaid-q-btn qaid-q-btn-secondary", d.textContent = this.questionnaire.backLabel ?? "Back", d.addEventListener("click", () => this.back()), d;
825
- })() : null, p = document.createElement("button");
826
- if (p.type = "button", p.className = "qaid-q-btn qaid-q-btn-primary", p.textContent = q ? this.questionnaire.submitLabel ?? "Submit" : this.questionnaire.nextLabel ?? "Next", p.addEventListener("click", () => this.advance(n, o)), h)
827
- this.footerEl.classList.add("qaid-q-footer--inline-progress"), c && this.footerEl.appendChild(c), this.progressEl && this.footerEl.appendChild(this.progressEl), this.savingEl && this.footerEl.appendChild(this.savingEl), this.stepCounterEl && this.footerEl.appendChild(this.stepCounterEl), this.footerEl.appendChild(p);
829
+ this.currentInput = q, r.appendChild(q.element), r.appendChild(o), this.bodyEl.replaceChildren(r), this.scrollCueEl && this.bodyEl.appendChild(this.scrollCueEl), this.bodyEl.scrollTop = 0, this.overflow?.refresh(), this.footerEl.replaceChildren();
830
+ const d = !(!!this.questionnaire.hideProgress || this.questionnaire.questions.length <= 1) && this.effectiveProgressPosition() === "bottom", h = a > 0 ? (() => {
831
+ const p = document.createElement("button");
832
+ return p.type = "button", p.className = "qaid-q-btn qaid-q-btn-secondary", p.textContent = this.questionnaire.backLabel ?? "Back", p.addEventListener("click", () => this.back()), p;
833
+ })() : null, l = document.createElement("button");
834
+ if (l.type = "button", l.className = "qaid-q-btn qaid-q-btn-primary", this.primaryBtn = l, this.syncPrimaryLabel(), l.addEventListener("click", () => this.advance(n, o)), d)
835
+ this.footerEl.classList.add("qaid-q-footer--inline-progress"), h && this.footerEl.appendChild(h), this.progressEl && this.footerEl.appendChild(this.progressEl), this.savingEl && this.footerEl.appendChild(this.savingEl), this.stepCounterEl && this.footerEl.appendChild(this.stepCounterEl), this.footerEl.appendChild(l);
828
836
  else {
829
837
  this.footerEl.classList.remove("qaid-q-footer--inline-progress");
830
- const d = document.createElement("div");
831
- d.className = "qaid-q-footer-left";
832
- const b = document.createElement("div");
833
- b.className = "qaid-q-footer-right", c && d.appendChild(c), b.appendChild(p), this.footerEl.appendChild(d), this.footerEl.appendChild(b);
838
+ const p = document.createElement("div");
839
+ p.className = "qaid-q-footer-left";
840
+ const c = document.createElement("div");
841
+ c.className = "qaid-q-footer-right", h && p.appendChild(h), c.appendChild(l), this.footerEl.appendChild(p), this.footerEl.appendChild(c);
834
842
  }
835
- const f = !this.hasRenderedStep;
836
- this.hasRenderedStep = !0, !e && (!f || this.config.autoFocus) && requestAnimationFrame(() => m.focus());
843
+ const m = !this.hasRenderedStep;
844
+ this.hasRenderedStep = !0, !e && (!m || this.config.autoFocus) && requestAnimationFrame(() => q.focus());
837
845
  }
838
846
  renderDone() {
839
847
  if (!this.cardEl || !this.questionnaire) return;
840
- this.cardEl.replaceChildren();
848
+ this.cardEl.replaceChildren(), this.primaryBtn = null;
841
849
  const e = document.createElement("div");
842
850
  e.className = "qaid-q-done";
843
851
  const i = document.createElement("div");
@@ -855,7 +863,7 @@ ${s}
855
863
  }
856
864
  if (this.cardEl.appendChild(e), requestAnimationFrame(() => a.focus()), this.shadowRoot) {
857
865
  const r = this.questionnaire.thankYouMessage ? `${n}. ${this.questionnaire.thankYouMessage}` : n;
858
- v(this.shadowRoot, r);
866
+ b(this.shadowRoot, r);
859
867
  }
860
868
  }
861
869
  /**
@@ -865,7 +873,7 @@ ${s}
865
873
  * if needed) without the visitor re-entering anything.
866
874
  */
867
875
  renderSubmitError() {
868
- if (this.state = "SUBMIT_FAILED", !this.cardEl) return;
876
+ if (this.state = "SUBMIT_FAILED", this.primaryBtn = null, !this.cardEl) return;
869
877
  this.cardEl.replaceChildren();
870
878
  const e = document.createElement("div");
871
879
  e.className = "qaid-q-submit-error";
@@ -886,7 +894,7 @@ ${s}
886
894
  const u = document.createElement("button");
887
895
  u.type = "button", u.className = "qaid-q-btn qaid-q-btn-secondary", u.textContent = "Close", u.addEventListener("click", () => this.close()), s.appendChild(u);
888
896
  }
889
- e.appendChild(s), this.cardEl.appendChild(e), requestAnimationFrame(() => i.focus()), this.shadowRoot && v(this.shadowRoot, `${a}. ${r}`, { assertive: !0 });
897
+ e.appendChild(s), this.cardEl.appendChild(e), requestAnimationFrame(() => i.focus()), this.shadowRoot && b(this.shadowRoot, `${a}. ${r}`, { assertive: !0 });
890
898
  }
891
899
  // ------------------------------------------------------------------
892
900
  // Navigation
@@ -910,10 +918,24 @@ ${s}
910
918
  // Answer handling + autosave
911
919
  // ------------------------------------------------------------------
912
920
  recomputeVisible() {
913
- this.questionnaire && (this.visibleQuestions = C(this.questionnaire, this.answers));
921
+ this.questionnaire && (this.visibleQuestions = w(this.questionnaire, this.answers));
922
+ }
923
+ /**
924
+ * Label the step's primary button for what pressing it will do: "Submit"
925
+ * when no question after this one is visible under the current answers,
926
+ * "Next" otherwise. Uses the same test as `advance()`, so the two cannot
927
+ * disagree. Called on draw AND on every answer, because an answer can
928
+ * reveal a follow-up (Submit → Next) or hide the last one (Next → Submit).
929
+ * Edits the one button in place — no redraw, so focus and typed text stay.
930
+ */
931
+ syncPrimaryLabel() {
932
+ const e = this.primaryBtn;
933
+ if (!e || !this.questionnaire) return;
934
+ const a = this.stepIndex >= this.visibleQuestions.length - 1 ? this.questionnaire.submitLabel ?? "Submit" : this.questionnaire.nextLabel ?? "Next";
935
+ e.textContent !== a && (e.textContent = a);
914
936
  }
915
937
  handleAnswerChange(e, i, a = {}) {
916
- this.answers[e.id] = i, this.recomputeVisible();
938
+ this.answers[e.id] = i, this.recomputeVisible(), this.syncPrimaryLabel();
917
939
  const n = e.type === "text" || e.type === "currency" || e.type === "range";
918
940
  if (a.immediate || !n) {
919
941
  this.flushPendingSave(), this.saveAnswer(e.id, i);
@@ -961,8 +983,14 @@ ${s}
961
983
  }), this.createPromise;
962
984
  }
963
985
  async createResponse() {
986
+ let e;
987
+ try {
988
+ e = await this.metadata;
989
+ } catch {
990
+ e = void 0;
991
+ }
964
992
  try {
965
- const e = await fetch(this.config.endpoint, {
993
+ const i = await fetch(this.config.endpoint, {
966
994
  method: "POST",
967
995
  headers: this.jsonHeaders(),
968
996
  body: JSON.stringify({
@@ -971,19 +999,19 @@ ${s}
971
999
  pageUrl: window.location.href,
972
1000
  visitorId: this.visitorId,
973
1001
  userAgent: navigator.userAgent,
974
- metadata: this.metadata
1002
+ metadata: e
975
1003
  })
976
1004
  });
977
- if (!e.ok) {
1005
+ if (!i.ok) {
978
1006
  console.error(
979
- `[quests-embed] failed to create response (${e.status})`
1007
+ `[quests-embed] failed to create response (${i.status})`
980
1008
  );
981
1009
  return;
982
1010
  }
983
- const i = await e.json();
984
- i && i.id !== null && i.id !== void 0 ? this.responseId = i.id : console.error("[quests-embed] create response returned no id");
985
- } catch (e) {
986
- console.error("[quests-embed] failed to create response:", e);
1011
+ const a = await i.json();
1012
+ a && a.id !== null && a.id !== void 0 ? this.responseId = a.id : console.error("[quests-embed] create response returned no id");
1013
+ } catch (i) {
1014
+ console.error("[quests-embed] failed to create response:", i);
987
1015
  }
988
1016
  }
989
1017
  async submit() {
@@ -1117,7 +1145,7 @@ ${s}
1117
1145
  const i = new Set(e.questions.map((o) => o.id)), a = {};
1118
1146
  for (const [o, u] of Object.entries(this.answers))
1119
1147
  i.has(o) && (a[o] = u);
1120
- const n = C(e, a);
1148
+ const n = w(e, a);
1121
1149
  if (n.length === 0) return !1;
1122
1150
  this.flushPendingSave();
1123
1151
  const r = this.getCurrentQuestionId();
@@ -1155,7 +1183,7 @@ function De(t) {
1155
1183
  return "Please choose a value.";
1156
1184
  }
1157
1185
  }
1158
- function V(t) {
1186
+ function j(t) {
1159
1187
  return document.querySelector(t)?.textContent?.trim() ?? "";
1160
1188
  }
1161
1189
  function je() {
@@ -1167,33 +1195,33 @@ function je() {
1167
1195
  if (!e) return null;
1168
1196
  try {
1169
1197
  const i = JSON.parse(e);
1170
- return i.cssSelector && !i.css && (i.css = V(i.cssSelector), delete i.cssSelector), i;
1198
+ return i.cssSelector && !i.css && (i.css = j(i.cssSelector), delete i.cssSelector), i;
1171
1199
  } catch {
1172
1200
  return null;
1173
1201
  }
1174
1202
  }
1175
- function A(t, e, i) {
1203
+ function k(t, e, i) {
1176
1204
  console.warn(
1177
1205
  `[quests-embed] Ignoring ${t}="${e}": expected ${i}.`
1178
1206
  );
1179
1207
  }
1180
- function D(t, e) {
1208
+ function z(t, e) {
1181
1209
  if (e !== null) {
1182
1210
  if (e === "true") return !0;
1183
1211
  if (e === "false") return !1;
1184
- A(t, e, '"true" or "false"');
1212
+ k(t, e, '"true" or "false"');
1185
1213
  }
1186
1214
  }
1187
1215
  function Ve(t, e, i) {
1188
1216
  if (e !== null) {
1189
1217
  if (i.includes(e)) return e;
1190
- A(t, e, i.map((a) => `"${a}"`).join(" or "));
1218
+ k(t, e, i.map((a) => `"${a}"`).join(" or "));
1191
1219
  }
1192
1220
  }
1193
1221
  function He(t) {
1194
1222
  return typeof t == "object" && t !== null && !Array.isArray(t);
1195
1223
  }
1196
- function w(t, e, i, a = () => !0) {
1224
+ function E(t, e, i, a = () => !0) {
1197
1225
  if (e === null) return;
1198
1226
  let n = null;
1199
1227
  try {
@@ -1202,31 +1230,31 @@ function w(t, e, i, a = () => !0) {
1202
1230
  n = null;
1203
1231
  }
1204
1232
  if (He(n) && a(n)) return n;
1205
- A(t, e, i);
1233
+ k(t, e, i);
1206
1234
  }
1207
1235
  function Re(t) {
1208
1236
  const e = t.getAttribute("data-endpoint");
1209
1237
  if (!e) return null;
1210
- const i = t.getAttribute("data-config-url"), a = t.getAttribute("data-api-key"), n = t.getAttribute("data-container"), r = t.getAttribute("data-zindex"), s = t.getAttribute("data-accent-color"), o = t.getAttribute("data-error-color"), u = t.getAttribute("data-focus-color"), q = t.getAttribute("data-positive-color"), m = t.getAttribute("data-negative-color"), l = t.getAttribute("data-marker-color"), h = t.getAttribute("data-modal-width"), c = t.getAttribute("data-backdrop-opacity"), p = t.getAttribute("data-font-family"), f = t.getAttribute("data-font-size"), g = t.getAttribute("data-css"), d = t.getAttribute("data-css-selector"), b = t.getAttribute("data-auto-advance"), S = t.getAttribute("data-save-debounce-ms"), H = t.getAttribute("data-theme-url"), I = t.getAttribute("data-preset"), N = t.getAttribute("data-theme"), R = t.getAttribute("data-unstyled"), $ = D(
1238
+ const i = t.getAttribute("data-config-url"), a = t.getAttribute("data-api-key"), n = t.getAttribute("data-container"), r = t.getAttribute("data-zindex"), s = t.getAttribute("data-accent-color"), o = t.getAttribute("data-error-color"), u = t.getAttribute("data-focus-color"), q = t.getAttribute("data-positive-color"), f = t.getAttribute("data-negative-color"), d = t.getAttribute("data-marker-color"), h = t.getAttribute("data-modal-width"), l = t.getAttribute("data-backdrop-opacity"), m = t.getAttribute("data-font-family"), g = t.getAttribute("data-font-size"), p = t.getAttribute("data-css"), c = t.getAttribute("data-css-selector"), V = t.getAttribute("data-auto-advance"), A = t.getAttribute("data-save-debounce-ms"), H = t.getAttribute("data-theme-url"), S = t.getAttribute("data-preset"), I = t.getAttribute("data-theme"), R = t.getAttribute("data-unstyled"), $ = z(
1211
1239
  "data-auto-focus",
1212
1240
  t.getAttribute("data-auto-focus")
1213
- ), U = D(
1241
+ ), U = z(
1214
1242
  "data-animate",
1215
1243
  t.getAttribute("data-animate")
1216
1244
  ), F = Ve(
1217
1245
  "data-progress-position",
1218
1246
  t.getAttribute("data-progress-position"),
1219
1247
  ["top", "bottom"]
1220
- ), M = w(
1248
+ ), M = E(
1221
1249
  "data-questionnaire",
1222
1250
  t.getAttribute("data-questionnaire"),
1223
1251
  'a JSON questionnaire with a "questions" array',
1224
- (B) => Array.isArray(B.questions)
1225
- ), Q = w(
1252
+ (K) => Array.isArray(K.questions)
1253
+ ), Q = E(
1226
1254
  "data-theme-document",
1227
1255
  t.getAttribute("data-theme-document"),
1228
1256
  "a JSON theme object"
1229
- ), K = w(
1257
+ ), B = E(
1230
1258
  "data-metadata",
1231
1259
  t.getAttribute("data-metadata"),
1232
1260
  "a JSON object"
@@ -1243,27 +1271,27 @@ function Re(t) {
1243
1271
  error: o ?? void 0,
1244
1272
  focus: u ?? void 0,
1245
1273
  positive: q ?? void 0,
1246
- negative: m ?? void 0,
1247
- marker: l ?? void 0
1274
+ negative: f ?? void 0,
1275
+ marker: d ?? void 0
1248
1276
  },
1249
1277
  modalWidth: h ? parseInt(h, 10) : void 0,
1250
- backdropOpacity: c ? parseFloat(c) : void 0,
1251
- fontFamily: p ?? void 0,
1252
- fontSize: f ? parseInt(f, 10) : void 0,
1278
+ backdropOpacity: l ? parseFloat(l) : void 0,
1279
+ fontFamily: m ?? void 0,
1280
+ fontSize: g ? parseInt(g, 10) : void 0,
1253
1281
  // Inline CSS wins over a selector, as `css` wins over `cssSelector` in
1254
1282
  // the JSON block.
1255
- css: g || (d ? V(d) : void 0),
1256
- autoAdvance: b === "true" ? !0 : void 0,
1257
- saveDebounceMs: S ? parseInt(S, 10) : void 0,
1283
+ css: p || (c ? j(c) : void 0),
1284
+ autoAdvance: V === "true" ? !0 : void 0,
1285
+ saveDebounceMs: A ? parseInt(A, 10) : void 0,
1258
1286
  autoFocus: $,
1259
1287
  animate: U,
1260
1288
  progressPosition: F,
1261
1289
  themeUrl: H ?? void 0,
1262
1290
  themeDocument: Q,
1263
- preset: I || void 0,
1264
- theme: N || void 0,
1291
+ preset: S || void 0,
1292
+ theme: I || void 0,
1265
1293
  unstyled: R === "true" ? !0 : void 0,
1266
- metadata: K
1294
+ metadata: B
1267
1295
  };
1268
1296
  }
1269
1297
  if (typeof document < "u") {
@@ -1275,8 +1303,8 @@ if (typeof document < "u") {
1275
1303
  }
1276
1304
  export {
1277
1305
  ze as QaidQuests,
1278
- k as evaluateRule,
1306
+ C as evaluateRule,
1279
1307
  pe as getVisibleAnswers,
1280
- C as getVisibleQuestions
1308
+ w as getVisibleQuestions
1281
1309
  };
1282
1310
  //# sourceMappingURL=qaid-quests.js.map