@helpway/react 0.4.2 → 0.5.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/README.md +7 -0
- package/dist/index.d.ts +25 -4
- package/dist/index.js +57 -0
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -2,6 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
Official React SDK for [Helpway](https://helpway.ai) — AI-powered customer support widget with full programmatic control.
|
|
4
4
|
|
|
5
|
+
> **📚 Full documentation:** https://helpway.ai/docs
|
|
6
|
+
> · [Quick start](https://helpway.ai/docs/quick-start)
|
|
7
|
+
> · [React SDK](https://helpway.ai/docs/react-sdk)
|
|
8
|
+
> · [Customization & theming](https://helpway.ai/docs/customization)
|
|
9
|
+
> · [Widget API](https://helpway.ai/docs/widget-api)
|
|
10
|
+
> · [Integration notes (CSP, SSR, multi-tenant)](https://helpway.ai/docs/integration-notes)
|
|
11
|
+
|
|
5
12
|
## Install
|
|
6
13
|
|
|
7
14
|
```bash
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
2
|
import * as _helpway_widget_core from '@helpway/widget-core';
|
|
3
|
-
import { HelpwayMethods, WidgetStore } from '@helpway/widget-core';
|
|
4
|
-
export { ConversationSummary, HelpwayAPI, RealtimeEvent, TimelineItem, WidgetEventName, WidgetEvents, WidgetState, WidgetStore, clearVisitorId, formatRelativeTime, formatTime, getInitials, getOrCreateVisitorId } from '@helpway/widget-core';
|
|
3
|
+
import { HelpwayMethods, WidgetTheme, WidgetStore } from '@helpway/widget-core';
|
|
4
|
+
export { ConversationSummary, HelpwayAPI, RealtimeEvent, TimelineItem, WidgetEventName, WidgetEvents, WidgetPosition, WidgetState, WidgetStore, WidgetTheme, 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';
|
|
@@ -52,6 +52,16 @@ interface HelpwayWidgetProps {
|
|
|
52
52
|
onClose?: () => void;
|
|
53
53
|
/** Fires when the unread count changes */
|
|
54
54
|
onUnreadChange?: (count: number) => void;
|
|
55
|
+
/**
|
|
56
|
+
* Developer-side theme override. Most consumers should configure
|
|
57
|
+
* appearance from the dashboard so changes apply without a redeploy
|
|
58
|
+
* — see https://helpway.ai/docs/customization. Use this prop only
|
|
59
|
+
* for runtime-resolved theming (multi-tenant brand colors, dark/
|
|
60
|
+
* light sync with the host app, etc). Values map to CSS custom
|
|
61
|
+
* properties on the widget host. See the `WidgetTheme` type for
|
|
62
|
+
* the full set of supported keys.
|
|
63
|
+
*/
|
|
64
|
+
theme?: WidgetTheme;
|
|
55
65
|
/**
|
|
56
66
|
* @deprecated Legacy prop from the v0.1 script-loader era. If set,
|
|
57
67
|
* the `/widget.js` suffix is stripped to derive `apiUrl`. New code
|
|
@@ -66,7 +76,7 @@ type HelpwayPublicAPI = HelpwayMethods;
|
|
|
66
76
|
* `layout.tsx`, or `main.tsx`). Unmounting cleanly tears down the
|
|
67
77
|
* widget and its WebSocket connection — useful for route-scoped mounts.
|
|
68
78
|
*/
|
|
69
|
-
declare function HelpwayWidget({ apiKey, apiUrl, locale, initialConversationId, onReady, hideLauncher, customLauncherSelector, onOpen, onClose, onUnreadChange, src, }: HelpwayWidgetProps): react_jsx_runtime.JSX.Element;
|
|
79
|
+
declare function HelpwayWidget({ apiKey, apiUrl, locale, initialConversationId, onReady, hideLauncher, customLauncherSelector, onOpen, onClose, onUnreadChange, theme, src, }: HelpwayWidgetProps): react_jsx_runtime.JSX.Element;
|
|
70
80
|
|
|
71
81
|
interface IdentifyData {
|
|
72
82
|
externalId: string;
|
|
@@ -89,6 +99,17 @@ interface SupportProviderProps {
|
|
|
89
99
|
onOpen?: () => void;
|
|
90
100
|
onClose?: () => void;
|
|
91
101
|
onUnreadChange?: (count: number) => void;
|
|
102
|
+
/**
|
|
103
|
+
* Developer-side theme override. Most consumers should configure
|
|
104
|
+
* appearance in the Helpway dashboard (see
|
|
105
|
+
* https://helpway.ai/docs/customization) so changes apply without
|
|
106
|
+
* a redeploy. Use this prop only when you need the widget to inherit
|
|
107
|
+
* a host-app theme that the dashboard can't see (e.g. a tenant-
|
|
108
|
+
* specific brand color resolved at runtime). Values here are written
|
|
109
|
+
* as CSS custom properties on the widget host and override the
|
|
110
|
+
* dashboard config for this mount only.
|
|
111
|
+
*/
|
|
112
|
+
theme?: WidgetTheme;
|
|
92
113
|
children: ReactNode;
|
|
93
114
|
}
|
|
94
115
|
/**
|
|
@@ -98,7 +119,7 @@ interface SupportProviderProps {
|
|
|
98
119
|
* Visitor identity is managed via server-side cookies (hw_visitor).
|
|
99
120
|
* No localStorage or client-side ID management needed.
|
|
100
121
|
*/
|
|
101
|
-
declare function SupportProvider({ apiKey, apiUrl, locale, initialConversationId, onReady, customLauncherSelector, onOpen, onClose, onUnreadChange, children, }: SupportProviderProps): react_jsx_runtime.JSX.Element;
|
|
122
|
+
declare function SupportProvider({ apiKey, apiUrl, locale, initialConversationId, onReady, customLauncherSelector, onOpen, onClose, onUnreadChange, theme, children, }: SupportProviderProps): react_jsx_runtime.JSX.Element;
|
|
102
123
|
|
|
103
124
|
/**
|
|
104
125
|
* Core widget state — connection status, visitor identity, website info.
|
package/dist/index.js
CHANGED
|
@@ -585,6 +585,55 @@ function createHelpwayAPI(deps) {
|
|
|
585
585
|
};
|
|
586
586
|
}
|
|
587
587
|
|
|
588
|
+
// ../widget-core/src/theme.ts
|
|
589
|
+
function isValidHex(color) {
|
|
590
|
+
return /^#[0-9a-fA-F]{6}$/.test(color);
|
|
591
|
+
}
|
|
592
|
+
function lighten(hex) {
|
|
593
|
+
if (!isValidHex(hex)) return hex;
|
|
594
|
+
const r = Math.min(255, Number.parseInt(hex.slice(1, 3), 16) + 30);
|
|
595
|
+
const g = Math.min(255, Number.parseInt(hex.slice(3, 5), 16) + 30);
|
|
596
|
+
const b = Math.min(255, Number.parseInt(hex.slice(5, 7), 16) + 30);
|
|
597
|
+
const hex2 = (n) => n.toString(16).padStart(2, "0");
|
|
598
|
+
return `#${hex2(r)}${hex2(g)}${hex2(b)}`;
|
|
599
|
+
}
|
|
600
|
+
function setVar(host, name, value) {
|
|
601
|
+
if (value == null || value === "") return;
|
|
602
|
+
host.style.setProperty(name, value);
|
|
603
|
+
}
|
|
604
|
+
function applyTheme(host, theme) {
|
|
605
|
+
if (!host || !theme) return;
|
|
606
|
+
if (theme.primaryColor) {
|
|
607
|
+
setVar(host, "--hw-primary", theme.primaryColor);
|
|
608
|
+
setVar(host, "--hw-primary-hover", lighten(theme.primaryColor));
|
|
609
|
+
setVar(host, "--hw-brand", theme.primaryColor);
|
|
610
|
+
}
|
|
611
|
+
setVar(host, "--hw-on-brand", theme.onPrimaryColor);
|
|
612
|
+
setVar(host, "--hw-visitor-bubble-bg", theme.bubbleColor ?? theme.primaryColor);
|
|
613
|
+
setVar(host, "--hw-visitor-bubble-text", theme.bubbleTextColor ?? theme.onPrimaryColor);
|
|
614
|
+
setVar(host, "--hw-bg", theme.backgroundColor);
|
|
615
|
+
setVar(host, "--hw-text", theme.textColor);
|
|
616
|
+
setVar(host, "--hw-border", theme.borderColor);
|
|
617
|
+
setVar(host, "--hw-radius", theme.radius);
|
|
618
|
+
setVar(host, "--hw-font", theme.fontFamily);
|
|
619
|
+
if (theme.position === "bottom-left") {
|
|
620
|
+
setVar(host, "--hw-position-right", "auto");
|
|
621
|
+
setVar(host, "--hw-position-left", "20px");
|
|
622
|
+
setVar(host, "--hw-window-right", "auto");
|
|
623
|
+
setVar(host, "--hw-window-left", "0");
|
|
624
|
+
} else if (theme.position === "bottom-right") {
|
|
625
|
+
host.style.removeProperty("--hw-position-right");
|
|
626
|
+
host.style.removeProperty("--hw-position-left");
|
|
627
|
+
host.style.removeProperty("--hw-window-right");
|
|
628
|
+
host.style.removeProperty("--hw-window-left");
|
|
629
|
+
}
|
|
630
|
+
if (theme.cssVariables) {
|
|
631
|
+
for (const [key, value] of Object.entries(theme.cssVariables)) {
|
|
632
|
+
if (key.startsWith("--")) host.style.setProperty(key, value);
|
|
633
|
+
}
|
|
634
|
+
}
|
|
635
|
+
}
|
|
636
|
+
|
|
588
637
|
// ../widget-core/src/events.ts
|
|
589
638
|
var WidgetEventEmitter = class {
|
|
590
639
|
listeners = /* @__PURE__ */ new Map();
|
|
@@ -884,6 +933,7 @@ function SupportProvider({
|
|
|
884
933
|
onOpen,
|
|
885
934
|
onClose,
|
|
886
935
|
onUnreadChange,
|
|
936
|
+
theme,
|
|
887
937
|
children
|
|
888
938
|
}) {
|
|
889
939
|
const initRef = useRef(null);
|
|
@@ -1080,6 +1130,11 @@ function SupportProvider({
|
|
|
1080
1130
|
observer?.disconnect();
|
|
1081
1131
|
};
|
|
1082
1132
|
}, [customLauncherSelector, api]);
|
|
1133
|
+
useEffect(() => {
|
|
1134
|
+
if (!theme || typeof document === "undefined") return;
|
|
1135
|
+
const target = document.getElementById("helpway-widget") ?? document.documentElement;
|
|
1136
|
+
applyTheme(target, theme);
|
|
1137
|
+
}, [theme]);
|
|
1083
1138
|
useEffect(() => {
|
|
1084
1139
|
if (typeof window === "undefined") return;
|
|
1085
1140
|
const callable = installCallable(api);
|
|
@@ -4589,6 +4644,7 @@ function HelpwayWidget({
|
|
|
4589
4644
|
onOpen,
|
|
4590
4645
|
onClose,
|
|
4591
4646
|
onUnreadChange,
|
|
4647
|
+
theme,
|
|
4592
4648
|
// eslint-disable-next-line @typescript-eslint/no-deprecated
|
|
4593
4649
|
src
|
|
4594
4650
|
}) {
|
|
@@ -4605,6 +4661,7 @@ function HelpwayWidget({
|
|
|
4605
4661
|
onOpen,
|
|
4606
4662
|
onClose,
|
|
4607
4663
|
onUnreadChange,
|
|
4664
|
+
theme,
|
|
4608
4665
|
children: /* @__PURE__ */ jsx14(DefaultWidget, { hideLauncher })
|
|
4609
4666
|
}
|
|
4610
4667
|
);
|