@frame-kit/ui-ng 0.0.3 → 0.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,184 +0,0 @@
1
- # OverlayOrchestrator
2
-
3
- A centralized service for managing overlay interactions (dialogs, drawers, popovers, navigation panels, tooltips) using a priority-based stack. Prevents UI conflicts like drawers staying open behind dialogs, or menus persisting when modals appear.
4
-
5
- ---
6
-
7
- ## Initialization
8
-
9
- The `OverlayOrchestrator` is provided at the root level (`providedIn: 'root'`). No setup is needed — inject it wherever you need overlay coordination.
10
-
11
- ```ts
12
- import { OverlayOrchestrator, OVERLAY_PRIORITY } from '@frame-kit/ui-ng';
13
- ```
14
-
15
- ### Built-in Integration
16
-
17
- `DialogService` and `DrawerService` automatically register with the orchestrator. Opening a dialog auto-closes any open drawer or popover. Opening a drawer auto-closes any open popover. No consumer code is needed for these — it works out of the box.
18
-
19
- ### Registering Custom Overlays
20
-
21
- For overlays not managed by `DialogService` or `DrawerService` (e.g., custom popovers, app navigation panels, kebab menus), register them manually:
22
-
23
- ```ts
24
- @Component({ ... })
25
- export class MyComponent {
26
- private readonly orchestrator = inject(OverlayOrchestrator);
27
- private overlayId: string | null = null;
28
-
29
- open(): void {
30
- // Register with a priority — closes all lower-priority overlays
31
- this.overlayId = this.orchestrator.register({
32
- priority: OVERLAY_PRIORITY.POPOVER,
33
- type: "my-popover",
34
- close: () => this.close(),
35
- });
36
- }
37
-
38
- close(): void {
39
- if (this.overlayId) {
40
- this.orchestrator.unregister(this.overlayId);
41
- this.overlayId = null;
42
- }
43
-
44
- // ... your close logic
45
- }
46
- }
47
- ```
48
-
49
- ### Registering App Navigation
50
-
51
- The app shell sidebar should register at the highest priority so it always opens on top:
52
-
53
- ```ts
54
- @Component({ ... })
55
- export class AppShellComponent {
56
- private readonly orchestrator = inject(OverlayOrchestrator);
57
- private navOverlayId: string | null = null;
58
-
59
- openNav(): void {
60
- this.navOverlayId = this.orchestrator.register({
61
- priority: OVERLAY_PRIORITY.NAVIGATION,
62
- type: "navigation",
63
- close: () => this.closeNav(),
64
- });
65
- }
66
-
67
- closeNav(): void {
68
- if (this.navOverlayId) {
69
- this.orchestrator.unregister(this.navOverlayId);
70
- this.navOverlayId = null;
71
- }
72
-
73
- // ... your close logic
74
- }
75
- }
76
- ```
77
-
78
- ### Guarding Before Opening
79
-
80
- Check if a higher-priority overlay is already open before opening yours:
81
-
82
- ```ts
83
- if (!this.orchestrator.hasOverlayAtOrAbove(OVERLAY_PRIORITY.DIALOG)) {
84
- this.openDrawer();
85
- }
86
- ```
87
-
88
- ---
89
-
90
- ## API
91
-
92
- ### OverlayOrchestrator (Injectable)
93
-
94
- #### Methods
95
-
96
- | Method | Signature | Description |
97
- | --------------------- | --------------------------------------------- | ------------------------------------------------------------------------------ |
98
- | `register` | `(entry: Omit<OverlayEntry, 'id'>) => string` | Register an overlay. Auto-closes lower-priority overlays. Returns a unique ID. |
99
- | `unregister` | `(id: string) => void` | Remove an overlay by ID. Call when the overlay closes. |
100
- | `closeAll` | `() => void` | Close all overlays, lowest priority first. |
101
- | `closeAtOrBelow` | `(priority: number) => void` | Close all overlays at or below the given priority. |
102
- | `hasOverlayAtOrAbove` | `(priority: number) => boolean` | Check if any overlay at or above a priority is open. |
103
- | `hasOverlayOfType` | `(type: string) => boolean` | Check if any overlay of a given type is open. |
104
-
105
- #### Signals (Reactive)
106
-
107
- | Signal | Type | Description |
108
- | ------------------ | ------------------------------ | ---------------------------------- |
109
- | `hasActiveOverlay` | `Signal<boolean>` | Whether any overlay is open. |
110
- | `topOverlay` | `Signal<OverlayEntry \| null>` | The highest-priority open overlay. |
111
- | `count` | `Signal<number>` | Number of active overlays. |
112
-
113
- ---
114
-
115
- ## Priority Levels
116
-
117
- Default priority constants are provided via `OVERLAY_PRIORITY`. You can use any number — these are conventions, not constraints.
118
-
119
- ```ts
120
- import { OVERLAY_PRIORITY } from '@frame-kit/ui-ng';
121
-
122
- OVERLAY_PRIORITY.TOOLTIP; // 0 — tooltips, inline hints
123
- OVERLAY_PRIORITY.POPOVER; // 10 — dropdown menus, kebab menus
124
- OVERLAY_PRIORITY.DRAWER; // 20 — side panels, detail drawers
125
- OVERLAY_PRIORITY.DIALOG; // 30 — modal dialogs, confirmations
126
- OVERLAY_PRIORITY.NAVIGATION; // 40 — app-level navigation sidebar
127
- ```
128
-
129
- ### Custom Priorities
130
-
131
- Use any number to fine-tune behavior:
132
-
133
- ```ts
134
- // A toast notification that sits between popover and drawer
135
- orchestrator.register({
136
- priority: 15,
137
- type: 'toast',
138
- close: () => this.dismissToast(),
139
- });
140
- ```
141
-
142
- ---
143
-
144
- ## OverlayEntry Interface
145
-
146
- ```ts
147
- interface OverlayEntry {
148
- id: string; // Auto-generated unique ID
149
- priority: number; // Higher = stays open longer
150
- type: string; // Label for debugging/querying
151
- close: () => void; // Called by orchestrator to close
152
- }
153
- ```
154
-
155
- ---
156
-
157
- ## Behavior Rules
158
-
159
- 1. **Opening a new overlay closes all overlays with LOWER priority.**
160
- - Opening a dialog (30) closes drawers (20), popovers (10), tooltips (0).
161
- - Opening a drawer (20) closes popovers (10) and tooltips (0).
162
- - Opening the nav (40) does not close dialogs (30) — they have lower priority.
163
-
164
- 2. **Overlays with EQUAL or HIGHER priority are left open.**
165
- - Opening a second dialog does not close the first dialog.
166
- - Opening the nav while a dialog is open leaves the dialog open.
167
-
168
- 3. **Unregistration is the consumer's responsibility.**
169
- - The orchestrator calls `close()` on entries to request closure.
170
- - The consumer must call `unregister(id)` when the overlay actually closes.
171
- - `DialogService` and `DrawerService` handle this automatically.
172
-
173
- 4. **Priority is set per instance, not per type.**
174
- - The same component can register at different priorities depending on context.
175
- - A critical confirmation dialog could register at 35 to stay above normal dialogs.
176
-
177
- ---
178
-
179
- ## Import
180
-
181
- ```ts
182
- import { OverlayOrchestrator, OVERLAY_PRIORITY } from '@frame-kit/ui-ng';
183
- import type { OverlayEntry } from '@frame-kit/ui-ng';
184
- ```
@@ -1,96 +0,0 @@
1
- import * as _angular_core from '@angular/core';
2
-
3
- /**
4
- * Default priority levels for common overlay types.
5
- * Higher number = higher priority = stays open when lower-priority overlays open.
6
- *
7
- * Consumers can use any number — these are conventions, not constraints.
8
- */
9
- declare const OVERLAY_PRIORITY: {
10
- /** Tooltips, inline popovers */
11
- readonly TOOLTIP: 0;
12
- /** Dropdown menus, kebab menus, popovers */
13
- readonly POPOVER: 10;
14
- /** Side panels, detail drawers */
15
- readonly DRAWER: 20;
16
- /** Modal dialogs, confirmations */
17
- readonly DIALOG: 30;
18
- /** App-level navigation (sidebar, mobile nav) */
19
- readonly NAVIGATION: 40;
20
- };
21
- interface OverlayEntry {
22
- /** Unique identifier for this overlay instance */
23
- id: string;
24
- /** Priority level — higher stays open, lower gets closed */
25
- priority: number;
26
- /** Overlay type label (for debugging/logging) */
27
- type: string;
28
- /** Called by the orchestrator to close this overlay */
29
- close: () => void;
30
- }
31
-
32
- /**
33
- * Centralized overlay orchestrator.
34
- *
35
- * Tracks all open overlays (dialogs, drawers, popovers, navigation, tooltips)
36
- * in a priority-based stack. When a new overlay opens:
37
- *
38
- * - All overlays with LOWER priority are closed automatically.
39
- * - Overlays with EQUAL or HIGHER priority are left open.
40
- *
41
- * This prevents UI conflicts like drawers staying open behind dialogs,
42
- * or kebab menus persisting when a modal pops up.
43
- *
44
- * @example
45
- * ```ts
46
- * const id = orchestrator.register({
47
- * priority: OVERLAY_PRIORITY.DRAWER,
48
- * type: 'drawer',
49
- * close: () => drawerRef.close(),
50
- * });
51
- *
52
- * // Later, when the overlay closes:
53
- * orchestrator.unregister(id);
54
- * ```
55
- */
56
- declare class OverlayOrchestrator {
57
- private readonly entries;
58
- /** Whether any overlay is currently open. */
59
- readonly hasActiveOverlay: _angular_core.Signal<boolean>;
60
- /** The topmost (highest priority) overlay. */
61
- readonly topOverlay: _angular_core.Signal<OverlayEntry | null>;
62
- /** Current number of active overlays. */
63
- readonly count: _angular_core.Signal<number>;
64
- /**
65
- * Register an overlay and close all overlays with lower priority.
66
- *
67
- * @returns The unique overlay ID — pass this to `unregister()` when closing.
68
- */
69
- register(entry: Omit<OverlayEntry, 'id'>): string;
70
- /**
71
- * Unregister an overlay by ID. Call this when the overlay closes.
72
- */
73
- unregister(id: string): void;
74
- /**
75
- * Check if an overlay with the given priority or higher is currently open.
76
- * Useful for guards that want to prevent opening lower-priority overlays.
77
- */
78
- hasOverlayAtOrAbove(priority: number): boolean;
79
- /**
80
- * Check if any overlay of a specific type is open.
81
- */
82
- hasOverlayOfType(type: string): boolean;
83
- /**
84
- * Close all overlays. Closes from lowest to highest priority.
85
- */
86
- closeAll(): void;
87
- /**
88
- * Close all overlays at or below the given priority.
89
- */
90
- closeAtOrBelow(priority: number): void;
91
- static ɵfac: _angular_core.ɵɵFactoryDeclaration<OverlayOrchestrator, never>;
92
- static ɵprov: _angular_core.ɵɵInjectableDeclaration<OverlayOrchestrator>;
93
- }
94
-
95
- export { OVERLAY_PRIORITY, OverlayOrchestrator };
96
- export type { OverlayEntry };