@ngutil/layout 0.0.3-dev.8 → 0.0.3
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/docking/docking-content.component.d.ts +1 -1
- package/docking/docking-layout.component.d.ts +1 -3
- package/docking/docking-panel.component.d.ts +10 -4
- package/esm2022/docking/docking-content.component.mjs +3 -3
- package/esm2022/docking/docking-layout.component.mjs +16 -140
- package/esm2022/docking/docking-panel.component.mjs +70 -15
- package/esm2022/index.mjs +2 -2
- package/esm2022/l9/state.mjs +1 -9
- package/esm2022/services/slots.service.mjs +240 -0
- package/fesm2022/ngutil-layout.mjs +322 -269
- package/fesm2022/ngutil-layout.mjs.map +1 -1
- package/index.d.ts +1 -1
- package/l9/state.d.ts +1 -3
- package/package.json +4 -2
- package/services/slots.service.d.ts +69 -0
- package/esm2022/util/dimension-watcher.mjs +0 -84
- package/esm2022/util/dimension.mjs +0 -2
- package/esm2022/util/index.mjs +0 -3
- package/esm2022/util/media-watcher.mjs +0 -29
- package/esm2022/util/rect.mjs +0 -2
- package/util/dimension-watcher.d.ts +0 -4
- package/util/dimension.d.ts +0 -5
- package/util/index.d.ts +0 -4
- package/util/media-watcher.d.ts +0 -5
- package/util/rect.d.ts +0 -5
|
@@ -1,115 +1,8 @@
|
|
|
1
|
+
import { BehaviorSubject, map, shareReplay, ReplaySubject, combineLatest, switchMap, of, Subject, startWith, scan, tap, distinctUntilChanged, finalize } from 'rxjs';
|
|
1
2
|
import * as i0 from '@angular/core';
|
|
2
|
-
import {
|
|
3
|
-
import { Observable, distinctUntilChanged, shareReplay, BehaviorSubject, map, combineLatest, switchMap, of, Subject, startWith } from 'rxjs';
|
|
3
|
+
import { Component, inject, ElementRef, ViewChild, Input, Output, ChangeDetectionStrategy, ContentChild, ContentChildren, NgModule, Injectable, TemplateRef, Directive, ViewContainerRef, Injector } from '@angular/core';
|
|
4
4
|
import { NumberWithUnit, Destructible, coerceBoolAttr, FastDOM } from '@ngutil/common';
|
|
5
|
-
|
|
6
|
-
const WATCHES = {};
|
|
7
|
-
/**
|
|
8
|
-
* watchMedia("(display-mode: standalone)")
|
|
9
|
-
*/
|
|
10
|
-
function watchMedia(expr) {
|
|
11
|
-
const existing = WATCHES[expr];
|
|
12
|
-
if (existing == null) {
|
|
13
|
-
return (WATCHES[expr] = _createWatcher(expr));
|
|
14
|
-
}
|
|
15
|
-
return existing;
|
|
16
|
-
}
|
|
17
|
-
function _createWatcher(expr) {
|
|
18
|
-
const zone = inject(NgZone);
|
|
19
|
-
return zone.runOutsideAngular(() => new Observable((sub) => {
|
|
20
|
-
const query = window.matchMedia(expr);
|
|
21
|
-
const listener = (event) => {
|
|
22
|
-
sub.next(event.matches);
|
|
23
|
-
};
|
|
24
|
-
query.addEventListener("change", listener);
|
|
25
|
-
sub.next(query.matches);
|
|
26
|
-
return () => {
|
|
27
|
-
query.removeEventListener("change", listener);
|
|
28
|
-
delete WATCHES[expr];
|
|
29
|
-
};
|
|
30
|
-
}).pipe(distinctUntilChanged(), shareReplay(1)));
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
const RESIZE_WATCHES = new Map();
|
|
34
|
-
const SCROLL_WATCHES = new Map();
|
|
35
|
-
function watchDimension(el, box = "border-box") {
|
|
36
|
-
const zone = inject(NgZone);
|
|
37
|
-
return box === "scroll-box" ? _watchScroll(zone, el) : _watchResize(zone, el, box);
|
|
38
|
-
}
|
|
39
|
-
function _watchResize(zone, el, box) {
|
|
40
|
-
return _watch(zone, el, RESIZE_WATCHES, () => _createResizeWatcher(zone, el, box));
|
|
41
|
-
}
|
|
42
|
-
function _watchScroll(zone, el) {
|
|
43
|
-
return _watch(zone, el, SCROLL_WATCHES, () => _createScollWatcher(zone, el));
|
|
44
|
-
}
|
|
45
|
-
function _watch(zone, el, watches, factory) {
|
|
46
|
-
const existing = watches.get(el);
|
|
47
|
-
if (existing == null) {
|
|
48
|
-
const watcher = factory();
|
|
49
|
-
watches.set(el, watcher);
|
|
50
|
-
return watcher;
|
|
51
|
-
}
|
|
52
|
-
return existing;
|
|
53
|
-
}
|
|
54
|
-
function _createResizeWatcher(zone, el, box) {
|
|
55
|
-
if (box !== "border-box") {
|
|
56
|
-
throw new Error(`Currently not implemented box mode: ${box}`);
|
|
57
|
-
}
|
|
58
|
-
return zone.runOutsideAngular(() => new Observable((sub) => {
|
|
59
|
-
const observer = new ResizeObserver(entries => {
|
|
60
|
-
for (const entry of entries) {
|
|
61
|
-
if (entry.borderBoxSize) {
|
|
62
|
-
sub.next({
|
|
63
|
-
width: _number(entry.borderBoxSize[0].inlineSize),
|
|
64
|
-
height: _number(entry.borderBoxSize[0].blockSize)
|
|
65
|
-
});
|
|
66
|
-
}
|
|
67
|
-
else {
|
|
68
|
-
sub.next({
|
|
69
|
-
width: _number(el.offsetWidth),
|
|
70
|
-
height: _number(el.offsetHeight)
|
|
71
|
-
});
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
});
|
|
75
|
-
observer.observe(el, { box: box });
|
|
76
|
-
return () => {
|
|
77
|
-
observer.disconnect();
|
|
78
|
-
RESIZE_WATCHES.delete(el);
|
|
79
|
-
};
|
|
80
|
-
}).pipe(distinctUntilChanged((p, c) => p && c && p.width === c.width && p.height === c.height), shareReplay(1)));
|
|
81
|
-
}
|
|
82
|
-
function _createScollWatcher(zone, el) {
|
|
83
|
-
return zone.runOutsideAngular(() => new Observable((sub) => {
|
|
84
|
-
let lastSw = 0;
|
|
85
|
-
let lastSh = 0;
|
|
86
|
-
const emit = () => {
|
|
87
|
-
const sw = el.scrollWidth;
|
|
88
|
-
const sh = el.scrollHeight;
|
|
89
|
-
if (lastSw !== sw || lastSh !== sh) {
|
|
90
|
-
lastSw = sw;
|
|
91
|
-
lastSh = sh;
|
|
92
|
-
sub.next({ width: _number(lastSw), height: _number(lastSh) });
|
|
93
|
-
}
|
|
94
|
-
};
|
|
95
|
-
const dimSum = _watchResize(zone, el, "border-box").subscribe(emit);
|
|
96
|
-
const mutation = new MutationObserver(emit);
|
|
97
|
-
mutation.observe(el, {
|
|
98
|
-
subtree: true,
|
|
99
|
-
childList: true,
|
|
100
|
-
attributes: true,
|
|
101
|
-
characterData: true
|
|
102
|
-
});
|
|
103
|
-
return () => {
|
|
104
|
-
dimSum.unsubscribe();
|
|
105
|
-
mutation.disconnect();
|
|
106
|
-
SCROLL_WATCHES.delete(el);
|
|
107
|
-
};
|
|
108
|
-
}).pipe(shareReplay(1)));
|
|
109
|
-
}
|
|
110
|
-
function _number(val) {
|
|
111
|
-
return new NumberWithUnit(val, "pk");
|
|
112
|
-
}
|
|
5
|
+
import { DimensionWatcher } from '@ngutil/style';
|
|
113
6
|
|
|
114
7
|
/**
|
|
115
8
|
* -----------------------------------------------
|
|
@@ -238,29 +131,24 @@ class L9State {
|
|
|
238
131
|
return res;
|
|
239
132
|
}), shareReplay(1));
|
|
240
133
|
}
|
|
241
|
-
update(range, dim) {
|
|
242
|
-
range = L9Range.coerce(range);
|
|
243
|
-
const dims = { ...this.#dims.value };
|
|
244
|
-
// for (const cell of range.horizontals) {
|
|
245
|
-
// dims[cell] = dim.width
|
|
246
|
-
// }
|
|
247
|
-
}
|
|
248
134
|
}
|
|
249
135
|
|
|
250
136
|
class DockingContentComponent {
|
|
251
137
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: DockingContentComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
252
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.1.3", type: DockingContentComponent, isStandalone: true, selector: "nu-docking-content", ngImport: i0, template: `<ng-content></ng-content>`, isInline: true, styles: [":host{display:flex;flex-flow:column nowrap;align-items:stretch;box-sizing:border-box;flex:1
|
|
138
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.1.3", type: DockingContentComponent, isStandalone: true, selector: "nu-docking-content", exportAs: ["nuDockingContent"], ngImport: i0, template: `<ng-content></ng-content>`, isInline: true, styles: [":host{display:flex;flex-flow:column nowrap;align-items:stretch;box-sizing:border-box;flex:1}\n"] }); }
|
|
253
139
|
}
|
|
254
140
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: DockingContentComponent, decorators: [{
|
|
255
141
|
type: Component,
|
|
256
|
-
args: [{ standalone: true, selector: "nu-docking-content", template: `<ng-content></ng-content>`, styles: [":host{display:flex;flex-flow:column nowrap;align-items:stretch;box-sizing:border-box;flex:1
|
|
142
|
+
args: [{ standalone: true, selector: "nu-docking-content", exportAs: "nuDockingContent", template: `<ng-content></ng-content>`, styles: [":host{display:flex;flex-flow:column nowrap;align-items:stretch;box-sizing:border-box;flex:1}\n"] }]
|
|
257
143
|
}] });
|
|
258
144
|
|
|
259
145
|
const DEFAULT_POSITION = L9Range.coerce("left");
|
|
146
|
+
const HIDDEN_SIZE = new NumberWithUnit(0, "px");
|
|
147
|
+
const AUTO_SIZE = NumberWithUnit.coerce("auto");
|
|
260
148
|
class DockingPanelComponent extends Destructible {
|
|
149
|
+
#dimWatcher;
|
|
261
150
|
set positionInput(val) {
|
|
262
151
|
const coerced = L9Range.coerce(val);
|
|
263
|
-
console.log("SET POSITION", coerced, this.position.value.isEq(coerced));
|
|
264
152
|
if (coerced.orient === "rect") {
|
|
265
153
|
throw new Error(`Invalid position value: ${val}`);
|
|
266
154
|
}
|
|
@@ -301,19 +189,22 @@ class DockingPanelComponent extends Destructible {
|
|
|
301
189
|
}
|
|
302
190
|
#minimizable;
|
|
303
191
|
#minimizableAuto;
|
|
192
|
+
#contentSize;
|
|
304
193
|
#autoSize;
|
|
305
194
|
constructor() {
|
|
306
195
|
super();
|
|
307
196
|
this.el = inject((ElementRef));
|
|
197
|
+
this.#dimWatcher = inject(DimensionWatcher);
|
|
308
198
|
this.position = new BehaviorSubject(DEFAULT_POSITION);
|
|
309
|
-
this.state = new BehaviorSubject("
|
|
310
|
-
this.mode = new BehaviorSubject("
|
|
311
|
-
this.#fullSize = new BehaviorSubject(
|
|
312
|
-
this.#miniSize = new BehaviorSubject(
|
|
199
|
+
this.state = new BehaviorSubject("full");
|
|
200
|
+
this.mode = new BehaviorSubject("rigid");
|
|
201
|
+
this.#fullSize = new BehaviorSubject(AUTO_SIZE);
|
|
202
|
+
this.#miniSize = new BehaviorSubject(HIDDEN_SIZE);
|
|
313
203
|
this.#minimizable = false;
|
|
314
204
|
this.#minimizableAuto = true;
|
|
205
|
+
this.#contentSize = new ReplaySubject(1);
|
|
315
206
|
this.#autoSize = combineLatest({
|
|
316
|
-
dim:
|
|
207
|
+
dim: this.#contentSize,
|
|
317
208
|
pos: this.position
|
|
318
209
|
}).pipe(map(({ dim, pos }) => {
|
|
319
210
|
if (pos.orient === "horizontal") {
|
|
@@ -344,7 +235,8 @@ class DockingPanelComponent extends Destructible {
|
|
|
344
235
|
state: this.state,
|
|
345
236
|
mode: this.mode,
|
|
346
237
|
fullSize: this.fullSize,
|
|
347
|
-
miniSize: this.miniSize
|
|
238
|
+
miniSize: this.miniSize,
|
|
239
|
+
contentSize: this.#contentSize
|
|
348
240
|
});
|
|
349
241
|
this.d.sub(this.changes).subscribe(changes => {
|
|
350
242
|
if (this.#minimizableAuto) {
|
|
@@ -356,13 +248,51 @@ class DockingPanelComponent extends Destructible {
|
|
|
356
248
|
mode: changes.mode,
|
|
357
249
|
side: changes.position.orient === "horizontal" ? changes.position.cells[0].v : changes.position.cells[0].h
|
|
358
250
|
});
|
|
251
|
+
const isHorizontal = changes.position.orient === "horizontal";
|
|
252
|
+
let w = null;
|
|
253
|
+
let h = null;
|
|
254
|
+
// TODO: when change state from mini -> hidden, currently wrong behavior
|
|
255
|
+
// the good behavior is to not gain fullSize ang go to hidden
|
|
256
|
+
if (changes.state === "mini") {
|
|
257
|
+
if (isHorizontal) {
|
|
258
|
+
h = changes.miniSize.unit === "auto" ? changes.contentSize.height : changes.miniSize;
|
|
259
|
+
}
|
|
260
|
+
else {
|
|
261
|
+
w = changes.miniSize.unit === "auto" ? changes.contentSize.width : changes.miniSize;
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
else {
|
|
265
|
+
if (isHorizontal) {
|
|
266
|
+
h = changes.fullSize.unit === "auto" ? changes.contentSize.height : changes.fullSize;
|
|
267
|
+
}
|
|
268
|
+
else {
|
|
269
|
+
w = changes.fullSize.unit === "auto" ? changes.contentSize.width : changes.fullSize;
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
FastDOM.setStyle(this.el.nativeElement, {
|
|
273
|
+
"--docking-panel-w": w != null ? `${w}` : null,
|
|
274
|
+
"--docking-panel-h": h != null ? `${h}` : null,
|
|
275
|
+
"--docking-panel-content-w": changes.contentSize.width,
|
|
276
|
+
"--docking-panel-content-h": changes.contentSize.height
|
|
277
|
+
}, () => FastDOM.setAttributes(this.el.nativeElement, { animate: "" }));
|
|
359
278
|
});
|
|
360
279
|
}
|
|
280
|
+
ngAfterViewInit() {
|
|
281
|
+
this.d
|
|
282
|
+
.sub(this.#dimWatcher.watch(this.content, "scroll-box"))
|
|
283
|
+
.pipe(map(dim => {
|
|
284
|
+
return {
|
|
285
|
+
width: new NumberWithUnit(dim.width, "px"),
|
|
286
|
+
height: new NumberWithUnit(dim.height, "px")
|
|
287
|
+
};
|
|
288
|
+
}))
|
|
289
|
+
.subscribe(this.#contentSize);
|
|
290
|
+
}
|
|
361
291
|
open() {
|
|
362
292
|
this.state.next("full");
|
|
363
293
|
}
|
|
364
294
|
close() {
|
|
365
|
-
this.state.next("
|
|
295
|
+
this.state.next("hidden");
|
|
366
296
|
}
|
|
367
297
|
minimize() {
|
|
368
298
|
if (this.minimizable) {
|
|
@@ -370,12 +300,23 @@ class DockingPanelComponent extends Destructible {
|
|
|
370
300
|
}
|
|
371
301
|
}
|
|
372
302
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: DockingPanelComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
373
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.1.3", type: DockingPanelComponent, isStandalone: true, selector: "nu-docking-panel", inputs: { positionInput: ["position", "positionInput"], stateInput: ["state", "stateInput"], modeInput: ["mode", "modeInput"], fullSizeInput: ["fullSize", "fullSizeInput"], miniSizeInput: ["miniSize", "miniSizeInput"], minimizable: "minimizable" }, outputs: { state: "stateChanges" },
|
|
303
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.1.3", type: DockingPanelComponent, isStandalone: true, selector: "nu-docking-panel", inputs: { positionInput: ["position", "positionInput"], stateInput: ["state", "stateInput"], modeInput: ["mode", "modeInput"], fullSizeInput: ["fullSize", "fullSizeInput"], miniSizeInput: ["miniSize", "miniSizeInput"], minimizable: "minimizable" }, outputs: { state: "stateChanges" }, viewQueries: [{ propertyName: "content", first: true, predicate: ["content"], descendants: true, read: ElementRef, static: true }], exportAs: ["nuDockingPanel"], usesInheritance: true, ngImport: i0, template: `
|
|
304
|
+
<div class="content" #content>
|
|
305
|
+
<ng-content></ng-content>
|
|
306
|
+
</div>
|
|
307
|
+
`, isInline: true, styles: [":host{---docking-panel-t: var(--docking-panel-t, auto);---docking-panel-r: var(--docking-panel-r, auto);---docking-panel-b: var(--docking-panel-b, auto);---docking-panel-l: var(--docking-panel-l, auto);---docking-panel-w: var(--docking-panel-w, auto);---docking-panel-h: var(--docking-panel-h, auto);---docking-panel-content-w: var(--docking-panel-content-w, var(---docking-panel-w));---docking-panel-content-g: var(--docking-panel-content-g, var(---docking-panel-h));display:flex;flex-flow:column nowrap;align-items:stretch;position:absolute;box-sizing:border-box;overflow:hidden;top:var(---docking-panel-t);right:var(---docking-panel-r);bottom:var(---docking-panel-b);left:var(---docking-panel-l);width:var(---docking-panel-w);height:var(---docking-panel-h)}:host[animate]{transition:transform var(---docking-layout-anim-duration) var(---docking-layout-anim-ease),width var(---docking-layout-anim-duration) var(---docking-layout-anim-ease),height var(---docking-layout-anim-duration) var(---docking-layout-anim-ease)}:host[side=top],:host[side=left]{---docking-panel-t-hide: -100%;---docking-panel-t-visible: 0%}:host[side=bottom],:host[side=right]{---docking-panel-t-hide: 100%;---docking-panel-t-visible: 0%}:host[state=hidden][orient=horizontal]{transform:translateY(var(---docking-panel-t-hide))}:host[state=hidden][orient=vertical]{transform:translate(var(---docking-panel-t-hide))}:host:not([state=hidden])[orient=horizontal]{transform:translateY(var(---docking-panel-t-visible))}:host:not([state=hidden])[orient=vertical]{transform:translate(var(---docking-panel-t-visible))}\n"] }); }
|
|
374
308
|
}
|
|
375
309
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: DockingPanelComponent, decorators: [{
|
|
376
310
|
type: Component,
|
|
377
|
-
args: [{ standalone: true, selector: "nu-docking-panel", exportAs: "nuDockingPanel", template:
|
|
378
|
-
|
|
311
|
+
args: [{ standalone: true, selector: "nu-docking-panel", exportAs: "nuDockingPanel", template: `
|
|
312
|
+
<div class="content" #content>
|
|
313
|
+
<ng-content></ng-content>
|
|
314
|
+
</div>
|
|
315
|
+
`, styles: [":host{---docking-panel-t: var(--docking-panel-t, auto);---docking-panel-r: var(--docking-panel-r, auto);---docking-panel-b: var(--docking-panel-b, auto);---docking-panel-l: var(--docking-panel-l, auto);---docking-panel-w: var(--docking-panel-w, auto);---docking-panel-h: var(--docking-panel-h, auto);---docking-panel-content-w: var(--docking-panel-content-w, var(---docking-panel-w));---docking-panel-content-g: var(--docking-panel-content-g, var(---docking-panel-h));display:flex;flex-flow:column nowrap;align-items:stretch;position:absolute;box-sizing:border-box;overflow:hidden;top:var(---docking-panel-t);right:var(---docking-panel-r);bottom:var(---docking-panel-b);left:var(---docking-panel-l);width:var(---docking-panel-w);height:var(---docking-panel-h)}:host[animate]{transition:transform var(---docking-layout-anim-duration) var(---docking-layout-anim-ease),width var(---docking-layout-anim-duration) var(---docking-layout-anim-ease),height var(---docking-layout-anim-duration) var(---docking-layout-anim-ease)}:host[side=top],:host[side=left]{---docking-panel-t-hide: -100%;---docking-panel-t-visible: 0%}:host[side=bottom],:host[side=right]{---docking-panel-t-hide: 100%;---docking-panel-t-visible: 0%}:host[state=hidden][orient=horizontal]{transform:translateY(var(---docking-panel-t-hide))}:host[state=hidden][orient=vertical]{transform:translate(var(---docking-panel-t-hide))}:host:not([state=hidden])[orient=horizontal]{transform:translateY(var(---docking-panel-t-visible))}:host:not([state=hidden])[orient=vertical]{transform:translate(var(---docking-panel-t-visible))}\n"] }]
|
|
316
|
+
}], ctorParameters: () => [], propDecorators: { content: [{
|
|
317
|
+
type: ViewChild,
|
|
318
|
+
args: ["content", { read: ElementRef, static: true }]
|
|
319
|
+
}], positionInput: [{
|
|
379
320
|
type: Input,
|
|
380
321
|
args: ["position"]
|
|
381
322
|
}], stateInput: [{
|
|
@@ -398,29 +339,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.3", ngImpor
|
|
|
398
339
|
args: ["minimizable"]
|
|
399
340
|
}] } });
|
|
400
341
|
|
|
401
|
-
const
|
|
402
|
-
const
|
|
403
|
-
// interface PanelRefChanges {
|
|
404
|
-
// ref: PanelRef
|
|
405
|
-
// changes: DockingPanelChanges
|
|
406
|
-
// }
|
|
407
|
-
// class PanelRef {
|
|
408
|
-
// style: Partial<CSSStyleDeclaration> = {}
|
|
409
|
-
// readonly changes: Observable<PanelRefChanges>
|
|
410
|
-
// constructor(public readonly panel: DockingPanelDirective) {
|
|
411
|
-
// this.changes = panel.changes.pipe(
|
|
412
|
-
// map(changes => {
|
|
413
|
-
// return { ref: this, changes }
|
|
414
|
-
// })
|
|
415
|
-
// )
|
|
416
|
-
// }
|
|
417
|
-
// }
|
|
342
|
+
const RIGID_ZINDEX = 20;
|
|
343
|
+
const OVER_ZINDEX = RIGID_ZINDEX * 2;
|
|
418
344
|
class DockingLayoutComponent extends Destructible {
|
|
419
345
|
constructor() {
|
|
420
346
|
super(...arguments);
|
|
421
347
|
this.#el = inject((ElementRef));
|
|
422
348
|
this.contentOnly = false;
|
|
423
|
-
this.positionMode = "absolute";
|
|
424
349
|
this.#reflow = new Subject();
|
|
425
350
|
}
|
|
426
351
|
#el;
|
|
@@ -428,25 +353,12 @@ class DockingLayoutComponent extends Destructible {
|
|
|
428
353
|
ngAfterViewInit() {
|
|
429
354
|
// eslint-disable-next-line prettier/prettier
|
|
430
355
|
this.panels = this.dockingPanels.changes.pipe(startWith(null), map(() => this.dockingPanels.toArray()), shareReplay(1));
|
|
431
|
-
// this.panels.subscribe(panels => console.log({ panels }))
|
|
432
356
|
this.d
|
|
433
357
|
.sub(combineLatest({ panels: this.panels, reflow: this.#reflow.pipe(startWith(null)) }))
|
|
434
358
|
.pipe(switchMap(({ panels }) => combineLatest(panels.map(panel => panel.changes.pipe(map(changes => {
|
|
435
359
|
return { panel, changes };
|
|
436
360
|
}))))))
|
|
437
361
|
.subscribe(this.#layout.bind(this));
|
|
438
|
-
// this.d
|
|
439
|
-
// .sub(merge(this.dockingPanels.changes, this.#reflow))
|
|
440
|
-
// .pipe(
|
|
441
|
-
// startWith(null),
|
|
442
|
-
// map(() => this.dockingPanels.map(panel => new PanelRef(panel))),
|
|
443
|
-
// switchMap(refs => combineLatest(refs.map(ref => ref.changes))),
|
|
444
|
-
// map(changes => {
|
|
445
|
-
// this.#layout(changes)
|
|
446
|
-
// return changes.map(c => c.ref)
|
|
447
|
-
// })
|
|
448
|
-
// )
|
|
449
|
-
// .subscribe(this.panels)
|
|
450
362
|
}
|
|
451
363
|
ngOnChanges(changes) {
|
|
452
364
|
if ("contentOnly" in changes || "positionMode" in changes) {
|
|
@@ -454,13 +366,12 @@ class DockingLayoutComponent extends Destructible {
|
|
|
454
366
|
}
|
|
455
367
|
}
|
|
456
368
|
#layout(entries) {
|
|
457
|
-
console.log("layout", entries);
|
|
458
369
|
let paddingTop = 0;
|
|
459
370
|
let paddingRight = 0;
|
|
460
371
|
let paddingBottom = 0;
|
|
461
372
|
let paddingLeft = 0;
|
|
462
|
-
let
|
|
463
|
-
let
|
|
373
|
+
let rigidZIndex = RIGID_ZINDEX;
|
|
374
|
+
let overZIndex = OVER_ZINDEX;
|
|
464
375
|
if (this.contentOnly) {
|
|
465
376
|
// TODO:...
|
|
466
377
|
}
|
|
@@ -473,7 +384,7 @@ class DockingLayoutComponent extends Destructible {
|
|
|
473
384
|
? panelState.miniSize.value
|
|
474
385
|
: 0;
|
|
475
386
|
const isHorizontal = panelState.position.orient === "horizontal";
|
|
476
|
-
const
|
|
387
|
+
const isRigid = panelState.mode === "rigid";
|
|
477
388
|
let panelTop = null;
|
|
478
389
|
let panelRight = null;
|
|
479
390
|
let panelBottom = null;
|
|
@@ -482,13 +393,13 @@ class DockingLayoutComponent extends Destructible {
|
|
|
482
393
|
panelLeft = 0;
|
|
483
394
|
panelRight = 0;
|
|
484
395
|
if (panelState.position.cells[0].v === "top") {
|
|
485
|
-
if (
|
|
396
|
+
if (isRigid) {
|
|
486
397
|
paddingTop = Math.max(paddingTop, panelSize);
|
|
487
398
|
}
|
|
488
399
|
panelTop = 0;
|
|
489
400
|
}
|
|
490
401
|
else if (panelState.position.cells[0].v === "bottom") {
|
|
491
|
-
if (
|
|
402
|
+
if (isRigid) {
|
|
492
403
|
paddingBottom = Math.max(paddingBottom, panelSize);
|
|
493
404
|
}
|
|
494
405
|
panelBottom = 0;
|
|
@@ -498,40 +409,26 @@ class DockingLayoutComponent extends Destructible {
|
|
|
498
409
|
panelTop = 0;
|
|
499
410
|
panelBottom = 0;
|
|
500
411
|
if (panelState.position.cells[0].h === "left") {
|
|
501
|
-
if (
|
|
412
|
+
if (isRigid) {
|
|
502
413
|
paddingLeft = Math.max(paddingLeft, panelSize);
|
|
503
414
|
}
|
|
504
415
|
panelLeft = 0;
|
|
505
416
|
}
|
|
506
417
|
else if (panelState.position.cells[0].h === "right") {
|
|
507
|
-
if (
|
|
418
|
+
if (isRigid) {
|
|
508
419
|
paddingRight = Math.max(paddingRight, panelSize);
|
|
509
420
|
}
|
|
510
421
|
panelRight = 0;
|
|
511
422
|
}
|
|
512
423
|
}
|
|
513
|
-
const panelGivenSize = panelState.state === "full"
|
|
514
|
-
? panelState.fullSize
|
|
515
|
-
: panelState.state === "mini"
|
|
516
|
-
? panelState.miniSize
|
|
517
|
-
: new NumberWithUnit(0, "px");
|
|
518
424
|
FastDOM.setStyle(entry.panel.el.nativeElement, {
|
|
519
|
-
"z-index": `${
|
|
425
|
+
"z-index": `${isRigid ? rigidZIndex++ : overZIndex++}`,
|
|
520
426
|
"--docking-panel-t": panelTop != null ? `${panelTop}px` : null,
|
|
521
427
|
"--docking-panel-r": panelRight != null ? `${panelRight}px` : null,
|
|
522
428
|
"--docking-panel-b": panelBottom != null ? `${panelBottom}px` : null,
|
|
523
|
-
"--docking-panel-l": panelLeft != null ? `${panelLeft}px` : null
|
|
524
|
-
"--docking-panel-w": !isHorizontal
|
|
525
|
-
? `${panelGivenSize.unit === "auto" ? "auto" : panelGivenSize}`
|
|
526
|
-
: null,
|
|
527
|
-
"--docking-panel-h": isHorizontal
|
|
528
|
-
? `${panelGivenSize.unit === "auto" ? "auto" : panelGivenSize}`
|
|
529
|
-
: null,
|
|
530
|
-
"--docking-panel-real-w": !isHorizontal ? `${panelSize}px` : null,
|
|
531
|
-
"--docking-panel-real-h": isHorizontal ? `${panelSize}px` : null
|
|
429
|
+
"--docking-panel-l": panelLeft != null ? `${panelLeft}px` : null
|
|
532
430
|
});
|
|
533
431
|
}
|
|
534
|
-
console.log({ paddingTop, paddingRight, paddingBottom, paddingLeft });
|
|
535
432
|
FastDOM.setStyle(this.#el.nativeElement, {
|
|
536
433
|
"--docking-layout-top": `${paddingTop}px`,
|
|
537
434
|
"--docking-layout-right": `${paddingRight}px`,
|
|
@@ -540,86 +437,8 @@ class DockingLayoutComponent extends Destructible {
|
|
|
540
437
|
});
|
|
541
438
|
}
|
|
542
439
|
}
|
|
543
|
-
#layoutOld(entries) {
|
|
544
|
-
// let paddingTop = 0
|
|
545
|
-
// let paddingRight = 0
|
|
546
|
-
// let paddingBottom = 0
|
|
547
|
-
// let paddingLeft = 0
|
|
548
|
-
// if (!this.contentOnly) {
|
|
549
|
-
// let embeddedZIndex = EMBEDDED_ZINDEX
|
|
550
|
-
// let overlayZIndex = OVERLAY_ZINDEX
|
|
551
|
-
// const leftRight: PanelRefChanges[] = entries.filter(v =>
|
|
552
|
-
// ["left", "right"].includes(v.changes.position.side)
|
|
553
|
-
// )
|
|
554
|
-
// const topBottom: PanelRefChanges[] = entries.filter(v =>
|
|
555
|
-
// ["top", "bottom"].includes(v.changes.position.side)
|
|
556
|
-
// )
|
|
557
|
-
// for (const entry of entries) {
|
|
558
|
-
// const changes = entry.changes
|
|
559
|
-
// const ref = entry.ref
|
|
560
|
-
// if (changes.mode === "embedded") {
|
|
561
|
-
// ref.style.zIndex = `${embeddedZIndex++}`
|
|
562
|
-
// } else if (changes.mode === "overlay") {
|
|
563
|
-
// ref.style.zIndex = `${overlayZIndex++}`
|
|
564
|
-
// }
|
|
565
|
-
// }
|
|
566
|
-
// for (const entry of leftRight) {
|
|
567
|
-
// const changes = entry.changes
|
|
568
|
-
// const ref = entry.ref
|
|
569
|
-
// const padding =
|
|
570
|
-
// changes.mode === "embedded"
|
|
571
|
-
// ? changes.state === "full"
|
|
572
|
-
// ? changes.fullSize
|
|
573
|
-
// : changes.state === "mini"
|
|
574
|
-
// ? changes.miniSize
|
|
575
|
-
// : 0
|
|
576
|
-
// : 0
|
|
577
|
-
// ref.style.top = "0"
|
|
578
|
-
// ref.style.bottom = "0"
|
|
579
|
-
// if (changes.position.side === "left") {
|
|
580
|
-
// paddingLeft = Math.max(paddingLeft, padding)
|
|
581
|
-
// ref.style.left = "0"
|
|
582
|
-
// ref.style.right = ""
|
|
583
|
-
// } else {
|
|
584
|
-
// paddingRight = Math.max(paddingRight, padding)
|
|
585
|
-
// ref.style.right = "0"
|
|
586
|
-
// ref.style.left = ""
|
|
587
|
-
// }
|
|
588
|
-
// }
|
|
589
|
-
// for (const entry of topBottom) {
|
|
590
|
-
// const changes = entry.changes
|
|
591
|
-
// const ref = entry.ref
|
|
592
|
-
// const padding =
|
|
593
|
-
// changes.mode === "embedded"
|
|
594
|
-
// ? changes.state === "full"
|
|
595
|
-
// ? changes.fullSize
|
|
596
|
-
// : changes.state === "mini"
|
|
597
|
-
// ? changes.miniSize
|
|
598
|
-
// : 0
|
|
599
|
-
// : 0
|
|
600
|
-
// if (changes.mode === "embedded") {
|
|
601
|
-
// ref.style.left = `${paddingLeft}px`
|
|
602
|
-
// ref.style.right = `${paddingRight}px`
|
|
603
|
-
// } else {
|
|
604
|
-
// ref.style.left = "0"
|
|
605
|
-
// ref.style.right = "0"
|
|
606
|
-
// }
|
|
607
|
-
// if (changes.position?.cells[0].v === "top") {
|
|
608
|
-
// paddingTop = Math.max(paddingTop, padding)
|
|
609
|
-
// ref.style.top = "0"
|
|
610
|
-
// ref.style.bottom = ""
|
|
611
|
-
// } else {
|
|
612
|
-
// paddingBottom = Math.max(paddingBottom, padding)
|
|
613
|
-
// ref.style.bottom = `0`
|
|
614
|
-
// ref.style.top = ""
|
|
615
|
-
// }
|
|
616
|
-
// }
|
|
617
|
-
// }
|
|
618
|
-
// const cel = this.contentEl.nativeElement
|
|
619
|
-
// cel.style.padding = `${paddingTop}px ${paddingRight}px ${paddingBottom}px ${paddingLeft}px`
|
|
620
|
-
}
|
|
621
440
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: DockingLayoutComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
|
|
622
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.1.3", type: DockingLayoutComponent, isStandalone: true, selector: "nu-docking", inputs: { contentOnly: "contentOnly"
|
|
441
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.1.3", type: DockingLayoutComponent, isStandalone: true, selector: "nu-docking", inputs: { contentOnly: "contentOnly" }, queries: [{ propertyName: "contentComponent", first: true, predicate: DockingContentComponent, descendants: true }, { propertyName: "dockingPanels", predicate: DockingPanelComponent }], usesInheritance: true, usesOnChanges: true, ngImport: i0, template: `
|
|
623
442
|
<ng-content select="nu-docking-panel"></ng-content>
|
|
624
443
|
|
|
625
444
|
@if (!contentComponent) {
|
|
@@ -629,7 +448,7 @@ class DockingLayoutComponent extends Destructible {
|
|
|
629
448
|
} @else {
|
|
630
449
|
<ng-content select="nu-docking-content"></ng-content>
|
|
631
450
|
}
|
|
632
|
-
`, isInline: true, styles: [":host{---docking-layout-top: var(--docking-layout-top, 0px);---docking-layout-right: var(--docking-layout-right, 0px);---docking-layout-bottom: var(--docking-layout-bottom, 0px);---docking-layout-left: var(--docking-layout-left, 0px);---docking-layout-anim-duration: var(--docking-layout-anim-duration, .
|
|
451
|
+
`, isInline: true, styles: [":host{---docking-layout-top: var(--docking-layout-top, 0px);---docking-layout-right: var(--docking-layout-right, 0px);---docking-layout-bottom: var(--docking-layout-bottom, 0px);---docking-layout-left: var(--docking-layout-left, 0px);---docking-layout-anim-duration: var(--docking-layout-anim-duration, .3s);---docking-layout-anim-ease: var(--docking-layout-anim-ease, cubic-bezier(.4, 0, .2, 1));display:flex;flex-flow:column nowrap;align-items:stretch;position:relative;overflow:hidden;box-sizing:border-box;z-index:0;padding:var(---docking-layout-top) var(---docking-layout-right) var(---docking-layout-bottom) var(---docking-layout-left);transition:padding var(---docking-layout-anim-duration) var(---docking-layout-anim-ease)}\n"], dependencies: [{ kind: "component", type: DockingContentComponent, selector: "nu-docking-content", exportAs: ["nuDockingContent"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
633
452
|
}
|
|
634
453
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: DockingLayoutComponent, decorators: [{
|
|
635
454
|
type: Component,
|
|
@@ -643,11 +462,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.3", ngImpor
|
|
|
643
462
|
} @else {
|
|
644
463
|
<ng-content select="nu-docking-content"></ng-content>
|
|
645
464
|
}
|
|
646
|
-
`, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{---docking-layout-top: var(--docking-layout-top, 0px);---docking-layout-right: var(--docking-layout-right, 0px);---docking-layout-bottom: var(--docking-layout-bottom, 0px);---docking-layout-left: var(--docking-layout-left, 0px);---docking-layout-anim-duration: var(--docking-layout-anim-duration, .
|
|
465
|
+
`, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{---docking-layout-top: var(--docking-layout-top, 0px);---docking-layout-right: var(--docking-layout-right, 0px);---docking-layout-bottom: var(--docking-layout-bottom, 0px);---docking-layout-left: var(--docking-layout-left, 0px);---docking-layout-anim-duration: var(--docking-layout-anim-duration, .3s);---docking-layout-anim-ease: var(--docking-layout-anim-ease, cubic-bezier(.4, 0, .2, 1));display:flex;flex-flow:column nowrap;align-items:stretch;position:relative;overflow:hidden;box-sizing:border-box;z-index:0;padding:var(---docking-layout-top) var(---docking-layout-right) var(---docking-layout-bottom) var(---docking-layout-left);transition:padding var(---docking-layout-anim-duration) var(---docking-layout-anim-ease)}\n"] }]
|
|
647
466
|
}], propDecorators: { contentOnly: [{
|
|
648
467
|
type: Input
|
|
649
|
-
}], positionMode: [{
|
|
650
|
-
type: Input
|
|
651
468
|
}], contentComponent: [{
|
|
652
469
|
type: ContentChild,
|
|
653
470
|
args: [DockingContentComponent]
|
|
@@ -670,9 +487,245 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.3", ngImpor
|
|
|
670
487
|
}]
|
|
671
488
|
}] });
|
|
672
489
|
|
|
490
|
+
const SLOT_REGEX = /^([^:\s]+)(?::(\d+))?(?:\s+as\s+(.*?))?$/i;
|
|
491
|
+
class SlotDef {
|
|
492
|
+
constructor(slot, tpl) {
|
|
493
|
+
this.tpl = tpl;
|
|
494
|
+
const match = slot.match(SLOT_REGEX);
|
|
495
|
+
if (!match) {
|
|
496
|
+
console.warn(`Invalid slot definition: ${slot}`);
|
|
497
|
+
}
|
|
498
|
+
else {
|
|
499
|
+
this.slot = match[1];
|
|
500
|
+
this.order = match[2] != null ? Number(match[2]) : Infinity;
|
|
501
|
+
this.id = match[3];
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
dispose() {
|
|
505
|
+
this.viewRef?.destroy();
|
|
506
|
+
this.viewRef = undefined;
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
/**
|
|
510
|
+
* @Directive({selector: "ng-template[xyzSlot]", inputs: [{name: "slot", alias: "xyzSlot"}]})
|
|
511
|
+
* class XYZSlotDirective extends SlotDirective<XYZComponentSlots> { }
|
|
512
|
+
*
|
|
513
|
+
* @Directive({selector: "ng-template[xyzSlotOutlet]", inputs: [{name: "slot", alias: "xyzSlotOutlet"}]})
|
|
514
|
+
* class XYZSlotOutletDirective extends SlotOutletDirective<XYZComponentSlots> { }
|
|
515
|
+
*
|
|
516
|
+
*
|
|
517
|
+
* @Component({provides: [SlotsService]})
|
|
518
|
+
* class XYZComponent {
|
|
519
|
+
* slots: inject(SlotsService<XYZComponentSlots>)
|
|
520
|
+
* }
|
|
521
|
+
*
|
|
522
|
+
*
|
|
523
|
+
*/
|
|
524
|
+
class SlotsService extends Destructible {
|
|
525
|
+
#events = new Subject();
|
|
526
|
+
#entries = this.#events.pipe(scan((entries, event) => {
|
|
527
|
+
if (event.type === "add") {
|
|
528
|
+
const index = entries.findIndex(value => value === event.def);
|
|
529
|
+
if (index > -1) {
|
|
530
|
+
entries[index] = event.def;
|
|
531
|
+
}
|
|
532
|
+
else {
|
|
533
|
+
entries.push(event.def);
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
else if (event.type === "del") {
|
|
537
|
+
const index = entries.findIndex(value => value === event.def);
|
|
538
|
+
if (index > -1) {
|
|
539
|
+
entries.splice(index, 1);
|
|
540
|
+
}
|
|
541
|
+
}
|
|
542
|
+
return entries;
|
|
543
|
+
}, []), tap(entries => {
|
|
544
|
+
entries.sort((a, b) => {
|
|
545
|
+
if (a.slot === b.slot) {
|
|
546
|
+
return a.order - b.order;
|
|
547
|
+
}
|
|
548
|
+
else {
|
|
549
|
+
return a.slot.localeCompare(b.slot);
|
|
550
|
+
}
|
|
551
|
+
});
|
|
552
|
+
}), shareReplay(1));
|
|
553
|
+
constructor() {
|
|
554
|
+
super();
|
|
555
|
+
// XXX: need to collect entries from the beginning
|
|
556
|
+
this.d.sub(this.#entries).subscribe();
|
|
557
|
+
}
|
|
558
|
+
addTpl(def) {
|
|
559
|
+
this.#events.next({ type: "add", def });
|
|
560
|
+
}
|
|
561
|
+
delTpl(def) {
|
|
562
|
+
this.#events.next({ type: "del", def });
|
|
563
|
+
}
|
|
564
|
+
#watchers = {};
|
|
565
|
+
watch(slot) {
|
|
566
|
+
const existing = this.#watchers[slot];
|
|
567
|
+
if (existing == null) {
|
|
568
|
+
return (this.#watchers[slot] = this.#watch(slot));
|
|
569
|
+
}
|
|
570
|
+
else {
|
|
571
|
+
return existing;
|
|
572
|
+
}
|
|
573
|
+
}
|
|
574
|
+
#watch(slot) {
|
|
575
|
+
return this.#entries.pipe(map(entries => entries.filter(entry => entry.slot === slot)), distinctUntilChanged((prev, curr) => {
|
|
576
|
+
if (prev.length === curr.length) {
|
|
577
|
+
for (let i = 0; i < prev.length; i++) {
|
|
578
|
+
if (prev[i] !== curr[i]) {
|
|
579
|
+
return false;
|
|
580
|
+
}
|
|
581
|
+
}
|
|
582
|
+
return true;
|
|
583
|
+
}
|
|
584
|
+
else {
|
|
585
|
+
return false;
|
|
586
|
+
}
|
|
587
|
+
}), finalize(() => {
|
|
588
|
+
delete this.#watchers[slot];
|
|
589
|
+
}), shareReplay(1));
|
|
590
|
+
}
|
|
591
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: SlotsService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
592
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: SlotsService }); }
|
|
593
|
+
}
|
|
594
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: SlotsService, decorators: [{
|
|
595
|
+
type: Injectable
|
|
596
|
+
}], ctorParameters: () => [] });
|
|
597
|
+
class SlotDirective {
|
|
598
|
+
constructor() {
|
|
599
|
+
this.tpl = inject((TemplateRef));
|
|
600
|
+
}
|
|
601
|
+
set slot(slot) {
|
|
602
|
+
if (this.#slot !== slot) {
|
|
603
|
+
this.#slot = slot;
|
|
604
|
+
if (this.#slotDef) {
|
|
605
|
+
this.slotSvc.delTpl(this.#slotDef);
|
|
606
|
+
}
|
|
607
|
+
this.#slotDef = new SlotDef(slot, this.tpl);
|
|
608
|
+
this.slotSvc.addTpl(this.#slotDef);
|
|
609
|
+
}
|
|
610
|
+
}
|
|
611
|
+
get slot() {
|
|
612
|
+
return this.#slot;
|
|
613
|
+
}
|
|
614
|
+
#slot;
|
|
615
|
+
#slotDef;
|
|
616
|
+
ngOnDestroy() {
|
|
617
|
+
if (this.#slotDef) {
|
|
618
|
+
this.slotSvc.delTpl(this.#slotDef);
|
|
619
|
+
}
|
|
620
|
+
}
|
|
621
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: SlotDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
622
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.1.3", type: SlotDirective, ngImport: i0 }); }
|
|
623
|
+
}
|
|
624
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: SlotDirective, decorators: [{
|
|
625
|
+
type: Directive
|
|
626
|
+
}] });
|
|
627
|
+
class SlotOutletDirective extends Destructible {
|
|
628
|
+
set slot(slot) {
|
|
629
|
+
if (this.#slot.value !== slot) {
|
|
630
|
+
this.#slot.next(slot);
|
|
631
|
+
}
|
|
632
|
+
}
|
|
633
|
+
get slot() {
|
|
634
|
+
return this.#slot.value;
|
|
635
|
+
}
|
|
636
|
+
#slot;
|
|
637
|
+
#watch;
|
|
638
|
+
#views;
|
|
639
|
+
constructor() {
|
|
640
|
+
super();
|
|
641
|
+
this.vcr = inject(ViewContainerRef);
|
|
642
|
+
this.injector = inject(Injector);
|
|
643
|
+
this.#slot = new BehaviorSubject(null);
|
|
644
|
+
this.#watch = this.#slot.pipe(switchMap(slot => {
|
|
645
|
+
if (slot) {
|
|
646
|
+
return this.slotSvc.watch(slot);
|
|
647
|
+
}
|
|
648
|
+
else {
|
|
649
|
+
return of([]);
|
|
650
|
+
}
|
|
651
|
+
}));
|
|
652
|
+
this.#views = [];
|
|
653
|
+
this.#onEntriesChanged = (entries) => {
|
|
654
|
+
const { remove, undecided } = this.#determineActions(entries);
|
|
655
|
+
for (const r of remove) {
|
|
656
|
+
r.dispose();
|
|
657
|
+
const idx = this.#views.indexOf(r);
|
|
658
|
+
if (idx >= 0) {
|
|
659
|
+
this.#views.splice(idx, 1);
|
|
660
|
+
}
|
|
661
|
+
}
|
|
662
|
+
this.#views.length = 0;
|
|
663
|
+
for (const [pos, entry] of undecided.entries()) {
|
|
664
|
+
if (entry.viewRef && !entry.viewRef.destroyed) {
|
|
665
|
+
const currentPos = this.vcr.indexOf(entry.viewRef);
|
|
666
|
+
if (currentPos !== pos) {
|
|
667
|
+
this.vcr.insert(entry.viewRef, pos);
|
|
668
|
+
}
|
|
669
|
+
}
|
|
670
|
+
else {
|
|
671
|
+
;
|
|
672
|
+
entry.viewRef = this.vcr.createEmbeddedView(entry.tpl, null, {
|
|
673
|
+
index: pos,
|
|
674
|
+
injector: this.injector
|
|
675
|
+
});
|
|
676
|
+
entry.viewRef.markForCheck();
|
|
677
|
+
}
|
|
678
|
+
this.#views.push(entry);
|
|
679
|
+
}
|
|
680
|
+
};
|
|
681
|
+
this.d.any(this.#clearViews.bind(this));
|
|
682
|
+
}
|
|
683
|
+
ngOnInit() {
|
|
684
|
+
this.d.sub(this.#watch).subscribe(this.#onEntriesChanged);
|
|
685
|
+
}
|
|
686
|
+
#onEntriesChanged;
|
|
687
|
+
#determineActions(entries) {
|
|
688
|
+
const byId = {};
|
|
689
|
+
let remove = [];
|
|
690
|
+
const undecided = [];
|
|
691
|
+
for (const entry of entries) {
|
|
692
|
+
if (entry.id != null) {
|
|
693
|
+
if (!byId[entry.id]) {
|
|
694
|
+
byId[entry.id] = [entry];
|
|
695
|
+
}
|
|
696
|
+
else {
|
|
697
|
+
byId[entry.id].push(entry);
|
|
698
|
+
}
|
|
699
|
+
}
|
|
700
|
+
else {
|
|
701
|
+
undecided.push(entry);
|
|
702
|
+
}
|
|
703
|
+
}
|
|
704
|
+
for (const values of Object.values(byId)) {
|
|
705
|
+
remove = remove.concat(values.slice(0, -1));
|
|
706
|
+
undecided.push(values[values.length - 1]);
|
|
707
|
+
}
|
|
708
|
+
for (const current of this.#views) {
|
|
709
|
+
if (!undecided.includes(current)) {
|
|
710
|
+
remove.push(current);
|
|
711
|
+
}
|
|
712
|
+
}
|
|
713
|
+
return { remove, undecided };
|
|
714
|
+
}
|
|
715
|
+
#clearViews() {
|
|
716
|
+
this.vcr.clear();
|
|
717
|
+
this.#views = [];
|
|
718
|
+
}
|
|
719
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: SlotOutletDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
720
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.1.3", type: SlotOutletDirective, usesInheritance: true, ngImport: i0 }); }
|
|
721
|
+
}
|
|
722
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: SlotOutletDirective, decorators: [{
|
|
723
|
+
type: Directive
|
|
724
|
+
}], ctorParameters: () => [] });
|
|
725
|
+
|
|
673
726
|
/**
|
|
674
727
|
* Generated bundle index. Do not edit.
|
|
675
728
|
*/
|
|
676
729
|
|
|
677
|
-
export { DockingContentComponent, DockingLayoutComponent, DockingPanelComponent, L9Cell, L9Range, L9State, NuDockingLayout,
|
|
730
|
+
export { DockingContentComponent, DockingLayoutComponent, DockingPanelComponent, L9Cell, L9Range, L9State, NuDockingLayout, SlotDef, SlotDirective, SlotOutletDirective, SlotsService };
|
|
678
731
|
//# sourceMappingURL=ngutil-layout.mjs.map
|