From 748022f2bac6ee09634db053d554d63a7fdff231 Mon Sep 17 00:00:00 2001 From: Danielle Maywood Date: Thu, 19 Mar 2026 18:10:23 +0000 Subject: [PATCH] fix(site): add inline decorator spacing to chat input via Lexical theme (#23308) --- .../ChatMessageInput/ChatMessageInput.tsx | 1 + .../ChatMessageInput/FileReferenceNode.tsx | 3 +- .../AgentsPage/AgentChatInput.stories.tsx | 68 +++++++++++++++++++ .../AgentDetail/ConversationTimeline.tsx | 5 +- 4 files changed, 72 insertions(+), 5 deletions(-) diff --git a/site/src/components/ChatMessageInput/ChatMessageInput.tsx b/site/src/components/ChatMessageInput/ChatMessageInput.tsx index dcebd74380..8c7f0afa9f 100644 --- a/site/src/components/ChatMessageInput/ChatMessageInput.tsx +++ b/site/src/components/ChatMessageInput/ChatMessageInput.tsx @@ -324,6 +324,7 @@ const ChatMessageInput = memo( namespace: "ChatMessageInput", theme: { paragraph: "m-0", + inlineDecorator: "mx-1", }, onError: (error: Error) => console.error("Lexical error:", error), nodes: [FileReferenceNode], diff --git a/site/src/components/ChatMessageInput/FileReferenceNode.tsx b/site/src/components/ChatMessageInput/FileReferenceNode.tsx index 50fb65a0e9..585bc645fc 100644 --- a/site/src/components/ChatMessageInput/FileReferenceNode.tsx +++ b/site/src/components/ChatMessageInput/FileReferenceNode.tsx @@ -122,8 +122,9 @@ export class FileReferenceNode extends DecoratorNode { this.__content = content; } - createDOM(_config: EditorConfig): HTMLElement { + createDOM(config: EditorConfig): HTMLElement { const span = document.createElement("span"); + span.className = config.theme.inlineDecorator ?? ""; span.style.display = "inline"; span.style.userSelect = "none"; return span; diff --git a/site/src/pages/AgentsPage/AgentChatInput.stories.tsx b/site/src/pages/AgentsPage/AgentChatInput.stories.tsx index af73b2bbc9..f57f286d81 100644 --- a/site/src/pages/AgentsPage/AgentChatInput.stories.tsx +++ b/site/src/pages/AgentsPage/AgentChatInput.stories.tsx @@ -1,4 +1,6 @@ import type { Meta, StoryObj } from "@storybook/react-vite"; +import type { ChatMessageInputRef } from "components/ChatMessageInput/ChatMessageInput"; +import { useEffect, useRef } from "react"; import { expect, fn, userEvent, waitFor, within } from "storybook/test"; import { AgentChatInput, type UploadState } from "./AgentChatInput"; @@ -260,6 +262,72 @@ export const WithAttachmentError: Story = { })(), }; +/** File reference chip rendered inline with text in the editor. */ +export const WithFileReference: Story = { + render: (args) => { + const ref = useRef(null); + + useEffect(() => { + const handle = ref.current; + if (!handle) return; + handle.addFileReference({ + fileName: "site/src/components/Button.tsx", + startLine: 42, + endLine: 42, + content: "export const Button = ...", + }); + }, []); + + return ; + }, + args: { + initialValue: "Can you refactor ", + }, + play: async ({ canvasElement }) => { + const canvas = within(canvasElement); + await waitFor(() => { + expect(canvas.getByText(/Button\.tsx/)).toBeInTheDocument(); + }); + }, +}; + +/** Multiple file reference chips rendered inline with text. */ +export const WithMultipleFileReferences: Story = { + render: (args) => { + const ref = useRef(null); + + useEffect(() => { + const handle = ref.current; + if (!handle) return; + handle.addFileReference({ + fileName: "api/handler.go", + startLine: 1, + endLine: 50, + content: "...", + }); + handle.insertText(" and "); + handle.addFileReference({ + fileName: "api/handler_test.go", + startLine: 10, + endLine: 30, + content: "...", + }); + }, []); + + return ; + }, + args: { + initialValue: "Compare ", + }, + play: async ({ canvasElement }) => { + const canvas = within(canvasElement); + await waitFor(() => { + expect(canvas.getByText(/handler\.go/)).toBeInTheDocument(); + expect(canvas.getByText(/handler_test\.go/)).toBeInTheDocument(); + }); + }, +}; + export const AttachmentsOnly: Story = { args: (() => { const file = createMockFile("photo.png", "image/png"); diff --git a/site/src/pages/AgentsPage/AgentDetail/ConversationTimeline.tsx b/site/src/pages/AgentsPage/AgentDetail/ConversationTimeline.tsx index 7357089b7a..d7a6b804d3 100644 --- a/site/src/pages/AgentsPage/AgentDetail/ConversationTimeline.tsx +++ b/site/src/pages/AgentsPage/AgentDetail/ConversationTimeline.tsx @@ -366,10 +366,7 @@ const ChatMessageItem = memo<{ fileName={block.file_name} startLine={block.start_line} endLine={block.end_line} - className={cn( - i > 0 && "ml-1", - i < userInlineContent.length - 1 && "mr-1", - )} + className="mx-1" /> ), )