@goflowstate/widget-sdk 0.3.2 → 0.3.4
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 +9 -2
- package/dist/canvas-widget-sdk.js +126 -18
- package/dist/canvas-widget-sdk.js.map +2 -2
- package/dist/feedback.d.ts +8 -1
- package/dist/feedback.d.ts.map +1 -1
- package/dist/index.mjs +126 -18
- package/dist/index.mjs.map +2 -2
- package/package.json +1 -1
package/dist/feedback.d.ts
CHANGED
|
@@ -23,6 +23,12 @@ export interface FlowFeedbackTheme {
|
|
|
23
23
|
fontBody: string;
|
|
24
24
|
fontDisplay: string;
|
|
25
25
|
displayWeight: string;
|
|
26
|
+
/** Letter spacing of the flow's titles, in em, so it scales to the sheet's title size. */
|
|
27
|
+
displayTracking: string;
|
|
28
|
+
fontButton: string;
|
|
29
|
+
buttonWeight: string;
|
|
30
|
+
buttonTracking: string;
|
|
31
|
+
buttonTransform: string;
|
|
26
32
|
radius: string;
|
|
27
33
|
buttonRadius: string;
|
|
28
34
|
dark: boolean;
|
|
@@ -41,7 +47,8 @@ export interface FlowFeedbackOptions {
|
|
|
41
47
|
/** Sends the report. The session client passes `session.request('feedback', report)`. */
|
|
42
48
|
submit: (report: FlowFeedbackReport) => Promise<unknown>;
|
|
43
49
|
/** Renders the page to a JPEG data URL, or null when it cannot. Defaults to the built-in
|
|
44
|
-
* rasterizer; tests and unusual hosts pass their own.
|
|
50
|
+
* rasterizer; tests and unusual hosts pass their own. It runs while the sheet is already
|
|
51
|
+
* open, so a host's own capture must leave the feedback host element out of the picture. */
|
|
45
52
|
capture?: () => Promise<string | null>;
|
|
46
53
|
/** Called once the icon is on the page, so a host page can hide its own fallback. */
|
|
47
54
|
onReady?: () => void;
|
package/dist/feedback.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"feedback.d.ts","sourceRoot":"","sources":["../src/feedback.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,OAAO,CAAC;CACf;AAED,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;CAC7C;AAED,MAAM,WAAW,mBAAmB;IAClC,yFAAyF;IACzF,MAAM,EAAE,CAAC,MAAM,EAAE,kBAAkB,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IACzD;
|
|
1
|
+
{"version":3,"file":"feedback.d.ts","sourceRoot":"","sources":["../src/feedback.ts"],"names":[],"mappings":"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"}
|
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// @goflowstate/widget-sdk v0.3.
|
|
1
|
+
// @goflowstate/widget-sdk v0.3.4
|
|
2
2
|
// https://github.com/goflowstate/goflowstate-sdk
|
|
3
3
|
|
|
4
4
|
var __defProp = Object.defineProperty;
|
|
@@ -121,6 +121,46 @@ var primaryButton = (doc, ground) => {
|
|
|
121
121
|
});
|
|
122
122
|
return best;
|
|
123
123
|
};
|
|
124
|
+
var TEXT_SAMPLE_LIMIT = 600;
|
|
125
|
+
var DISPLAY_MIN_PX = 22;
|
|
126
|
+
var sizeOf = (style) => {
|
|
127
|
+
const n = parseFloat(style.fontSize);
|
|
128
|
+
return Number.isFinite(n) && n > 0 ? n : 16;
|
|
129
|
+
};
|
|
130
|
+
var textSamples = (doc) => {
|
|
131
|
+
const out = [];
|
|
132
|
+
const all = doc.body.querySelectorAll("*");
|
|
133
|
+
for (let i = 0; i < all.length && out.length < TEXT_SAMPLE_LIMIT; i += 1) {
|
|
134
|
+
const el = all[i];
|
|
135
|
+
if (el.tagName === "SCRIPT" || el.tagName === "STYLE" || inOurs(el)) continue;
|
|
136
|
+
let chars = 0;
|
|
137
|
+
for (const node of Array.from(el.childNodes)) {
|
|
138
|
+
if (node.nodeType === 3) chars += (node.textContent ?? "").trim().length;
|
|
139
|
+
}
|
|
140
|
+
if (chars === 0 || !visible(el)) continue;
|
|
141
|
+
const style = styleOf(el);
|
|
142
|
+
if (!style.fontFamily) continue;
|
|
143
|
+
out.push({
|
|
144
|
+
family: style.fontFamily,
|
|
145
|
+
size: sizeOf(style),
|
|
146
|
+
chars,
|
|
147
|
+
style,
|
|
148
|
+
heading: /^H[1-3]$/.test(el.tagName)
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
return out;
|
|
152
|
+
};
|
|
153
|
+
var trackingEm = (style, min, max, fallback) => {
|
|
154
|
+
const px = style ? parseFloat(style.letterSpacing) : NaN;
|
|
155
|
+
const em = style && Number.isFinite(px) ? px / sizeOf(style) : fallback;
|
|
156
|
+
const held = Math.min(max, Math.max(min, em));
|
|
157
|
+
return held === 0 ? "0em" : `${Math.round(held * 1e3) / 1e3}em`;
|
|
158
|
+
};
|
|
159
|
+
var weightIn = (style, min, max, fallback) => {
|
|
160
|
+
const raw = style?.fontWeight ?? "";
|
|
161
|
+
const n = raw === "bold" ? 700 : raw === "normal" ? 400 : parseFloat(raw);
|
|
162
|
+
return Number.isFinite(n) ? String(Math.min(max, Math.max(min, n))) : fallback;
|
|
163
|
+
};
|
|
124
164
|
function readFlowTheme(doc = document) {
|
|
125
165
|
const body = doc.body;
|
|
126
166
|
const stage = body.querySelector(":scope > :not(script):not(style):not([data-fs-feedback-host])");
|
|
@@ -143,12 +183,32 @@ function readFlowTheme(doc = document) {
|
|
|
143
183
|
const pinnedCtaInk = parseColor(rootVar(doc, ["--fs-feedback-cta-ink"]));
|
|
144
184
|
const sampledCtaInk = !pinnedCta && sampledCta && buttonStyle ? parseColor(buttonStyle.color) : null;
|
|
145
185
|
const ctaInk = pinnedCtaInk ?? (sampledCtaInk && contrast(sampledCtaInk, cta) >= 3 ? sampledCtaInk : null) ?? (luminance(cta) > 0.4 ? BLACK : WHITE);
|
|
146
|
-
const
|
|
186
|
+
const samples = textSamples(doc);
|
|
187
|
+
const headings = Array.from(doc.querySelectorAll('h1, h2, [class*="title"]')).filter(
|
|
147
188
|
(el) => !inOurs(el) && visible(el)
|
|
148
189
|
);
|
|
149
|
-
const
|
|
150
|
-
|
|
190
|
+
const largest = (items, size) => items.reduce(
|
|
191
|
+
(best, item) => best === null || size(item) > size(best) ? item : best,
|
|
192
|
+
null
|
|
193
|
+
);
|
|
194
|
+
const bigHeading = largest(
|
|
195
|
+
headings.filter((el) => sizeOf(styleOf(el)) >= DISPLAY_MIN_PX),
|
|
196
|
+
(el) => sizeOf(styleOf(el))
|
|
197
|
+
);
|
|
198
|
+
const bigLine = largest(
|
|
199
|
+
samples.filter((t) => t.size >= DISPLAY_MIN_PX && t.chars >= 3),
|
|
200
|
+
(t) => t.size
|
|
201
|
+
);
|
|
202
|
+
const headingStyle = bigHeading ? styleOf(bigHeading) : bigLine?.style ?? (headings[0] ? styleOf(headings[0]) : null);
|
|
203
|
+
const byFamily = /* @__PURE__ */ new Map();
|
|
204
|
+
for (const t of samples) {
|
|
205
|
+
if (t.size < DISPLAY_MIN_PX && !t.heading)
|
|
206
|
+
byFamily.set(t.family, (byFamily.get(t.family) ?? 0) + t.chars);
|
|
207
|
+
}
|
|
208
|
+
const readBody = largest(Array.from(byFamily), ([, chars]) => chars)?.[0] ?? "";
|
|
209
|
+
const fontBody = rootVar(doc, ["--fs-feedback-font"]) || readBody || (stage ? styleOf(stage).fontFamily : "") || bodyStyle.fontFamily || rootVar(doc, ["--sb-font-body", "--font-body"]) || "system-ui, sans-serif";
|
|
151
210
|
const fontDisplay = rootVar(doc, ["--fs-feedback-font-display"]) || headingStyle?.fontFamily || rootVar(doc, ["--sb-font-display", "--sb-font-title", "--font-display"]) || fontBody;
|
|
211
|
+
const buttonType = buttonStyle?.fontFamily ? buttonStyle : null;
|
|
152
212
|
const field = Array.from(
|
|
153
213
|
doc.querySelectorAll('textarea, input[type="text"], input:not([type])')
|
|
154
214
|
).find((el) => !inOurs(el) && visible(el));
|
|
@@ -172,6 +232,11 @@ function readFlowTheme(doc = document) {
|
|
|
172
232
|
fontBody,
|
|
173
233
|
fontDisplay,
|
|
174
234
|
displayWeight: headingStyle?.fontWeight || "500",
|
|
235
|
+
displayTracking: trackingEm(headingStyle, -0.04, 0.02, -0.01),
|
|
236
|
+
fontButton: buttonType?.fontFamily || fontBody,
|
|
237
|
+
buttonWeight: weightIn(buttonType, 500, 800, "600"),
|
|
238
|
+
buttonTracking: trackingEm(buttonType, -0.02, 0.08, 0),
|
|
239
|
+
buttonTransform: buttonType?.textTransform === "uppercase" ? "uppercase" : "none",
|
|
175
240
|
radius,
|
|
176
241
|
buttonRadius: buttonRadius === null ? "999px" : `${Math.min(buttonRadius, 999)}px`,
|
|
177
242
|
dark
|
|
@@ -197,9 +262,10 @@ function encodeScreenshot(canvas) {
|
|
|
197
262
|
return null;
|
|
198
263
|
}
|
|
199
264
|
async function captureViewport(ground) {
|
|
200
|
-
const { domToCanvas } = await import("modern-screenshot");
|
|
201
265
|
const width = window.innerWidth;
|
|
202
266
|
const height = window.innerHeight;
|
|
267
|
+
const { scrollX, scrollY } = window;
|
|
268
|
+
const { domToCanvas } = await import("modern-screenshot");
|
|
203
269
|
const scale = Math.min(
|
|
204
270
|
window.devicePixelRatio || 1,
|
|
205
271
|
SCREENSHOT_MAX_SIDE / Math.max(width, height)
|
|
@@ -209,7 +275,7 @@ async function captureViewport(ground) {
|
|
|
209
275
|
height,
|
|
210
276
|
scale,
|
|
211
277
|
backgroundColor: ground,
|
|
212
|
-
style: { transform: `translate(${-
|
|
278
|
+
style: { transform: `translate(${-scrollX}px, ${-scrollY}px)` },
|
|
213
279
|
filter: (node) => !(node instanceof Element && node.hasAttribute(FEEDBACK_HOST_ATTR))
|
|
214
280
|
});
|
|
215
281
|
return encodeScreenshot(canvas);
|
|
@@ -403,9 +469,15 @@ var STYLE = `
|
|
|
403
469
|
font-family: var(--font-body); font-size: 15px; line-height: 1.4;
|
|
404
470
|
}
|
|
405
471
|
.grab { width: 36px; height: 4px; border-radius: 2px; background: var(--line); align-self: center; }
|
|
406
|
-
h2 {
|
|
472
|
+
h2 {
|
|
473
|
+
margin: 2px 0 0; font-family: var(--font-display); font-weight: var(--display-weight);
|
|
474
|
+
font-size: 22px; line-height: 1.15; letter-spacing: var(--display-tracking); text-wrap: balance;
|
|
475
|
+
}
|
|
407
476
|
.shot { display: flex; gap: 12px; align-items: center; font-size: 13px; color: var(--ink-dim); }
|
|
408
477
|
.shot img { width: 50px; max-height: 108px; object-fit: cover; object-position: top; border-radius: 8px; border: 1px solid var(--line); }
|
|
478
|
+
.ghost { display: none; width: 50px; height: 108px; border-radius: 8px; border: 1px solid var(--line); background: var(--fill); }
|
|
479
|
+
.shot[data-pending] .ghost { display: block; }
|
|
480
|
+
.shot[data-pending] img { display: none; }
|
|
409
481
|
.link { background: none; border: 0; padding: 0; font: inherit; color: var(--ink); text-decoration: underline; text-underline-offset: 3px; cursor: pointer; }
|
|
410
482
|
textarea {
|
|
411
483
|
width: 100%; min-height: 84px; resize: none; font: inherit; font-size: 16px; color: var(--ink);
|
|
@@ -413,7 +485,9 @@ textarea {
|
|
|
413
485
|
}
|
|
414
486
|
textarea::placeholder { color: var(--ink-dim); }
|
|
415
487
|
.send {
|
|
416
|
-
font:
|
|
488
|
+
font-family: var(--font-button); font-weight: var(--button-weight); font-size: 17px; line-height: 1.2;
|
|
489
|
+
letter-spacing: var(--button-tracking); text-transform: var(--button-transform);
|
|
490
|
+
cursor: pointer; border: 0; padding: 15px 14px;
|
|
417
491
|
background: var(--cta); color: var(--cta-ink); border-radius: var(--button-radius);
|
|
418
492
|
}
|
|
419
493
|
.send[disabled] { opacity: 0.5; cursor: default; }
|
|
@@ -426,6 +500,8 @@ textarea::placeholder { color: var(--ink-dim); }
|
|
|
426
500
|
}
|
|
427
501
|
.bug svg { transition: transform 0.1s ease-out, width 0.22s ease, height 0.22s ease; }
|
|
428
502
|
.sheet { animation: rise 0.22s ease-out; }
|
|
503
|
+
.shot[data-pending] .ghost { animation: wait 1.1s ease-in-out infinite alternate; }
|
|
504
|
+
@keyframes wait { from { opacity: 0.45; } to { opacity: 1; } }
|
|
429
505
|
@keyframes rise { from { transform: translateY(24px); opacity: 0; } to { transform: none; opacity: 1; } }
|
|
430
506
|
}
|
|
431
507
|
`;
|
|
@@ -446,7 +522,7 @@ function mountFlowFeedback(options) {
|
|
|
446
522
|
<div class="sheet" role="dialog" aria-modal="true" aria-labelledby="fsf-title" hidden>
|
|
447
523
|
<div class="grab" aria-hidden="true"></div>
|
|
448
524
|
<h2 id="fsf-title">Feedback on this page</h2>
|
|
449
|
-
<div class="shot" hidden><img alt="Screenshot of this page" /><span><span>Screenshot attached</span><br /><button type="button" class="link remove">Remove screenshot</button></span></div>
|
|
525
|
+
<div class="shot" hidden><span class="ghost" aria-hidden="true"></span><img alt="Screenshot of this page" /><span><span class="shot-label">Screenshot attached</span><br /><button type="button" class="link remove">Remove screenshot</button></span></div>
|
|
450
526
|
<textarea aria-labelledby="fsf-title" placeholder="What should change?" maxlength="2000"></textarea>
|
|
451
527
|
<p class="status" role="status" aria-live="polite"></p>
|
|
452
528
|
<button type="button" class="send" disabled>Send feedback</button>
|
|
@@ -458,6 +534,7 @@ function mountFlowFeedback(options) {
|
|
|
458
534
|
const sheet = q(".sheet");
|
|
459
535
|
const shot = q(".shot");
|
|
460
536
|
const img = q(".shot img");
|
|
537
|
+
const shotLabel = q(".shot-label");
|
|
461
538
|
const remove = q(".remove");
|
|
462
539
|
const text = q("textarea");
|
|
463
540
|
const status = q(".status");
|
|
@@ -668,6 +745,11 @@ function mountFlowFeedback(options) {
|
|
|
668
745
|
"--font-body": theme.fontBody,
|
|
669
746
|
"--font-display": theme.fontDisplay,
|
|
670
747
|
"--display-weight": theme.displayWeight,
|
|
748
|
+
"--display-tracking": theme.displayTracking,
|
|
749
|
+
"--font-button": theme.fontButton,
|
|
750
|
+
"--button-weight": theme.buttonWeight,
|
|
751
|
+
"--button-tracking": theme.buttonTracking,
|
|
752
|
+
"--button-transform": theme.buttonTransform,
|
|
671
753
|
"--radius": theme.radius,
|
|
672
754
|
"--button-radius": theme.buttonRadius
|
|
673
755
|
};
|
|
@@ -677,15 +759,21 @@ function mountFlowFeedback(options) {
|
|
|
677
759
|
const sync = () => {
|
|
678
760
|
send.disabled = busy || text.value.trim().length === 0;
|
|
679
761
|
};
|
|
762
|
+
let round = 0;
|
|
763
|
+
let pending = null;
|
|
680
764
|
const setShot = (url) => {
|
|
681
765
|
screenshot = url;
|
|
682
766
|
shot.hidden = url === null;
|
|
767
|
+
shot.removeAttribute("data-pending");
|
|
768
|
+
shotLabel.textContent = "Screenshot attached";
|
|
683
769
|
if (url) img.src = url;
|
|
684
770
|
else img.removeAttribute("src");
|
|
685
771
|
};
|
|
686
772
|
const close = () => {
|
|
687
773
|
if (closeTimer) clearTimeout(closeTimer);
|
|
688
774
|
closeTimer = null;
|
|
775
|
+
round += 1;
|
|
776
|
+
pending = null;
|
|
689
777
|
sheet.hidden = true;
|
|
690
778
|
scrim.hidden = true;
|
|
691
779
|
bug.hidden = false;
|
|
@@ -696,20 +784,28 @@ function mountFlowFeedback(options) {
|
|
|
696
784
|
sync();
|
|
697
785
|
schedulePlace();
|
|
698
786
|
};
|
|
699
|
-
const open =
|
|
700
|
-
if (!sheet.hidden
|
|
701
|
-
busy
|
|
787
|
+
const open = () => {
|
|
788
|
+
if (!sheet.hidden) return pending ?? Promise.resolve();
|
|
789
|
+
if (busy) return Promise.resolve();
|
|
702
790
|
paint();
|
|
791
|
+
const mine = round += 1;
|
|
703
792
|
bug.hidden = true;
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
793
|
+
setShot(null);
|
|
794
|
+
shot.hidden = false;
|
|
795
|
+
shot.setAttribute("data-pending", "");
|
|
796
|
+
shotLabel.textContent = "Taking a screenshot";
|
|
708
797
|
tuck.hidden = spot.state !== "float";
|
|
709
798
|
scrim.hidden = false;
|
|
710
799
|
sheet.hidden = false;
|
|
711
800
|
sync();
|
|
712
|
-
|
|
801
|
+
const capture = options.capture ?? (() => captureViewport(theme.ground));
|
|
802
|
+
pending = withTimeout(Promise.resolve().then(capture), CAPTURE_TIMEOUT_MS).then((url) => {
|
|
803
|
+
if (mine !== round) return;
|
|
804
|
+
pending = null;
|
|
805
|
+
setShot(url);
|
|
806
|
+
if (!root.activeElement || root.activeElement === bug) text.focus();
|
|
807
|
+
});
|
|
808
|
+
return pending;
|
|
713
809
|
};
|
|
714
810
|
const submit = async () => {
|
|
715
811
|
const message = text.value.trim();
|
|
@@ -717,6 +813,9 @@ function mountFlowFeedback(options) {
|
|
|
717
813
|
busy = true;
|
|
718
814
|
sync();
|
|
719
815
|
status.textContent = "";
|
|
816
|
+
const mine = round;
|
|
817
|
+
if (pending) await pending;
|
|
818
|
+
if (mine !== round) return;
|
|
720
819
|
try {
|
|
721
820
|
await options.submit({
|
|
722
821
|
message,
|
|
@@ -740,6 +839,11 @@ function mountFlowFeedback(options) {
|
|
|
740
839
|
if (!suppressClick) void open();
|
|
741
840
|
});
|
|
742
841
|
bug.addEventListener("pointerdown", onDown);
|
|
842
|
+
if (!options.capture)
|
|
843
|
+
bug.addEventListener("pointerdown", () => void import("modern-screenshot").catch(() => {
|
|
844
|
+
}), {
|
|
845
|
+
once: true
|
|
846
|
+
});
|
|
743
847
|
bug.addEventListener("pointermove", onMove);
|
|
744
848
|
bug.addEventListener("pointerup", onUp);
|
|
745
849
|
bug.addEventListener("pointercancel", onUp);
|
|
@@ -759,7 +863,11 @@ function mountFlowFeedback(options) {
|
|
|
759
863
|
);
|
|
760
864
|
});
|
|
761
865
|
scrim.addEventListener("click", close);
|
|
762
|
-
remove.addEventListener("click", () =>
|
|
866
|
+
remove.addEventListener("click", () => {
|
|
867
|
+
round += 1;
|
|
868
|
+
pending = null;
|
|
869
|
+
setShot(null);
|
|
870
|
+
});
|
|
763
871
|
text.addEventListener("input", sync);
|
|
764
872
|
send.addEventListener("click", () => void submit());
|
|
765
873
|
sheet.addEventListener("keydown", (event) => {
|