Skip to content

Commit 98ed8bc

Browse files
committed
fix(files): address review on the placeholder editor
- Give ReadOnlyPlaceholder a named props interface (repo component convention). - Render the placeholder synchronously (immediatelyRender: true) so it paints instantly like the static HTML it replaced instead of blanking for a frame while the editor mounts — safe because this surface is client-only, never SSR'd. - Hoist the editor reading-column classes into a shared EDITOR_SURFACE_CLASS so the placeholder and live editor stay geometrically identical (drop the now redundant placeholderContent term from the live editor's hidden class).
1 parent b5cc8f6 commit 98ed8bc

1 file changed

Lines changed: 19 additions & 12 deletions

File tree

apps/sim/app/workspace/[workspaceId]/files/components/file-viewer/rich-markdown-editor/rich-markdown-editor.tsx

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,14 @@ const STREAM_REPARSE_THROTTLE_MS = 120
8181
/** Debounce before naming a still-untitled file after its leading heading, so it fires once typing settles. */
8282
const DERIVE_TITLE_DEBOUNCE_MS = 600
8383

84+
/**
85+
* The editor's reading column — the centered, padded surface both the live editor and the read-only
86+
* {@link ReadOnlyPlaceholder} render into, so the two are geometrically identical and the placeholder →
87+
* live swap never reflows. Shared as one constant to keep them in lockstep.
88+
*/
89+
const EDITOR_SURFACE_CLASS =
90+
'mx-auto flex w-full max-w-[48rem] flex-1 flex-col px-8 py-6 selection:bg-[var(--selection-bg)] selection:text-[var(--text-primary)] dark:selection:bg-[var(--selection-dark)] dark:selection:text-white'
91+
8492
/**
8593
* Read-only editor that renders the already-fetched markdown while a collaborative doc waits for its
8694
* server seed, so the pane shows content instantly instead of blocking blank on the socket round-trip
@@ -92,21 +100,23 @@ const DERIVE_TITLE_DEBOUNCE_MS = 600
92100
* (a client seed would duplicate it), and `editable={false}` disables every editing affordance. Mounted
93101
* only while the placeholder shows, so no second editor lingers once the live one takes over.
94102
*/
95-
function ReadOnlyPlaceholder({ content }: { content: JSONContent }) {
103+
interface ReadOnlyPlaceholderProps {
104+
content: JSONContent
105+
}
106+
107+
function ReadOnlyPlaceholder({ content }: ReadOnlyPlaceholderProps) {
96108
const editor = useEditor({
97109
extensions: EXTENSIONS,
98110
editable: false,
99-
immediatelyRender: false,
111+
// Render synchronously on first paint (safe — this surface is client-only, never SSR'd) so the
112+
// placeholder appears instantly like the static HTML it replaced, instead of blanking for a frame
113+
// while the editor mounts.
114+
immediatelyRender: true,
100115
shouldRerenderOnTransaction: false,
101116
content,
102117
editorProps: { attributes: { class: 'rich-markdown-prose' } },
103118
})
104-
return (
105-
<EditorContent
106-
editor={editor}
107-
className='mx-auto flex w-full max-w-[48rem] flex-1 flex-col px-8 py-6'
108-
/>
109-
)
119+
return <EditorContent editor={editor} className={EDITOR_SURFACE_CLASS} />
110120
}
111121

112122
interface RichMarkdownEditorProps {
@@ -1226,10 +1236,7 @@ export function LoadedRichMarkdownEditor({
12261236
)}
12271237
<EditorContent
12281238
editor={editor}
1229-
className={cn(
1230-
'mx-auto flex w-full max-w-[48rem] flex-1 flex-col px-8 py-6 selection:bg-[var(--selection-bg)] selection:text-[var(--text-primary)] dark:selection:bg-[var(--selection-dark)] dark:selection:text-white',
1231-
showPlaceholder && placeholderContent && 'hidden'
1232-
)}
1239+
className={cn(EDITOR_SURFACE_CLASS, showPlaceholder && 'hidden')}
12331240
/>
12341241
</div>
12351242
)

0 commit comments

Comments
 (0)