react-dockable-desktop 3.2.0 → 4.1.0

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.
package/dist/index.d.ts CHANGED
@@ -1,6 +1,64 @@
1
1
  import React$1, { ComponentType, Context, Provider, ReactNode } from 'react';
2
- import { ContextMenuItem } from 'replace-react-contexify';
3
- export { ContextMenuItem, ContextMenuSeparator, ContextMenuSimpleItem, ContextMenuSubMenu } from 'replace-react-contexify';
2
+
3
+ interface ContextMenuPredefinedMessage$1 {
4
+ id: string;
5
+ defaultMessage?: string;
6
+ values?: Record<string, string | number>;
7
+ }
8
+ type MessageFormatter$1 = (msg: ContextMenuPredefinedMessage$1) => string;
9
+ type ContextMenuLabel = string | ContextMenuPredefinedMessage$1;
10
+ type MenuItemAction = () => void;
11
+
12
+ interface ContextMenuCheckbox {
13
+ /** Whether the checkbox column renders at all (default: true). */
14
+ active?: boolean;
15
+ /** Whether the item is interactive (default: true). Prefer top-level `disabled` on the item instead. */
16
+ enabled?: boolean;
17
+ /** Current checked state. */
18
+ value: boolean;
19
+ }
20
+ interface ContextMenuSimpleItem {
21
+ label: ContextMenuLabel;
22
+ icon?: React$1.ReactNode;
23
+ title?: ContextMenuLabel;
24
+ checkbox?: ContextMenuCheckbox;
25
+ action?: MenuItemAction;
26
+ cyAction?: string;
27
+ disabled?: boolean;
28
+ }
29
+ interface ContextMenuSeparator {
30
+ separator: true;
31
+ }
32
+ interface ContextMenuSubMenu {
33
+ label: ContextMenuLabel;
34
+ title?: ContextMenuLabel;
35
+ items?: ContextMenuItem[];
36
+ }
37
+ type ContextMenuItem = ContextMenuSimpleItem | ContextMenuSeparator | ContextMenuSubMenu;
38
+ interface ShowContextMenuOptions {
39
+ event?: React$1.MouseEvent | React$1.TouchEvent | MouseEvent | TouchEvent;
40
+ x?: number;
41
+ y?: number;
42
+ items: ContextMenuItem[];
43
+ }
44
+ interface ContextMenuHandle {
45
+ show(options: ShowContextMenuOptions): void;
46
+ }
47
+ interface ContextMenuProps {
48
+ theme?: string;
49
+ animation?: string;
50
+ formatMessageProvider?: MessageFormatter$1;
51
+ onShow?: () => void;
52
+ onHide?: () => void;
53
+ onOpenChange?: (open: boolean) => void;
54
+ className?: string;
55
+ style?: React$1.CSSProperties;
56
+ }
57
+ interface ContextMenuAdapter {
58
+ Component: React$1.ForwardRefExoticComponent<ContextMenuProps & React$1.RefAttributes<ContextMenuHandle>>;
59
+ }
60
+ declare const ContextMenu: React$1.ForwardRefExoticComponent<ContextMenuProps & React$1.RefAttributes<ContextMenuHandle>>;
61
+ declare const DefaultContextMenuAdapter: ContextMenuAdapter;
4
62
 
5
63
  /**
6
64
  * @file WindowManager.tsx
@@ -9,79 +67,167 @@ export { ContextMenuItem, ContextMenuSeparator, ContextMenuSimpleItem, ContextMe
9
67
  * resize handles, context menus, and taskbar docks. Exposes lifecycle event listeners.
10
68
  */
11
69
 
70
+ /** Controls when the minimized-panel taskbar is visible. */
71
+ type TaskbarVisibility = 'always' | 'compact' | 'autohide';
72
+ /** Props for `<WindowManager>`. */
12
73
  interface WindowManagerProps {
74
+ /** Built-in skin name or a custom skin key registered via CSS. @default 'vscode' */
13
75
  skin?: string;
76
+ /** Fallback icon shown in panel tabs when no panel-specific icon is provided. */
14
77
  defaultPanelIcon?: React$1.ReactNode;
15
- taskbarVisibility?: 'always' | 'compact' | 'autohide';
78
+ /**
79
+ * Controls taskbar visibility.
80
+ * - `'always'` — permanent bar at the bottom (default)
81
+ * - `'compact'` — only visible when minimized panels exist
82
+ * - `'autohide'` — overlay bar with 8 px peek strip
83
+ * @default 'always'
84
+ */
85
+ taskbarVisibility?: TaskbarVisibility;
86
+ /** Custom context menu renderer. Defaults to the built-in `DefaultContextMenuAdapter`. */
87
+ contextMenuAdapter?: ContextMenuAdapter;
16
88
  }
17
89
  declare const WindowManager: React$1.FC<WindowManagerProps>;
18
90
 
