@helpway/react 0.3.4 → 0.4.0

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.d.ts CHANGED
@@ -1,48 +1,12 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import * as _helpway_widget_core from '@helpway/widget-core';
3
- import { WidgetStore } from '@helpway/widget-core';
4
- export { ConversationSummary, RealtimeEvent, TimelineItem, WidgetState, WidgetStore, clearVisitorId, formatRelativeTime, formatTime, getInitials, getOrCreateVisitorId } from '@helpway/widget-core';
3
+ import { HelpwayAPI, WidgetStore } from '@helpway/widget-core';
4
+ export { ConversationSummary, HelpwayAPI, RealtimeEvent, TimelineItem, WidgetEventName, WidgetEvents, WidgetState, WidgetStore, clearVisitorId, formatRelativeTime, formatTime, getInitials, getOrCreateVisitorId } from '@helpway/widget-core';
5
5
  import * as react from 'react';
6
6
  import react__default, { ReactNode } from 'react';
7
7
  import * as _helpway_types from '@helpway/types';
8
8
  import { TimelineItem, RealtimeEvent, TimelineItemPart } from '@helpway/types';
9
9
 
10
- interface IdentifyData {
11
- externalId: string;
12
- email?: string;
13
- name?: string;
14
- image?: string;
15
- metadata?: Record<string, unknown>;
16
- }
17
- /** Use a slice of the widget store with auto re-render */
18
- declare function useWidgetStore<T>(selector: (state: WidgetStore) => T): T;
19
- /** Hook to identify the current visitor (link to customer contact) */
20
- declare function useIdentify(): (data: IdentifyData) => Promise<void>;
21
- interface SupportProviderProps {
22
- /** Public API key (pk_xxx) */
23
- apiKey: string;
24
- /** API base URL (default: auto-detect from script tag or window) */
25
- apiUrl?: string;
26
- /** Widget locale (e.g., "fr", "de"). Falls back to navigator.language → "en" */
27
- locale?: string;
28
- /** Deep link: auto-open this conversation after bootstrap (from ?hw_conv= URL param) */
29
- initialConversationId?: string;
30
- /** Callback to expose widget API to parent (for embed loader) */
31
- onReady?: (api: {
32
- identify: (data: IdentifyData) => Promise<void>;
33
- openConversation: (id: string) => void;
34
- }) => void;
35
- children: ReactNode;
36
- }
37
- /**
38
- * Root provider for the Helpway widget.
39
- * Creates tRPC client, WebSocket connection, and state store.
40
- *
41
- * Visitor identity is managed via server-side cookies (hw_visitor).
42
- * No localStorage or client-side ID management needed.
43
- */
44
- declare function SupportProvider({ apiKey, apiUrl, locale, initialConversationId, onReady, children, }: SupportProviderProps): react_jsx_runtime.JSX.Element;
45
-
46
10
  interface HelpwayWidgetProps {
47
11
  /**
48
12
  * Public API key from the Helpway dashboard. Required.
@@ -67,12 +31,27 @@ interface HelpwayWidgetProps {
67
31
  initialConversationId?: string;
68
32
  /**
69
33
  * Called once after the widget has bootstrapped and exposes
70
- * programmatic APIs (identify, openConversation).
34
+ * the full programmatic API object (also available as `window.Helpway`).
71
35
  */
72
- onReady?: (api: {
73
- identify: (data: IdentifyData) => Promise<void>;
74
- openConversation: (id: string) => void;
75
- }) => void;
36
+ onReady?: (api: HelpwayPublicAPI) => void;
37
+ /**
38
+ * Hide the default floating launcher button. Use with
39
+ * `customLauncherSelector` or `window.Helpway.open()` to trigger
40
+ * the widget from your own UI.
41
+ */
42
+ hideLauncher?: boolean;
43
+ /**
44
+ * CSS selector for a custom trigger element (e.g. `"#support-btn"`).
45
+ * Clicking the matched element calls `Helpway.open()`. Combine with
46
+ * `hideLauncher` to fully replace the default bubble.
47
+ */
48
+ customLauncherSelector?: string;
49
+ /** Fires when the widget panel opens */
50
+ onOpen?: () => void;
51
+ /** Fires when the widget panel closes */
52
+ onClose?: () => void;
53
+ /** Fires when the unread count changes */
54
+ onUnreadChange?: (count: number) => void;
76
55
  /**
77
56
  * @deprecated Legacy prop from the v0.1 script-loader era. If set,
78
57
  * the `/widget.js` suffix is stripped to derive `apiUrl`. New code
@@ -80,12 +59,46 @@ interface HelpwayWidgetProps {
80
59
  */
81
60
  src?: string;
82
61
  }
