@runtypelabs/persona 1.48.0 → 2.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 +140 -8
- package/dist/index.cjs +90 -39
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1055 -24
- package/dist/index.d.ts +1055 -24
- package/dist/index.global.js +111 -60
- package/dist/index.global.js.map +1 -1
- package/dist/index.js +90 -39
- package/dist/index.js.map +1 -1
- package/dist/install.global.js +1 -1
- package/dist/install.global.js.map +1 -1
- package/dist/widget.css +836 -513
- package/package.json +1 -1
- package/src/artifacts-session.test.ts +80 -0
- package/src/client.test.ts +20 -21
- package/src/client.ts +153 -4
- package/src/components/approval-bubble.ts +45 -42
- package/src/components/artifact-card.ts +91 -0
- package/src/components/artifact-pane.ts +501 -0
- package/src/components/composer-builder.ts +32 -27
- package/src/components/event-stream-view.ts +40 -40
- package/src/components/feedback.ts +36 -36
- package/src/components/forms.ts +11 -11
- package/src/components/header-builder.test.ts +32 -0
- package/src/components/header-builder.ts +55 -36
- package/src/components/header-layouts.ts +58 -125
- package/src/components/launcher.ts +36 -21
- package/src/components/message-bubble.ts +92 -65
- package/src/components/messages.ts +2 -2
- package/src/components/panel.ts +42 -11
- package/src/components/reasoning-bubble.ts +23 -23
- package/src/components/registry.ts +4 -0
- package/src/components/suggestions.ts +1 -1
- package/src/components/tool-bubble.ts +32 -32
- package/src/defaults.ts +30 -4
- package/src/index.ts +80 -2
- package/src/install.ts +22 -0
- package/src/plugins/types.ts +23 -0
- package/src/postprocessors.ts +2 -2
- package/src/runtime/host-layout.ts +174 -0
- package/src/runtime/init.test.ts +236 -0
- package/src/runtime/init.ts +114 -55
- package/src/session.ts +135 -2
- package/src/styles/tailwind.css +1 -1
- package/src/styles/widget.css +836 -513
- package/src/types/theme.ts +354 -0
- package/src/types.ts +314 -15
- package/src/ui.docked.test.ts +104 -0
- package/src/ui.ts +940 -227
- package/src/utils/artifact-gate.test.ts +255 -0
- package/src/utils/artifact-gate.ts +142 -0
- package/src/utils/artifact-resize.test.ts +64 -0
- package/src/utils/artifact-resize.ts +67 -0
- package/src/utils/attachment-manager.ts +10 -10
- package/src/utils/code-generators.test.ts +52 -0
- package/src/utils/code-generators.ts +40 -36
- package/src/utils/dock.ts +17 -0
- package/src/utils/dom-context.test.ts +504 -0
- package/src/utils/dom-context.ts +896 -0
- package/src/utils/dom.ts +12 -1
- package/src/utils/message-fingerprint.test.ts +187 -0
- package/src/utils/message-fingerprint.ts +105 -0
- package/src/utils/migration.ts +179 -0
- package/src/utils/morph.ts +1 -1
- package/src/utils/plugins.ts +175 -0
- package/src/utils/positioning.ts +4 -4
- package/src/utils/theme.test.ts +125 -0
- package/src/utils/theme.ts +216 -60
- package/src/utils/tokens.ts +682 -0
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import { createElement } from "../utils/dom";
|
|
2
2
|
import { renderLucideIcon } from "../utils/icons";
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
AgentWidgetConfig,
|
|
5
|
+
AgentWidgetHeaderLayoutConfig,
|
|
6
|
+
AgentWidgetHeaderTrailingAction
|
|
7
|
+
} from "../types";
|
|
4
8
|
import { buildHeader, HeaderElements, attachHeaderToContainer as _attachHeaderToContainer } from "./header-builder";
|
|
5
9
|
|
|
6
10
|
export interface HeaderLayoutContext {
|
|
@@ -8,6 +12,9 @@ export interface HeaderLayoutContext {
|
|
|
8
12
|
showClose?: boolean;
|
|
9
13
|
onClose?: () => void;
|
|
10
14
|
onClearChat?: () => void;
|
|
15
|
+
/** Passed from `buildHeaderWithLayout` for minimal/default chrome extensions */
|
|
16
|
+
layoutHeaderConfig?: AgentWidgetHeaderLayoutConfig;
|
|
17
|
+
onHeaderAction?: (actionId: string) => void;
|
|
11
18
|
}
|
|
12
19
|
|
|
13
20
|
export type HeaderLayoutRenderer = (context: HeaderLayoutContext) => HeaderElements;
|
|
@@ -29,20 +36,56 @@ export const buildDefaultHeader: HeaderLayoutRenderer = (context) => {
|
|
|
29
36
|
* Build minimal header layout
|
|
30
37
|
* Simplified layout with just title and close button
|
|
31
38
|
*/
|
|
39
|
+
function appendTrailingHeaderActions(
|
|
40
|
+
container: HTMLElement,
|
|
41
|
+
actions: AgentWidgetHeaderTrailingAction[] | undefined,
|
|
42
|
+
onAction?: (id: string) => void
|
|
43
|
+
): void {
|
|
44
|
+
if (!actions?.length) return;
|
|
45
|
+
for (const a of actions) {
|
|
46
|
+
const btn = createElement(
|
|
47
|
+
"button",
|
|
48
|
+
"persona-inline-flex persona-items-center persona-justify-center persona-rounded-md persona-border-none persona-bg-transparent persona-p-0 persona-text-persona-muted hover:persona-opacity-80"
|
|
49
|
+
) as HTMLButtonElement;
|
|
50
|
+
btn.type = "button";
|
|
51
|
+
btn.setAttribute("aria-label", a.ariaLabel ?? a.label ?? a.id);
|
|
52
|
+
if (a.icon) {
|
|
53
|
+
const ic = renderLucideIcon(a.icon, 14, "currentColor", 2);
|
|
54
|
+
if (ic) btn.appendChild(ic);
|
|
55
|
+
} else if (a.label) {
|
|
56
|
+
btn.textContent = a.label;
|
|
57
|
+
}
|
|
58
|
+
btn.addEventListener("click", () => onAction?.(a.id));
|
|
59
|
+
container.appendChild(btn);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
32
63
|
export const buildMinimalHeader: HeaderLayoutRenderer = (context) => {
|
|
33
|
-
const { config, showClose = true, onClose } = context;
|
|
64
|
+
const { config, showClose = true, onClose, layoutHeaderConfig, onHeaderAction } = context;
|
|
34
65
|
const launcher = config?.launcher ?? {};
|
|
35
66
|
|
|
36
67
|
const header = createElement(
|
|
37
68
|
"div",
|
|
38
|
-
"
|
|
69
|
+
"persona-flex persona-items-center persona-justify-between persona-bg-persona-surface persona-px-6 persona-py-4 persona-border-b-persona-divider"
|
|
70
|
+
);
|
|
71
|
+
|
|
72
|
+
const titleRow = createElement(
|
|
73
|
+
"div",
|
|
74
|
+
"persona-flex persona-min-w-0 persona-flex-1 persona-items-center persona-gap-1"
|
|
39
75
|
);
|
|
40
76
|
|
|
41
77
|
// Title only (no icon, no subtitle)
|
|
42
|
-
const title = createElement("span", "
|
|
78
|
+
const title = createElement("span", "persona-text-base persona-font-semibold persona-truncate");
|
|
43
79
|
title.textContent = launcher.title ?? "Chat Assistant";
|
|
44
80
|
|
|
45
|
-
|
|
81
|
+
titleRow.appendChild(title);
|
|
82
|
+
appendTrailingHeaderActions(
|
|
83
|
+
titleRow,
|
|
84
|
+
layoutHeaderConfig?.trailingActions,
|
|
85
|
+
layoutHeaderConfig?.onAction ?? onHeaderAction
|
|
86
|
+
);
|
|
87
|
+
|
|
88
|
+
header.appendChild(titleRow);
|
|
46
89
|
|
|
47
90
|
// Close button
|
|
48
91
|
const closeButtonSize = launcher.closeButtonSize ?? "32px";
|
|
@@ -50,7 +93,7 @@ export const buildMinimalHeader: HeaderLayoutRenderer = (context) => {
|
|
|
50
93
|
|
|
51
94
|
const closeButton = createElement(
|
|
52
95
|
"button",
|
|
53
|
-
"
|
|
96
|
+
"persona-inline-flex persona-items-center persona-justify-center persona-rounded-full persona-text-persona-muted hover:persona-bg-gray-100 persona-cursor-pointer persona-border-none"
|
|
54
97
|
) as HTMLButtonElement;
|
|
55
98
|
closeButton.style.height = closeButtonSize;
|
|
56
99
|
closeButton.style.width = closeButtonSize;
|
|
@@ -78,6 +121,8 @@ export const buildMinimalHeader: HeaderLayoutRenderer = (context) => {
|
|
|
78
121
|
closeButtonWrapper.appendChild(closeButton);
|
|
79
122
|
header.appendChild(closeButtonWrapper);
|
|
80
123
|
|
|
124
|
+
// title was moved into titleRow; keep headerTitle ref pointing at title for updateController
|
|
125
|
+
|
|
81
126
|
// Create placeholder elements for compatibility
|
|
82
127
|
const iconHolder = createElement("div");
|
|
83
128
|
iconHolder.style.display = "none";
|
|
@@ -96,129 +141,13 @@ export const buildMinimalHeader: HeaderLayoutRenderer = (context) => {
|
|
|
96
141
|
};
|
|
97
142
|
};
|
|
98
143
|
|
|
99
|
-
/**
|
|
100
|
-
* Build expanded header layout
|
|
101
|
-
* Full branding area with additional space for custom content
|
|
102
|
-
*/
|
|
103
|
-
export const buildExpandedHeader: HeaderLayoutRenderer = (context) => {
|
|
104
|
-
const { config, showClose = true, onClose, onClearChat: _onClearChat } = context;
|
|
105
|
-
const launcher = config?.launcher ?? {};
|
|
106
|
-
|
|
107
|
-
const header = createElement(
|
|
108
|
-
"div",
|
|
109
|
-
"tvw-flex tvw-flex-col tvw-bg-cw-surface tvw-px-6 tvw-py-5 tvw-border-b-cw-divider"
|
|
110
|
-
);
|
|
111
|
-
|
|
112
|
-
// Top row: icon + text + buttons
|
|
113
|
-
const topRow = createElement(
|
|
114
|
-
"div",
|
|
115
|
-
"tvw-flex tvw-items-center tvw-gap-3"
|
|
116
|
-
);
|
|
117
|
-
|
|
118
|
-
// Icon
|
|
119
|
-
const headerIconSize = launcher.headerIconSize ?? "56px";
|
|
120
|
-
const iconHolder = createElement(
|
|
121
|
-
"div",
|
|
122
|
-
"tvw-flex tvw-items-center tvw-justify-center tvw-rounded-xl tvw-bg-cw-primary tvw-text-white tvw-text-2xl"
|
|
123
|
-
);
|
|
124
|
-
iconHolder.style.height = headerIconSize;
|
|
125
|
-
iconHolder.style.width = headerIconSize;
|
|
126
|
-
|
|
127
|
-
const headerIconName = launcher.headerIconName;
|
|
128
|
-
if (headerIconName) {
|
|
129
|
-
const iconSize = parseFloat(headerIconSize) || 24;
|
|
130
|
-
const iconSvg = renderLucideIcon(headerIconName, iconSize * 0.5, "#ffffff", 2);
|
|
131
|
-
if (iconSvg) {
|
|
132
|
-
iconHolder.replaceChildren(iconSvg);
|
|
133
|
-
} else {
|
|
134
|
-
iconHolder.textContent = launcher.agentIconText ?? "💬";
|
|
135
|
-
}
|
|
136
|
-
} else if (launcher.iconUrl) {
|
|
137
|
-
const img = createElement("img") as HTMLImageElement;
|
|
138
|
-
img.src = launcher.iconUrl;
|
|
139
|
-
img.alt = "";
|
|
140
|
-
img.className = "tvw-rounded-xl tvw-object-cover";
|
|
141
|
-
img.style.height = headerIconSize;
|
|
142
|
-
img.style.width = headerIconSize;
|
|
143
|
-
iconHolder.replaceChildren(img);
|
|
144
|
-
} else {
|
|
145
|
-
iconHolder.textContent = launcher.agentIconText ?? "💬";
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
// Title and subtitle
|
|
149
|
-
const headerCopy = createElement("div", "tvw-flex tvw-flex-col tvw-flex-1");
|
|
150
|
-
const title = createElement("span", "tvw-text-lg tvw-font-semibold");
|
|
151
|
-
title.textContent = launcher.title ?? "Chat Assistant";
|
|
152
|
-
const subtitle = createElement("span", "tvw-text-sm tvw-text-cw-muted");
|
|
153
|
-
subtitle.textContent = launcher.subtitle ?? "Here to help you get answers fast";
|
|
154
|
-
headerCopy.append(title, subtitle);
|
|
155
|
-
|
|
156
|
-
topRow.append(iconHolder, headerCopy);
|
|
157
|
-
|
|
158
|
-
// Close button
|
|
159
|
-
const closeButtonSize = launcher.closeButtonSize ?? "32px";
|
|
160
|
-
const closeButtonWrapper = createElement("div", "");
|
|
161
|
-
|
|
162
|
-
const closeButton = createElement(
|
|
163
|
-
"button",
|
|
164
|
-
"tvw-inline-flex tvw-items-center tvw-justify-center tvw-rounded-full tvw-text-cw-muted hover:tvw-bg-gray-100 tvw-cursor-pointer tvw-border-none"
|
|
165
|
-
) as HTMLButtonElement;
|
|
166
|
-
closeButton.style.height = closeButtonSize;
|
|
167
|
-
closeButton.style.width = closeButtonSize;
|
|
168
|
-
closeButton.type = "button";
|
|
169
|
-
closeButton.setAttribute("aria-label", "Close chat");
|
|
170
|
-
closeButton.style.display = showClose ? "" : "none";
|
|
171
|
-
|
|
172
|
-
const closeButtonIconName = launcher.closeButtonIconName ?? "x";
|
|
173
|
-
const closeIconSvg = renderLucideIcon(
|
|
174
|
-
closeButtonIconName,
|
|
175
|
-
"20px",
|
|
176
|
-
launcher.closeButtonColor || "",
|
|
177
|
-
2
|
|
178
|
-
);
|
|
179
|
-
if (closeIconSvg) {
|
|
180
|
-
closeButton.appendChild(closeIconSvg);
|
|
181
|
-
} else {
|
|
182
|
-
closeButton.textContent = "×";
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
if (onClose) {
|
|
186
|
-
closeButton.addEventListener("click", onClose);
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
closeButtonWrapper.appendChild(closeButton);
|
|
190
|
-
topRow.appendChild(closeButtonWrapper);
|
|
191
|
-
|
|
192
|
-
header.appendChild(topRow);
|
|
193
|
-
|
|
194
|
-
// Bottom row: additional space for status or branding
|
|
195
|
-
const bottomRow = createElement(
|
|
196
|
-
"div",
|
|
197
|
-
"tvw-mt-3 tvw-pt-3 tvw-border-t tvw-border-gray-100 tvw-text-xs tvw-text-cw-muted"
|
|
198
|
-
);
|
|
199
|
-
bottomRow.textContent = "Online and ready to help";
|
|
200
|
-
header.appendChild(bottomRow);
|
|
201
|
-
|
|
202
|
-
return {
|
|
203
|
-
header,
|
|
204
|
-
iconHolder,
|
|
205
|
-
headerTitle: title,
|
|
206
|
-
headerSubtitle: subtitle,
|
|
207
|
-
closeButton,
|
|
208
|
-
closeButtonWrapper,
|
|
209
|
-
clearChatButton: null,
|
|
210
|
-
clearChatButtonWrapper: null
|
|
211
|
-
};
|
|
212
|
-
};
|
|
213
|
-
|
|
214
144
|
/**
|
|
215
145
|
* Header layout registry
|
|
216
146
|
* Maps layout names to their renderer functions
|
|
217
147
|
*/
|
|
218
148
|
export const headerLayouts: Record<string, HeaderLayoutRenderer> = {
|
|
219
149
|
default: buildDefaultHeader,
|
|
220
|
-
minimal: buildMinimalHeader
|
|
221
|
-
expanded: buildExpandedHeader
|
|
150
|
+
minimal: buildMinimalHeader
|
|
222
151
|
};
|
|
223
152
|
|
|
224
153
|
/**
|
|
@@ -242,7 +171,9 @@ export const buildHeaderWithLayout = (
|
|
|
242
171
|
const customHeader = layoutConfig.render({
|
|
243
172
|
config,
|
|
244
173
|
onClose: context?.onClose,
|
|
245
|
-
onClearChat: context?.onClearChat
|
|
174
|
+
onClearChat: context?.onClearChat,
|
|
175
|
+
trailingActions: layoutConfig.trailingActions,
|
|
176
|
+
onAction: layoutConfig.onAction
|
|
246
177
|
});
|
|
247
178
|
|
|
248
179
|
// Wrap in HeaderElements structure
|
|
@@ -276,7 +207,9 @@ export const buildHeaderWithLayout = (
|
|
|
276
207
|
config,
|
|
277
208
|
showClose: layoutConfig?.showCloseButton ?? context?.showClose ?? true,
|
|
278
209
|
onClose: context?.onClose,
|
|
279
|
-
onClearChat: context?.onClearChat
|
|
210
|
+
onClearChat: context?.onClearChat,
|
|
211
|
+
layoutHeaderConfig: layoutConfig,
|
|
212
|
+
onHeaderAction: layoutConfig?.onAction
|
|
280
213
|
});
|
|
281
214
|
|
|
282
215
|
// Apply visibility settings from layout config
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { createElement } from "../utils/dom";
|
|
2
2
|
import { AgentWidgetConfig } from "../types";
|
|
3
3
|
import { positionMap } from "../utils/positioning";
|
|
4
|
+
import { isDockedMountMode, resolveDockConfig } from "../utils/dock";
|
|
4
5
|
import { renderLucideIcon } from "../utils/icons";
|
|
5
6
|
|
|
6
7
|
export interface LauncherButton {
|
|
@@ -16,18 +17,19 @@ export const createLauncherButton = (
|
|
|
16
17
|
const button = createElement("button") as HTMLButtonElement;
|
|
17
18
|
button.type = "button";
|
|
18
19
|
button.innerHTML = `
|
|
19
|
-
<span class="
|
|
20
|
-
<img data-role="launcher-image" class="
|
|
21
|
-
<span class="
|
|
22
|
-
<span class="
|
|
23
|
-
<span class="
|
|
20
|
+
<span class="persona-inline-flex persona-items-center persona-justify-center persona-rounded-full persona-bg-persona-primary persona-text-white" data-role="launcher-icon">💬</span>
|
|
21
|
+
<img data-role="launcher-image" class="persona-rounded-full persona-object-cover" alt="" style="display:none" />
|
|
22
|
+
<span class="persona-flex persona-flex-col persona-items-start persona-text-left">
|
|
23
|
+
<span class="persona-text-sm persona-font-semibold persona-text-persona-primary" data-role="launcher-title"></span>
|
|
24
|
+
<span class="persona-text-xs persona-text-persona-muted" data-role="launcher-subtitle"></span>
|
|
24
25
|
</span>
|
|
25
|
-
<span class="
|
|
26
|
+
<span class="persona-ml-2 persona-grid persona-place-items-center persona-rounded-full persona-bg-persona-primary persona-text-persona-call-to-action" data-role="launcher-call-to-action-icon">↗</span>
|
|
26
27
|
`;
|
|
27
28
|
button.addEventListener("click", onToggle);
|
|
28
29
|
|
|
29
30
|
const update = (newConfig: AgentWidgetConfig) => {
|
|
30
31
|
const launcher = newConfig.launcher ?? {};
|
|
32
|
+
const dockedMode = isDockedMountMode(newConfig);
|
|
31
33
|
|
|
32
34
|
const titleEl = button.querySelector("[data-role='launcher-title']");
|
|
33
35
|
if (titleEl) {
|
|
@@ -40,9 +42,9 @@ export const createLauncherButton = (
|
|
|
40
42
|
}
|
|
41
43
|
|
|
42
44
|
// Hide/show text container
|
|
43
|
-
const textContainer = button.querySelector(".
|
|
45
|
+
const textContainer = button.querySelector(".persona-flex-col");
|
|
44
46
|
if (textContainer) {
|
|
45
|
-
if (launcher.textHidden) {
|
|
47
|
+
if (launcher.textHidden || dockedMode) {
|
|
46
48
|
(textContainer as HTMLElement).style.display = "none";
|
|
47
49
|
} else {
|
|
48
50
|
(textContainer as HTMLElement).style.display = "";
|
|
@@ -65,7 +67,7 @@ export const createLauncherButton = (
|
|
|
65
67
|
if (launcher.agentIconName) {
|
|
66
68
|
// Use Lucide icon
|
|
67
69
|
const iconSizeNum = parseFloat(iconSize) || 24;
|
|
68
|
-
const iconSvg = renderLucideIcon(launcher.agentIconName, iconSizeNum * 0.6, "#ffffff", 2);
|
|
70
|
+
const iconSvg = renderLucideIcon(launcher.agentIconName, iconSizeNum * 0.6, "var(--persona-text-inverse, #ffffff)", 2);
|
|
69
71
|
if (iconSvg) {
|
|
70
72
|
icon.appendChild(iconSvg);
|
|
71
73
|
icon.style.display = "";
|
|
@@ -108,10 +110,10 @@ export const createLauncherButton = (
|
|
|
108
110
|
// Apply background color if configured
|
|
109
111
|
if (launcher.callToActionIconBackgroundColor) {
|
|
110
112
|
callToActionIconEl.style.backgroundColor = launcher.callToActionIconBackgroundColor;
|
|
111
|
-
callToActionIconEl.classList.remove("
|
|
113
|
+
callToActionIconEl.classList.remove("persona-bg-persona-primary");
|
|
112
114
|
} else {
|
|
113
115
|
callToActionIconEl.style.backgroundColor = "";
|
|
114
|
-
callToActionIconEl.classList.add("
|
|
116
|
+
callToActionIconEl.classList.add("persona-bg-persona-primary");
|
|
115
117
|
}
|
|
116
118
|
|
|
117
119
|
// Calculate padding to adjust icon size
|
|
@@ -130,7 +132,7 @@ export const createLauncherButton = (
|
|
|
130
132
|
if (launcher.callToActionIconHidden) {
|
|
131
133
|
callToActionIconEl.style.display = "none";
|
|
132
134
|
} else {
|
|
133
|
-
callToActionIconEl.style.display = "";
|
|
135
|
+
callToActionIconEl.style.display = dockedMode ? "none" : "";
|
|
134
136
|
|
|
135
137
|
// Clear existing content
|
|
136
138
|
callToActionIconEl.innerHTML = "";
|
|
@@ -158,19 +160,34 @@ export const createLauncherButton = (
|
|
|
158
160
|
? positionMap[launcher.position]
|
|
159
161
|
: positionMap["bottom-right"];
|
|
160
162
|
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
const
|
|
164
|
-
"
|
|
163
|
+
const floatingBase =
|
|
164
|
+
"persona-fixed persona-flex persona-items-center persona-gap-3 persona-rounded-launcher persona-bg-persona-surface persona-py-2.5 persona-pl-3 persona-pr-3 persona-transition hover:persona-translate-y-[-2px] persona-cursor-pointer persona-z-50";
|
|
165
|
+
const dockedBase =
|
|
166
|
+
"persona-relative persona-mt-4 persona-mb-4 persona-mx-auto persona-flex persona-items-center persona-justify-center persona-rounded-launcher persona-bg-persona-surface persona-transition hover:persona-translate-y-[-2px] persona-cursor-pointer";
|
|
165
167
|
|
|
166
|
-
button.className = `${
|
|
168
|
+
button.className = dockedMode ? dockedBase : `${floatingBase} ${positionClass}`;
|
|
167
169
|
|
|
168
170
|
// Apply launcher border and shadow from config (with defaults matching previous Tailwind classes)
|
|
169
|
-
const defaultBorder = "1px solid #e5e7eb";
|
|
170
|
-
const defaultShadow = "0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -4px rgba(0, 0, 0, 0.1)";
|
|
171
|
+
const defaultBorder = "1px solid var(--persona-border, #e5e7eb)";
|
|
172
|
+
const defaultShadow = "var(--persona-shadow, 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -4px rgba(0, 0, 0, 0.1))";
|
|
171
173
|
|
|
172
174
|
button.style.border = launcher.border ?? defaultBorder;
|
|
173
175
|
button.style.boxShadow = launcher.shadow ?? defaultShadow;
|
|
176
|
+
|
|
177
|
+
if (dockedMode) {
|
|
178
|
+
const dock = resolveDockConfig(newConfig);
|
|
179
|
+
button.style.width = `calc(${dock.collapsedWidth} - 16px)`;
|
|
180
|
+
button.style.minWidth = "40px";
|
|
181
|
+
button.style.maxWidth = `calc(${dock.collapsedWidth} - 16px)`;
|
|
182
|
+
button.style.justifyContent = "center";
|
|
183
|
+
button.style.padding = "12px 0";
|
|
184
|
+
} else {
|
|
185
|
+
button.style.width = "";
|
|
186
|
+
button.style.minWidth = "";
|
|
187
|
+
button.style.maxWidth = "";
|
|
188
|
+
button.style.justifyContent = "";
|
|
189
|
+
button.style.padding = "";
|
|
190
|
+
}
|
|
174
191
|
};
|
|
175
192
|
|
|
176
193
|
const destroy = () => {
|
|
@@ -189,5 +206,3 @@ export const createLauncherButton = (
|
|
|
189
206
|
destroy
|
|
190
207
|
};
|
|
191
208
|
};
|
|
192
|
-
|
|
193
|
-
|