@deepfrog/pangents-widget 2.1.6 → 2.2.1

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 CHANGED
@@ -133,6 +133,61 @@ Initialize the widget with configuration.
133
133
 
134
134
  Update widget configuration dynamically.
135
135
 
136
+ #### Example: Fetch config from an API and update at runtime
137
+
138
+ ```html
139
+ <script type="module">
140
+ import Chatbot from 'https://cdn.jsdelivr.net/npm/@deepfrog/pangents-widget/dist/widget.min.js';
141
+
142
+ Chatbot.init({
143
+ pangentsApiKey: '<api_key>',
144
+ tenantId: '<tenant_id>'
145
+ });
146
+
147
+ async function loadWidgetConfig() {
148
+ const res = await fetch('https://api.example.com/widget-config?tenant=<tenant_id>');
149
+ if (!res.ok) throw new Error('Failed to load widget config');
150
+ const remote = await res.json();
151
+
152
+ Chatbot.updateConfig({
153
+ pangentsApiKey: remote.pangentsApiKey ?? '<api_key>',
154
+ tenantId: remote.tenantId ?? '<tenant_id>',
155
+ email: remote.email,
156
+ theme: remote.theme,
157
+ position: remote.position,
158
+ margin: remote.margin,
159
+ zIndex: remote.zIndex
160
+ });
161
+ }
162
+
163
+ loadWidgetConfig();
164
+ </script>
165
+ ```
166
+
167
+ ```ts
168
+ // ESM/bundlers
169
+ import Chatbot from '@deepfrog/pangents-widget/widget';
170
+
171
+ Chatbot.init({
172
+ pangentsApiKey: '<api_key>',
173
+ tenantId: '<tenant_id>'
174
+ });
175
+
176
+ const res = await fetch('/api/widget-config');
177
+ if (!res.ok) throw new Error('Failed to load widget config');
178
+ const cfg = await res.json();
179
+
180
+ Chatbot.updateConfig({
181
+ pangentsApiKey: cfg.pangentsApiKey,
182
+ tenantId: cfg.tenantId,
183
+ email: cfg.email,
184
+ theme: cfg.theme,
185
+ position: cfg.position,
186
+ margin: cfg.margin,
187
+ zIndex: cfg.zIndex
188
+ });
189
+ ```
190
+
136
191
  ### `Chatbot.updateTheme(theme)`
137
192
 
138
193
  Update only the theme configuration.
package/dist/Widget.d.ts CHANGED
@@ -6,6 +6,7 @@ interface WidgetProps extends Partial<WidgetConfig> {
6
6
  pangentsApiKey?: string;
7
7
  tenantId?: string;
8
8
  email?: string;
9
+ zIndex?: number;
9
10
  }
10
- export declare function Widget({ theme, className, position, margin, pangentsApiKey, tenantId, email }: WidgetProps): import("react/jsx-runtime").JSX.Element;
11
+ export declare function Widget({ theme, className, position, margin, pangentsApiKey, tenantId, email, zIndex }: WidgetProps): import("react/jsx-runtime").JSX.Element;
11
12
  export default Widget;
@@ -1,6 +1,7 @@
1
1
  interface WidgetBubbleProps {
2
2
  position?: 'bottom-right' | 'bottom-left' | 'top-right' | 'top-left';
3
3
  margin?: string;
4
+ zIndex?: number;
4
5
  }
5
- export declare function WidgetBubble({ position, margin }: WidgetBubbleProps): import("react/jsx-runtime").JSX.Element;
6
+ export declare function WidgetBubble({ position, margin, zIndex }: WidgetBubbleProps): import("react/jsx-runtime").JSX.Element;
6
7
  export {};
@@ -1,5 +1,6 @@
1
1
  interface WidgetPopupProps {
2
2
  position?: 'bottom-right' | 'bottom-left' | 'top-right' | 'top-left';
3
+ zIndex?: number;
3
4
  }