62
+
63
+ type HelpwayPublicAPI = HelpwayAPI;
83
64
  /**
84
65
  * Render this once at the root of your app (e.g. in `_app.tsx`,
85
66
  * `layout.tsx`, or `main.tsx`). Unmounting cleanly tears down the
86
67
  * widget and its WebSocket connection — useful for route-scoped mounts.
87
68
  */
88
- declare function HelpwayWidget({ apiKey, apiUrl, locale, initialConversationId, onReady, src, }: HelpwayWidgetProps): react_jsx_runtime.JSX.Element;
69
+ declare function HelpwayWidget({ apiKey, apiUrl, locale, initialConversationId, onReady, hideLauncher, customLauncherSelector, onOpen, onClose, onUnreadChange, src, }: HelpwayWidgetProps): react_jsx_runtime.JSX.Element;
70
+
71
+ interface IdentifyData {
72
+ externalId: string;
73
+ email?: string;
74
+ name?: string;
75
+ image?: string;
76
+ metadata?: Record<string, unknown>;
77
+ }
78
+ /** Use a slice of the widget store with auto re-render */
79
+ declare function useWidgetStore<T>(selector: (state: WidgetStore) => T): T;
80
+ /** Hook to identify the current visitor (link to customer contact) */
81
+ declare function useIdentify(): (data: IdentifyData) => Promise<void>;
82
+ interface SupportProviderProps {
83
+ apiKey: string;
84
+ apiUrl?: string;
85
+ locale?: string;
86
+ initialConversationId?: string;
87
+ onReady?: (api: HelpwayAPI) => void;
88
+ customLauncherSelector?: string;
89
+ onOpen?: () => void;
90
+ onClose?: () => void;
91
+ onUnreadChange?: (count: number) => void;
92
+ children: ReactNode;
93
+ }
94
+ /**
95
+ * Root provider for the Helpway widget.
96
+ * Creates tRPC client, WebSocket connection, and state store.
97
+ *
98
+ * Visitor identity is managed via server-side cookies (hw_visitor).
99
+ * No localStorage or client-side ID management needed.
100
+ */
101
+ declare function SupportProvider({ apiKey, apiUrl, locale, initialConversationId, onReady, customLauncherSelector, onOpen, onClose, onUnreadChange, children, }: SupportProviderProps): react_jsx_runtime.JSX.Element;
89
102
 
90
103
  /**
91
104
  * Core widget state — connection status, visitor identity, website info.
@@ -216,8 +229,8 @@ declare function useRealtime(handler: (event: RealtimeEvent) => void): void;
216
229
  * Unified support widget — Intercom-style with tab navigation.
217
230
  * Two tabs: Home + Messages. Sub-views: conversation + new conversation.
218
231
  */