19
- /**
20
- * Represents a registered component configuration template inside the panel catalog registry.
21
- */
22
- interface PanelRegistryEntry {
23
- /** The React component type registered. */
24
- Component: ComponentType<any>;
25
- /** Default metadata settings configuration applied on instantiation. */
26
- defaultOptions?: {
27
- /** Tab and window headers text — plain string or i18n descriptor. */
28
- title?: string | {
29
- id: string;
30
- defaultMessage?: string;
31
- values?: Record<string, string | number>;
32
- };
33
- /** Icon placed next to title tags. */
34
- icon?: React.ReactNode;
35
- /** Initial mounting state inside the desktop layout grid. */
36
- initialTarget?: 'floating' | 'docked' | 'tabbed';
37
- /** Custom default bounds applied when the container is floated. */
38
- favoritePosition?: {
39
- x: number | string;
40
- y: number | string;
41
- width: number | string;
42
- height: number | string;
43
- };
44
- /** Enables/disables window drag interactions. */
45
- canDrag?: boolean;
46
- /** Enables/disables minimizing of the panel instance. */
47
- canMinimize?: boolean;
48
- /** Enables/disables closing actions for the tab/window. */
49
- canClose?: boolean;
50
- /** Affixes the panel to the right edge. */
51
- defaultStickyRight?: boolean;
52
- /** Affixes the panel to the bottom edge. */
53
- defaultStickyBottom?: boolean;
54
- /** Disables live WebGL rendering canvas thumbnails inside the taskbar hover popup previews. */
55
- disableLivePreview?: boolean;
56
- /** Custom header actions renderer, placing custom components in the window/tab titlebar. */
57
- renderHeaderActions?: (panelId: string) => React.ReactNode;
91
+ /** Built-in lifecycle events always available on the WorkspaceClient event bus. */
92
+ interface BuiltInPanelEvents {
93
+ 'panel:opened': {
94
+ id: string;
95
+ component: string;
96
+ };
97
+ 'panel:closed': {
98
+ id: string;
99
+ };
100
+ 'panel:minimized': {
101
+ id: string;
102
+ };
103
+ 'panel:restored': {
104
+ id: string;
58
105
  };
59
106
  }
60
- /**
61
- * Registry mapping catalog entries to allow programmatic panel instantiation
62
- * inside dynamic layout cells or floating windows.
63
- * Exported so WorkspaceClient can create scoped, per-instance registries.
64
- */
65
- declare class PanelRegistryClass {
66
- private registry;
107
+ /** Per-panel definition supplied to WorkspaceClient constructor. */
108
+ interface PanelDefinition {
109
+ component: ComponentType<any>;
110
+ defaultOptions?: PanelRegistryEntry['defaultOptions'];
111
+ }
112
+ /** Configuration object accepted by the WorkspaceClient constructor. */
113
+ interface WorkspaceClientConfig {
67
114
  /**
68
- * Register a new component to the panel catalog registry.
69
- * @param id - Unique string identifier.
70
- * @param Component - React component instance template.
71
- * @param defaultOptions - Custom default settings configuration.
115
+ * Declarative panel catalog. Replaces imperative PanelRegistry.register() calls.
116
+ * Keys are the component identifiers used in openPanel() and serialised layouts.
72
117
  */
73
- register<P extends object>(id: string, Component: ComponentType<P>, defaultOptions?: PanelRegistryEntry['defaultOptions']): void;
118
+ panels?: Record<string, PanelDefinition>;
74
119
  /**
75
- * Retrieve a registered panel configuration by identifier.
120
+ * Serialised layout produced by a previous saveLayout() call.
121
+ * Pass null or omit to start with an empty canvas.
76
122
  */
77
- get(id: string): PanelRegistryEntry | undefined;
123
+ initialState?: string | null;
124
+ /** Custom i18n formatter for all internal strings. */
125
+ formatMessage?: MessageFormatter;
126
+ /** Override any subset of the built-in predefined message catalog. */
127
+ predefinedMessages?: Record<string, ContextMenuPredefinedMessage>;
128
+ /** Initial layout direction. */
129
+ dir?: 'ltr' | 'rtl';
78
130
  /**
79
- * Returns a list of all registered panel entry identifiers.
131
+ * Fraction of the target panel the new panel takes when dropped on a panel's
132
+ * top/bottom/left/right cross target. Range 0.1–0.9. Default: 0.5.
80
133
  */
81
- getRegisteredIds(): string[];
134
+ defaultSplitRatio?: number;
135
+ /**
136
+ * Fraction of the workspace the new panel takes when dropped on the workspace
137
+ * outer edge. Range 0.1–0.9. Default: 0.2.
138
+ */
139
+ defaultEdgeSplitRatio?: number;
140
+ }
141
+ /**
142
+ * WorkspaceClient is the central configuration and imperative API object for
143
+ * react-dockable-desktop. Create one instance outside the React tree and pass
144
+ * it to `<WindowManagerProvider client={client}>`.
145
+ *
146
+ * Pattern: TanStack QueryClient / Redux store — configuration and imperative
147
+ * access live on the client; rendering is delegated to the thin React provider.
148
+ *
149
+ * @remarks
150
+ * Calls made before the provider mounts are queued and replayed automatically
151
+ * in order once `_connect()` fires. Duplicate `openPanel` calls for the same
152
+ * ID are deduplicated while queued. Subscriptions made before mount are
153
+ * buffered and re-registered on each connect/reconnect.
154
+ *
155
+ * @example
156
+ * const workspace = new WorkspaceClient<MyEvents>({
157
+ * panels: {
158
+ * map: { component: MapPanel },
159
+ * editor: { component: EditorPanel, defaultOptions: { title: 'Code Editor' } },
160
+ * },
161
+ * initialState: localStorage.getItem('layout'),
162
+ * });
163
+ *
164
+ * <WindowManagerProvider client={workspace}>
165
+ * <WindowManager />
166
+ * </WindowManagerProvider>
167
+ *
168
+ * // Imperative access from anywhere:
169
+ * workspace.saveLayout();
170
+ * workspace.openPanel('map-1', 'map');
171
+ * workspace.focusPanel('map-1');
172
+ */
173
+ declare class WorkspaceClient<TUserEvents extends Record<string, unknown> = Record<string, unknown>> {
174
+ /** Scoped panel registry — fully independent from the global singleton. */
175
+ readonly registry: PanelRegistryClass;
176
+ /** Serialised layout to restore on mount, or null to start with an empty canvas. */
177
+ readonly initialState: string | null;
178
+ /** Non-rendering configuration forwarded to the provider. */
179
+ readonly config: Pick<WorkspaceClientConfig, 'formatMessage' | 'predefinedMessages' | 'dir' | 'defaultSplitRatio' | 'defaultEdgeSplitRatio'>;
180
+ private _actions;
181
+ private _initialized;
182
+ /** Calls queued before _connect() fires — replayed in order on first connect. */
183
+ private _pendingCalls;
184
+ /** Tracks openPanel IDs in the pending queue to prevent duplicates before mount. */
185
+ private _pendingOpenPanelIds;
186
+ /** Subscriptions buffered before connect — re-registered on every connect/reconnect. */
187
+ private _pendingSubscriptions;
188
+ /** Timer that emits an error if _connect() is never called with pending work. */
189
+ private _disconnectedWarnTimer;
190
+ constructor(config?: WorkspaceClientConfig);
191
+ /** @internal Called by WindowManagerProvider after mount. */
192
+ _connect(actions: WindowActions): void;
193
+ /** @internal Called by WindowManagerProvider on unmount. */
194
+ _disconnect(): void;
195
+ /** True while the provider is mounted and React state is accessible. */
196
+ get isConnected(): boolean;
197
+ private _startWarnTimer;
198
+ private _dispatch;
199
+ private _subscribeRaw;
200
+ openPanel(...args: Parameters<WindowActions['openPanel']>): void;
201
+ closePanel(id: string): void;
202
+ minimizePanel(id: string): void;
203
+ restorePanel(id: string): void;
204
+ floatPanel(...args: Parameters<WindowActions['floatPanel']>): void;
205
+ dockPanel(...args: Parameters<WindowActions['dockPanel']>): void;
206
+ maximizePanel(id: string): void;
207
+ /**
208
+ * Activates the given panel regardless of its current state.
209
+ * For floating panels: raises z-index so the window appears on top.
210
+ * For docked panels: selects the tab within its leaf group.
211
+ */
212
+ focusPanel(id: string): void;
213
+ /** Returns `true` if a panel with this ID is currently open. */
214
+ isOpen(id: string): boolean;
215
+ /** Returns the IDs of all currently open panels. */
216
+ getOpenPanelIds(): string[];
217
+ saveLayout(): string;
218
+ loadLayout(json: string): boolean;
219
+ setDirection(dir: 'ltr' | 'rtl'): void;
220
+ publish<K extends keyof (TUserEvents & BuiltInPanelEvents)>(event: K, data: (TUserEvents & BuiltInPanelEvents)[K]): void;
221
+ subscribe<K extends keyof (TUserEvents & BuiltInPanelEvents)>(event: K, callback: (data: (TUserEvents & BuiltInPanelEvents)[K]) => void): () => void;
222
+ /** Subscribe to panel open events. Fires only for newly created panels. */
223
+ onPanelOpen(callback: (id: string, component: string) => void): () => void;
224
+ /** Subscribe to panel close events. */
225
+ onPanelClose(callback: (id: string) => void): () => void;
226
+ /** Subscribe to panel minimize events. */
227
+ onPanelMinimize(callback: (id: string) => void): () => void;
228
+ /** Subscribe to panel restore events. */
229
+ onPanelRestore(callback: (id: string) => void): () => void;
82
230
  }
83
- /** Global singleton instance of the Panel Registry. */
84
- declare const PanelRegistry: PanelRegistryClass;
85
231
 
86
232
  /**
87
233
  * @file predefinedMessages.ts
@@ -144,18 +290,6 @@ declare const defaultPredefinedMessages: {
144
290
  readonly id: "dockable-desktop-closeEmptyGroup";
145
291
  readonly defaultMessage: "Close empty split group";
146
292
  };
147
- readonly anchorToRightEdge: {
148
- readonly id: "dockable-desktop-anchorToRightEdge";
149
- readonly defaultMessage: "Anchor to Right Edge";
150
- };
151
- readonly anchorToBottomEdge: {
152
- readonly id: "dockable-desktop-anchorToBottomEdge";
153
- readonly defaultMessage: "Anchor to Bottom Edge";
154
- };
155
- readonly windowAnchoringOptions: {
156
- readonly id: "dockable-desktop-windowAnchoringOptions";
157
- readonly defaultMessage: "Window Anchoring Options";
158
- };
159
293
  readonly unsavedChangesTitle: {
160
294
  readonly id: "dockable-desktop-unsavedChangesTitle";
161
295
  readonly defaultMessage: "Unsaved Changes";
@@ -290,6 +424,8 @@ interface LayoutLeafNode {
290
424
  }
291
425
  /** Union type representing either a branch or a leaf node in the layout grid. */
292
426
  type LayoutNode = LayoutGridNode | LayoutLeafNode;
427
+ /** Corner of the workspace a floating window is pinned to. */
428
+ type FloatAnchor = 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';
293
429
  /**
294
430
  * Bounds and depth metadata for floated panel windows.
295
431
  */
@@ -308,10 +444,8 @@ interface FloatingWindow {
308
444
  z: number;
309
445
  /** True if the window is currently maximized to full workspace bounds. */
310
446
  maximized?: boolean;
311
- /** Sticky right flag. */
312
- stickyRight?: boolean;
313
- /** Sticky bottom flag. */
314
- stickyBottom?: boolean;
447
+ /** Corner of the workspace this window is pinned to, or null when free-floating. */
448
+ anchor?: FloatAnchor | null;
315
449
  }
316
450
  /**
317
451
  * Stores active runtime properties and status metadata for individual panel instances.
@@ -333,8 +467,7 @@ interface PanelInfo {
333
467
  y: number;
334
468
  width: number;
335
469
  height: number;
336
- stickyRight?: boolean;
337
- stickyBottom?: boolean;
470
+ anchor?: FloatAnchor | null;
338
471
  };
339
472
  /** The leaf group ID this panel was docked in prior to being floated. */
340
473
  lastLeafId?: string;
@@ -367,6 +500,10 @@ interface WindowState {
367
500
  dir: 'ltr' | 'rtl';
368
501
  /** Convenient boolean flag indicating RTL direction */
369
502
  isRtl: boolean;
503
+ /** Split ratio for panel cross-target drops (0.1–0.9). Default 0.5. */
504
+ splitRatio: number;
505
+ /** Split ratio for workspace outer-edge drops (0.1–0.9). Default 0.2. */
506
+ edgeSplitRatio: number;
370
507
  }
371
508
  /**
372
509
  * All layout mutation methods, event bus handles, and serialization methods
@@ -399,8 +536,7 @@ interface WindowActions {
399
536
  openPanel: (id: string, component: string, options?: {
400
537
  title?: string | ContextMenuPredefinedMessage;
401
538
  initialTarget?: 'floating' | 'docked' | 'tabbed';
402
- stickyRight?: boolean;
403
- stickyBottom?: boolean;
539
+ anchor?: FloatAnchor | null;
404
540
  }) => void;
405
541
  /**
406
542
  * Closes a panel immediately, bypassing dirty-state close guards.
@@ -428,7 +564,7 @@ interface WindowActions {
428
564
  y: number;
429
565
  width: number;
430
566
  height: number;
431
- }) => void;
567
+ }, anchor?: FloatAnchor | null) => void;
432
568
  /**
433
569
  * Returns a floating window to a docked grid tab group.
434
570
  * @param id - Panel instance ID.
@@ -449,9 +585,9 @@ interface WindowActions {
449
585
  /**
450
586
  * Updates the position or size of a floating window.
451
587
  * @param id - Panel instance ID.
452
- * @param updates - Partial update to `x`, `y`, `width`, `height`, `stickyRight`, or `stickyBottom`.
588
+ * @param updates - Partial update to `x`, `y`, `width`, `height`, or `anchor`.
453
589
  */
454
- updateFloatingPosition: (id: string, updates: Partial<Pick<FloatingWindow, 'x' | 'y' | 'width' | 'height' | 'stickyRight' | 'stickyBottom'>>) => void;
590
+ updateFloatingPosition: (id: string, updates: Partial<Pick<FloatingWindow, 'x' | 'y' | 'width' | 'height' | 'anchor'>>) => void;
455
591
  /**
456
592
  * Activates the given panel regardless of its current state.
457
593
  * - Floating panel: raises z-index so the window appears on top of others.
@@ -615,19 +751,37 @@ declare const useStyleClasses: () => StyleClasses;
615
751
  * ```
616
752
  */
617
753
  declare const useRegistry: () => PanelRegistryClass;
754
+ /**
755
+ * Props for `<DockableDesktopProvider>` and `<WindowManagerProvider>`.
756
+ * Also exported as `DockableDesktopProviderProps` for consumers who use
757
+ * the composite provider.
758
+ * @see DockableDesktopProviderProps
759
+ */
618
760
  interface WindowManagerProviderProps {
619
761
  children: React$1.ReactNode;
620
- /** WorkspaceClient instance created outside the React tree. When provided, its registry
621
- * and config take precedence over the individual props below. */
762
+ /** `WorkspaceClient` instance created outside the React tree. When provided, its panel
763
+ * registry and config take precedence over the individual props below. */
622
764
  client?: WorkspaceClient;
765
+ /** Custom i18n formatter. Receives a `{ id, defaultMessage }` descriptor and returns
766
+ * the translated string. When omitted, `defaultMessage` is used as-is. */
623
767
  formatMessage?: MessageFormatter;
768
+ /** Override the built-in predefined UI strings (confirm button labels, close tooltips, etc.).
769
+ * Merge with or replace `defaultPredefinedMessages` to localise system strings. */
624
770
  predefinedMessages?: Record<string, ContextMenuPredefinedMessage>;
771
+ /** Layout direction. `'rtl'` mirrors all controls, tab order, and drop zones.
772
+ * Can also be changed at runtime via `WorkspaceClient.setDirection()`. @default 'ltr' */
625
773
  dir?: 'ltr' | 'rtl';
774
+ /** CSS class applied to the outer wrapper element of every modal overlay. */
626
775
  modalClass?: string;
776
+ /** CSS class applied to the inner content area of every modal overlay. */
627
777
  modalBodyClass?: string;
778
+ /** CSS class applied to the outer wrapper of left/right side-panel drawers. */
628
779
  sidePanelClass?: string;
780
+ /** CSS class applied to the inner content area of side-panel drawers. */
629
781
  sidePanelBodyClass?: string;
782
+ /** CSS class applied to the outer wrapper of floating panel windows. */
630
783
  windowClass?: string;
784
+ /** CSS class applied to the inner content area of floating panel windows. */
631
785
  windowBodyClass?: string;
632
786
  }
633
787
  declare const WindowManagerProvider: React$1.FC<WindowManagerProviderProps>;
@@ -706,137 +860,76 @@ declare const usePanelId: () => string;
706
860
  */
707
861
  declare function usePanelContextMenu(items: ContextMenuItem[]): void;
708
862
 
709
- /** Built-in lifecycle events always available on the WorkspaceClient event bus. */
710
- interface BuiltInPanelEvents {
711
- 'panel:opened': {
712
- id: string;
713
- component: string;
714
- };
715
- 'panel:closed': {
716
- id: string;
717
- };
718
- 'panel:minimized': {
719
- id: string;
720
- };
721
- 'panel:restored': {
722
- id: string;
863
+ /**
864
+ * Represents a registered component configuration template inside the panel catalog registry.
865
+ */
866
+ interface PanelRegistryEntry {
867
+ /** The React component type registered. */
868
+ Component: ComponentType<any>;
869
+ /** Default metadata settings configuration applied on instantiation. */
870
+ defaultOptions?: {
871
+ /** Tab and window headers text — plain string or i18n descriptor. */
872
+ title?: string | {
873
+ id: string;
874
+ defaultMessage?: string;
875
+ values?: Record<string, string | number>;
876
+ };
877
+ /** Icon placed next to title tags. */
878
+ icon?: React.ReactNode;
879
+ /** Initial mounting state inside the desktop layout grid. */
880
+ initialTarget?: 'floating' | 'docked' | 'tabbed';
881
+ /** Custom default bounds applied when the container is floated. */
882
+ favoritePosition?: {
883
+ x: number | string;
884
+ y: number | string;
885
+ width: number | string;
886
+ height: number | string;
887
+ };
888
+ /** Enables/disables window drag interactions. */
889
+ canDrag?: boolean;
890
+ /** Enables/disables minimizing of the panel instance. */
891
+ canMinimize?: boolean;
892
+ /** Enables/disables closing actions for the tab/window. */
893
+ canClose?: boolean;
894
+ /** Corner of the workspace to anchor newly-opened floating windows to. */
895
+ defaultAnchor?: FloatAnchor;
896
+ /** Disables live WebGL rendering canvas thumbnails inside the taskbar hover popup previews. */
897
+ disableLivePreview?: boolean;
898
+ /** Custom header actions renderer, placing custom components in the window/tab titlebar. */
899
+ renderHeaderActions?: (panelId: string) => React.ReactNode;
723
900
  };
724
901
  }
725
- /** Per-panel definition supplied to WorkspaceClient constructor. */
726
- interface PanelDefinition {
727
- component: ComponentType<any>;
728
- defaultOptions?: PanelRegistryEntry['defaultOptions'];
729
- }
730
- /** Configuration object accepted by the WorkspaceClient constructor. */
731
- interface WorkspaceClientConfig {
902
+ /**
903
+ * Registry mapping catalog entries to allow programmatic panel instantiation
904
+ * inside dynamic layout cells or floating windows.
905
+ * Exported so WorkspaceClient can create scoped, per-instance registries.
906
+ */
907
+ declare class PanelRegistryClass {
908
+ private registry;
732
909
  /**
733
- * Declarative panel catalog. Replaces imperative PanelRegistry.register() calls.
734
- * Keys are the component identifiers used in openPanel() and serialised layouts.
910
+ * Register a new component to the panel catalog registry.
911
+ * @param id - Unique string identifier.
912
+ * @param Component - React component instance template.
913
+ * @param defaultOptions - Custom default settings configuration.
735
914
  */
736
- panels?: Record<string, PanelDefinition>;
915
+ register<P extends object>(id: string, Component: ComponentType<P>, defaultOptions?: PanelRegistryEntry['defaultOptions']): void;
737
916
  /**
738
- * Serialised layout produced by a previous saveLayout() call.
739
- * Pass null or omit to start with an empty canvas.
917
+ * Retrieve a registered panel configuration by identifier.
740
918
  */
741
- initialState?: string | null;
742
- /** Custom i18n formatter for all internal strings. */
743
- formatMessage?: MessageFormatter;
744
- /** Override any subset of the built-in predefined message catalog. */
745
- predefinedMessages?: Record<string, ContextMenuPredefinedMessage>;
746
- /** Initial layout direction. */
747
- dir?: 'ltr' | 'rtl';
748
- }
749
- /**
750
- * WorkspaceClient is the central configuration and imperative API object for
751
- * react-dockable-desktop. Create one instance outside the React tree and pass
752
- * it to `<WindowManagerProvider client={client}>`.
753
- *
754
- * Pattern: TanStack QueryClient / Redux store — configuration and imperative
755
- * access live on the client; rendering is delegated to the thin React provider.
756
- *
757
- * @remarks
758
- * Calls made before the provider mounts are queued and replayed automatically
759
- * in order once `_connect()` fires. Duplicate `openPanel` calls for the same
760
- * ID are deduplicated while queued. Subscriptions made before mount are
761
- * buffered and re-registered on each connect/reconnect.
762
- *
763
- * @example
764
- * const workspace = new WorkspaceClient<MyEvents>({
765
- * panels: {
766
- * map: { component: MapPanel },
767
- * editor: { component: EditorPanel, defaultOptions: { title: 'Code Editor' } },
768
- * },
769
- * initialState: localStorage.getItem('layout'),
770
- * });
771
- *
772
- * <WindowManagerProvider client={workspace}>
773
- * <WindowManager />
774
- * </WindowManagerProvider>
775
- *
776
- * // Imperative access from anywhere:
777
- * workspace.saveLayout();
778
- * workspace.openPanel('map-1', 'map');
779
- * workspace.focusPanel('map-1');
780
- */
781
- declare class WorkspaceClient<TUserEvents extends Record<string, unknown> = Record<string, unknown>> {
782
- /** Scoped panel registry — fully independent from the global singleton. */
783
- readonly registry: PanelRegistryClass;
784
- /** Serialised layout to restore on mount, or null to start with an empty canvas. */
785
- readonly initialState: string | null;
786
- /** Non-rendering configuration forwarded to the provider. */
787
- readonly config: Pick<WorkspaceClientConfig, 'formatMessage' | 'predefinedMessages' | 'dir'>;
788
- private _actions;
789
- private _initialized;
790
- /** Calls queued before _connect() fires — replayed in order on first connect. */
791
- private _pendingCalls;
792
- /** Tracks openPanel IDs in the pending queue to prevent duplicates before mount. */
793
- private _pendingOpenPanelIds;
794
- /** Subscriptions buffered before connect — re-registered on every connect/reconnect. */
795
- private _pendingSubscriptions;
796
- /** Timer that emits an error if _connect() is never called with pending work. */
797
- private _disconnectedWarnTimer;
798
- constructor(config?: WorkspaceClientConfig);
799
- /** @internal Called by WindowManagerProvider after mount. */
800
- _connect(actions: WindowActions): void;
801
- /** @internal Called by WindowManagerProvider on unmount. */
802
- _disconnect(): void;
803
- /** True while the provider is mounted and React state is accessible. */
804
- get isConnected(): boolean;
805
- private _startWarnTimer;
806
- private _dispatch;
807
- private _subscribeRaw;
808
- openPanel(...args: Parameters<WindowActions['openPanel']>): void;
809
- closePanel(id: string): void;
810
- minimizePanel(id: string): void;
811
- restorePanel(id: string): void;
812
- floatPanel(...args: Parameters<WindowActions['floatPanel']>): void;
813
- dockPanel(...args: Parameters<WindowActions['dockPanel']>): void;
814
- maximizePanel(id: string): void;
919
+ get(id: string): PanelRegistryEntry | undefined;
815
920
  /**
816
- * Activates the given panel regardless of its current state.
817
- * For floating panels: raises z-index so the window appears on top.
818
- * For docked panels: selects the tab within its leaf group.
921
+ * Returns a list of all registered panel entry identifiers.
819
922
  */
820
- focusPanel(id: string): void;
821
- /** Returns `true` if a panel with this ID is currently open. */
822
- isOpen(id: string): boolean;
823
- /** Returns the IDs of all currently open panels. */
824
- getOpenPanelIds(): string[];
825
- saveLayout(): string;
826
- loadLayout(json: string): boolean;
827
- setDirection(dir: 'ltr' | 'rtl'): void;
828
- publish<K extends keyof (TUserEvents & BuiltInPanelEvents)>(event: K, data: (TUserEvents & BuiltInPanelEvents)[K]): void;
829
- subscribe<K extends keyof (TUserEvents & BuiltInPanelEvents)>(event: K, callback: (data: (TUserEvents & BuiltInPanelEvents)[K]) => void): () => void;
830
- /** Subscribe to panel open events. Fires only for newly created panels. */
831
- onPanelOpen(callback: (id: string, component: string) => void): () => void;
832
- /** Subscribe to panel close events. */
833
- onPanelClose(callback: (id: string) => void): () => void;
834
- /** Subscribe to panel minimize events. */
835
- onPanelMinimize(callback: (id: string) => void): () => void;
836
- /** Subscribe to panel restore events. */
837
- onPanelRestore(callback: (id: string) => void): () => void;
923
+ getRegisteredIds(): string[];
838
924
  }
925
+ /** Global singleton instance of the Panel Registry. */
926
+ declare const PanelRegistry: PanelRegistryClass;
839
927
 
928
+ /**
929
+ * Props for `<DockableDesktopProvider>`. Alias of `WindowManagerProviderProps`.
930
+ * @see WindowManagerProviderProps
931
+ */
932
+ type DockableDesktopProviderProps = WindowManagerProviderProps;
840
933
  /**
841
934
  * Composite provider that wraps both `WindowManagerProvider` and `PanelProvider`
842
935
  * in the correct order. Drop-in replacement for manually nesting both providers.
@@ -1259,7 +1352,7 @@ interface ToolbarToggleItem {
1259
1352
  disabled?: boolean;
1260
1353
  }
1261
1354
  /** A visual divider between button groups. */
1262
- interface ToolbarSeparator {
1355
+ interface ToolbarSeparator$1 {
1263
1356
  type: 'separator';
1264
1357
  }
1265
1358
  /**
@@ -1314,12 +1407,12 @@ interface ToolbarGroupItem {
1314
1407
  */
1315
1408
  onActiveItemChange?: (id: string) => void;
1316
1409
  }
1317
- type ToolbarItem = ToolbarActionItem | ToolbarRadioItem | ToolbarToggleItem | ToolbarGroupItem | ToolbarSeparator;
1410
+ type ToolbarItem$1 = ToolbarActionItem | ToolbarRadioItem | ToolbarToggleItem | ToolbarGroupItem | ToolbarSeparator$1;
1318
1411
  interface ToolbarProps {
1319
1412
  /** Side the strip is attached to. Controls strip orientation. Default: 'left' */
1320
1413
  position?: 'left' | 'right' | 'top' | 'bottom';
1321
1414
  /** Ordered list of items to render. */
1322
- items: ToolbarItem[];
1415
+ items: ToolbarItem$1[];
1323
1416
  /** Collapse the strip to zero width/height. State is preserved — no unmount. */
1324
1417
  visible?: boolean;
1325
1418
  /** Called when show/hide/toggle is invoked on the imperative handle. */
@@ -1334,4 +1427,375 @@ interface ToolbarHandle {
1334
1427
  }
1335
1428
  declare const Toolbar: React$1.ForwardRefExoticComponent<ToolbarProps & React$1.RefAttributes<ToolbarHandle>>;
1336
1429
 
1337
- export { type BuiltInPanelEvents, type CloseOptions, ConfirmationForm, type ConfirmationFormProps, type ContextMenuPredefinedMessage, DockableDesktopProvider, type DropPosition, type DropTarget, type FloatingWindow, FormContainerContext, type FormContainerContract, FormContainerProvider, type LayoutGridNode, type LayoutLeafNode, type LayoutNode, LeftPanelRenderer, type MessageFormatter, type ModalOptions, ModalStackRenderer, type PanelActions, type PanelDefinition, type PanelInfo, type PanelInstance, type PanelInstanceId, PanelProvider, PanelRegistry, PanelRegistryClass, type PanelRegistryEntry, type PanelState, type PanelTitle, type PredefinedMessageKey, RightPanelRenderer, type SidePanelOptions, SidePanelRenderer, type SidePanelRendererProps, Sidebar, type SidebarContextValue, type SidebarHandle, type SidebarProps, type SidebarTab, type SidebarTabContextValue, type SplitDirection, type SplitOrientation, type StyleClasses, Toolbar, type ToolbarActionItem, type ToolbarContextValue, type ToolbarGroupEntry, type ToolbarGroupItem, type ToolbarGroupSubItem, type ToolbarHandle, type ToolbarItem, type ToolbarProps, ToolbarProvider, type ToolbarRadioItem, type ToolbarSeparator, type ToolbarToggleItem, type WindowActions, WindowManager, WindowManagerProvider, type WindowState, WorkspaceClient, type WorkspaceClientConfig, defaultPredefinedMessages, formatLabel, useFormContainer, useFormatMessage, usePanelActions, usePanelContext, usePanelContextMenu, usePanelId, usePanelState, usePredefinedMessages, useRegistry, useSidebar, useSidebarTab, useStyleClasses, useToolbar, useWindowManagerActions, useWindowManagerState };
1430
+ /** Visual type of a toast notification. Determines the icon and accent color. */
1431
+ type ToastType = 'info' | 'success' | 'warning' | 'error';
1432
+ /** Corner position of the `<ToastContainer>` relative to the viewport. */
1433
+ type ToastPosition = 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';
1434
+ /**
1435
+ * Per-notification options passed to `toast()`, `toast.info()`, etc.
1436
+ * All fields are optional and fall back to `<ToastContainer>` defaults when unset.
1437
+ */
1438
+ interface ToastOptions {
1439
+ /** Visual type. Overridden by the `toast.info/success/warning/error` shorthands. @default 'info' */
1440
+ type?: ToastType;
1441
+ /** Auto-dismiss delay in ms. `0` = sticky (never auto-dismisses). @default from container */
1442
+ duration?: number;
1443
+ /** Explicit ID for dedup — calling `toast.*` with the same `id` updates the existing card in-place. */
1444
+ id?: string;
1445
+ /** Show the × close button on this notification. @default from container */
1446
+ closable?: boolean;
1447
+ /** Override the built-in type icon with arbitrary content. */
1448
+ icon?: React$1.ReactNode;
1449
+ /** Replace the string message with arbitrary JSX. */
1450
+ content?: React$1.ReactNode;
1451
+ /** Called when the notification is dismissed by timer, close button, or `toast.dismiss()`. */
1452
+ onClose?: () => void;
1453
+ }
1454
+ /**
1455
+ * Fully-resolved options passed to `ToastAdapter.show()` and `ToastAdapter.update()`.
1456
+ * All optional `ToastOptions` fields are resolved against the container defaults.
1457
+ */
1458
+ interface ResolvedToastOptions {
1459
+ id: string;
1460
+ type: ToastType;
1461
+ duration: number;
1462
+ closable: boolean;
1463
+ icon?: React$1.ReactNode;
1464
+ content?: React$1.ReactNode;
1465
+ onClose?: () => void;
1466
+ }
1467
+ /**
1468
+ * Props for `<ToastContainer>`. Mount one instance at your app root alongside `ModalStackRenderer`.
1469
+ * @example
1470
+ * <ToastContainer position="top-right" progressBar />
1471
+ */
1472
+ interface ToastContainerProps {
1473
+ /** Where notifications appear in the viewport. @default 'top-right' */
1474
+ position?: ToastPosition;
1475
+ /** Maximum number of notifications shown simultaneously. Extras are queued. @default 3 */
1476
+ maxVisible?: number;
1477
+ /** Default auto-dismiss delay in ms. `0` = all notifications sticky. @default 5000 */
1478
+ defaultDuration?: number;
1479
+ /** Show the × close button on all notifications unless overridden per-toast. @default true */
1480
+ defaultClosable?: boolean;
1481
+ /** Pause the auto-dismiss timer while the cursor is over a notification. @default true */
1482
+ pauseOnHover?: boolean;
1483
+ /** Entry/exit animation style. @default 'slide' */
1484
+ animation?: 'slide' | 'fade' | 'none';
1485
+ /** When `true`, newest notification appears at the top of the stack. @default false */
1486
+ newestOnTop?: boolean;
1487
+ /** Show a countdown progress bar at the bottom of each notification. @default false */
1488
+ progressBar?: boolean;
1489
+ /** Width of each notification card in pixels. @default 320 */
1490
+ width?: number;
1491
+ /** Delegate all `toast.*` calls to a custom renderer (Ant Design, MUI, Sonner, etc.). */
1492
+ adapter?: ToastAdapter;
1493
+ }
1494
+ /**
1495
+ * Message set for `toast.promise()`. Each field may be static content or a function
1496
+ * that receives the resolved/rejected value and returns renderable content.
1497
+ * @template T The resolved value type of the tracked promise.
1498
+ */
1499
+ interface ToastPromiseMessages<T> {
1500
+ /** Shown while the promise is pending. */
1501
+ pending: React$1.ReactNode;
1502
+ /** Shown on fulfillment. Pass a function to include the resolved value. */
1503
+ success: React$1.ReactNode | ((result: T) => React$1.ReactNode);
1504
+ /** Shown on rejection. Pass a function to include the error reason. */
1505
+ error: React$1.ReactNode | ((err: unknown) => React$1.ReactNode);
1506
+ }
1507
+ /**
1508
+ * Strategy interface for replacing the built-in toast renderer with an external library.
1509
+ * Pass an instance via `<ToastContainer adapter={...} />` to redirect all `toast.*` calls
1510
+ * without changing any call sites in your application.
1511
+ * @see ToastContainerProps.adapter
1512
+ */
1513
+ interface ToastAdapter {
1514
+ /** Called when a new notification is requested. */
1515
+ show(id: string, message: React$1.ReactNode, options: ResolvedToastOptions): void;
1516
+ /** Called when an existing notification is updated (e.g. after `toast.promise()` resolves). */
1517
+ update(id: string, message: React$1.ReactNode, options: Partial<ResolvedToastOptions>): void;
1518
+ /** Called to dismiss one notification (`id` provided) or all active notifications (no `id`). */
1519
+ dismiss(id?: string): void;
1520
+ /**
1521
+ * `null` means the adapter manages its own DOM and `<ToastContainer>` renders nothing.
1522
+ * A component causes `<ToastContainer>` to portal-render it with a `position` prop.
1523
+ */
1524
+ Container: React$1.ComponentType<{
1525
+ position: ToastPosition;
1526
+ }> | null;
1527
+ }
1528
+ /**
1529
+ * Type of the `toast` singleton. Callable directly or via named shorthand methods.
1530
+ * Import this type to annotate variables or props that accept the `toast` object.
1531
+ * @example
1532
+ * function notify(fn: ToastFunction) { fn.success('Done!'); }
1533
+ */
1534
+ interface ToastFunction {
1535
+ /** Show a notification. `opts.type` defaults to `'info'`. Returns the notification ID. */
1536
+ (msg: React$1.ReactNode, opts?: ToastOptions): string;
1537
+ /** Show an info notification. Returns the notification ID. */
1538
+ info: (msg: React$1.ReactNode, opts?: ToastOptions) => string;
1539
+ /** Show a success notification. Returns the notification ID. */
1540
+ success: (msg: React$1.ReactNode, opts?: ToastOptions) => string;
1541
+ /** Show a warning notification. Returns the notification ID. */
1542
+ warning: (msg: React$1.ReactNode, opts?: ToastOptions) => string;
1543
+ /** Show an error notification. Returns the notification ID. */
1544
+ error: (msg: React$1.ReactNode, opts?: ToastOptions) => string;
1545
+ /** Dismiss a notification by ID, or all active notifications when called with no argument. */
1546
+ dismiss: (id?: string) => void;
1547
+ /**
1548
+ * Track a promise through pending → success/error states.
1549
+ * Shows a sticky pending notification immediately, then transitions it on settlement.
1550
+ * @template T The resolved value type of the promise.
1551
+ */
1552
+ promise: <T>(promise: Promise<T>, messages: ToastPromiseMessages<T>, opts?: ToastOptions) => Promise<T>;
1553
+ }
1554
+ /**
1555
+ * Imperative notification singleton. Call from anywhere — inside or outside React.
1556
+ * Mount `<ToastContainer>` once at your app root to activate the renderer.
1557
+ * @example
1558
+ * toast.success('File saved.');
1559
+ * toast.error('Upload failed.', { duration: 0 }); // sticky
1560
+ * toast.promise(saveFile(), { pending: 'Saving…', success: 'Saved!', error: 'Failed.' });
1561
+ */
1562
+ declare const toast: ToastFunction;
1563
+ /**
1564
+ * Portal-rendered notification host. Mount once at your app root, outside the workspace
1565
+ * container. All `toast.*` calls are routed here automatically via the internal event emitter.
1566
+ * @example
1567
+ * <ToastContainer position="top-right" progressBar />
1568
+ */
1569
+ declare function ToastContainer({ position, maxVisible, defaultDuration, defaultClosable, pauseOnHover, animation, newestOnTop, progressBar, width, adapter, }: ToastContainerProps): React$1.ReactElement | null;
1570
+
1571
+ /** Edge of a panel to which a `PanelToolbar` attaches. */
1572
+ type ToolbarPosition = 'top' | 'bottom' | 'left' | 'right';
1573
+ /**
1574
+ * Configuration for a window spawned imperatively via `usePanelFloatingWindowManager().open()`.
1575
+ * @see usePanelFloatingWindowManager
1576
+ */
1577
+ interface ManagedWindowConfig {
1578
+ /** Text shown in the window's header bar. */
1579
+ title: string;
1580
+ /** Optional icon shown to the left of the title in the header. */
1581
+ icon?: React$1.ReactNode;
1582
+ /** Window body content. */
1583
+ content: React$1.ReactNode;
1584
+ /** Corner of the panel to dock to on first render. @default 'top-right' */
1585
+ anchor?: FloatAnchor;
1586
+ /** Initial width in pixels. */
1587
+ width?: number;
1588
+ /** Initial height in pixels. */
1589
+ height?: number;
1590
+ }
1591
+ /** Props for `<PanelOverlayRoot>`. */
1592
+ interface PanelOverlayRootProps {
1593
+ children: React$1.ReactNode;
1594
+ className?: string;
1595
+ style?: React$1.CSSProperties;
1596
+ }
1597
+ /**
1598
+ * Context provider and layout root for the Panel Overlay system. Wrap your panel content
1599
+ * with this to enable `PanelToolbar`, `PanelFloatingWindow`, and `usePanelFloatingWindowManager`.
1600
+ * @example
1601
+ * function MyPanel() {
1602
+ * return (
1603
+ * <PanelOverlayRoot style={{ position: 'relative', width: '100%', height: '100%' }}>
1604
+ * <PanelToolbar position="top">...</PanelToolbar>
1605
+ * <div className="panel-body">content</div>
1606
+ * </PanelOverlayRoot>
1607
+ * );
1608
+ * }
1609
+ */
1610
+ declare function PanelOverlayRoot({ children, className, style }: PanelOverlayRootProps): React$1.ReactElement;
1611
+ /** Background style of a `PanelToolbar`. */
1612
+ type ToolbarVariant = 'transparent' | 'frosted' | 'solid';
1613
+ /** Visual style applied to `ToolbarButton` and `ToolbarToggle` components. */
1614
+ type ButtonVariant = 'ghost' | 'soft' | 'outlined' | 'filled';
1615
+ /** Props for `<PanelToolbar>`. */
1616
+ interface PanelToolbarProps {
1617
+ /** Edge of the panel overlay to attach to. @see ToolbarPosition */
1618
+ position: ToolbarPosition;
1619
+ /** Background style of the toolbar strip. @default 'transparent' */
1620
+ variant?: ToolbarVariant;
1621
+ /** Default button style inherited by `ToolbarButton` and `ToolbarToggle` children. @default 'ghost' */
1622
+ buttonVariant?: ButtonVariant;
1623
+ /** Icon size in pixels for all buttons in this toolbar. Falls back to CSS default when unset. */
1624
+ buttonSize?: number;
1625
+ style?: React$1.CSSProperties;
1626
+ className?: string;
1627
+ children?: React$1.ReactNode;
1628
+ }
1629
+ /**
1630
+ * Toolbar strip that attaches to any edge of a `PanelOverlayRoot`.
1631
+ * Left/right toolbars inset automatically to avoid overlapping top/bottom toolbars.
1632
+ * RTL layouts are detected and handled automatically.
1633
+ * @example
1634
+ * <PanelToolbar position="top" variant="frosted">
1635
+ * <ToolbarButton icon={<SaveIcon />} title="Save" onClick={save} />
1636
+ * <ToolbarToggle icon={<GridIcon />} title="Grid" active={grid} onToggle={() => setGrid(v => !v)} />
1637
+ * </PanelToolbar>
1638
+ */
1639
+ declare function PanelToolbar({ position, variant, buttonVariant, buttonSize, style, className, children }: PanelToolbarProps): React$1.ReactElement;
1640
+ /** Props for `<ToolbarButton>`. */
1641
+ interface ToolbarButtonProps {
1642
+ /** Button icon — typically a small SVG component. */
1643
+ icon: React$1.ReactNode;
1644
+ /** Click handler. */
1645
+ onClick(): void;
1646
+ disabled?: boolean;
1647
+ /** Tooltip text and accessible `aria-label`. */
1648
+ title?: string;
1649
+ /** Visual style override. Falls back to the parent `PanelToolbar`'s `buttonVariant`. */
1650
+ variant?: ButtonVariant;
1651
+ }
1652
+ /** Icon button for use inside a `PanelToolbar`. */
1653
+ declare function ToolbarButton({ icon, onClick, disabled, title, variant }: ToolbarButtonProps): React$1.ReactElement;
1654
+ /** Props for `<ToolbarToggle>`. */
1655
+ interface ToolbarToggleProps {
1656
+ /** Button icon — typically a small SVG component. */
1657
+ icon: React$1.ReactNode;
1658
+ /** Whether the toggle is in the active/pressed state. Sets `aria-pressed` automatically. */
1659
+ active: boolean;
1660
+ /** Called when the button is clicked. Toggle `active` in response. */
1661
+ onToggle(): void;
1662
+ disabled?: boolean;
1663
+ /** Tooltip text and accessible `aria-label`. */
1664
+ title?: string;
1665
+ /** Visual style override. Falls back to the parent `PanelToolbar`'s `buttonVariant`. */
1666
+ variant?: ButtonVariant;
1667
+ }
1668
+ /** Two-state icon toggle button for use inside a `PanelToolbar`. Sets `aria-pressed` automatically. */
1669
+ declare function ToolbarToggle({ icon, active, onToggle, disabled, title, variant }: ToolbarToggleProps): React$1.ReactElement;
1670
+ /** Vertical (or horizontal) divider line between groups of toolbar items. */
1671
+ declare function ToolbarSeparator(): React$1.ReactElement;
1672
+ /** Flex-grow spacer that pushes subsequent toolbar items to the far edge. */
1673
+ declare function ToolbarSpacer(): React$1.ReactElement;
1674
+ /** Wrapper for a custom non-button control (e.g. a dropdown or input) inside a `PanelToolbar`. */
1675
+ declare function ToolbarItem({ children }: {
1676
+ children: React$1.ReactNode;
1677
+ }): React$1.ReactElement;
1678
+ /** Centers its children within the toolbar using absolute positioning. */
1679
+ declare function ToolbarCenter({ children }: {
1680
+ children: React$1.ReactNode;
1681
+ }): React$1.ReactElement;
1682
+ /** A single result item returned by `ToolbarSearchInputProps.onSearch`. */
1683
+ interface SearchResult {
1684
+ /** Unique identifier for this result — passed to `onSelect`. */
1685
+ id: string;
1686
+ /** Primary display text. */
1687
+ label: string;
1688
+ /** Optional secondary text shown below the label in the dropdown. */
1689
+ description?: string;
1690
+ /** Optional group header used to bucket results visually. */
1691
+ group?: string;
1692
+ /** Optional icon shown to the left of the label. */
1693
+ icon?: React$1.ReactNode;
1694
+ }
1695
+ /** Props for `<ToolbarSearchInput>`. */
1696
+ interface ToolbarSearchInputProps {
1697
+ /** Placeholder text shown in the expanded input field. @default 'Search…' */
1698
+ placeholder?: string;
1699
+ /**
1700
+ * Called with the current query and an `AbortSignal` each time the input changes (debounced).
1701
+ * Return `SearchResult[]` directly for synchronous sources, or `Promise<SearchResult[]>` for async.
1702
+ * Abort in-flight requests when the signal fires to prevent stale result races.
1703
+ */
1704
+ onSearch(query: string, signal: AbortSignal): Promise<SearchResult[]> | SearchResult[];
1705
+ /** Called when the user selects a result from the dropdown. */
1706
+ onSelect(result: SearchResult): void;
1707
+ }
1708
+ /**
1709
+ * Debounced async search field for use inside a `PanelToolbar`.
1710
+ * Renders as a compact icon button that expands into a text input on activation.
1711
+ * Results appear in a portal-rendered dropdown below the input.
1712
+ * @example
1713
+ * <ToolbarSearchInput
1714
+ * placeholder="Find layer…"
1715
+ * onSearch={(q, signal) => fetchLayers(q, { signal })}
1716
+ * onSelect={result => workspace.focusLayer(result.id)}
1717
+ * />
1718
+ */
1719
+ declare function ToolbarSearchInput({ placeholder, onSearch, onSelect }: ToolbarSearchInputProps): React$1.ReactElement;
1720
+ /** Props for `<PanelFloatingWindow>`. */
1721
+ interface PanelFloatingWindowProps {
1722
+ /** Unique identifier within the panel overlay. Used for z-order and stack tracking. */
1723
+ id: string;
1724
+ /** Text shown in the window's header bar. */
1725
+ title: string;
1726
+ /** Optional icon shown to the left of the title in the header. */
1727
+ icon?: React$1.ReactNode;
1728
+ /** Whether the window is mounted and visible. Set to `false` to close/unmount it. */
1729
+ open: boolean;
1730
+ /** Called when the user clicks the × button. Set `open` to `false` in response. */
1731
+ onClose(): void;
1732
+ /** Corner of the panel to dock to on first render. @see FloatAnchor */
1733
+ defaultAnchor: FloatAnchor;
1734
+ /** Initial width in pixels. */
1735
+ defaultWidth: number;
1736
+ /** Initial height in pixels. */
1737
+ defaultHeight: number;
1738
+ children?: React$1.ReactNode;
1739
+ }
1740
+ /**
1741
+ * Declarative floating window anchored inside a `PanelOverlayRoot`.
1742
+ * Supports 8-direction resize, drag-to-free, and drag-to-dock at any corner.
1743
+ * Multiple windows docked to the same corner stack vertically with animated offsets.
1744
+ * @example
1745
+ * const info = usePanelFloatingWindow();
1746
+ * <PanelFloatingWindow
1747
+ * id="layer-info" title="Layer Info"
1748
+ * open={info.isOpen} onClose={info.close}
1749
+ * defaultAnchor="top-right" defaultWidth={300} defaultHeight={200}
1750
+ * >
1751
+ * <LayerInfoContent />
1752
+ * </PanelFloatingWindow>
1753
+ */
1754
+ declare function PanelFloatingWindow(props: PanelFloatingWindowProps): React$1.ReactElement | null;
1755
+ /** Return type of `usePanelFloatingWindow`. @see usePanelFloatingWindow */
1756
+ interface UsePanelFloatingWindowReturn {
1757
+ /** Whether the floating window is currently open. */
1758
+ isOpen: boolean;
1759
+ /** Open the floating window. */
1760
+ open(): void;
1761
+ /** Close the floating window. */
1762
+ close(): void;
1763
+ }
1764
+ /**
1765
+ * Manages the open/close boolean state for a single `PanelFloatingWindow`.
1766
+ * Pass `isOpen` to `open`, `close` to `onClose` on the component directly.
1767
+ * @returns A stable `UsePanelFloatingWindowReturn` object.
1768
+ * @example
1769
+ * const info = usePanelFloatingWindow();
1770
+ * <PanelFloatingWindow id="info" open={info.isOpen} onClose={info.close} ... />
1771
+ */
1772
+ declare function usePanelFloatingWindow(): UsePanelFloatingWindowReturn;
1773
+ /**
1774
+ * Imperative handle returned by `usePanelFloatingWindowManager`.
1775
+ * @see usePanelFloatingWindowManager
1776
+ */
1777
+ interface PanelFloatingWindowManagerHandle {
1778
+ /** Spawn or reconfigure a named window. Safe to call with an already-open ID to update config. */
1779
+ open(id: string, config: ManagedWindowConfig): void;
1780
+ /** Close a named window by ID. No-op if the window is not open. */
1781
+ close(id: string): void;
1782
+ /** Close all managed windows. */
1783
+ closeAll(): void;
1784
+ /** Returns `true` if the named window is currently open. */
1785
+ isOpen(id: string): boolean;
1786
+ /** IDs of all currently open managed windows. Changes to this array trigger re-renders. */
1787
+ openIds: string[];
1788
+ }
1789
+ /**
1790
+ * Imperative hook for spawning N named floating windows at runtime from data or event handlers.
1791
+ * All windows share z-ordering, drag, and corner-docking infrastructure of the `PanelOverlayRoot`.
1792
+ *
1793
+ * Must be called inside a **descendant** of `PanelOverlayRoot`, not in the component that renders the root.
1794
+ * @returns A stable `PanelFloatingWindowManagerHandle`.
1795
+ * @example
1796
+ * const manager = usePanelFloatingWindowManager();
1797
+ * manager.open('feature-42', { title: 'Feature 42', content: <FeatureDetail id={42} />, anchor: 'top-right' });
1798
+ */
1799
+ declare function usePanelFloatingWindowManager(): PanelFloatingWindowManagerHandle;
1800
+
1801
+ export { type BuiltInPanelEvents, type ButtonVariant, type CloseOptions, ConfirmationForm, type ConfirmationFormProps, ContextMenu, type ContextMenuAdapter, type ContextMenuCheckbox, type ContextMenuHandle, type ContextMenuItem, type ContextMenuLabel, type ContextMenuPredefinedMessage, type ContextMenuProps, type ContextMenuSeparator, type ContextMenuSimpleItem, type ContextMenuSubMenu, DefaultContextMenuAdapter, DockableDesktopProvider, type DockableDesktopProviderProps, type DropPosition, type DropTarget, type FloatAnchor, type FloatingWindow, FormContainerContext, type FormContainerContract, FormContainerProvider, type LayoutGridNode, type LayoutLeafNode, type LayoutNode, LeftPanelRenderer, type ManagedWindowConfig, type MenuItemAction, type MessageFormatter, type ModalOptions, ModalStackRenderer, type PanelActions, type PanelDefinition, PanelFloatingWindow, type PanelFloatingWindowManagerHandle, type PanelFloatingWindowProps, type PanelInfo, type PanelInstance, type PanelInstanceId, PanelOverlayRoot, type PanelOverlayRootProps, PanelProvider, PanelRegistry, PanelRegistryClass, type PanelRegistryEntry, type PanelState, type PanelTitle, PanelToolbar, ToolbarItem as PanelToolbarItem, type PanelToolbarProps, ToolbarSeparator as PanelToolbarSeparator, type PredefinedMessageKey, type ResolvedToastOptions, RightPanelRenderer, type SearchResult, type ShowContextMenuOptions, type SidePanelOptions, SidePanelRenderer, type SidePanelRendererProps, Sidebar, type SidebarContextValue, type SidebarHandle, type SidebarProps, type SidebarTab, type SidebarTabContextValue, type SplitDirection, type SplitOrientation, type StyleClasses, type TaskbarVisibility, type ToastAdapter, ToastContainer, type ToastContainerProps, type ToastFunction, type ToastOptions, type ToastPosition, type ToastPromiseMessages, type ToastType, Toolbar, type ToolbarActionItem, ToolbarButton, type ToolbarButtonProps, ToolbarCenter, type ToolbarContextValue, type ToolbarGroupEntry, type ToolbarGroupItem, type ToolbarGroupSubItem, type ToolbarHandle, type ToolbarItem$1 as ToolbarItem, type ToolbarPosition, type ToolbarProps, ToolbarProvider, type ToolbarRadioItem, ToolbarSearchInput, type ToolbarSearchInputProps, type ToolbarSeparator$1 as ToolbarSeparator, ToolbarSpacer, ToolbarToggle, type ToolbarToggleItem, type ToolbarToggleProps, type ToolbarVariant, type UsePanelFloatingWindowReturn, type WindowActions, WindowManager, type WindowManagerProps, WindowManagerProvider, type WindowManagerProviderProps, type WindowState, WorkspaceClient, type WorkspaceClientConfig, defaultPredefinedMessages, formatLabel, toast, useFormContainer, useFormatMessage, usePanelActions, usePanelContext, usePanelContextMenu, usePanelFloatingWindow, usePanelFloatingWindowManager, usePanelId, usePanelState, usePredefinedMessages, useRegistry, useSidebar, useSidebarTab, useStyleClasses, useToolbar, useWindowManagerActions, useWindowManagerState };