Skip to content

Commit 591177c

Browse files
authored
feat(superdoc): add generic surfaces API for dialogs and floating panels (#2549)
* feat(superdoc): add generic surfaces API for dialogs and floating panels * fix(surface-manager): ignore stale callbacks from replaced surfaces
1 parent 476e6b0 commit 591177c

21 files changed

Lines changed: 3365 additions & 0 deletions

apps/docs/core/superdoc/configuration.mdx

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,60 @@ new SuperDoc({
229229
</Expandable>
230230
</ParamField>
231231

232+
### Surface defaults
233+
234+
<ParamField path="modules.surfaces" type="Object">
235+
Optional defaults and resolver for SuperDoc surfaces.
236+
237+
<Expandable title="properties" defaultOpen>
238+
<ParamField path="modules.surfaces.resolver" type="function">
239+
Resolve intent-based surface requests opened with `kind`
240+
</ParamField>
241+
<ParamField path="modules.surfaces.dialog" type="Object">
242+
Default dialog options
243+
</ParamField>
244+
<ParamField path="modules.surfaces.dialog.closeOnEscape" type="boolean" default="true">
245+
Close dialogs on `Escape`
246+
</ParamField>
247+
<ParamField path="modules.surfaces.dialog.closeOnBackdrop" type="boolean" default="true">
248+
Close dialogs on backdrop click
249+
</ParamField>
250+
<ParamField path="modules.surfaces.dialog.maxWidth" type="string | number">
251+
Default dialog max-width
252+
</ParamField>
253+
<ParamField path="modules.surfaces.floating" type="Object">
254+
Default floating-surface options
255+
</ParamField>
256+
<ParamField path="modules.surfaces.floating.placement" type="'top-right' | 'top-left' | 'bottom-right' | 'bottom-left' | 'top-center' | 'bottom-center'" default="'top-right'">
257+
Default floating placement
258+
</ParamField>
259+
<ParamField path="modules.surfaces.floating.width" type="string | number">
260+
Default floating width
261+
</ParamField>
262+
<ParamField path="modules.surfaces.floating.maxWidth" type="string | number">
263+
Default floating max-width
264+
</ParamField>
265+
<ParamField path="modules.surfaces.floating.maxHeight" type="string | number">
266+
Default floating max-height
267+
</ParamField>
268+
<ParamField path="modules.surfaces.floating.closeOnEscape" type="boolean" default="true">
269+
Close floating surfaces on `Escape`
270+
</ParamField>
271+
<ParamField path="modules.surfaces.floating.closeOnOutsidePointerDown" type="boolean" default="false">
272+
Close floating surfaces when clicking outside
273+
</ParamField>
274+
<ParamField path="modules.surfaces.floating.autoFocus" type="boolean" default="true">
275+
Move focus into the first focusable child on open
276+
</ParamField>
277+
</Expandable>
278+
</ParamField>
279+
280+
<Note>
281+
You only need `modules.surfaces` if you want shared defaults or a central resolver. Direct `superdoc.openSurface(...)` calls do not require any special setup.
282+
</Note>
283+
284+
See [Surfaces](/core/superdoc/surfaces) for the full API and examples.
285+
232286
<ParamField path="modules.slashMenu" type="Object" deprecated>
233287
<Warning>**Deprecated** — Use `modules.contextMenu` instead. See the [Context Menu module](/modules/context-menu) for configuration options.</Warning>
234288
</ParamField>

apps/docs/core/superdoc/methods.mdx

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -365,6 +365,73 @@ const superdoc = new SuperDoc({
365365

366366
</CodeGroup>
367367

368+
### `openSurface`
369+
370+
Open a `dialog` or `floating` surface above the document.
371+
372+
**Returns:** `SurfaceHandle`
373+
374+
<ParamField path="request" type="Object" required>
375+
Surface request. Set `mode` to `'dialog'` or `'floating'`, then provide content via `render` (framework-agnostic) or `component` (Vue). See [Surfaces](/core/superdoc/surfaces) for the full request shape.
376+
</ParamField>
377+
378+
<CodeGroup>
379+
380+
```javascript Usage
381+
const handle = superdoc.openSurface({
382+
mode: 'floating',
383+
title: 'Find',
384+
floating: { placement: 'top-right', width: 360 },
385+
render: ({ container }) => {
386+
container.innerHTML = '<input placeholder="Find..." style="width:100%" />';
387+
},
388+
});
389+
```
390+
391+
```javascript Full Example
392+
const handle = superdoc.openSurface({
393+
mode: 'dialog',
394+
title: 'Confirm action',
395+
render: ({ container, close }) => {
396+
container.innerHTML = '<button type="button">Close</button>';
397+
container.querySelector('button')?.addEventListener('click', () => close('manual-close'));
398+
},
399+
});
400+
401+
const outcome = await handle.result;
402+
console.log(outcome.status);
403+
```
404+
405+
</CodeGroup>
406+
407+
See [Surfaces](/core/superdoc/surfaces) for the full request shape, Vue/React examples, and resolver-based usage.
408+
409+
### `closeSurface`
410+
411+
Close a specific surface by id, or the topmost active surface when no id is provided. When both a dialog and a floating surface are open, the dialog closes first.
412+
413+
<CodeGroup>
414+
415+
```javascript Usage
416+
superdoc.closeSurface();
417+
```
418+
419+
```javascript Full Example
420+
const handle = superdoc.openSurface({
421+
mode: 'floating',
422+
title: 'Find',
423+
render: ({ container }) => {
424+
container.innerHTML = '<input placeholder="Find..." style="width:100%" />';
425+
},
426+
});
427+
428+
superdoc.closeSurface(handle.id);
429+
```
430+
431+
</CodeGroup>
432+
433+
See [Surfaces](/core/superdoc/surfaces) for lifecycle behavior and close ordering.
434+
368435
### `setTrackedChangesPreferences`
369436
370437
Override how tracked changes are rendered in the layout engine.

0 commit comments

Comments
 (0)