# PaneShell editor integration

> ROM 0.1.5. [Release artifacts](https://git.cybernomad.it/pmikstacki/ROM/releases/tag/v0.1.5).
> Matching package version: 0.1.0-alpha.8. Archive SHA-256: bf6620cd2467f45ce5afc5e803f88bb2401f9c609c58616aaf14b9f887876255.
> Guide origin: package archive.


`rom-ui/paneshell` composes host-supplied document editors with Dockview Svelte.
Dockview owns tabs, splits and floating windows. ROM or your application owns document contents, permissions and saves.
PaneShell uses Dockview's retained renderer to keep editor DOM attached during tab activation.
Saved layouts cannot select a detaching renderer. Omitted renderer metadata is normalized to retained rendering.

## Document and layout ownership

Supply document metadata through `bind:documents`. Each document has a unique `id`, a `title` and an optional `dirty` flag.
The shell supports up to 128 documents. A dirty flag does not establish whether a close operation is permitted.

Supply `onclose(document)` to decide whether a document can close. Return `true` only after the host approves closure.
A rejected decision retains the editor. Pending decisions from an old authority cannot close a replacement document.

Use `onlayout` to observe the native manager's layout projection. This callback does not control a second layout model.
Call `saveLayout()` and `restoreLayout(snapshot)` on the shell instance to preserve arrangements.
Restoration checks the disclosed document set, native fields and maximized paths before calling Dockview.
Malformed snapshots return `false` and report an error through `onerror`.

Change `authority` when the editor lifetime changes, including session or permission replacement.
The shell destroys the old editor subtree. The host must also replace its private drafts and disclosed document list.
Use a stable, nonsecret scalar lifetime token when storing serialized layouts. Object tokens compare by identity after loading.
A layout snapshot does not grant access to a Resource.

## Document search

Use the Find document toolbar button to open the shared command dialog.
Search matches the supplied document IDs and titles. Keyboard selection activates the existing native panel without creating another editor.
Escape closes the dialog and returns focus to its opener.
Host navigation can call `selectDocument(id)` on the shell instance. It returns `false` for unavailable panels or pending close decisions.
The command dialog is recreated when authority changes. This operation does not save a Resource or perform a server query.

## Navigation

Supply `navigation(close)` to render host navigation in the shared Sidebar.
After `selectDocument(id)` returns `true`, call `close()` to close the mobile Sheet.
Desktop navigation remains collapsible. Each embedded shell disables shared sidebar cookies and global shortcuts.
The navigation subtree is recreated when authority changes.

## Inspector

Supply an `inspector` snippet to add a responsive details panel. The inspector starts closed.
Use its toolbar button or `bind:inspectorOpen` to control visibility.
The desktop separator uses PaneForge. Drag it or use Arrow keys while it has focus to resize the inspector.
PaneForge controls outer chrome widths; Dockview still controls document tabs, splits and floating windows.
On narrow screens, the shared ResponsiveDetails component presents a modal Sheet with focus return.
The same inspector input survives desktop/mobile relocation. Authority replacement closes and recreates the inspector subtree.
The host must also replace its private inspector drafts when authority changes.

## CodeMirror composition

Install the qualified editor packages separately. The default ROM UI controls entry does not import them.

```sh
corepack pnpm add --save-exact svelte-codemirror-editor@2.1.0 codemirror@6.0.2
```

```svelte
<script lang="ts">
  import { PaneShell, type PaneDocument } from 'rom-ui/paneshell';
  import CodeMirror from 'svelte-codemirror-editor';
  let documents = $state([{ id: 'code', title: 'Code editor' }]);
  let drafts = $state<Record<string, string>>({ code: 'const enabled = false;' });
</script>

{#snippet editor(document: PaneDocument)}
  <CodeMirror
    value={drafts[document.id] ?? ''}
    onchange={value => drafts = { ...drafts, [document.id]: value }}
    nodebounce
    useTab={false}
    onready={view => view.contentDOM.setAttribute('aria-label', document.title)}
  />
{/snippet}

<PaneShell bind:documents authority="code-example" {editor} />
```

`nodebounce` updates host drafts without the wrapper's change debounce. `useTab={false}` lets Tab move focus out of the editor.
Supply language extensions through the editor's `lang` or `extensions` props.
Use `readonly` to prevent document edits while retaining selection and copy behavior.
CodeMirror reports this state with `aria-readonly`; its DOM can remain content-editable.

Connect saves through the existing ROM Studio session and recovery composition.
Keep candidate editor text separate from validated wire values and confirmed Resource state.
This example contains local drafts and does not perform a ROM action.

The [Svelte wrapper documentation](https://github.com/touchifyapp/svelte-codemirror-editor) describes its props and editor callbacks.

## Qualification scope

The installed consumer tests cover editor selection, undo history, one mounted view during float/dock operations and authority replacement.
They also hydrate server-rendered PaneShell markup in Chromium and WebKit without hydration warnings.
CodeMirror mounts its editor contents on the client; server rendering emits its container.

The gallery includes a local CodeMirror workspace, read-only controls and a copyable composition example.
These checks do not establish ROM attachment, persistence or release completion.
# Validate a restored document set

Import `validatePaneLayout` from `rom-ui/paneshell` to admit saved layout metadata before changing the mounted document list.
Supply the exact document IDs permitted by the host. The function returns a detached layout with retained editor rendering.
Resource access remains enforced by ROM. After an authorized settings read, bind the snapshot to the current authority before restoration.

## Workspace appearance and extension slots

PaneShell uses a compact navigation rail, document tabs and icon controls.
The light palette uses warm surfaces and sage accents.
An ancestor with the `dark` class selects the dark forest palette.
The editor, inspector and navigation use the same workspace color tokens.

Supply `activities` to add host controls to the navigation rail.
Supply `status` to render host content in the bottom status bar.
Supply `editor(document)`, `navigation(close)` and `inspector` for the main workspace regions.
These snippets inherit the application context. Authority replacement recreates their private workspace scope.
Give each interactive icon an accessible name. Keep host operations subject to ROM permissions.

Dockview owns tab dragging, split drop targets and floating window movement.
PaneForge owns the inspector separator. The shell does not maintain a second docking engine.

Use Split to move the current document into a pane on the right.
Use Split below to place it below the other documents.
Both controls use Dockview and retain the mounted editor.

The top bar provides previous/next document controls, search, split controls and the inspector toggle.
Previous and next follow the current document list. They do not represent browser history.
Supply `toolbar` to add application icon buttons or menus to the top bar.
The bottom bar shows the disclosed document count and the active document's dirty state.
Supply `status` for editor-specific information, such as cursor position.
Supply `statusActions` for buttons or menus at the end of the bottom bar.
The CodeMirror gallery demonstrates a live cursor position and a line-wrapping button.
