@widgetstools/angular-dock-manager 0.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.
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { EventEmitter, ViewChild, Output, Input, ChangeDetectionStrategy, Component, Injectable } from '@angular/core';
|
|
3
|
+
import { DockviewComponent } from '@widgetstools/dock-manager-core';
|
|
4
|
+
export { DockviewApi, DockviewComponent, EventEmitter, clearLocalStorage, createDefaultState, deserialize, dockReducer, draculaDark, exportToFile, findAllTabGroups, findFirstTabGroup, findTabGroupById, findTabGroupForPanel, forestDark, getThemeByName, getThemesByMode, githubLight, importFromFile, lavenderLight, loadFromLocalStorage, midnightDark, mintLight, nordDark, saveToLocalStorage, sepiaLight, serialize, slateDark, solarizedDark, solarizedLight, themes, validateState, vsCodeDark, vsCodeLight, warmLight } from '@widgetstools/dock-manager-core';
|
|
5
|
+
import { BehaviorSubject } from 'rxjs';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Thin Angular wrapper around the core DockviewComponent.
|
|
9
|
+
*
|
|
10
|
+
* All DOM rendering, event handling, and layout logic lives in core.
|
|
11
|
+
* Angular only provides panel content via dynamic component creation.
|
|
12
|
+
*
|
|
13
|
+
* Zoneless: Uses ChangeDetectorRef.markForCheck() instead of NgZone.
|
|
14
|
+
* Compatible with both zone.js and zoneless (provideZonelessChangeDetection).
|
|
15
|
+
*/
|
|
16
|
+
class DockManagerCoreComponent {
|
|
17
|
+
cdr;
|
|
18
|
+
/** Initial state for the dock manager */
|
|
19
|
+
initialState;
|
|
20
|
+
/** Content renderer — called when a panel needs content mounted into a container */
|
|
21
|
+
createContent;
|
|
22
|
+
/** Optional custom tab renderer */
|
|
23
|
+
createTab;
|
|
24
|
+
/** Optional header actions renderer */
|
|
25
|
+
createHeaderActions;
|
|
26
|
+
/** Theme: 'light', 'dark', or a DockTheme object */
|
|
27
|
+
theme = 'light';
|
|
28
|
+
/** Emits when state changes */
|
|
29
|
+
stateChange = new EventEmitter();
|
|
30
|
+
/** Emits before a panel close (preventable) */
|
|
31
|
+
willClose = new EventEmitter();
|
|
32
|
+
/** Emits before a drop (preventable) */
|
|
33
|
+
willDrop = new EventEmitter();
|
|
34
|
+
containerRef;
|
|
35
|
+
dock = null;
|
|
36
|
+
constructor(cdr) {
|
|
37
|
+
this.cdr = cdr;
|
|
38
|
+
}
|
|
39
|
+
ngAfterViewInit() {
|
|
40
|
+
const options = {
|
|
41
|
+
initialState: this.initialState,
|
|
42
|
+
theme: this.theme,
|
|
43
|
+
createContent: (panelId, container, api) => {
|
|
44
|
+
const disposable = this.createContent(panelId, container, api);
|
|
45
|
+
this.cdr.markForCheck();
|
|
46
|
+
return disposable;
|
|
47
|
+
},
|
|
48
|
+
createTab: this.createTab
|
|
49
|
+
? (panelId, container, isActive) => {
|
|
50
|
+
const disposable = this.createTab(panelId, container, isActive);
|
|
51
|
+
this.cdr.markForCheck();
|
|
52
|
+
return disposable;
|
|
53
|
+
}
|
|
54
|
+
: undefined,
|
|
55
|
+
createHeaderActions: this.createHeaderActions
|
|
56
|
+
? (slot, tabGroupId, container) => {
|
|
57
|
+
const disposable = this.createHeaderActions(slot, tabGroupId, container);
|
|
58
|
+
this.cdr.markForCheck();
|
|
59
|
+
return disposable;
|
|
60
|
+
}
|
|
61
|
+
: undefined,
|
|
62
|
+
onStateChange: (state) => {
|
|
63
|
+
this.stateChange.emit(state);
|
|
64
|
+
this.cdr.markForCheck();
|
|
65
|
+
},
|
|
66
|
+
onWillClose: (event, panelId) => {
|
|
67
|
+
this.willClose.emit({ event, panelId });
|
|
68
|
+
this.cdr.markForCheck();
|
|
69
|
+
},
|
|
70
|
+
onWillDrop: (event, sourceId, targetId, position) => {
|
|
71
|
+
this.willDrop.emit({ event, sourceId, targetId, position });
|
|
72
|
+
this.cdr.markForCheck();
|
|
73
|
+
},
|
|
74
|
+
};
|
|
75
|
+
this.dock = new DockviewComponent(this.containerRef.nativeElement, options);
|
|
76
|
+
}
|
|
77
|
+
ngOnChanges(changes) {
|
|
78
|
+
if (changes['theme'] && !changes['theme'].firstChange && this.dock) {
|
|
79
|
+
this.dock.updateOptions({ theme: this.theme });
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
ngOnDestroy() {
|
|
83
|
+
this.dock?.dispose();
|
|
84
|
+
this.dock = null;
|
|
85
|
+
}
|
|
86
|
+
/** Dispatch an action to the dock manager */
|
|
87
|
+
dispatch(action) {
|
|
88
|
+
this.dock?.dispatch(action);
|
|
89
|
+
}
|
|
90
|
+
/** Get current state */
|
|
91
|
+
getState() {
|
|
92
|
+
return this.dock?.getState() ?? null;
|
|
93
|
+
}
|
|
94
|
+
/** Get the underlying DockviewComponent instance */
|
|
95
|
+
getInstance() {
|
|
96
|
+
return this.dock;
|
|
97
|
+
}
|
|
98
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.2", ngImport: i0, type: DockManagerCoreComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
99
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.0.2", type: DockManagerCoreComponent, isStandalone: true, selector: "dock-manager-core", inputs: { initialState: "initialState", createContent: "createContent", createTab: "createTab", createHeaderActions: "createHeaderActions", theme: "theme" }, outputs: { stateChange: "stateChange", willClose: "willClose", willDrop: "willDrop" }, viewQueries: [{ propertyName: "containerRef", first: true, predicate: ["container"], descendants: true, static: true }], usesOnChanges: true, ngImport: i0, template: `<div #container style="width:100%;height:100%"></div>`, isInline: true, styles: [":host{display:block;width:100%;height:100%;overflow:hidden}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
100
|
+
}
|
|
101
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.2", ngImport: i0, type: DockManagerCoreComponent, decorators: [{
|
|
102
|
+
type: Component,
|
|
103
|
+
args: [{ selector: 'dock-manager-core', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, template: `<div #container style="width:100%;height:100%"></div>`, styles: [":host{display:block;width:100%;height:100%;overflow:hidden}\n"] }]
|
|
104
|
+
}], ctorParameters: () => [{ type: i0.ChangeDetectorRef }], propDecorators: { initialState: [{
|
|
105
|
+
type: Input
|
|
106
|
+
}], createContent: [{
|
|
107
|
+
type: Input
|
|
108
|
+
}], createTab: [{
|
|
109
|
+
type: Input
|
|
110
|
+
}], createHeaderActions: [{
|
|
111
|
+
type: Input
|
|
112
|
+
}], theme: [{
|
|
113
|
+
type: Input
|
|
114
|
+
}], stateChange: [{
|
|
115
|
+
type: Output
|
|
116
|
+
}], willClose: [{
|
|
117
|
+
type: Output
|
|
118
|
+
}], willDrop: [{
|
|
119
|
+
type: Output
|
|
120
|
+
}], containerRef: [{
|
|
121
|
+
type: ViewChild,
|
|
122
|
+
args: ['container', { static: true }]
|
|
123
|
+
}] } });
|
|
124
|
+
|
|
125
|
+
class DockThemeService {
|
|
126
|
+
themeModeSubject = new BehaviorSubject('light');
|
|
127
|
+
mediaQueryList = null;
|
|
128
|
+
mediaQueryListener = null;
|
|
129
|
+
themeMode$ = this.themeModeSubject.asObservable();
|
|
130
|
+
constructor() {
|
|
131
|
+
this.initializeSystemModeListener();
|
|
132
|
+
}
|
|
133
|
+
setThemeMode(mode) {
|
|
134
|
+
this.themeModeSubject.next(mode);
|
|
135
|
+
this.applyTheme(mode);
|
|
136
|
+
}
|
|
137
|
+
getThemeMode() {
|
|
138
|
+
return this.themeModeSubject.getValue();
|
|
139
|
+
}
|
|
140
|
+
applyTheme(mode) {
|
|
141
|
+
const root = document.documentElement;
|
|
142
|
+
const isDark = mode === 'dark' || (mode === 'system' && this.isSystemDark());
|
|
143
|
+
if (isDark) {
|
|
144
|
+
root.classList.add('dark');
|
|
145
|
+
}
|
|
146
|
+
else {
|
|
147
|
+
root.classList.remove('dark');
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
isSystemDark() {
|
|
151
|
+
if (typeof window === 'undefined')
|
|
152
|
+
return false;
|
|
153
|
+
return window.matchMedia('(prefers-color-scheme: dark)').matches;
|
|
154
|
+
}
|
|
155
|
+
initializeSystemModeListener() {
|
|
156
|
+
if (typeof window === 'undefined')
|
|
157
|
+
return;
|
|
158
|
+
try {
|
|
159
|
+
this.mediaQueryList = window.matchMedia('(prefers-color-scheme: dark)');
|
|
160
|
+
this.mediaQueryListener = (e) => {
|
|
161
|
+
const currentMode = this.themeModeSubject.getValue();
|
|
162
|
+
if (currentMode === 'system') {
|
|
163
|
+
this.applyTheme('system');
|
|
164
|
+
}
|
|
165
|
+
};
|
|
166
|
+
this.mediaQueryList.addEventListener('change', this.mediaQueryListener);
|
|
167
|
+
}
|
|
168
|
+
catch (e) {
|
|
169
|
+
console.warn('System theme detection not supported', e);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
ngOnDestroy() {
|
|
173
|
+
if (this.mediaQueryList && this.mediaQueryListener) {
|
|
174
|
+
this.mediaQueryList.removeEventListener('change', this.mediaQueryListener);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.2", ngImport: i0, type: DockThemeService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
178
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.0.2", ngImport: i0, type: DockThemeService, providedIn: 'root' });
|
|
179
|
+
}
|
|
180
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.2", ngImport: i0, type: DockThemeService, decorators: [{
|
|
181
|
+
type: Injectable,
|
|
182
|
+
args: [{
|
|
183
|
+
providedIn: 'root',
|
|
184
|
+
}]
|
|
185
|
+
}], ctorParameters: () => [] });
|
|
186
|
+
|
|
187
|
+
// Core-owned DOM architecture
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* Generated bundle index. Do not edit.
|
|
191
|
+
*/
|
|
192
|
+
|
|
193
|
+
export { DockManagerCoreComponent, DockThemeService };
|
|
194
|
+
//# sourceMappingURL=widgetstools-angular-dock-manager.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"widgetstools-angular-dock-manager.mjs","sources":["../../../packages/angular-dock-manager/src/lib/components/dock-manager-core/dock-manager-core.component.ts","../../../packages/angular-dock-manager/src/lib/services/dock-theme.service.ts","../../../packages/angular-dock-manager/src/public-api.ts","../../../packages/angular-dock-manager/src/widgetstools-angular-dock-manager.ts"],"sourcesContent":["/**\n * Thin Angular wrapper around the core DockviewComponent.\n *\n * All DOM rendering, event handling, and layout logic lives in core.\n * Angular only provides panel content via dynamic component creation.\n *\n * Zoneless: Uses ChangeDetectorRef.markForCheck() instead of NgZone.\n * Compatible with both zone.js and zoneless (provideZonelessChangeDetection).\n */\nimport {\n Component,\n Input,\n Output,\n EventEmitter,\n ViewChild,\n ElementRef,\n AfterViewInit,\n OnDestroy,\n OnChanges,\n SimpleChanges,\n ChangeDetectionStrategy,\n ChangeDetectorRef,\n} from '@angular/core';\nimport type {\n DockManagerState,\n DockPosition,\n PreventableDockEvent,\n DockviewComponentOptions,\n IDisposable,\n DockTheme,\n} from '@widgetstools/dock-manager-core';\nimport {\n DockviewComponent,\n PanelApi,\n} from '@widgetstools/dock-manager-core';\nimport type { DockAction } from '@widgetstools/dock-manager-core';\n\n/**\n * Content renderer function type.\n * Called by the core when a panel needs content.\n * @param api - PanelApi instance for widget-to-header communication.\n * Returns a dispose function to clean up when the panel is hidden/removed.\n */\nexport type ContentRenderer = (panelId: string, container: HTMLElement, api: PanelApi) => IDisposable;\nexport type TabRenderer = (panelId: string, container: HTMLElement, isActive: boolean) => IDisposable;\nexport type HeaderActionsRenderer = (slot: 'left' | 'right' | 'prefix', tabGroupId: string, container: HTMLElement) => IDisposable;\n\n@Component({\n selector: 'dock-manager-core',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `<div #container style=\"width:100%;height:100%\"></div>`,\n styles: [`:host { display: block; width: 100%; height: 100%; overflow: hidden; }`],\n})\nexport class DockManagerCoreComponent implements AfterViewInit, OnDestroy, OnChanges {\n /** Initial state for the dock manager */\n @Input() initialState!: DockManagerState;\n\n /** Content renderer — called when a panel needs content mounted into a container */\n @Input() createContent!: ContentRenderer;\n\n /** Optional custom tab renderer */\n @Input() createTab?: TabRenderer;\n\n /** Optional header actions renderer */\n @Input() createHeaderActions?: HeaderActionsRenderer;\n\n /** Theme: 'light', 'dark', or a DockTheme object */\n @Input() theme: 'light' | 'dark' | DockTheme = 'light';\n\n /** Emits when state changes */\n @Output() stateChange = new EventEmitter<DockManagerState>();\n\n /** Emits before a panel close (preventable) */\n @Output() willClose = new EventEmitter<{ event: PreventableDockEvent; panelId: string }>();\n\n /** Emits before a drop (preventable) */\n @Output() willDrop = new EventEmitter<{\n event: PreventableDockEvent;\n sourceId: string;\n targetId: string;\n position: DockPosition;\n }>();\n\n @ViewChild('container', { static: true }) containerRef!: ElementRef<HTMLDivElement>;\n\n private dock: DockviewComponent | null = null;\n\n constructor(private cdr: ChangeDetectorRef) {}\n\n ngAfterViewInit(): void {\n const options: DockviewComponentOptions = {\n initialState: this.initialState,\n theme: this.theme,\n\n createContent: (panelId: string, container: HTMLElement, api: PanelApi): IDisposable => {\n const disposable = this.createContent(panelId, container, api);\n this.cdr.markForCheck();\n return disposable;\n },\n\n createTab: this.createTab\n ? (panelId: string, container: HTMLElement, isActive: boolean): IDisposable => {\n const disposable = this.createTab!(panelId, container, isActive);\n this.cdr.markForCheck();\n return disposable;\n }\n : undefined,\n\n createHeaderActions: this.createHeaderActions\n ? (slot, tabGroupId, container): IDisposable => {\n const disposable = this.createHeaderActions!(slot, tabGroupId, container);\n this.cdr.markForCheck();\n return disposable;\n }\n : undefined,\n\n onStateChange: (state: DockManagerState) => {\n this.stateChange.emit(state);\n this.cdr.markForCheck();\n },\n\n onWillClose: (event: PreventableDockEvent, panelId: string) => {\n this.willClose.emit({ event, panelId });\n this.cdr.markForCheck();\n },\n\n onWillDrop: (event, sourceId, targetId, position) => {\n this.willDrop.emit({ event, sourceId, targetId, position });\n this.cdr.markForCheck();\n },\n };\n\n this.dock = new DockviewComponent(this.containerRef.nativeElement, options);\n }\n\n ngOnChanges(changes: SimpleChanges): void {\n if (changes['theme'] && !changes['theme'].firstChange && this.dock) {\n this.dock.updateOptions({ theme: this.theme });\n }\n }\n\n ngOnDestroy(): void {\n this.dock?.dispose();\n this.dock = null;\n }\n\n /** Dispatch an action to the dock manager */\n dispatch(action: DockAction): void {\n this.dock?.dispatch(action);\n }\n\n /** Get current state */\n getState(): DockManagerState | null {\n return this.dock?.getState() ?? null;\n }\n\n /** Get the underlying DockviewComponent instance */\n getInstance(): DockviewComponent | null {\n return this.dock;\n }\n}\n","import { Injectable } from '@angular/core';\nimport { BehaviorSubject, Observable } from 'rxjs';\n\nexport type ThemeMode = 'light' | 'dark' | 'system';\n\n@Injectable({\n providedIn: 'root',\n})\nexport class DockThemeService {\n private themeModeSubject = new BehaviorSubject<ThemeMode>('light');\n private mediaQueryList: MediaQueryList | null = null;\n private mediaQueryListener: ((e: MediaQueryListEvent) => void) | null = null;\n\n themeMode$: Observable<ThemeMode> = this.themeModeSubject.asObservable();\n\n constructor() {\n this.initializeSystemModeListener();\n }\n\n setThemeMode(mode: ThemeMode): void {\n this.themeModeSubject.next(mode);\n this.applyTheme(mode);\n }\n\n getThemeMode(): ThemeMode {\n return this.themeModeSubject.getValue();\n }\n\n private applyTheme(mode: ThemeMode): void {\n const root = document.documentElement;\n const isDark = mode === 'dark' || (mode === 'system' && this.isSystemDark());\n\n if (isDark) {\n root.classList.add('dark');\n } else {\n root.classList.remove('dark');\n }\n }\n\n private isSystemDark(): boolean {\n if (typeof window === 'undefined') return false;\n return window.matchMedia('(prefers-color-scheme: dark)').matches;\n }\n\n private initializeSystemModeListener(): void {\n if (typeof window === 'undefined') return;\n\n try {\n this.mediaQueryList = window.matchMedia('(prefers-color-scheme: dark)');\n this.mediaQueryListener = (e) => {\n const currentMode = this.themeModeSubject.getValue();\n if (currentMode === 'system') {\n this.applyTheme('system');\n }\n };\n this.mediaQueryList.addEventListener('change', this.mediaQueryListener);\n } catch (e) {\n console.warn('System theme detection not supported', e);\n }\n }\n\n ngOnDestroy(): void {\n if (this.mediaQueryList && this.mediaQueryListener) {\n this.mediaQueryList.removeEventListener('change', this.mediaQueryListener);\n }\n }\n}\n","// Core-owned DOM architecture\nexport * from './lib/components/dock-manager-core/dock-manager-core.component';\n\n// Services\nexport * from './lib/services/dock-theme.service';\n\n// Re-export core types and utilities for convenience\nexport {\n DockviewComponent, DockviewApi, EventEmitter,\n dockReducer, createDefaultState, validateState,\n findTabGroupForPanel, findFirstTabGroup, findTabGroupById, findAllTabGroups,\n serialize, deserialize, saveToLocalStorage, loadFromLocalStorage, clearLocalStorage, exportToFile, importFromFile,\n themes, vsCodeLight, githubLight, warmLight, solarizedLight, sepiaLight, mintLight, lavenderLight,\n vsCodeDark, draculaDark, nordDark, solarizedDark, midnightDark, forestDark, slateDark,\n getThemeByName, getThemesByMode,\n} from '@widgetstools/dock-manager-core';\nexport type {\n DockviewComponentOptions, IDisposable, DockAction,\n AddPanelOptions, FloatPanelOptions, MovePanelOptions,\n SplitDirection, DockPosition, DockEdge, PanelConfig, TabGroupNode,\n SplitNode, LayoutNode, FloatingPanel, PopoutPanel, UnpinnedPanel,\n DockManagerState, PreventableDockEvent, HeaderPosition,\n DockTheme, DockThemeColors,\n} from '@widgetstools/dock-manager-core';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@widgetstools/angular-dock-manager",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Angular dock manager — thin wrapper around dock-manager-core",
|
|
5
|
+
"peerDependencies": {
|
|
6
|
+
"@angular/common": ">=21.0.0",
|
|
7
|
+
"@angular/core": ">=21.0.0",
|
|
8
|
+
"rxjs": "^7.8.0"
|
|
9
|
+
},
|
|
10
|
+
"dependencies": {
|
|
11
|
+
"tslib": "^2.3.0"
|
|
12
|
+
},
|
|
13
|
+
"keywords": [
|
|
14
|
+
"angular",
|
|
15
|
+
"dock-manager",
|
|
16
|
+
"layout",
|
|
17
|
+
"tabs",
|
|
18
|
+
"split-pane",
|
|
19
|
+
"floating-panels",
|
|
20
|
+
"drag-and-drop"
|
|
21
|
+
],
|
|
22
|
+
"license": "MIT",
|
|
23
|
+
"repository": {
|
|
24
|
+
"type": "git",
|
|
25
|
+
"url": "https://github.com/widgetstools/dockmanager.git",
|
|
26
|
+
"directory": "packages/angular-dock-manager"
|
|
27
|
+
},
|
|
28
|
+
"homepage": "https://github.com/widgetstools/dockmanager#readme",
|
|
29
|
+
"bugs": {
|
|
30
|
+
"url": "https://github.com/widgetstools/dockmanager/issues"
|
|
31
|
+
},
|
|
32
|
+
"publishConfig": {
|
|
33
|
+
"access": "public"
|
|
34
|
+
},
|
|
35
|
+
"sideEffects": false,
|
|
36
|
+
"module": "fesm2022/widgetstools-angular-dock-manager.mjs",
|
|
37
|
+
"typings": "types/widgetstools-angular-dock-manager.d.ts",
|
|
38
|
+
"exports": {
|
|
39
|
+
"./package.json": {
|
|
40
|
+
"default": "./package.json"
|
|
41
|
+
},
|
|
42
|
+
".": {
|
|
43
|
+
"types": "./types/widgetstools-angular-dock-manager.d.ts",
|
|
44
|
+
"default": "./fesm2022/widgetstools-angular-dock-manager.mjs"
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { AfterViewInit, OnDestroy, OnChanges, EventEmitter, ElementRef, ChangeDetectorRef, SimpleChanges } from '@angular/core';
|
|
3
|
+
import { PanelApi, IDisposable, DockManagerState, DockTheme, PreventableDockEvent, DockPosition, DockAction, DockviewComponent } from '@widgetstools/dock-manager-core';
|
|
4
|
+
export { AddPanelOptions, DockAction, DockEdge, DockManagerState, DockPosition, DockTheme, DockThemeColors, DockviewApi, DockviewComponent, DockviewComponentOptions, EventEmitter, FloatPanelOptions, FloatingPanel, HeaderPosition, IDisposable, LayoutNode, MovePanelOptions, PanelConfig, PopoutPanel, PreventableDockEvent, SplitDirection, SplitNode, TabGroupNode, UnpinnedPanel, clearLocalStorage, createDefaultState, deserialize, dockReducer, draculaDark, exportToFile, findAllTabGroups, findFirstTabGroup, findTabGroupById, findTabGroupForPanel, forestDark, getThemeByName, getThemesByMode, githubLight, importFromFile, lavenderLight, loadFromLocalStorage, midnightDark, mintLight, nordDark, saveToLocalStorage, sepiaLight, serialize, slateDark, solarizedDark, solarizedLight, themes, validateState, vsCodeDark, vsCodeLight, warmLight } from '@widgetstools/dock-manager-core';
|
|
5
|
+
import { Observable } from 'rxjs';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Thin Angular wrapper around the core DockviewComponent.
|
|
9
|
+
*
|
|
10
|
+
* All DOM rendering, event handling, and layout logic lives in core.
|
|
11
|
+
* Angular only provides panel content via dynamic component creation.
|
|
12
|
+
*
|
|
13
|
+
* Zoneless: Uses ChangeDetectorRef.markForCheck() instead of NgZone.
|
|
14
|
+
* Compatible with both zone.js and zoneless (provideZonelessChangeDetection).
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Content renderer function type.
|
|
19
|
+
* Called by the core when a panel needs content.
|
|
20
|
+
* @param api - PanelApi instance for widget-to-header communication.
|
|
21
|
+
* Returns a dispose function to clean up when the panel is hidden/removed.
|
|
22
|
+
*/
|
|
23
|
+
type ContentRenderer = (panelId: string, container: HTMLElement, api: PanelApi) => IDisposable;
|
|
24
|
+
type TabRenderer = (panelId: string, container: HTMLElement, isActive: boolean) => IDisposable;
|
|
25
|
+
type HeaderActionsRenderer = (slot: 'left' | 'right' | 'prefix', tabGroupId: string, container: HTMLElement) => IDisposable;
|
|
26
|
+
declare class DockManagerCoreComponent implements AfterViewInit, OnDestroy, OnChanges {
|
|
27
|
+
private cdr;
|
|
28
|
+
/** Initial state for the dock manager */
|
|
29
|
+
initialState: DockManagerState;
|
|
30
|
+
/** Content renderer — called when a panel needs content mounted into a container */
|
|
31
|
+
createContent: ContentRenderer;
|
|
32
|
+
/** Optional custom tab renderer */
|
|
33
|
+
createTab?: TabRenderer;
|
|
34
|
+
/** Optional header actions renderer */
|
|
35
|
+
createHeaderActions?: HeaderActionsRenderer;
|
|
36
|
+
/** Theme: 'light', 'dark', or a DockTheme object */
|
|
37
|
+
theme: 'light' | 'dark' | DockTheme;
|
|
38
|
+
/** Emits when state changes */
|
|
39
|
+
stateChange: EventEmitter<DockManagerState>;
|
|
40
|
+
/** Emits before a panel close (preventable) */
|
|
41
|
+
willClose: EventEmitter<{
|
|
42
|
+
event: PreventableDockEvent;
|
|
43
|
+
panelId: string;
|
|
44
|
+
}>;
|
|
45
|
+
/** Emits before a drop (preventable) */
|
|
46
|
+
willDrop: EventEmitter<{
|
|
47
|
+
event: PreventableDockEvent;
|
|
48
|
+
sourceId: string;
|
|
49
|
+
targetId: string;
|
|
50
|
+
position: DockPosition;
|
|
51
|
+
}>;
|
|
52
|
+
containerRef: ElementRef<HTMLDivElement>;
|
|
53
|
+
private dock;
|
|
54
|
+
constructor(cdr: ChangeDetectorRef);
|
|
55
|
+
ngAfterViewInit(): void;
|
|
56
|
+
ngOnChanges(changes: SimpleChanges): void;
|
|
57
|
+
ngOnDestroy(): void;
|
|
58
|
+
/** Dispatch an action to the dock manager */
|
|
59
|
+
dispatch(action: DockAction): void;
|
|
60
|
+
/** Get current state */
|
|
61
|
+
getState(): DockManagerState | null;
|
|
62
|
+
/** Get the underlying DockviewComponent instance */
|
|
63
|
+
getInstance(): DockviewComponent | null;
|
|
64
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<DockManagerCoreComponent, never>;
|
|
65
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<DockManagerCoreComponent, "dock-manager-core", never, { "initialState": { "alias": "initialState"; "required": false; }; "createContent": { "alias": "createContent"; "required": false; }; "createTab": { "alias": "createTab"; "required": false; }; "createHeaderActions": { "alias": "createHeaderActions"; "required": false; }; "theme": { "alias": "theme"; "required": false; }; }, { "stateChange": "stateChange"; "willClose": "willClose"; "willDrop": "willDrop"; }, never, never, true, never>;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
type ThemeMode = 'light' | 'dark' | 'system';
|
|
69
|
+
declare class DockThemeService {
|
|
70
|
+
private themeModeSubject;
|
|
71
|
+
private mediaQueryList;
|
|
72
|
+
private mediaQueryListener;
|
|
73
|
+
themeMode$: Observable<ThemeMode>;
|
|
74
|
+
constructor();
|
|
75
|
+
setThemeMode(mode: ThemeMode): void;
|
|
76
|
+
getThemeMode(): ThemeMode;
|
|
77
|
+
private applyTheme;
|
|
78
|
+
private isSystemDark;
|
|
79
|
+
private initializeSystemModeListener;
|
|
80
|
+
ngOnDestroy(): void;
|
|
81
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<DockThemeService, never>;
|
|
82
|
+
static ɵprov: i0.ɵɵInjectableDeclaration<DockThemeService>;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export { DockManagerCoreComponent, DockThemeService };
|
|
86
|
+
export type { ContentRenderer, HeaderActionsRenderer, TabRenderer, ThemeMode };
|