@runtypelabs/persona 2.3.0 → 3.0.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 +221 -4
- package/dist/index.cjs +42 -42
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +832 -571
- package/dist/index.d.ts +832 -571
- package/dist/index.global.js +87 -87
- package/dist/index.global.js.map +1 -1
- package/dist/index.js +42 -42
- package/dist/index.js.map +1 -1
- package/dist/widget.css +205 -15
- package/package.json +2 -2
- package/src/components/artifact-card.ts +39 -5
- package/src/components/artifact-pane.ts +67 -126
- package/src/components/composer-builder.ts +3 -23
- package/src/components/header-builder.ts +29 -34
- package/src/components/header-layouts.ts +109 -41
- package/src/components/launcher.ts +10 -7
- package/src/components/message-bubble.ts +7 -11
- package/src/components/panel.ts +4 -4
- package/src/defaults.ts +22 -93
- package/src/index.ts +20 -7
- package/src/presets.ts +66 -51
- package/src/runtime/host-layout.test.ts +196 -0
- package/src/runtime/host-layout.ts +265 -27
- package/src/runtime/init.test.ts +77 -7
- package/src/styles/widget.css +205 -15
- package/src/types/theme.ts +76 -0
- package/src/types.ts +86 -97
- package/src/ui.docked.test.ts +203 -7
- package/src/ui.ts +129 -88
- package/src/utils/buttons.ts +417 -0
- package/src/utils/code-generators.test.ts +43 -7
- package/src/utils/code-generators.ts +9 -25
- package/src/utils/deep-merge.ts +26 -0
- package/src/utils/dock.ts +18 -5
- package/src/utils/dropdown.ts +178 -0
- package/src/utils/sanitize.ts +1 -1
- package/src/utils/theme.test.ts +90 -15
- package/src/utils/theme.ts +20 -46
- package/src/utils/tokens.ts +108 -11
- package/src/utils/migration.ts +0 -220
|
@@ -15,6 +15,16 @@ export type WidgetHostLayout = {
|
|
|
15
15
|
destroy: () => void;
|
|
16
16
|
};
|
|
17
17
|
|
|
18
|
+
/** Parse `dock.width` for push layout math (px or % of shell). Fallback: 420. */
|
|
19
|
+
const parseDockWidthToPx = (width: string, shellClientWidth: number): number => {
|
|
20
|
+
const w = width.trim();
|
|
21
|
+
const px = /^(\d+(?:\.\d+)?)px$/i.exec(w);
|
|
22
|
+
if (px) return Math.max(0, parseFloat(px[1]));
|
|
23
|
+
const pct = /^(\d+(?:\.\d+)?)%$/i.exec(w);
|
|
24
|
+
if (pct) return Math.max(0, (shellClientWidth * parseFloat(pct[1])) / 100);
|
|
25
|
+
return 420;
|
|
26
|
+
};
|
|
27
|
+
|
|
18
28
|
const setDirectHostStyles = (host: HTMLElement, config?: AgentWidgetConfig): void => {
|
|
19
29
|
const launcherEnabled = config?.launcher?.enabled ?? true;
|
|
20
30
|
host.className = "persona-host";
|
|
@@ -25,8 +35,90 @@ const setDirectHostStyles = (host: HTMLElement, config?: AgentWidgetConfig): voi
|
|
|
25
35
|
host.style.minHeight = launcherEnabled ? "" : "0";
|
|
26
36
|
};
|
|
27
37
|
|
|
38
|
+
const clearOverlayDockSlotStyles = (dockSlot: HTMLElement): void => {
|
|
39
|
+
dockSlot.style.position = "";
|
|
40
|
+
dockSlot.style.top = "";
|
|
41
|
+
dockSlot.style.bottom = "";
|
|
42
|
+
dockSlot.style.left = "";
|
|
43
|
+
dockSlot.style.right = "";
|
|
44
|
+
dockSlot.style.zIndex = "";
|
|
45
|
+
dockSlot.style.transform = "";
|
|
46
|
+
dockSlot.style.pointerEvents = "";
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
const clearResizeDockSlotTransition = (dockSlot: HTMLElement): void => {
|
|
50
|
+
dockSlot.style.transition = "";
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
const clearPushTrackStyles = (pushTrack: HTMLElement): void => {
|
|
54
|
+
pushTrack.style.display = "";
|
|
55
|
+
pushTrack.style.flexDirection = "";
|
|
56
|
+
pushTrack.style.flex = "";
|
|
57
|
+
pushTrack.style.minHeight = "";
|
|
58
|
+
pushTrack.style.minWidth = "";
|
|
59
|
+
pushTrack.style.width = "";
|
|
60
|
+
pushTrack.style.height = "";
|
|
61
|
+
pushTrack.style.alignItems = "";
|
|
62
|
+
pushTrack.style.transition = "";
|
|
63
|
+
pushTrack.style.transform = "";
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
const resetContentSlotFlexSizing = (contentSlot: HTMLElement): void => {
|
|
67
|
+
contentSlot.style.width = "";
|
|
68
|
+
contentSlot.style.maxWidth = "";
|
|
69
|
+
contentSlot.style.minWidth = "";
|
|
70
|
+
contentSlot.style.flex = "1 1 auto";
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
const clearEmergeDockStyles = (host: HTMLElement, dockSlot: HTMLElement): void => {
|
|
74
|
+
host.style.width = "";
|
|
75
|
+
host.style.minWidth = "";
|
|
76
|
+
host.style.maxWidth = "";
|
|
77
|
+
host.style.boxSizing = "";
|
|
78
|
+
dockSlot.style.alignItems = "";
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
const migrateDockChildren = (
|
|
82
|
+
shell: HTMLElement,
|
|
83
|
+
pushTrack: HTMLElement,
|
|
84
|
+
contentSlot: HTMLElement,
|
|
85
|
+
dockSlot: HTMLElement,
|
|
86
|
+
usePush: boolean
|
|
87
|
+
): void => {
|
|
88
|
+
if (usePush) {
|
|
89
|
+
if (contentSlot.parentElement !== pushTrack) {
|
|
90
|
+
shell.replaceChildren();
|
|
91
|
+
pushTrack.replaceChildren(contentSlot, dockSlot);
|
|
92
|
+
shell.appendChild(pushTrack);
|
|
93
|
+
}
|
|
94
|
+
} else if (contentSlot.parentElement === pushTrack) {
|
|
95
|
+
pushTrack.replaceChildren();
|
|
96
|
+
shell.appendChild(contentSlot);
|
|
97
|
+
shell.appendChild(dockSlot);
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
const orderDockChildren = (
|
|
102
|
+
shell: HTMLElement,
|
|
103
|
+
pushTrack: HTMLElement,
|
|
104
|
+
contentSlot: HTMLElement,
|
|
105
|
+
dockSlot: HTMLElement,
|
|
106
|
+
side: "left" | "right",
|
|
107
|
+
usePush: boolean
|
|
108
|
+
): void => {
|
|
109
|
+
const parent = usePush ? pushTrack : shell;
|
|
110
|
+
if (side === "left") {
|
|
111
|
+
if (parent.firstElementChild !== dockSlot) {
|
|
112
|
+
parent.replaceChildren(dockSlot, contentSlot);
|
|
113
|
+
}
|
|
114
|
+
} else if (parent.lastElementChild !== dockSlot) {
|
|
115
|
+
parent.replaceChildren(contentSlot, dockSlot);
|
|
116
|
+
}
|
|
117
|
+
};
|
|
118
|
+
|
|
28
119
|
const applyDockStyles = (
|
|
29
120
|
shell: HTMLElement,
|
|
121
|
+
pushTrack: HTMLElement,
|
|
30
122
|
contentSlot: HTMLElement,
|
|
31
123
|
dockSlot: HTMLElement,
|
|
32
124
|
host: HTMLElement,
|
|
@@ -34,14 +126,14 @@ const applyDockStyles = (
|
|
|
34
126
|
expanded: boolean
|
|
35
127
|
): void => {
|
|
36
128
|
const dock = resolveDockConfig(config);
|
|
37
|
-
const
|
|
129
|
+
const usePush = dock.reveal === "push";
|
|
130
|
+
|
|
131
|
+
migrateDockChildren(shell, pushTrack, contentSlot, dockSlot, usePush);
|
|
132
|
+
orderDockChildren(shell, pushTrack, contentSlot, dockSlot, dock.side, usePush);
|
|
38
133
|
|
|
39
134
|
shell.dataset.personaHostLayout = "docked";
|
|
40
135
|
shell.dataset.personaDockSide = dock.side;
|
|
41
136
|
shell.dataset.personaDockOpen = expanded ? "true" : "false";
|
|
42
|
-
shell.style.display = "flex";
|
|
43
|
-
shell.style.flexDirection = "row";
|
|
44
|
-
shell.style.alignItems = "stretch";
|
|
45
137
|
shell.style.width = "100%";
|
|
46
138
|
shell.style.maxWidth = "100%";
|
|
47
139
|
shell.style.minWidth = "0";
|
|
@@ -51,22 +143,9 @@ const applyDockStyles = (
|
|
|
51
143
|
|
|
52
144
|
contentSlot.style.display = "flex";
|
|
53
145
|
contentSlot.style.flexDirection = "column";
|
|
54
|
-
contentSlot.style.flex = "1 1 auto";
|
|
55
|
-
contentSlot.style.minWidth = "0";
|
|
56
146
|
contentSlot.style.minHeight = "0";
|
|
57
147
|
contentSlot.style.position = "relative";
|
|
58
148
|
|
|
59
|
-
dockSlot.style.display = "flex";
|
|
60
|
-
dockSlot.style.flexDirection = "column";
|
|
61
|
-
dockSlot.style.flex = `0 0 ${width}`;
|
|
62
|
-
dockSlot.style.width = width;
|
|
63
|
-
dockSlot.style.maxWidth = width;
|
|
64
|
-
dockSlot.style.minWidth = width;
|
|
65
|
-
dockSlot.style.minHeight = "0";
|
|
66
|
-
dockSlot.style.position = "relative";
|
|
67
|
-
dockSlot.style.overflow = "visible";
|
|
68
|
-
dockSlot.style.transition = "width 180ms ease, min-width 180ms ease, max-width 180ms ease, flex-basis 180ms ease";
|
|
69
|
-
|
|
70
149
|
host.className = "persona-host";
|
|
71
150
|
host.style.height = "100%";
|
|
72
151
|
host.style.minHeight = "0";
|
|
@@ -74,12 +153,138 @@ const applyDockStyles = (
|
|
|
74
153
|
host.style.flexDirection = "column";
|
|
75
154
|
host.style.flex = "1 1 auto";
|
|
76
155
|
|
|
77
|
-
if (dock.
|
|
78
|
-
|
|
79
|
-
|
|
156
|
+
if (dock.reveal === "overlay") {
|
|
157
|
+
shell.style.display = "flex";
|
|
158
|
+
shell.style.flexDirection = "row";
|
|
159
|
+
shell.style.alignItems = "stretch";
|
|
160
|
+
shell.style.overflow = "hidden";
|
|
161
|
+
shell.dataset.personaDockReveal = "overlay";
|
|
162
|
+
clearPushTrackStyles(pushTrack);
|
|
163
|
+
clearResizeDockSlotTransition(dockSlot);
|
|
164
|
+
resetContentSlotFlexSizing(contentSlot);
|
|
165
|
+
clearEmergeDockStyles(host, dockSlot);
|
|
166
|
+
|
|
167
|
+
const dockTransition = dock.animate ? "transform 180ms ease" : "none";
|
|
168
|
+
const translateClosed = dock.side === "right" ? "translateX(100%)" : "translateX(-100%)";
|
|
169
|
+
const translate = expanded ? "translateX(0)" : translateClosed;
|
|
170
|
+
|
|
171
|
+
dockSlot.style.display = "flex";
|
|
172
|
+
dockSlot.style.flexDirection = "column";
|
|
173
|
+
dockSlot.style.flex = "none";
|
|
174
|
+
dockSlot.style.position = "absolute";
|
|
175
|
+
dockSlot.style.top = "0";
|
|
176
|
+
dockSlot.style.bottom = "0";
|
|
177
|
+
dockSlot.style.width = dock.width;
|
|
178
|
+
dockSlot.style.maxWidth = dock.width;
|
|
179
|
+
dockSlot.style.minWidth = dock.width;
|
|
180
|
+
dockSlot.style.minHeight = "0";
|
|
181
|
+
dockSlot.style.overflow = "hidden";
|
|
182
|
+
dockSlot.style.transition = dockTransition;
|
|
183
|
+
dockSlot.style.transform = translate;
|
|
184
|
+
dockSlot.style.pointerEvents = expanded ? "auto" : "none";
|
|
185
|
+
dockSlot.style.zIndex = "2";
|
|
186
|
+
if (dock.side === "right") {
|
|
187
|
+
dockSlot.style.right = "0";
|
|
188
|
+
dockSlot.style.left = "";
|
|
189
|
+
} else {
|
|
190
|
+
dockSlot.style.left = "0";
|
|
191
|
+
dockSlot.style.right = "";
|
|
192
|
+
}
|
|
193
|
+
} else if (dock.reveal === "push") {
|
|
194
|
+
// Row flex so the wide push track is laid out on the horizontal axis; column was stretching
|
|
195
|
+
// the track to the shell width and fighting explicit width, which could confuse overflow.
|
|
196
|
+
shell.style.display = "flex";
|
|
197
|
+
shell.style.flexDirection = "row";
|
|
198
|
+
shell.style.alignItems = "stretch";
|
|
199
|
+
shell.style.overflow = "hidden";
|
|
200
|
+
shell.dataset.personaDockReveal = "push";
|
|
201
|
+
clearResizeDockSlotTransition(dockSlot);
|
|
202
|
+
clearOverlayDockSlotStyles(dockSlot);
|
|
203
|
+
clearEmergeDockStyles(host, dockSlot);
|
|
204
|
+
|
|
205
|
+
const panelPx = parseDockWidthToPx(dock.width, shell.clientWidth);
|
|
206
|
+
const contentPx = Math.max(0, shell.clientWidth);
|
|
207
|
+
const dockTransition = dock.animate ? "transform 180ms ease" : "none";
|
|
208
|
+
const translate =
|
|
209
|
+
dock.side === "right"
|
|
210
|
+
? expanded
|
|
211
|
+
? `translateX(-${panelPx}px)`
|
|
212
|
+
: "translateX(0)"
|
|
213
|
+
: expanded
|
|
214
|
+
? "translateX(0)"
|
|
215
|
+
: `translateX(-${panelPx}px)`;
|
|
216
|
+
|
|
217
|
+
pushTrack.style.display = "flex";
|
|
218
|
+
pushTrack.style.flexDirection = "row";
|
|
219
|
+
pushTrack.style.flex = "0 0 auto";
|
|
220
|
+
pushTrack.style.minHeight = "0";
|
|
221
|
+
pushTrack.style.minWidth = "0";
|
|
222
|
+
pushTrack.style.alignItems = "stretch";
|
|
223
|
+
pushTrack.style.height = "100%";
|
|
224
|
+
pushTrack.style.width = `${contentPx + panelPx}px`;
|
|
225
|
+
pushTrack.style.transition = dockTransition;
|
|
226
|
+
pushTrack.style.transform = translate;
|
|
227
|
+
|
|
228
|
+
contentSlot.style.flex = "0 0 auto";
|
|
229
|
+
contentSlot.style.flexGrow = "0";
|
|
230
|
+
contentSlot.style.flexShrink = "0";
|
|
231
|
+
contentSlot.style.width = `${contentPx}px`;
|
|
232
|
+
contentSlot.style.maxWidth = `${contentPx}px`;
|
|
233
|
+
contentSlot.style.minWidth = `${contentPx}px`;
|
|
234
|
+
|
|
235
|
+
dockSlot.style.display = "flex";
|
|
236
|
+
dockSlot.style.flexDirection = "column";
|
|
237
|
+
dockSlot.style.flex = "0 0 auto";
|
|
238
|
+
dockSlot.style.flexShrink = "0";
|
|
239
|
+
dockSlot.style.width = dock.width;
|
|
240
|
+
dockSlot.style.minWidth = dock.width;
|
|
241
|
+
dockSlot.style.maxWidth = dock.width;
|
|
242
|
+
dockSlot.style.position = "relative";
|
|
243
|
+
dockSlot.style.overflow = "hidden";
|
|
244
|
+
dockSlot.style.transition = "none";
|
|
245
|
+
dockSlot.style.pointerEvents = expanded ? "auto" : "none";
|
|
246
|
+
} else {
|
|
247
|
+
shell.style.display = "flex";
|
|
248
|
+
shell.style.flexDirection = "row";
|
|
249
|
+
shell.style.alignItems = "stretch";
|
|
250
|
+
shell.style.overflow = "";
|
|
251
|
+
clearPushTrackStyles(pushTrack);
|
|
252
|
+
clearOverlayDockSlotStyles(dockSlot);
|
|
253
|
+
resetContentSlotFlexSizing(contentSlot);
|
|
254
|
+
clearEmergeDockStyles(host, dockSlot);
|
|
255
|
+
|
|
256
|
+
const isEmerge = dock.reveal === "emerge";
|
|
257
|
+
if (isEmerge) {
|
|
258
|
+
shell.dataset.personaDockReveal = "emerge";
|
|
259
|
+
} else {
|
|
260
|
+
shell.removeAttribute("data-persona-dock-reveal");
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
const width = expanded ? dock.width : "0px";
|
|
264
|
+
const dockTransition = dock.animate
|
|
265
|
+
? "width 180ms ease, min-width 180ms ease, max-width 180ms ease, flex-basis 180ms ease"
|
|
266
|
+
: "none";
|
|
267
|
+
const collapsedClosed = !expanded;
|
|
268
|
+
|
|
269
|
+
dockSlot.style.display = "flex";
|
|
270
|
+
dockSlot.style.flexDirection = "column";
|
|
271
|
+
dockSlot.style.flex = `0 0 ${width}`;
|
|
272
|
+
dockSlot.style.width = width;
|
|
273
|
+
dockSlot.style.maxWidth = width;
|
|
274
|
+
dockSlot.style.minWidth = width;
|
|
275
|
+
dockSlot.style.minHeight = "0";
|
|
276
|
+
dockSlot.style.position = "relative";
|
|
277
|
+
dockSlot.style.overflow =
|
|
278
|
+
isEmerge ? "hidden" : collapsedClosed ? "hidden" : "visible";
|
|
279
|
+
dockSlot.style.transition = dockTransition;
|
|
280
|
+
|
|
281
|
+
if (isEmerge) {
|
|
282
|
+
dockSlot.style.alignItems = dock.side === "right" ? "flex-start" : "flex-end";
|
|
283
|
+
host.style.width = dock.width;
|
|
284
|
+
host.style.minWidth = dock.width;
|
|
285
|
+
host.style.maxWidth = dock.width;
|
|
286
|
+
host.style.boxSizing = "border-box";
|
|
80
287
|
}
|
|
81
|
-
} else if (shell.lastElementChild !== dockSlot) {
|
|
82
|
-
shell.replaceChildren(contentSlot, dockSlot);
|
|
83
288
|
}
|
|
84
289
|
};
|
|
85
290
|
|
|
@@ -117,11 +322,13 @@ const createDockedLayout = (target: HTMLElement, config?: AgentWidgetConfig): Wi
|
|
|
117
322
|
|
|
118
323
|
const originalNextSibling = target.nextSibling;
|
|
119
324
|
const shell = ownerDocument.createElement("div");
|
|
325
|
+
const pushTrack = ownerDocument.createElement("div");
|
|
120
326
|
const contentSlot = ownerDocument.createElement("div");
|
|
121
327
|
const dockSlot = ownerDocument.createElement("aside");
|
|
122
328
|
const host = ownerDocument.createElement("div");
|
|
123
329
|
let expanded = (config?.launcher?.enabled ?? true) ? (config?.launcher?.autoExpand ?? false) : true;
|
|
124
330
|
|
|
331
|
+
pushTrack.dataset.personaDockRole = "push-track";
|
|
125
332
|
contentSlot.dataset.personaDockRole = "content";
|
|
126
333
|
dockSlot.dataset.personaDockRole = "panel";
|
|
127
334
|
host.dataset.personaDockRole = "host";
|
|
@@ -129,9 +336,39 @@ const createDockedLayout = (target: HTMLElement, config?: AgentWidgetConfig): Wi
|
|
|
129
336
|
dockSlot.appendChild(host);
|
|
130
337
|
originalParent.insertBefore(shell, target);
|
|
131
338
|
contentSlot.appendChild(target);
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
339
|
+
|
|
340
|
+
let resizeObserver: ResizeObserver | null = null;
|
|
341
|
+
|
|
342
|
+
const disconnectResizeObserver = (): void => {
|
|
343
|
+
resizeObserver?.disconnect();
|
|
344
|
+
resizeObserver = null;
|
|
345
|
+
};
|
|
346
|
+
|
|
347
|
+
const syncPushResizeObserver = (): void => {
|
|
348
|
+
disconnectResizeObserver();
|
|
349
|
+
if (resolveDockConfig(config).reveal !== "push") return;
|
|
350
|
+
if (typeof ResizeObserver === "undefined") return;
|
|
351
|
+
resizeObserver = new ResizeObserver(() => {
|
|
352
|
+
applyDockStyles(shell, pushTrack, contentSlot, dockSlot, host, config, expanded);
|
|
353
|
+
});
|
|
354
|
+
resizeObserver.observe(shell);
|
|
355
|
+
};
|
|
356
|
+
|
|
357
|
+
const layout = (): void => {
|
|
358
|
+
applyDockStyles(shell, pushTrack, contentSlot, dockSlot, host, config, expanded);
|
|
359
|
+
syncPushResizeObserver();
|
|
360
|
+
};
|
|
361
|
+
|
|
362
|
+
if (resolveDockConfig(config).reveal === "push") {
|
|
363
|
+
pushTrack.appendChild(contentSlot);
|
|
364
|
+
pushTrack.appendChild(dockSlot);
|
|
365
|
+
shell.appendChild(pushTrack);
|
|
366
|
+
} else {
|
|
367
|
+
shell.appendChild(contentSlot);
|
|
368
|
+
shell.appendChild(dockSlot);
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
layout();
|
|
135
372
|
|
|
136
373
|
return {
|
|
137
374
|
mode: "docked",
|
|
@@ -141,16 +378,17 @@ const createDockedLayout = (target: HTMLElement, config?: AgentWidgetConfig): Wi
|
|
|
141
378
|
const nextExpanded = state.launcherEnabled ? state.open : true;
|
|
142
379
|
if (expanded === nextExpanded) return;
|
|
143
380
|
expanded = nextExpanded;
|
|
144
|
-
|
|
381
|
+
layout();
|
|
145
382
|
},
|
|
146
383
|
updateConfig(nextConfig?: AgentWidgetConfig) {
|
|
147
384
|
config = nextConfig;
|
|
148
385
|
if ((config?.launcher?.enabled ?? true) === false) {
|
|
149
386
|
expanded = true;
|
|
150
387
|
}
|
|
151
|
-
|
|
388
|
+
layout();
|
|
152
389
|
},
|
|
153
390
|
destroy() {
|
|
391
|
+
disconnectResizeObserver();
|
|
154
392
|
if (originalParent.isConnected) {
|
|
155
393
|
if (originalNextSibling && originalNextSibling.parentNode === originalParent) {
|
|
156
394
|
originalParent.insertBefore(target, originalNextSibling);
|
package/src/runtime/init.test.ts
CHANGED
|
@@ -104,7 +104,7 @@ describe("initAgentWidget docked mode", () => {
|
|
|
104
104
|
config: {
|
|
105
105
|
launcher: {
|
|
106
106
|
mountMode: "docked",
|
|
107
|
-
dock: { width: "420px"
|
|
107
|
+
dock: { width: "420px" },
|
|
108
108
|
},
|
|
109
109
|
},
|
|
110
110
|
});
|
|
@@ -146,7 +146,7 @@ describe("initAgentWidget docked mode", () => {
|
|
|
146
146
|
launcher: {
|
|
147
147
|
mountMode: "docked",
|
|
148
148
|
autoExpand: true,
|
|
149
|
-
dock: { width: "400px"
|
|
149
|
+
dock: { width: "400px" },
|
|
150
150
|
},
|
|
151
151
|
},
|
|
152
152
|
});
|
|
@@ -155,12 +155,82 @@ describe("initAgentWidget docked mode", () => {
|
|
|
155
155
|
expect(panelSlot.style.width).toBe("400px");
|
|
156
156
|
|
|
157
157
|
handle.close();
|
|
158
|
-
expect(panelSlot.style.width).toBe("
|
|
158
|
+
expect(panelSlot.style.width).toBe("0px");
|
|
159
159
|
|
|
160
160
|
handle.open();
|
|
161
161
|
expect(panelSlot.style.width).toBe("400px");
|
|
162
162
|
});
|
|
163
163
|
|
|
164
|
+
it("overlay dock reveal keeps width and uses transform when closing", async () => {
|
|
165
|
+
const { initAgentWidget } = await import("./init");
|
|
166
|
+
document.body.innerHTML = `<div id="content">Workspace</div>`;
|
|
167
|
+
|
|
168
|
+
const handle = initAgentWidget({
|
|
169
|
+
target: "#content",
|
|
170
|
+
config: {
|
|
171
|
+
launcher: {
|
|
172
|
+
mountMode: "docked",
|
|
173
|
+
autoExpand: true,
|
|
174
|
+
dock: { width: "400px", reveal: "overlay" },
|
|
175
|
+
},
|
|
176
|
+
},
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
const panelSlot = document.querySelector<HTMLElement>('[data-persona-dock-role="panel"]')!;
|
|
180
|
+
expect(panelSlot.style.width).toBe("400px");
|
|
181
|
+
|
|
182
|
+
handle.close();
|
|
183
|
+
expect(panelSlot.style.width).toBe("400px");
|
|
184
|
+
expect(panelSlot.style.transform).toBe("translateX(100%)");
|
|
185
|
+
|
|
186
|
+
handle.open();
|
|
187
|
+
expect(panelSlot.style.transform).toBe("translateX(0)");
|
|
188
|
+
|
|
189
|
+
handle.destroy();
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
it("push dock reveal translates the push-track; panel keeps width when closing", async () => {
|
|
193
|
+
const { initAgentWidget } = await import("./init");
|
|
194
|
+
const wrapper = document.createElement("div");
|
|
195
|
+
wrapper.style.width = "900px";
|
|
196
|
+
document.body.appendChild(wrapper);
|
|
197
|
+
wrapper.innerHTML = `<div id="content">Workspace</div>`;
|
|
198
|
+
|
|
199
|
+
const handle = initAgentWidget({
|
|
200
|
+
target: "#content",
|
|
201
|
+
config: {
|
|
202
|
+
launcher: {
|
|
203
|
+
mountMode: "docked",
|
|
204
|
+
autoExpand: true,
|
|
205
|
+
dock: { width: "400px", reveal: "push" },
|
|
206
|
+
},
|
|
207
|
+
},
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
const shell = document.querySelector<HTMLElement>('[data-persona-host-layout="docked"]')!;
|
|
211
|
+
Object.defineProperty(shell, "clientWidth", { get: () => 900, configurable: true });
|
|
212
|
+
handle.update({
|
|
213
|
+
launcher: {
|
|
214
|
+
mountMode: "docked",
|
|
215
|
+
autoExpand: true,
|
|
216
|
+
dock: { width: "400px", reveal: "push" },
|
|
217
|
+
},
|
|
218
|
+
});
|
|
219
|
+
|
|
220
|
+
const pushTrack = shell.querySelector<HTMLElement>('[data-persona-dock-role="push-track"]');
|
|
221
|
+
const panelSlot = shell.querySelector<HTMLElement>('[data-persona-dock-role="panel"]')!;
|
|
222
|
+
expect(pushTrack).not.toBeNull();
|
|
223
|
+
expect(panelSlot.style.width).toBe("400px");
|
|
224
|
+
expect(pushTrack?.style.transform).toBe("translateX(-400px)");
|
|
225
|
+
|
|
226
|
+
handle.close();
|
|
227
|
+
expect(panelSlot.style.width).toBe("400px");
|
|
228
|
+
expect(pushTrack?.style.transform).toBe("translateX(0)");
|
|
229
|
+
|
|
230
|
+
handle.destroy();
|
|
231
|
+
wrapper.remove();
|
|
232
|
+
});
|
|
233
|
+
|
|
164
234
|
it("rebuilds when mount mode changes from floating to docked", async () => {
|
|
165
235
|
const { initAgentWidget } = await import("./init");
|
|
166
236
|
document.body.innerHTML = `<div id="content">Workspace</div>`;
|
|
@@ -178,7 +248,7 @@ describe("initAgentWidget docked mode", () => {
|
|
|
178
248
|
handle.update({
|
|
179
249
|
launcher: {
|
|
180
250
|
mountMode: "docked",
|
|
181
|
-
dock: { side: "left", width: "460px"
|
|
251
|
+
dock: { side: "left", width: "460px" },
|
|
182
252
|
},
|
|
183
253
|
});
|
|
184
254
|
|
|
@@ -197,7 +267,7 @@ describe("initAgentWidget docked mode", () => {
|
|
|
197
267
|
config: {
|
|
198
268
|
launcher: {
|
|
199
269
|
mountMode: "docked",
|
|
200
|
-
dock: { side: "right", width: "420px"
|
|
270
|
+
dock: { side: "right", width: "420px" },
|
|
201
271
|
},
|
|
202
272
|
},
|
|
203
273
|
});
|
|
@@ -205,7 +275,7 @@ describe("initAgentWidget docked mode", () => {
|
|
|
205
275
|
expect(createAgentExperienceMock).toHaveBeenCalledTimes(1);
|
|
206
276
|
handle.update({
|
|
207
277
|
launcher: {
|
|
208
|
-
dock: { side: "left", width: "500px"
|
|
278
|
+
dock: { side: "left", width: "500px" },
|
|
209
279
|
},
|
|
210
280
|
});
|
|
211
281
|
|
|
@@ -213,7 +283,7 @@ describe("initAgentWidget docked mode", () => {
|
|
|
213
283
|
const shell = document.querySelector<HTMLElement>('[data-persona-host-layout="docked"]');
|
|
214
284
|
const panelSlot = document.querySelector<HTMLElement>('[data-persona-dock-role="panel"]');
|
|
215
285
|
expect(shell?.firstElementChild?.getAttribute("data-persona-dock-role")).toBe("panel");
|
|
216
|
-
expect(panelSlot?.style.width).toBe("
|
|
286
|
+
expect(panelSlot?.style.width).toBe("0px");
|
|
217
287
|
});
|
|
218
288
|
|
|
219
289
|
it("supports shadow DOM hosts in docked mode", async () => {
|