diff --git a/static/app/components/core/chat/index.tsx b/static/app/components/core/chat/index.tsx index f9a891bc7201..9d967d6768a0 100644 --- a/static/app/components/core/chat/index.tsx +++ b/static/app/components/core/chat/index.tsx @@ -1,3 +1,4 @@ export {UserBubble} from './userBubble'; export {ToolCallIndicator, type ToolCallStatus} from './toolCallIndicator'; export {Spinner} from './spinner'; +export {MessageRow} from './messageRow'; diff --git a/static/app/components/core/chat/messageRow.mdx b/static/app/components/core/chat/messageRow.mdx new file mode 100644 index 000000000000..29c1b4007857 --- /dev/null +++ b/static/app/components/core/chat/messageRow.mdx @@ -0,0 +1,49 @@ +--- +title: MessageRow +description: The full-width row that positions a single message turn in a conversation. +category: chat +source: '@sentry/scraps/chat' +resources: + js: https://github.com/getsentry/sentry/blob/master/static/app/components/core/chat/messageRow.tsx +--- + +import {MessageRow, UserBubble} from '@sentry/scraps/chat'; +import {Container} from '@sentry/scraps/layout'; + +import * as Storybook from 'sentry/stories'; + +export const documentation = import('!!type-loader!@sentry/scraps/chat/messageRow'); + +The `MessageRow` lays out a single message turn within a conversation. It is +presentation only — it owns alignment and the consistent gutter around a turn, +while the bubble or content is the caller's responsibility. + +## Alignment + +Use `justify="end"` for the sender's own messages and the default `justify="start"` +for the agent's responses, so the two sides sit opposite each other. + + + + + Which of my issues are getting worse? + + Here are the three escalating issues I found. + + + +```jsx + + Which of my issues are getting worse? + +Here are the three escalating issues I found. +``` + +## Padding + +The row applies a consistent gutter (`md xl`) around each turn. Override +`padding` for surfaces that need a different gutter. + +```jsx + +``` diff --git a/static/app/components/core/chat/messageRow.tsx b/static/app/components/core/chat/messageRow.tsx new file mode 100644 index 000000000000..64ee9cbc852d --- /dev/null +++ b/static/app/components/core/chat/messageRow.tsx @@ -0,0 +1,29 @@ +import {Flex, type FlexProps} from '@sentry/scraps/layout'; + +interface MessageRowProps extends Omit { + children: React.ReactNode; + /** + * Which side of the conversation the message sits on: `end` for the sender's + * own messages, `start` (default) for the agent's responses. + */ + justify?: 'start' | 'end'; +} + +/** + * The full-width row that positions a single message turn within a conversation. + * + * Presentation only — it owns alignment and the consistent gutter around a turn; + * the bubble or content is the caller's responsibility. + */ +export function MessageRow({ + children, + justify = 'start', + padding = 'md xl', + ...props +}: MessageRowProps) { + return ( + + {children} + + ); +} diff --git a/static/app/views/seerExplorer/components/chat/shared.tsx b/static/app/views/seerExplorer/components/chat/shared.tsx index a3efe3dcd423..b8e000bcdc33 100644 --- a/static/app/views/seerExplorer/components/chat/shared.tsx +++ b/static/app/views/seerExplorer/components/chat/shared.tsx @@ -1,4 +1,4 @@ -import {Spinner, type ToolCallStatus} from '@sentry/scraps/chat'; +import {MessageRow, Spinner, type ToolCallStatus} from '@sentry/scraps/chat'; import {Flex} from '@sentry/scraps/layout'; import {SeerMarkdown} from 'sentry/components/seer/markdown'; @@ -66,7 +66,7 @@ export function hasValidContent(content: string | null | undefined): content is export function MessagePlaceholder({content}: {content?: string}) { return ( - + {hasValidContent(content) && } - + ); } diff --git a/static/app/views/seerExplorer/components/chat/user.tsx b/static/app/views/seerExplorer/components/chat/user.tsx index 2940d8278929..9a3b4eb4238a 100644 --- a/static/app/views/seerExplorer/components/chat/user.tsx +++ b/static/app/views/seerExplorer/components/chat/user.tsx @@ -1,12 +1,11 @@ -import {UserBubble} from '@sentry/scraps/chat'; -import {Flex} from '@sentry/scraps/layout'; +import {MessageRow, UserBubble} from '@sentry/scraps/chat'; import type {UserBlockProps} from './shared'; export function UserBlock({block}: UserBlockProps) { return ( - + {block.message.content ?? ''} - + ); }