@runtypelabs/persona 3.10.0 → 3.11.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.
@@ -1 +1 @@
1
- "use strict";var t=Object.defineProperty;var l=Object.getOwnPropertyDescriptor;var c=Object.getOwnPropertyNames;var d=Object.prototype.hasOwnProperty;var m=(o,e)=>{for(var a in e)t(o,a,{get:e[a],enumerable:!0})},u=(o,e,a,s)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of c(e))!d.call(o,r)&&r!==a&&t(o,r,{get:()=>e[r],enumerable:!(s=l(e,r))||s.enumerable});return o};var g=o=>u(t({},"__esModule",{value:!0}),o);var h={};m(h,{THEME_EXAMPLES:()=>p,THEME_TOKEN_DOCS:()=>i,getThemeReference:()=>b});module.exports=g(h);var n={colors:{primary:{50:"#ffffff",100:"#f5f5f5",200:"#d4d4d4",300:"#a3a3a3",400:"#737373",500:"#171717",600:"#0f0f0f",700:"#0a0a0a",800:"#050505",900:"#030303",950:"#000000"},secondary:{50:"#f5f3ff",100:"#ede9fe",200:"#ddd6fe",300:"#c4b5fd",400:"#a78bfa",500:"#8b5cf6",600:"#7c3aed",700:"#6d28d9",800:"#5b21b6",900:"#4c1d95",950:"#2e1065"},accent:{50:"#ecfeff",100:"#cffafe",200:"#a5f3fc",300:"#67e8f9",400:"#22d3ee",500:"#06b6d4",600:"#0891b2",700:"#0e7490",800:"#155e75",900:"#164e63",950:"#083344"},gray:{50:"#f9fafb",100:"#f3f4f6",200:"#e5e7eb",300:"#d1d5db",400:"#9ca3af",500:"#6b7280",600:"#4b5563",700:"#374151",800:"#1f2937",900:"#111827",950:"#030712"},success:{50:"#f0fdf4",100:"#dcfce7",200:"#bbf7d0",300:"#86efac",400:"#4ade80",500:"#22c55e",600:"#16a34a",700:"#15803d",800:"#166534",900:"#14532d"},warning:{50:"#fefce8",100:"#fef9c3",200:"#fef08a",300:"#fde047",400:"#facc15",500:"#eab308",600:"#ca8a04",700:"#a16207",800:"#854d0e",900:"#713f12"},error:{50:"#fef2f2",100:"#fee2e2",200:"#fecaca",300:"#fca5a5",400:"#f87171",500:"#ef4444",600:"#dc2626",700:"#b91c1c",800:"#991b1b",900:"#7f1d1d"},info:{50:"#eff6ff",100:"#dbeafe",200:"#bfdbfe",300:"#93c5fd",400:"#60a5fa",500:"#3b82f6",600:"#2563eb",700:"#1d4ed8",800:"#1e40af",900:"#1e3a8a",950:"#172554"}},spacing:{0:"0px",1:"0.25rem",2:"0.5rem",3:"0.75rem",4:"1rem",5:"1.25rem",6:"1.5rem",8:"2rem",10:"2.5rem",12:"3rem",16:"4rem",20:"5rem",24:"6rem",32:"8rem",40:"10rem",48:"12rem",56:"14rem",64:"16rem"},typography:{fontFamily:{sans:'system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',serif:'Georgia, Cambria, "Times New Roman", Times, serif',mono:"ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace"},fontSize:{xs:"0.75rem",sm:"0.875rem",base:"1rem",lg:"1.125rem",xl:"1.25rem","2xl":"1.5rem","3xl":"1.875rem","4xl":"2.25rem"},fontWeight:{normal:"400",medium:"500",semibold:"600",bold:"700"},lineHeight:{tight:"1.25",normal:"1.5",relaxed:"1.625"}},shadows:{none:"none",sm:"0 1px 2px 0 rgb(0 0 0 / 0.05)",md:"0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1)",lg:"0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1)",xl:"0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1)","2xl":"0 25px 50px -12px rgb(0 0 0 / 0.25)"},borders:{none:"none",sm:"1px solid",md:"2px solid",lg:"4px solid"},radius:{none:"0px",sm:"0.125rem",md:"0.375rem",lg:"0.5rem",xl:"0.75rem","2xl":"1rem",full:"9999px"}};var i={overview:"Persona uses a three-layer design token system: palette \u2192 semantic \u2192 components. Most themes only need palette.colors overrides \u2014 semantic and component layers auto-derive from palette values. Config also accepts non-theme appearance options (launcher, sendButton, toolCall, etc.).",layers:{palette:{description:"Primitive design tokens. Override specific shades to change the entire widget feel.",colors:{description:"7 color scales, each with shades 50 (lightest) to 950 (darkest). Override only the shades you need.",scales:{gray:"Neutrals \u2014 backgrounds, text, borders. Key shades: 50 (lightest bg), 100 (secondary bg), 200 (borders), 500 (muted text), 900 (primary text).",primary:"Brand color \u2014 buttons, links, interactive elements. Key shades: 500 (default), 600 (hover).",accent:"Secondary highlight. Key shades: 500 (default), 600 (hover).",secondary:"Tertiary color scale.",success:"Positive feedback (default: green).",warning:"Caution feedback (default: yellow).",error:"Error/danger feedback (default: red)."}},radius:{description:"Border radius scale. Add custom keys like launcher, button.",defaults:{none:"0px",sm:"0.125rem",md:"0.375rem",lg:"0.5rem",xl:"0.75rem","2xl":"1rem",full:"9999px"}},typography:{fontFamily:"Three stacks: sans (system-ui), serif (Georgia), mono (ui-monospace). Override individual stack values.",fontSize:"Scale: xs (0.75rem), sm (0.875rem), base (1rem), lg (1.125rem), xl (1.25rem), 2xl (1.5rem), 3xl (1.875rem), 4xl (2.25rem).",fontWeight:"normal (400), medium (500), semibold (600), bold (700).",lineHeight:"tight (1.25), normal (1.5), relaxed (1.625)."},shadows:"Scale: none, sm, md, lg, xl, 2xl. Values are CSS box-shadow strings.",borders:"Scale: none, sm (1px solid), md (2px solid), lg (4px solid).",spacing:"Scale: 0 (0px), 1 (0.25rem), 2 (0.5rem), 3 (0.75rem), 4 (1rem), 5 (1.25rem), 6 (1.5rem), 8 (2rem), 10 (2.5rem), 12 (3rem), 16-64."},semantic:{description:'Design intent tokens. Auto-derived from palette by default. Override to redirect token resolution. Values are token reference strings like "palette.colors.primary.500".',colors:{primary:"palette.colors.primary.500 \u2014 Primary brand color.",secondary:"palette.colors.gray.500 \u2014 Secondary color.",accent:"palette.colors.primary.600 \u2014 Accent/interactive color.",surface:"palette.colors.gray.50 \u2014 Panel/card backgrounds.",background:"palette.colors.gray.50 \u2014 Page background.",container:"palette.colors.gray.100 \u2014 Container backgrounds.",text:"palette.colors.gray.900 \u2014 Primary text.",textMuted:"palette.colors.gray.500 \u2014 Muted/secondary text.",textInverse:"palette.colors.gray.50 \u2014 Text on dark backgrounds.",border:"palette.colors.gray.200 \u2014 Default border color.",divider:"palette.colors.gray.200 \u2014 Divider lines.",interactive:{default:"palette.colors.primary.500",hover:"palette.colors.primary.600",focus:"palette.colors.primary.700",active:"palette.colors.primary.800",disabled:"palette.colors.gray.300"},feedback:{success:"palette.colors.success.500",warning:"palette.colors.warning.500",error:"palette.colors.error.500",info:"palette.colors.primary.500"}},spacing:"xs (0.25rem), sm (0.5rem), md (1rem), lg (1.5rem), xl (2rem), 2xl (2.5rem).",typography:"fontFamily, fontSize, fontWeight, lineHeight \u2014 reference palette typography tokens."},components:{description:"UI element tokens. Rarely needed for basic theming. Override for fine-grained control. All values are token references or raw CSS strings.",button:{description:"Three variants: primary, secondary, ghost.",properties:"background, foreground, borderRadius, padding."},input:{description:"Message input field.",properties:"background, placeholder, borderRadius, padding, focus.border, focus.ring."},launcher:{description:"Floating launcher button.",properties:"size (60px), iconSize (28px), borderRadius, shadow."},panel:{description:"Chat panel container.",properties:"width, maxWidth (440px), height (600px), maxHeight, borderRadius, shadow."},header:{description:"Chat panel header.",properties:"background, border, borderRadius, padding, iconBackground, iconForeground, titleForeground, subtitleForeground, actionIconForeground, shadow, borderBottom."},message:{description:"Chat message bubbles.",user:"background, text, borderRadius, shadow.",assistant:"background, text, borderRadius, border (optional), shadow (optional)."},markdown:{description:"Markdown rendering in messages and artifact pane.",properties:"inlineCode (background, foreground), link.foreground, prose.fontFamily, heading.h1/h2 (fontSize, fontWeight)."},voice:"recording (indicator, background, border), processing (icon, background), speaking (icon).",approval:"requested (background, border, text), approve (background, foreground), deny (background, foreground).",attachment:"image (background, border).",scrollToBottom:"Floating scroll-to-bottom affordance shared by transcript and event stream: background, foreground, border, size, borderRadius, shadow, padding, gap, fontSize, iconSize.",toolBubble:"shadow \u2014 tool call row box-shadow.",reasoningBubble:"shadow \u2014 reasoning/thinking row box-shadow.",composer:"shadow \u2014 message input form box-shadow.",artifact:"toolbar (icon styling, copy menu), tab (background, active states), pane (background, toolbarBackground)."}},colorScheme:'"dark" merges darkTheme overrides on top of theme. "auto" detects system preference or <html class="dark">. "light" is default. colorScheme does NOT auto-invert colors \u2014 provide dark palette and semantic overrides yourself.',plugins:{description:"Plugins transform theme tokens before resolution. Use with createTheme().",available:{brandPlugin:'Auto-generates full color scales from a single brand hex: brandPlugin({ colors: { primary: "#7c3aed" } }).',accessibilityPlugin:"Enhanced focus indicators and disabled states.",highContrastPlugin:"Increased contrast for visual accessibility.",reducedMotionPlugin:"Disables all animations (sets transitions to 0ms).",animationsPlugin:"Adds transition and easing tokens."},usage:'createTheme(themeOverrides, { plugins: [brandPlugin({ colors: { primary: "#7c3aed" } })] })'},widgetConfig:{description:'Non-theme config options on the widget config object that affect appearance. These are siblings of "theme" in the config, not nested inside it.',launcher:{description:"Floating launcher button and panel positioning.",properties:{enabled:"Show/hide the launcher button.",title:"Header title text.",subtitle:"Header subtitle text.",position:'"bottom-right" | "bottom-left" | "top-right" | "top-left".',width:"Chat panel width (CSS value).",fullHeight:"Fill full height of container.",mountMode:'"floating" | "docked".',agentIconText:"Emoji/text for agent icon.",border:"Border style for launcher button.",shadow:"Box shadow for launcher button.",collapsedMaxWidth:"Max-width for launcher pill when panel closed."}},sendButton:{description:"Send button appearance.",properties:"backgroundColor, textColor, borderWidth, borderColor, paddingX, paddingY, iconText, iconName, size."},closeButton:{description:"Close button (on launcher config).",properties:"closeButtonSize, closeButtonColor, closeButtonBackgroundColor, closeButtonBorderWidth, closeButtonBorderColor, closeButtonBorderRadius."},clearChat:{description:"Clear chat button (on launcher.clearChat config).",properties:"enabled, iconColor, backgroundColor, borderWidth, borderColor, borderRadius, size."},scrollToBottom:{description:"Shared transcript + event-stream jump-to-latest affordance.",properties:'features.scrollToBottom.enabled, features.scrollToBottom.iconName, features.scrollToBottom.label (empty string renders icon-only). Defaults: enabled=true, iconName="arrow-down", label="".'},toolCall:{description:"Tool call display styling and collapsed/grouped rendering hooks.",properties:"shadow, backgroundColor, borderColor, borderWidth, borderRadius, headerBackgroundColor, headerTextColor, headerPaddingX, headerPaddingY, contentBackgroundColor, contentTextColor, contentPaddingX, contentPaddingY, codeBlockBackgroundColor, codeBlockBorderColor, codeBlockTextColor, toggleTextColor, labelTextColor, renderCollapsedSummary, renderCollapsedPreview, renderGroupedSummary."},reasoning:{description:"Reasoning/thinking row rendering hooks.",properties:"renderCollapsedSummary, renderCollapsedPreview."},approval:{description:"Tool approval bubble styling and behavior. Set to false to disable.",properties:"backgroundColor, borderColor, titleColor, descriptionColor, approveButtonColor, approveButtonTextColor, denyButtonColor, denyButtonTextColor, parameterBackgroundColor, parameterTextColor, title, approveLabel, denyLabel."},copy:{description:"Widget text content.",properties:"showWelcomeCard (boolean), welcomeTitle, welcomeSubtitle, inputPlaceholder, sendButtonLabel."},voiceRecognition:{description:"Voice input configuration.",properties:"enabled, pauseDuration, iconColor, backgroundColor."},textToSpeech:{description:"Text-to-speech for assistant messages.",properties:'enabled, provider ("browser" | "runtype"), browserFallback, voice, rate, pitch.'},suggestionChips:"string[] \u2014 Suggested prompts shown to the user.",messageActions:{description:"Message action buttons (copy, upvote, downvote).",properties:'enabled, showCopy, showUpvote, showDownvote, visibility ("hover" | "always"), align ("left" | "center" | "right"), layout ("pill-inside" | "row-inside").'},attachments:{description:"File attachment configuration.",properties:"enabled, allowedTypes (string[]), maxFileSize (bytes), maxFiles, buttonIconName, buttonTooltipText."},markdown:{description:"Markdown rendering configuration.",properties:"options (gfm, breaks, headerIds, headerPrefix, pedantic, mangle, silent), disableDefaultStyles."},layout:{description:"Layout configuration.",showHeader:"boolean \u2014 show/hide the header section entirely.",showFooter:"boolean \u2014 show/hide the footer/composer section entirely.",contentMaxWidth:'CSS width value for centering content (e.g. "720px", "90ch").',header:'"default" | "minimal". Options: showIcon, showTitle, showSubtitle, showCloseButton, showClearChat.',messages:'"bubble" | "flat" | "minimal". Options: groupConsecutive, avatar (show, position, userAvatar, assistantAvatar), timestamp (show, position).'},statusIndicator:{description:"Status text shown below the composer.",properties:{visible:"Show/hide the status indicator.",align:'"left" | "center" | "right" \u2014 text alignment (default: "right").',idleText:'Text shown when idle (default: "Online").',idleLink:"URL to open when idle text is clicked (wraps text in a link).",connectingText:'Text shown while connecting (default: "Connecting\u2026").',connectedText:'Text shown while streaming (default: "Streaming\u2026").',errorText:'Text shown on error (default: "Offline").'}},features:{description:"Feature flags.",properties:"showReasoning (AI thinking steps), showToolCalls (tool invocations), toolCallDisplay (collapsedMode, activePreview, activeMinHeight, previewMaxLines, grouped), reasoningDisplay (activePreview, activeMinHeight, previewMaxLines), artifacts (sidebar config)."}}},p={darkIndigo:{description:"Dark mode with indigo accent \u2014 override grays for dark backgrounds and semantic tokens for inverted text/surface",theme:{palette:{colors:{primary:{500:"#6366f1",600:"#4f46e5"},gray:{50:"#f1f5f9",100:"#1e293b",200:"#334155",500:"#94a3b8",900:"#0f172a",950:"#020617"}}},semantic:{colors:{surface:"palette.colors.gray.900",background:"palette.colors.gray.900",container:"palette.colors.gray.100",text:"palette.colors.gray.50",textMuted:"palette.colors.gray.500",textInverse:"palette.colors.gray.900",border:"palette.colors.gray.200"}}}},warmVintage:{description:"Warm sepia tones with serif font and subtle radius",theme:{palette:{colors:{primary:{500:"#b45309",600:"#92400e"},gray:{50:"#fef3c7",100:"#fef9c3",200:"#d6d3d1",500:"#78716c",900:"#44403c"}},radius:{sm:"0.125rem",md:"0.25rem",lg:"0.375rem"},typography:{fontFamily:{sans:'Georgia, Cambria, "Times New Roman", Times, serif'}}}}},neonCyberpunk:{description:"Neon on dark with monospace font \u2014 full semantic override for dark background",theme:{palette:{colors:{primary:{500:"#f0abfc",600:"#e879f9"},accent:{500:"#22d3ee",600:"#06b6d4"},gray:{50:"#f0abfc",100:"#1e0a3c",200:"#3b0764",500:"#c084fc",900:"#0c0a1a",950:"#050412"}},radius:{sm:"0",md:"0.25rem",lg:"0.375rem"},typography:{fontFamily:{sans:"ui-monospace, SFMono-Regular, Menlo, monospace"}}},semantic:{colors:{surface:"palette.colors.gray.900",background:"palette.colors.gray.950",container:"palette.colors.gray.100",text:"palette.colors.gray.50",textMuted:"palette.colors.gray.500",border:"palette.colors.gray.200"}}}},cleanRounded:{description:"Clean light theme with large radius and panel styling",theme:{palette:{radius:{sm:"6px",md:"8px",lg:"12px",launcher:"50px",button:"8px"}},components:{panel:{borderRadius:"16px",shadow:"palette.shadows.2xl"}}}}};function b(){return{tokenDocs:i,defaultColorPalette:n.colors,defaultRadius:n.radius,examples:p,sdkPresets:["shop","minimal","fullscreen"]}}0&&(module.exports={THEME_EXAMPLES,THEME_TOKEN_DOCS,getThemeReference});
1
+ "use strict";var t=Object.defineProperty;var l=Object.getOwnPropertyDescriptor;var c=Object.getOwnPropertyNames;var d=Object.prototype.hasOwnProperty;var m=(o,e)=>{for(var a in e)t(o,a,{get:e[a],enumerable:!0})},u=(o,e,a,s)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of c(e))!d.call(o,r)&&r!==a&&t(o,r,{get:()=>e[r],enumerable:!(s=l(e,r))||s.enumerable});return o};var g=o=>u(t({},"__esModule",{value:!0}),o);var h={};m(h,{THEME_EXAMPLES:()=>p,THEME_TOKEN_DOCS:()=>i,getThemeReference:()=>b});module.exports=g(h);var n={colors:{primary:{50:"#ffffff",100:"#f5f5f5",200:"#d4d4d4",300:"#a3a3a3",400:"#737373",500:"#171717",600:"#0f0f0f",700:"#0a0a0a",800:"#050505",900:"#030303",950:"#000000"},secondary:{50:"#f5f3ff",100:"#ede9fe",200:"#ddd6fe",300:"#c4b5fd",400:"#a78bfa",500:"#8b5cf6",600:"#7c3aed",700:"#6d28d9",800:"#5b21b6",900:"#4c1d95",950:"#2e1065"},accent:{50:"#ecfeff",100:"#cffafe",200:"#a5f3fc",300:"#67e8f9",400:"#22d3ee",500:"#06b6d4",600:"#0891b2",700:"#0e7490",800:"#155e75",900:"#164e63",950:"#083344"},gray:{50:"#f9fafb",100:"#f3f4f6",200:"#e5e7eb",300:"#d1d5db",400:"#9ca3af",500:"#6b7280",600:"#4b5563",700:"#374151",800:"#1f2937",900:"#111827",950:"#030712"},success:{50:"#f0fdf4",100:"#dcfce7",200:"#bbf7d0",300:"#86efac",400:"#4ade80",500:"#22c55e",600:"#16a34a",700:"#15803d",800:"#166534",900:"#14532d"},warning:{50:"#fefce8",100:"#fef9c3",200:"#fef08a",300:"#fde047",400:"#facc15",500:"#eab308",600:"#ca8a04",700:"#a16207",800:"#854d0e",900:"#713f12"},error:{50:"#fef2f2",100:"#fee2e2",200:"#fecaca",300:"#fca5a5",400:"#f87171",500:"#ef4444",600:"#dc2626",700:"#b91c1c",800:"#991b1b",900:"#7f1d1d"},info:{50:"#eff6ff",100:"#dbeafe",200:"#bfdbfe",300:"#93c5fd",400:"#60a5fa",500:"#3b82f6",600:"#2563eb",700:"#1d4ed8",800:"#1e40af",900:"#1e3a8a",950:"#172554"}},spacing:{0:"0px",1:"0.25rem",2:"0.5rem",3:"0.75rem",4:"1rem",5:"1.25rem",6:"1.5rem",8:"2rem",10:"2.5rem",12:"3rem",16:"4rem",20:"5rem",24:"6rem",32:"8rem",40:"10rem",48:"12rem",56:"14rem",64:"16rem"},typography:{fontFamily:{sans:'system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',serif:'Georgia, Cambria, "Times New Roman", Times, serif',mono:"ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace"},fontSize:{xs:"0.75rem",sm:"0.875rem",base:"1rem",lg:"1.125rem",xl:"1.25rem","2xl":"1.5rem","3xl":"1.875rem","4xl":"2.25rem"},fontWeight:{normal:"400",medium:"500",semibold:"600",bold:"700"},lineHeight:{tight:"1.25",normal:"1.5",relaxed:"1.625"}},shadows:{none:"none",sm:"0 1px 2px 0 rgb(0 0 0 / 0.05)",md:"0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1)",lg:"0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1)",xl:"0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1)","2xl":"0 25px 50px -12px rgb(0 0 0 / 0.25)"},borders:{none:"none",sm:"1px solid",md:"2px solid",lg:"4px solid"},radius:{none:"0px",sm:"0.125rem",md:"0.375rem",lg:"0.5rem",xl:"0.75rem","2xl":"1rem",full:"9999px"}};var i={overview:"Persona uses a three-layer design token system: palette \u2192 semantic \u2192 components. Most themes only need palette.colors overrides \u2014 semantic and component layers auto-derive from palette values. Config also accepts non-theme appearance options (launcher, sendButton, toolCall, etc.).",layers:{palette:{description:"Primitive design tokens. Override specific shades to change the entire widget feel.",colors:{description:"7 color scales, each with shades 50 (lightest) to 950 (darkest). Override only the shades you need.",scales:{gray:"Neutrals \u2014 backgrounds, text, borders. Key shades: 50 (lightest bg), 100 (secondary bg), 200 (borders), 500 (muted text), 900 (primary text).",primary:"Brand color \u2014 buttons, links, interactive elements. Key shades: 500 (default), 600 (hover).",accent:"Secondary highlight. Key shades: 500 (default), 600 (hover).",secondary:"Tertiary color scale.",success:"Positive feedback (default: green).",warning:"Caution feedback (default: yellow).",error:"Error/danger feedback (default: red)."}},radius:{description:"Border radius scale. Add custom keys like launcher, button.",defaults:{none:"0px",sm:"0.125rem",md:"0.375rem",lg:"0.5rem",xl:"0.75rem","2xl":"1rem",full:"9999px"}},typography:{fontFamily:"Three stacks: sans (system-ui), serif (Georgia), mono (ui-monospace). Override individual stack values.",fontSize:"Scale: xs (0.75rem), sm (0.875rem), base (1rem), lg (1.125rem), xl (1.25rem), 2xl (1.5rem), 3xl (1.875rem), 4xl (2.25rem).",fontWeight:"normal (400), medium (500), semibold (600), bold (700).",lineHeight:"tight (1.25), normal (1.5), relaxed (1.625)."},shadows:"Scale: none, sm, md, lg, xl, 2xl. Values are CSS box-shadow strings.",borders:"Scale: none, sm (1px solid), md (2px solid), lg (4px solid).",spacing:"Scale: 0 (0px), 1 (0.25rem), 2 (0.5rem), 3 (0.75rem), 4 (1rem), 5 (1.25rem), 6 (1.5rem), 8 (2rem), 10 (2.5rem), 12 (3rem), 16-64."},semantic:{description:'Design intent tokens. Auto-derived from palette by default. Override to redirect token resolution. Values are token reference strings like "palette.colors.primary.500".',colors:{primary:"palette.colors.primary.500 \u2014 Primary brand color.",secondary:"palette.colors.gray.500 \u2014 Secondary color.",accent:"palette.colors.primary.600 \u2014 Accent/interactive color.",surface:"palette.colors.gray.50 \u2014 Panel/card backgrounds.",background:"palette.colors.gray.50 \u2014 Page background.",container:"palette.colors.gray.100 \u2014 Container backgrounds.",text:"palette.colors.gray.900 \u2014 Primary text.",textMuted:"palette.colors.gray.500 \u2014 Muted/secondary text.",textInverse:"palette.colors.gray.50 \u2014 Text on dark backgrounds.",border:"palette.colors.gray.200 \u2014 Default border color.",divider:"palette.colors.gray.200 \u2014 Divider lines.",interactive:{default:"palette.colors.primary.500",hover:"palette.colors.primary.600",focus:"palette.colors.primary.700",active:"palette.colors.primary.800",disabled:"palette.colors.gray.300"},feedback:{success:"palette.colors.success.500",warning:"palette.colors.warning.500",error:"palette.colors.error.500",info:"palette.colors.primary.500"}},spacing:"xs (0.25rem), sm (0.5rem), md (1rem), lg (1.5rem), xl (2rem), 2xl (2.5rem).",typography:"fontFamily, fontSize, fontWeight, lineHeight \u2014 reference palette typography tokens."},components:{description:"UI element tokens. Rarely needed for basic theming. Override for fine-grained control. All values are token references or raw CSS strings.",button:{description:"Three variants: primary, secondary, ghost.",properties:"background, foreground, borderRadius, padding."},input:{description:"Message input field.",properties:"background, placeholder, borderRadius, padding, focus.border, focus.ring."},launcher:{description:"Floating launcher button.",properties:"size (60px), iconSize (28px), borderRadius, shadow."},panel:{description:"Chat panel container.",properties:"width, maxWidth (440px), height (600px), maxHeight, borderRadius, shadow."},header:{description:"Chat panel header.",properties:"background, border, borderRadius, padding, iconBackground, iconForeground, titleForeground, subtitleForeground, actionIconForeground, shadow, borderBottom."},message:{description:"Chat message bubbles.",user:"background, text, borderRadius, shadow.",assistant:"background, text, borderRadius, border (optional), shadow (optional)."},markdown:{description:"Markdown rendering in messages and artifact pane.",properties:"inlineCode (background, foreground), link.foreground, prose.fontFamily, heading.h1/h2 (fontSize, fontWeight)."},voice:"recording (indicator, background, border), processing (icon, background), speaking (icon).",approval:"requested (background, border, text), approve (background, foreground), deny (background, foreground).",attachment:"image (background, border).",scrollToBottom:"Floating scroll-to-bottom affordance shared by transcript and event stream: background, foreground, border, size, borderRadius, shadow, padding, gap, fontSize, iconSize.",toolBubble:"shadow \u2014 tool call row box-shadow.",reasoningBubble:"shadow \u2014 reasoning/thinking row box-shadow.",composer:"shadow \u2014 message input form box-shadow.",artifact:"toolbar (icon styling, copy menu), tab (background, active states), pane (background, toolbarBackground)."}},colorScheme:'"dark" merges darkTheme overrides on top of theme. "auto" detects system preference or <html class="dark">. "light" is default. colorScheme does NOT auto-invert colors \u2014 provide dark palette and semantic overrides yourself.',plugins:{description:"Plugins transform theme tokens before resolution. Use with createTheme().",available:{brandPlugin:'Auto-generates full color scales from a single brand hex: brandPlugin({ colors: { primary: "#7c3aed" } }).',accessibilityPlugin:"Enhanced focus indicators and disabled states.",highContrastPlugin:"Increased contrast for visual accessibility.",reducedMotionPlugin:"Disables all animations (sets transitions to 0ms).",animationsPlugin:"Adds transition and easing tokens."},usage:'createTheme(themeOverrides, { plugins: [brandPlugin({ colors: { primary: "#7c3aed" } })] })'},widgetConfig:{description:'Non-theme config options on the widget config object that affect appearance. These are siblings of "theme" in the config, not nested inside it.',launcher:{description:"Floating launcher button and panel positioning.",properties:{enabled:"Show/hide the launcher button.",title:"Header title text.",subtitle:"Header subtitle text.",position:'"bottom-right" | "bottom-left" | "top-right" | "top-left".',width:"Chat panel width (CSS value).",fullHeight:"Fill full height of container.",mountMode:'"floating" | "docked".',agentIconText:"Emoji/text for agent icon.",border:"Border style for launcher button.",shadow:"Box shadow for launcher button.",collapsedMaxWidth:"Max-width for launcher pill when panel closed."}},sendButton:{description:"Send button appearance.",properties:"backgroundColor, textColor, borderWidth, borderColor, paddingX, paddingY, iconText, iconName, size."},closeButton:{description:"Close button (on launcher config).",properties:"closeButtonSize, closeButtonColor, closeButtonBackgroundColor, closeButtonBorderWidth, closeButtonBorderColor, closeButtonBorderRadius."},clearChat:{description:"Clear chat button (on launcher.clearChat config).",properties:"enabled, iconColor, backgroundColor, borderWidth, borderColor, borderRadius, size."},scrollToBottom:{description:"Shared transcript + event-stream jump-to-latest affordance.",properties:'features.scrollToBottom.enabled, features.scrollToBottom.iconName, features.scrollToBottom.label (empty string renders icon-only). Defaults: enabled=true, iconName="arrow-down", label="".'},toolCall:{description:"Tool call display styling, text templates, loading animations, and rendering hooks. Text templates support placeholders ({toolName}, {duration}) and inline formatting (~dim~, *italic*, **bold**). renderCollapsedSummary receives elapsed (static string) and createElapsedElement() (live-updating span) in its context.",properties:"shadow, backgroundColor, borderColor, borderWidth, borderRadius, headerBackgroundColor, headerTextColor, headerPaddingX, headerPaddingY, contentBackgroundColor, contentTextColor, contentPaddingX, contentPaddingY, codeBlockBackgroundColor, codeBlockBorderColor, codeBlockTextColor, toggleTextColor, labelTextColor, activeTextTemplate, completeTextTemplate, loadingAnimationColor, loadingAnimationSecondaryColor, loadingAnimationDuration, renderCollapsedSummary, renderCollapsedPreview, renderGroupedSummary."},reasoning:{description:"Reasoning/thinking row rendering hooks.",properties:"renderCollapsedSummary, renderCollapsedPreview."},approval:{description:"Tool approval bubble styling and behavior. Set to false to disable.",properties:"backgroundColor, borderColor, titleColor, descriptionColor, approveButtonColor, approveButtonTextColor, denyButtonColor, denyButtonTextColor, parameterBackgroundColor, parameterTextColor, title, approveLabel, denyLabel."},copy:{description:"Widget text content.",properties:"showWelcomeCard (boolean), welcomeTitle, welcomeSubtitle, inputPlaceholder, sendButtonLabel."},voiceRecognition:{description:"Voice input configuration.",properties:"enabled, pauseDuration, iconColor, backgroundColor."},textToSpeech:{description:"Text-to-speech for assistant messages.",properties:'enabled, provider ("browser" | "runtype"), browserFallback, voice, rate, pitch.'},suggestionChips:"string[] \u2014 Suggested prompts shown to the user.",messageActions:{description:"Message action buttons (copy, upvote, downvote).",properties:'enabled, showCopy, showUpvote, showDownvote, visibility ("hover" | "always"), align ("left" | "center" | "right"), layout ("pill-inside" | "row-inside").'},attachments:{description:"File attachment configuration.",properties:"enabled, allowedTypes (string[]), maxFileSize (bytes), maxFiles, buttonIconName, buttonTooltipText."},markdown:{description:"Markdown rendering configuration.",properties:"options (gfm, breaks, headerIds, headerPrefix, pedantic, mangle, silent), disableDefaultStyles."},layout:{description:"Layout configuration.",showHeader:"boolean \u2014 show/hide the header section entirely.",showFooter:"boolean \u2014 show/hide the footer/composer section entirely.",contentMaxWidth:'CSS width value for centering content (e.g. "720px", "90ch").',header:'"default" | "minimal". Options: showIcon, showTitle, showSubtitle, showCloseButton, showClearChat.',messages:'"bubble" | "flat" | "minimal". Options: groupConsecutive, avatar (show, position, userAvatar, assistantAvatar), timestamp (show, position).'},statusIndicator:{description:"Status text shown below the composer.",properties:{visible:"Show/hide the status indicator.",align:'"left" | "center" | "right" \u2014 text alignment (default: "right").',idleText:'Text shown when idle (default: "Online").',idleLink:"URL to open when idle text is clicked (wraps text in a link).",connectingText:'Text shown while connecting (default: "Connecting\u2026").',connectedText:'Text shown while streaming (default: "Streaming\u2026").',errorText:'Text shown on error (default: "Offline").'}},features:{description:"Feature flags.",properties:"showReasoning (AI thinking steps), showToolCalls (tool invocations), toolCallDisplay (collapsedMode, activePreview, activeMinHeight, previewMaxLines, grouped, expandable, loadingAnimation), reasoningDisplay (activePreview, activeMinHeight, previewMaxLines, expandable), artifacts (sidebar config)."}}},p={darkIndigo:{description:"Dark mode with indigo accent \u2014 override grays for dark backgrounds and semantic tokens for inverted text/surface",theme:{palette:{colors:{primary:{500:"#6366f1",600:"#4f46e5"},gray:{50:"#f1f5f9",100:"#1e293b",200:"#334155",500:"#94a3b8",900:"#0f172a",950:"#020617"}}},semantic:{colors:{surface:"palette.colors.gray.900",background:"palette.colors.gray.900",container:"palette.colors.gray.100",text:"palette.colors.gray.50",textMuted:"palette.colors.gray.500",textInverse:"palette.colors.gray.900",border:"palette.colors.gray.200"}}}},warmVintage:{description:"Warm sepia tones with serif font and subtle radius",theme:{palette:{colors:{primary:{500:"#b45309",600:"#92400e"},gray:{50:"#fef3c7",100:"#fef9c3",200:"#d6d3d1",500:"#78716c",900:"#44403c"}},radius:{sm:"0.125rem",md:"0.25rem",lg:"0.375rem"},typography:{fontFamily:{sans:'Georgia, Cambria, "Times New Roman", Times, serif'}}}}},neonCyberpunk:{description:"Neon on dark with monospace font \u2014 full semantic override for dark background",theme:{palette:{colors:{primary:{500:"#f0abfc",600:"#e879f9"},accent:{500:"#22d3ee",600:"#06b6d4"},gray:{50:"#f0abfc",100:"#1e0a3c",200:"#3b0764",500:"#c084fc",900:"#0c0a1a",950:"#050412"}},radius:{sm:"0",md:"0.25rem",lg:"0.375rem"},typography:{fontFamily:{sans:"ui-monospace, SFMono-Regular, Menlo, monospace"}}},semantic:{colors:{surface:"palette.colors.gray.900",background:"palette.colors.gray.950",container:"palette.colors.gray.100",text:"palette.colors.gray.50",textMuted:"palette.colors.gray.500",border:"palette.colors.gray.200"}}}},cleanRounded:{description:"Clean light theme with large radius and panel styling",theme:{palette:{radius:{sm:"6px",md:"8px",lg:"12px",launcher:"50px",button:"8px"}},components:{panel:{borderRadius:"16px",shadow:"palette.shadows.2xl"}}}}};function b(){return{tokenDocs:i,defaultColorPalette:n.colors,defaultRadius:n.radius,examples:p,sdkPresets:["shop","minimal","fullscreen"]}}0&&(module.exports={THEME_EXAMPLES,THEME_TOKEN_DOCS,getThemeReference});
@@ -1 +1 @@
1
- var e={colors:{primary:{50:"#ffffff",100:"#f5f5f5",200:"#d4d4d4",300:"#a3a3a3",400:"#737373",500:"#171717",600:"#0f0f0f",700:"#0a0a0a",800:"#050505",900:"#030303",950:"#000000"},secondary:{50:"#f5f3ff",100:"#ede9fe",200:"#ddd6fe",300:"#c4b5fd",400:"#a78bfa",500:"#8b5cf6",600:"#7c3aed",700:"#6d28d9",800:"#5b21b6",900:"#4c1d95",950:"#2e1065"},accent:{50:"#ecfeff",100:"#cffafe",200:"#a5f3fc",300:"#67e8f9",400:"#22d3ee",500:"#06b6d4",600:"#0891b2",700:"#0e7490",800:"#155e75",900:"#164e63",950:"#083344"},gray:{50:"#f9fafb",100:"#f3f4f6",200:"#e5e7eb",300:"#d1d5db",400:"#9ca3af",500:"#6b7280",600:"#4b5563",700:"#374151",800:"#1f2937",900:"#111827",950:"#030712"},success:{50:"#f0fdf4",100:"#dcfce7",200:"#bbf7d0",300:"#86efac",400:"#4ade80",500:"#22c55e",600:"#16a34a",700:"#15803d",800:"#166534",900:"#14532d"},warning:{50:"#fefce8",100:"#fef9c3",200:"#fef08a",300:"#fde047",400:"#facc15",500:"#eab308",600:"#ca8a04",700:"#a16207",800:"#854d0e",900:"#713f12"},error:{50:"#fef2f2",100:"#fee2e2",200:"#fecaca",300:"#fca5a5",400:"#f87171",500:"#ef4444",600:"#dc2626",700:"#b91c1c",800:"#991b1b",900:"#7f1d1d"},info:{50:"#eff6ff",100:"#dbeafe",200:"#bfdbfe",300:"#93c5fd",400:"#60a5fa",500:"#3b82f6",600:"#2563eb",700:"#1d4ed8",800:"#1e40af",900:"#1e3a8a",950:"#172554"}},spacing:{0:"0px",1:"0.25rem",2:"0.5rem",3:"0.75rem",4:"1rem",5:"1.25rem",6:"1.5rem",8:"2rem",10:"2.5rem",12:"3rem",16:"4rem",20:"5rem",24:"6rem",32:"8rem",40:"10rem",48:"12rem",56:"14rem",64:"16rem"},typography:{fontFamily:{sans:'system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',serif:'Georgia, Cambria, "Times New Roman", Times, serif',mono:"ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace"},fontSize:{xs:"0.75rem",sm:"0.875rem",base:"1rem",lg:"1.125rem",xl:"1.25rem","2xl":"1.5rem","3xl":"1.875rem","4xl":"2.25rem"},fontWeight:{normal:"400",medium:"500",semibold:"600",bold:"700"},lineHeight:{tight:"1.25",normal:"1.5",relaxed:"1.625"}},shadows:{none:"none",sm:"0 1px 2px 0 rgb(0 0 0 / 0.05)",md:"0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1)",lg:"0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1)",xl:"0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1)","2xl":"0 25px 50px -12px rgb(0 0 0 / 0.25)"},borders:{none:"none",sm:"1px solid",md:"2px solid",lg:"4px solid"},radius:{none:"0px",sm:"0.125rem",md:"0.375rem",lg:"0.5rem",xl:"0.75rem","2xl":"1rem",full:"9999px"}};var o={overview:"Persona uses a three-layer design token system: palette \u2192 semantic \u2192 components. Most themes only need palette.colors overrides \u2014 semantic and component layers auto-derive from palette values. Config also accepts non-theme appearance options (launcher, sendButton, toolCall, etc.).",layers:{palette:{description:"Primitive design tokens. Override specific shades to change the entire widget feel.",colors:{description:"7 color scales, each with shades 50 (lightest) to 950 (darkest). Override only the shades you need.",scales:{gray:"Neutrals \u2014 backgrounds, text, borders. Key shades: 50 (lightest bg), 100 (secondary bg), 200 (borders), 500 (muted text), 900 (primary text).",primary:"Brand color \u2014 buttons, links, interactive elements. Key shades: 500 (default), 600 (hover).",accent:"Secondary highlight. Key shades: 500 (default), 600 (hover).",secondary:"Tertiary color scale.",success:"Positive feedback (default: green).",warning:"Caution feedback (default: yellow).",error:"Error/danger feedback (default: red)."}},radius:{description:"Border radius scale. Add custom keys like launcher, button.",defaults:{none:"0px",sm:"0.125rem",md:"0.375rem",lg:"0.5rem",xl:"0.75rem","2xl":"1rem",full:"9999px"}},typography:{fontFamily:"Three stacks: sans (system-ui), serif (Georgia), mono (ui-monospace). Override individual stack values.",fontSize:"Scale: xs (0.75rem), sm (0.875rem), base (1rem), lg (1.125rem), xl (1.25rem), 2xl (1.5rem), 3xl (1.875rem), 4xl (2.25rem).",fontWeight:"normal (400), medium (500), semibold (600), bold (700).",lineHeight:"tight (1.25), normal (1.5), relaxed (1.625)."},shadows:"Scale: none, sm, md, lg, xl, 2xl. Values are CSS box-shadow strings.",borders:"Scale: none, sm (1px solid), md (2px solid), lg (4px solid).",spacing:"Scale: 0 (0px), 1 (0.25rem), 2 (0.5rem), 3 (0.75rem), 4 (1rem), 5 (1.25rem), 6 (1.5rem), 8 (2rem), 10 (2.5rem), 12 (3rem), 16-64."},semantic:{description:'Design intent tokens. Auto-derived from palette by default. Override to redirect token resolution. Values are token reference strings like "palette.colors.primary.500".',colors:{primary:"palette.colors.primary.500 \u2014 Primary brand color.",secondary:"palette.colors.gray.500 \u2014 Secondary color.",accent:"palette.colors.primary.600 \u2014 Accent/interactive color.",surface:"palette.colors.gray.50 \u2014 Panel/card backgrounds.",background:"palette.colors.gray.50 \u2014 Page background.",container:"palette.colors.gray.100 \u2014 Container backgrounds.",text:"palette.colors.gray.900 \u2014 Primary text.",textMuted:"palette.colors.gray.500 \u2014 Muted/secondary text.",textInverse:"palette.colors.gray.50 \u2014 Text on dark backgrounds.",border:"palette.colors.gray.200 \u2014 Default border color.",divider:"palette.colors.gray.200 \u2014 Divider lines.",interactive:{default:"palette.colors.primary.500",hover:"palette.colors.primary.600",focus:"palette.colors.primary.700",active:"palette.colors.primary.800",disabled:"palette.colors.gray.300"},feedback:{success:"palette.colors.success.500",warning:"palette.colors.warning.500",error:"palette.colors.error.500",info:"palette.colors.primary.500"}},spacing:"xs (0.25rem), sm (0.5rem), md (1rem), lg (1.5rem), xl (2rem), 2xl (2.5rem).",typography:"fontFamily, fontSize, fontWeight, lineHeight \u2014 reference palette typography tokens."},components:{description:"UI element tokens. Rarely needed for basic theming. Override for fine-grained control. All values are token references or raw CSS strings.",button:{description:"Three variants: primary, secondary, ghost.",properties:"background, foreground, borderRadius, padding."},input:{description:"Message input field.",properties:"background, placeholder, borderRadius, padding, focus.border, focus.ring."},launcher:{description:"Floating launcher button.",properties:"size (60px), iconSize (28px), borderRadius, shadow."},panel:{description:"Chat panel container.",properties:"width, maxWidth (440px), height (600px), maxHeight, borderRadius, shadow."},header:{description:"Chat panel header.",properties:"background, border, borderRadius, padding, iconBackground, iconForeground, titleForeground, subtitleForeground, actionIconForeground, shadow, borderBottom."},message:{description:"Chat message bubbles.",user:"background, text, borderRadius, shadow.",assistant:"background, text, borderRadius, border (optional), shadow (optional)."},markdown:{description:"Markdown rendering in messages and artifact pane.",properties:"inlineCode (background, foreground), link.foreground, prose.fontFamily, heading.h1/h2 (fontSize, fontWeight)."},voice:"recording (indicator, background, border), processing (icon, background), speaking (icon).",approval:"requested (background, border, text), approve (background, foreground), deny (background, foreground).",attachment:"image (background, border).",scrollToBottom:"Floating scroll-to-bottom affordance shared by transcript and event stream: background, foreground, border, size, borderRadius, shadow, padding, gap, fontSize, iconSize.",toolBubble:"shadow \u2014 tool call row box-shadow.",reasoningBubble:"shadow \u2014 reasoning/thinking row box-shadow.",composer:"shadow \u2014 message input form box-shadow.",artifact:"toolbar (icon styling, copy menu), tab (background, active states), pane (background, toolbarBackground)."}},colorScheme:'"dark" merges darkTheme overrides on top of theme. "auto" detects system preference or <html class="dark">. "light" is default. colorScheme does NOT auto-invert colors \u2014 provide dark palette and semantic overrides yourself.',plugins:{description:"Plugins transform theme tokens before resolution. Use with createTheme().",available:{brandPlugin:'Auto-generates full color scales from a single brand hex: brandPlugin({ colors: { primary: "#7c3aed" } }).',accessibilityPlugin:"Enhanced focus indicators and disabled states.",highContrastPlugin:"Increased contrast for visual accessibility.",reducedMotionPlugin:"Disables all animations (sets transitions to 0ms).",animationsPlugin:"Adds transition and easing tokens."},usage:'createTheme(themeOverrides, { plugins: [brandPlugin({ colors: { primary: "#7c3aed" } })] })'},widgetConfig:{description:'Non-theme config options on the widget config object that affect appearance. These are siblings of "theme" in the config, not nested inside it.',launcher:{description:"Floating launcher button and panel positioning.",properties:{enabled:"Show/hide the launcher button.",title:"Header title text.",subtitle:"Header subtitle text.",position:'"bottom-right" | "bottom-left" | "top-right" | "top-left".',width:"Chat panel width (CSS value).",fullHeight:"Fill full height of container.",mountMode:'"floating" | "docked".',agentIconText:"Emoji/text for agent icon.",border:"Border style for launcher button.",shadow:"Box shadow for launcher button.",collapsedMaxWidth:"Max-width for launcher pill when panel closed."}},sendButton:{description:"Send button appearance.",properties:"backgroundColor, textColor, borderWidth, borderColor, paddingX, paddingY, iconText, iconName, size."},closeButton:{description:"Close button (on launcher config).",properties:"closeButtonSize, closeButtonColor, closeButtonBackgroundColor, closeButtonBorderWidth, closeButtonBorderColor, closeButtonBorderRadius."},clearChat:{description:"Clear chat button (on launcher.clearChat config).",properties:"enabled, iconColor, backgroundColor, borderWidth, borderColor, borderRadius, size."},scrollToBottom:{description:"Shared transcript + event-stream jump-to-latest affordance.",properties:'features.scrollToBottom.enabled, features.scrollToBottom.iconName, features.scrollToBottom.label (empty string renders icon-only). Defaults: enabled=true, iconName="arrow-down", label="".'},toolCall:{description:"Tool call display styling and collapsed/grouped rendering hooks.",properties:"shadow, backgroundColor, borderColor, borderWidth, borderRadius, headerBackgroundColor, headerTextColor, headerPaddingX, headerPaddingY, contentBackgroundColor, contentTextColor, contentPaddingX, contentPaddingY, codeBlockBackgroundColor, codeBlockBorderColor, codeBlockTextColor, toggleTextColor, labelTextColor, renderCollapsedSummary, renderCollapsedPreview, renderGroupedSummary."},reasoning:{description:"Reasoning/thinking row rendering hooks.",properties:"renderCollapsedSummary, renderCollapsedPreview."},approval:{description:"Tool approval bubble styling and behavior. Set to false to disable.",properties:"backgroundColor, borderColor, titleColor, descriptionColor, approveButtonColor, approveButtonTextColor, denyButtonColor, denyButtonTextColor, parameterBackgroundColor, parameterTextColor, title, approveLabel, denyLabel."},copy:{description:"Widget text content.",properties:"showWelcomeCard (boolean), welcomeTitle, welcomeSubtitle, inputPlaceholder, sendButtonLabel."},voiceRecognition:{description:"Voice input configuration.",properties:"enabled, pauseDuration, iconColor, backgroundColor."},textToSpeech:{description:"Text-to-speech for assistant messages.",properties:'enabled, provider ("browser" | "runtype"), browserFallback, voice, rate, pitch.'},suggestionChips:"string[] \u2014 Suggested prompts shown to the user.",messageActions:{description:"Message action buttons (copy, upvote, downvote).",properties:'enabled, showCopy, showUpvote, showDownvote, visibility ("hover" | "always"), align ("left" | "center" | "right"), layout ("pill-inside" | "row-inside").'},attachments:{description:"File attachment configuration.",properties:"enabled, allowedTypes (string[]), maxFileSize (bytes), maxFiles, buttonIconName, buttonTooltipText."},markdown:{description:"Markdown rendering configuration.",properties:"options (gfm, breaks, headerIds, headerPrefix, pedantic, mangle, silent), disableDefaultStyles."},layout:{description:"Layout configuration.",showHeader:"boolean \u2014 show/hide the header section entirely.",showFooter:"boolean \u2014 show/hide the footer/composer section entirely.",contentMaxWidth:'CSS width value for centering content (e.g. "720px", "90ch").',header:'"default" | "minimal". Options: showIcon, showTitle, showSubtitle, showCloseButton, showClearChat.',messages:'"bubble" | "flat" | "minimal". Options: groupConsecutive, avatar (show, position, userAvatar, assistantAvatar), timestamp (show, position).'},statusIndicator:{description:"Status text shown below the composer.",properties:{visible:"Show/hide the status indicator.",align:'"left" | "center" | "right" \u2014 text alignment (default: "right").',idleText:'Text shown when idle (default: "Online").',idleLink:"URL to open when idle text is clicked (wraps text in a link).",connectingText:'Text shown while connecting (default: "Connecting\u2026").',connectedText:'Text shown while streaming (default: "Streaming\u2026").',errorText:'Text shown on error (default: "Offline").'}},features:{description:"Feature flags.",properties:"showReasoning (AI thinking steps), showToolCalls (tool invocations), toolCallDisplay (collapsedMode, activePreview, activeMinHeight, previewMaxLines, grouped), reasoningDisplay (activePreview, activeMinHeight, previewMaxLines), artifacts (sidebar config)."}}},r={darkIndigo:{description:"Dark mode with indigo accent \u2014 override grays for dark backgrounds and semantic tokens for inverted text/surface",theme:{palette:{colors:{primary:{500:"#6366f1",600:"#4f46e5"},gray:{50:"#f1f5f9",100:"#1e293b",200:"#334155",500:"#94a3b8",900:"#0f172a",950:"#020617"}}},semantic:{colors:{surface:"palette.colors.gray.900",background:"palette.colors.gray.900",container:"palette.colors.gray.100",text:"palette.colors.gray.50",textMuted:"palette.colors.gray.500",textInverse:"palette.colors.gray.900",border:"palette.colors.gray.200"}}}},warmVintage:{description:"Warm sepia tones with serif font and subtle radius",theme:{palette:{colors:{primary:{500:"#b45309",600:"#92400e"},gray:{50:"#fef3c7",100:"#fef9c3",200:"#d6d3d1",500:"#78716c",900:"#44403c"}},radius:{sm:"0.125rem",md:"0.25rem",lg:"0.375rem"},typography:{fontFamily:{sans:'Georgia, Cambria, "Times New Roman", Times, serif'}}}}},neonCyberpunk:{description:"Neon on dark with monospace font \u2014 full semantic override for dark background",theme:{palette:{colors:{primary:{500:"#f0abfc",600:"#e879f9"},accent:{500:"#22d3ee",600:"#06b6d4"},gray:{50:"#f0abfc",100:"#1e0a3c",200:"#3b0764",500:"#c084fc",900:"#0c0a1a",950:"#050412"}},radius:{sm:"0",md:"0.25rem",lg:"0.375rem"},typography:{fontFamily:{sans:"ui-monospace, SFMono-Regular, Menlo, monospace"}}},semantic:{colors:{surface:"palette.colors.gray.900",background:"palette.colors.gray.950",container:"palette.colors.gray.100",text:"palette.colors.gray.50",textMuted:"palette.colors.gray.500",border:"palette.colors.gray.200"}}}},cleanRounded:{description:"Clean light theme with large radius and panel styling",theme:{palette:{radius:{sm:"6px",md:"8px",lg:"12px",launcher:"50px",button:"8px"}},components:{panel:{borderRadius:"16px",shadow:"palette.shadows.2xl"}}}}};function m(){return{tokenDocs:o,defaultColorPalette:e.colors,defaultRadius:e.radius,examples:r,sdkPresets:["shop","minimal","fullscreen"]}}export{r as THEME_EXAMPLES,o as THEME_TOKEN_DOCS,m as getThemeReference};
1
+ var e={colors:{primary:{50:"#ffffff",100:"#f5f5f5",200:"#d4d4d4",300:"#a3a3a3",400:"#737373",500:"#171717",600:"#0f0f0f",700:"#0a0a0a",800:"#050505",900:"#030303",950:"#000000"},secondary:{50:"#f5f3ff",100:"#ede9fe",200:"#ddd6fe",300:"#c4b5fd",400:"#a78bfa",500:"#8b5cf6",600:"#7c3aed",700:"#6d28d9",800:"#5b21b6",900:"#4c1d95",950:"#2e1065"},accent:{50:"#ecfeff",100:"#cffafe",200:"#a5f3fc",300:"#67e8f9",400:"#22d3ee",500:"#06b6d4",600:"#0891b2",700:"#0e7490",800:"#155e75",900:"#164e63",950:"#083344"},gray:{50:"#f9fafb",100:"#f3f4f6",200:"#e5e7eb",300:"#d1d5db",400:"#9ca3af",500:"#6b7280",600:"#4b5563",700:"#374151",800:"#1f2937",900:"#111827",950:"#030712"},success:{50:"#f0fdf4",100:"#dcfce7",200:"#bbf7d0",300:"#86efac",400:"#4ade80",500:"#22c55e",600:"#16a34a",700:"#15803d",800:"#166534",900:"#14532d"},warning:{50:"#fefce8",100:"#fef9c3",200:"#fef08a",300:"#fde047",400:"#facc15",500:"#eab308",600:"#ca8a04",700:"#a16207",800:"#854d0e",900:"#713f12"},error:{50:"#fef2f2",100:"#fee2e2",200:"#fecaca",300:"#fca5a5",400:"#f87171",500:"#ef4444",600:"#dc2626",700:"#b91c1c",800:"#991b1b",900:"#7f1d1d"},info:{50:"#eff6ff",100:"#dbeafe",200:"#bfdbfe",300:"#93c5fd",400:"#60a5fa",500:"#3b82f6",600:"#2563eb",700:"#1d4ed8",800:"#1e40af",900:"#1e3a8a",950:"#172554"}},spacing:{0:"0px",1:"0.25rem",2:"0.5rem",3:"0.75rem",4:"1rem",5:"1.25rem",6:"1.5rem",8:"2rem",10:"2.5rem",12:"3rem",16:"4rem",20:"5rem",24:"6rem",32:"8rem",40:"10rem",48:"12rem",56:"14rem",64:"16rem"},typography:{fontFamily:{sans:'system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',serif:'Georgia, Cambria, "Times New Roman", Times, serif',mono:"ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace"},fontSize:{xs:"0.75rem",sm:"0.875rem",base:"1rem",lg:"1.125rem",xl:"1.25rem","2xl":"1.5rem","3xl":"1.875rem","4xl":"2.25rem"},fontWeight:{normal:"400",medium:"500",semibold:"600",bold:"700"},lineHeight:{tight:"1.25",normal:"1.5",relaxed:"1.625"}},shadows:{none:"none",sm:"0 1px 2px 0 rgb(0 0 0 / 0.05)",md:"0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1)",lg:"0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1)",xl:"0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1)","2xl":"0 25px 50px -12px rgb(0 0 0 / 0.25)"},borders:{none:"none",sm:"1px solid",md:"2px solid",lg:"4px solid"},radius:{none:"0px",sm:"0.125rem",md:"0.375rem",lg:"0.5rem",xl:"0.75rem","2xl":"1rem",full:"9999px"}};var o={overview:"Persona uses a three-layer design token system: palette \u2192 semantic \u2192 components. Most themes only need palette.colors overrides \u2014 semantic and component layers auto-derive from palette values. Config also accepts non-theme appearance options (launcher, sendButton, toolCall, etc.).",layers:{palette:{description:"Primitive design tokens. Override specific shades to change the entire widget feel.",colors:{description:"7 color scales, each with shades 50 (lightest) to 950 (darkest). Override only the shades you need.",scales:{gray:"Neutrals \u2014 backgrounds, text, borders. Key shades: 50 (lightest bg), 100 (secondary bg), 200 (borders), 500 (muted text), 900 (primary text).",primary:"Brand color \u2014 buttons, links, interactive elements. Key shades: 500 (default), 600 (hover).",accent:"Secondary highlight. Key shades: 500 (default), 600 (hover).",secondary:"Tertiary color scale.",success:"Positive feedback (default: green).",warning:"Caution feedback (default: yellow).",error:"Error/danger feedback (default: red)."}},radius:{description:"Border radius scale. Add custom keys like launcher, button.",defaults:{none:"0px",sm:"0.125rem",md:"0.375rem",lg:"0.5rem",xl:"0.75rem","2xl":"1rem",full:"9999px"}},typography:{fontFamily:"Three stacks: sans (system-ui), serif (Georgia), mono (ui-monospace). Override individual stack values.",fontSize:"Scale: xs (0.75rem), sm (0.875rem), base (1rem), lg (1.125rem), xl (1.25rem), 2xl (1.5rem), 3xl (1.875rem), 4xl (2.25rem).",fontWeight:"normal (400), medium (500), semibold (600), bold (700).",lineHeight:"tight (1.25), normal (1.5), relaxed (1.625)."},shadows:"Scale: none, sm, md, lg, xl, 2xl. Values are CSS box-shadow strings.",borders:"Scale: none, sm (1px solid), md (2px solid), lg (4px solid).",spacing:"Scale: 0 (0px), 1 (0.25rem), 2 (0.5rem), 3 (0.75rem), 4 (1rem), 5 (1.25rem), 6 (1.5rem), 8 (2rem), 10 (2.5rem), 12 (3rem), 16-64."},semantic:{description:'Design intent tokens. Auto-derived from palette by default. Override to redirect token resolution. Values are token reference strings like "palette.colors.primary.500".',colors:{primary:"palette.colors.primary.500 \u2014 Primary brand color.",secondary:"palette.colors.gray.500 \u2014 Secondary color.",accent:"palette.colors.primary.600 \u2014 Accent/interactive color.",surface:"palette.colors.gray.50 \u2014 Panel/card backgrounds.",background:"palette.colors.gray.50 \u2014 Page background.",container:"palette.colors.gray.100 \u2014 Container backgrounds.",text:"palette.colors.gray.900 \u2014 Primary text.",textMuted:"palette.colors.gray.500 \u2014 Muted/secondary text.",textInverse:"palette.colors.gray.50 \u2014 Text on dark backgrounds.",border:"palette.colors.gray.200 \u2014 Default border color.",divider:"palette.colors.gray.200 \u2014 Divider lines.",interactive:{default:"palette.colors.primary.500",hover:"palette.colors.primary.600",focus:"palette.colors.primary.700",active:"palette.colors.primary.800",disabled:"palette.colors.gray.300"},feedback:{success:"palette.colors.success.500",warning:"palette.colors.warning.500",error:"palette.colors.error.500",info:"palette.colors.primary.500"}},spacing:"xs (0.25rem), sm (0.5rem), md (1rem), lg (1.5rem), xl (2rem), 2xl (2.5rem).",typography:"fontFamily, fontSize, fontWeight, lineHeight \u2014 reference palette typography tokens."},components:{description:"UI element tokens. Rarely needed for basic theming. Override for fine-grained control. All values are token references or raw CSS strings.",button:{description:"Three variants: primary, secondary, ghost.",properties:"background, foreground, borderRadius, padding."},input:{description:"Message input field.",properties:"background, placeholder, borderRadius, padding, focus.border, focus.ring."},launcher:{description:"Floating launcher button.",properties:"size (60px), iconSize (28px), borderRadius, shadow."},panel:{description:"Chat panel container.",properties:"width, maxWidth (440px), height (600px), maxHeight, borderRadius, shadow."},header:{description:"Chat panel header.",properties:"background, border, borderRadius, padding, iconBackground, iconForeground, titleForeground, subtitleForeground, actionIconForeground, shadow, borderBottom."},message:{description:"Chat message bubbles.",user:"background, text, borderRadius, shadow.",assistant:"background, text, borderRadius, border (optional), shadow (optional)."},markdown:{description:"Markdown rendering in messages and artifact pane.",properties:"inlineCode (background, foreground), link.foreground, prose.fontFamily, heading.h1/h2 (fontSize, fontWeight)."},voice:"recording (indicator, background, border), processing (icon, background), speaking (icon).",approval:"requested (background, border, text), approve (background, foreground), deny (background, foreground).",attachment:"image (background, border).",scrollToBottom:"Floating scroll-to-bottom affordance shared by transcript and event stream: background, foreground, border, size, borderRadius, shadow, padding, gap, fontSize, iconSize.",toolBubble:"shadow \u2014 tool call row box-shadow.",reasoningBubble:"shadow \u2014 reasoning/thinking row box-shadow.",composer:"shadow \u2014 message input form box-shadow.",artifact:"toolbar (icon styling, copy menu), tab (background, active states), pane (background, toolbarBackground)."}},colorScheme:'"dark" merges darkTheme overrides on top of theme. "auto" detects system preference or <html class="dark">. "light" is default. colorScheme does NOT auto-invert colors \u2014 provide dark palette and semantic overrides yourself.',plugins:{description:"Plugins transform theme tokens before resolution. Use with createTheme().",available:{brandPlugin:'Auto-generates full color scales from a single brand hex: brandPlugin({ colors: { primary: "#7c3aed" } }).',accessibilityPlugin:"Enhanced focus indicators and disabled states.",highContrastPlugin:"Increased contrast for visual accessibility.",reducedMotionPlugin:"Disables all animations (sets transitions to 0ms).",animationsPlugin:"Adds transition and easing tokens."},usage:'createTheme(themeOverrides, { plugins: [brandPlugin({ colors: { primary: "#7c3aed" } })] })'},widgetConfig:{description:'Non-theme config options on the widget config object that affect appearance. These are siblings of "theme" in the config, not nested inside it.',launcher:{description:"Floating launcher button and panel positioning.",properties:{enabled:"Show/hide the launcher button.",title:"Header title text.",subtitle:"Header subtitle text.",position:'"bottom-right" | "bottom-left" | "top-right" | "top-left".',width:"Chat panel width (CSS value).",fullHeight:"Fill full height of container.",mountMode:'"floating" | "docked".',agentIconText:"Emoji/text for agent icon.",border:"Border style for launcher button.",shadow:"Box shadow for launcher button.",collapsedMaxWidth:"Max-width for launcher pill when panel closed."}},sendButton:{description:"Send button appearance.",properties:"backgroundColor, textColor, borderWidth, borderColor, paddingX, paddingY, iconText, iconName, size."},closeButton:{description:"Close button (on launcher config).",properties:"closeButtonSize, closeButtonColor, closeButtonBackgroundColor, closeButtonBorderWidth, closeButtonBorderColor, closeButtonBorderRadius."},clearChat:{description:"Clear chat button (on launcher.clearChat config).",properties:"enabled, iconColor, backgroundColor, borderWidth, borderColor, borderRadius, size."},scrollToBottom:{description:"Shared transcript + event-stream jump-to-latest affordance.",properties:'features.scrollToBottom.enabled, features.scrollToBottom.iconName, features.scrollToBottom.label (empty string renders icon-only). Defaults: enabled=true, iconName="arrow-down", label="".'},toolCall:{description:"Tool call display styling, text templates, loading animations, and rendering hooks. Text templates support placeholders ({toolName}, {duration}) and inline formatting (~dim~, *italic*, **bold**). renderCollapsedSummary receives elapsed (static string) and createElapsedElement() (live-updating span) in its context.",properties:"shadow, backgroundColor, borderColor, borderWidth, borderRadius, headerBackgroundColor, headerTextColor, headerPaddingX, headerPaddingY, contentBackgroundColor, contentTextColor, contentPaddingX, contentPaddingY, codeBlockBackgroundColor, codeBlockBorderColor, codeBlockTextColor, toggleTextColor, labelTextColor, activeTextTemplate, completeTextTemplate, loadingAnimationColor, loadingAnimationSecondaryColor, loadingAnimationDuration, renderCollapsedSummary, renderCollapsedPreview, renderGroupedSummary."},reasoning:{description:"Reasoning/thinking row rendering hooks.",properties:"renderCollapsedSummary, renderCollapsedPreview."},approval:{description:"Tool approval bubble styling and behavior. Set to false to disable.",properties:"backgroundColor, borderColor, titleColor, descriptionColor, approveButtonColor, approveButtonTextColor, denyButtonColor, denyButtonTextColor, parameterBackgroundColor, parameterTextColor, title, approveLabel, denyLabel."},copy:{description:"Widget text content.",properties:"showWelcomeCard (boolean), welcomeTitle, welcomeSubtitle, inputPlaceholder, sendButtonLabel."},voiceRecognition:{description:"Voice input configuration.",properties:"enabled, pauseDuration, iconColor, backgroundColor."},textToSpeech:{description:"Text-to-speech for assistant messages.",properties:'enabled, provider ("browser" | "runtype"), browserFallback, voice, rate, pitch.'},suggestionChips:"string[] \u2014 Suggested prompts shown to the user.",messageActions:{description:"Message action buttons (copy, upvote, downvote).",properties:'enabled, showCopy, showUpvote, showDownvote, visibility ("hover" | "always"), align ("left" | "center" | "right"), layout ("pill-inside" | "row-inside").'},attachments:{description:"File attachment configuration.",properties:"enabled, allowedTypes (string[]), maxFileSize (bytes), maxFiles, buttonIconName, buttonTooltipText."},markdown:{description:"Markdown rendering configuration.",properties:"options (gfm, breaks, headerIds, headerPrefix, pedantic, mangle, silent), disableDefaultStyles."},layout:{description:"Layout configuration.",showHeader:"boolean \u2014 show/hide the header section entirely.",showFooter:"boolean \u2014 show/hide the footer/composer section entirely.",contentMaxWidth:'CSS width value for centering content (e.g. "720px", "90ch").',header:'"default" | "minimal". Options: showIcon, showTitle, showSubtitle, showCloseButton, showClearChat.',messages:'"bubble" | "flat" | "minimal". Options: groupConsecutive, avatar (show, position, userAvatar, assistantAvatar), timestamp (show, position).'},statusIndicator:{description:"Status text shown below the composer.",properties:{visible:"Show/hide the status indicator.",align:'"left" | "center" | "right" \u2014 text alignment (default: "right").',idleText:'Text shown when idle (default: "Online").',idleLink:"URL to open when idle text is clicked (wraps text in a link).",connectingText:'Text shown while connecting (default: "Connecting\u2026").',connectedText:'Text shown while streaming (default: "Streaming\u2026").',errorText:'Text shown on error (default: "Offline").'}},features:{description:"Feature flags.",properties:"showReasoning (AI thinking steps), showToolCalls (tool invocations), toolCallDisplay (collapsedMode, activePreview, activeMinHeight, previewMaxLines, grouped, expandable, loadingAnimation), reasoningDisplay (activePreview, activeMinHeight, previewMaxLines, expandable), artifacts (sidebar config)."}}},r={darkIndigo:{description:"Dark mode with indigo accent \u2014 override grays for dark backgrounds and semantic tokens for inverted text/surface",theme:{palette:{colors:{primary:{500:"#6366f1",600:"#4f46e5"},gray:{50:"#f1f5f9",100:"#1e293b",200:"#334155",500:"#94a3b8",900:"#0f172a",950:"#020617"}}},semantic:{colors:{surface:"palette.colors.gray.900",background:"palette.colors.gray.900",container:"palette.colors.gray.100",text:"palette.colors.gray.50",textMuted:"palette.colors.gray.500",textInverse:"palette.colors.gray.900",border:"palette.colors.gray.200"}}}},warmVintage:{description:"Warm sepia tones with serif font and subtle radius",theme:{palette:{colors:{primary:{500:"#b45309",600:"#92400e"},gray:{50:"#fef3c7",100:"#fef9c3",200:"#d6d3d1",500:"#78716c",900:"#44403c"}},radius:{sm:"0.125rem",md:"0.25rem",lg:"0.375rem"},typography:{fontFamily:{sans:'Georgia, Cambria, "Times New Roman", Times, serif'}}}}},neonCyberpunk:{description:"Neon on dark with monospace font \u2014 full semantic override for dark background",theme:{palette:{colors:{primary:{500:"#f0abfc",600:"#e879f9"},accent:{500:"#22d3ee",600:"#06b6d4"},gray:{50:"#f0abfc",100:"#1e0a3c",200:"#3b0764",500:"#c084fc",900:"#0c0a1a",950:"#050412"}},radius:{sm:"0",md:"0.25rem",lg:"0.375rem"},typography:{fontFamily:{sans:"ui-monospace, SFMono-Regular, Menlo, monospace"}}},semantic:{colors:{surface:"palette.colors.gray.900",background:"palette.colors.gray.950",container:"palette.colors.gray.100",text:"palette.colors.gray.50",textMuted:"palette.colors.gray.500",border:"palette.colors.gray.200"}}}},cleanRounded:{description:"Clean light theme with large radius and panel styling",theme:{palette:{radius:{sm:"6px",md:"8px",lg:"12px",launcher:"50px",button:"8px"}},components:{panel:{borderRadius:"16px",shadow:"palette.shadows.2xl"}}}}};function m(){return{tokenDocs:o,defaultColorPalette:e.colors,defaultRadius:e.radius,examples:r,sdkPresets:["shop","minimal","fullscreen"]}}export{r as THEME_EXAMPLES,o as THEME_TOKEN_DOCS,m as getThemeReference};
package/dist/widget.css CHANGED
@@ -93,6 +93,35 @@
93
93
  gap: 1.5rem;