219
- declare function DefaultWidget({ initialOpen }?: {
220
- initialOpen?: boolean;
232
+ declare function DefaultWidget({ hideLauncher }?: {
233
+ hideLauncher?: boolean;
221
234
  }): react_jsx_runtime.JSX.Element;
222
235
 
223
236
  interface MessageBubbleProps {
@@ -292,4 +305,4 @@ declare function MarkdownContent({ bodyHtml, bodyMarkdown, className, }: {
292
305
  className?: string;
293
306
  }): react_jsx_runtime.JSX.Element | null;
294
307
 
295
- export { Composer, DefaultWidget, HelpwayWidget, type HelpwayWidgetProps, type IdentifyData, MarkdownContent, MessageBubble, MessageList, SupportProvider, linkifyText, renderMarkdown, useComposer, useConversations, useIdentify, usePresence, useRealtime, useTimeline, useUnread, useWidget, useWidgetStore };
308
+ export { Composer, DefaultWidget, type HelpwayPublicAPI, HelpwayWidget, type HelpwayWidgetProps, type IdentifyData, MarkdownContent, MessageBubble, MessageList, SupportProvider, linkifyText, renderMarkdown, useComposer, useConversations, useIdentify, usePresence, useRealtime, useTimeline, useUnread, useWidget, useWidgetStore };
package/dist/index.js CHANGED
@@ -221,8 +221,10 @@ function createWidgetStore() {
221
221
  typingUsers: /* @__PURE__ */ new Map(),
222
222
  aiProcessing: /* @__PURE__ */ new Map(),
223
223
  isOpen: false,
224
+ isDismissed: false,
224
225
  view: "home",
225
226
  incomingPreview: null,
227
+ newConversationPrefill: null,
226
228
  contentCache: /* @__PURE__ */ new Map(),
227
229
  // ── Lifecycle ────────────────────────────────────
228
230
  setReady(visitor, website, agentConfig) {
@@ -377,12 +379,17 @@ function createWidgetStore() {
377
379
  set((s) => ({
378
380
  isOpen: open,
379
381
  incomingPreview: open ? null : s.incomingPreview
380
- // dismiss preview when opening
381
382
  }));
382
383
  },
384
+ setDismissed(dismissed) {
385
+ set({ isDismissed: dismissed });
386
+ },
383
387
  setView(view) {
384
388
  set({ view });
385
389
  },
390
+ setNewConversationPrefill(text) {
391
+ set({ newConversationPrefill: text });
392
+ },
386
393
  dismissPreview() {
387
394
  set({ incomingPreview: null });
388
395
  },
@@ -488,6 +495,97 @@ function createWidgetStore() {
488
495
  }));
489
496
  }
490
497
 
498
+ // ../widget-core/src/api.ts
499
+ function createHelpwayAPI(deps) {
500
+ const { store, emitter, identify, apiKey } = deps;
501
+ return {
502
+ open() {
503
+ store.getState().setOpen(true);
504
+ store.getState().setDismissed(false);
505
+ },
506
+ close() {
507
+ store.getState().setOpen(false);
508
+ },
509
+ toggle() {
510
+ const s = store.getState();
511
+ if (s.isDismissed) {
512
+ s.setDismissed(false);
513
+ s.setOpen(true);
514
+ emitter.emit("show");
515
+ } else {
516
+ s.setOpen(!s.isOpen);
517
+ }
518
+ },
519
+ dismiss() {
520
+ store.getState().setOpen(false);
521
+ store.getState().setDismissed(true);
522
+ emitter.emit("dismiss");
523
+ },
524
+ show() {
525
+ store.getState().setDismissed(false);
526
+ emitter.emit("show");
527
+ },
528
+ shutdown() {
529
+ store.getState().setOpen(false);
530
+ store.getState().setDismissed(false);
531
+ clearVisitorId(apiKey);
532
+ if (typeof document !== "undefined") {
533
+ document.cookie = "hw_visitor=; Path=/; Max-Age=0";
534
+ }
535
+ },
536
+ identify,
537
+ newConversation(prefill) {
538
+ const s = store.getState();
539
+ s.setDismissed(false);
540
+ s.setOpen(true);
541
+ s.setNewConversationPrefill(prefill ?? "");
542
+ },
543
+ openConversation(id) {
544
+ const s = store.getState();
545
+ s.setDismissed(false);
546
+ s.setActiveConversation(id);
547
+ s.setOpen(true);
548
+ },
549
+ get unreadCount() {
550
+ return store.getState().conversations.reduce((sum, c) => sum + c.unreadCount, 0);
551
+ },
552
+ get isOpen() {
553
+ return store.getState().isOpen;
554
+ },
555
+ on(event, fn) {
556
+ emitter.on(event, fn);
557
+ },
558
+ off(event, fn) {
559
+ emitter.off(event, fn);
560
+ }
561
+ };
562
+ }
563
+
564
+ // ../widget-core/src/events.ts
565
+ var WidgetEventEmitter = class {
566
+ listeners = /* @__PURE__ */ new Map();
567
+ on(event, fn) {
568
+ if (!this.listeners.has(event)) this.listeners.set(event, /* @__PURE__ */ new Set());
569
+ this.listeners.get(event).add(fn);
570
+ }
571
+ off(event, fn) {
572
+ this.listeners.get(event)?.delete(fn);
573
+ }
574
+ emit(event, ...args) {
575
+ const data = args[0];
576
+ this.listeners.get(event)?.forEach((fn) => {
577
+ try {
578
+ fn(data);
579
+ } catch (err) {
580
+ console.error(`[Helpway] Event handler error (${event}):`, err);
581
+ }
582
+ });
583
+ }
584
+ removeAll() {
585
+ this.listeners.clear();
586
+ }
587
+ };
588
+
491
589
  // ../widget-core/src/i18n.ts
492
590
  var en = {
493
591
  // Navigation & tabs
@@ -758,6 +856,10 @@ function SupportProvider({
758
856
  locale,
759
857
  initialConversationId,
760
858
  onReady,
859
+ customLauncherSelector,
860
+ onOpen,
861
+ onClose,
862
+ onUnreadChange,
761
863
  children
762
864
  }) {
763
865
  const initRef = useRef(null);
@@ -771,6 +873,7 @@ function SupportProvider({
771
873
  apiKey
772
874
  });
773
875
  const store2 = createWidgetStore();
876
+ const emitter2 = new WidgetEventEmitter();
774
877
  const ws2 = new WebSocketManager({
775
878
  apiUrl: resolvedApiUrl,
776
879
  visitorId: "",
@@ -794,9 +897,13 @@ function SupportProvider({
794
897
  console.error("[Helpway] identify failed:", err);
795
898
  }
796
899
  };
797
- initRef.current = { client: client2, store: store2, ws: ws2, identify: identify2 };
900
+ const api2 = createHelpwayAPI({ store: store2, emitter: emitter2, identify: identify2, apiKey });
901
+ if (typeof window !== "undefined") {
902
+ window.Helpway = api2;
903
+ }
904
+ initRef.current = { client: client2, store: store2, ws: ws2, identify: identify2, api: api2, emitter: emitter2 };
798
905
  }
799
- const { client, store, ws, identify } = initRef.current;
906
+ const { client, store, ws, identify, api, emitter } = initRef.current;
800
907
  const retryBootstrap = useCallback(() => {
801
908
  setHasBootstrapError(false);
802
909
  setBootstrapAttempt((n) => n + 1);
@@ -851,11 +958,8 @@ function SupportProvider({
851
958
  store.getState().setActiveConversation(initialConversationId);
852
959
  store.getState().setOpen(true);
853
960
  }
854
- const openConversation = (id) => {
855
- store.getState().setActiveConversation(id);
856
- store.getState().setOpen(true);
857
- };
858
- onReady?.({ identify: initRef.current.identify, openConversation });
961
+ emitter.emit("ready");
962
+ onReady?.(initRef.current.api);
859
963
  } catch (err) {
860
964
  console.error("[Helpway] Bootstrap failed:", err);
861
965
  if (!cancelled) {
@@ -879,6 +983,13 @@ function SupportProvider({
879
983
  if (event.type === "timelineItemCreated") {
880
984
  const item = event.item;
881
985
  const isPublicIncoming = item?.visibility === "public" && !item.visitorId;
986
+ if (isPublicIncoming && item?.text) {
987
+ emitter.emit("messageReceived", {
988
+ conversationId: event.conversationId,
989
+ text: item.text,
990
+ senderName: "aiAgentId" in item && item.aiAgentId ? "AI" : null
991
+ });
992
+ }
882
993
  if (!isPublicIncoming) return;
883
994
  const s = store.getState();
884
995
  const isViewing = s.isOpen && s.activeConversationId === event.conversationId;
@@ -901,11 +1012,68 @@ function SupportProvider({
901
1012
  setLocale(locale);
902
1013
  }
903
1014
  }, [locale]);
1015
+ useEffect(() => {
1016
+ const unsub = store.subscribe((state, prev) => {
1017
+ if (state.isOpen && !prev.isOpen) {
1018
+ emitter.emit("open");
1019
+ onOpen?.();
1020
+ }
1021
+ if (!state.isOpen && prev.isOpen) {
1022
+ emitter.emit("close");
1023
+ onClose?.();
1024
+ }
1025
+ const prevUnread = prev.conversations.reduce((s, c) => s + c.unreadCount, 0);
1026
+ const nextUnread = state.conversations.reduce((s, c) => s + c.unreadCount, 0);
1027
+ if (nextUnread !== prevUnread) {
1028
+ emitter.emit("unreadChange", nextUnread);
1029
+ onUnreadChange?.(nextUnread);
1030
+ }
1031
+ });
1032
+ return unsub;
1033
+ }, [store, emitter, onOpen, onClose, onUnreadChange]);
1034
+ useEffect(() => {
1035
+ if (!customLauncherSelector) return;
1036
+ const handler = (e) => {
1037
+ e.preventDefault();
1038
+ api.toggle();
1039
+ };
1040
+ const attach = () => {
1041
+ const el2 = document.querySelector(customLauncherSelector);
1042
+ if (el2) {
1043
+ el2.addEventListener("click", handler);
1044
+ return el2;
1045
+ }
1046
+ return null;
1047
+ };
1048
+ let el = attach();
1049
+ let observer = null;
1050
+ if (!el) {
1051
+ observer = new MutationObserver(() => {
1052
+ el = attach();
1053
+ if (el) observer?.disconnect();
1054
+ });
1055
+ observer.observe(document.body, { childList: true, subtree: true });
1056
+ }
1057
+ return () => {
1058
+ el?.removeEventListener("click", handler);
1059
+ observer?.disconnect();
1060
+ };
1061
+ }, [customLauncherSelector, api]);
1062
+ useEffect(() => {
1063
+ return () => {
1064
+ if (window.Helpway === api) {
1065
+ window.Helpway = void 0;
1066
+ }
1067
+ emitter.removeAll();
1068
+ };
1069
+ }, [api, emitter]);
904
1070
  const ctxValue = {
905
1071
  client,
906
1072
  store,
907
1073
  ws,
908
1074
  identify,
1075
+ api,
1076
+ emitter,
909
1077
  hasBootstrapError,
910
1078
  wsDisconnected,
911
1079
  retryBootstrap
@@ -3381,12 +3549,13 @@ function AgentPresetIcon({ presetId }) {
3381
3549
  )
3382
3550
  );
3383
3551
  }
3384
- function DefaultWidget({ initialOpen = false } = {}) {
3552
+ function DefaultWidget({ hideLauncher = false } = {}) {
3385
3553
  const { isReady, website, agentConfig } = useWidget();
3386
3554
  useI18n();
3387
3555
  const { client, store, hasBootstrapError, wsDisconnected, retryBootstrap } = useWidgetContext();
3388
3556
  const { conversations, create, isCreating, setActiveConversation } = useConversations();
3389
3557
  const activeId = useWidgetStore((s) => s.activeConversationId);
3558
+ const isDismissed = useWidgetStore((s) => s.isDismissed);
3390
3559
  const { totalUnread } = useUnread();
3391
3560
  const contentTabs = useWidgetStore((s) => s.agentConfig?.contentTabs) ?? EMPTY_CONTENT_TABS;
3392
3561
  const visitorContact = useWidgetStore((s) => s.visitor?.contact);
@@ -3397,13 +3566,30 @@ function DefaultWidget({ initialOpen = false } = {}) {
3397
3566
  activeId
3398
3567
  });
3399
3568
  }
3400
- const [isOpen, setIsOpen] = useState12(initialOpen);
3569
+ const storeIsOpen = useWidgetStore((s) => s.isOpen);
3401
3570
  const [isClosing, setIsClosing] = useState12(false);
3571
+ const isOpen = storeIsOpen || isClosing;
3402
3572
  const [activeTab, setActiveTab] = useState12("home");
3403
3573
  const [subView, setSubView] = useState12(null);
3404
3574
  const [newText, setNewText] = useState12("");
3405
3575
  const [contentDetailSlug, setContentDetailSlug] = useState12(null);
3406
3576
  const [contentCategoryName, setContentCategoryName] = useState12(null);
3577
+ const prevActiveIdRef = useRef13(activeId);
3578
+ useEffect11(() => {
3579
+ if (activeId && activeId !== prevActiveIdRef.current && subView !== "conversation") {
3580
+ setSubView("conversation");
3581
+ }
3582
+ prevActiveIdRef.current = activeId;
3583
+ }, [activeId, subView]);
3584
+ const prefill = useWidgetStore((s) => s.newConversationPrefill);
3585
+ useEffect11(() => {
3586
+ if (prefill !== null) {
3587
+ if (prefill.length > 0) setNewText(prefill);
3588
+ setSubView("new");
3589
+ setActiveTab("home");
3590
+ store.getState().setNewConversationPrefill(null);
3591
+ }
3592
+ }, [prefill, store]);
3407
3593
  const closeTimerRef = useRef13(void 0);
3408
3594
  const welcomeMsgRaw = agentConfig?.welcomeMessage;
3409
3595
  const welcomeIsFactoryDefault = !welcomeMsgRaw || welcomeMsgRaw === DEFAULT_EN_WELCOME;
@@ -3482,9 +3668,9 @@ function DefaultWidget({ initialOpen = false } = {}) {
3482
3668
  },
3483
3669
  [activeTab, subView, activeId, setActiveConversation]
3484
3670
  );
3485
- const storeSetOpen = useWidgetStore((s) => s.setOpen);
3671
+ const setStoreOpen = useWidgetStore((s) => s.setOpen);
3486
3672
  const handleBubbleClick = useCallback12(() => {
3487
- if (isOpen) {
3673
+ if (storeIsOpen) {
3488
3674
  const leavingId = store.getState().activeConversationId;
3489
3675
  if (leavingId && !leavingId.startsWith("temp-")) {
3490
3676
  store.getState().clearUnread(leavingId);
@@ -3493,18 +3679,16 @@ function DefaultWidget({ initialOpen = false } = {}) {
3493
3679
  }
3494
3680
  setIsClosing(true);
3495
3681
  closeTimerRef.current = setTimeout(() => {
3496
- setIsOpen(false);
3497
3682
  setIsClosing(false);
3498
- storeSetOpen(false);
3683
+ setStoreOpen(false);
3499
3684
  }, 200);
3500
3685
  } else {
3501
- setIsOpen(true);
3502
3686
  setIsClosing(false);
3503
3687
  setSubView(null);
3504
3688
  setActiveTab("home");
3505
- storeSetOpen(true);
3689
+ setStoreOpen(true);
3506
3690
  }
3507
- }, [isOpen, storeSetOpen, client, store]);
3691
+ }, [storeIsOpen, setStoreOpen, client, store]);
3508
3692
  const handleClose = useCallback12(() => {
3509
3693
  const leavingId = store.getState().activeConversationId;
3510
3694
  if (leavingId && !leavingId.startsWith("temp-")) {
@@ -3514,11 +3698,10 @@ function DefaultWidget({ initialOpen = false } = {}) {
3514
3698
  }
3515
3699
  setIsClosing(true);
3516
3700
  closeTimerRef.current = setTimeout(() => {
3517
- setIsOpen(false);
3518
3701
  setIsClosing(false);
3519
- storeSetOpen(false);
3702
+ setStoreOpen(false);
3520
3703
  }, 200);
3521
- }, [storeSetOpen, client, store]);
3704
+ }, [setStoreOpen, client, store]);
3522
3705
  const handleNewConversation = useCallback12(async () => {
3523
3706
  const trimmed = newText.trim();
3524
3707
  if (!trimmed || isCreating) return;
@@ -3890,9 +4073,9 @@ function DefaultWidget({ initialOpen = false } = {}) {
3890
4073
  ]
3891
4074
  }
3892
4075
  ),
3893
- !isOpen && /* @__PURE__ */ jsx13(MessagePreview, { onOpen: handleBubbleClick }),
4076
+ !isOpen && !isDismissed && !hideLauncher && /* @__PURE__ */ jsx13(MessagePreview, { onOpen: handleBubbleClick }),
3894
4077
  /* @__PURE__ */ jsx13(WidgetDebugOverlay, {}),
3895
- /* @__PURE__ */ jsxs8(
4078
+ !isDismissed && !hideLauncher && /* @__PURE__ */ jsxs8(
3896
4079
  "button",
3897
4080
  {
3898
4081
  ref: bubbleRef,
@@ -4427,6 +4610,11 @@ function HelpwayWidget({
4427
4610
  locale,
4428
4611
  initialConversationId,
4429
4612
  onReady,
4613
+ hideLauncher,
4614
+ customLauncherSelector,
4615
+ onOpen,
4616
+ onClose,
4617
+ onUnreadChange,
4430
4618
  // eslint-disable-next-line @typescript-eslint/no-deprecated
4431
4619
  src
4432
4620
  }) {
@@ -4439,7 +4627,11 @@ function HelpwayWidget({
4439
4627
  locale,
4440
4628
  initialConversationId,
4441
4629
  onReady,
4442
- children: /* @__PURE__ */ jsx14(DefaultWidget, {})
4630
+ customLauncherSelector,
4631
+ onOpen,
4632
+ onClose,
4633
+ onUnreadChange,
4634
+ children: /* @__PURE__ */ jsx14(DefaultWidget, { hideLauncher })
4443
4635
  }
4444
4636
  );
4445
4637
  }