diff --git a/libs/chat/src/lib/primitives/chat-message/chat-message.component.ts b/libs/chat/src/lib/primitives/chat-message/chat-message.component.ts index 3a547e5b7..89b17996a 100644 --- a/libs/chat/src/lib/primitives/chat-message/chat-message.component.ts +++ b/libs/chat/src/lib/primitives/chat-message/chat-message.component.ts @@ -16,7 +16,18 @@ export type ChatMessageRole = 'user' | 'assistant' | 'system' | 'tool'; imports: [ChatCitationsComponent, ChatCheckpointMarkerComponent], changeDetection: ChangeDetectionStrategy.OnPush, styles: [CHAT_HOST_TOKENS, CHAT_MESSAGE_STYLES, ` - .chat-message__layout { display: flex; gap: 8px; align-items: flex-start; } + /* + * Layout MUST be width:100% so user-role __main's max-width:80% (defined + * in chat-message.styles.ts) has a concrete containing block to resolve + * against. Without this, layout shrinks to __main's content, __main + * shrinks to its bubble's content, the bubble's fit-content is then + * capped by max-width:80% of layout (a circular dependency the browser + * breaks at the bubble's wrap-point intrinsic width — ~166px instead of + * the unwrapped ~199px), forcing short user phrases like "Show me the + * dashboard" to wrap mid-message. See PRs #313, #325, c0b9e88c — each + * shifted which element held the 80% cap but none gave it a stable base. + */ + .chat-message__layout { display: flex; gap: 8px; align-items: flex-start; width: 100%; } .chat-message__gutter { flex: 0 0 14px; display: flex; align-items: flex-start; padding-top: 4px; } .chat-message__gutter:empty { flex-basis: 0; } .chat-message__main { flex: 1; min-width: 0; } diff --git a/libs/chat/src/lib/styles/chat-message.styles.ts b/libs/chat/src/lib/styles/chat-message.styles.ts index 66916add1..698c1bcae 100644 --- a/libs/chat/src/lib/styles/chat-message.styles.ts +++ b/libs/chat/src/lib/styles/chat-message.styles.ts @@ -3,19 +3,22 @@ export const CHAT_MESSAGE_STYLES = ` :host { display: block; } :host([data-role="user"]) { - display: flex; - justify-content: flex-end; + /* + * Block (not flex) so the layout child gets its width:100% (set in + * chat-message.component.ts inline styles). Right-alignment happens + * inside layout via justify-content:flex-end below, NOT here. The old + * "display:flex; justify-content:flex-end" on the host caused layout + * to shrink-wrap its content, which collapsed __main's 80% containing + * block — see chat-message.component.ts comment for the full story. + */ + display: block; margin-top: 0.5rem; } :host([data-role="user"][data-prev-role="assistant"]) { margin-top: 1.5rem; } - /* - * For user-role messages, the bubble's containing column must size to - * content rather than collapse via the flex chain. Without this, the - * bubble's max-width: 80% (defined below) resolves against a collapsed - * parent (~58px instead of the full row), capping the bubble below - * intrinsic single-word width and forcing mid-word wraps like - * "hello" → "hel" / "lo". See PR #313 follow-up. - */ + :host([data-role="user"]) .chat-message__layout { + /* Right-align the bubble column inside the full-width row. */ + justify-content: flex-end; + } :host([data-role="user"]) .chat-message__main { flex: none; width: fit-content;