94
94
  }
95
95
 
96
+ [data-persona-root] .persona-widget-container .persona-attachment-drop-overlay {
97
+ display: none;
98
+ position: absolute;
99
+ inset: var(--persona-drop-overlay-inset, 0);
100
+ z-index: 50;
101
+ flex-direction: column;
102
+ align-items: center;
103
+ justify-content: center;
104
+ gap: 0.5rem;
105
+ pointer-events: none;
106
+ background: var(--persona-drop-overlay-bg, rgba(59, 130, 246, 0.08));
107
+ -webkit-backdrop-filter: blur(var(--persona-drop-overlay-blur, 8px));
108
+ backdrop-filter: blur(var(--persona-drop-overlay-blur, 8px));
109
+ border: var(--persona-drop-overlay-border, 2px dashed rgba(59, 130, 246, 0.4));
110
+ border-radius: var(--persona-drop-overlay-radius, inherit);
111
+ transition: opacity 0.15s ease;
112
+ }
113
+
114
+ [data-persona-root] .persona-widget-container .persona-attachment-drop-overlay .persona-drop-overlay-label {
115
+ font-size: var(--persona-drop-overlay-label-size, 0.875rem);
116
+ color: var(--persona-drop-overlay-label-color, rgba(59, 130, 246, 0.8));
117
+ font-weight: 500;
118
+ user-select: none;
119
+ }
120
+
121
+ [data-persona-root] .persona-widget-container.persona-attachment-drop-active .persona-attachment-drop-overlay {
122
+ display: flex;
123
+ }
124
+
96
125
  /* Widget CSS Variables - scoped to widget root to avoid polluting global namespace */
