diff --git a/libs/chat/package.json b/libs/chat/package.json index 0153f1439..a28577eb7 100644 --- a/libs/chat/package.json +++ b/libs/chat/package.json @@ -1,6 +1,6 @@ { "name": "@ngaf/chat", - "version": "0.0.12", + "version": "0.0.13", "exports": { ".": { "types": "./index.d.ts", diff --git a/libs/chat/src/lib/styles/chat-message.styles.ts b/libs/chat/src/lib/styles/chat-message.styles.ts index b0a54039c..1f9f556ad 100644 --- a/libs/chat/src/lib/styles/chat-message.styles.ts +++ b/libs/chat/src/lib/styles/chat-message.styles.ts @@ -41,13 +41,19 @@ export const CHAT_MESSAGE_STYLES = ` margin-left: 2px; margin-top: 0.25rem; color: var(--ngaf-chat-text-muted); - /* Smooth pulse curve (copilotkit-style) — easier on the eyes than a - hard step-end blink, especially during long streams. */ - animation: ngaf-chat-pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite; vertical-align: text-bottom; } :host([data-role="assistant"][data-current="true"][data-streaming="true"]) .chat-message__caret { display: inline-block; + /* The caret is suppressed for the first 300ms of streaming so quick + responses (one-or-two-token "hello"-style replies) never flash the + cursor. Past 300ms the smooth pulse takes over (copilotkit-style) + — easier on the eyes than a hard blink during long streams. + Note: animations restart whenever the element is created/inserted, + so this delay re-applies on every new streaming message. */ + opacity: 0; + animation: ngaf-chat-caret-fade-in 200ms ease-out 300ms forwards, + ngaf-chat-pulse 2s cubic-bezier(0.4, 0, 0.6, 1) 500ms infinite; } .chat-message__plain { /* system / tool fallback */ } diff --git a/libs/chat/src/lib/styles/chat-tokens.ts b/libs/chat/src/lib/styles/chat-tokens.ts index a78191215..1dae6e800 100644 --- a/libs/chat/src/lib/styles/chat-tokens.ts +++ b/libs/chat/src/lib/styles/chat-tokens.ts @@ -86,6 +86,10 @@ const KEYFRAMES = ` 0%, 50% { opacity: 1; } 50.01%, 100% { opacity: 0; } } + @keyframes ngaf-chat-caret-fade-in { + from { opacity: 0; } + to { opacity: 1; } + } `; /** diff --git a/libs/chat/src/lib/styles/chat-typing-indicator.styles.ts b/libs/chat/src/lib/styles/chat-typing-indicator.styles.ts index f5d5ee407..3a934b055 100644 --- a/libs/chat/src/lib/styles/chat-typing-indicator.styles.ts +++ b/libs/chat/src/lib/styles/chat-typing-indicator.styles.ts @@ -1,6 +1,16 @@ // SPDX-License-Identifier: MIT export const CHAT_TYPING_INDICATOR_STYLES = ` - :host { display: block; padding: 0 var(--ngaf-chat-space-6) var(--ngaf-chat-space-3); } + /* Sit in the same centered column as chat-message-list so the dots + don't flash at the scroll container's left edge before the assistant + message renders. */ + :host { + display: block; + padding: 0 var(--ngaf-chat-space-6) var(--ngaf-chat-space-3); + max-width: var(--ngaf-chat-max-width); + margin: 0 auto; + width: 100%; + box-sizing: border-box; + } .chat-typing__dots { display: inline-flex; gap: 4px; align-items: center; } .chat-typing__dot { width: 6px;