4
- export declare function WidgetPopup({ position }: WidgetPopupProps): import("react/jsx-runtime").JSX.Element;
5
+ export declare function WidgetPopup({ position, zIndex }: WidgetPopupProps): import("react/jsx-runtime").JSX.Element;
5
6
  export {};
package/dist/index.cjs.js CHANGED
@@ -6,5 +6,5 @@
6
6
  }
7
7
  } catch (error) {}
8
8
  })();
9
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./widget-embed-9DdEqVMP.cjs.js"),t=require("react/jsx-runtime"),n=require("react"),o=e=>Object.freeze(Object.defineProperty({__proto__:null,default:e},Symbol.toStringTag,{value:"Module"}));if("undefined"!=typeof window)try{const e=window.__PANGENTS_WIDGET_CSS;if(e&&!document.getElementById("pangents-widget-styles")){const t=document.createElement("style");t.id="pangents-widget-styles",t.textContent=e,document.head.appendChild(t)}}catch{}exports.Chatbot=e.Chatbot,exports.Widget=e.Widget,exports.ChatbotWidget=({pangentsApiKey:e,email:r,tenantId:i,theme:s,position:d="bottom-right",zIndex:c=9999,onInit:a,onDestroy:l})=>{const u=n.useRef(null),g=n.useRef(null);return n.useEffect(()=>((async()=>{try{const{default:t}=await Promise.resolve().then(()=>o(require("./widget-embed.cjs.js"))),n={pangentsApiKey:e,email:r,tenantId:i,theme:s,position:d,zIndex:c};u.current=t,t.init(n),a&&a()}catch(t){console.error("Failed to initialize chatbot widget:",t)}})(),()=>{if(u.current)try{u.current.destroy(),l&&l()}catch(e){console.error("Error destroying chatbot widget:",e)}}),[e,r,i,s,d,c,a,l]),n.useEffect(()=>{if(u.current){const n={pangentsApiKey:e,email:r,tenantId:i,theme:s,position:d,zIndex:c};try{u.current.updateConfig(n)}catch(t){console.error("Error updating chatbot widget config:",t)}}},[e,r,i,s,d,c]),t.jsx("div",{ref:g,style:{display:"none"}})};
9
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./widget-embed-DgFZhnDu.cjs.js"),t=require("react/jsx-runtime"),n=require("react"),o=e=>Object.freeze(Object.defineProperty({__proto__:null,default:e},Symbol.toStringTag,{value:"Module"}));if("undefined"!=typeof window)try{const e=window.__PANGENTS_WIDGET_CSS;if(e&&!document.getElementById("pangents-widget-styles")){const t=document.createElement("style");t.id="pangents-widget-styles",t.textContent=e,document.head.appendChild(t)}}catch{}exports.Chatbot=e.Chatbot,exports.Widget=e.Widget,exports.ChatbotWidget=({pangentsApiKey:e,email:r,tenantId:i,theme:s,position:d="bottom-right",zIndex:c=9999,onInit:a,onDestroy:l})=>{const u=n.useRef(null),g=n.useRef(null);return n.useEffect(()=>((async()=>{try{const{default:t}=await Promise.resolve().then(()=>o(require("./widget-embed.cjs.js"))),n={pangentsApiKey:e,email:r,tenantId:i,theme:s,position:d,zIndex:c};u.current=t,t.init(n),a&&a()}catch(t){console.error("Failed to initialize chatbot widget:",t)}})(),()=>{if(u.current)try{u.current.destroy(),l&&l()}catch(e){console.error("Error destroying chatbot widget:",e)}}),[e,r,i,s,d,c,a,l]),n.useEffect(()=>{if(u.current){const n={pangentsApiKey:e,email:r,tenantId:i,theme:s,position:d,zIndex:c};try{u.current.updateConfig(n)}catch(t){console.error("Error updating chatbot widget config:",t)}}},[e,r,i,s,d,c]),t.jsx("div",{ref:g,style:{display:"none"}})};
10
10
  //# sourceMappingURL=index.cjs.js.map
