@runtypelabs/persona 4.14.0 → 4.16.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 +4 -4
- package/dist/animations/glyph-cycle.d.cts +1 -1
- package/dist/animations/glyph-cycle.d.ts +1 -1
- package/dist/animations/{types-DveIaNx6.d.cts → types-BpWGm7_6.d.cts} +17 -0
- package/dist/animations/{types-DveIaNx6.d.ts → types-BpWGm7_6.d.ts} +17 -0
- package/dist/animations/wipe.d.cts +1 -1
- package/dist/animations/wipe.d.ts +1 -1
- package/dist/chunk-QJ4LV2KW.js +1 -0
- package/dist/codegen.cjs +12 -11
- package/dist/codegen.js +14 -13
- package/dist/{context-mentions-ONG7A7M6.js → context-mentions-BTSTIBFC.js} +1 -1
- package/dist/context-mentions.cjs +11 -8
- package/dist/context-mentions.d.cts +520 -21
- package/dist/context-mentions.d.ts +520 -21
- package/dist/context-mentions.js +11 -8
- package/dist/index.cjs +69 -68
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +595 -46
- package/dist/index.d.ts +595 -46
- package/dist/index.global.js +60 -57
- package/dist/index.global.js.map +1 -1
- package/dist/index.js +69 -68
- package/dist/index.js.map +1 -1
- package/dist/launcher.global.js +5 -2
- package/dist/launcher.global.js.map +1 -1
- package/dist/smart-dom-reader.d.cts +520 -21
- package/dist/smart-dom-reader.d.ts +520 -21
- package/dist/testing.cjs +3 -3
- package/dist/testing.d.cts +7 -0
- package/dist/testing.d.ts +7 -0
- package/dist/testing.js +3 -3
- package/dist/theme-editor-preview.cjs +67 -67
- package/dist/theme-editor-preview.d.cts +534 -22
- package/dist/theme-editor-preview.d.ts +534 -22
- package/dist/theme-editor-preview.js +57 -57
- package/dist/theme-editor.cjs +10 -10
- package/dist/theme-editor.d.cts +521 -23
- package/dist/theme-editor.d.ts +521 -23
- package/dist/theme-editor.js +10 -10
- package/dist/theme-reference.cjs +1 -1
- package/dist/theme-reference.d.cts +104 -3
- package/dist/theme-reference.d.ts +104 -3
- package/dist/theme-reference.js +1 -1
- package/dist/widget.css +1 -1
- package/package.json +1 -1
- package/src/ask-user-question-tool.ts +10 -7
- package/src/components/artifact-pane.test.ts +27 -0
- package/src/components/artifact-pane.ts +7 -3
- package/src/components/artifact-preview.ts +1 -1
- package/src/components/composer-parts.test.ts +103 -4
- package/src/components/composer-parts.ts +53 -15
- package/src/components/header-builder.ts +27 -2
- package/src/components/header-layouts.test.ts +56 -0
- package/src/components/header-layouts.ts +29 -9
- package/src/components/launcher-surface.test.ts +403 -0
- package/src/components/launcher.ts +297 -2
- package/src/components/messages.ts +5 -2
- package/src/components/panel.ts +92 -71
- package/src/components/pill-composer-builder.test.ts +18 -0
- package/src/components/suggestions.test.ts +273 -0
- package/src/components/suggestions.ts +528 -86
- package/src/components/welcome.test.ts +121 -0
- package/src/components/welcome.ts +305 -0
- package/src/components/widget-view.test.ts +5 -3
- package/src/components/widget-view.ts +18 -7
- package/src/defaults.ts +7 -5
- package/src/generated/runtype-openapi-contract.ts +17 -0
- package/src/index-core.ts +29 -2
- package/src/launcher-global.ts +11 -8
- package/src/plugins/types.ts +136 -3
- package/src/presets.ts +3 -3
- package/src/session.ts +10 -8
- package/src/styles/widget-styles.test.ts +382 -0
- package/src/styles/widget.css +778 -4
- package/src/suggest-replies-tool.test.ts +233 -2
- package/src/suggest-replies-tool.ts +115 -39
- package/src/testing/mock-stream.test.ts +19 -0
- package/src/testing/mock-stream.ts +20 -0
- package/src/theme-editor/preview-utils.test.ts +34 -0
- package/src/theme-editor/preview-utils.ts +77 -2
- package/src/theme-editor/sections.test.ts +33 -0
- package/src/theme-editor/sections.ts +83 -6
- package/src/theme-reference.ts +34 -5
- package/src/types/theme.ts +72 -3
- package/src/types.ts +312 -18
- package/src/ui.body-top-slot.test.ts +95 -0
- package/src/ui.content-width.test.ts +91 -0
- package/src/ui.detached-panel.test.ts +1 -1
- package/src/ui.docked.test.ts +7 -4
- package/src/ui.launcher-teaser.test.ts +162 -0
- package/src/ui.rebuild-composer.test.ts +491 -0
- package/src/ui.render-welcome.test.ts +505 -0
- package/src/ui.scroll-additive.test.ts +91 -21
- package/src/ui.scroll.test.ts +302 -14
- package/src/ui.suggest-replies.test.ts +1112 -1
- package/src/ui.ts +1008 -149
- package/src/ui.welcome.test.ts +504 -0
- package/src/utils/artifact-file.test.ts +1 -1
- package/src/utils/artifact-gate.test.ts +27 -0
- package/src/utils/artifact-gate.ts +9 -0
- package/src/utils/attachment-manager.test.ts +37 -0
- package/src/utils/attachment-manager.ts +15 -0
- package/src/utils/auto-follow.test.ts +23 -0
- package/src/utils/auto-follow.ts +11 -1
- package/src/utils/code-generators.test.ts +40 -0
- package/src/utils/code-generators.ts +22 -0
- package/src/utils/config-merge.test.ts +24 -0
- package/src/utils/config-merge.ts +2 -0
- package/src/utils/content-width.test.ts +37 -0
- package/src/utils/content-width.ts +17 -0
- package/src/utils/icons.test.ts +26 -0
- package/src/utils/icons.ts +8 -0
- package/src/utils/plugin-storage.test.ts +94 -0
- package/src/utils/plugin-storage.ts +98 -0
- package/src/utils/theme.test.ts +216 -0
- package/src/utils/tokens.ts +113 -3
- package/src/welcome.test.ts +213 -0
- package/src/welcome.ts +130 -0
- package/dist/chunk-MMUPR2JW.js +0 -1
|
@@ -195,7 +195,12 @@ export function buildSrcdoc(
|
|
|
195
195
|
|
|
196
196
|
// ─── Preview Messages ───────────────────────────────────────────
|
|
197
197
|
|
|
198
|
-
export type PreviewScene =
|
|
198
|
+
export type PreviewScene =
|
|
199
|
+
| 'home'
|
|
200
|
+
| 'conversation'
|
|
201
|
+
| 'follow-ups'
|
|
202
|
+
| 'minimized'
|
|
203
|
+
| 'artifact';
|
|
199
204
|
|
|
200
205
|
export type PreviewTranscriptEntryPreset =
|
|
201
206
|
| 'user-message'
|
|
@@ -543,8 +548,78 @@ export function createPreviewMessages(
|
|
|
543
548
|
config?: Partial<AgentWidgetConfig>,
|
|
544
549
|
appendedMessages: AgentWidgetMessage[] = []
|
|
545
550
|
): AgentWidgetMessage[] {
|
|
551
|
+
if (scene === 'follow-ups') {
|
|
552
|
+
const now = Date.now();
|
|
553
|
+
return [
|
|
554
|
+
{
|
|
555
|
+
id: 'preview-follow-up-user',
|
|
556
|
+
role: 'user',
|
|
557
|
+
content: 'What can Persona help me build?',
|
|
558
|
+
createdAt: new Date(now - 120000).toISOString(),
|
|
559
|
+
},
|
|
560
|
+
{
|
|
561
|
+
id: 'preview-follow-up-assistant',
|
|
562
|
+
role: 'assistant',
|
|
563
|
+
content:
|
|
564
|
+
'Persona gives you a themeable streaming chat interface with flexible integrations and interaction patterns. Where would you like to go next?',
|
|
565
|
+
createdAt: new Date(now - 60000).toISOString(),
|
|
566
|
+
},
|
|
567
|
+
{
|
|
568
|
+
id: 'preview-follow-up-suggestions',
|
|
569
|
+
role: 'assistant',
|
|
570
|
+
content: '',
|
|
571
|
+
createdAt: new Date(now - 59000).toISOString(),
|
|
572
|
+
streaming: false,
|
|
573
|
+
variant: 'tool',
|
|
574
|
+
toolCall: {
|
|
575
|
+
id: 'preview-follow-up-suggestions',
|
|
576
|
+
name: 'suggest_replies',
|
|
577
|
+
status: 'complete',
|
|
578
|
+
args: {
|
|
579
|
+
suggestions: [
|
|
580
|
+
{
|
|
581
|
+
id: 'preview-implementation',
|
|
582
|
+
label: 'Show me an implementation',
|
|
583
|
+
prompt: 'Show me a practical implementation',
|
|
584
|
+
description: 'See a complete integration example',
|
|
585
|
+
icon: 'code-2',
|
|
586
|
+
emphasis: 'primary',
|
|
587
|
+
},
|
|
588
|
+
{
|
|
589
|
+
id: 'preview-theming',
|
|
590
|
+
label: 'Explore theming',
|
|
591
|
+
prompt: 'Tell me how theming works',
|
|
592
|
+
description: 'Customize colors, type, and component styles',
|
|
593
|
+
icon: 'palette',
|
|
594
|
+
},
|
|
595
|
+
{
|
|
596
|
+
id: 'preview-security',
|
|
597
|
+
label: 'Review security',
|
|
598
|
+
prompt: 'Explain the security model',
|
|
599
|
+
description: 'Learn about isolation and safe rendering',
|
|
600
|
+
icon: 'shield-check',
|
|
601
|
+
},
|
|
602
|
+
{
|
|
603
|
+
id: 'preview-support',
|
|
604
|
+
label: 'Talk to support',
|
|
605
|
+
prompt: 'Help me contact support',
|
|
606
|
+
description: 'Get help choosing the right approach',
|
|
607
|
+
icon: 'messages-square',
|
|
608
|
+
},
|
|
609
|
+
],
|
|
610
|
+
},
|
|
611
|
+
chunks: [],
|
|
612
|
+
},
|
|
613
|
+
},
|
|
614
|
+
...appendedMessages,
|
|
615
|
+
];
|
|
616
|
+
}
|
|
546
617
|
if (scene === 'home') {
|
|
547
|
-
|
|
618
|
+
// Home is the pre-conversation state: welcome copy + starter suggestions
|
|
619
|
+
// already provide the greeting and entry points. Seeding an assistant
|
|
620
|
+
// bubble here creates a duplicate greeting that the default runtime never
|
|
621
|
+
// enters unless a host explicitly configures its own initialMessages.
|
|
622
|
+
return [];
|
|
548
623
|
}
|
|
549
624
|
if (scene === 'minimized') {
|
|
550
625
|
return [{ id: 'preview-min-1', role: 'assistant', content: 'We are here whenever you are ready.', createdAt: new Date().toISOString() }];
|
|
@@ -60,6 +60,39 @@ describe("theme editor scroll-to-bottom controls", () => {
|
|
|
60
60
|
expect(fieldPaths).toContain("theme.components.scrollToBottom.iconSize");
|
|
61
61
|
});
|
|
62
62
|
|
|
63
|
+
it("exposes suggestion behavior and component token controls", () => {
|
|
64
|
+
const suggestions = CONFIGURE_SECTIONS.find(
|
|
65
|
+
(section) => section.id === "suggestions"
|
|
66
|
+
);
|
|
67
|
+
const configPaths =
|
|
68
|
+
suggestions?.fields.map((field) => field.path) ?? [];
|
|
69
|
+
expect(configPaths).toEqual(
|
|
70
|
+
expect.arrayContaining([
|
|
71
|
+
"suggestions.starters.variant",
|
|
72
|
+
"suggestions.starters.placement",
|
|
73
|
+
"suggestions.starters.behavior",
|
|
74
|
+
"suggestions.followUps.variant",
|
|
75
|
+
"suggestions.followUps.placement",
|
|
76
|
+
"suggestions.followUps.behavior",
|
|
77
|
+
"suggestions.followUps.overflow",
|
|
78
|
+
])
|
|
79
|
+
);
|
|
80
|
+
|
|
81
|
+
const componentPaths = COMPONENTS_SECTIONS.flatMap((section) =>
|
|
82
|
+
section.fields.map((field) => field.path)
|
|
83
|
+
);
|
|
84
|
+
expect(componentPaths).toEqual(
|
|
85
|
+
expect.arrayContaining([
|
|
86
|
+
"theme.components.suggestion.chip.background",
|
|
87
|
+
"theme.components.suggestion.chip.hoverBackground",
|
|
88
|
+
"theme.components.suggestion.chip.focusRing",
|
|
89
|
+
"theme.components.suggestion.card.background",
|
|
90
|
+
"theme.components.suggestion.card.shadow",
|
|
91
|
+
"theme.components.suggestion.list.background",
|
|
92
|
+
])
|
|
93
|
+
);
|
|
94
|
+
});
|
|
95
|
+
|
|
63
96
|
it("exposes a shadow control for every themeable component", () => {
|
|
64
97
|
const fieldPaths = COMPONENTS_SECTIONS.flatMap((section) => section.fields.map((field) => field.path));
|
|
65
98
|
|
|
@@ -369,6 +369,18 @@ const inputShapeSectionDef: SectionDef = {
|
|
|
369
369
|
],
|
|
370
370
|
};
|
|
371
371
|
|
|
372
|
+
const composerSpacingSectionDef: SectionDef = {
|
|
373
|
+
id: 'comp-composer-spacing',
|
|
374
|
+
title: 'Composer Spacing',
|
|
375
|
+
collapsed: true,
|
|
376
|
+
fields: [
|
|
377
|
+
{ id: 'composer-padding', label: 'Padding', type: 'text', path: 'theme.components.composer.padding', defaultValue: '0.75rem 1rem' },
|
|
378
|
+
{ id: 'composer-gap', label: 'Row Gap', description: 'Space between the textarea row and the actions row', type: 'text', path: 'theme.components.composer.gap', defaultValue: '0.5rem' },
|
|
379
|
+
{ id: 'composer-font-size', label: 'Font Size', type: 'text', path: 'theme.components.composer.fontSize', defaultValue: '0.875rem' },
|
|
380
|
+
{ id: 'composer-line-height', label: 'Line Height', type: 'text', path: 'theme.components.composer.lineHeight', defaultValue: '1.25rem' },
|
|
381
|
+
],
|
|
382
|
+
};
|
|
383
|
+
|
|
372
384
|
const buttonShapeSectionDef: SectionDef = {
|
|
373
385
|
id: 'comp-button-shape',
|
|
374
386
|
title: 'Button Shape',
|
|
@@ -466,6 +478,35 @@ const scrollToBottomSectionDef: SectionDef = {
|
|
|
466
478
|
],
|
|
467
479
|
};
|
|
468
480
|
|
|
481
|
+
const suggestionStyleSectionDef: SectionDef = {
|
|
482
|
+
id: 'comp-suggestions',
|
|
483
|
+
title: 'Suggestions',
|
|
484
|
+
description: 'Style starter cards, follow-up chips, and list rows.',
|
|
485
|
+
collapsed: true,
|
|
486
|
+
fields: [
|
|
487
|
+
{ id: 'suggestion-chip-bg', label: 'Chip Background', type: 'token-ref', path: 'theme.components.suggestion.chip.background', defaultValue: 'semantic.colors.surface', tokenRef: { tokenType: 'color' } },
|
|
488
|
+
{ id: 'suggestion-chip-fg', label: 'Chip Text', type: 'token-ref', path: 'theme.components.suggestion.chip.foreground', defaultValue: 'semantic.colors.text', tokenRef: { tokenType: 'color' } },
|
|
489
|
+
{ id: 'suggestion-chip-border', label: 'Chip Border', type: 'token-ref', path: 'theme.components.suggestion.chip.border', defaultValue: 'semantic.colors.border', tokenRef: { tokenType: 'color' } },
|
|
490
|
+
{ id: 'suggestion-chip-hover', label: 'Chip Hover', type: 'token-ref', path: 'theme.components.suggestion.chip.hoverBackground', defaultValue: 'palette.colors.gray.100', tokenRef: { tokenType: 'color' } },
|
|
491
|
+
{ id: 'suggestion-chip-focus', label: 'Chip Focus Ring', type: 'token-ref', path: 'theme.components.suggestion.chip.focusRing', defaultValue: 'semantic.colors.interactive.focus', tokenRef: { tokenType: 'color' } },
|
|
492
|
+
{ id: 'suggestion-card-bg', label: 'Card Background', type: 'token-ref', path: 'theme.components.suggestion.card.background', defaultValue: 'semantic.colors.surface', tokenRef: { tokenType: 'color' } },
|
|
493
|
+
{ id: 'suggestion-card-fg', label: 'Card Text', type: 'token-ref', path: 'theme.components.suggestion.card.foreground', defaultValue: 'semantic.colors.text', tokenRef: { tokenType: 'color' } },
|
|
494
|
+
{ id: 'suggestion-card-border', label: 'Card Border', type: 'token-ref', path: 'theme.components.suggestion.card.border', defaultValue: 'semantic.colors.border', tokenRef: { tokenType: 'color' } },
|
|
495
|
+
{ id: 'suggestion-card-hover', label: 'Card Hover', type: 'token-ref', path: 'theme.components.suggestion.card.hoverBackground', defaultValue: 'palette.colors.gray.100', tokenRef: { tokenType: 'color' } },
|
|
496
|
+
{ id: 'suggestion-card-shadow', label: 'Card Shadow', type: 'select', path: 'theme.components.suggestion.card.shadow', defaultValue: 'palette.shadows.sm', options: [
|
|
497
|
+
{ value: 'palette.shadows.none', label: 'None' },
|
|
498
|
+
{ value: 'palette.shadows.sm', label: 'Small' },
|
|
499
|
+
{ value: 'palette.shadows.md', label: 'Medium' },
|
|
500
|
+
{ value: 'palette.shadows.lg', label: 'Large' },
|
|
501
|
+
] },
|
|
502
|
+
{ id: 'suggestion-list-bg', label: 'List Background', type: 'color', path: 'theme.components.suggestion.list.background', defaultValue: 'transparent' },
|
|
503
|
+
{ id: 'suggestion-list-border', label: 'List Border', type: 'token-ref', path: 'theme.components.suggestion.list.border', defaultValue: 'semantic.colors.border', tokenRef: { tokenType: 'color' } },
|
|
504
|
+
{ id: 'suggestion-chip-item-gap', label: 'Chip Spacing', description: 'Space between chips', type: 'text', path: 'theme.components.suggestion.chip.itemGap', defaultValue: '8px' },
|
|
505
|
+
{ id: 'suggestion-card-item-gap', label: 'Card Spacing', description: 'Space between cards', type: 'text', path: 'theme.components.suggestion.card.itemGap', defaultValue: '8px' },
|
|
506
|
+
{ id: 'suggestion-list-item-gap', label: 'List Spacing', description: 'Space between list rows', type: 'text', path: 'theme.components.suggestion.list.itemGap', defaultValue: '8px' },
|
|
507
|
+
],
|
|
508
|
+
};
|
|
509
|
+
|
|
469
510
|
// Reusable shadow-scale options matching the launcher / panel / scroll-to-bottom selects.
|
|
470
511
|
const SHADOW_SCALE_OPTIONS: { value: string; label: string }[] = [
|
|
471
512
|
{ value: 'palette.shadows.none', label: 'None' },
|
|
@@ -497,12 +538,39 @@ const componentShadowsSectionDef: SectionDef = {
|
|
|
497
538
|
};
|
|
498
539
|
|
|
499
540
|
/** Shared shape sections (not scoped to light/dark) */
|
|
541
|
+
// Blank keeps the built-in fallback: parseOptionalCssValue drops the path so
|
|
542
|
+
// the CSS variable never emits.
|
|
543
|
+
const TEXT_FONT_WEIGHT_OPTIONS: { value: string; label: string }[] = [
|
|
544
|
+
{ value: '', label: 'Default' },
|
|
545
|
+
{ value: '400', label: 'Normal (400)' },
|
|
546
|
+
{ value: '500', label: 'Medium (500)' },
|
|
547
|
+
{ value: '600', label: 'Semibold (600)' },
|
|
548
|
+
{ value: '700', label: 'Bold (700)' },
|
|
549
|
+
];
|
|
550
|
+
|
|
551
|
+
const textStylesSectionDef: SectionDef = {
|
|
552
|
+
id: 'comp-text-styles',
|
|
553
|
+
title: 'Header & Welcome Text',
|
|
554
|
+
description: 'Typography for the header title and the welcome greeting. Leave blank to keep the built-in defaults.',
|
|
555
|
+
collapsed: true,
|
|
556
|
+
fields: [
|
|
557
|
+
{ id: 'header-title-font-family', label: 'Header Title Font', description: 'CSS font-family, e.g. Georgia, serif', type: 'text', path: 'theme.components.header.title.fontFamily', defaultValue: '', parseValue: parseOptionalCssValue },
|
|
558
|
+
{ id: 'header-title-font-size', label: 'Header Title Size', description: 'CSS length, e.g. 1.125rem', type: 'text', path: 'theme.components.header.title.fontSize', defaultValue: '', parseValue: parseOptionalCssValue },
|
|
559
|
+
{ id: 'header-title-font-weight', label: 'Header Title Weight', type: 'select', path: 'theme.components.header.title.fontWeight', defaultValue: '', options: TEXT_FONT_WEIGHT_OPTIONS, parseValue: parseOptionalCssValue },
|
|
560
|
+
{ id: 'welcome-title-font-family', label: 'Welcome Title Font', description: 'CSS font-family, e.g. Georgia, serif', type: 'text', path: 'theme.components.introCard.title.fontFamily', defaultValue: '', parseValue: parseOptionalCssValue },
|
|
561
|
+
{ id: 'welcome-title-font-size', label: 'Welcome Title Size', description: 'CSS length, e.g. 1.5rem', type: 'text', path: 'theme.components.introCard.title.fontSize', defaultValue: '', parseValue: parseOptionalCssValue },
|
|
562
|
+
{ id: 'welcome-title-font-weight', label: 'Welcome Title Weight', type: 'select', path: 'theme.components.introCard.title.fontWeight', defaultValue: '', options: TEXT_FONT_WEIGHT_OPTIONS, parseValue: parseOptionalCssValue },
|
|
563
|
+
],
|
|
564
|
+
};
|
|
565
|
+
|
|
500
566
|
export const COMPONENT_SHAPE_SECTIONS: SectionDef[] = [
|
|
501
567
|
panelLayoutSectionDef,
|
|
502
568
|
launcherLayoutSectionDef,
|
|
503
569
|
messageShapeSectionDef,
|
|
504
570
|
inputShapeSectionDef,
|
|
571
|
+
composerSpacingSectionDef,
|
|
505
572
|
buttonShapeSectionDef,
|
|
573
|
+
textStylesSectionDef,
|
|
506
574
|
componentShadowsSectionDef,
|
|
507
575
|
];
|
|
508
576
|
|
|
@@ -513,6 +581,7 @@ export const COMPONENT_COLOR_SECTIONS: SectionDef[] = [
|
|
|
513
581
|
inputColorsSectionDef,
|
|
514
582
|
buttonColorsSectionDef,
|
|
515
583
|
scrollToBottomSectionDef,
|
|
584
|
+
suggestionStyleSectionDef,
|
|
516
585
|
];
|
|
517
586
|
|
|
518
587
|
export const COMPONENTS_SECTIONS: SectionDef[] = [
|
|
@@ -526,9 +595,9 @@ export const COMPONENTS_SECTIONS: SectionDef[] = [
|
|
|
526
595
|
|
|
527
596
|
const MB = 1024 * 1024;
|
|
528
597
|
const DEFAULT_SUGGESTION_CHIPS = [
|
|
529
|
-
'
|
|
530
|
-
'
|
|
531
|
-
'
|
|
598
|
+
'Show me what you can help with',
|
|
599
|
+
'Walk me through getting started',
|
|
600
|
+
'Answer a question about this page',
|
|
532
601
|
];
|
|
533
602
|
|
|
534
603
|
const ATTACHMENT_TYPE_PRESETS: Record<string, string[]> = {
|
|
@@ -569,16 +638,24 @@ const copySectionDef: SectionDef = {
|
|
|
569
638
|
fields: [
|
|
570
639
|
{ id: 'copy-show-welcome-card', label: 'Show Welcome Card', type: 'toggle', path: 'copy.showWelcomeCard', defaultValue: true },
|
|
571
640
|
{ id: 'copy-welcome-title', label: 'Welcome Title', type: 'text', path: 'copy.welcomeTitle', defaultValue: 'Hello 👋' },
|
|
572
|
-
{ id: 'copy-welcome-subtitle', label: 'Welcome Subtitle', type: 'text', path: 'copy.welcomeSubtitle', defaultValue: '
|
|
641
|
+
{ id: 'copy-welcome-subtitle', label: 'Welcome Subtitle', type: 'text', path: 'copy.welcomeSubtitle', defaultValue: 'I can answer questions and help you get things done here.' },
|
|
573
642
|
{ id: 'copy-placeholder', label: 'Input Placeholder', type: 'text', path: 'copy.inputPlaceholder', defaultValue: 'Type your message…' },
|
|
574
643
|
{ id: 'copy-send-label', label: 'Send Button Label', type: 'text', path: 'copy.sendButtonLabel', defaultValue: 'Send' },
|
|
575
644
|
],
|
|
576
645
|
};
|
|
577
646
|
|
|
578
647
|
const suggestionsSectionDef: SectionDef = {
|
|
579
|
-
id: 'suggestions', title: '
|
|
648
|
+
id: 'suggestions', title: 'Suggestions', description: 'Configure starter prompts and agent follow-ups.', collapsed: true,
|
|
580
649
|
fields: [
|
|
581
|
-
{ id: 'suggestions-list', label: '
|
|
650
|
+
{ id: 'suggestions-list', label: 'Starter Prompts', description: 'Add, edit, and remove starter prompts directly.', type: 'chip-list', path: 'suggestionChips', defaultValue: DEFAULT_SUGGESTION_CHIPS },
|
|
651
|
+
{ id: 'suggestions-starter-variant', label: 'Starter Style', type: 'select', path: 'suggestions.starters.variant', defaultValue: 'card', options: [{ value: 'card', label: 'Cards' }, { value: 'chip', label: 'Chips' }, { value: 'list', label: 'List' }] },
|
|
652
|
+
{ id: 'suggestions-starter-placement', label: 'Starter Placement', type: 'select', path: 'suggestions.starters.placement', defaultValue: 'auto', options: [{ value: 'auto', label: 'Automatic' }, { value: 'welcome', label: 'Welcome Surface' }, { value: 'composer', label: 'Above Composer' }] },
|
|
653
|
+
{ id: 'suggestions-starter-behavior', label: 'Starter Click', type: 'select', path: 'suggestions.starters.behavior', defaultValue: 'send', options: [{ value: 'send', label: 'Send Immediately' }, { value: 'fill', label: 'Fill Composer' }] },
|
|
654
|
+
{ id: 'suggestions-starter-overflow', label: 'Starter Overflow', type: 'select', path: 'suggestions.starters.overflow', defaultValue: 'wrap', options: [{ value: 'wrap', label: 'Wrap Rows' }, { value: 'scroll', label: 'Horizontal Scroll' }] },
|
|
655
|
+
{ id: 'suggestions-followup-variant', label: 'Follow-up Style', type: 'select', path: 'suggestions.followUps.variant', defaultValue: 'chip', options: [{ value: 'chip', label: 'Chips' }, { value: 'card', label: 'Cards' }, { value: 'list', label: 'List' }] },
|
|
656
|
+
{ id: 'suggestions-followup-placement', label: 'Follow-up Placement', type: 'select', path: 'suggestions.followUps.placement', defaultValue: 'auto', options: [{ value: 'auto', label: 'Automatic' }, { value: 'after-message', label: 'After Messages' }, { value: 'composer', label: 'Above Composer' }] },
|
|
657
|
+
{ id: 'suggestions-followup-behavior', label: 'Follow-up Click', type: 'select', path: 'suggestions.followUps.behavior', defaultValue: 'send', options: [{ value: 'send', label: 'Send Immediately' }, { value: 'fill', label: 'Fill Composer' }] },
|
|
658
|
+
{ id: 'suggestions-followup-overflow', label: 'Follow-up Overflow', type: 'select', path: 'suggestions.followUps.overflow', defaultValue: 'scroll', options: [{ value: 'scroll', label: 'Horizontal Scroll' }, { value: 'wrap', label: 'Wrap Rows' }] },
|
|
582
659
|
],
|
|
583
660
|
};
|
|
584
661
|
|
package/src/theme-reference.ts
CHANGED
|
@@ -120,7 +120,9 @@ export const THEME_TOKEN_DOCS = {
|
|
|
120
120
|
header: {
|
|
121
121
|
description: 'Chat panel header.',
|
|
122
122
|
properties:
|
|
123
|
-
'background, border, borderRadius, padding, iconBackground, iconForeground,
|
|
123
|
+
'background, border, borderRadius, padding, iconBackground, iconForeground, actionIconForeground, shadow, borderBottom, title and subtitle (each fontFamily, fontSize, fontWeight, lineHeight, letterSpacing, color).',
|
|
124
|
+
legacy:
|
|
125
|
+
'titleForeground and subtitleForeground are legacy aliases of header.title.color and header.subtitle.color. Both still work; the title/subtitle color wins when both are set.',
|
|
124
126
|
},
|
|
125
127
|
message: {
|
|
126
128
|
description: 'Chat message bubbles.',
|
|
@@ -131,7 +133,19 @@ export const THEME_TOKEN_DOCS = {
|
|
|
131
133
|
markdown: {
|
|
132
134
|
description: 'Markdown rendering in messages and artifact pane.',
|
|
133
135
|
properties:
|
|
134
|
-
'inlineCode (background, foreground), link.foreground, prose.fontFamily, heading.h1/h2 (fontSize, fontWeight).',
|
|
136
|
+
'inlineCode (background, foreground), link.foreground, prose.fontFamily, heading.h1/h2 (fontSize, fontWeight), codeBlock (background, borderColor, textColor, borderRadius: follows palette.radius.md), table (headerBackground, borderColor), hr.color, blockquote (borderColor, background, textColor).',
|
|
137
|
+
},
|
|
138
|
+
introCard: {
|
|
139
|
+
description:
|
|
140
|
+
'Welcome surface above the message list. Flat by default (transparent, no shadow).',
|
|
141
|
+
properties:
|
|
142
|
+
'background, borderRadius, padding, shadow, border (full CSS shorthand, default none), title and subtitle (each fontFamily, fontSize, fontWeight, lineHeight, letterSpacing, color).',
|
|
143
|
+
},
|
|
144
|
+
suggestion: {
|
|
145
|
+
description:
|
|
146
|
+
'Starter prompt and follow-up suggestion chrome. Three variants: chip, card, list.',
|
|
147
|
+
properties:
|
|
148
|
+
'background, foreground, border, borderRadius, padding, shadow, gap (icon to copy inside one item), itemGap (space between items, default 8px), minHeight, fontSize, lineHeight, iconSize, hoverBackground, hoverForeground, hoverBorder, pressedBackground, focusRing, disabledOpacity.',
|
|
135
149
|
},
|
|
136
150
|
voice:
|
|
137
151
|
'recording (indicator, background, border), processing (icon, background), speaking (icon).',
|
|
@@ -141,8 +155,11 @@ export const THEME_TOKEN_DOCS = {
|
|
|
141
155
|
scrollToBottom:
|
|
142
156
|
'Floating scroll-to-bottom affordance shared by transcript and event stream: background, foreground, border, size, borderRadius, shadow, padding, gap, fontSize, iconSize.',
|
|
143
157
|
toolBubble: 'shadow: tool call row box-shadow.',
|
|
158
|
+
scrollbar:
|
|
159
|
+
'Shared scrollbar appearance for every scroller: thumb (default semantic.colors.border), track (default transparent).',
|
|
144
160
|
reasoningBubble: 'shadow: reasoning/thinking row box-shadow.',
|
|
145
|
-
composer:
|
|
161
|
+
composer:
|
|
162
|
+
'Message input form: shadow (box-shadow), borderColor, padding (form inset), gap (textarea row to actions row), fontSize and lineHeight (textarea type).',
|
|
146
163
|
artifact:
|
|
147
164
|
'toolbar (icon styling, copy menu), tab (background, active states), pane (background, toolbarBackground).',
|
|
148
165
|
},
|
|
@@ -234,7 +251,7 @@ export const THEME_TOKEN_DOCS = {
|
|
|
234
251
|
copy: {
|
|
235
252
|
description: 'Widget text content.',
|
|
236
253
|
properties:
|
|
237
|
-
'
|
|
254
|
+
'inputPlaceholder, sendButtonLabel, stopButtonLabel. (showWelcomeCard, welcomeTitle, welcomeSubtitle are deprecated aliases of the welcome namespace.)',
|
|
238
255
|
},
|
|
239
256
|
voiceRecognition: {
|
|
240
257
|
description: 'Voice input configuration.',
|
|
@@ -245,8 +262,20 @@ export const THEME_TOKEN_DOCS = {
|
|
|
245
262
|
properties:
|
|
246
263
|
'enabled, provider ("browser" | "runtype"), browserFallback, voice, rate, pitch.',
|
|
247
264
|
},
|
|
265
|
+
suggestions: {
|
|
266
|
+
description:
|
|
267
|
+
'Rich starter and follow-up suggestion surfaces. Strings remain valid item shorthand.',
|
|
268
|
+
properties:
|
|
269
|
+
'starters.items, starters.variant ("card" | "chip" | "list"), starters.placement ("auto" | "welcome" | "composer"), starters.behavior ("send" | "fill"), starters.overflow ("scroll" | "wrap"), starters.maxItems, followUps.enabled, followUps.expose, followUps.variant, followUps.placement ("auto" | "after-message" | "composer"), followUps.behavior, followUps.overflow ("scroll" | "wrap"), followUps.maxItems.',
|
|
270
|
+
},
|
|
271
|
+
welcome: {
|
|
272
|
+
description:
|
|
273
|
+
'First-open welcome surface. Supersedes copy.welcomeTitle / welcomeSubtitle / showWelcomeCard.',
|
|
274
|
+
properties:
|
|
275
|
+
'title, subtitle, icon ({ type: "lucide", name } | { type: "image", url, alt } | { type: "text", text } | function), variant ("card" | "hero" | "none"), dismiss ("never" | "on-first-message"), message (display-only greeting bubble, ignored under "hero").',
|
|
276
|
+
},
|
|
248
277
|
suggestionChips:
|
|
249
|
-
'string[]
|
|
278
|
+
'Deprecated string[] shorthand for starter prompts. Prefer suggestions.starters.items.',
|
|
250
279
|
messageActions: {
|
|
251
280
|
description: 'Message action buttons (copy, upvote, downvote).',
|
|
252
281
|
properties:
|
package/src/types/theme.ts
CHANGED
|
@@ -202,6 +202,16 @@ export interface PanelTokens extends ComponentTokenSet {
|
|
|
202
202
|
canvasBackground?: string;
|
|
203
203
|
}
|
|
204
204
|
|
|
205
|
+
/** Per-element text styling shared by themable text surfaces. */
|
|
206
|
+
export interface TextStyleTokens {
|
|
207
|
+
fontFamily?: string;
|
|
208
|
+
fontSize?: string;
|
|
209
|
+
fontWeight?: string;
|
|
210
|
+
lineHeight?: string;
|
|
211
|
+
letterSpacing?: string;
|
|
212
|
+
color?: TokenReference<'color'>;
|
|
213
|
+
}
|
|
214
|
+
|
|
205
215
|
export interface HeaderTokens extends ComponentTokenSet {
|
|
206
216
|
background: TokenReference<'color'>;
|
|
207
217
|
border: TokenReference<'color'>;
|
|
@@ -210,10 +220,14 @@ export interface HeaderTokens extends ComponentTokenSet {
|
|
|
210
220
|
iconBackground: TokenReference<'color'>;
|
|
211
221
|
/** Foreground (glyph stroke or emoji text) on the header avatar tile. */
|
|
212
222
|
iconForeground: TokenReference<'color'>;
|
|
213
|
-
/**
|
|
223
|
+
/** Legacy alias of `title.color`; `title.color` wins when both are set. */
|
|
214
224
|
titleForeground: TokenReference<'color'>;
|
|
215
|
-
/**
|
|
225
|
+
/** Legacy alias of `subtitle.color`; `subtitle.color` wins when both are set. */
|
|
216
226
|
subtitleForeground: TokenReference<'color'>;
|
|
227
|
+
/** Header title typography (next to the icon, or minimal layout title). */
|
|
228
|
+
title?: TextStyleTokens;
|
|
229
|
+
/** Header subtitle typography, for the line under the title. */
|
|
230
|
+
subtitle?: TextStyleTokens;
|
|
217
231
|
/** Default color for clear / close icon buttons when launcher overrides are unset. */
|
|
218
232
|
actionIconForeground: TokenReference<'color'>;
|
|
219
233
|
/** Box-shadow on the header (e.g., a fade shadow to replace the default border). */
|
|
@@ -245,7 +259,7 @@ export interface MessageTokens {
|
|
|
245
259
|
|
|
246
260
|
/**
|
|
247
261
|
* Welcome / intro card rendered above the message list when no messages exist.
|
|
248
|
-
* Set `
|
|
262
|
+
* Set `welcome.variant: "none"` to hide it; use `layout.slots["body-top"]`
|
|
249
263
|
* to replace it wholesale.
|
|
250
264
|
*/
|
|
251
265
|
export interface IntroCardTokens extends ComponentTokenSet {
|
|
@@ -254,6 +268,12 @@ export interface IntroCardTokens extends ComponentTokenSet {
|
|
|
254
268
|
padding?: TokenReference<'spacing'>;
|
|
255
269
|
/** Box-shadow on the intro card (token ref or raw CSS, e.g. `none`). */
|
|
256
270
|
shadow?: string;
|
|
271
|
+
/** Full border shorthand on the intro card (raw CSS, e.g. `"1px solid rgba(0,0,0,0.1)"`). @default "none" */
|
|
272
|
+
border?: string;
|
|
273
|
+
/** Welcome title typography. */
|
|
274
|
+
title?: TextStyleTokens;
|
|
275
|
+
/** Welcome subtitle typography. */
|
|
276
|
+
subtitle?: TextStyleTokens;
|
|
257
277
|
}
|
|
258
278
|
|
|
259
279
|
/** Collapsible widget chrome (tool bubbles, reasoning bubbles, approval bubbles). */
|
|
@@ -298,6 +318,8 @@ export interface MarkdownTokens {
|
|
|
298
318
|
background?: TokenReference<'color'>;
|
|
299
319
|
borderColor?: TokenReference<'color'>;
|
|
300
320
|
textColor?: TokenReference<'color'>;
|
|
321
|
+
/** Corner radius; follows `palette.radius.md` by default so square-corner themes get square code blocks. */
|
|
322
|
+
borderRadius?: TokenReference<'radius'>;
|
|
301
323
|
};
|
|
302
324
|
/** Table styling. */
|
|
303
325
|
table?: {
|
|
@@ -361,10 +383,28 @@ export interface ReasoningBubbleTokens {
|
|
|
361
383
|
shadow: string;
|
|
362
384
|
}
|
|
363
385
|
|
|
386
|
+
/** Scrollbar appearance shared by every scroller in the widget. */
|
|
387
|
+
export interface ScrollbarTokens {
|
|
388
|
+
/** Thumb color. @default semantic.colors.border */
|
|
389
|
+
thumb?: TokenReference<'color'>;
|
|
390
|
+
/** Track color. @default "transparent" */
|
|
391
|
+
track?: TokenReference<'color'>;
|
|
392
|
+
}
|
|
393
|
+
|
|
364
394
|
/** Composer (message input) chrome. */
|
|
365
395
|
export interface ComposerChromeTokens {
|
|
366
396
|
/** Box-shadow on the composer form (raw CSS, e.g. `none`). */
|
|
367
397
|
shadow: string;
|
|
398
|
+
/** Border color of the composer form. @default semantic.colors.border */
|
|
399
|
+
borderColor?: TokenReference<'color'>;
|
|
400
|
+
/** Inner padding of the composer form (raw CSS shorthand). @default "0.75rem 1rem" */
|
|
401
|
+
padding?: string;
|
|
402
|
+
/** Gap between the textarea row and the actions row. @default "0.5rem" */
|
|
403
|
+
gap?: string;
|
|
404
|
+
/** Composer textarea font-size. @default "0.875rem" */
|
|
405
|
+
fontSize?: string;
|
|
406
|
+
/** Composer textarea line-height. @default "1.25rem" */
|
|
407
|
+
lineHeight?: string;
|
|
368
408
|
}
|
|
369
409
|
|
|
370
410
|
/** Artifact toolbar chrome. */
|
|
@@ -524,6 +564,31 @@ export interface ScrollToBottomTokens extends ComponentTokenSet {
|
|
|
524
564
|
iconSize?: string;
|
|
525
565
|
}
|
|
526
566
|
|
|
567
|
+
/** Visual tokens shared by one suggestion presentation variant. */
|
|
568
|
+
export interface SuggestionVariantTokens extends ComponentTokenSet {
|
|
569
|
+
/** Space inside one item, between its icon and its copy. */
|
|
570
|
+
gap?: string;
|
|
571
|
+
/** Space between suggestion items in the container. */
|
|
572
|
+
itemGap?: string;
|
|
573
|
+
minHeight?: string;
|
|
574
|
+
fontSize?: string;
|
|
575
|
+
lineHeight?: string;
|
|
576
|
+
iconSize?: string;
|
|
577
|
+
hoverBackground?: TokenReference<'color'>;
|
|
578
|
+
hoverForeground?: TokenReference<'color'>;
|
|
579
|
+
hoverBorder?: TokenReference<'color'>;
|
|
580
|
+
pressedBackground?: TokenReference<'color'>;
|
|
581
|
+
focusRing?: TokenReference<'color'>;
|
|
582
|
+
disabledOpacity?: string;
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
/** Starter and follow-up suggestion chrome. */
|
|
586
|
+
export interface SuggestionTokens {
|
|
587
|
+
chip: SuggestionVariantTokens;
|
|
588
|
+
card: SuggestionVariantTokens;
|
|
589
|
+
list: SuggestionVariantTokens;
|
|
590
|
+
}
|
|
591
|
+
|
|
527
592
|
/** Toggle group chrome (used by createToggleGroup). */
|
|
528
593
|
export interface ToggleGroupTokens {
|
|
529
594
|
/** Gap between toggle buttons. Default: 0 (connected). */
|
|
@@ -549,12 +614,16 @@ export interface ComponentTokens {
|
|
|
549
614
|
toolBubble: ToolBubbleTokens;
|
|
550
615
|
reasoningBubble: ReasoningBubbleTokens;
|
|
551
616
|
composer: ComposerChromeTokens;
|
|
617
|
+
/** Scrollbar appearance for every scroller in the widget. */
|
|
618
|
+
scrollbar?: ScrollbarTokens;
|
|
552
619
|
/** Icon button styling tokens. */
|
|
553
620
|
iconButton?: IconButtonTokens;
|
|
554
621
|
/** Label button styling tokens. */
|
|
555
622
|
labelButton?: LabelButtonTokens;
|
|
556
623
|
/** Scroll-to-bottom indicator styling tokens. */
|
|
557
624
|
scrollToBottom?: ScrollToBottomTokens;
|
|
625
|
+
/** Starter prompt and follow-up suggestion styling tokens. */
|
|
626
|
+
suggestion?: SuggestionTokens;
|
|
558
627
|
/** Toggle group styling tokens. */
|
|
559
628
|
toggleGroup?: ToggleGroupTokens;
|
|
560
629
|
/** Artifact toolbar, tab strip, and pane chrome. */
|