@usereq/widget 0.2.15 → 0.2.17
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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@usereq/widget",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.17",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./src/index.ts",
|
|
6
6
|
"types": "./src/index.ts",
|
|
@@ -76,7 +76,7 @@
|
|
|
76
76
|
},
|
|
77
77
|
"dependencies": {
|
|
78
78
|
"@streamdown/mermaid": "^1.0.2",
|
|
79
|
-
"@usereq/ui": "^0.2.
|
|
79
|
+
"@usereq/ui": "^0.2.22",
|
|
80
80
|
"lucide-react": "^0.553.0",
|
|
81
81
|
"motion": "^12.23.24",
|
|
82
82
|
"react": "^19.2.0",
|
|
@@ -223,8 +223,9 @@ export class AgentWidgetElement extends HTMLElement {
|
|
|
223
223
|
const placement = this.getResolvedPlacement();
|
|
224
224
|
const variant = this.getResolvedVariant();
|
|
225
225
|
const preset = this.getResolvedPreset();
|
|
226
|
-
const
|
|
227
|
-
|
|
226
|
+
const behavior = this.sessionConfig?.widgetConfig.widgetBehavior;
|
|
227
|
+
const autoStartEnabled = behavior?.autoStart === true;
|
|
228
|
+
const alwaysOpen = behavior?.alwaysOpen === true;
|
|
228
229
|
const awaitingConversation =
|
|
229
230
|
this.status === "booting" ||
|
|
230
231
|
(this.sessionState != null && !this.sessionState.conversationId);
|
|
@@ -267,6 +268,7 @@ export class AgentWidgetElement extends HTMLElement {
|
|
|
267
268
|
spotlights: this.getSpotlights(),
|
|
268
269
|
ctaLink: this.getCtaLink(),
|
|
269
270
|
open: this.open,
|
|
271
|
+
alwaysOpen,
|
|
270
272
|
status: this.status,
|
|
271
273
|
messages: this.messages,
|
|
272
274
|
errorMessage: this.errorMessage,
|
|
@@ -333,6 +335,13 @@ export class AgentWidgetElement extends HTMLElement {
|
|
|
333
335
|
this.welcomeMessage = state.session.widgetConfig.welcomeMessage;
|
|
334
336
|
this.status = "ready";
|
|
335
337
|
this.bootstrapPhase = "ready";
|
|
338
|
+
// Apply the agent's configured open-state on mount. `alwaysOpen`
|
|
339
|
+
// wins (the panel is pinned regardless), and `defaultOpen` opens it
|
|
340
|
+
// once if the visitor hasn't already interacted with the launcher.
|
|
341
|
+
const behavior = state.session.widgetConfig.widgetBehavior;
|
|
342
|
+
if (behavior?.alwaysOpen || behavior?.defaultOpen) {
|
|
343
|
+
this.open = true;
|
|
344
|
+
}
|
|
336
345
|
this.renderWidget();
|
|
337
346
|
} catch (error) {
|
|
338
347
|
if (runVersion !== this.bootstrapVersion) {
|
|
@@ -50,6 +50,12 @@ export type WidgetRuntimeProps = {
|
|
|
50
50
|
spotlights: string[];
|
|
51
51
|
ctaLink?: string | null;
|
|
52
52
|
open: boolean;
|
|
53
|
+
/**
|
|
54
|
+
* When true, the embedded panel is pinned open and the launcher is hidden.
|
|
55
|
+
* Mirrors `WidgetBehavior.alwaysOpen` and short-circuits the trigger-rule
|
|
56
|
+
* gate (a pinned widget has no "open" event to trigger on).
|
|
57
|
+
*/
|
|
58
|
+
alwaysOpen?: boolean;
|
|
53
59
|
status: WidgetRuntimeStatus;
|
|
54
60
|
messages: WidgetMessage[];
|
|
55
61
|
errorMessage: string | null;
|
|
@@ -88,6 +94,7 @@ export function WidgetRuntime({
|
|
|
88
94
|
spotlights,
|
|
89
95
|
ctaLink,
|
|
90
96
|
open,
|
|
97
|
+
alwaysOpen = false,
|
|
91
98
|
status,
|
|
92
99
|
messages,
|
|
93
100
|
errorMessage,
|
|
@@ -101,7 +108,10 @@ export function WidgetRuntime({
|
|
|
101
108
|
portalContainer,
|
|
102
109
|
onLauncherClick,
|
|
103
110
|
}: WidgetRuntimeProps) {
|
|
104
|
-
|
|
111
|
+
// Always-open widgets bypass the trigger-rule gate — the panel renders
|
|
112
|
+
// unconditionally, so any "open on X seconds / on scroll / on click"
|
|
113
|
+
// configuration would be meaningless. Pass `null` to short-circuit it.
|
|
114
|
+
const { ready } = useWidgetTriggerGate(alwaysOpen ? null : triggerRule);
|
|
105
115
|
const { horizontal, vertical } = splitWidgetPlacement(placement);
|
|
106
116
|
|
|
107
117
|
const { panelMessages, confirmation } = React.useMemo(
|
|
@@ -210,6 +220,7 @@ export function WidgetRuntime({
|
|
|
210
220
|
status={RUNTIME_TO_PANEL_STATUS[status]}
|
|
211
221
|
errorMessage={errorMessage}
|
|
212
222
|
open={open}
|
|
223
|
+
alwaysOpen={alwaysOpen}
|
|
213
224
|
onOpenChange={onOpenChange}
|
|
214
225
|
onSendMessage={handleSend}
|
|
215
226
|
onStopConversation={
|
|
@@ -30,11 +30,21 @@ export type WidgetTriggerRule =
|
|
|
30
30
|
| { triggerRuleType: "element_displayed"; elementDisplayed: string };
|
|
31
31
|
|
|
32
32
|
export type WidgetBehavior = {
|
|
33
|
+
/** Eagerly spin up the server-side conversation when the widget mounts. */
|
|
33
34
|
autoStart: boolean;
|
|
35
|
+
/** Open the panel as soon as the widget mounts. The launcher stays visible
|
|
36
|
+
* and the visitor can still close the panel from there. */
|
|
37
|
+
defaultOpen: boolean;
|
|
38
|
+
/** Pin the panel open: launcher is hidden, the close affordance is hidden,
|
|
39
|
+
* and the panel is rendered inline as the only thing this widget shows.
|
|
40
|
+
* Useful for full-page or dedicated-chat embeds. Implies `defaultOpen`. */
|
|
41
|
+
alwaysOpen: boolean;
|
|
34
42
|
};
|
|
35
43
|
|
|
36
44
|
export const DEFAULT_WIDGET_BEHAVIOR: WidgetBehavior = {
|
|
37
45
|
autoStart: false,
|
|
46
|
+
defaultOpen: false,
|
|
47
|
+
alwaysOpen: false,
|
|
38
48
|
};
|
|
39
49
|
|
|
40
50
|
export function normalizeWidgetBehavior(
|
|
@@ -42,6 +52,8 @@ export function normalizeWidgetBehavior(
|
|
|
42
52
|
): WidgetBehavior {
|
|
43
53
|
return {
|
|
44
54
|
autoStart: Boolean(behavior?.autoStart),
|
|
55
|
+
defaultOpen: Boolean(behavior?.defaultOpen),
|
|
56
|
+
alwaysOpen: Boolean(behavior?.alwaysOpen),
|
|
45
57
|
};
|
|
46
58
|
}
|
|
47
59
|
|