import * as i0 from '@angular/core'; import { ComponentRef, WritableSignal, Signal, InjectionToken } from '@angular/core'; import { OverlayRef } from '@angular/cdk/overlay'; import { Subject } from 'rxjs'; import { ComponentType } from '@angular/cdk/portal'; /** * @license * * Use of this source code is governed by an MIT-style license that can be * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE */ /** * Chrome bar density. * * - `normal` (default) — 2.25rem bar, regular title font. * - `compact` — 1.625rem bar, smaller title + tighter action dots; useful * for utility / docked panels where vertical space is precious. */ type WrWindowChromeSize = 'compact' | 'normal'; /** * @license * * Use of this source code is governed by an MIT-style license that can be * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE */ /** * Chrome style preset. Picks the side, glyphs, and button look of the * minimize / maximize / close cluster. * * - `auto` (default) — read the user's OS from the browser and pick * `macos` / `windows` / `linux`. Unknown platforms fall back to * `windows`. SSR-safe (resolves to `windows` on the server). * - `macos` — traffic-light dots on the LEFT (red close, yellow minimize, * green maximize). Glyphs (×, −, +) appear when the cluster is hovered. * - `windows` — monochrome glyph buttons on the RIGHT. * - `linux` — close-only on the right; minimize / maximize hidden unless * explicitly requested. */ type WrWindowOs = 'auto' | 'macos' | 'windows' | 'linux'; /** * @license * * Use of this source code is governed by an MIT-style license that can be * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE */ /** * Size preset — seeds initial width / height when `[initialWidth]` / * `[initialHeight]` are not provided. * * - `sm` — 320 × 200 * - `md` — 480 × 320 (default) * - `lg` — 720 × 480 */ type WrWindowSize = 'sm' | 'md' | 'lg'; /** * @license * * Use of this source code is governed by an MIT-style license that can be * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE */ /** * Edge / corner snap behaviour. Activated by dragging the title bar * close to a viewport edge. * * - `none` — no snapping. * - `edges` — left / right / top edges snap to halves; top snaps to maximise. * - `all` — adds the four corners → quarter-screen snaps. */ type WrWindowSnap = 'none' | 'edges' | 'all'; /** * @license * * Use of this source code is governed by an MIT-style license that can be * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE */ /** What slice of geometry the storage layer should keep in sync. */ type WrWindowPersistMode = 'position' | 'size' | 'all'; /** * Persistence configuration — drop into `WrWindowConfig.storage`. * * Reads and writes happen through the consumer's `WrStorage` instance. * Override the underlying engine at any injector level with * `provideWrStorage({ engine: window.sessionStorage })` when you want * session-scoped persistence instead of the default `localStorage`. */ interface WrWindowStorageConfig { /** * Storage key for this window. Combined with `prefix` (if any) and a * `wr:window:` namespace, e.g. `wr:window:my-app:editor`. */ readonly key: string; /** Namespace prefix (typically your app id). @default '' */ readonly prefix?: string; /** What to persist. @default 'all' */ readonly persist?: WrWindowPersistMode; } /** * Options accepted by `WrWindowManager.open(component, config)`. * * Every property has a sensible default — pass `{}` to open a window * with the standard chrome at the cascaded position. */ interface WrWindowConfig { /** Stable identifier — used by the taskbar, workspace save, and DI. */ readonly id?: string; readonly title?: string; readonly os?: WrWindowOs; /** Initial size preset. Ignored when `width` / `height` are passed. */ readonly size?: WrWindowSize; /** Title-bar density. @default 'normal' */ readonly chromeSize?: WrWindowChromeSize; readonly x?: number; readonly y?: number; readonly width?: number; readonly height?: number; readonly minWidth?: number; readonly minHeight?: number; readonly maxWidth?: number; readonly maxHeight?: number; readonly movable?: boolean; readonly resizable?: boolean; readonly keepInViewport?: boolean; readonly closeOnEscape?: boolean; /** Snap-on-drag mode. @default 'none' */ readonly snap?: WrWindowSnap; readonly showMinimize?: boolean; readonly showMaximize?: boolean; readonly showClose?: boolean; /** Show in `` when minimized. @default true */ readonly taskbar?: boolean; readonly animations?: boolean; /** CSS selector inside the projected content that restricts the move-grab area. */ readonly dragHandle?: string; readonly storage?: WrWindowStorageConfig; readonly data?: D; } /** * @license * * Use of this source code is governed by an MIT-style license that can be * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE */ /** * Visual state of a ``: * - `normal` — free-floating, drag / resize allowed * - `minimized` — collapsed to a small bar (only the header is shown) * - `maximized` — pinned to the full viewport, drag / resize disabled */ type WrWindowState = 'normal' | 'minimized' | 'maximized'; /** Hook signature for `WrWindowRef.beforeClose()`. Return falsy to veto. */ type WrWindowBeforeCloseHook = (result: R | undefined) => boolean | Promise; /** * @license * * Use of this source code is governed by an MIT-style license that can be * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE */ /** * Handle returned by `WrWindowManager.open()`. * * Wraps the underlying overlay, exposes signals for the live geometry, * and gives the consumer programmatic control over the window * (focus, move, resize, minimize, maximize, close). * * @example * ```ts * const ref = manager.open(EditorComponent, { * title: 'Untitled.md', * storage: { key: 'editor', prefix: 'app' }, * }); * * ref.beforeClose(async () => { * if (!isDirty) return true; * return await confirmDiscard(); * }); * * const saved = await ref.afterClosed(); // resolves with whatever the * // component passed to ref.close(value) * ``` */ declare class WrWindowRef { readonly _overlayRef: OverlayRef; /** Stable id — used by the taskbar, workspace save, and DI. */ readonly id: string; /** @internal — emits the close result once and completes. */ readonly _closed: Subject; /** @internal — emits whenever the visual state changes. */ readonly _stateChanged: Subject; /** @internal — set by the container right after attach. */ componentRef: ComponentRef | null; /** @internal — whether this window opts into the taskbar list. */ taskbarVisible: boolean; /** * @internal — non-`normal` state to apply right after the container * wires its bridges (so `restoreLayout` can land a window straight * into `minimized` / `maximized` even though it just opened). */ pendingStateOnMount: WrWindowState | null; /** @internal */ readonly _state: WritableSignal; /** @internal */ readonly _x: WritableSignal; /** @internal */ readonly _y: WritableSignal; /** @internal */ readonly _width: WritableSignal; /** @internal */ readonly _height: WritableSignal; /** @internal */ readonly _z: WritableSignal; /** @internal */ readonly _title: WritableSignal; /** Window state. */ readonly state: Signal; /** Live X. */ readonly x: Signal; /** Live Y. */ readonly y: Signal; /** Live width. */ readonly width: Signal; /** Live height. */ readonly height: Signal; /** Stack z-index. */ readonly z: Signal; /** Live title. */ readonly title: Signal; private _beforeCloseHook; /** @internal */ _doClose: ((result: R | undefined) => void) | null; /** @internal */ _doMinimize: (() => void) | null; /** @internal */ _doMaximize: (() => void) | null; /** @internal */ _doRestore: (() => void) | null; /** @internal */ _doFocus: (() => void) | null; /** @internal */ _doMoveTo: ((x: number, y: number) => void) | null; /** @internal */ _doResizeTo: ((w: number, h: number) => void) | null; /** @internal */ _doCenter: (() => void) | null; /** @internal */ _doSetTitle: ((title: string) => void) | null; constructor(id: string, _overlayRef: OverlayRef); /** Resolved instance of the projected component. */ get componentInstance(): C; /** * Close the window, optionally returning a result. If a `beforeClose` * hook is registered it is consulted first — a falsy resolution * cancels the close. */ close(result?: R): Promise; /** Toggle the minimized state. */ minimize(): void; /** Toggle the maximized state. */ maximize(): void; /** Force-restore from minimized / maximized to `normal`. */ restore(): void; /** Bring this window to the top of the stack. */ focus(): void; moveTo(x: number, y: number): void; resizeTo(width: number, height: number): void; /** Re-position the window so it sits centered in the current viewport. */ center(): void; setTitle(title: string): void; /** * Register a guard that runs before `close()`. Return `false` (or a * Promise resolving to false) to veto. Only one hook per ref — * subsequent calls replace the previous. */ beforeClose(hook: WrWindowBeforeCloseHook): void; /** Resolves with the result passed to `close()` (or `undefined`). */ afterClosed(): Promise; /** Escape hatch — the underlying CDK overlay ref. */ get overlayRef(): OverlayRef; } /** * @license * * Use of this source code is governed by an MIT-style license that can be * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE */ /** Resolves to the active `WrWindowRef` inside a programmatically-opened window's content tree. */ declare const WR_WINDOW_REF: InjectionToken>; /** Resolves to the `data` passed in `WrWindowConfig.data`. */ declare const WR_WINDOW_DATA: InjectionToken; interface RestoreSnapshot { readonly id: string; readonly state: WrWindowState; readonly x: number; readonly y: number; readonly width: number; readonly height: number; readonly title: string; } /** * Owns the open `` stack, hands out z-indexes, cascades the * default spawn position, and opens programmatic windows that wrap a * consumer component. * * Inject the singleton and call `open(component, config)` for a * dialog-style flow: * * ```ts * const manager = inject(WrWindowManager); * * const ref = manager.open(EditorComponent, { * title: 'Untitled.md', * size: 'lg', * storage: { key: 'editor', prefix: 'my-app' }, * }); * * const saved = await ref.afterClosed(); * ``` * * Declarative `` instances also register with * the manager on focus, so both styles share the same stack ordering. */ declare class WrWindowManager { private readonly overlay; private readonly parentInjector; private readonly storage; private readonly isBrowser; private readonly baseZ; private topZ; private openCount; /** All open windows opened via `open()` — declarative `` is not tracked here. */ private readonly _windows; /** * Filled by `restoreLayout` right before it invokes the consumer's * opener callback. The next `open()` call with a matching `config.id` * pops the entry and uses it as the initial geometry (so the seed * lands at the saved coords instead of the cascade default) and * applies any non-`normal` state after the bridges are wired. */ private readonly pendingRestores; /** All currently-open programmatic windows. */ readonly windows: Signal[]>; /** Programmatic windows that are minimized AND opted into the taskbar. */ readonly minimized: Signal[]>; /** Reserve the next z-index. Strictly increasing across the app's lifetime. */ bringToFront(): number; /** Cascade offset for new windows, so two opens don't perfectly overlap. */ nextStartOffset(): { readonly x: number; readonly y: number; }; /** * Open a window with `component` rendered as its body. Returns a ref * the caller can use to drive the window programmatically and await * its result. * * **Singleton by id** — if `config.id` is set and a window with that * id is already open, the existing ref is restored (if minimized), * brought to the front, and returned. No duplicate window is * created. Use this to coalesce repeated open() calls (e.g. a * "Settings" menu item that should always re-focus the same window). */ open(component: ComponentType, config?: WrWindowConfig): WrWindowRef; /** Close every programmatically-opened window. */ closeAll(): void; /** Look up an open window by its `config.id`. Returns `null` when no match. */ findById(id: string): WrWindowRef | null; /** * Drop the persisted geometry for a window so the next open uses the * config defaults again. Matches `WrWindowConfig.storage` exactly. */ clearPersistedPosition(cfg: WrWindowStorageConfig): void; /** Snapshot of one window — what `saveLayout` writes / `restoreLayout` returns. */ private layoutKey; /** * Persist the geometry + state of every open programmatic window * under `name`. Pair with `restoreLayout(name)` after re-opening the * matching components. */ saveLayout(name: string): void; /** Read a saved workspace. Returns `null` when no snapshot is found. */ readLayout(name: string): readonly RestoreSnapshot[] | null; /** * Apply a saved workspace. * * Each saved entry is matched to a currently-open window by `id`. For * matches, the geometry / state / title is re-applied immediately. * For misses, the optional `open` callback is invoked so the consumer * can re-open the right component for that id — the freshly-opened * window then seeds straight to the saved geometry (no cascade flicker) * and the saved state lands once the bridges are wired. * * ```ts * manager.restoreLayout('default', (id, snap) => { * if (id.startsWith('editor:')) { * manager.open(EditorComponent, { id, title: snap.title, data: ... }); * } * }); * ``` */ restoreLayout(name: string, open?: (id: string, snapshot: { readonly title: string; }) => void): void; private applyRestore; /** Drop a saved workspace. */ clearLayout(name: string): void; static ɵfac: i0.ɵɵFactoryDeclaration; static ɵprov: i0.ɵɵInjectableDeclaration; } /** * OS-style window taskbar. Drop one anywhere in the app — typically * fixed to the bottom of the viewport — and it lists every window * `WrWindowManager.open()` has handed out that's currently * `minimized`. Clicking a tab restores the window; clicking the close * glyph dismisses it without restoring. * * Windows opted out via `config.taskbar = false` never show up here. * * @example * ```html * * * ``` * * @see https://ngwr.dev/components/window */ declare class WrWindowTaskbar { /** Edge the taskbar pins itself to. @default 'bottom' */ readonly position: i0.InputSignal<"top" | "bottom">; private readonly manager; /** @internal — minimized windows that haven't opted out via `taskbar: false`. */ protected readonly items: i0.Signal[]>; protected readonly classes: i0.Signal; protected restore(ref: WrWindowRef): void; protected close(ref: WrWindowRef, event: Event): void; static ɵfac: i0.ɵɵFactoryDeclaration; static ɵcmp: i0.ɵɵComponentDeclaration; } export { WR_WINDOW_DATA, WR_WINDOW_REF, WrWindowManager, WrWindowRef, WrWindowTaskbar }; export type { WrWindowBeforeCloseHook, WrWindowChromeSize, WrWindowConfig, WrWindowOs, WrWindowPersistMode, WrWindowSize, WrWindowSnap, WrWindowState, WrWindowStorageConfig };