@runtypelabs/persona 3.5.2 → 3.6.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/dist/index.cjs +30 -30
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +14 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.global.js +41 -41
- package/dist/index.global.js.map +1 -1
- package/dist/index.js +29 -29
- package/dist/index.js.map +1 -1
- package/dist/theme-editor.cjs +17728 -0
- package/dist/theme-editor.d.cts +3857 -0
- package/dist/theme-editor.d.ts +3857 -0
- package/dist/theme-editor.js +17623 -0
- package/dist/theme-reference.cjs +1 -1
- package/dist/theme-reference.d.cts +14 -0
- package/dist/theme-reference.d.ts +14 -0
- package/dist/theme-reference.js +1 -1
- package/dist/widget.css +29 -25
- package/package.json +9 -7
- package/src/components/artifact-card.ts +1 -1
- package/src/components/composer-builder.ts +16 -29
- package/src/components/demo-carousel.ts +4 -4
- package/src/components/event-stream-view.ts +1 -1
- package/src/components/header-builder.ts +2 -2
- package/src/components/launcher.ts +9 -0
- package/src/components/message-bubble.ts +9 -3
- package/src/components/suggestions.ts +1 -1
- package/src/defaults.ts +9 -9
- package/src/styles/widget.css +29 -25
- package/src/theme-editor/color-utils.ts +252 -0
- package/src/theme-editor/index.ts +130 -0
- package/src/theme-editor/presets.ts +144 -0
- package/src/theme-editor/preview-utils.ts +265 -0
- package/src/theme-editor/preview.ts +445 -0
- package/src/theme-editor/role-mappings.ts +331 -0
- package/src/theme-editor/sections.ts +952 -0
- package/src/theme-editor/state.ts +298 -0
- package/src/theme-editor/types.ts +177 -0
- package/src/theme-editor.ts +2 -0
- package/src/types/theme.ts +1 -0
- package/src/ui.ts +53 -58
- package/src/utils/plugins.ts +1 -1
- package/src/utils/theme.test.ts +10 -8
- package/src/utils/theme.ts +11 -11
- package/src/utils/tokens.ts +88 -41
- package/widget.css +0 -1
package/src/ui.ts
CHANGED
|
@@ -703,9 +703,7 @@ export const createAgentExperience = (
|
|
|
703
703
|
eventStreamView.update();
|
|
704
704
|
}
|
|
705
705
|
if (eventStreamToggleBtn) {
|
|
706
|
-
eventStreamToggleBtn.
|
|
707
|
-
eventStreamToggleBtn.classList.add("persona-text-persona-accent");
|
|
708
|
-
eventStreamToggleBtn.style.boxShadow = "inset 0 0 0 1.5px var(--persona-accent, #3b82f6)";
|
|
706
|
+
eventStreamToggleBtn.style.boxShadow = `inset 0 0 0 1.5px ${HEADER_THEME_CSS.actionIconColor}`;
|
|
709
707
|
const activeClasses = config.features?.eventStream?.classNames?.toggleButtonActive;
|
|
710
708
|
if (activeClasses) activeClasses.split(/\s+/).forEach(c => c && eventStreamToggleBtn!.classList.add(c));
|
|
711
709
|
}
|
|
@@ -732,8 +730,6 @@ export const createAgentExperience = (
|
|
|
732
730
|
}
|
|
733
731
|
body.style.display = "";
|
|
734
732
|
if (eventStreamToggleBtn) {
|
|
735
|
-
eventStreamToggleBtn.classList.remove("persona-text-persona-accent");
|
|
736
|
-
eventStreamToggleBtn.classList.add("persona-text-persona-muted");
|
|
737
733
|
eventStreamToggleBtn.style.boxShadow = "";
|
|
738
734
|
const activeClasses = config.features?.eventStream?.classNames?.toggleButtonActive;
|
|
739
735
|
if (activeClasses) activeClasses.split(/\s+/).forEach(c => c && eventStreamToggleBtn!.classList.remove(c));
|
|
@@ -750,10 +746,11 @@ export const createAgentExperience = (
|
|
|
750
746
|
let eventStreamToggleBtn: HTMLButtonElement | null = null;
|
|
751
747
|
if (showEventStreamToggle) {
|
|
752
748
|
const esClassNames = config.features?.eventStream?.classNames;
|
|
753
|
-
const toggleBtnClasses = "persona-inline-flex persona-items-center persona-justify-center persona-rounded-full
|
|
749
|
+
const toggleBtnClasses = "persona-inline-flex persona-items-center persona-justify-center persona-rounded-full hover:persona-opacity-80 persona-cursor-pointer persona-border-none persona-bg-transparent persona-p-1" + (esClassNames?.toggleButton ? " " + esClassNames.toggleButton : "");
|
|
754
750
|
eventStreamToggleBtn = createElement("button", toggleBtnClasses) as HTMLButtonElement;
|
|
755
751
|
eventStreamToggleBtn.style.width = "28px";
|
|
756
752
|
eventStreamToggleBtn.style.height = "28px";
|
|
753
|
+
eventStreamToggleBtn.style.color = HEADER_THEME_CSS.actionIconColor;
|
|
757
754
|
eventStreamToggleBtn.type = "button";
|
|
758
755
|
eventStreamToggleBtn.setAttribute("aria-label", "Event Stream");
|
|
759
756
|
eventStreamToggleBtn.title = "Event Stream";
|
|
@@ -877,13 +874,18 @@ export const createAgentExperience = (
|
|
|
877
874
|
ensureComposerAttachmentSurface(footer);
|
|
878
875
|
bindComposerRefsFromFooter(footer);
|
|
879
876
|
|
|
880
|
-
// Apply contentMaxWidth to composer form if configured
|
|
877
|
+
// Apply contentMaxWidth to composer form and attachment previews if configured
|
|
881
878
|
const contentMaxWidth = config.layout?.contentMaxWidth;
|
|
882
879
|
if (contentMaxWidth && composerForm) {
|
|
883
880
|
composerForm.style.maxWidth = contentMaxWidth;
|
|
884
881
|
composerForm.style.marginLeft = "auto";
|
|
885
882
|
composerForm.style.marginRight = "auto";
|
|
886
883
|
}
|
|
884
|
+
if (contentMaxWidth && attachmentPreviewsContainer) {
|
|
885
|
+
attachmentPreviewsContainer.style.maxWidth = contentMaxWidth;
|
|
886
|
+
attachmentPreviewsContainer.style.marginLeft = "auto";
|
|
887
|
+
attachmentPreviewsContainer.style.marginRight = "auto";
|
|
888
|
+
}
|
|
887
889
|
|
|
888
890
|
if (config.attachments?.enabled && attachmentInput && attachmentPreviewsContainer) {
|
|
889
891
|
attachmentManager = AttachmentManager.fromConfig(config.attachments);
|
|
@@ -2388,7 +2390,6 @@ export const createAgentExperience = (
|
|
|
2388
2390
|
"persona-shadow-sm",
|
|
2389
2391
|
"persona-bg-persona-surface",
|
|
2390
2392
|
"persona-border",
|
|
2391
|
-
"persona-border-persona-message-border",
|
|
2392
2393
|
"persona-text-persona-primary",
|
|
2393
2394
|
"persona-px-5",
|
|
2394
2395
|
"persona-py-3"
|
|
@@ -2400,6 +2401,7 @@ export const createAgentExperience = (
|
|
|
2400
2401
|
"persona-text-persona-primary"
|
|
2401
2402
|
].join(" ");
|
|
2402
2403
|
typingBubble.setAttribute("data-typing-indicator", "true");
|
|
2404
|
+
typingBubble.style.borderColor = "var(--persona-message-assistant-border, var(--persona-border, #e5e7eb))";
|
|
2403
2405
|
|
|
2404
2406
|
typingBubble.appendChild(typingIndicator);
|
|
2405
2407
|
|
|
@@ -2483,12 +2485,16 @@ export const createAgentExperience = (
|
|
|
2483
2485
|
// This allows the browser to update layout (e.g., typing indicator removal) before scrolling
|
|
2484
2486
|
// Use double RAF to ensure layout has fully settled before starting scroll animation
|
|
2485
2487
|
// Get the scrollable container using its unique ID (#persona-scroll-container)
|
|
2486
|
-
|
|
2488
|
+
// Only smooth-scroll if auto-scroll hasn't been blocked by the user scrolling up
|
|
2489
|
+
if (shouldAutoScroll && !isAutoScrollBlocked) {
|
|
2487
2490
|
requestAnimationFrame(() => {
|
|
2488
|
-
|
|
2489
|
-
|
|
2491
|
+
requestAnimationFrame(() => {
|
|
2492
|
+
if (!shouldAutoScroll || isAutoScrollBlocked) return;
|
|
2493
|
+
const scrollableContainer = getScrollableContainer();
|
|
2494
|
+
smoothScrollToBottom(scrollableContainer);
|
|
2495
|
+
});
|
|
2490
2496
|
});
|
|
2491
|
-
}
|
|
2497
|
+
}
|
|
2492
2498
|
};
|
|
2493
2499
|
|
|
2494
2500
|
// Alias for clarity - the implementation handles flicker prevention via typing indicator logic
|
|
@@ -2982,17 +2988,16 @@ export const createAgentExperience = (
|
|
|
2982
2988
|
iconSize: parseFloat(voiceConfig.iconSize ?? config.sendButton?.size ?? "40") || 24,
|
|
2983
2989
|
};
|
|
2984
2990
|
|
|
2985
|
-
// Apply recording state styles from config
|
|
2986
|
-
const recordingBackgroundColor = voiceConfig.recordingBackgroundColor
|
|
2991
|
+
// Apply recording state styles from config or theme tokens
|
|
2992
|
+
const recordingBackgroundColor = voiceConfig.recordingBackgroundColor;
|
|
2987
2993
|
const recordingIconColor = voiceConfig.recordingIconColor;
|
|
2988
2994
|
const recordingBorderColor = voiceConfig.recordingBorderColor;
|
|
2989
|
-
|
|
2995
|
+
|
|
2990
2996
|
micButton.classList.add("persona-voice-recording");
|
|
2991
|
-
micButton.style.backgroundColor = recordingBackgroundColor;
|
|
2992
|
-
|
|
2997
|
+
micButton.style.backgroundColor = recordingBackgroundColor ?? "var(--persona-voice-recording-bg, #ef4444)";
|
|
2998
|
+
micButton.style.color = recordingIconColor ?? "var(--persona-voice-recording-indicator, #ffffff)";
|
|
2999
|
+
|
|
2993
3000
|
if (recordingIconColor) {
|
|
2994
|
-
micButton.style.color = recordingIconColor;
|
|
2995
|
-
// Update SVG stroke color if present
|
|
2996
3001
|
const svg = micButton.querySelector("svg");
|
|
2997
3002
|
if (svg) {
|
|
2998
3003
|
svg.setAttribute("stroke", recordingIconColor);
|
|
@@ -3092,30 +3097,27 @@ export const createAgentExperience = (
|
|
|
3092
3097
|
micButton.style.fontSize = "18px";
|
|
3093
3098
|
micButton.style.lineHeight = "1";
|
|
3094
3099
|
|
|
3095
|
-
//
|
|
3100
|
+
// Set mic button foreground from config or theme token
|
|
3101
|
+
if (iconColor) {
|
|
3102
|
+
micButton.style.color = iconColor;
|
|
3103
|
+
} else {
|
|
3104
|
+
micButton.style.color = "var(--persona-text, #111827)";
|
|
3105
|
+
}
|
|
3106
|
+
|
|
3107
|
+
// Use Lucide mic icon (stroke width 1.5 for minimalist outline style)
|
|
3096
3108
|
const iconColorValue = iconColor || "currentColor";
|
|
3097
3109
|
const micIconSvg = renderLucideIcon(micIconName, micIconSizeNum, iconColorValue, 1.5);
|
|
3098
3110
|
if (micIconSvg) {
|
|
3099
3111
|
micButton.appendChild(micIconSvg);
|
|
3100
|
-
micButton.style.color = iconColorValue;
|
|
3101
3112
|
} else {
|
|
3102
|
-
// Fallback to text if icon fails
|
|
3103
3113
|
micButton.textContent = "🎤";
|
|
3104
|
-
micButton.style.color = iconColorValue;
|
|
3105
3114
|
}
|
|
3106
|
-
|
|
3115
|
+
|
|
3107
3116
|
// Apply background color
|
|
3108
3117
|
if (backgroundColor) {
|
|
3109
3118
|
micButton.style.backgroundColor = backgroundColor;
|
|
3110
3119
|
} else {
|
|
3111
|
-
micButton.
|
|
3112
|
-
}
|
|
3113
|
-
|
|
3114
|
-
// Apply icon/text color
|
|
3115
|
-
if (iconColor) {
|
|
3116
|
-
micButton.style.color = iconColor;
|
|
3117
|
-
} else if (!iconColor && !sendButtonConfig?.textColor) {
|
|
3118
|
-
micButton.classList.add("persona-text-white");
|
|
3120
|
+
micButton.style.backgroundColor = "";
|
|
3119
3121
|
}
|
|
3120
3122
|
|
|
3121
3123
|
// Apply border styling
|
|
@@ -3187,14 +3189,14 @@ export const createAgentExperience = (
|
|
|
3187
3189
|
if (!micButton) return;
|
|
3188
3190
|
storeOriginalMicStyles();
|
|
3189
3191
|
const voiceConfig = config.voiceRecognition ?? {};
|
|
3190
|
-
const recordingBackgroundColor = voiceConfig.recordingBackgroundColor
|
|
3192
|
+
const recordingBackgroundColor = voiceConfig.recordingBackgroundColor;
|
|
3191
3193
|
const recordingIconColor = voiceConfig.recordingIconColor;
|
|
3192
3194
|
const recordingBorderColor = voiceConfig.recordingBorderColor;
|
|
3193
3195
|
removeAllVoiceStateClasses();
|
|
3194
3196
|
micButton.classList.add("persona-voice-recording");
|
|
3195
|
-
micButton.style.backgroundColor = recordingBackgroundColor;
|
|
3197
|
+
micButton.style.backgroundColor = recordingBackgroundColor ?? "var(--persona-voice-recording-bg, #ef4444)";
|
|
3198
|
+
micButton.style.color = recordingIconColor ?? "var(--persona-voice-recording-indicator, #ffffff)";
|
|
3196
3199
|
if (recordingIconColor) {
|
|
3197
|
-
micButton.style.color = recordingIconColor;
|
|
3198
3200
|
const svg = micButton.querySelector("svg");
|
|
3199
3201
|
if (svg) svg.setAttribute("stroke", recordingIconColor);
|
|
3200
3202
|
}
|
|
@@ -3240,7 +3242,7 @@ export const createAgentExperience = (
|
|
|
3240
3242
|
const iconColor = voiceConfig.speakingIconColor
|
|
3241
3243
|
?? (interruptionMode === "barge-in" ? (voiceConfig.recordingIconColor ?? originalMicStyles?.color ?? "") : (originalMicStyles?.color ?? ""));
|
|
3242
3244
|
const bgColor = voiceConfig.speakingBackgroundColor
|
|
3243
|
-
?? (interruptionMode === "barge-in" ? (voiceConfig.recordingBackgroundColor ?? "#ef4444") : (originalMicStyles?.backgroundColor ?? ""));
|
|
3245
|
+
?? (interruptionMode === "barge-in" ? (voiceConfig.recordingBackgroundColor ?? "var(--persona-voice-recording-bg, #ef4444)") : (originalMicStyles?.backgroundColor ?? ""));
|
|
3244
3246
|
const borderColor = voiceConfig.speakingBorderColor
|
|
3245
3247
|
?? (interruptionMode === "barge-in" ? (voiceConfig.recordingBorderColor ?? "") : (originalMicStyles?.borderColor ?? ""));
|
|
3246
3248
|
|
|
@@ -3718,10 +3720,11 @@ export const createAgentExperience = (
|
|
|
3718
3720
|
// Add header toggle button if not present
|
|
3719
3721
|
if (!eventStreamToggleBtn && header) {
|
|
3720
3722
|
const dynEsClassNames = config.features?.eventStream?.classNames;
|
|
3721
|
-
const dynToggleBtnClasses = "persona-inline-flex persona-items-center persona-justify-center persona-rounded-full
|
|
3723
|
+
const dynToggleBtnClasses = "persona-inline-flex persona-items-center persona-justify-center persona-rounded-full hover:persona-opacity-80 persona-cursor-pointer persona-border-none persona-bg-transparent persona-p-1" + (dynEsClassNames?.toggleButton ? " " + dynEsClassNames.toggleButton : "");
|
|
3722
3724
|
eventStreamToggleBtn = createElement("button", dynToggleBtnClasses) as HTMLButtonElement;
|
|
3723
3725
|
eventStreamToggleBtn.style.width = "28px";
|
|
3724
3726
|
eventStreamToggleBtn.style.height = "28px";
|
|
3727
|
+
eventStreamToggleBtn.style.color = HEADER_THEME_CSS.actionIconColor;
|
|
3725
3728
|
eventStreamToggleBtn.type = "button";
|
|
3726
3729
|
eventStreamToggleBtn.setAttribute("aria-label", "Event Stream");
|
|
3727
3730
|
eventStreamToggleBtn.title = "Event Stream";
|
|
@@ -4488,22 +4491,18 @@ export const createAgentExperience = (
|
|
|
4488
4491
|
micButton.textContent = "🎤";
|
|
4489
4492
|
}
|
|
4490
4493
|
|
|
4491
|
-
// Update colors
|
|
4494
|
+
// Update colors from config or theme tokens
|
|
4492
4495
|
const backgroundColor = voiceConfig.backgroundColor ?? sendButtonConfig.backgroundColor;
|
|
4493
4496
|
if (backgroundColor) {
|
|
4494
4497
|
micButton.style.backgroundColor = backgroundColor;
|
|
4495
|
-
micButton.classList.remove("persona-bg-persona-primary");
|
|
4496
4498
|
} else {
|
|
4497
4499
|
micButton.style.backgroundColor = "";
|
|
4498
|
-
micButton.classList.add("persona-bg-persona-primary");
|
|
4499
4500
|
}
|
|
4500
|
-
|
|
4501
|
+
|
|
4501
4502
|
if (iconColor) {
|
|
4502
4503
|
micButton.style.color = iconColor;
|
|
4503
|
-
|
|
4504
|
-
|
|
4505
|
-
micButton.style.color = "";
|
|
4506
|
-
micButton.classList.add("persona-text-white");
|
|
4504
|
+
} else {
|
|
4505
|
+
micButton.style.color = "var(--persona-text, #111827)";
|
|
4507
4506
|
}
|
|
4508
4507
|
|
|
4509
4508
|
// Update border styling
|
|
@@ -4729,30 +4728,25 @@ export const createAgentExperience = (
|
|
|
4729
4728
|
// Clear existing content
|
|
4730
4729
|
sendButton.innerHTML = "";
|
|
4731
4730
|
|
|
4731
|
+
// Set foreground color from config or theme token
|
|
4732
|
+
if (textColor) {
|
|
4733
|
+
sendButton.style.color = textColor;
|
|
4734
|
+
} else {
|
|
4735
|
+
sendButton.style.color = "var(--persona-button-primary-fg, #ffffff)";
|
|
4736
|
+
}
|
|
4737
|
+
|
|
4732
4738
|
// Use Lucide icon if iconName is provided, otherwise fall back to iconText
|
|
4733
4739
|
if (iconName) {
|
|
4734
4740
|
const iconSize = parseFloat(buttonSize) || 24;
|
|
4735
|
-
const iconColor = textColor
|
|
4741
|
+
const iconColor = textColor?.trim() || "currentColor";
|
|
4736
4742
|
const iconSvg = renderLucideIcon(iconName, iconSize, iconColor, 2);
|
|
4737
4743
|
if (iconSvg) {
|
|
4738
4744
|
sendButton.appendChild(iconSvg);
|
|
4739
|
-
sendButton.style.color = iconColor;
|
|
4740
4745
|
} else {
|
|
4741
|
-
// Fallback to text if icon fails to render
|
|
4742
4746
|
sendButton.textContent = iconText;
|
|
4743
|
-
if (textColor) {
|
|
4744
|
-
sendButton.style.color = textColor;
|
|
4745
|
-
} else {
|
|
4746
|
-
sendButton.classList.add("persona-text-white");
|
|
4747
|
-
}
|
|
4748
4747
|
}
|
|
4749
4748
|
} else {
|
|
4750
4749
|
sendButton.textContent = iconText;
|
|
4751
|
-
if (textColor) {
|
|
4752
|
-
sendButton.style.color = textColor;
|
|
4753
|
-
} else {
|
|
4754
|
-
sendButton.classList.add("persona-text-white");
|
|
4755
|
-
}
|
|
4756
4750
|
}
|
|
4757
4751
|
|
|
4758
4752
|
// Update classes
|
|
@@ -4762,6 +4756,7 @@ export const createAgentExperience = (
|
|
|
4762
4756
|
sendButton.style.backgroundColor = backgroundColor;
|
|
4763
4757
|
sendButton.classList.remove("persona-bg-persona-primary");
|
|
4764
4758
|
} else {
|
|
4759
|
+
sendButton.style.backgroundColor = "";
|
|
4765
4760
|
sendButton.classList.add("persona-bg-persona-primary");
|
|
4766
4761
|
}
|
|
4767
4762
|
} else {
|
package/src/utils/plugins.ts
CHANGED
|
@@ -22,7 +22,7 @@ export function accessibilityPlugin(): PersonaThemePlugin {
|
|
|
22
22
|
},
|
|
23
23
|
cssVariables: {
|
|
24
24
|
'--persona-accessibility-focus-ring':
|
|
25
|
-
'0 0 0 2px var(--persona-semantic-colors-surface, #fff), 0 0 0 4px var(--persona-semantic-colors-interactive-focus, #
|
|
25
|
+
'0 0 0 2px var(--persona-semantic-colors-surface, #fff), 0 0 0 4px var(--persona-semantic-colors-interactive-focus, #0f0f0f)',
|
|
26
26
|
},
|
|
27
27
|
};
|
|
28
28
|
}
|
package/src/utils/theme.test.ts
CHANGED
|
@@ -139,15 +139,16 @@ describe('theme utils', () => {
|
|
|
139
139
|
expect(cssVars['--persona-md-prose-font-family']).toBe('Georgia, serif');
|
|
140
140
|
});
|
|
141
141
|
|
|
142
|
-
it('maps header chrome tokens to dedicated CSS variables with
|
|
142
|
+
it('maps header chrome tokens to dedicated CSS variables with palette refs', () => {
|
|
143
143
|
const theme = createTheme();
|
|
144
144
|
const cssVars = themeToCssVariables(theme);
|
|
145
145
|
|
|
146
|
-
|
|
147
|
-
expect(cssVars['--persona-header-icon-
|
|
148
|
-
expect(cssVars['--persona-header-
|
|
149
|
-
expect(cssVars['--persona-header-
|
|
150
|
-
expect(cssVars['--persona-header-
|
|
146
|
+
// Default header uses solid primary role: icon-bg=primary.600, icon-fg=primary.50, etc.
|
|
147
|
+
expect(cssVars['--persona-header-icon-bg']).toBe('#0f0f0f'); // primary.600
|
|
148
|
+
expect(cssVars['--persona-header-icon-fg']).toBe('#ffffff'); // primary.50
|
|
149
|
+
expect(cssVars['--persona-header-title-fg']).toBe('#ffffff'); // primary.50
|
|
150
|
+
expect(cssVars['--persona-header-subtitle-fg']).toBe('#d4d4d4'); // primary.200
|
|
151
|
+
expect(cssVars['--persona-header-action-icon-fg']).toBe('#d4d4d4'); // primary.200
|
|
151
152
|
|
|
152
153
|
const custom = createTheme({
|
|
153
154
|
components: {
|
|
@@ -172,8 +173,9 @@ describe('theme utils', () => {
|
|
|
172
173
|
const theme = createTheme();
|
|
173
174
|
const cssVars = themeToCssVariables(theme);
|
|
174
175
|
|
|
175
|
-
|
|
176
|
-
expect(cssVars['--persona-artifact-
|
|
176
|
+
// container defaults to gray.50 now (soft gray surfaces role)
|
|
177
|
+
expect(cssVars['--persona-components-artifact-pane-background']).toBe('#f9fafb');
|
|
178
|
+
expect(cssVars['--persona-artifact-toolbar-bg']).toBe('#f9fafb');
|
|
177
179
|
|
|
178
180
|
const surfacePane = createTheme({
|
|
179
181
|
components: {
|
package/src/utils/theme.ts
CHANGED
|
@@ -16,17 +16,17 @@ type WidgetConfig = PersonaWidgetConfig | AgentWidgetConfig;
|
|
|
16
16
|
const DARK_PALETTE = {
|
|
17
17
|
colors: {
|
|
18
18
|
primary: {
|
|
19
|
-
50: '#
|
|
20
|
-
100: '#
|
|
21
|
-
200: '#
|
|
22
|
-
300: '#
|
|
23
|
-
400: '#
|
|
24
|
-
500: '#
|
|
25
|
-
600: '#
|
|
26
|
-
700: '#
|
|
27
|
-
800: '#
|
|
28
|
-
900: '#
|
|
29
|
-
950: '#
|
|
19
|
+
50: '#ffffff',
|
|
20
|
+
100: '#f5f5f5',
|
|
21
|
+
200: '#d4d4d4',
|
|
22
|
+
300: '#a3a3a3',
|
|
23
|
+
400: '#737373',
|
|
24
|
+
500: '#171717',
|
|
25
|
+
600: '#0f0f0f',
|
|
26
|
+
700: '#0a0a0a',
|
|
27
|
+
800: '#050505',
|
|
28
|
+
900: '#030303',
|
|
29
|
+
950: '#000000',
|
|
30
30
|
},
|
|
31
31
|
secondary: {
|
|
32
32
|
50: '#f5f3ff',
|
package/src/utils/tokens.ts
CHANGED
|
@@ -12,17 +12,17 @@ import type {
|
|
|
12
12
|
export const DEFAULT_PALETTE = {
|
|
13
13
|
colors: {
|
|
14
14
|
primary: {
|
|
15
|
-
50: '#
|
|
16
|
-
100: '#
|
|
17
|
-
200: '#
|
|
18
|
-
300: '#
|
|
19
|
-
400: '#
|
|
20
|
-
500: '#
|
|
21
|
-
600: '#
|
|
22
|
-
700: '#
|
|
23
|
-
800: '#
|
|
24
|
-
900: '#
|
|
25
|
-
950: '#
|
|
15
|
+
50: '#ffffff',
|
|
16
|
+
100: '#f5f5f5',
|
|
17
|
+
200: '#d4d4d4',
|
|
18
|
+
300: '#a3a3a3',
|
|
19
|
+
400: '#737373',
|
|
20
|
+
500: '#171717',
|
|
21
|
+
600: '#0f0f0f',
|
|
22
|
+
700: '#0a0a0a',
|
|
23
|
+
800: '#050505',
|
|
24
|
+
900: '#030303',
|
|
25
|
+
950: '#000000',
|
|
26
26
|
},
|
|
27
27
|
secondary: {
|
|
28
28
|
50: '#f5f3ff',
|
|
@@ -99,6 +99,19 @@ export const DEFAULT_PALETTE = {
|
|
|
99
99
|
800: '#991b1b',
|
|
100
100
|
900: '#7f1d1d',
|
|
101
101
|
},
|
|
102
|
+
info: {
|
|
103
|
+
50: '#eff6ff',
|
|
104
|
+
100: '#dbeafe',
|
|
105
|
+
200: '#bfdbfe',
|
|
106
|
+
300: '#93c5fd',
|
|
107
|
+
400: '#60a5fa',
|
|
108
|
+
500: '#3b82f6',
|
|
109
|
+
600: '#2563eb',
|
|
110
|
+
700: '#1d4ed8',
|
|
111
|
+
800: '#1e40af',
|
|
112
|
+
900: '#1e3a8a',
|
|
113
|
+
950: '#172554',
|
|
114
|
+
},
|
|
102
115
|
},
|
|
103
116
|
spacing: {
|
|
104
117
|
0: '0px',
|
|
@@ -176,28 +189,33 @@ export const DEFAULT_PALETTE = {
|
|
|
176
189
|
export const DEFAULT_SEMANTIC: SemanticTokens = {
|
|
177
190
|
colors: {
|
|
178
191
|
primary: 'palette.colors.primary.500',
|
|
179
|
-
secondary: 'palette.colors.
|
|
192
|
+
secondary: 'palette.colors.secondary.500',
|
|
193
|
+
// Links/Focus role — solid primary
|
|
180
194
|
accent: 'palette.colors.primary.600',
|
|
195
|
+
// Surfaces role — soft gray
|
|
181
196
|
surface: 'palette.colors.gray.50',
|
|
182
197
|
background: 'palette.colors.gray.50',
|
|
183
|
-
container: 'palette.colors.gray.
|
|
198
|
+
container: 'palette.colors.gray.50',
|
|
184
199
|
text: 'palette.colors.gray.900',
|
|
185
200
|
textMuted: 'palette.colors.gray.500',
|
|
186
201
|
textInverse: 'palette.colors.gray.50',
|
|
202
|
+
// Borders role — soft gray
|
|
187
203
|
border: 'palette.colors.gray.200',
|
|
188
204
|
divider: 'palette.colors.gray.200',
|
|
189
205
|
interactive: {
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
206
|
+
// Primary Actions role — solid primary
|
|
207
|
+
default: 'palette.colors.primary.600',
|
|
208
|
+
hover: 'palette.colors.primary.700',
|
|
209
|
+
// Links/Focus role — solid primary
|
|
210
|
+
focus: 'palette.colors.primary.600',
|
|
211
|
+
active: 'palette.colors.primary.600',
|
|
194
212
|
disabled: 'palette.colors.gray.300',
|
|
195
213
|
},
|
|
196
214
|
feedback: {
|
|
197
215
|
success: 'palette.colors.success.500',
|
|
198
216
|
warning: 'palette.colors.warning.500',
|
|
199
217
|
error: 'palette.colors.error.500',
|
|
200
|
-
info: 'palette.colors.
|
|
218
|
+
info: 'palette.colors.info.500',
|
|
201
219
|
},
|
|
202
220
|
},
|
|
203
221
|
spacing: {
|
|
@@ -219,14 +237,15 @@ export const DEFAULT_SEMANTIC: SemanticTokens = {
|
|
|
219
237
|
export const DEFAULT_COMPONENTS: ComponentTokens = {
|
|
220
238
|
button: {
|
|
221
239
|
primary: {
|
|
222
|
-
|
|
223
|
-
|
|
240
|
+
// Primary Actions role — solid primary
|
|
241
|
+
background: 'palette.colors.primary.500',
|
|
242
|
+
foreground: 'palette.colors.primary.50',
|
|
224
243
|
borderRadius: 'palette.radius.lg',
|
|
225
244
|
padding: 'semantic.spacing.md',
|
|
226
245
|
},
|
|
227
246
|
secondary: {
|
|
228
247
|
background: 'semantic.colors.surface',
|
|
229
|
-
foreground: 'semantic.colors.
|
|
248
|
+
foreground: 'semantic.colors.secondary',
|
|
230
249
|
borderRadius: 'palette.radius.lg',
|
|
231
250
|
padding: 'semantic.spacing.md',
|
|
232
251
|
},
|
|
@@ -238,16 +257,20 @@ export const DEFAULT_COMPONENTS: ComponentTokens = {
|
|
|
238
257
|
},
|
|
239
258
|
},
|
|
240
259
|
input: {
|
|
241
|
-
|
|
242
|
-
|
|
260
|
+
// Input role — soft gray
|
|
261
|
+
background: 'palette.colors.gray.50',
|
|
262
|
+
placeholder: 'palette.colors.gray.400',
|
|
243
263
|
borderRadius: 'palette.radius.lg',
|
|
244
264
|
padding: 'semantic.spacing.md',
|
|
245
265
|
focus: {
|
|
246
|
-
border: '
|
|
247
|
-
ring: '
|
|
266
|
+
border: 'palette.colors.gray.400',
|
|
267
|
+
ring: 'palette.colors.gray.400',
|
|
248
268
|
},
|
|
249
269
|
},
|
|
250
270
|
launcher: {
|
|
271
|
+
background: 'palette.colors.primary.500',
|
|
272
|
+
foreground: 'palette.colors.primary.50',
|
|
273
|
+
border: 'palette.colors.gray.200',
|
|
251
274
|
size: '60px',
|
|
252
275
|
iconSize: '28px',
|
|
253
276
|
borderRadius: 'palette.radius.full',
|
|
@@ -262,28 +285,31 @@ export const DEFAULT_COMPONENTS: ComponentTokens = {
|
|
|
262
285
|
shadow: 'palette.shadows.xl',
|
|
263
286
|
},
|
|
264
287
|
header: {
|
|
265
|
-
|
|
266
|
-
|
|
288
|
+
// Header role — solid primary
|
|
289
|
+
background: 'palette.colors.primary.500',
|
|
290
|
+
border: 'palette.colors.primary.600',
|
|
267
291
|
borderRadius: 'palette.radius.xl palette.radius.xl 0 0',
|
|
268
292
|
padding: 'semantic.spacing.md',
|
|
269
|
-
iconBackground: '
|
|
270
|
-
iconForeground: '
|
|
271
|
-
titleForeground: '
|
|
272
|
-
subtitleForeground: '
|
|
273
|
-
actionIconForeground: '
|
|
293
|
+
iconBackground: 'palette.colors.primary.600',
|
|
294
|
+
iconForeground: 'palette.colors.primary.50',
|
|
295
|
+
titleForeground: 'palette.colors.primary.50',
|
|
296
|
+
subtitleForeground: 'palette.colors.primary.200',
|
|
297
|
+
actionIconForeground: 'palette.colors.primary.200',
|
|
274
298
|
},
|
|
275
299
|
message: {
|
|
276
300
|
user: {
|
|
277
|
-
|
|
278
|
-
|
|
301
|
+
// User Messages role — solid primary
|
|
302
|
+
background: 'palette.colors.primary.500',
|
|
303
|
+
text: 'palette.colors.primary.50',
|
|
279
304
|
borderRadius: 'palette.radius.lg',
|
|
280
305
|
shadow: 'palette.shadows.sm',
|
|
281
306
|
},
|
|
282
307
|
assistant: {
|
|
283
|
-
|
|
284
|
-
|
|
308
|
+
// Assistant Messages role — soft gray
|
|
309
|
+
background: 'palette.colors.gray.50',
|
|
310
|
+
text: 'palette.colors.gray.900',
|
|
285
311
|
borderRadius: 'palette.radius.lg',
|
|
286
|
-
border: '
|
|
312
|
+
border: 'palette.colors.gray.200',
|
|
287
313
|
shadow: 'palette.shadows.sm',
|
|
288
314
|
},
|
|
289
315
|
},
|
|
@@ -298,11 +324,12 @@ export const DEFAULT_COMPONENTS: ComponentTokens = {
|
|
|
298
324
|
},
|
|
299
325
|
markdown: {
|
|
300
326
|
inlineCode: {
|
|
301
|
-
background: '
|
|
302
|
-
foreground: '
|
|
327
|
+
background: 'palette.colors.gray.50',
|
|
328
|
+
foreground: 'palette.colors.gray.900',
|
|
303
329
|
},
|
|
304
330
|
link: {
|
|
305
|
-
|
|
331
|
+
// Links/Focus role — solid primary
|
|
332
|
+
foreground: 'palette.colors.primary.600',
|
|
306
333
|
},
|
|
307
334
|
prose: {
|
|
308
335
|
fontFamily: 'inherit',
|
|
@@ -633,6 +660,21 @@ export function themeToCssVariables(theme: PersonaTheme): Record<string, string>
|
|
|
633
660
|
cssVars['--persona-components-launcher-borderRadius'] ??
|
|
634
661
|
cssVars['--persona-palette-radius-full'] ??
|
|
635
662
|
'9999px';
|
|
663
|
+
cssVars['--persona-launcher-bg'] =
|
|
664
|
+
cssVars['--persona-components-launcher-background'] ??
|
|
665
|
+
cssVars['--persona-primary'];
|
|
666
|
+
cssVars['--persona-launcher-fg'] =
|
|
667
|
+
cssVars['--persona-components-launcher-foreground'] ??
|
|
668
|
+
cssVars['--persona-text-inverse'];
|
|
669
|
+
cssVars['--persona-launcher-border'] =
|
|
670
|
+
cssVars['--persona-components-launcher-border'] ??
|
|
671
|
+
cssVars['--persona-border'];
|
|
672
|
+
cssVars['--persona-button-primary-bg'] =
|
|
673
|
+
cssVars['--persona-components-button-primary-background'] ??
|
|
674
|
+
cssVars['--persona-primary'];
|
|
675
|
+
cssVars['--persona-button-primary-fg'] =
|
|
676
|
+
cssVars['--persona-components-button-primary-foreground'] ??
|
|
677
|
+
cssVars['--persona-text-inverse'];
|
|
636
678
|
cssVars['--persona-button-radius'] =
|
|
637
679
|
cssVars['--persona-components-button-primary-borderRadius'] ??
|
|
638
680
|
cssVars['--persona-palette-radius-full'] ??
|
|
@@ -681,6 +723,11 @@ export function themeToCssVariables(theme: PersonaTheme): Record<string, string>
|
|
|
681
723
|
if (headerTokens?.shadow) cssVars['--persona-header-shadow'] = headerTokens.shadow;
|
|
682
724
|
if (headerTokens?.borderBottom) cssVars['--persona-header-border-bottom'] = headerTokens.borderBottom;
|
|
683
725
|
|
|
726
|
+
cssVars['--persona-input-background'] =
|
|
727
|
+
cssVars['--persona-components-input-background'] ?? cssVars['--persona-surface'];
|
|
728
|
+
cssVars['--persona-input-placeholder'] =
|
|
729
|
+
cssVars['--persona-components-input-placeholder'] ?? cssVars['--persona-text-muted'];
|
|
730
|
+
|
|
684
731
|
cssVars['--persona-message-user-bg'] =
|
|
685
732
|
cssVars['--persona-components-message-user-background'] ?? cssVars['--persona-accent'];
|
|
686
733
|
cssVars['--persona-message-user-text'] =
|
|
@@ -711,7 +758,7 @@ export function themeToCssVariables(theme: PersonaTheme): Record<string, string>
|
|
|
711
758
|
cssVars['--persona-md-link-color'] =
|
|
712
759
|
cssVars['--persona-components-markdown-link-foreground'] ??
|
|
713
760
|
cssVars['--persona-accent'] ??
|
|
714
|
-
'#
|
|
761
|
+
'#0f0f0f';
|
|
715
762
|
|
|
716
763
|
const mdH1Size = cssVars['--persona-components-markdown-heading-h1-fontSize'];
|
|
717
764
|
if (mdH1Size) cssVars['--persona-md-h1-size'] = mdH1Size;
|
package/widget.css
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
@import "./src/widget.css";
|