react-dockable-desktop 4.3.0 → 5.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/README.md +7 -4
- package/dist/index.cjs +4 -4
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +321 -17
- package/dist/index.d.ts +321 -17
- package/dist/index.js +5 -5
- package/dist/index.js.map +1 -1
- package/dist/styles.css +1122 -1115
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -90,6 +90,8 @@ interface WindowManagerProps {
|
|
|
90
90
|
taskbarVisibility?: TaskbarVisibility;
|
|
91
91
|
/** Custom context menu renderer. Defaults to the built-in `DefaultContextMenuAdapter`. */
|
|
92
92
|
contextMenuAdapter?: ContextMenuAdapter;
|
|
93
|
+
/** Enables the library's own transitions/animations (tab hover, dock preview, etc.). Never affects the consumer's own page. @default true */
|
|
94
|
+
animations?: boolean;
|
|
93
95
|
}
|
|
94
96
|
declare const WindowManager: React$1.FC<WindowManagerProps>;
|
|
95
97
|
|
|
@@ -108,6 +110,30 @@ interface BuiltInPanelEvents {
|
|
|
108
110
|
'panel:restored': {
|
|
109
111
|
id: string;
|
|
110
112
|
};
|
|
113
|
+
/**
|
|
114
|
+
* Fires whenever something `saveLayout()` would capture changes — open/close/minimize/restore,
|
|
115
|
+
* and an `openPanel` `dedupeKey` redirect. Coalesces those into one signal for autosave-style
|
|
116
|
+
* consumers, so they don't need to subscribe to four separate events. Does **not** cover a
|
|
117
|
+
* `registerStateProvider` callback's return value changing on its own — that's a pull, there's
|
|
118
|
+
* no way to observe it changing without the panel separately notifying — nor resize/split-ratio
|
|
119
|
+
* drag/dock-rearrange, which have no hooks yet.
|
|
120
|
+
*/
|
|
121
|
+
'layout:changed': Record<string, never>;
|
|
122
|
+
/**
|
|
123
|
+
* Fires from inside `saveLayout()` itself, only when that specific call excluded at least one
|
|
124
|
+
* panel (a panel whose current `props` — static or from a `registerStateProvider` — failed
|
|
125
|
+
* {@link isSerializable}). A passive `PanelInfo.serializable` flag alone isn't enough for this:
|
|
126
|
+
* nobody may be polling it at the exact moment a save happens and something silently drops out
|
|
127
|
+
* (e.g. a floating window rendering data from a live class instance). This is deliberately just
|
|
128
|
+
* a signal, not a UI opinion — decide for yourself whether that becomes a toast, a console
|
|
129
|
+
* warning, or nothing.
|
|
130
|
+
*/
|
|
131
|
+
'layout:panels-excluded': {
|
|
132
|
+
panels: {
|
|
133
|
+
id: string;
|
|
134
|
+
component: string;
|
|
135
|
+
}[];
|
|
136
|
+
};
|
|
111
137
|
}
|
|
112
138
|
/** Per-panel definition supplied to WorkspaceClient constructor. */
|
|
113
139
|
interface PanelDefinition {
|
|
@@ -142,6 +168,13 @@ interface WorkspaceClientConfig {
|
|
|
142
168
|
* outer edge. Range 0.1–0.9. Default: 0.2.
|
|
143
169
|
*/
|
|
144
170
|
defaultEdgeSplitRatio?: number;
|
|
171
|
+
/**
|
|
172
|
+
* Starting z-index for floating windows and the library's own chrome overlays
|
|
173
|
+
* (context menu, toolbar flyout, modal stack, toast, workspace edge zones),
|
|
174
|
+
* all of which shift together via `--rdd-z-base`. Set this above/below a host
|
|
175
|
+
* app's own modal z-index range to control stacking against it. Default: 1000.
|
|
176
|
+
*/
|
|
177
|
+
zIndexBase?: number;
|
|
145
178
|
}
|
|
146
179
|
/**
|
|
147
180
|
* WorkspaceClient is the central configuration and imperative API object for
|
|
@@ -181,7 +214,7 @@ declare class WorkspaceClient<TUserEvents extends Record<string, unknown> = Reco
|
|
|
181
214
|
/** Serialised layout to restore on mount, or null to start with an empty canvas. */
|
|
182
215
|
readonly initialState: string | null;
|
|
183
216
|
/** Non-rendering configuration forwarded to the provider. */
|
|
184
|
-
readonly config: Pick<WorkspaceClientConfig, 'formatMessage' | 'predefinedMessages' | 'dir' | 'defaultSplitRatio' | 'defaultEdgeSplitRatio'>;
|
|
217
|
+
readonly config: Pick<WorkspaceClientConfig, 'formatMessage' | 'predefinedMessages' | 'dir' | 'defaultSplitRatio' | 'defaultEdgeSplitRatio' | 'zIndexBase'>;
|
|
185
218
|
private _actions;
|
|
186
219
|
private _initialized;
|
|
187
220
|
/** Calls queued before _connect() fires — replayed in order on first connect. */
|
|
@@ -219,9 +252,54 @@ declare class WorkspaceClient<TUserEvents extends Record<string, unknown> = Reco
|
|
|
219
252
|
isOpen(id: string): boolean;
|
|
220
253
|
/** Returns the IDs of all currently open panels. */
|
|
221
254
|
getOpenPanelIds(): string[];
|
|
255
|
+
/** Finds an already-open panel of the given component with a matching `dedupeKey` (set via
|
|
256
|
+
* `openPanel`'s `dedupeKey` option). Returns `null` if none is open. */
|
|
257
|
+
findPanelId(component: string, dedupeKey: string): string | null;
|
|
222
258
|
saveLayout(): string;
|
|
223
259
|
loadLayout(json: string): boolean;
|
|
224
260
|
setDirection(dir: 'ltr' | 'rtl'): void;
|
|
261
|
+
/** Updates the split-size fractions at the given grid path. */
|
|
262
|
+
updateSplitSizes(path: number[], sizes: number[]): void;
|
|
263
|
+
/** Updates position/size/anchor of a floating panel. */
|
|
264
|
+
updateFloatingPosition(id: string, updates: Partial<Pick<FloatingWindow, 'x' | 'y' | 'width' | 'height' | 'anchor'>>): void;
|
|
265
|
+
/** @internal Drives the drag-in-progress visual state; normally only the library's own drag UI calls this. */
|
|
266
|
+
setDraggedPanelId(id: string | null): void;
|
|
267
|
+
/** Docks a panel into an existing leaf group at the given drop position. */
|
|
268
|
+
dockPanelToGroup(id: string, targetLeafId: string, position: DropPosition): void;
|
|
269
|
+
/** Reorders a panel's tab within its leaf group. */
|
|
270
|
+
movePanelOrder(panelId: string, targetLeafId: string, targetIndex: number): void;
|
|
271
|
+
/** Closes an entire leaf group (all of its tabs) at once. */
|
|
272
|
+
closeLeafGroup(leafId: string): void;
|
|
273
|
+
/** Registers a guard that can veto closing the given panel. */
|
|
274
|
+
registerCloseGuard(id: string, guard: () => boolean | Promise<boolean>): void;
|
|
275
|
+
/** Removes a previously registered close guard. */
|
|
276
|
+
unregisterCloseGuard(id: string): void;
|
|
277
|
+
/** Registers a callback reporting a panel's current restorable state, pulled fresh on every
|
|
278
|
+
* `saveLayout()` call — see {@link BuiltInPanelEvents}'s `'layout:panels-excluded'` doc and
|
|
279
|
+
* `FormContainerContract.registerStateProvider`. */
|
|
280
|
+
registerStateProvider(id: string, provider: () => unknown): void;
|
|
281
|
+
/** Removes a previously registered state provider. */
|
|
282
|
+
unregisterStateProvider(id: string): void;
|
|
283
|
+
/** Sets/clears a panel's dirty (unsaved changes) flag. */
|
|
284
|
+
setPanelDirty(id: string, dirty: boolean, options?: DirtyStateOptions): void;
|
|
285
|
+
/** Updates a panel's displayed title. */
|
|
286
|
+
updatePanelTitle(id: string, title: string | ContextMenuPredefinedMessage): void;
|
|
287
|
+
/**
|
|
288
|
+
* Requests that a panel close, honoring its dirty flag and any registered close guard.
|
|
289
|
+
* Resolves once the close (or user cancellation) has been resolved.
|
|
290
|
+
*
|
|
291
|
+
* @remarks If called before the provider mounts, the request is queued and this
|
|
292
|
+
* returns an already-resolved promise immediately — the caller can't observe the
|
|
293
|
+
* eventual outcome of a queued call, only that the request was accepted.
|
|
294
|
+
*/
|
|
295
|
+
requestClosePanel(id: string, options?: {
|
|
296
|
+
force?: boolean;
|
|
297
|
+
onConfirm?: (opts?: DirtyStateOptions) => Promise<boolean>;
|
|
298
|
+
}): Promise<void>;
|
|
299
|
+
/** Docks a panel to one of the workspace's outer edges. */
|
|
300
|
+
dockPanelToWorkspaceEdge(id: string, position: SplitDirection): void;
|
|
301
|
+
/** Shows a context menu using the app's configured ContextMenuAdapter. */
|
|
302
|
+
showContextMenu(options: ShowContextMenuOptions): void;
|
|
225
303
|
publish<K extends keyof (TUserEvents & BuiltInPanelEvents)>(event: K, data: (TUserEvents & BuiltInPanelEvents)[K]): void;
|
|
226
304
|
subscribe<K extends keyof (TUserEvents & BuiltInPanelEvents)>(event: K, callback: (data: (TUserEvents & BuiltInPanelEvents)[K]) => void): () => void;
|
|
227
305
|
/** Subscribe to panel open events. Fires only for newly created panels. */
|
|
@@ -232,6 +310,16 @@ declare class WorkspaceClient<TUserEvents extends Record<string, unknown> = Reco
|
|
|
232
310
|
onPanelMinimize(callback: (id: string) => void): () => void;
|
|
233
311
|
/** Subscribe to panel restore events. */
|
|
234
312
|
onPanelRestore(callback: (id: string) => void): () => void;
|
|
313
|
+
/** Subscribe to the coalesced layout-change signal — see {@link BuiltInPanelEvents}'s
|
|
314
|
+
* `'layout:changed'` doc for exactly what it covers (and doesn't). */
|
|
315
|
+
onLayoutChanged(callback: () => void): () => void;
|
|
316
|
+
/** Subscribe to notification that a `saveLayout()` call excluded one or more panels because
|
|
317
|
+
* their current props weren't serializable — see {@link BuiltInPanelEvents}'s
|
|
318
|
+
* `'layout:panels-excluded'` doc. */
|
|
319
|
+
onPanelsExcluded(callback: (panels: {
|
|
320
|
+
id: string;
|
|
321
|
+
component: string;
|
|
322
|
+
}[]) => void): () => void;
|
|
235
323
|
}
|
|
236
324
|
|
|
237
325
|
/**
|
|
@@ -489,6 +577,51 @@ interface PanelInfo {
|
|
|
489
577
|
dirty?: boolean;
|
|
490
578
|
/** Custom options applied to the automatic unsaved changes modal. */
|
|
491
579
|
dirtyOptions?: DirtyStateOptions;
|
|
580
|
+
/** Custom per-instance data passed via `openPanel(id, component, { props })`. Unconstrained —
|
|
581
|
+
* any value is accepted, but only a value that passes {@link isSerializable} is actually
|
|
582
|
+
* included in {@link WindowActions.saveLayout}'s output. See {@link PanelInfo.serializable}. */
|
|
583
|
+
props?: Record<string, unknown>;
|
|
584
|
+
/** Whether this panel's current `props` can round-trip through `saveLayout()`/`loadLayout()`.
|
|
585
|
+
* Computed automatically — `true` when no `props` were passed, or when they were and passed
|
|
586
|
+
* {@link isSerializable}. A panel with `serializable: false` still renders and works normally;
|
|
587
|
+
* it's simply excluded from the next `saveLayout()` call (and pruned from `gridRoot`/
|
|
588
|
+
* `floating`/`minimized` in that saved snapshot) rather than corrupting or throwing. */
|
|
589
|
+
serializable: boolean;
|
|
590
|
+
/** Optional dedup key. If another open panel of the same `component` already has this exact
|
|
591
|
+
* key, `openPanel` focuses that existing panel instead of creating a new one — see
|
|
592
|
+
* {@link WindowActions.openPanel}'s `dedupeKey` option and {@link WindowActions.findPanelId}. */
|
|
593
|
+
dedupeKey?: string;
|
|
594
|
+
}
|
|
595
|
+
/**
|
|
596
|
+
* Options accepted by {@link WindowActions.openPanel}.
|
|
597
|
+
*/
|
|
598
|
+
interface OpenPanelOptions<P extends object = Record<string, unknown>> {
|
|
599
|
+
/** Override the panel tab/window title. Accepts a plain string or an i18n message descriptor. */
|
|
600
|
+
title?: string | ContextMenuPredefinedMessage;
|
|
601
|
+
/** Initial placement: `'floating'`, `'docked'` (default when a grid exists), or `'tabbed'`. */
|
|
602
|
+
initialTarget?: 'floating' | 'docked' | 'tabbed';
|
|
603
|
+
/** Pin the new floating window to a workspace corner on creation. Has no effect when
|
|
604
|
+
* `initialTarget` is `'docked'` or `'tabbed'`. */
|
|
605
|
+
anchor?: FloatAnchor | null;
|
|
606
|
+
/** Set `state.activePanelId` to this panel. @default true */
|
|
607
|
+
focus?: boolean;
|
|
608
|
+
/**
|
|
609
|
+
* Custom per-instance data spread onto the panel component alongside `panelId`, matching
|
|
610
|
+
* `openModal`/`openLeftPanel`/`openRightPanel`'s already-unconstrained `props` argument — no
|
|
611
|
+
* type restriction here either. Whether a specific value round-trips through `saveLayout()` is
|
|
612
|
+
* a runtime fact, not a type-level guarantee: see {@link PanelInfo.serializable} and the
|
|
613
|
+
* `'layout:panels-excluded'` event.
|
|
614
|
+
*/
|
|
615
|
+
props?: P;
|
|
616
|
+
/**
|
|
617
|
+
* If set, and another currently-open panel of the same `component` already has this exact
|
|
618
|
+
* `dedupeKey`, that existing panel is focused instead of opening a new one — the `id`/`props`
|
|
619
|
+
* passed to *this* call are ignored in that case, the same way re-opening an already-open exact
|
|
620
|
+
* `id` already focuses it instead of duplicating it. Use this when multiple call sites might
|
|
621
|
+
* not agree on the same literal `id` for what is semantically the same entity (e.g. "the panel
|
|
622
|
+
* for the document at this path"). See also {@link WindowActions.findPanelId}.
|
|
623
|
+
*/
|
|
624
|
+
dedupeKey?: string;
|
|
492
625
|
}
|
|
493
626
|
/**
|
|
494
627
|
* Global window manager state tree representing grid nodes, windows, and panels.
|
|
@@ -547,6 +680,8 @@ interface WindowActions {
|
|
|
547
680
|
* @param options.initialTarget - Initial placement: `'floating'`, `'docked'` (default when a grid exists), or `'tabbed'`.
|
|
548
681
|
* @param options.anchor - Pin the new floating window to a workspace corner on creation. Has no effect when `initialTarget` is `'docked'` or `'tabbed'`.
|
|
549
682
|
* @param options.focus - Set `state.activePanelId` to this panel. @default true
|
|
683
|
+
* @param options.props - Custom per-instance data spread onto the component alongside `panelId`. Unconstrained, like `openModal`/`openLeftPanel`/`openRightPanel`'s `props` — see {@link PanelInfo.serializable} for what determines whether it survives `saveLayout()`.
|
|
684
|
+
* @param options.dedupeKey - If another open panel of the same `component` already has this key, that panel is focused instead of opening a new one.
|
|
550
685
|
* @example
|
|
551
686
|
* ```ts
|
|
552
687
|
* // Open floating and pin to the top-right corner:
|
|
@@ -554,14 +689,15 @@ interface WindowActions {
|
|
|
554
689
|
*
|
|
555
690
|
* // Open in the background without stealing focus:
|
|
556
691
|
* actions.openPanel('prefetch', 'report', { focus: false });
|
|
692
|
+
*
|
|
693
|
+
* // Open with per-instance data, deduped by document path:
|
|
694
|
+
* actions.openPanel(crypto.randomUUID(), 'document', {
|
|
695
|
+
* props: { path: '/notes/todo.md' },
|
|
696
|
+
* dedupeKey: '/notes/todo.md',
|
|
697
|
+
* });
|
|
557
698
|
* ```
|
|
558
699
|
*/
|
|
559
|
-
openPanel: (id: string, component: string, options?:
|
|
560
|
-
title?: string | ContextMenuPredefinedMessage;
|
|
561
|
-
initialTarget?: 'floating' | 'docked' | 'tabbed';
|
|
562
|
-
anchor?: FloatAnchor | null;
|
|
563
|
-
focus?: boolean;
|
|
564
|
-
}) => void;
|
|
700
|
+
openPanel: <P extends object = Record<string, unknown>>(id: string, component: string, options?: OpenPanelOptions<P>) => void;
|
|
565
701
|
/**
|
|
566
702
|
* Closes a panel immediately, bypassing dirty-state close guards.
|
|
567
703
|
* For guarded close, use {@link requestClosePanel}.
|
|
@@ -646,6 +782,15 @@ interface WindowActions {
|
|
|
646
782
|
* @returns Array of panel instance IDs.
|
|
647
783
|
*/
|
|
648
784
|
getOpenPanelIds: () => string[];
|
|
785
|
+
/**
|
|
786
|
+
* Finds the ID of an already-open panel of the given `component` with a matching `dedupeKey`
|
|
787
|
+
* (set via `openPanel`'s `dedupeKey` option). Uses a synchronous `stateRef` read — safe to
|
|
788
|
+
* call outside of render.
|
|
789
|
+
* @param component - Component key registered in the panel catalog.
|
|
790
|
+
* @param dedupeKey - The dedup key to search for.
|
|
791
|
+
* @returns The matching panel's ID, or `null` if none is open.
|
|
792
|
+
*/
|
|
793
|
+
findPanelId: (component: string, dedupeKey: string) => string | null;
|
|
649
794
|
/**
|
|
650
795
|
* Serializes the entire workspace state to a JSON string.
|
|
651
796
|
* Includes grid layout, floating window positions, minimized panels, and panel metadata.
|
|
@@ -712,6 +857,23 @@ interface WindowActions {
|
|
|
712
857
|
* @param id - Panel instance ID.
|
|
713
858
|
*/
|
|
714
859
|
unregisterCloseGuard: (id: string) => void;
|
|
860
|
+
/**
|
|
861
|
+
* Registers a callback reporting a docked/floating panel's *current* restorable state, pulled
|
|
862
|
+
* fresh every `saveLayout()` call — for panels whose props alone can't capture state they
|
|
863
|
+
* accumulate after opening (scroll position, an in-progress edit, a view-mode toggle). A panel
|
|
864
|
+
* that registers nothing keeps its static open-time `props` (or none). The returned value goes
|
|
865
|
+
* through the same {@link isSerializable} check as static props, re-evaluated on every save —
|
|
866
|
+
* a provider-backed panel's serializability can flip over its lifetime.
|
|
867
|
+
* @param id - Panel instance ID.
|
|
868
|
+
* @param provider - Called synchronously at each `saveLayout()`; return the current state (or
|
|
869
|
+
* `undefined` to fall back to the static `props` this panel was opened with).
|
|
870
|
+
*/
|
|
871
|
+
registerStateProvider: (id: string, provider: () => unknown) => void;
|
|
872
|
+
/**
|
|
873
|
+
* Removes a previously registered state provider.
|
|
874
|
+
* @param id - Panel instance ID.
|
|
875
|
+
*/
|
|
876
|
+
unregisterStateProvider: (id: string) => void;
|
|
715
877
|
/**
|
|
716
878
|
* Marks a panel as dirty (has unsaved changes). Dirty panels show a visual indicator
|
|
717
879
|
* and the built-in close guard prompts the user before closing.
|
|
@@ -782,6 +944,19 @@ declare const useStyleClasses: () => StyleClasses;
|
|
|
782
944
|
* ```
|
|
783
945
|
*/
|
|
784
946
|
declare const useRegistry: () => PanelRegistryClass;
|
|
947
|
+
/** The on-disk shape produced by `saveLayout()` and accepted by `loadLayout()`/`initialState`. */
|
|
948
|
+
interface SerializedLayout {
|
|
949
|
+
/** Schema version — absent on layouts saved before this field was introduced (treated as 0). */
|
|
950
|
+
version?: number;
|
|
951
|
+
gridRoot: LayoutNode;
|
|
952
|
+
floating: FloatingWindow[];
|
|
953
|
+
minimized: {
|
|
954
|
+
id: string;
|
|
955
|
+
title: string | ContextMenuPredefinedMessage;
|
|
956
|
+
component: string;
|
|
957
|
+
}[];
|
|
958
|
+
panels: Record<string, PanelInfo>;
|
|
959
|
+
}
|
|
785
960
|
/**
|
|
786
961
|
* Props for `<DockableDesktopProvider>` and `<WindowManagerProvider>`.
|
|
787
962
|
* Also exported as `DockableDesktopProviderProps` for consumers who use
|
|
@@ -814,6 +989,13 @@ interface WindowManagerProviderProps {
|
|
|
814
989
|
windowClass?: string;
|
|
815
990
|
/** CSS class applied to the inner content area of floating panel windows. */
|
|
816
991
|
windowBodyClass?: string;
|
|
992
|
+
/**
|
|
993
|
+
* Starting z-index for floating windows and the library's own chrome overlays
|
|
994
|
+
* (context menu, toolbar flyout, modal stack, toast, workspace edge zones),
|
|
995
|
+
* all of which shift together via `--rdd-z-base`. Set this above/below a host
|
|
996
|
+
* app's own modal z-index range to control stacking against it. @default 1000
|
|
997
|
+
*/
|
|
998
|
+
zIndexBase?: number;
|
|
817
999
|
}
|
|
818
1000
|
declare const WindowManagerProvider: React$1.FC<WindowManagerProviderProps>;
|
|
819
1001
|
declare function useWindowManagerState(): WindowState;
|
|
@@ -994,6 +1176,26 @@ interface DockableDesktopProviderProps extends WindowManagerProviderProps {
|
|
|
994
1176
|
*/
|
|
995
1177
|
declare const DockableDesktopProvider: React$1.FC<DockableDesktopProviderProps>;
|
|
996
1178
|
|
|
1179
|
+
/**
|
|
1180
|
+
* Recursively checks whether a value can round-trip through `JSON.stringify`/`JSON.parse`
|
|
1181
|
+
* without silently losing information.
|
|
1182
|
+
*
|
|
1183
|
+
* Deliberately **not** a `JSON.stringify` try/catch — that call doesn't throw for the actual
|
|
1184
|
+
* failure case this guards against: a function-valued property is simply dropped by
|
|
1185
|
+
* `JSON.stringify`, not rejected. This walks the value tree instead, returning `false` as soon as
|
|
1186
|
+
* it finds a function, symbol, `undefined`, React element, or any non-plain object (a class
|
|
1187
|
+
* instance, `Map`, `Set`, `RegExp`, etc.).
|
|
1188
|
+
*
|
|
1189
|
+
* `Date` is treated as an explicit exception — serializable-enough, matching `JSON.stringify`'s
|
|
1190
|
+
* own behavior — even though it doesn't round-trip back to a `Date` instance on parse. That's a
|
|
1191
|
+
* smaller, more tolerable gotcha than a silently-vanishing function, so it's documented rather
|
|
1192
|
+
* than treated as a disqualifying case.
|
|
1193
|
+
*
|
|
1194
|
+
* Used to decide whether a docked/floating panel's `props` can be included in
|
|
1195
|
+
* `WorkspaceClient.saveLayout()`'s output — see {@link PanelInfo.serializable}.
|
|
1196
|
+
*/
|
|
1197
|
+
declare function isSerializable(value: unknown): boolean;
|
|
1198
|
+
|
|
997
1199
|
/**
|
|
998
1200
|
* Options used when requesting to close a container.
|
|
999
1201
|
*/
|
|
@@ -1014,6 +1216,17 @@ interface FormContainerContract {
|
|
|
1014
1216
|
setDirty: (dirty: boolean, options?: DirtyStateOptions) => void;
|
|
1015
1217
|
/** Register a custom close guard handler. Returning false or a promise resolving to false blocks closing. */
|
|
1016
1218
|
onCloseRequested: (handler: () => boolean | Promise<boolean>) => (() => void);
|
|
1219
|
+
/**
|
|
1220
|
+
* Registers a callback reporting this panel's *current* restorable state, pulled fresh by
|
|
1221
|
+
* `WorkspaceClient.saveLayout()` every time it's called — for panels whose static open-time
|
|
1222
|
+
* props can't capture state accumulated after opening (scroll position, an in-progress edit, a
|
|
1223
|
+
* view-mode toggle). Only meaningful for docked/floating panels — left/right side panels and
|
|
1224
|
+
* modals already have a complete answer to this via `openLeftPanel`/`openRightPanel`/
|
|
1225
|
+
* `openModal`'s own `props` argument plus `updateInstance`, so this is `undefined` there.
|
|
1226
|
+
* The returned value must be synchronous — `saveLayout()` itself never returns a `Promise`.
|
|
1227
|
+
* Return `undefined` to fall back to the static `props` this panel was opened with.
|
|
1228
|
+
*/
|
|
1229
|
+
registerStateProvider?: (getState: () => unknown) => (() => void);
|
|
1017
1230
|
/** Change the display title of the containing tab or window dynamically. */
|
|
1018
1231
|
setTitle: (title: string | {
|
|
1019
1232
|
id: string;
|
|
@@ -1073,6 +1286,17 @@ declare const FormContainerProvider: Provider<FormContainerContract>;
|
|
|
1073
1286
|
* (resize, close, minimize, restore, activate, deactivate, container-type changes).
|
|
1074
1287
|
*/
|
|
1075
1288
|
declare const useFormContainer: () => FormContainerContract;
|
|
1289
|
+
/**
|
|
1290
|
+
* Reactive alternative to calling {@link FormContainerContract.getDimensions} yourself.
|
|
1291
|
+
* Returns the panel's current `{ width, height }`, or `null` before it has been laid
|
|
1292
|
+
* out, and re-renders whenever the panel's rendered box changes — including resizes
|
|
1293
|
+
* caused by the workspace itself (a grid split being dragged, docking, floating, or
|
|
1294
|
+
* tab activation), not just resizes of an element the panel created.
|
|
1295
|
+
*/
|
|
1296
|
+
declare const usePanelSize: () => {
|
|
1297
|
+
width: number;
|
|
1298
|
+
height: number;
|
|
1299
|
+
} | null;
|
|
1076
1300
|
|
|
1077
1301
|
/** Unique string identifier for panel/modal instances. */
|
|
1078
1302
|
type PanelInstanceId = string;
|
|
@@ -1280,7 +1504,7 @@ interface SidebarProps {
|
|
|
1280
1504
|
/** Which side the activity bar and drawer appear on. Default: 'right' */
|
|
1281
1505
|
position?: 'left' | 'right';
|
|
1282
1506
|
tabs: SidebarTab[];
|
|
1283
|
-
/** Initial drawer width in pixels. Default:
|
|
1507
|
+
/** Initial drawer width in pixels. Default: 280 */
|
|
1284
1508
|
defaultWidth?: number;
|
|
1285
1509
|
/** Minimum drawer width in pixels during drag-resize. Default: 150 */
|
|
1286
1510
|
minWidth?: number;
|
|
@@ -1302,8 +1526,6 @@ interface SidebarProps {
|
|
|
1302
1526
|
onStripVisibilityChange?: (visible: boolean) => void;
|
|
1303
1527
|
/** Main workspace content rendered alongside the sidebar. */
|
|
1304
1528
|
children?: React$1.ReactNode;
|
|
1305
|
-
/** @deprecated Use defaultWidth (number, pixels) instead. */
|
|
1306
|
-
drawerWidth?: string;
|
|
1307
1529
|
}
|
|
1308
1530
|
/**
|
|
1309
1531
|
* Imperative handle exposed by `<Sidebar ref={...}>`.
|
|
@@ -1344,14 +1566,14 @@ declare const Sidebar: React$1.ForwardRefExoticComponent<SidebarProps & React$1.
|
|
|
1344
1566
|
* Returns sidebar control functions from anywhere inside a `<Sidebar>` tree,
|
|
1345
1567
|
* including floating panels rendered via `{children}`.
|
|
1346
1568
|
*
|
|
1347
|
-
*
|
|
1569
|
+
* @throws Error if used outside of a {@link Sidebar}.
|
|
1348
1570
|
*/
|
|
1349
1571
|
declare function useSidebar(): SidebarContextValue;
|
|
1350
1572
|
/**
|
|
1351
1573
|
* Returns tab-specific control functions for components rendered inside a
|
|
1352
1574
|
* sidebar tab's `renderContent` tree.
|
|
1353
1575
|
*
|
|
1354
|
-
*
|
|
1576
|
+
* @throws Error if used outside of a {@link Sidebar} tab's `renderContent` tree.
|
|
1355
1577
|
*/
|
|
1356
1578
|
declare function useSidebarTab(): SidebarTabContextValue;
|
|
1357
1579
|
|
|
@@ -1380,7 +1602,7 @@ declare const ToolbarProvider: React$1.FC<{
|
|
|
1380
1602
|
* Returns toolbar state and control functions from anywhere inside
|
|
1381
1603
|
* a `<DockableDesktopProvider>` tree.
|
|
1382
1604
|
*
|
|
1383
|
-
*
|
|
1605
|
+
* @throws Error if used outside of a {@link DockableDesktopProvider}.
|
|
1384
1606
|
*/
|
|
1385
1607
|
declare function useToolbar(): ToolbarContextValue;
|
|
1386
1608
|
|
|
@@ -1417,8 +1639,8 @@ interface ToolbarRadioItem {
|
|
|
1417
1639
|
/**
|
|
1418
1640
|
* An independent on/off toggle modifier (e.g. snap-to-grid).
|
|
1419
1641
|
*
|
|
1420
|
-
* Supports both uncontrolled mode (omit `active` — state lives in
|
|
1421
|
-
* ToolbarContext, keyed by `id`) and controlled mode (provide `active` —
|
|
1642
|
+
* Supports both uncontrolled mode (omit `rdd-active` — state lives in
|
|
1643
|
+
* ToolbarContext, keyed by `id`) and controlled mode (provide `rdd-active` —
|
|
1422
1644
|
* the caller is the single source of truth and must update the prop in
|
|
1423
1645
|
* response to `onToggle`). Controlled mode is what lets independent
|
|
1424
1646
|
* instances of the same panel type report independent active state
|
|
@@ -1929,8 +2151,9 @@ declare const PanelContributionProvider: React$1.FC<{
|
|
|
1929
2151
|
* `useMemo`/`useCallback`) to avoid republishing on every unrelated re-render.
|
|
1930
2152
|
*
|
|
1931
2153
|
* Contributions are only ever surfaced while this panel is `state.activePanelId` —
|
|
1932
|
-
* see `useActivePanelContribution()`.
|
|
2154
|
+
* see `useActivePanelContribution()`.
|
|
1933
2155
|
*
|
|
2156
|
+
* @throws Error if used outside of a {@link PanelContributionProvider}.
|
|
1934
2157
|
* @example
|
|
1935
2158
|
* function MapPanel() {
|
|
1936
2159
|
* const [controller, setController] = useState<'pan' | 'draw' | 'measure'>('pan');
|
|
@@ -1950,6 +2173,8 @@ declare function usePanelContribution(contribution: PanelContribution): void;
|
|
|
1950
2173
|
* via `usePanelContribution()`, or `null` if no panel is active or the active panel
|
|
1951
2174
|
* hasn't contributed anything. Intended for the app shell to merge into its own
|
|
1952
2175
|
* `<Toolbar items={...}>` / `<Sidebar tabs={...}>` calls.
|
|
2176
|
+
*
|
|
2177
|
+
* @throws Error if used outside of a {@link PanelContributionProvider}.
|
|
1953
2178
|
*/
|
|
1954
2179
|
declare function useActivePanelContribution(): PanelContribution | null;
|
|
1955
2180
|
/**
|
|
@@ -1975,4 +2200,83 @@ declare function useMergedToolbarItems(staticItems: ToolbarItem$1[]): ToolbarIte
|
|
|
1975
2200
|
*/
|
|
1976
2201
|
declare function useMergedSidebarTabs(staticTabs: SidebarTab[], fallbackIcon?: React$1.ReactNode): SidebarTab[];
|
|
1977
2202
|
|
|
1978
|
-
|
|
2203
|
+
/**
|
|
2204
|
+
* Shared pointer-drag-resize primitives.
|
|
2205
|
+
*
|
|
2206
|
+
* Extracted from four previously-independent implementations (the workspace grid
|
|
2207
|
+
* split resizer, the sidebar drawer resizer, and two floating-window resize-handle
|
|
2208
|
+
* implementations) that had quietly drifted apart in exactly the kind of detail
|
|
2209
|
+
* (an inline-style property present in one and missing in the other) that once
|
|
2210
|
+
* caused a real, user-visible bug. This file is the single place that mechanic now
|
|
2211
|
+
* lives, so it can't drift again.
|
|
2212
|
+
*/
|
|
2213
|
+
interface PointerDragConfig<TStart> {
|
|
2214
|
+
/** The element to capture the pointer on — normally the handle the user grabbed. */
|
|
2215
|
+
element: HTMLElement;
|
|
2216
|
+
pointerId: number;
|
|
2217
|
+
/** The pointerdown event's clientX/clientY, used as the delta origin. */
|
|
2218
|
+
startClientX: number;
|
|
2219
|
+
startClientY: number;
|
|
2220
|
+
/** Snapshot whatever state the caller needs at drag start (sizes, positions, ...). */
|
|
2221
|
+
captureStart: () => TStart;
|
|
2222
|
+
/** Called on every pointermove with the delta from the drag's start position. */
|
|
2223
|
+
onMove: (dx: number, dy: number, start: TStart) => void;
|
|
2224
|
+
/** Called once when the drag ends (pointerup or pointercancel). */
|
|
2225
|
+
onEnd?: (start: TStart) => void;
|
|
2226
|
+
/** Classes toggled on the given elements for the duration of the drag. */
|
|
2227
|
+
activeClasses?: Array<{
|
|
2228
|
+
el: HTMLElement;
|
|
2229
|
+
classes: string[];
|
|
2230
|
+
}>;
|
|
2231
|
+
}
|
|
2232
|
+
/**
|
|
2233
|
+
* Starts a pointer-capture-based drag: captures the pointer on `element`, tracks
|
|
2234
|
+
* movement via listeners scoped to that element's own lifetime (not `window`), and
|
|
2235
|
+
* cleans up automatically on release or cancel.
|
|
2236
|
+
*/
|
|
2237
|
+
declare function startPointerDrag<TStart>(config: PointerDragConfig<TStart>): void;
|
|
2238
|
+
type ResizeDir = 'n' | 'ne' | 'e' | 'se' | 's' | 'sw' | 'w' | 'nw';
|
|
2239
|
+
interface ResizeRect {
|
|
2240
|
+
x: number;
|
|
2241
|
+
y: number;
|
|
2242
|
+
w: number;
|
|
2243
|
+
h: number;
|
|
2244
|
+
}
|
|
2245
|
+
interface ResizeConstraints {
|
|
2246
|
+
minW: number;
|
|
2247
|
+
minH: number;
|
|
2248
|
+
/** Upper bound on width — only applies to eastward growth (dir includes 'e'). */
|
|
2249
|
+
maxW?: number;
|
|
2250
|
+
/** Upper bound on height — only applies to southward growth (dir includes 's'). */
|
|
2251
|
+
maxH?: number;
|
|
2252
|
+
/** Lower bound on the resulting x — only applies to westward growth (dir includes 'w'). */
|
|
2253
|
+
minX?: number;
|
|
2254
|
+
/** Lower bound on the resulting y — only applies to northward growth (dir includes 'n'). */
|
|
2255
|
+
minY?: number;
|
|
2256
|
+
}
|
|
2257
|
+
/**
|
|
2258
|
+
* Pure function computing the new rect for an 8-directional resize handle drag.
|
|
2259
|
+
*
|
|
2260
|
+
* `maxW`/`maxH` and `minX`/`minY` are independent, direction-scoped constraints
|
|
2261
|
+
* rather than one "container bound" — a resize toward the fixed edge (e/s) is
|
|
2262
|
+
* naturally bounded by a maximum dimension, while a resize toward the moving edge
|
|
2263
|
+
* (w/n) is naturally bounded by a minimum position, and the two calling sites this
|
|
2264
|
+
* was extracted from need different subsets of these (see WindowManager.tsx's
|
|
2265
|
+
* `startResize`, which omits all four and lets a window grow unbounded and be
|
|
2266
|
+
* dragged fully off-screen, vs. PanelOverlay.tsx's `handleResizePointerDown`, which
|
|
2267
|
+
* supplies all four to keep windows within their container).
|
|
2268
|
+
*/
|
|
2269
|
+
declare function computeResizedRect(dir: ResizeDir, dx: number, dy: number, start: ResizeRect, constraints: ResizeConstraints): ResizeRect;
|
|
2270
|
+
|
|
2271
|
+
/**
|
|
2272
|
+
* Reactively reads the workspace's current `data-color-scheme` attribute
|
|
2273
|
+
* (set on `document.documentElement` by `<WindowManager />`), returning
|
|
2274
|
+
* `'dark'` or `'light'` and re-rendering whenever it changes.
|
|
2275
|
+
*
|
|
2276
|
+
* Useful for panel content that needs to react to the same scheme the
|
|
2277
|
+
* workspace itself is using — e.g. swapping a map's tile layer or an
|
|
2278
|
+
* embedded editor's theme to match.
|
|
2279
|
+
*/
|
|
2280
|
+
declare function useColorScheme(): 'dark' | 'light';
|
|
2281
|
+
|
|
2282
|
+
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, ContextMenuProvider, 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 OpenPanelOptions, type PanelActions, type PanelContribution, PanelContributionProvider, type PanelDefinition, PanelFloatingWindow, type PanelFloatingWindowManagerHandle, type PanelFloatingWindowProps, type PanelInfo, type PanelInstance, type PanelInstanceId, PanelOverlayRoot, type PanelOverlayRootProps, PanelProvider, PanelRegistry, PanelRegistryClass, type PanelRegistryEntry, type PanelSidebarSection, type PanelState, type PanelTitle, PanelToolbar, ToolbarItem as PanelToolbarItem, type PanelToolbarProps, ToolbarSeparator as PanelToolbarSeparator, type PointerDragConfig, type PredefinedMessageKey, type ResizeConstraints, type ResizeDir, type ResizeRect, type ResolvedToastOptions, RightPanelRenderer, type SearchResult, type SerializedLayout, 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, computeResizedRect, defaultPredefinedMessages, formatLabel, isSerializable, sidebarSectionToTab, startPointerDrag, toast, useActivePanelContribution, useColorScheme, useFormContainer, useFormatMessage, useMergedSidebarTabs, useMergedToolbarItems, usePanelActions, usePanelContext, usePanelContextMenu, usePanelContribution, usePanelFloatingWindow, usePanelFloatingWindowManager, usePanelId, usePanelSize, usePanelState, usePredefinedMessages, useRegistry, useShowContextMenu, useSidebar, useSidebarTab, useStyleClasses, useToolbar, useWindowManagerActions, useWindowManagerState };
|