diff --git a/web/oss/src/styles/globals.css b/web/oss/src/styles/globals.css index bcf2162872..35ebc409b2 100644 --- a/web/oss/src/styles/globals.css +++ b/web/oss/src/styles/globals.css @@ -206,28 +206,14 @@ body { } } -/* Align the message text with the first character of the role label above it, - with the same symmetric horizontal inset on the role, the text, and the - placeholder. The single inset value lives in --ag-message-inline-pad. - - Notes: - - The role label is an antd Button whose default padding is wider than the - inset (Tailwind's px-2 on it loses to antd), so it is pinned with !important. - - The text is padded here in CSS rather than via an editor prop because - ChatMessageEditor renders the Editor with `noProvider`, a mode where - `className`/`editorClassName` is currently dropped (known bug, tracked - separately). JSON/code editors are excluded; they have a line-number gutter. */ -.agenta-chat-message-editor { - --ag-message-inline-pad: 8px; -} +/* Align the role label's first character with the message text below it. + The message text and placeholder are inset 8px via ChatMessageEditor's + editorClassName prop; this rule pins the role label to the same 8px. The role + label is an antd Button whose default padding is wider than 8px and ignores + Tailwind's px-2, so the override needs !important. Scoped to the message + editor via the .agenta-chat-message-editor marker class. */ .agenta-chat-message-editor .message-user-select { - padding-inline: var(--ag-message-inline-pad) !important; -} -.agenta-chat-message-editor .editor-input:not(.code-only) { - padding-inline: var(--ag-message-inline-pad); -} -.agenta-chat-message-editor .editor-placeholder { - left: var(--ag-message-inline-pad); + padding-inline: 8px !important; } /** Align the input search with the search box **/ diff --git a/web/packages/agenta-playground-ui/src/components/ExecutionItemComparisonView/GenerationComparisonChatOutput/index.tsx b/web/packages/agenta-playground-ui/src/components/ExecutionItemComparisonView/GenerationComparisonChatOutput/index.tsx index 8bff03803b..d673ed3f65 100644 --- a/web/packages/agenta-playground-ui/src/components/ExecutionItemComparisonView/GenerationComparisonChatOutput/index.tsx +++ b/web/packages/agenta-playground-ui/src/components/ExecutionItemComparisonView/GenerationComparisonChatOutput/index.tsx @@ -150,9 +150,15 @@ const GenerationComparisonChatOutputCell = ({ allowFileUpload: true, }} messageProps={{ - className: - "!p-0 [&_.agenta-editor-wrapper]:!p-3 !mt-0 [&:nth-child(1)]:!mt-0 mt-2", + className: "!p-0 !mt-0 [&:nth-child(1)]:!mt-0 mt-2", + // Comparison cells set their own editor padding via + // editorClassName (works after the noProvider className + // fix), replacing the previous + // `[&_.agenta-editor-wrapper]:!p-3` container hack. + // alignTextWithRole is off so the role-alignment inset + // does not stack on top of this padding. editorClassName: "!p-3", + alignTextWithRole: false, headerClassName: "min-h-[48px] px-2 border-0 border-b border-solid border-[var(--ag-rgba-051729-06)]", footerClassName: "px-2", @@ -198,9 +204,14 @@ const GenerationComparisonChatOutputCell = ({ withControls={false} hideUserMessage messageProps={{ - className: - "!p-0 [&_.agenta-editor-wrapper]:!p-3 !mt-0 [&:nth-child(1)]:!mt-0 mt-2", + // Padding via editorClassName only (the + // [&_.agenta-editor-wrapper]:!p-3 hack is removed so it does + // not double up now that editorClassName works), and + // alignTextWithRole off so the role-alignment inset does not + // stack on top. + className: "!p-0 !mt-0 [&:nth-child(1)]:!mt-0 mt-2", editorClassName: "!p-3", + alignTextWithRole: false, headerClassName: "min-h-[48px] border-0 border-b border-solid border-[var(--ag-rgba-051729-06)]", footerClassName: "px-2 !m-0", diff --git a/web/packages/agenta-playground-ui/src/components/adapters/VariableControlAdapter.tsx b/web/packages/agenta-playground-ui/src/components/adapters/VariableControlAdapter.tsx index 0a9ce04c2c..0018464a4d 100644 --- a/web/packages/agenta-playground-ui/src/components/adapters/VariableControlAdapter.tsx +++ b/web/packages/agenta-playground-ui/src/components/adapters/VariableControlAdapter.tsx @@ -549,7 +549,14 @@ const VariableControlAdapter: React.FC = ({ handleChange={handleChange} initialValue={effectiveValue} value={effectiveValue} - editorClassName={className} + // NOTE: the parent's `className` is a container/cell-strip style + // (e.g. `*:!border-none px-3`) and is applied to the container + // below. It must NOT be forwarded to the editor body, where it + // would strip the editor's own border and gutter (see the + // matching note on the code-editor branch above). It was + // previously passed as `editorClassName` but silently dropped by + // the `noProvider` className bug; now that the bug is fixed, the + // forward is removed so it stays a container-only style. placeholder={effectivePlaceholder} disabled={isEffectivelyDisabled} className={clsx( diff --git a/web/packages/agenta-ui/src/ChatMessage/components/ChatMessageEditor.tsx b/web/packages/agenta-ui/src/ChatMessage/components/ChatMessageEditor.tsx index 85ceca76ef..a0abbd5aae 100644 --- a/web/packages/agenta-ui/src/ChatMessage/components/ChatMessageEditor.tsx +++ b/web/packages/agenta-ui/src/ChatMessage/components/ChatMessageEditor.tsx @@ -74,6 +74,14 @@ export interface ChatMessageEditorProps { * up via an internal synchronizer mounted inside the EditorProvider. */ markdownView?: boolean + /** + * Inset the message text + placeholder so they line up with the role label + * above (the default tight message layout). Set to false for surfaces that + * apply their own editor padding (e.g. the comparison view's `!p-3` cells), + * where the alignment inset would stack on top and over-pad the text. + * @default true + */ + alignTextWithRole?: boolean } /** @@ -134,6 +142,7 @@ const ChatMessageEditorInner: React.FC = ({ onFocusChange, maxPasteChars = DEFAULT_MAX_TEXT_PASTE_CHARS, onPasteLimitExceeded, + alignTextWithRole = true, ...props }) => { const selectOptions = useMemo( @@ -210,16 +219,25 @@ const ChatMessageEditorInner: React.FC = ({ // // Kaosiso QA 2026-06-02 (also reproduces in production). disableDebounce - editorClassName={editorClassName} + // Inset the message text and its placeholder by 8px so they line up + // with the role label above. Goes through editorClassName (the proper + // prop) now that the noProvider className bug is fixed. Code editors + // (JSON/tool) keep their own gutter, so they are excluded via + // `:not(.code-only)`. The role label is an antd button outside the + // editor and is aligned via the `.agenta-chat-message-editor` rule in + // globals.css. Both are skipped when alignTextWithRole is false (e.g. + // the comparison view, which applies its own editor padding). + editorClassName={cn( + alignTextWithRole && + "[&_.editor-input:not(.code-only)]:px-2 [&_.editor-placeholder]:left-2", + editorClassName, + )} placeholder={placeholder} disabled={disabled} state={disabled ? "readOnly" : state} - // `agenta-chat-message-editor` is the styling hook used in globals.css - // to align the message text with the role label (see that file). The - // padding can't go through `editorClassName` because ChatMessageEditor - // renders the Editor with `noProvider`, where `className` is dropped. className={cn( - "agenta-chat-message-editor relative", + alignTextWithRole && "agenta-chat-message-editor", + "relative", flexLayouts.column, gapClasses.xs, "rounded-md", diff --git a/web/packages/agenta-ui/src/Editor/Editor.tsx b/web/packages/agenta-ui/src/Editor/Editor.tsx index 2b3378c302..a4cae15880 100644 --- a/web/packages/agenta-ui/src/Editor/Editor.tsx +++ b/web/packages/agenta-ui/src/Editor/Editor.tsx @@ -173,6 +173,7 @@ const EditorInner = forwardRef( disableIndentationPlugin = false, useNativeCodeNodes = false, diffExtensionConfig, + className, ...rest }: EditorProps, ref, @@ -755,7 +756,17 @@ const EditorInner = forwardRef( }, [codeOnly, editor, effectiveValue, hydrateRichTextFromControlledValue]) return ( -
+