@zylem/editor 0.6.9 → 0.7.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,121 +1,7 @@
1
1
  import { Component } from 'solid-js';
2
2
  import { LucideProps } from 'lucide-solid';
3
3
  import * as _zylem_bridge from '@zylem/bridge';
4
- import { BridgeDebugTool } from '@zylem/bridge';
5
-
6
- type EditorLauncherMode = 'floating' | 'hidden';
7
-
8
- /**
9
- * Configuration options for the ZylemEditorElement
10
- */
11
- interface ZylemEditorConfig {
12
- /**
13
- * External debug state to sync with.
14
- * If provided, the editor will use this state instead of its internal state.
15
- */
16
- debugState?: any;
17
- /**
18
- * External game state to sync with.
19
- */
20
- gameState?: any;
21
- /**
22
- * External stage state to sync with.
23
- */
24
- stageState?: any;
25
- /**
26
- * Whether to include default styles.
27
- * @default true
28
- */
29
- includeStyles?: boolean;
30
- /**
31
- * Controls whether the internal floating launcher is rendered.
32
- * @default 'floating'
33
- */
34
- launcherMode?: EditorLauncherMode;
35
- }
36
- /**
37
- * ZylemEditorElement - A web component that wraps the Zylem Editor.
38
- *
39
- * This component is fully self-contained with bundled styles.
40
- * It can be imported and used in any project without additional CSS configuration.
41
- *
42
- * @example
43
- * ```html
44
- * <!-- Standalone usage -->
45
- * <zylem-editor></zylem-editor>
46
- * ```
47
- *
48
- * @example
49
- * ```js
50
- * // Configured usage
51
- * const editor = document.querySelector('zylem-editor');
52
- * editor.config = {
53
- * debugState: myGame.debugState,
54
- * gameState: myGame.gameState,
55
- * stageState: myGame.stageState,
56
- * };
57
- * ```
58
- *
59
- * @example
60
- * ```js
61
- * // Manual registration in another project
62
- * import { ZylemEditorElement } from '@zylem/editor';
63
- *
64
- * // Optionally customize before registering
65
- * customElements.define('my-editor', ZylemEditorElement);
66
- * ```
67
- */
68
- declare class ZylemEditorElement extends HTMLElement {
69
- private dispose;
70
- private _config;
71
- private _initialized;
72
- private controller;
73
- /** Releases this element's bridge subscription (reference-counted). */
74
- private releaseBridge;
75
- constructor();
76
- /**
77
- * Set configuration for the editor.
78
- * Must be set before the element is connected to the DOM, or call `reinitialize()` after.
79
- */
80
- set config(value: ZylemEditorConfig);
81
- get config(): ZylemEditorConfig;
82
- set launcherMode(value: EditorLauncherMode);
83
- get launcherMode(): EditorLauncherMode;
84
- /**
85
- * Observed attributes for the web component
86
- */
87
- static get observedAttributes(): string[];
88
- attributeChangedCallback(name: string, _oldValue: string, newValue: string): void;
89
- connectedCallback(): void;
90
- private initialize;
91
- openPanel(): void;
92
- closePanel(): void;
93
- togglePanel(): void;
94
- /**
95
- * Reinitialize the editor with new configuration.
96
- * Call this after changing the `config` property if the element is already connected.
97
- */
98
- reinitialize(): void;
99
- disconnectedCallback(): void;
100
- private teardown;
101
- }
102
- /**
103
- * Register the ZylemEditorElement as a custom element.
104
- * Call this function to use the default 'zylem-editor' tag name.
105
- *
106
- * @example
107
- * ```js
108
- * import { registerZylemEditor } from '@zylem/editor';
109
- * registerZylemEditor();
110
- * // Now you can use <zylem-editor> in your HTML
111
- * ```
112
- */
113
- declare function registerZylemEditor(tagName?: string): void;
114
-
115
- interface IconProps extends LucideProps {
116
- icon: Component<LucideProps>;
117
- }
118
- declare const Icon: Component<IconProps>;
4
+ import { BridgeDebugTool, BridgeVec3, BridgeQuat, BridgePose, SnapSettingsPayload, SceneOperationPayload, EntityTypeDescriptor } from '@zylem/bridge';
119
5
 
