@feedvalue/core 0.1.5 → 0.1.7
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/index.cjs +57 -33
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +9 -2
- package/dist/index.d.ts +9 -2
- package/dist/index.js +57 -33
- package/dist/index.js.map +1 -1
- package/dist/umd/index.min.js +9 -7
- package/dist/umd/index.min.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -387,7 +387,7 @@ var DEFAULT_CONFIG = {
|
|
|
387
387
|
locale: "en"
|
|
388
388
|
};
|
|
389
389
|
var instances = /* @__PURE__ */ new Map();
|
|
390
|
-
var
|
|
390
|
+
var _FeedValue = class _FeedValue {
|
|
391
391
|
/**
|
|
392
392
|
* Create a new FeedValue instance
|
|
393
393
|
* Use FeedValue.init() for public API
|
|
@@ -421,6 +421,8 @@ var FeedValue = class _FeedValue {
|
|
|
421
421
|
__publicField(this, "stylesInjected", false);
|
|
422
422
|
// Auto-close timeout reference (for cleanup on destroy)
|
|
423
423
|
__publicField(this, "autoCloseTimeout", null);
|
|
424
|
+
// Destroyed flag - guards async continuations (fixes React StrictMode race condition)
|
|
425
|
+
__publicField(this, "isDestroyed", false);
|
|
424
426
|
this.widgetId = options.widgetId;
|
|
425
427
|
this.headless = options.headless ?? false;
|
|
426
428
|
this.config = { ...DEFAULT_CONFIG, ...options.config };
|
|
@@ -465,11 +467,19 @@ var FeedValue = class _FeedValue {
|
|
|
465
467
|
this.log("Already initialized");
|
|
466
468
|
return;
|
|
467
469
|
}
|
|
470
|
+
if (this.isDestroyed) {
|
|
471
|
+
this.log("Instance destroyed before init could complete");
|
|
472
|
+
return;
|
|
473
|
+
}
|
|
468
474
|
try {
|
|
469
475
|
this.log("Initializing...");
|
|
470
476
|
const fingerprint = generateFingerprint();
|
|
471
477
|
this.apiClient.setFingerprint(fingerprint);
|
|
472
478
|
const configResponse = await this.apiClient.fetchConfig(this.widgetId);
|
|
479
|
+
if (this.isDestroyed) {
|
|
480
|
+
this.log("Instance destroyed during config fetch, aborting init");
|
|
481
|
+
return;
|
|
482
|
+
}
|
|
473
483
|
this.widgetConfig = {
|
|
474
484
|
widgetId: configResponse.widget_id,
|
|
475
485
|
widgetKey: configResponse.widget_key,
|
|
@@ -511,6 +521,7 @@ var FeedValue = class _FeedValue {
|
|
|
511
521
|
*/
|
|
512
522
|
destroy() {
|
|
513
523
|
this.log("Destroying...");
|
|
524
|
+
this.isDestroyed = true;
|
|
514
525
|
if (this.autoCloseTimeout) {
|
|
515
526
|
clearTimeout(this.autoCloseTimeout);
|
|
516
527
|
this.autoCloseTimeout = null;
|
|
@@ -882,9 +893,6 @@ var FeedValue = class _FeedValue {
|
|
|
882
893
|
.fv-widget-trigger {
|
|
883
894
|
position: fixed;
|
|
884
895
|
${positionStyles}
|
|
885
|
-
display: inline-flex;
|
|
886
|
-
align-items: center;
|
|
887
|
-
gap: 8px;
|
|
888
896
|
background-color: ${styling.primaryColor};
|
|
889
897
|
color: ${styling.buttonTextColor};
|
|
890
898
|
padding: 12px 24px;
|
|
@@ -903,13 +911,18 @@ var FeedValue = class _FeedValue {
|
|
|
903
911
|
box-shadow: 0 6px 12px rgba(0, 0, 0, 0.15);
|
|
904
912
|
}
|
|
905
913
|
.fv-widget-trigger-icon {
|
|
914
|
+
width: 56px;
|
|
915
|
+
height: 56px;
|
|
916
|
+
padding: 14px;
|
|
917
|
+
border-radius: 50%;
|
|
906
918
|
display: flex;
|
|
907
919
|
align-items: center;
|
|
908
920
|
justify-content: center;
|
|
909
921
|
}
|
|
910
922
|
.fv-widget-trigger-icon svg {
|
|
911
|
-
width:
|
|
912
|
-
height:
|
|
923
|
+
width: 24px;
|
|
924
|
+
height: 24px;
|
|
925
|
+
stroke: currentColor;
|
|
913
926
|
}
|
|
914
927
|
.fv-widget-overlay {
|
|
915
928
|
position: fixed;
|
|
@@ -1065,50 +1078,49 @@ var FeedValue = class _FeedValue {
|
|
|
1065
1078
|
}
|
|
1066
1079
|
}
|
|
1067
1080
|
/**
|
|
1068
|
-
*
|
|
1081
|
+
* Parse SVG string to DOM element safely using DOMParser
|
|
1069
1082
|
*/
|
|
1070
|
-
|
|
1071
|
-
const icons = {
|
|
1072
|
-
chat: '<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/></svg>',
|
|
1073
|
-
message: '<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 11.5a8.38 8.38 0 0 1-.9 3.8 8.5 8.5 0 0 1-7.6 4.7 8.38 8.38 0 0 1-3.8-.9L3 21l1.9-5.7a8.38 8.38 0 0 1-.9-3.8 8.5 8.5 0 0 1 4.7-7.6 8.38 8.38 0 0 1 3.8-.9h.5a8.48 8.48 0 0 1 8 8v.5z"/></svg>',
|
|
1074
|
-
feedback: '<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M14 9V5a3 3 0 0 0-3-3l-4 9v11h11.28a2 2 0 0 0 2-1.7l1.38-9a2 2 0 0 0-2-2.3zM7 22H4a2 2 0 0 1-2-2v-7a2 2 0 0 1 2-2h3"/></svg>',
|
|
1075
|
-
comment: '<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/><line x1="9" y1="10" x2="15" y2="10"/></svg>',
|
|
1076
|
-
help: '<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><path d="M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3"/><line x1="12" y1="17" x2="12.01" y2="17"/></svg>',
|
|
1077
|
-
lightbulb: '<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="9" y1="18" x2="15" y2="18"/><line x1="10" y1="22" x2="14" y2="22"/><path d="M15.09 14c.18-.98.65-1.74 1.41-2.5A4.65 4.65 0 0 0 18 8 6 6 0 0 0 6 8c0 1 .23 2.23 1.5 3.5A4.61 4.61 0 0 1 8.91 14"/></svg>'
|
|
1078
|
-
};
|
|
1079
|
-
const svgString = icons[iconType];
|
|
1080
|
-
if (!svgString) return null;
|
|
1083
|
+
parseSvgString(svgString) {
|
|
1081
1084
|
const parser = new DOMParser();
|
|
1082
1085
|
const doc = parser.parseFromString(svgString, "image/svg+xml");
|
|
1086
|
+
const parserError = doc.querySelector("parsererror");
|
|
1087
|
+
if (parserError) {
|
|
1088
|
+
this.log("SVG parse error:", parserError.textContent);
|
|
1089
|
+
return null;
|
|
1090
|
+
}
|
|
1083
1091
|
const svg = doc.querySelector("svg");
|
|
1084
1092
|
if (!svg || svg.nodeName !== "svg") return null;
|
|
1085
1093
|
return svg;
|
|
1086
1094
|
}
|
|
1087
1095
|
/**
|
|
1088
1096
|
* Render trigger button using safe DOM methods
|
|
1097
|
+
* Matches widget-bundle behavior: icon mode = circular button, text mode = rectangular
|
|
1098
|
+
* Falls back to text mode if icon rendering fails (fixes "square with ellipses" bug)
|
|
1089
1099
|
*/
|
|
1090
1100
|
renderTrigger() {
|
|
1091
1101
|
if (!this.widgetConfig) return;
|
|
1092
1102
|
const { triggerIcon, triggerText } = this.widgetConfig.config;
|
|
1103
|
+
const hasIcon = triggerIcon && triggerIcon !== "none";
|
|
1093
1104
|
this.triggerButton = document.createElement("button");
|
|
1094
|
-
|
|
1095
|
-
if (
|
|
1096
|
-
const
|
|
1097
|
-
if (
|
|
1098
|
-
const
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
this.triggerButton.appendChild(textSpan);
|
|
1105
|
+
let iconRendered = false;
|
|
1106
|
+
if (hasIcon) {
|
|
1107
|
+
const iconSvgString = _FeedValue.TRIGGER_ICONS[triggerIcon];
|
|
1108
|
+
if (iconSvgString) {
|
|
1109
|
+
const svgElement = this.parseSvgString(iconSvgString);
|
|
1110
|
+
if (svgElement) {
|
|
1111
|
+
this.triggerButton.className = "fv-widget-trigger fv-widget-trigger-icon";
|
|
1112
|
+
this.triggerButton.appendChild(svgElement);
|
|
1113
|
+
iconRendered = true;
|
|
1114
|
+
} else {
|
|
1115
|
+
this.log(`SVG parsing failed for icon: ${triggerIcon}, falling back to text`);
|
|
1106
1116
|
}
|
|
1107
1117
|
} else {
|
|
1108
|
-
this.
|
|
1118
|
+
this.log(`Icon not found: ${triggerIcon}, falling back to text`);
|
|
1109
1119
|
}
|
|
1110
|
-
}
|
|
1111
|
-
|
|
1120
|
+
}
|
|
1121
|
+
if (!iconRendered) {
|
|
1122
|
+
this.triggerButton.className = "fv-widget-trigger";
|
|
1123
|
+
this.triggerButton.textContent = triggerText || "Feedback";
|
|
1112
1124
|
}
|
|
1113
1125
|
this.triggerButton.addEventListener("click", () => this.open());
|
|
1114
1126
|
document.body.appendChild(this.triggerButton);
|
|
@@ -1265,6 +1277,18 @@ var FeedValue = class _FeedValue {
|
|
|
1265
1277
|
}
|
|
1266
1278
|
}
|
|
1267
1279
|
};
|
|
1280
|
+
/**
|
|
1281
|
+
* SVG icons for trigger button (matching widget-bundle exactly)
|
|
1282
|
+
*/
|
|
1283
|
+
__publicField(_FeedValue, "TRIGGER_ICONS", {
|
|
1284
|
+
chat: '<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"><path d="M7.9 20A9 9 0 1 0 4 16.1L2 22Z"/></svg>',
|
|
1285
|
+
message: '<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"><rect width="18" height="18" x="3" y="3" rx="2"/><path d="M8 12h.01"/><path d="M12 12h.01"/><path d="M16 12h.01"/></svg>',
|
|
1286
|
+
feedback: '<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"><path d="M14 9a2 2 0 0 1-2 2H6l-4 4V4c0-1.1.9-2 2-2h8a2 2 0 0 1 2 2v5Z"/><path d="M18 9h2a2 2 0 0 1 2 2v11l-4-4h-6a2 2 0 0 1-2-2v-1"/></svg>',
|
|
1287
|
+
comment: '<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"><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/><path d="M13 8H7"/><path d="M17 12H7"/></svg>',
|
|
1288
|
+
help: '<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"><circle cx="12" cy="12" r="10"/><path d="M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3"/><path d="M12 17h.01"/></svg>',
|
|
1289
|
+
lightbulb: '<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"><path d="M15 14c.2-1 .7-1.7 1.5-2.5 1-.9 1.5-2.2 1.5-3.5A6 6 0 0 0 6 8c0 1 .2 2.2 1.5 3.5.7.7 1.3 1.5 1.5 2.5"/><path d="M9 18h6"/><path d="M10 22h4"/></svg>'
|
|
1290
|
+
});
|
|
1291
|
+
var FeedValue = _FeedValue;
|
|
1268
1292
|
|
|
1269
1293
|
export { ApiClient, DEFAULT_API_BASE_URL, FeedValue, TypedEventEmitter, clearFingerprint, generateFingerprint };
|
|
1270
1294
|
//# sourceMappingURL=index.js.map
|