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
2 changes: 1 addition & 1 deletion packages/react/AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ Pass `contained` to scroll inside a fixed-height parent. The wrapper must have a

## SSR Behavior

- Container divs are always rendered (hidden with `display: none` until initialized)
- Container divs are always rendered and remain measurable while loading
- No `isClient` state or extra rerender — containers exist from first render
- SuperDoc initializes in `useEffect` (client-side only) and mounts into the existing containers
- `renderLoading()` shown alongside hidden containers until initialization completes
Expand Down
30 changes: 30 additions & 0 deletions packages/react/src/SuperDocEditor.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,36 @@ describe('SuperDocEditor', () => {

expect(container.querySelector('[data-testid="loading"]')).toBeTruthy();
});

it('keeps the editor container measurable while loading', () => {
const { container } = render(
<SuperDocEditor renderLoading={() => <div data-testid='loading'>Loading...</div>} />,
);

const editorContainer = container.querySelector('.superdoc-editor-container') as HTMLElement;

expect(editorContainer.style.display).not.toBe('none');
expect(editorContainer.style.visibility).toBe('hidden');
expect(editorContainer.style.pointerEvents).toBe('none');
});

it('overlays loading content while contained and loading', () => {
const { container } = render(
<SuperDocEditor contained renderLoading={() => <div data-testid='loading'>Loading...</div>} />,
);

const wrapper = container.querySelector('.superdoc-wrapper') as HTMLElement;
const editorContainer = container.querySelector('.superdoc-editor-container') as HTMLElement;
const loadingContainer = container.querySelector('.superdoc-loading-container') as HTMLElement;

expect(wrapper.style.position).toBe('relative');
expect(editorContainer.style.display).not.toBe('none');
expect(editorContainer.style.visibility).toBe('hidden');
expect(editorContainer.style.flex).toBe('1 1 0%');
expect(loadingContainer.style.position).toBe('absolute');
expect(loadingContainer.style.inset).toBe('0');
expect(loadingContainer.style.zIndex).toBe('1');
});
});

describe('callbacks', () => {
Expand Down
18 changes: 16 additions & 2 deletions packages/react/src/SuperDocEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -245,11 +245,21 @@ function SuperDocEditorInner(props: SuperDocEditorProps, ref: ForwardedRef<Super
}, [documentProp, user, users, modules, role, hideToolbar, contained, containerId, toolbarId]);

const wrapperClassName = ['superdoc-wrapper', className].filter(Boolean).join(' ');
const hideWhenLoading: CSSProperties | undefined = isLoading ? { display: 'none' } : undefined;
const hideWhenLoading: CSSProperties | undefined = isLoading
? { visibility: 'hidden', pointerEvents: 'none' }
: undefined;
Comment thread
palmer-cl marked this conversation as resolved.

const wrapperStyle: CSSProperties = {
...style,
...(contained && { display: 'flex', flexDirection: 'column' as const }),
...(isLoading &&
renderLoading && { position: style?.position && style.position !== 'static' ? style.position : 'relative' }),
};

const loadingStyle: CSSProperties = {
position: 'absolute',
inset: 0,
zIndex: 1,
};

return (
Expand All @@ -262,7 +272,11 @@ function SuperDocEditorInner(props: SuperDocEditorProps, ref: ForwardedRef<Super
className='superdoc-editor-container'
style={{ ...hideWhenLoading, ...(contained && { flex: 1, minHeight: 0 }) }}
/>
{isLoading && !hasError && renderLoading && <div className='superdoc-loading-container'>{renderLoading()}</div>}
{isLoading && !hasError && renderLoading && (
<div className='superdoc-loading-container' style={loadingStyle}>
{renderLoading()}
</div>
)}
{hasError && <div className='superdoc-error-container'>Failed to load editor. Check console for details.</div>}
</div>
);
Expand Down
Loading