@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
package/src/utils/migration.ts
DELETED
|
@@ -1,220 +0,0 @@
|
|
|
1
|
-
import type { AgentWidgetTheme } from '../types';
|
|
2
|
-
import type { PersonaTheme } from '../types/theme';
|
|
3
|
-
|
|
4
|
-
export interface V1ToV2MigrationOptions {
|
|
5
|
-
warn?: boolean;
|
|
6
|
-
colorScheme?: 'light' | 'dark' | 'auto';
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
const v1ToV2Mapping: Record<string, string> = {
|
|
10
|
-
primary: 'palette.colors.primary.500',
|
|
11
|
-
secondary: 'palette.colors.secondary.500',
|
|
12
|
-
accent: 'palette.colors.accent.600',
|
|
13
|
-
surface: 'palette.colors.gray.50',
|
|
14
|
-
muted: 'palette.colors.gray.500',
|
|
15
|
-
container: 'palette.colors.gray.100',
|
|
16
|
-
border: 'palette.colors.gray.200',
|
|
17
|
-
divider: 'palette.colors.gray.200',
|
|
18
|
-
messageBorder: 'palette.colors.gray.200',
|
|
19
|
-
inputBackground: 'palette.colors.gray.50',
|
|
20
|
-
callToAction: 'palette.colors.gray.900',
|
|
21
|
-
callToActionBackground: 'palette.colors.gray.50',
|
|
22
|
-
sendButtonBackgroundColor: 'semantic.colors.primary',
|
|
23
|
-
sendButtonTextColor: 'semantic.colors.textInverse',
|
|
24
|
-
sendButtonBorderColor: 'semantic.colors.primary',
|
|
25
|
-
closeButtonColor: 'palette.colors.gray.500',
|
|
26
|
-
closeButtonBackgroundColor: 'transparent',
|
|
27
|
-
clearChatIconColor: 'palette.colors.gray.500',
|
|
28
|
-
clearChatBackgroundColor: 'transparent',
|
|
29
|
-
micIconColor: 'palette.colors.gray.900',
|
|
30
|
-
micBackgroundColor: 'transparent',
|
|
31
|
-
recordingIconColor: 'palette.colors.white',
|
|
32
|
-
recordingBackgroundColor: 'palette.colors.error.500',
|
|
33
|
-
tooltipBackground: 'palette.colors.gray.900',
|
|
34
|
-
tooltipForeground: 'palette.colors.white',
|
|
35
|
-
};
|
|
36
|
-
|
|
37
|
-
const v1RadiusMapping: Record<string, string> = {
|
|
38
|
-
radiusSm: 'palette.radius.md',
|
|
39
|
-
radiusMd: 'palette.radius.lg',
|
|
40
|
-
radiusLg: 'palette.radius.xl',
|
|
41
|
-
launcherRadius: 'palette.radius.full',
|
|
42
|
-
buttonRadius: 'palette.radius.full',
|
|
43
|
-
};
|
|
44
|
-
|
|
45
|
-
export function migrateV1Theme(
|
|
46
|
-
v1Theme: AgentWidgetTheme | undefined,
|
|
47
|
-
options: V1ToV2MigrationOptions = {}
|
|
48
|
-
): Partial<PersonaTheme> {
|
|
49
|
-
if (!v1Theme) {
|
|
50
|
-
return {};
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
const migrated: any = {
|
|
54
|
-
palette: {
|
|
55
|
-
colors: {
|
|
56
|
-
primary: {},
|
|
57
|
-
gray: {},
|
|
58
|
-
secondary: {},
|
|
59
|
-
accent: {},
|
|
60
|
-
success: {},
|
|
61
|
-
warning: {},
|
|
62
|
-
error: {},
|
|
63
|
-
},
|
|
64
|
-
},
|
|
65
|
-
semantic: {
|
|
66
|
-
colors: {
|
|
67
|
-
interactive: {},
|
|
68
|
-
feedback: {},
|
|
69
|
-
},
|
|
70
|
-
},
|
|
71
|
-
};
|
|
72
|
-
|
|
73
|
-
for (const [key, value] of Object.entries(v1Theme)) {
|
|
74
|
-
if (!value) continue;
|
|
75
|
-
|
|
76
|
-
if (key in v1ToV2Mapping) {
|
|
77
|
-
const v2Path = v1ToV2Mapping[key];
|
|
78
|
-
const [category, type, name, shade] = v2Path.split('.');
|
|
79
|
-
|
|
80
|
-
if (category === 'palette' && type === 'colors') {
|
|
81
|
-
const colorName = name as keyof typeof migrated.palette.colors;
|
|
82
|
-
if (migrated.palette.colors[colorName]) {
|
|
83
|
-
(migrated.palette.colors[colorName] as any)[shade || '500'] = value;
|
|
84
|
-
}
|
|
85
|
-
} else if (category === 'semantic') {
|
|
86
|
-
const pathParts = v2Path.replace('semantic.colors.', '').split('.');
|
|
87
|
-
if (pathParts.length === 1) {
|
|
88
|
-
migrated.semantic.colors[pathParts[0]] = value;
|
|
89
|
-
} else {
|
|
90
|
-
(migrated.semantic.colors as any)[pathParts[0]] = {
|
|
91
|
-
...(migrated.semantic.colors as any)[pathParts[0]],
|
|
92
|
-
[pathParts[1]]: value,
|
|
93
|
-
};
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
} else if (key in v1RadiusMapping) {
|
|
97
|
-
if (!migrated.palette.radius) {
|
|
98
|
-
migrated.palette.radius = {};
|
|
99
|
-
}
|
|
100
|
-
const radiusKey = key.replace('radius', '').toLowerCase();
|
|
101
|
-
(migrated.palette.radius as any)[radiusKey || 'md'] = value;
|
|
102
|
-
} else if (key === 'inputFontFamily') {
|
|
103
|
-
if (!migrated.palette.typography) {
|
|
104
|
-
migrated.palette.typography = { fontFamily: {} };
|
|
105
|
-
}
|
|
106
|
-
migrated.palette.typography.fontFamily = {
|
|
107
|
-
sans: value === 'sans-serif' ? 'system-ui, sans-serif' : undefined,
|
|
108
|
-
serif: value === 'serif' ? 'Georgia, serif' : undefined,
|
|
109
|
-
mono: value === 'mono' ? 'monospace' : undefined,
|
|
110
|
-
};
|
|
111
|
-
} else if (key === 'inputFontWeight') {
|
|
112
|
-
if (!migrated.palette.typography) {
|
|
113
|
-
migrated.palette.typography = { fontWeight: {} };
|
|
114
|
-
}
|
|
115
|
-
migrated.palette.typography.fontWeight = {
|
|
116
|
-
normal: value,
|
|
117
|
-
};
|
|
118
|
-
} else if (key === 'panelBorder') {
|
|
119
|
-
if (!migrated.components) {
|
|
120
|
-
migrated.components = {};
|
|
121
|
-
}
|
|
122
|
-
if (!migrated.components.panel) {
|
|
123
|
-
migrated.components.panel = {};
|
|
124
|
-
}
|
|
125
|
-
migrated.components.panel.border = value;
|
|
126
|
-
} else if (key === 'panelShadow') {
|
|
127
|
-
if (!migrated.components) {
|
|
128
|
-
migrated.components = {};
|
|
129
|
-
}
|
|
130
|
-
if (!migrated.components.panel) {
|
|
131
|
-
migrated.components.panel = {};
|
|
132
|
-
}
|
|
133
|
-
migrated.components.panel.shadow = value;
|
|
134
|
-
} else if (key === 'panelBorderRadius') {
|
|
135
|
-
if (!migrated.components) {
|
|
136
|
-
migrated.components = {};
|
|
137
|
-
}
|
|
138
|
-
if (!migrated.components.panel) {
|
|
139
|
-
migrated.components.panel = {};
|
|
140
|
-
}
|
|
141
|
-
migrated.components.panel.borderRadius = value;
|
|
142
|
-
} else if (key === 'messageUserShadow') {
|
|
143
|
-
if (!migrated.components) migrated.components = {};
|
|
144
|
-
if (!migrated.components.message) migrated.components.message = {};
|
|
145
|
-
if (!migrated.components.message.user) migrated.components.message.user = {};
|
|
146
|
-
(migrated.components.message.user as { shadow?: string }).shadow = value as string;
|
|
147
|
-
} else if (key === 'messageAssistantShadow') {
|
|
148
|
-
if (!migrated.components) migrated.components = {};
|
|
149
|
-
if (!migrated.components.message) migrated.components.message = {};
|
|
150
|
-
if (!migrated.components.message.assistant) migrated.components.message.assistant = {};
|
|
151
|
-
(migrated.components.message.assistant as { shadow?: string }).shadow = value as string;
|
|
152
|
-
} else if (key === 'toolBubbleShadow') {
|
|
153
|
-
if (!migrated.components) migrated.components = {};
|
|
154
|
-
if (!migrated.components.toolBubble) migrated.components.toolBubble = {};
|
|
155
|
-
(migrated.components.toolBubble as { shadow?: string }).shadow = value as string;
|
|
156
|
-
} else if (key === 'reasoningBubbleShadow') {
|
|
157
|
-
if (!migrated.components) migrated.components = {};
|
|
158
|
-
if (!migrated.components.reasoningBubble) migrated.components.reasoningBubble = {};
|
|
159
|
-
(migrated.components.reasoningBubble as { shadow?: string }).shadow = value as string;
|
|
160
|
-
} else if (key === 'composerShadow') {
|
|
161
|
-
if (!migrated.components) migrated.components = {};
|
|
162
|
-
if (!migrated.components.composer) migrated.components.composer = {};
|
|
163
|
-
(migrated.components.composer as { shadow?: string }).shadow = value as string;
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
if (options.warn !== false) {
|
|
168
|
-
console.warn(
|
|
169
|
-
'[Persona Widget] v1 theme configuration detected. ' +
|
|
170
|
-
'v1 themes are deprecated in v2.0.0. ' +
|
|
171
|
-
'Please migrate to the new semantic token system. ' +
|
|
172
|
-
'See https://persona.sh/docs/v2-migration for guidance.'
|
|
173
|
-
);
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
return migrated;
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
export function validateV1Theme(v1Theme: unknown): {
|
|
180
|
-
valid: boolean;
|
|
181
|
-
warnings: string[];
|
|
182
|
-
} {
|
|
183
|
-
const warnings: string[] = [];
|
|
184
|
-
const theme = v1Theme as AgentWidgetTheme | undefined;
|
|
185
|
-
|
|
186
|
-
if (!theme) {
|
|
187
|
-
return { valid: true, warnings: [] };
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
const v1ThemeChromeKeys = new Set([
|
|
191
|
-
'panelBorder',
|
|
192
|
-
'panelShadow',
|
|
193
|
-
'panelBorderRadius',
|
|
194
|
-
'messageUserShadow',
|
|
195
|
-
'messageAssistantShadow',
|
|
196
|
-
'toolBubbleShadow',
|
|
197
|
-
'reasoningBubbleShadow',
|
|
198
|
-
'composerShadow',
|
|
199
|
-
]);
|
|
200
|
-
|
|
201
|
-
const deprecatedProperties = Object.keys(theme).filter(
|
|
202
|
-
(key) =>
|
|
203
|
-
!(
|
|
204
|
-
key in v1ToV2Mapping ||
|
|
205
|
-
key in v1RadiusMapping ||
|
|
206
|
-
key === 'inputFontFamily' ||
|
|
207
|
-
key === 'inputFontWeight' ||
|
|
208
|
-
key.startsWith('panel') ||
|
|
209
|
-
v1ThemeChromeKeys.has(key)
|
|
210
|
-
)
|
|
211
|
-
);
|
|
212
|
-
|
|
213
|
-
if (deprecatedProperties.length > 0) {
|
|
214
|
-
warnings.push(
|
|
215
|
-
`The following v1 theme properties have no v2 equivalent and will be ignored: ${deprecatedProperties.join(', ')}`
|
|
216
|
-
);
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
return { valid: true, warnings };
|
|
220
|
-
}
|