120
6
  /**
121
7
  * Editor Event Bus
@@ -178,7 +64,22 @@ interface DebugState {
178
64
  paused: boolean;
179
65
  tool: DebugTools;
180
66
  selectedEntityId: string | null;
67
+ /**
68
+ * Full selection, mirroring the game. `selectedEntityId` is its first entry,
69
+ * kept so single-select consumers need no change.
70
+ */
71
+ selectedEntityIds: string[];
181
72
  hoveredEntityId: string | null;
73
+ /**
74
+ * Most recently selected or created entity, kept after it is deselected.
75
+ *
76
+ * What the gizmo tools fall back to: pressing Rotate with nothing selected
77
+ * should turn the thing you were last working on, rather than nothing. Never
78
+ * cleared on deselect — only overwritten — and validated against the current
79
+ * entity list at the point of use, since the entity it names can be deleted
80
+ * or undone away.
81
+ */
82
+ lastTouchedEntityId: string | null;
182
83
  flags: Set<string>;
183
84
  }
184
85
  declare const debugState: DebugState;
@@ -259,6 +160,58 @@ interface StageStateInterface {
259
160
 
260
161
  declare const stageState: StageStateInterface;
261
162
 
163
+ /**
164
+ * Dock layout geometry.
165
+ *
166
+ * Docking used to be per-panel: each panel snapped itself to a viewport edge
167
+ * and sized itself from `window.innerWidth`. That cannot express two panels
168
+ * sharing a side, or a bottom strip that stops at a left-docked panel, so the
169
+ * dock state lives in one registry (persisted in the editor store) and every
170
+ * panel's rect comes from `computeDockLayout`.
171
+ *
172
+ * This module is deliberately free of Solid and `window` so the geometry can
173
+ * be unit tested directly.
174
+ */
175
+ type DockSide = 'left' | 'right' | 'top' | 'bottom';
176
+ /** `'main'` is the editor panel; any other id is a detached section id. */
177
+ type DockPanelId = string;
178
+ interface DockZoneState {
179
+ /** Occupants in slot order along the zone's long axis. */
180
+ panels: DockPanelId[];
181
+ /**
182
+ * Width for left/right, height for top/bottom.
183
+ * `0` means "not chosen yet"; the layout falls back to a viewport quarter.
184
+ */
185
+ thickness: number;
186
+ }
187
+ type DockRegistry = Record<DockSide, DockZoneState>;
188
+ interface Viewport {
189
+ width: number;
190
+ height: number;
191
+ }
192
+ interface DockRect {
193
+ x: number;
194
+ y: number;
195
+ width: number;
196
+ height: number;
197
+ }
198
+ declare const DOCK_SIDES: readonly DockSide[];
199
+ declare const findDockedSide: (registry: DockRegistry, panelId: DockPanelId) => DockSide | null;
200
+ interface DockLayoutOptions {
201
+ /** Smallest slot extent along a zone's long axis. */
202
+ minSlotExtent?: number;
203
+ }
204
+ /**
205
+ * Rect for every docked panel.
206
+ *
207
+ * Left and right zones take the full viewport height and win over top and
208
+ * bottom, which inset horizontally to the space between them. Panels sharing a
209
+ * zone split its long axis evenly.
210
+ */
211
+ declare const computeDockLayout: (registry: DockRegistry, viewport: Viewport, options?: DockLayoutOptions) => Record<DockPanelId, DockRect>;
212
+
213
+ /** Registry id of the main editor panel; detached sections use their panel id. */
214
+ declare const MAIN_PANEL_ID = "main";
262
215
  interface DetachedPanelState {
263
216
  position: {
264
217
  x: number;
@@ -269,16 +222,25 @@ interface DetachedPanelState {
269
222
  height: number;
270
223
  };
271
224
  }
225
+ /** First-run dock assignments a host can request; see `applyDefaultDocks`. */
226
+ type EditorDockDefaults = Partial<Record<DockSide, DockPanelId[]>>;
272
227
  declare const debugStore: {
273
228
  debug: boolean;
274
229
  tool: DebugTools;
275
230
  paused: boolean;
276
231
  hovered: string | null;
277
232
  selected: string[];
233
+ /** Fallback target for the gizmo tools; see `DebugState.lastTouchedEntityId`. */
234
+ lastTouched: string | null;
278
235
  panelPosition: {
279
236
  x: number;
280
237
  y: number;
281
238
  } | null;
239
+ /** Main panel's floating size; its docked size comes from the registry. */
240
+ panelSize: {
241
+ width: number;
242
+ height: number;
243
+ } | null;
282
244
  toggleButtonPosition: {
283
245
  x: number;
284
246
  y: number;
@@ -287,9 +249,158 @@ declare const debugStore: {
287
249
  detachedPanels: Record<string, DetachedPanelState>;
288
250
  openSections: string[];
289
251
  panelZOrder: string[];
252
+ docks: DockRegistry;
253
+ dockDefaultsApplied: boolean;
290
254
  draggingPanelId: string | null;
291
255
  dropTargetIndex: number | null;
292
256
  };
257
+ declare const dockPanelToSide: (panelId: DockPanelId, side: DockSide, index?: number) => void;
258
+ declare const undockPanelFromSides: (panelId: DockPanelId) => void;
259
+ declare const getDockedSide: (panelId: DockPanelId) => DockSide | null;
260
+
261
+ type EditorLauncherMode = 'floating' | 'hidden';
262
+
263
+ /**
264
+ * Configuration options for the ZylemEditorElement
265
+ */
266
+ interface ZylemEditorConfig {
267
+ /**
268
+ * External debug state to sync with.
269
+ * If provided, the editor will use this state instead of its internal state.
270
+ */
271
+ debugState?: any;
272
+ /**
273
+ * External game state to sync with.
274
+ */
275
+ gameState?: any;
276
+ /**
277
+ * External stage state to sync with.
278
+ */
279
+ stageState?: any;
280
+ /**
281
+ * Whether to include default styles.
282
+ * @default true
283
+ */
284
+ includeStyles?: boolean;
285
+ /**
286
+ * Controls whether the internal floating launcher is rendered.
287
+ * @default 'floating'
288
+ */
289
+ launcherMode?: EditorLauncherMode;
290
+ /**
291
+ * Dock layout to seed the first time the editor runs in this browser, keyed
292
+ * by viewport edge. Use `'main'` for the editor panel itself; any other id is
293
+ * a section (for example `'console'`), which gets detached from the accordion
294
+ * so it can hold a dock slot.
295
+ *
296
+ * Ignored once the user has a saved layout, so it sets a starting point
297
+ * rather than forcing one.
298
+ */
299
+ defaultDocks?: EditorDockDefaults;
300
+ /**
301
+ * Whether the editor claims cmd/ctrl+z for its own undo stack.
302
+ *
303
+ * Disable it when embedding the editor in an app with its own history, and
304
+ * call the exported `undo()` / `redo()` from that app's handler instead.
305
+ * @default true
306
+ */
307
+ enableUndoShortcut?: boolean;
308
+ /**
309
+ * Whether Escape disarms the active tool.
310
+ * @default true
311
+ */
312
+ enableEscapeShortcut?: boolean;
313
+ }
314
+ /**
315
+ * ZylemEditorElement - A web component that wraps the Zylem Editor.
316
+ *
317
+ * This component is fully self-contained with bundled styles.
318
+ * It can be imported and used in any project without additional CSS configuration.
319
+ *
320
+ * @example
321
+ * ```html
322
+ * <!-- Standalone usage -->
323
+ * <zylem-editor></zylem-editor>
324
+ * ```
325
+ *
326
+ * @example
327
+ * ```js
328
+ * // Configured usage
329
+ * const editor = document.querySelector('zylem-editor');
330
+ * editor.config = {
331
+ * debugState: myGame.debugState,
332
+ * gameState: myGame.gameState,
333
+ * stageState: myGame.stageState,
334
+ * };
335
+ * ```
336
+ *
337
+ * @example
338
+ * ```js
339
+ * // Manual registration in another project
340
+ * import { ZylemEditorElement } from '@zylem/editor';
341
+ *
342
+ * // Optionally customize before registering
343
+ * customElements.define('my-editor', ZylemEditorElement);
344
+ * ```
345
+ */
346
+ declare class ZylemEditorElement extends HTMLElement {
347
+ private dispose;
348
+ private _config;
349
+ private _initialized;
350
+ private controller;
351
+ /** Releases this element's bridge subscription (reference-counted). */
352
+ private releaseBridge;
353
+ /** Keyboard shortcuts and the snap/grid mirror, torn down with the element. */
354
+ private teardownHooks;
355
+ constructor();
356
+ /**
357
+ * Set configuration for the editor.
358
+ * Must be set before the element is connected to the DOM, or call `reinitialize()` after.
359
+ */
360
+ set config(value: ZylemEditorConfig);
361
+ get config(): ZylemEditorConfig;
362
+ set launcherMode(value: EditorLauncherMode);
363
+ get launcherMode(): EditorLauncherMode;
364
+ /**
365
+ * Observed attributes for the web component
366
+ */
367
+ static get observedAttributes(): string[];
368
+ attributeChangedCallback(name: string, _oldValue: string, newValue: string): void;
369
+ connectedCallback(): void;
370
+ private initialize;
371
+ openPanel(): void;
372
+ closePanel(): void;
373
+ togglePanel(): void;
374
+ /**
375
+ * Dock a panel to a viewport edge, or pass `null` to float it again.
376
+ * Defaults to the main editor panel.
377
+ */
378
+ dockPanel(side: DockSide | null, panelId?: DockPanelId): void;
379
+ /**
380
+ * Reinitialize the editor with new configuration.
381
+ * Call this after changing the `config` property if the element is already connected.
382
+ */
383
+ reinitialize(): void;
384
+ disconnectedCallback(): void;
385
+ private teardown;
386
+ }
387
+ /**
388
+ * Register the ZylemEditorElement as a custom element.
389
+ * Call this function to use the default 'zylem-editor' tag name.
390
+ *
391
+ * @example
392
+ * ```js
393
+ * import { registerZylemEditor } from '@zylem/editor';
394
+ * registerZylemEditor();
395
+ * // Now you can use <zylem-editor> in your HTML
396
+ * ```
397
+ */
398
+ declare function registerZylemEditor(tagName?: string): void;
399
+
400
+ interface IconProps extends LucideProps {
401
+ icon: Component<LucideProps>;
402
+ }
403
+ declare const Icon: Component<IconProps>;
293
404
 
294
405
  declare const channel: _zylem_bridge.BridgeChannel;
295
406
  /**
@@ -318,6 +429,216 @@ declare function sendEntitySelect(uuid: string | null): void;
318
429
  declare function sendEntityFocus(uuid: string): void;
319
430
  /** Write a stage variable in the running game. */
320
431
  declare function sendStageVariable(key: string, value: unknown): void;
432
+ /**
433
+ * Set an entity's transform absolutely.
434
+ *
435
+ * `quaternion` is authoritative when supplied; `rotation` is Euler radians for
436
+ * the numeric fields, and round-trips less cleanly.
437
+ */
438
+ declare function sendEntityTransform(uuid: string, transform: {
439
+ position?: BridgeVec3;
440
+ rotation?: BridgeVec3;
441
+ quaternion?: BridgeQuat;
442
+ scale?: BridgeVec3;
443
+ }): void;
444
+ /** Arm the game's add tool with a catalog type, or `null` to disarm it. */
445
+ declare function sendAddType(typeId: string | null, props?: Record<string, unknown>): void;
446
+ /** Spawn a catalog entity without a placement click. */
447
+ declare function sendEntityCreate(typeId: string, options?: {
448
+ props?: Record<string, unknown>;
449
+ pose?: BridgePose;
450
+ }): void;
451
+ /** Push snap increments to the game's gizmo. */
452
+ declare function sendSnapSettings(snap: SnapSettingsPayload): void;
453
+ /** Show or hide the game's construction-plane grid. */
454
+ declare function sendGridVisible(visible: boolean): void;
455
+
456
+ /**
457
+ * Undo/redo history for scene edits.
458
+ *
459
+ * The editor owns the stack but never the inversion. Every edit originates in
460
+ * the game (gizmo drags, placement clicks, delete clicks), so the game publishes
461
+ * a committed before/after record and the editor stores it. Replaying one sends
462
+ * it back over the bridge: undoing a delete has to produce the original entity
463
+ * with its original uuid, which the editor could not do — all it ever receives
464
+ * is a summary of name, type, and transform.
465
+ *
466
+ * In-memory only. A reload drops history, which is correct: the game's entities
467
+ * are gone too, so the uuids every entry refers to would be dangling.
468
+ */
469
+
470
+ /**
471
+ * Depth cap. Each entry holds two poses per affected entity, so this is cheap;
472
+ * the limit exists so a long editing session cannot grow without bound. The
473
+ * game's detached-entity bin is sized above this, so a uuid still reachable
474
+ * from here is still restorable.
475
+ */
476
+ declare const MAX_HISTORY_DEPTH = 100;
477
+ interface HistoryState {
478
+ /** Oldest first; the last entry is what `undo()` reverts. */
479
+ undoStack: SceneOperationPayload[];
480
+ /** Operations that have been undone, newest last. */
481
+ redoStack: SceneOperationPayload[];
482
+ }
483
+ declare const historyState: HistoryState;
484
+ declare function canUndo(): boolean;
485
+ declare function canRedo(): boolean;
486
+ /** Label of the operation `undo()` would revert, for menu text. */
487
+ declare function undoLabel(): string | null;
488
+ /** Label of the operation `redo()` would replay. */
489
+ declare function redoLabel(): string | null;
490
+ /** Revert the most recent operation. */
491
+ declare function undo(): boolean;
492
+ /** Replay the most recently undone operation. */
493
+ declare function redo(): boolean;
494
+ /**
495
+ * Drop all history. Called on a fresh stage snapshot, because the entities the
496
+ * stack refers to are gone and replaying an entry would either do nothing or
497
+ * hit an unrelated entity that happens to share a uuid.
498
+ */
499
+ declare function clearHistory(): void;
500
+
501
+ /**
502
+ * The placeable entity types the game offers, and which one the Add tool is
503
+ * armed with.
504
+ *
505
+ * The list is game-owned: it arrives over the bridge as `catalog:snapshot`, so
506
+ * a host that registers its own entity types game-side gets them in the palette
507
+ * with no editor change. Icons come through as inline SVG markup because the
508
+ * editor and its hosts do not share an icon library.
509
+ */
510
+
511
+ interface CatalogState {
512
+ entities: EntityTypeDescriptor[];
513
+ /** Type the Add tool will place, or null when disarmed. */
514
+ armedTypeId: string | null;
515
+ /**
516
+ * Last type chosen from the palette, so re-arming the tool does not make the
517
+ * user re-pick. Survives disarming; cleared only when the catalog no longer
518
+ * contains it.
519
+ */
520
+ lastTypeId: string | null;
521
+ }
522
+ declare const catalogState: CatalogState;
523
+ declare function setEntityCatalog(entities: EntityTypeDescriptor[]): void;
524
+ declare function setArmedType(typeId: string | null): void;
525
+
526
+ /** Drop the armed placement type and return to the neutral tool. */
527
+ declare function disarmTools(): boolean;
528
+
529
+ /**
530
+ * Keeps the gizmo modes from outliving the selection they act on.
531
+ *
532
+ * The Move/Rotate/Scale buttons are only shown while something is selected, so
533
+ * a tool left active after the selection clears would be unreachable: no button
534
+ * to toggle it off, and the game keeps the simulation paused for the whole time
535
+ * a transform tool is held (see `StageTransformTool.setMode`). Escape already
536
+ * offers a manual way out via `disarmTools`; this is the automatic one.
537
+ */
538
+
539
+ /**
540
+ * Drop an active transform tool when nothing is selected.
541
+ *
542
+ * @returns `true` when a tool was reset.
543
+ */
544
+ declare function releaseOrphanedTransformTool(): boolean;
545
+ interface TransformToolGuardOptions {
546
+ /** @default true */
547
+ enabled?: boolean;
548
+ }
549
+ /**
550
+ * Watch the selection and release orphaned transform tools.
551
+ *
552
+ * @returns An uninstall function.
553
+ */
554
+ declare function installTransformToolGuard(options?: TransformToolGuardOptions): () => void;
555
+
556
+ /**
557
+ * Snap settings and grid visibility for the transform tools.
558
+ *
559
+ * Owned by the editor because it is the UI for them, and mirrored to the game
560
+ * over `snap:set` — the gizmo does the actual snapping, since only it knows the
561
+ * drag target.
562
+ */
563
+
564
+ /** 15 degrees, the default rotation increment. */
565
+ declare const DEFAULT_ROTATE_SNAP: number;
566
+ interface TransformState extends SnapSettingsPayload {
567
+ /** Whether the game draws its construction-plane grid. */
568
+ gridVisible: boolean;
569
+ }
570
+ declare const transformState: TransformState;
571
+ declare function setSnapEnabled(enabled: boolean): void;
572
+ declare function setSnapIncrements(increments: Partial<Pick<TransformState, 'translate' | 'rotate' | 'scale'>>): void;
573
+ declare function setGridVisible(visible: boolean): void;
574
+
575
+ /**
576
+ * Host observation of committed scene edits.
577
+ *
578
+ * Every edit the editor records is also announced here, so an embedding app can
579
+ * react to it — persisting a layout, marking a document dirty, or eventually
580
+ * writing changes back to source. Kept in its own module so `editor-bridge` does
581
+ * not have to import the host surface (which imports the bridge), which would be
582
+ * circular.
583
+ */
584
+
585
+ type SceneOperationListener = (op: SceneOperationPayload) => void;
586
+ /**
587
+ * Observe committed scene operations.
588
+ *
589
+ * @returns An unsubscribe function.
590
+ */
591
+ declare function onSceneOperation(listener: SceneOperationListener): () => void;
592
+
593
+ /**
594
+ * Stage export.
595
+ *
596
+ * Edits are runtime-only: moving a crate in the editor does not rewrite the
597
+ * source that created it. Export is the bridge between the two — it dumps the
598
+ * current stage as JSON so the values can be pasted back into the code that
599
+ * authored the scene. Source write-back is a later problem; this makes the work
600
+ * recoverable in the meantime.
601
+ *
602
+ * Built from the editor's own bridge state rather than `@zylem/game-lib/schema`,
603
+ * because the editor has no game-lib dependency at runtime and the entity
604
+ * blueprint schema stores 2D positions, which would drop the Z of every
605
+ * transform this feature exists to preserve.
606
+ */
607
+
608
+ interface StageExportEntity {
609
+ uuid: string;
610
+ name?: string;
611
+ type?: string;
612
+ position?: Vector3Like;
613
+ /** Euler angles in radians, matching the game's own representation. */
614
+ rotation?: Vector3Like;
615
+ scale?: Vector3Like;
616
+ }
617
+ interface StageExport {
618
+ /** Bumped when the shape changes, so an old file is recognisable. */
619
+ version: 1;
620
+ exportedAt: string;
621
+ stage: {
622
+ id: string;
623
+ backgroundColor: string;
624
+ backgroundImage: string | null;
625
+ gravity: Vector3Like;
626
+ variables: Record<string, unknown>;
627
+ } | null;
628
+ entities: StageExportEntity[];
629
+ }
630
+ /** Snapshot the current stage as a plain, serializable object. */
631
+ declare function buildStageExport(): StageExport;
632
+ /** The export as formatted JSON. */
633
+ declare function stageExportToString(): string;
634
+ /**
635
+ * Copy the export to the clipboard.
636
+ *
637
+ * @returns The serialized stage when the copy succeeded, or `null` when the
638
+ * clipboard was unavailable — over plain HTTP, or without a user gesture, the
639
+ * API is either missing or rejects, and the caller falls back to the console.
640
+ */
641
+ declare function copyStageExport(): Promise<string | null>;
321
642
 
322
643
  /**
323
644
  * Editor Host Helpers
@@ -401,6 +722,17 @@ interface MountZylemEditorOptions extends EditorStateBridgeOptions {
401
722
  * @default 'floating'
402
723
  */
403
724
  launcherMode?: EditorLauncherMode;
725
+ /**
726
+ * Dock layout to seed on first run, keyed by viewport edge. `'main'` is the
727
+ * editor panel; any other id is a section such as `'console'`. Ignored once
728
+ * the user has a saved layout.
729
+ *
730
+ * @example
731
+ * ```ts
732
+ * mountZylemEditor({ defaultDocks: { left: ['main'], bottom: ['console'] } });
733
+ * ```
734
+ */
735
+ defaultDocks?: EditorDockDefaults;
404
736
  /**
405
737
  * Element the <zylem-editor> overlay is appended to.
406
738
  * @default document.body
@@ -409,6 +741,8 @@ interface MountZylemEditorOptions extends EditorStateBridgeOptions {
409
741
  }
410
742
  interface MountedZylemEditor extends EditorStateBridge {
411
743
  element: ZylemEditorElement;
744
+ /** Dock a panel to a viewport edge, or pass `null` to float it again. */
745
+ dockPanel(side: DockSide | null, panelId?: DockPanelId): void;
412
746
  }
413
747
  /**
414
748
  * Imperatively mount a <zylem-editor> overlay and attach the state bridge.
@@ -422,4 +756,4 @@ interface MountedZylemEditor extends EditorStateBridge {
422
756
  */
423
757
  declare function mountZylemEditor(options?: MountZylemEditorOptions): MountedZylemEditor;
424
758
 
425
- export { type EditorEvent, type EditorEventType, type EditorStateBridge, type EditorStateBridgeOptions, type EditorUpdatePayload, Icon, type MountZylemEditorOptions, type MountedZylemEditor, type ZylemEditorConfig, ZylemEditorElement, attachEditorStateBridge, channel as bridgeChannel, connectEditorBridge, debugState, debugStore, disconnectEditorBridge, dispatchEditorUpdate, dispatchToEditor, editorEvents, gameState, mountZylemEditor, registerZylemEditor, sendDebugEnabled, sendEntityFocus, sendEntitySelect, sendPlayback, sendStageVariable, sendTool, stageState };
759
+ export { type CatalogState, DEFAULT_ROTATE_SNAP, DOCK_SIDES, type DockPanelId, type DockRect, type DockRegistry, type DockSide, type DockZoneState, type EditorDockDefaults, type EditorEvent, type EditorEventType, type EditorStateBridge, type EditorStateBridgeOptions, type EditorUpdatePayload, type HistoryState, Icon, MAIN_PANEL_ID, MAX_HISTORY_DEPTH, type MountZylemEditorOptions, type MountedZylemEditor, type SceneOperationListener, type StageExport, type StageExportEntity, type TransformState, type TransformToolGuardOptions, type ZylemEditorConfig, ZylemEditorElement, attachEditorStateBridge, channel as bridgeChannel, buildStageExport, canRedo, canUndo, catalogState, clearHistory, computeDockLayout, connectEditorBridge, copyStageExport, debugState, debugStore, disarmTools, disconnectEditorBridge, dispatchEditorUpdate, dispatchToEditor, dockPanelToSide, editorEvents, findDockedSide, gameState, getDockedSide, historyState, installTransformToolGuard, mountZylemEditor, onSceneOperation, redo, redoLabel, registerZylemEditor, releaseOrphanedTransformTool, sendAddType, sendDebugEnabled, sendEntityCreate, sendEntityFocus, sendEntitySelect, sendEntityTransform, sendGridVisible, sendPlayback, sendSnapSettings, sendStageVariable, sendTool, setArmedType, setEntityCatalog, setGridVisible, setSnapEnabled, setSnapIncrements, stageExportToString, stageState, transformState, undo, undoLabel, undockPanelFromSides };