package/dist/index.es.js CHANGED
@@ -6,7 +6,7 @@
6
6
  }
7
7
  } catch (error) {}
8
8
  })();
9
- import { C, W } from "./widget-embed-LzSoeVtX.es.js";
9
+ import { C, W } from "./widget-embed-B3A5H6pf.es.js";
10
10
  import { jsx } from "react/jsx-runtime";
11
11
  import { useRef, useEffect } from "react";
12
12
  const ChatbotWidget = ({
@@ -26,6 +26,7 @@ export interface WidgetConfig {
26
26
  pangentsApiKey: string;
27
27
  tenantId?: string;
28
28
  theme?: WidgetTheme;
29
+ zIndex?: number;
29
30
  }
30
31
  export interface ChatState {
31
32
  isOpen: boolean;
@@ -28,7 +28,7 @@ var __privateWrapper = (obj, member, setter, getter) => ({
28
28
  var _provider, _providerCalled, _a, _focused, _cleanup, _setup, _b, _online, _cleanup2, _setup2, _c, _gcTimeout, _d, _initialState, _revertState, _cache, _client, _retryer, _defaultOptions, _abortSignalConsumed, _Query_instances, dispatch_fn, _e, _client2, _currentQuery, _currentQueryInitialState, _currentResult, _currentResultState, _currentResultOptions, _currentThenable, _selectError, _selectFn, _selectResult, _lastQueryWithDefinedData, _staleTimeoutId, _refetchIntervalId, _currentRefetchInterval, _trackedProps, _QueryObserver_instances, executeFetch_fn, updateStaleTimeout_fn, computeRefetchInterval_fn, updateRefetchInterval_fn, updateTimers_fn, clearStaleTimeout_fn, clearRefetchInterval_fn, updateQuery_fn, notify_fn, _f, _client3, _observers, _mutationCache, _retryer2, _Mutation_instances, dispatch_fn2, _g, _mutations, _scopes, _mutationId, _h, _client4, _currentResult2, _currentMutation, _mutateOptions, _MutationObserver_instances, updateResult_fn, notify_fn2, _i, _queries, _j, _queryCache, _mutationCache2, _defaultOptions2, _queryDefaults, _mutationDefaults, _mountCount, _unsubscribeFocus, _unsubscribeOnline, _k;
29
29
  import { jsx, Fragment, jsxs } from "react/jsx-runtime";
30
30
  import * as React from "react";
31
- import React__default, { useReducer, useRef, useEffect, createContext, useContext, useLayoutEffect, useId, useInsertionEffect, useMemo, useCallback, Children, isValidElement, useState, Fragment as Fragment$1, createElement, forwardRef, Component } from "react";
31
+ import React__default, { createContext, useContext, useReducer, useRef, useEffect, useLayoutEffect, useId, useInsertionEffect, useMemo, useCallback, Children, isValidElement, useState, Fragment as Fragment$1, createElement, forwardRef, Component } from "react";
32
32
  import ReactDOM from "react-dom";
33
33
  var Subscribable = class {
34
34
  constructor() {
@@ -16793,7 +16793,7 @@ class EnhancedErrorHandler {
16793
16793
  // 30 seconds
16794
16794
  constructor() {
16795
16795
  __publicField(this, "errorQueue", []);
16796
- __publicField(this, "isOnline", navigator.onLine);
16796
+ __publicField(this, "isOnline", typeof navigator !== "undefined" ? navigator.onLine : true);
16797
16797
  __publicField(this, "maxQueueSize", 50);
16798
16798
  // Reduced from 100
16799
16799
  __publicField(this, "retryAttempts", 2);
@@ -16809,6 +16809,7 @@ class EnhancedErrorHandler {
16809
16809
  }
16810
16810
  // Setup event listeners for online/offline status
16811
16811
  setupEventListeners() {
16812
+ if (typeof window === "undefined") return;
16812
16813
  window.addEventListener("online", () => {
16813
16814
  this.isOnline = true;
16814
16815
  this.flushErrorQueue();
@@ -16875,8 +16876,8 @@ class EnhancedErrorHandler {
16875
16876
  action: (context == null ? void 0 : context.action) || "Unknown",
16876
16877
  userId: context == null ? void 0 : context.userId,
16877
16878
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
16878
- userAgent: navigator.userAgent,
16879
- url: window.location.href,
16879
+ userAgent: typeof navigator !== "undefined" ? navigator.userAgent : "server",
16880
+ url: typeof window !== "undefined" ? window.location.href : "",
16880
16881
  apiKey: (context == null ? void 0 : context.apiKey) ? context.apiKey.substring(0, 20) + "..." : void 0
16881
16882
  };
16882
16883
  const severity = this.determineSeverity(apiError);
@@ -16909,8 +16910,8 @@ class EnhancedErrorHandler {
16909
16910
  action: (context == null ? void 0 : context.action) || "Runtime",
16910
16911
  userId: context == null ? void 0 : context.userId,
16911
16912
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
16912
- userAgent: navigator.userAgent,
16913
- url: window.location.href
16913
+ userAgent: typeof navigator !== "undefined" ? navigator.userAgent : "server",
16914
+ url: typeof window !== "undefined" ? window.location.href : ""
16914
16915
  };
16915
16916
  const errorReport = {
16916
16917
  error: apiError,
@@ -16989,9 +16990,9 @@ class EnhancedErrorHandler {
16989
16990
  await api2.post("/errors/report", {
16990
16991
  errors: errorsToSend,
16991
16992
  clientInfo: {
16992
- userAgent: navigator.userAgent,
16993
+ userAgent: typeof navigator !== "undefined" ? navigator.userAgent : "server",
16993
16994
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
16994
- url: window.location.href,
16995
+ url: typeof window !== "undefined" ? window.location.href : "",
16995
16996
  circuitBreakerState: this.circuitBreaker.getState(),
16996
16997
  remainingRateLimit: this.rateLimiter.getRemainingRequests()
16997
16998
  }
@@ -17026,15 +17027,17 @@ class EnhancedErrorHandler {
17026
17027
  // Show user notification based on error severity
17027
17028
  showUserNotification(error, severity) {
17028
17029
  const message = this.getUserFriendlyMessage(error);
17029
- window.dispatchEvent(new CustomEvent("error:notification", {
17030
- detail: {
17031
- message,
17032
- severity,
17033
- error,
17034
- timestamp: (/* @__PURE__ */ new Date()).toISOString(),
17035
- canRetry: this.canRetryError(error)
17036
- }
17037
- }));
17030
+ if (typeof window !== "undefined") {
17031
+ window.dispatchEvent(new CustomEvent("error:notification", {
17032
+ detail: {
17033
+ message,
17034
+ severity,
17035
+ error,
17036
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
17037
+ canRetry: this.canRetryError(error)
17038
+ }
17039
+ }));
17040
+ }
17038
17041
  }
17039
17042
  // Determine if error can be retried
17040
17043
  canRetryError(error) {
@@ -17839,7 +17842,7 @@ const useEmailLeadsStore = create()(
17839
17842
  }
17840
17843
  }))
17841
17844
  );
17842
- function WidgetBubble({ position = "bottom-right", margin }) {
17845
+ function WidgetBubble({ position = "bottom-right", margin, zIndex }) {
17843
17846
  const { openWidget, theme, isOpen, isAuthenticated } = useChatContext();
17844
17847
  const { hasNewLeads, newLeadsCount, startPolling, stopPolling, clearNewLeadsNotification } = useEmailLeadsStore();
17845
17848
  useEffect(() => {
@@ -17868,7 +17871,7 @@ function WidgetBubble({ position = "bottom-right", margin }) {
17868
17871
  return "fixed bottom-6 right-6 z-50";
17869
17872
  }
17870
17873
  };
17871
- return /* @__PURE__ */ jsx("div", { className: getPositionClasses(), style: { margin: margin || void 0 }, children: /* @__PURE__ */ jsxs("div", { className: "relative", children: [
17874
+ return /* @__PURE__ */ jsx("div", { className: getPositionClasses(), style: { margin: margin || void 0, zIndex: zIndex || void 0 }, children: /* @__PURE__ */ jsxs("div", { className: "relative", children: [
17872
17875
  /* @__PURE__ */ jsxs(
17873
17876
  Button,
17874
17877
  {
@@ -29380,7 +29383,7 @@ function WidgetContent() {
29380
29383
  /* @__PURE__ */ jsx(PoweredByFooter, {})
29381
29384
  ] });
29382
29385
  }
29383
- function WidgetPopup({ position = "bottom-right" }) {
29386
+ function WidgetPopup({ position = "bottom-right", zIndex }) {
29384
29387
  const { isOpen, theme, closeWidget, isAuthenticated } = useChatContext();
29385
29388
  const isLeftPosition = position === "bottom-left" || position === "top-left";
29386
29389
  const containerRef = useRef(null);
@@ -29504,6 +29507,7 @@ function WidgetPopup({ position = "bottom-right" }) {
29504
29507
  motion.div,
29505
29508
  {
29506
29509
  className: "fixed inset-0 z-50",
29510
+ style: { zIndex: zIndex ?? 50 },
29507
29511
  initial: { opacity: 0 },
29508
29512
  animate: { opacity: 1 },
29509
29513
  exit: { opacity: 0 },
@@ -29673,10 +29677,22 @@ function WidgetPopup({ position = "bottom-right" }) {
29673
29677
  }
29674
29678
  ) });
29675
29679
  }
29676
- function Widget({ theme, className, position, margin, pangentsApiKey, tenantId, email }) {
29680
+ function Widget({ theme, className, position, margin, pangentsApiKey, tenantId, email, zIndex }) {
29681
+ useEffect(() => {
29682
+ try {
29683
+ const css = window.__PANGENTS_WIDGET_CSS;
29684
+ if (css && !document.getElementById("pangents-widget-styles")) {
29685
+ const style = document.createElement("style");
29686
+ style.id = "pangents-widget-styles";
29687
+ style.textContent = css;
29688
+ document.head.appendChild(style);
29689
+ }
29690
+ } catch {
29691
+ }
29692
+ }, []);
29677
29693
  return /* @__PURE__ */ jsx("div", { className: className ? `pg-widget-root ${className}` : "pg-widget-root", children: /* @__PURE__ */ jsx(QueryClientProvider, { client: queryClient, children: /* @__PURE__ */ jsxs(ChatProvider, { initialTheme: theme, apiKey: pangentsApiKey, tenantId, email, children: [
29678
- /* @__PURE__ */ jsx(WidgetBubble, { position, margin }),
29679
- /* @__PURE__ */ jsx(WidgetPopup, { position })
29694
+ /* @__PURE__ */ jsx(WidgetBubble, { position, margin, zIndex }),
29695
+ /* @__PURE__ */ jsx(WidgetPopup, { position, zIndex })
29680
29696
  ] }) }) });
29681
29697
  }
29682
29698
  var client = {};
@@ -29820,4 +29836,4 @@ export {
29820
29836
  Chatbot as C,
29821
29837
  Widget as W
29822
29838
  };
29823
- //# sourceMappingURL=widget-embed-LzSoeVtX.es.js.map
29839
+ //# sourceMappingURL=widget-embed-B3A5H6pf.es.js.map