97
126
  [data-persona-root] {
98
127
  --persona-radius-sm: 0.125rem;
@@ -935,6 +964,7 @@
935
964
  }
936
965
 
937
966
  .persona-widget-container {
967
+ position: relative;
938
968
  border-radius: var(--persona-panel-radius, var(--persona-radius-xl, 0.75rem));
939
969
  }
940
970
 
@@ -1190,6 +1220,86 @@
1190
1220
  box-shadow: var(--persona-tool-bubble-shadow, 0 5px 15px rgba(15, 23, 42, 0.08));
1191
1221
  }
1192
1222
 
1223
+ /* ==============================
1224
+ Tool call loading animations
1225
+ ============================== */
1226
+
1227
+ /* Inline formatting classes for template text */
1228
+ [data-persona-root] .persona-tool-text-dim {
1229
+ opacity: 0.5;
1230
+ }
1231
+ [data-persona-root] .persona-tool-text-bold {
1232
+ font-weight: 600;
1233
+ }
1234
+ [data-persona-root] .persona-tool-text-italic {
1235
+ font-style: italic;
1236
+ }
1237
+
1238
+ /* Pulse mode: entire text element pulses opacity */
1239
+ @keyframes persona-tool-loading-pulse {
1240
+ 0%, 100% { opacity: 1; }
1241
+ 50% { opacity: 0.4; }
1242
+ }
1243
+
1244
+ [data-persona-root] .persona-tool-loading-pulse {
1245
+ animation: persona-tool-loading-pulse var(--persona-tool-anim-duration, 2s) ease-in-out infinite;
1246
+ }
1247
+
1248
+ /* Shimmer mode: monochrome brightness sweep per character */
1249
+ @keyframes persona-tool-loading-shimmer {
1250
+ 0%, 100% { opacity: 0.4; }
1251
+ 50% { opacity: 1; }
1252
+ }
1253
+
1254
+ [data-persona-root] .persona-tool-loading-shimmer .persona-tool-char {
1255
+ display: inline-block;
1256
+ animation: persona-tool-loading-shimmer var(--persona-tool-anim-duration, 2s) ease-in-out infinite;
1257
+ animation-delay: calc(var(--char-index, 0) * 60ms);
1258
+ }
1259
+
1260
+ /* Shimmer-color mode: color gradient sweep per character */
1261
+ @keyframes persona-tool-loading-shimmer-color {
1262
+ 0%, 100% {
1263
+ color: var(--persona-tool-anim-color, currentColor);
1264
+ }
1265
+ 50% {
1266
+ color: var(--persona-tool-anim-secondary-color, #3b82f6);
1267
+ }
1268
+ }
1269
+
1270
+ [data-persona-root] .persona-tool-loading-shimmer-color .persona-tool-char {
1271
+ display: inline-block;
1272
+ animation: persona-tool-loading-shimmer-color var(--persona-tool-anim-duration, 2s) ease-in-out infinite;
1273
+ animation-delay: calc(var(--char-index, 0) * 60ms);
1274
+ }
1275
+
1276
+ /* Rainbow mode: hue rotation per character */
1277
+ @keyframes persona-tool-loading-rainbow {
1278
+ 0% { color: #ef4444; }
1279
+ 16% { color: #f59e0b; }
1280
+ 33% { color: #22c55e; }
1281
+ 50% { color: #06b6d4; }
1282
+ 66% { color: #3b82f6; }
1283
+ 83% { color: #8b5cf6; }
1284
+ 100% { color: #ef4444; }
1285
+ }
1286
+
1287
+ [data-persona-root] .persona-tool-loading-rainbow .persona-tool-char {
1288
+ display: inline-block;
1289
+ animation: persona-tool-loading-rainbow var(--persona-tool-anim-duration, 2s) linear infinite;
1290
+ animation-delay: calc(var(--char-index, 0) * 80ms);
1291
+ }
1292
+
1293
+ /* Prefers-reduced-motion: disable all tool loading animations */
1294
+ @media (prefers-reduced-motion: reduce) {
1295
+ [data-persona-root] .persona-tool-loading-pulse,
1296
+ [data-persona-root] .persona-tool-loading-shimmer .persona-tool-char,
1297
+ [data-persona-root] .persona-tool-loading-shimmer-color .persona-tool-char,
1298
+ [data-persona-root] .persona-tool-loading-rainbow .persona-tool-char {
1299
+ animation: none !important;
1300
+ }
1301
+ }
1302
+
1193
1303
  [data-persona-root] .persona-reasoning-bubble.persona-shadow-sm {
1194
1304
  box-shadow: var(--persona-reasoning-bubble-shadow, 0 5px 15px rgba(15, 23, 42, 0.08));
1195
1305
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@runtypelabs/persona",
3
- "version": "3.10.0",
3
+ "version": "3.11.0",
4
4
  "description": "Themeable, pluggable streaming agent widget for websites, in plain JS with support for voice input and reasoning / tool output.",
5
5
  "type": "module",
6
6
  "main": "dist/index.cjs",
@@ -1,11 +1,12 @@
1
1
  import { createElement } from "../utils/dom";
2
2
  import { AgentWidgetMessage, AgentWidgetConfig } from "../types";
3
- import { formatUnknownValue, describeToolTitle } from "../utils/formatting";
3
+ import { formatUnknownValue, describeToolTitle, resolveToolHeaderText, computeToolElapsed, parseFormattedTemplate } from "../utils/formatting";
4
4
  import { renderLucideIcon } from "../utils/icons";
5
5
 
6
6
  // Expansion state per widget instance
7
7
  export const toolExpansionState = new Set<string>();
8
8
 
9
+
9
10
  const appendRenderedValue = (
10
11
  container: HTMLElement,
11
12
  value: HTMLElement | string | null | undefined
@@ -59,6 +60,7 @@ const getToolSummaryText = (
59
60
  }
60
61
 
61
62
  const isActive = tool.status !== "complete";
63
+ const toolCallConfig = config?.toolCall ?? {};
62
64
  let summary = defaultSummary;
63
65
  if (collapsedMode === "tool-name") {
64
66
  summary = tool.name?.trim() || defaultSummary;
@@ -66,6 +68,13 @@ const getToolSummaryText = (
66
68
  summary = previewText;
67
69
  }
68
70
 
71
+ // Apply text templates if configured
72
+ if (isActive && toolCallConfig.activeTextTemplate) {
73
+ summary = resolveToolHeaderText(tool, toolCallConfig.activeTextTemplate, summary);
74
+ } else if (!isActive && toolCallConfig.completeTextTemplate) {
75
+ summary = resolveToolHeaderText(tool, toolCallConfig.completeTextTemplate, summary);
76
+ }
77
+
69
78
  return { summary, previewText, isActive };
70
79
  };
71
80
 
@@ -151,6 +160,7 @@ export const createToolBubble = (message: AgentWidgetMessage, config?: AgentWidg
151
160
  const expandable = toolDisplayConfig.expandable !== false;
152
161
  let expanded = expandable && toolExpansionState.has(message.id);
153
162
  const { summary, previewText, isActive } = getToolSummaryText(message, config);
163
+
154
164
  const header = createElement(
155
165
  "button",
156
166
  expandable
@@ -182,6 +192,18 @@ export const createToolBubble = (message: AgentWidgetMessage, config?: AgentWidg
182
192
  if (toolCallConfig.headerTextColor) {
183
193
  title.style.color = toolCallConfig.headerTextColor;
184
194
  }
195
+
196
+ // Elapsed helpers — defined early so they're available to renderCollapsedSummary
197
+ const startedAt = String(tool.startedAt ?? Date.now());
198
+
199
+ // Helper: build a <span data-tool-elapsed> that the global timer in ui.ts updates
200
+ const createElapsedSpan = (): HTMLElement => {
201
+ const span = createElement("span", "");
202
+ span.setAttribute("data-tool-elapsed", startedAt);
203
+ span.textContent = computeToolElapsed(tool);
204
+ return span;
205
+ };
206
+
185
207
  const customSummary = toolCallConfig.renderCollapsedSummary?.({
186
208
  message,
187
209
  toolCall: tool,
@@ -190,6 +212,8 @@ export const createToolBubble = (message: AgentWidgetMessage, config?: AgentWidg
190
212
  collapsedMode: toolDisplayConfig.collapsedMode ?? "tool-call",
191
213
  isActive,
192
214
  config: config ?? {},
215
+ elapsed: computeToolElapsed(tool),
216
+ createElapsedElement: createElapsedSpan,
193
217
  });
194
218
  if (typeof customSummary === "string" && customSummary.trim()) {
195
219
  title.textContent = customSummary;
@@ -201,6 +225,102 @@ export const createToolBubble = (message: AgentWidgetMessage, config?: AgentWidg
201
225
  headerContent.appendChild(title);
202
226
  }
203
227
 
228
+ // Apply loading animation when tool is active and no custom HTMLElement was provided
229
+ const loadingAnimation = toolDisplayConfig.loadingAnimation ?? "none";
230
+ const activeTemplate = toolCallConfig.activeTextTemplate;
231
+ const completeTemplate = toolCallConfig.completeTextTemplate;
232
+ const currentTemplate = isActive ? activeTemplate : completeTemplate;
233
+ const skipCustomElement = customSummary instanceof HTMLElement;
234
+
235
+ // Helper: append text as individual animated character spans
236
+ const appendCharSpans = (container: HTMLElement, text: string, startIndex: number): number => {
237
+ let idx = startIndex;
238
+ for (const char of text) {
239
+ const span = createElement("span", "persona-tool-char");
240
+ span.style.setProperty("--char-index", String(idx));
241
+ span.textContent = char === " " ? "\u00A0" : char;
242
+ container.appendChild(span);
243
+ idx++;
244
+ }
245
+ return idx;
246
+ };
247
+
248
+ /**
249
+ * Renders a template into the title element, handling:
250
+ * - Inline formatting markers: **bold**, *italic*, ~dim~
251
+ * - {duration} as a live-updating elapsed span (active) or static text (complete)
252
+ * - Character-by-character animation wrapping when `animated` is true
253
+ */
254
+ const renderFormattedTitle = (template: string, animated: boolean) => {
255
+ title.textContent = "";
256
+ const toolName = tool.name?.trim() || "tool";
257
+ const segments = parseFormattedTemplate(template, toolName);
258
+ let charIndex = 0;
259
+
260
+ for (const seg of segments) {
261
+ // Determine parent: wrap in a styled span if formatting is present
262
+ const parent = seg.styles.length > 0
263
+ ? (() => {
264
+ const w = createElement("span", seg.styles.map(s => `persona-tool-text-${s}`).join(" "));
265
+ title.appendChild(w);
266
+ return w;
267
+ })()
268
+ : title;
269
+
270
+ if (seg.isDuration && isActive) {
271
+ // Live-updating elapsed span for active tools
272
+ parent.appendChild(createElapsedSpan());
273
+ } else {
274
+ // Static text (or resolved duration for completed tools)
275
+ const text = seg.isDuration ? computeToolElapsed(tool) : seg.text;
276
+ if (animated) {
277
+ charIndex = appendCharSpans(parent, text, charIndex);
278
+ } else {
279
+ parent.appendChild(document.createTextNode(text));
280
+ }
281
+ }
282
+ }
283
+ };
284
+
285
+ if (!skipCustomElement) {
286
+ if (isActive && loadingAnimation !== "none") {
287
+ const animDuration = toolCallConfig.loadingAnimationDuration ?? 2000;
288
+ title.setAttribute("data-preserve-animation", "true");
289
+
290
+ if (loadingAnimation === "pulse") {
291
+ title.classList.add("persona-tool-loading-pulse");
292
+ title.style.setProperty("--persona-tool-anim-duration", `${animDuration}ms`);
293
+ if (currentTemplate) {
294
+ renderFormattedTitle(currentTemplate, false);
295
+ }
296
+ } else {
297
+ // Character-by-character modes: shimmer, shimmer-color, rainbow
298
+ title.classList.add(`persona-tool-loading-${loadingAnimation}`);
299
+ title.style.setProperty("--persona-tool-anim-duration", `${animDuration}ms`);
300
+
301
+ if (loadingAnimation === "shimmer-color") {
302
+ if (toolCallConfig.loadingAnimationColor) {
303
+ title.style.setProperty("--persona-tool-anim-color", toolCallConfig.loadingAnimationColor);
304
+ }
305
+ if (toolCallConfig.loadingAnimationSecondaryColor) {
306
+ title.style.setProperty("--persona-tool-anim-secondary-color", toolCallConfig.loadingAnimationSecondaryColor);
307
+ }
308
+ }
309
+
310
+ if (currentTemplate) {
311
+ renderFormattedTitle(currentTemplate, true);
312
+ } else {
313
+ const text = title.textContent || summary;
314
+ title.textContent = "";
315
+ appendCharSpans(title, text, 0);
316
+ }
317
+ }
318
+ } else if (currentTemplate) {
319
+ // Template with formatting but no animation (or completed tool)
320
+ renderFormattedTitle(currentTemplate, false);
321
+ }
322
+ }
323
+
204
324
  let toggleIcon: HTMLElement | null = null;
205
325
  if (expandable) {
206
326
  toggleIcon = createElement("div", "persona-flex persona-items-center");
package/src/defaults.ts CHANGED
@@ -123,6 +123,7 @@ export const DEFAULT_WIDGET_CONFIG: Partial<AgentWidgetConfig> = {
123
123
  grouped: false,
124
124
  previewMaxLines: 3,
125
125
  expandable: true,
126
+ loadingAnimation: "none",
126
127
  },
127
128
  reasoningDisplay: {
128
129
  activePreview: false,
@@ -93,6 +93,35 @@
93
93
  gap: 1.5rem;
94
94
  }
95
95
 
96
+ [data-persona-root] .persona-widget-container .persona-attachment-drop-overlay {
97
+ display: none;
98
+ position: absolute;
99
+ inset: var(--persona-drop-overlay-inset, 0);
100
+ z-index: 50;
101
+ flex-direction: column;
102
+ align-items: center;
103
+ justify-content: center;
104
+ gap: 0.5rem;
105
+ pointer-events: none;
106
+ background: var(--persona-drop-overlay-bg, rgba(59, 130, 246, 0.08));
107
+ -webkit-backdrop-filter: blur(var(--persona-drop-overlay-blur, 8px));
108
+ backdrop-filter: blur(var(--persona-drop-overlay-blur, 8px));
109
+ border: var(--persona-drop-overlay-border, 2px dashed rgba(59, 130, 246, 0.4));
110
+ border-radius: var(--persona-drop-overlay-radius, inherit);
111
+ transition: opacity 0.15s ease;
112
+ }
113
+
114
+ [data-persona-root] .persona-widget-container .persona-attachment-drop-overlay .persona-drop-overlay-label {
115
+ font-size: var(--persona-drop-overlay-label-size, 0.875rem);
116
+ color: var(--persona-drop-overlay-label-color, rgba(59, 130, 246, 0.8));
117
+ font-weight: 500;
118
+ user-select: none;
119
+ }
120
+
121
+ [data-persona-root] .persona-widget-container.persona-attachment-drop-active .persona-attachment-drop-overlay {
122
+ display: flex;
123
+ }
124
+
96
125
  /* Widget CSS Variables - scoped to widget root to avoid polluting global namespace */
97
126
  [data-persona-root] {
98
127
  --persona-radius-sm: 0.125rem;
@@ -935,6 +964,7 @@
935
964
  }
936
965
 
937
966
  .persona-widget-container {
967
+ position: relative;
938
968
  border-radius: var(--persona-panel-radius, var(--persona-radius-xl, 0.75rem));
939
969
  }
940
970
 
@@ -1190,6 +1220,86 @@
1190
1220
  box-shadow: var(--persona-tool-bubble-shadow, 0 5px 15px rgba(15, 23, 42, 0.08));
1191
1221
  }
1192
1222
 
1223
+ /* ==============================
1224
+ Tool call loading animations
1225
+ ============================== */
1226
+
1227
+ /* Inline formatting classes for template text */
1228
+ [data-persona-root] .persona-tool-text-dim {
1229
+ opacity: 0.5;
1230
+ }
1231
+ [data-persona-root] .persona-tool-text-bold {
1232
+ font-weight: 600;
1233
+ }
1234
+ [data-persona-root] .persona-tool-text-italic {
1235
+ font-style: italic;
1236
+ }
1237
+
1238
+ /* Pulse mode: entire text element pulses opacity */
1239
+ @keyframes persona-tool-loading-pulse {
1240
+ 0%, 100% { opacity: 1; }
1241
+ 50% { opacity: 0.4; }
1242
+ }
1243
+
1244
+ [data-persona-root] .persona-tool-loading-pulse {
1245
+ animation: persona-tool-loading-pulse var(--persona-tool-anim-duration, 2s) ease-in-out infinite;
1246
+ }
1247
+
1248
+ /* Shimmer mode: monochrome brightness sweep per character */
1249
+ @keyframes persona-tool-loading-shimmer {
1250
+ 0%, 100% { opacity: 0.4; }
1251
+ 50% { opacity: 1; }
1252
+ }
1253
+
1254
+ [data-persona-root] .persona-tool-loading-shimmer .persona-tool-char {
1255
+ display: inline-block;
1256
+ animation: persona-tool-loading-shimmer var(--persona-tool-anim-duration, 2s) ease-in-out infinite;
1257
+ animation-delay: calc(var(--char-index, 0) * 60ms);
1258
+ }
1259
+
1260
+ /* Shimmer-color mode: color gradient sweep per character */
1261
+ @keyframes persona-tool-loading-shimmer-color {
1262
+ 0%, 100% {
1263
+ color: var(--persona-tool-anim-color, currentColor);
1264
+ }
1265
+ 50% {
1266
+ color: var(--persona-tool-anim-secondary-color, #3b82f6);
1267
+ }
1268
+ }
1269
+
1270
+ [data-persona-root] .persona-tool-loading-shimmer-color .persona-tool-char {
1271
+ display: inline-block;
1272
+ animation: persona-tool-loading-shimmer-color var(--persona-tool-anim-duration, 2s) ease-in-out infinite;
1273
+ animation-delay: calc(var(--char-index, 0) * 60ms);
1274
+ }
1275
+
1276
+ /* Rainbow mode: hue rotation per character */
1277
+ @keyframes persona-tool-loading-rainbow {
1278
+ 0% { color: #ef4444; }
1279
+ 16% { color: #f59e0b; }
1280
+ 33% { color: #22c55e; }
1281
+ 50% { color: #06b6d4; }
1282
+ 66% { color: #3b82f6; }
1283
+ 83% { color: #8b5cf6; }
1284
+ 100% { color: #ef4444; }
1285
+ }
1286
+
1287
+ [data-persona-root] .persona-tool-loading-rainbow .persona-tool-char {
1288
+ display: inline-block;
1289
+ animation: persona-tool-loading-rainbow var(--persona-tool-anim-duration, 2s) linear infinite;
1290
+ animation-delay: calc(var(--char-index, 0) * 80ms);
1291
+ }
1292
+
1293
+ /* Prefers-reduced-motion: disable all tool loading animations */
1294
+ @media (prefers-reduced-motion: reduce) {
1295
+ [data-persona-root] .persona-tool-loading-pulse,
1296
+ [data-persona-root] .persona-tool-loading-shimmer .persona-tool-char,
1297
+ [data-persona-root] .persona-tool-loading-shimmer-color .persona-tool-char,
1298
+ [data-persona-root] .persona-tool-loading-rainbow .persona-tool-char {
1299
+ animation: none !important;
1300
+ }
1301
+ }
1302
+
1193
1303
  [data-persona-root] .persona-reasoning-bubble.persona-shadow-sm {
1194
1304
  box-shadow: var(--persona-reasoning-bubble-shadow, 0 5px 15px rgba(15, 23, 42, 0.08));
1195
1305
  }