@revvue/embed 0.0.0-beta.3 → 0.0.0-beta.5
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/dist/browser/css/dialog.css +1 -1
- package/dist/browser/css/drawer.css +1 -1
- package/dist/browser/css/popover.css +1 -1
- package/dist/browser/embed.js +2 -2
- package/dist/package/css/dialog.css +1 -1
- package/dist/package/css/drawer.css +1 -1
- package/dist/package/css/popover.css +1 -1
- package/dist/package/package.cjs +278 -105
- package/dist/package/package.mjs +278 -106
- package/dist/package/types/core/app-options.d.ts +3 -2
- package/dist/package/types/core/app-options.d.ts.map +1 -1
- package/dist/package/types/core/button-options.d.ts +13 -0
- package/dist/package/types/core/button-options.d.ts.map +1 -1
- package/dist/package/types/core/common.d.ts +2 -0
- package/dist/package/types/core/common.d.ts.map +1 -1
- package/dist/package/types/core/create-iframe.d.ts +3 -1
- package/dist/package/types/core/create-iframe.d.ts.map +1 -1
- package/dist/package/types/core/embed-types.d.ts +12 -0
- package/dist/package/types/core/embed-types.d.ts.map +1 -1
- package/dist/package/types/core/iframe-messages.d.ts +6 -0
- package/dist/package/types/core/iframe-messages.d.ts.map +1 -0
- package/dist/package/types/factories/create-dialog/create-dialog.d.ts +2 -1
- package/dist/package/types/factories/create-dialog/create-dialog.d.ts.map +1 -1
- package/dist/package/types/factories/create-drawer/create-drawer.d.ts +2 -2
- package/dist/package/types/factories/create-drawer/create-drawer.d.ts.map +1 -1
- package/dist/package/types/factories/create-popover/create-popover.d.ts +2 -1
- package/dist/package/types/factories/create-popover/create-popover.d.ts.map +1 -1
- package/dist/package/types/factories/create-widget/create-widget.d.ts +2 -1
- package/dist/package/types/factories/create-widget/create-widget.d.ts.map +1 -1
- package/dist/package/types/package.d.ts +1 -0
- package/dist/package/types/package.d.ts.map +1 -1
- package/dist/package/types/utils/brand-types.d.ts +7 -0
- package/dist/package/types/utils/brand-types.d.ts.map +1 -1
- package/dist/package/types/utils/built-button/built-button.d.ts.map +1 -1
- package/dist/package/types/utils/create-closing-guard.d.ts +6 -0
- package/dist/package/types/utils/create-closing-guard.d.ts.map +1 -0
- package/dist/package/types/utils/icons.d.ts +3 -0
- package/dist/package/types/utils/icons.d.ts.map +1 -0
- package/dist/package/types/utils/open-state-store/index.d.ts +2 -0
- package/dist/package/types/utils/open-state-store/index.d.ts.map +1 -0
- package/dist/package/types/utils/open-state-store/open-state-store.d.ts +18 -0
- package/dist/package/types/utils/open-state-store/open-state-store.d.ts.map +1 -0
- package/dist/package/types/utils/open-state-store/open-state-store.spec.d.ts +2 -0
- package/dist/package/types/utils/open-state-store/open-state-store.spec.d.ts.map +1 -0
- package/package.json +1 -1
package/dist/package/package.cjs
CHANGED
|
@@ -3,6 +3,51 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
|
3
3
|
var tenantId = (id) => id;
|
|
4
4
|
var formId = (id) => id;
|
|
5
5
|
var embedId = (id) => id;
|
|
6
|
+
var integrationProfileId = (id) => id;
|
|
7
|
+
//#endregion
|
|
8
|
+
//#region src/utils/create-env.ts
|
|
9
|
+
function createEnv(schema, source = {}) {
|
|
10
|
+
const result = {};
|
|
11
|
+
for (const key in schema) {
|
|
12
|
+
const field = schema[key];
|
|
13
|
+
const raw = source[key];
|
|
14
|
+
if (raw !== void 0) result[key] = field.parse ? field.parse(raw) : raw;
|
|
15
|
+
else if (field.default !== void 0) result[key] = field.default;
|
|
16
|
+
else if (field.required) throw new Error(`[embed] Missing required env variable: ${key}`);
|
|
17
|
+
}
|
|
18
|
+
return result;
|
|
19
|
+
}
|
|
20
|
+
//#endregion
|
|
21
|
+
//#region src/config/env.ts
|
|
22
|
+
var removeTrailingSlash = (url) => url.replace(/\/$/, "");
|
|
23
|
+
var env = createEnv({
|
|
24
|
+
CHAT_URL: {
|
|
25
|
+
default: "https://app.revvue.ai/chat",
|
|
26
|
+
parse: removeTrailingSlash
|
|
27
|
+
},
|
|
28
|
+
FORM_URL: {
|
|
29
|
+
default: "https://app.revvue.ai/survey",
|
|
30
|
+
parse: removeTrailingSlash
|
|
31
|
+
},
|
|
32
|
+
CDN_URL: {
|
|
33
|
+
default: "https://cdn.revvue.ai/v1",
|
|
34
|
+
parse: removeTrailingSlash
|
|
35
|
+
},
|
|
36
|
+
EMBED_LOOKUP_URL: {
|
|
37
|
+
default: "https://app.revvue.ai/api/v1/embeds",
|
|
38
|
+
parse: removeTrailingSlash
|
|
39
|
+
},
|
|
40
|
+
DEBUG: {
|
|
41
|
+
default: false,
|
|
42
|
+
parse: (v) => v === "true"
|
|
43
|
+
}
|
|
44
|
+
}, {
|
|
45
|
+
"BASE_URL": "/",
|
|
46
|
+
"DEV": false,
|
|
47
|
+
"MODE": "production",
|
|
48
|
+
"PROD": true,
|
|
49
|
+
"SSR": false
|
|
50
|
+
});
|
|
6
51
|
//#endregion
|
|
7
52
|
//#region src/utils/refresh-iframe.ts
|
|
8
53
|
function refreshIframe(iframe) {
|
|
@@ -17,12 +62,21 @@ function refreshIframe(iframe) {
|
|
|
17
62
|
}
|
|
18
63
|
}
|
|
19
64
|
//#endregion
|
|
65
|
+
//#region src/core/iframe-messages.ts
|
|
66
|
+
var IFRAME_MESSAGES = {
|
|
67
|
+
close: "rvv-embed-close",
|
|
68
|
+
focus: "rvv-embed-focus"
|
|
69
|
+
};
|
|
70
|
+
//#endregion
|
|
20
71
|
//#region src/core/create-iframe.ts
|
|
21
|
-
function getIframeSrc() {
|
|
22
|
-
|
|
72
|
+
function getIframeSrc(options) {
|
|
73
|
+
const base = options.app === "chat" ? env.CHAT_URL : env.FORM_URL;
|
|
74
|
+
const params = new URLSearchParams({ tenant_id: options.tenantId });
|
|
75
|
+
if (options.app === "chat") params.set("integration_profile_id", options.integrationProfileId);
|
|
76
|
+
return `${base}?${params}`;
|
|
23
77
|
}
|
|
24
|
-
function createIframe(
|
|
25
|
-
const src = getIframeSrc();
|
|
78
|
+
function createIframe(options) {
|
|
79
|
+
const src = getIframeSrc(options);
|
|
26
80
|
const embedId = crypto.randomUUID();
|
|
27
81
|
const iframe = document.createElement("iframe");
|
|
28
82
|
iframe.src = src;
|
|
@@ -32,13 +86,52 @@ function createIframe(_options) {
|
|
|
32
86
|
iframe.id = embedId;
|
|
33
87
|
const refresh = () => refreshIframe(iframe);
|
|
34
88
|
const focus = () => {
|
|
35
|
-
iframe.contentWindow?.postMessage(
|
|
89
|
+
iframe.contentWindow?.postMessage(IFRAME_MESSAGES.focus, "*");
|
|
90
|
+
};
|
|
91
|
+
const onMessage = (handler) => {
|
|
92
|
+
const listener = (event) => {
|
|
93
|
+
if (event.source !== iframe.contentWindow) return;
|
|
94
|
+
handler(event.data);
|
|
95
|
+
};
|
|
96
|
+
window.addEventListener("message", listener);
|
|
97
|
+
return () => window.removeEventListener("message", listener);
|
|
36
98
|
};
|
|
37
99
|
return {
|
|
38
100
|
iframe,
|
|
39
101
|
focus,
|
|
40
102
|
refresh,
|
|
41
|
-
embedId
|
|
103
|
+
embedId,
|
|
104
|
+
onMessage
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
//#endregion
|
|
108
|
+
//#region src/utils/create-closing-guard.ts
|
|
109
|
+
function createClosingGuard() {
|
|
110
|
+
let cancelClose = null;
|
|
111
|
+
function isClosing() {
|
|
112
|
+
return cancelClose !== null;
|
|
113
|
+
}
|
|
114
|
+
function scheduleClose(element, onDone) {
|
|
115
|
+
const abortController = new AbortController();
|
|
116
|
+
element.addEventListener("transitionend", () => {
|
|
117
|
+
cancelClose = null;
|
|
118
|
+
onDone();
|
|
119
|
+
}, {
|
|
120
|
+
signal: abortController.signal,
|
|
121
|
+
once: true
|
|
122
|
+
});
|
|
123
|
+
cancelClose = () => {
|
|
124
|
+
abortController.abort();
|
|
125
|
+
cancelClose = null;
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
function cancelPendingClose() {
|
|
129
|
+
cancelClose?.();
|
|
130
|
+
}
|
|
131
|
+
return {
|
|
132
|
+
isClosing,
|
|
133
|
+
scheduleClose,
|
|
134
|
+
cancelPendingClose
|
|
42
135
|
};
|
|
43
136
|
}
|
|
44
137
|
//#endregion
|
|
@@ -73,6 +166,26 @@ function onEscape(callback) {
|
|
|
73
166
|
});
|
|
74
167
|
}
|
|
75
168
|
//#endregion
|
|
169
|
+
//#region src/utils/open-state-store/open-state-store.ts
|
|
170
|
+
function createOpenStateStore(initial = false) {
|
|
171
|
+
let state = initial;
|
|
172
|
+
const listeners = /* @__PURE__ */ new Set();
|
|
173
|
+
return {
|
|
174
|
+
getState: () => state,
|
|
175
|
+
setState(next) {
|
|
176
|
+
if (state === next) return;
|
|
177
|
+
state = next;
|
|
178
|
+
for (const listener of listeners) listener();
|
|
179
|
+
},
|
|
180
|
+
subscribe(listener) {
|
|
181
|
+
listeners.add(listener);
|
|
182
|
+
return () => {
|
|
183
|
+
listeners.delete(listener);
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
//#endregion
|
|
76
189
|
//#region src/utils/set-element-size.ts
|
|
77
190
|
var getValueWithUnits = (value) => {
|
|
78
191
|
if (typeof value === "string" && !value.match(/^[0-9]+$/)) return value;
|
|
@@ -85,6 +198,7 @@ var setElementSize = (element, { width, height }) => {
|
|
|
85
198
|
};
|
|
86
199
|
//#endregion
|
|
87
200
|
//#region src/factories/create-dialog/create-dialog.ts
|
|
201
|
+
var noop$3 = () => {};
|
|
88
202
|
function createDialogElement() {
|
|
89
203
|
const container = document.createElement("dialog");
|
|
90
204
|
container.classList.add("rvv-dialog");
|
|
@@ -99,15 +213,18 @@ function unmountElement$2(element) {
|
|
|
99
213
|
element.remove();
|
|
100
214
|
}
|
|
101
215
|
function createDialog(options, element) {
|
|
216
|
+
const store = createOpenStateStore();
|
|
102
217
|
if (!is.browser()) return {
|
|
103
|
-
toggle:
|
|
104
|
-
open:
|
|
105
|
-
close:
|
|
106
|
-
unmount:
|
|
107
|
-
refresh:
|
|
108
|
-
focus:
|
|
218
|
+
toggle: noop$3,
|
|
219
|
+
open: noop$3,
|
|
220
|
+
close: noop$3,
|
|
221
|
+
unmount: noop$3,
|
|
222
|
+
refresh: noop$3,
|
|
223
|
+
focus: noop$3,
|
|
224
|
+
isOpen: store.getState,
|
|
225
|
+
subscribe: store.subscribe
|
|
109
226
|
};
|
|
110
|
-
const { iframe, refresh, focus } = createIframe(options);
|
|
227
|
+
const { iframe, refresh, focus, onMessage } = createIframe(options);
|
|
111
228
|
const container = element ?? document.body;
|
|
112
229
|
const dialog = createDialogElement();
|
|
113
230
|
const wrapper = createDialogWrapper();
|
|
@@ -123,21 +240,35 @@ function createDialog(options, element) {
|
|
|
123
240
|
onEscape(close);
|
|
124
241
|
}
|
|
125
242
|
};
|
|
243
|
+
const guard = createClosingGuard();
|
|
126
244
|
function open() {
|
|
127
|
-
if (is.open(wrapper))
|
|
245
|
+
if (is.open(wrapper)) {
|
|
246
|
+
if (guard.isClosing()) {
|
|
247
|
+
guard.cancelPendingClose();
|
|
248
|
+
store.setState(true);
|
|
249
|
+
return;
|
|
250
|
+
}
|
|
251
|
+
return;
|
|
252
|
+
}
|
|
128
253
|
dialog.append(wrapper);
|
|
129
254
|
dialog.showModal();
|
|
255
|
+
store.setState(true);
|
|
130
256
|
}
|
|
131
257
|
function close() {
|
|
132
258
|
if (!is.open(wrapper)) return;
|
|
133
259
|
dialog.close();
|
|
134
|
-
unmountElement$2(wrapper);
|
|
260
|
+
guard.scheduleClose(dialog, () => unmountElement$2(wrapper));
|
|
261
|
+
store.setState(false);
|
|
135
262
|
}
|
|
136
263
|
function toggle() {
|
|
137
264
|
is.open(wrapper) ? close() : open();
|
|
138
265
|
}
|
|
266
|
+
const removeOnMessageHandler = onMessage((msg) => {
|
|
267
|
+
if (msg === IFRAME_MESSAGES.close) close();
|
|
268
|
+
});
|
|
139
269
|
function unmount() {
|
|
140
270
|
unmountElement$2(dialog);
|
|
271
|
+
removeOnMessageHandler();
|
|
141
272
|
}
|
|
142
273
|
return {
|
|
143
274
|
toggle,
|
|
@@ -145,59 +276,14 @@ function createDialog(options, element) {
|
|
|
145
276
|
close,
|
|
146
277
|
unmount,
|
|
147
278
|
refresh,
|
|
148
|
-
focus
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
//#endregion
|
|
152
|
-
//#region src/utils/built-button/built-button.ts
|
|
153
|
-
var defaultIcon = `
|
|
154
|
-
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-message-square-icon lucide-message-square"><path d="M22 17a2 2 0 0 1-2 2H6.828a2 2 0 0 0-1.414.586l-2.202 2.202A.71.71 0 0 1 2 21.286V5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2z"/></svg>`;
|
|
155
|
-
var closeIcon = `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-x-icon lucide-x"><path d="M18 6 6 18"/><path d="m6 6 12 12"/></svg>`;
|
|
156
|
-
function buildDefaultIcons() {
|
|
157
|
-
const openEl = document.createElement("span");
|
|
158
|
-
openEl.classList.add("rvv-button-icon--open");
|
|
159
|
-
openEl.innerHTML = defaultIcon;
|
|
160
|
-
const closeEl = document.createElement("span");
|
|
161
|
-
closeEl.classList.add("rvv-button-icon--close");
|
|
162
|
-
closeEl.innerHTML = closeIcon;
|
|
163
|
-
return {
|
|
164
|
-
openEl,
|
|
165
|
-
closeEl
|
|
166
|
-
};
|
|
167
|
-
}
|
|
168
|
-
function buildButtonElement(options) {
|
|
169
|
-
const button = document.createElement("button");
|
|
170
|
-
button.classList.add("rvv-button", "rvv-button--trigger");
|
|
171
|
-
button.setAttribute("type", "button");
|
|
172
|
-
button.dataset.position = options.position ?? "right";
|
|
173
|
-
button.dataset.open = "false";
|
|
174
|
-
if (options.color) button.style.setProperty("--rvv-button-color", options.color);
|
|
175
|
-
if (options.textColor) button.style.setProperty("--rvv-button-text-color", options.textColor);
|
|
176
|
-
const iconWrapper = document.createElement("span");
|
|
177
|
-
iconWrapper.classList.add("rvv-button-icon");
|
|
178
|
-
iconWrapper.setAttribute("aria-hidden", "true");
|
|
179
|
-
if (options.label) {
|
|
180
|
-
const labelEl = document.createElement("span");
|
|
181
|
-
labelEl.classList.add("rvv-button-label");
|
|
182
|
-
labelEl.textContent = options.label;
|
|
183
|
-
button.append(labelEl);
|
|
184
|
-
}
|
|
185
|
-
if (options.icon) iconWrapper.innerHTML = options.icon;
|
|
186
|
-
else if (!options.label) {
|
|
187
|
-
const { openEl, closeEl } = buildDefaultIcons();
|
|
188
|
-
iconWrapper.append(openEl, closeEl);
|
|
189
|
-
}
|
|
190
|
-
if (iconWrapper.childNodes.length > 0) button.append(iconWrapper);
|
|
191
|
-
function setOpen(isOpen) {
|
|
192
|
-
button.dataset.open = String(isOpen);
|
|
193
|
-
}
|
|
194
|
-
return {
|
|
195
|
-
el: button,
|
|
196
|
-
setOpen
|
|
279
|
+
focus,
|
|
280
|
+
isOpen: store.getState,
|
|
281
|
+
subscribe: store.subscribe
|
|
197
282
|
};
|
|
198
283
|
}
|
|
199
284
|
//#endregion
|
|
200
285
|
//#region src/factories/create-drawer/create-drawer.ts
|
|
286
|
+
var noop$2 = () => {};
|
|
201
287
|
function createDrawerElement() {
|
|
202
288
|
const container = document.createElement("div");
|
|
203
289
|
container.classList.add("rvv-drawer");
|
|
@@ -212,15 +298,18 @@ function unmountElement$1(element) {
|
|
|
212
298
|
element.remove();
|
|
213
299
|
}
|
|
214
300
|
function createDrawer(options, element) {
|
|
301
|
+
const store = createOpenStateStore();
|
|
215
302
|
if (!is.browser()) return {
|
|
216
|
-
toggle:
|
|
217
|
-
open:
|
|
218
|
-
close:
|
|
219
|
-
unmount:
|
|
220
|
-
refresh:
|
|
221
|
-
focus:
|
|
303
|
+
toggle: noop$2,
|
|
304
|
+
open: noop$2,
|
|
305
|
+
close: noop$2,
|
|
306
|
+
unmount: noop$2,
|
|
307
|
+
refresh: noop$2,
|
|
308
|
+
focus: noop$2,
|
|
309
|
+
isOpen: store.getState,
|
|
310
|
+
subscribe: store.subscribe
|
|
222
311
|
};
|
|
223
|
-
const { iframe, refresh, focus } = createIframe(options);
|
|
312
|
+
const { iframe, refresh, focus, onMessage } = createIframe(options);
|
|
224
313
|
const container = element ?? document.body;
|
|
225
314
|
const drawer = createDrawerElement();
|
|
226
315
|
const wrapper = createDrawerWrapper();
|
|
@@ -230,49 +319,106 @@ function createDrawer(options, element) {
|
|
|
230
319
|
});
|
|
231
320
|
container.append(drawer);
|
|
232
321
|
wrapper.append(iframe);
|
|
233
|
-
const { autoOpen = false, autoOpenDelay = 0 } = options;
|
|
234
|
-
let setButtonOpen = () => {};
|
|
235
|
-
const { el: buttonEl, setOpen } = buildButtonElement(options);
|
|
236
|
-
setButtonOpen = setOpen;
|
|
237
|
-
buttonEl.addEventListener("click", () => toggle());
|
|
238
|
-
document.body.append(buttonEl);
|
|
239
322
|
iframe.onload = (event) => {
|
|
240
323
|
if (event?.isTrusted) {
|
|
241
324
|
drawer.classList.add("open");
|
|
242
325
|
onEscape(close);
|
|
243
326
|
}
|
|
244
327
|
};
|
|
328
|
+
const guard = createClosingGuard();
|
|
245
329
|
function open() {
|
|
246
|
-
if (is.open(wrapper))
|
|
330
|
+
if (is.open(wrapper)) {
|
|
331
|
+
if (guard.isClosing()) {
|
|
332
|
+
guard.cancelPendingClose();
|
|
333
|
+
drawer.classList.add("open");
|
|
334
|
+
store.setState(true);
|
|
335
|
+
return;
|
|
336
|
+
}
|
|
337
|
+
return;
|
|
338
|
+
}
|
|
247
339
|
drawer.append(wrapper);
|
|
248
|
-
|
|
340
|
+
store.setState(true);
|
|
249
341
|
}
|
|
250
342
|
function close() {
|
|
251
343
|
if (!is.open(wrapper)) return;
|
|
252
|
-
unmountElement$1(wrapper);
|
|
253
344
|
drawer.classList.remove("open");
|
|
254
|
-
|
|
345
|
+
store.setState(false);
|
|
346
|
+
guard.scheduleClose(drawer, () => unmountElement$1(wrapper));
|
|
255
347
|
}
|
|
256
348
|
function toggle() {
|
|
257
349
|
is.open(wrapper) ? close() : open();
|
|
258
350
|
}
|
|
351
|
+
const removeOnMessageHandler = onMessage((msg) => {
|
|
352
|
+
if (msg === IFRAME_MESSAGES.close) close();
|
|
353
|
+
});
|
|
259
354
|
function unmount() {
|
|
260
|
-
buttonEl?.remove();
|
|
261
355
|
unmountElement$1(drawer);
|
|
356
|
+
removeOnMessageHandler();
|
|
262
357
|
}
|
|
263
|
-
if (autoOpen) if (autoOpenDelay > 0) setTimeout(() => open(), autoOpenDelay);
|
|
264
|
-
else open();
|
|
265
358
|
return {
|
|
266
359
|
toggle,
|
|
267
360
|
open,
|
|
268
361
|
close,
|
|
269
362
|
unmount,
|
|
270
363
|
refresh,
|
|
271
|
-
focus
|
|
364
|
+
focus,
|
|
365
|
+
isOpen: store.getState,
|
|
366
|
+
subscribe: store.subscribe
|
|
367
|
+
};
|
|
368
|
+
}
|
|
369
|
+
//#endregion
|
|
370
|
+
//#region src/utils/icons.ts
|
|
371
|
+
var chatIcon = `
|
|
372
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-message-square-icon lucide-message-square"><path d="M22 17a2 2 0 0 1-2 2H6.828a2 2 0 0 0-1.414.586l-2.202 2.202A.71.71 0 0 1 2 21.286V5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2z"/></svg>`;
|
|
373
|
+
var closeIcon = `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-x-icon lucide-x"><path d="M18 6 6 18"/><path d="m6 6 12 12"/></svg>`;
|
|
374
|
+
//#endregion
|
|
375
|
+
//#region src/utils/built-button/built-button.ts
|
|
376
|
+
function buildDefaultIcons() {
|
|
377
|
+
const openEl = document.createElement("span");
|
|
378
|
+
openEl.classList.add("rvv-button-icon--open");
|
|
379
|
+
openEl.innerHTML = chatIcon;
|
|
380
|
+
const closeEl = document.createElement("span");
|
|
381
|
+
closeEl.classList.add("rvv-button-icon--close");
|
|
382
|
+
closeEl.innerHTML = closeIcon;
|
|
383
|
+
return {
|
|
384
|
+
openEl,
|
|
385
|
+
closeEl
|
|
386
|
+
};
|
|
387
|
+
}
|
|
388
|
+
function buildButtonElement(options) {
|
|
389
|
+
const button = document.createElement("button");
|
|
390
|
+
button.classList.add("rvv-button", "rvv-button--trigger");
|
|
391
|
+
button.setAttribute("type", "button");
|
|
392
|
+
button.dataset.position = options.position ?? "right";
|
|
393
|
+
button.dataset.open = "false";
|
|
394
|
+
if (options.color) button.style.setProperty("--rvv-button-color", options.color);
|
|
395
|
+
if (options.textColor) button.style.setProperty("--rvv-button-text-color", options.textColor);
|
|
396
|
+
const iconWrapper = document.createElement("span");
|
|
397
|
+
iconWrapper.classList.add("rvv-button-icon");
|
|
398
|
+
iconWrapper.setAttribute("aria-hidden", "true");
|
|
399
|
+
if (options.label) {
|
|
400
|
+
const labelEl = document.createElement("span");
|
|
401
|
+
labelEl.classList.add("rvv-button-label");
|
|
402
|
+
labelEl.textContent = options.label;
|
|
403
|
+
button.append(labelEl);
|
|
404
|
+
}
|
|
405
|
+
if (options.icon) iconWrapper.innerHTML = options.icon;
|
|
406
|
+
else if (!options.label) {
|
|
407
|
+
const { openEl, closeEl } = buildDefaultIcons();
|
|
408
|
+
iconWrapper.append(openEl, closeEl);
|
|
409
|
+
}
|
|
410
|
+
if (iconWrapper.childNodes.length > 0) button.append(iconWrapper);
|
|
411
|
+
function setOpen(isOpen) {
|
|
412
|
+
button.dataset.open = String(isOpen);
|
|
413
|
+
}
|
|
414
|
+
return {
|
|
415
|
+
el: button,
|
|
416
|
+
setOpen
|
|
272
417
|
};
|
|
273
418
|
}
|
|
274
419
|
//#endregion
|
|
275
420
|
//#region src/factories/create-popover/create-popover.ts
|
|
421
|
+
var noop$1 = () => {};
|
|
276
422
|
function createPopoverElement() {
|
|
277
423
|
const container = document.createElement("div");
|
|
278
424
|
container.classList.add("rvv-popover");
|
|
@@ -287,15 +433,18 @@ function unmountElement(element) {
|
|
|
287
433
|
element.remove();
|
|
288
434
|
}
|
|
289
435
|
function createPopover(options, element) {
|
|
436
|
+
const store = createOpenStateStore();
|
|
290
437
|
if (!is.browser()) return {
|
|
291
|
-
toggle:
|
|
292
|
-
close:
|
|
293
|
-
open:
|
|
294
|
-
unmount:
|
|
295
|
-
refresh:
|
|
296
|
-
focus:
|
|
438
|
+
toggle: noop$1,
|
|
439
|
+
close: noop$1,
|
|
440
|
+
open: noop$1,
|
|
441
|
+
unmount: noop$1,
|
|
442
|
+
refresh: noop$1,
|
|
443
|
+
focus: noop$1,
|
|
444
|
+
isOpen: store.getState,
|
|
445
|
+
subscribe: store.subscribe
|
|
297
446
|
};
|
|
298
|
-
const { iframe, refresh, focus } = createIframe(options);
|
|
447
|
+
const { iframe, refresh, focus, onMessage } = createIframe(options);
|
|
299
448
|
const container = element ?? document.body;
|
|
300
449
|
const popover = createPopoverElement();
|
|
301
450
|
const wrapper = createPopoverWrapper();
|
|
@@ -305,12 +454,17 @@ function createPopover(options, element) {
|
|
|
305
454
|
});
|
|
306
455
|
container.append(popover);
|
|
307
456
|
wrapper.append(iframe);
|
|
308
|
-
const { autoOpen = false, autoOpenDelay = 0 } = options;
|
|
309
|
-
let setButtonOpen =
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
457
|
+
const { autoOpen = false, autoOpenDelay = 0, trigger = "default" } = options;
|
|
458
|
+
let setButtonOpen = noop$1;
|
|
459
|
+
let unmountButton = noop$1;
|
|
460
|
+
if (trigger === "default") {
|
|
461
|
+
const { el: buttonEl, setOpen } = buildButtonElement(options);
|
|
462
|
+
buttonEl.classList.add("rvv-button--trigger-popover");
|
|
463
|
+
setButtonOpen = setOpen;
|
|
464
|
+
buttonEl.addEventListener("click", () => toggle());
|
|
465
|
+
document.body.append(buttonEl);
|
|
466
|
+
unmountButton = () => buttonEl.remove();
|
|
467
|
+
}
|
|
314
468
|
function toggle() {
|
|
315
469
|
is.open(wrapper) ? close() : open();
|
|
316
470
|
}
|
|
@@ -320,20 +474,35 @@ function createPopover(options, element) {
|
|
|
320
474
|
onEscape(close);
|
|
321
475
|
}
|
|
322
476
|
};
|
|
477
|
+
const guard = createClosingGuard();
|
|
323
478
|
function open() {
|
|
324
|
-
if (is.open(wrapper))
|
|
479
|
+
if (is.open(wrapper)) {
|
|
480
|
+
if (guard.isClosing()) {
|
|
481
|
+
guard.cancelPendingClose();
|
|
482
|
+
popover.classList.add("open");
|
|
483
|
+
store.setState(true);
|
|
484
|
+
return;
|
|
485
|
+
}
|
|
486
|
+
return;
|
|
487
|
+
}
|
|
325
488
|
popover.append(wrapper);
|
|
326
489
|
setButtonOpen(true);
|
|
490
|
+
store.setState(true);
|
|
327
491
|
}
|
|
328
492
|
function close() {
|
|
329
493
|
if (!is.open(wrapper)) return;
|
|
330
494
|
popover.classList.remove("open");
|
|
331
495
|
setButtonOpen(false);
|
|
332
|
-
|
|
496
|
+
store.setState(false);
|
|
497
|
+
guard.scheduleClose(popover, () => unmountElement(wrapper));
|
|
333
498
|
}
|
|
499
|
+
const removeOnMessageHandler = onMessage((msg) => {
|
|
500
|
+
if (msg === IFRAME_MESSAGES.close) close();
|
|
501
|
+
});
|
|
334
502
|
function unmount() {
|
|
335
|
-
|
|
503
|
+
unmountButton();
|
|
336
504
|
unmountElement(popover);
|
|
505
|
+
removeOnMessageHandler();
|
|
337
506
|
}
|
|
338
507
|
if (autoOpen) if (autoOpenDelay > 0) setTimeout(() => open(), autoOpenDelay);
|
|
339
508
|
else open();
|
|
@@ -343,16 +512,19 @@ function createPopover(options, element) {
|
|
|
343
512
|
open,
|
|
344
513
|
unmount,
|
|
345
514
|
refresh,
|
|
346
|
-
focus
|
|
515
|
+
focus,
|
|
516
|
+
isOpen: store.getState,
|
|
517
|
+
subscribe: store.subscribe
|
|
347
518
|
};
|
|
348
519
|
}
|
|
349
520
|
//#endregion
|
|
350
521
|
//#region src/factories/create-widget/create-widget.ts
|
|
522
|
+
var noop = () => {};
|
|
351
523
|
function createWidget(options, element) {
|
|
352
524
|
if (!is.browser()) return {
|
|
353
|
-
unmount:
|
|
354
|
-
refresh:
|
|
355
|
-
focus:
|
|
525
|
+
unmount: noop,
|
|
526
|
+
refresh: noop,
|
|
527
|
+
focus: noop
|
|
356
528
|
};
|
|
357
529
|
const { iframe, refresh, focus } = createIframe(options);
|
|
358
530
|
const container = element ?? document.body;
|
|
@@ -380,4 +552,5 @@ exports.createPopover = createPopover;
|
|
|
380
552
|
exports.createWidget = createWidget;
|
|
381
553
|
exports.embedId = embedId;
|
|
382
554
|
exports.formId = formId;
|
|
555
|
+
exports.integrationProfileId = integrationProfileId;
|
|
383
556
|
exports.tenantId = tenantId;
|