Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,10 @@ const PlaygroundVariantConfig: React.FC<
revisionId={variantId}
onRefinePrompt={handleRefinePrompt}
viewMode={viewMode}
// Embedded (drawer) renders the variant config
// header non-sticky, so the section headers have
// nothing to clear — pin them at the scroll top.
stickyHeaderTop={embedded ? 0 : 48}
/>
</PlaygroundNodeTokenPathProvider>
</FieldsDetectionProvider>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -451,6 +451,15 @@ export interface PlaygroundConfigSectionProps {
onRefinePrompt?: (promptKey: string) => void
/** View mode controlled from parent (form/json/yaml) */
viewMode?: ConfigViewMode
/**
* Top offset (px) for the sticky section headers. Defaults to 48 to clear
* the sticky `PlaygroundVariantConfigHeader` (h-[48px], `sticky top-0`) that
* sits above the config in the full playground. In the embedded drawer that
* header is rendered non-sticky (`grow`), so there is nothing to clear —
* pass 0 there to keep the section headers flush with the scroll top instead
* of floating 48px down into the editor content.
*/
stickyHeaderTop?: number
}

function PlaygroundConfigSection({
Expand All @@ -461,6 +470,7 @@ function PlaygroundConfigSection({
moleculeAdapter,
onRefinePrompt,
viewMode: externalViewMode,
stickyHeaderTop = 48,
}: PlaygroundConfigSectionProps) {
const {llmProviderConfig} = useDrillInUI()

Expand Down Expand Up @@ -1362,7 +1372,8 @@ function PlaygroundConfigSection({

return (
<div
className="flex items-center justify-between w-full px-3 py-2 bg-[var(--ag-c-FAFAFB)] cursor-pointer select-none sticky top-[48px] z-[2]"
className="flex items-center justify-between w-full px-3 py-2 bg-[var(--ag-c-FAFAFB)] cursor-pointer select-none sticky z-[2]"
style={{top: stickyHeaderTop}}
onClick={() => toggleSection(fieldKey)}
Comment thread
ashrafchowdury marked this conversation as resolved.
>
<div className="flex items-center gap-1">
Expand Down Expand Up @@ -1578,7 +1589,10 @@ function PlaygroundConfigSection({
) : (
<>
{!hasTopLevelObjectSection && (
<div className="flex items-center w-full px-3 py-2 bg-[var(--ag-c-FAFAFB)] sticky top-[48px] z-[2]">
<div
className="flex items-center w-full px-3 py-2 bg-[var(--ag-c-FAFAFB)] sticky z-[2]"
style={{top: stickyHeaderTop}}
>
<span className="capitalize font-medium text-sm">Config</span>
</div>
)}
Expand Down
16 changes: 11 additions & 5 deletions web/packages/agenta-ui/src/Editor/plugins/code/utils/pasteUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -117,8 +117,13 @@ export function $insertLinesWithSelectionAndIndent({
}
}

// Clone trailing lines before removal
const clonedTrailingLines = linesAfter.map((l) => $copyNode(l))
// Capture trailing-line TEXT before removal, then rebuild fresh nodes after
// insertion (see re-insertion below). We can't element-clone these lines:
// `$copyNode` assigns the clone a fresh key, and Lexical's ElementNode only
// carries child pointers when the key is unchanged — so a cloned CodeLineNode
// comes back EMPTY, wiping every line below the paste point. Rebuilding from
// text mirrors the large-paste fast path and preserves the content faithfully.
const trailingLineTexts = linesAfter.map((l) => l.getTextContent())
linesAfter.forEach((l) => l.remove())
// Remove current line
currentLine.remove()
Expand Down Expand Up @@ -174,11 +179,12 @@ export function $insertLinesWithSelectionAndIndent({
insertIdx++
}

// Add trailing lines (use clones)
clonedTrailingLines.forEach((l, i) => {
// Add trailing lines (rebuilt from captured text — see note above)
const trailingLanguage = parentBlock.getLanguage()
trailingLineTexts.forEach((text, i) => {
const prevChild = $getLineAtIndex(parentBlock, insertIdx - 1 + i)
if (prevChild) {
prevChild.insertAfter(l)
prevChild.insertAfter($createNodeForLineWithTabs(text, trailingLanguage))
}
})

Expand Down
20 changes: 16 additions & 4 deletions web/packages/agenta-ui/src/SharedEditor/SharedEditorImpl.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -453,12 +453,24 @@ const SharedEditor = ({
style={
{
...props.style,
interpolateSize: "allow-keywords",
height: "var(--editor-h, auto)",
overflow: "hidden",
transitionProperty: "height",
transitionDuration: "300ms",
transitionTimingFunction: "cubic-bezier(0.4, 0, 0.2, 1)",
// The height transition exists only to animate the collapse
// toggle (which sets `--editor-h` to a fixed px ↔ auto). Code
// editors never use that toggle, so `--editor-h` stays `auto`
// and `interpolate-size: allow-keywords` would instead animate
// EVERY content-height change while typing/pasting — making the
// editor grow over 300ms and lurching the surrounding drawer's
// scroll. Disable the animation for codeOnly so growth is
// instant; keep it for the collapsible rich-text/prompt editors.
...(editorProps?.codeOnly
? {}
: {
interpolateSize: "allow-keywords",
transitionProperty: "height",
transitionDuration: "300ms",
transitionTimingFunction: "cubic-bezier(0.4, 0, 0.2, 1)",
}),
} as React.CSSProperties
}
onPasteCapture={handlePasteCapture}
Expand Down
Loading