@sagepilot-ai/web-events-addon 0.2.1 → 0.2.3
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 +1 -1
- package/dist/index.cjs +44 -5
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +44 -5
- package/dist/index.js.map +1 -1
- package/dist/sagepilot-web-events.global.js +44 -5
- package/dist/sagepilot-web-events.global.js.map +1 -1
- package/package.json +9 -4
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Sagepilot web events add-on
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Capture supported browser events and render published Sagepilot popups for an SDK installation in your workspace. The add-on runs independently of the Sagepilot chat SDK.
|
|
4
4
|
|
|
5
5
|
The add-on bundles the shared installation client. Install `@sagepilot-ai/web-events-addon` for npm usage, or load the standalone browser bundle.
|
|
6
6
|
|
package/dist/index.cjs
CHANGED
|
@@ -364,7 +364,7 @@ function createSagepilotInstallationClient(options) {
|
|
|
364
364
|
|
|
365
365
|
// package.json
|
|
366
366
|
var name = "@sagepilot-ai/web-events-addon";
|
|
367
|
-
var version = "0.2.
|
|
367
|
+
var version = "0.2.3";
|
|
368
368
|
|
|
369
369
|
// src/projection.ts
|
|
370
370
|
var sensitive = /password|passwd|secret|token|authorization|cookie|session|email|phone|contact|address|card|payment|cvv|ssn|dob|birth|customer|user|account|person|profile|name|description|message|content|text|search|query/i;
|
|
@@ -2201,6 +2201,8 @@ var popupDesignStyles = [
|
|
|
2201
2201
|
].join("");
|
|
2202
2202
|
|
|
2203
2203
|
// src/popup.ts
|
|
2204
|
+
var PHONE_FORMAT = /^\+[1-9][0-9]{7,14}$/;
|
|
2205
|
+
var PHONE_GUIDANCE = "Start with + and your country code, e.g. +12025550123. No spaces or dashes.";
|
|
2204
2206
|
function popupCompletionKey(workspaceId, installationId) {
|
|
2205
2207
|
return `sagepilot:sdk-popup:${workspaceId}:${installationId}:completed`;
|
|
2206
2208
|
}
|
|
@@ -2251,6 +2253,30 @@ function createPopup(options) {
|
|
|
2251
2253
|
if (text2 !== void 0) node2.textContent = text2;
|
|
2252
2254
|
return node2;
|
|
2253
2255
|
}
|
|
2256
|
+
function phoneField(label2, input) {
|
|
2257
|
+
const guidance = input.required ? PHONE_GUIDANCE : "Optional. " + PHONE_GUIDANCE;
|
|
2258
|
+
const hint = element("small", guidance);
|
|
2259
|
+
hint.id = "sage-popup-phone-hint";
|
|
2260
|
+
hint.className = "phone-hint";
|
|
2261
|
+
hint.setAttribute("aria-live", "polite");
|
|
2262
|
+
input.setAttribute("aria-describedby", hint.id);
|
|
2263
|
+
function validate() {
|
|
2264
|
+
const value = input.value.trim();
|
|
2265
|
+
const invalid = (input.required || value.length > 0) && !PHONE_FORMAT.test(value);
|
|
2266
|
+
if (invalid === (input.getAttribute("aria-invalid") === "true")) return !invalid;
|
|
2267
|
+
input.setAttribute("aria-invalid", String(invalid));
|
|
2268
|
+
hint.classList.toggle("phone-error", invalid);
|
|
2269
|
+
hint.textContent = invalid ? "Check your phone number. " + PHONE_GUIDANCE : guidance;
|
|
2270
|
+
return !invalid;
|
|
2271
|
+
}
|
|
2272
|
+
function updatePhoneError() {
|
|
2273
|
+
if (input.getAttribute("aria-invalid") === "true") validate();
|
|
2274
|
+
}
|
|
2275
|
+
input.addEventListener("input", updatePhoneError);
|
|
2276
|
+
const group = element("div");
|
|
2277
|
+
group.append(label2, hint);
|
|
2278
|
+
return { group, validate };
|
|
2279
|
+
}
|
|
2254
2280
|
function show() {
|
|
2255
2281
|
if (!eligible() || !config) return;
|
|
2256
2282
|
const published = config, revision = ++generation;
|
|
@@ -2261,6 +2287,7 @@ function createPopup(options) {
|
|
|
2261
2287
|
const shadow = host.attachShadow({ mode: "open" });
|
|
2262
2288
|
const style = element("style");
|
|
2263
2289
|
style.textContent = `:host{font-family:system-ui,sans-serif;color:#172c23;color-scheme:light}*{box-sizing:border-box}.panel{background:white;width:min(420px,calc(100vw - 40px));max-height:90dvh;overflow:auto;border-radius:18px;padding:28px;box-shadow:0 16px 80px #0003;position:relative}h2{margin:4px 28px 10px 0;font-size:25px}p{line-height:1.5;color:#52645a}label{display:block;margin-top:14px;font-size:14px}input{display:block;width:100%;padding:11px;border:1px solid #b6c7bd;border-radius:7px;margin-top:6px;font:inherit;background:white;color:#172c23}button{cursor:pointer;font:inherit;color:inherit}button[type=submit]{display:block;width:100%;border:0;border-radius:8px;background:${published.accent_color};color:white;padding:13px;margin-top:20px;font-weight:600}button:disabled{opacity:.6;cursor:wait}.close{position:absolute;right:15px;top:12px;border:0;background:transparent;font-size:25px}.status{min-height:1.3em;font-size:14px}.logo{max-width:160px;max-height:60px;object-fit:contain}input:focus-visible,button:focus-visible{outline:3px solid #729e82;outline-offset:3px}@media(max-width:480px){.panel{padding:22px}h2{font-size:22px}}`;
|
|
2290
|
+
style.textContent += ".phone-hint{display:block;margin-top:6px;line-height:1.4}.phone-error{font-weight:600}";
|
|
2264
2291
|
style.textContent += popupDesignStyles;
|
|
2265
2292
|
shadow.append(style);
|
|
2266
2293
|
const panel = element("section");
|
|
@@ -2282,7 +2309,8 @@ function createPopup(options) {
|
|
|
2282
2309
|
status.setAttribute("role", "status");
|
|
2283
2310
|
status.setAttribute("aria-live", "polite");
|
|
2284
2311
|
const inputs = /* @__PURE__ */ new Map();
|
|
2285
|
-
const
|
|
2312
|
+
const contactFields = [];
|
|
2313
|
+
let validatePhone;
|
|
2286
2314
|
for (const field of ["name", "email", "phone"]) {
|
|
2287
2315
|
if (!published.fields[field]) continue;
|
|
2288
2316
|
const label2 = element("label", field === "phone" ? "Phone" : field === "email" ? "Email" : "Name");
|
|
@@ -2293,8 +2321,14 @@ function createPopup(options) {
|
|
|
2293
2321
|
input.maxLength = field === "phone" ? 32 : field === "email" ? 254 : 100;
|
|
2294
2322
|
input.required = published.required_fields.includes(field) || field === "email" && published.verification === "email";
|
|
2295
2323
|
label2.append(input);
|
|
2296
|
-
|
|
2297
|
-
|
|
2324
|
+
let control = label2;
|
|
2325
|
+
if (field === "phone") {
|
|
2326
|
+
const phone = phoneField(label2, input);
|
|
2327
|
+
control = phone.group;
|
|
2328
|
+
validatePhone = phone.validate;
|
|
2329
|
+
}
|
|
2330
|
+
form.append(control);
|
|
2331
|
+
contactFields.push(control);
|
|
2298
2332
|
inputs.set(field, input);
|
|
2299
2333
|
}
|
|
2300
2334
|
const submit = element("button", published.button_text);
|
|
@@ -2310,6 +2344,11 @@ function createPopup(options) {
|
|
|
2310
2344
|
async function submitForm(event) {
|
|
2311
2345
|
event.preventDefault();
|
|
2312
2346
|
if (busy || revision !== generation) return;
|
|
2347
|
+
if (!challenge && validatePhone?.() === false) {
|
|
2348
|
+
status.textContent = "";
|
|
2349
|
+
inputs.get("phone")?.focus();
|
|
2350
|
+
return;
|
|
2351
|
+
}
|
|
2313
2352
|
busy = true;
|
|
2314
2353
|
submit.disabled = true;
|
|
2315
2354
|
status.textContent = "";
|
|
@@ -2338,7 +2377,7 @@ function createPopup(options) {
|
|
|
2338
2377
|
for (const [key, value] of contactInputs) inputs.set(key, value);
|
|
2339
2378
|
submit.textContent = published.button_text;
|
|
2340
2379
|
status.textContent = "";
|
|
2341
|
-
form.replaceChildren(...
|
|
2380
|
+
form.replaceChildren(...contactFields, submit, status);
|
|
2342
2381
|
inputs.values().next().value?.focus();
|
|
2343
2382
|
};
|
|
2344
2383
|
var restartForm = restartForm2;
|