@ngutil/layout 0.0.3-dev.0 → 0.0.3-dev.10
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 +5 -0
- package/docking/docking-layout.component.d.ts +22 -0
- package/docking/docking-panel.component.d.ts +40 -0
- package/docking/index.d.ts +13 -0
- package/esm2022/docking/docking-content.component.mjs +11 -0
- package/esm2022/docking/docking-layout.component.mjs +140 -0
- package/esm2022/docking/docking-panel.component.mjs +179 -0
- package/esm2022/docking/index.mjs +20 -0
- package/esm2022/index.mjs +5 -0
- package/esm2022/l9/index.mjs +3 -0
- package/esm2022/l9/range.mjs +109 -0
- package/esm2022/l9/state.mjs +29 -0
- package/esm2022/ngutil-layout.mjs +5 -0
- package/esm2022/services/slots.service.mjs +240 -0
- package/esm2022/util/dimension-watcher.mjs +85 -0
- package/esm2022/util/dimension.mjs +2 -0
- package/esm2022/util/index.mjs +3 -0
- package/esm2022/util/media-watcher.mjs +29 -0
- package/esm2022/util/rect.mjs +2 -0
- package/fesm2022/ngutil-layout.mjs +822 -0
- package/fesm2022/ngutil-layout.mjs.map +1 -0
- package/index.d.ts +4 -0
- package/l9/index.d.ts +2 -0
- package/l9/range.d.ts +28 -0
- package/l9/state.d.ts +14 -0
- package/package.json +19 -5
- package/services/slots.service.d.ts +69 -0
- package/util/dimension-watcher.d.ts +4 -0
- package/util/dimension.d.ts +5 -0
- package/util/index.d.ts +4 -0
- package/util/media-watcher.d.ts +5 -0
- package/util/rect.d.ts +5 -0
- package/.eslintrc.json +0 -25
- package/.storybook/main.ts +0 -16
- package/.storybook/preview.ts +0 -0
- package/.storybook/tsconfig.json +0 -16
- package/jest.config.ts +0 -22
- package/ng-package.json +0 -7
- package/project.json +0 -73
- package/src/index.ts +0 -1
- package/src/lib/layout/layout.component.scss +0 -0
- package/src/lib/layout/layout.component.spec.ts +0 -22
- package/src/lib/layout/layout.component.stories.ts +0 -24
- package/src/lib/layout/layout.component.ts +0 -11
- package/src/test-setup.ts +0 -9
- package/tsconfig.json +0 -32
- package/tsconfig.lib.json +0 -19
- package/tsconfig.lib.prod.json +0 -9
- package/tsconfig.spec.json +0 -11
|
@@ -0,0 +1,822 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { inject, NgZone, Component, ElementRef, Input, Output, ChangeDetectionStrategy, ContentChild, ContentChildren, NgModule, Injectable, TemplateRef, Directive, ViewContainerRef, Injector } from '@angular/core';
|
|
3
|
+
import { Observable, distinctUntilChanged, shareReplay, BehaviorSubject, map, combineLatest, switchMap, of, Subject, startWith, scan, tap, finalize } from 'rxjs';
|
|
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 = NaN;
|
|
85
|
+
let lastSh = NaN;
|
|
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
|
+
emit();
|
|
104
|
+
return () => {
|
|
105
|
+
dimSum.unsubscribe();
|
|
106
|
+
mutation.disconnect();
|
|
107
|
+
SCROLL_WATCHES.delete(el);
|
|
108
|
+
};
|
|
109
|
+
}).pipe(shareReplay(1)));
|
|
110
|
+
}
|
|
111
|
+
function _number(val) {
|
|
112
|
+
return new NumberWithUnit(val, "px");
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* -----------------------------------------------
|
|
117
|
+
* | TOP:LEFT | TOP:CENTER | TOP:RIGHT |
|
|
118
|
+
* -----------------------------------------------
|
|
119
|
+
* | MIDDLE:LEFT | MIDDLE:CENTER | MIDDLE:RIGH |
|
|
120
|
+
* -----------------------------------------------
|
|
121
|
+
* | BOTTOMN:LEFT | BOTTOM:CENTER | BOTTOM:RIGHT |
|
|
122
|
+
* -----------------------------------------------
|
|
123
|
+
*/
|
|
124
|
+
const vertical = ["top", "middle", "bottom"];
|
|
125
|
+
const horizontal = ["left", "center", "right"];
|
|
126
|
+
class L9Cell {
|
|
127
|
+
static coerce(value) {
|
|
128
|
+
const [v, h] = value.split(":");
|
|
129
|
+
if (vertical.includes(v) && horizontal.includes(h)) {
|
|
130
|
+
return new L9Cell(v, h);
|
|
131
|
+
}
|
|
132
|
+
throw new Error(`Invalid cell value: ${value}`);
|
|
133
|
+
}
|
|
134
|
+
constructor(v, h) {
|
|
135
|
+
this.v = v;
|
|
136
|
+
this.h = h;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
class L9Range {
|
|
140
|
+
static coerce(value) {
|
|
141
|
+
if (value instanceof L9Range) {
|
|
142
|
+
return value;
|
|
143
|
+
}
|
|
144
|
+
else {
|
|
145
|
+
return new L9Range(value);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
constructor(range) {
|
|
149
|
+
this.cells = parse(range);
|
|
150
|
+
this.orient = this.#determineOrient();
|
|
151
|
+
}
|
|
152
|
+
isEq(other) {
|
|
153
|
+
if (other instanceof L9Range) {
|
|
154
|
+
const selfFirst = this.cells[0];
|
|
155
|
+
const otherFirst = other.cells[0];
|
|
156
|
+
if (selfFirst.h !== otherFirst.h || selfFirst.v !== otherFirst.v) {
|
|
157
|
+
return false;
|
|
158
|
+
}
|
|
159
|
+
const selfLast = this.cells[this.cells.length - 1];
|
|
160
|
+
const otherLast = other.cells[other.cells.length - 1];
|
|
161
|
+
if (selfLast.h === otherLast.h && selfLast.v === otherLast.v) {
|
|
162
|
+
return true;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
return false;
|
|
166
|
+
}
|
|
167
|
+
#determineOrient() {
|
|
168
|
+
const { v: sv, h: sh } = this.cells[0];
|
|
169
|
+
const { v: ev, h: eh } = this.cells[this.cells.length - 1];
|
|
170
|
+
if (sv === ev) {
|
|
171
|
+
return "horizontal";
|
|
172
|
+
}
|
|
173
|
+
else if (sh === eh) {
|
|
174
|
+
return "vertical";
|
|
175
|
+
}
|
|
176
|
+
else {
|
|
177
|
+
return "rect";
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
function parse(value) {
|
|
182
|
+
const cells = [];
|
|
183
|
+
if (vertical.includes(value)) {
|
|
184
|
+
for (const h of horizontal) {
|
|
185
|
+
cells.push(new L9Cell(value, h));
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
else if (horizontal.includes(value)) {
|
|
189
|
+
for (const v of vertical) {
|
|
190
|
+
cells.push(new L9Cell(v, value));
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
else if (value.includes("-")) {
|
|
194
|
+
const [begin, end] = value.split("-");
|
|
195
|
+
const beginCells = parse(begin);
|
|
196
|
+
const endCells = parse(end);
|
|
197
|
+
if (beginCells.length > 1) {
|
|
198
|
+
throw new Error(`Currently not supported begin range value: ${begin}`);
|
|
199
|
+
}
|
|
200
|
+
if (endCells.length > 1) {
|
|
201
|
+
throw new Error(`Currently not supported end range value: ${end}`);
|
|
202
|
+
}
|
|
203
|
+
const { v: bv, h: bh } = beginCells[0];
|
|
204
|
+
const { v: ev, h: eh } = endCells[0];
|
|
205
|
+
const vstart = Math.min(vertical.indexOf(bv), vertical.indexOf(ev));
|
|
206
|
+
const vend = Math.max(vertical.indexOf(bv), vertical.indexOf(ev));
|
|
207
|
+
const hstart = Math.min(horizontal.indexOf(bh), horizontal.indexOf(eh));
|
|
208
|
+
const hend = Math.max(horizontal.indexOf(bh), horizontal.indexOf(eh));
|
|
209
|
+
for (let vi = vstart; vi <= vend; vi++) {
|
|
210
|
+
for (let hi = hstart; hi <= hend; hi++) {
|
|
211
|
+
cells.push(new L9Cell(vertical[vi], horizontal[hi]));
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
else if (value.includes(":")) {
|
|
216
|
+
cells.push(L9Cell.coerce(value));
|
|
217
|
+
}
|
|
218
|
+
if (cells.length === 0) {
|
|
219
|
+
throw Error(`Undefined l9cell: "${value}"`);
|
|
220
|
+
}
|
|
221
|
+
return cells;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
class L9State {
|
|
225
|
+
#dims;
|
|
226
|
+
constructor(prefix) {
|
|
227
|
+
this.prefix = prefix;
|
|
228
|
+
this.#dims = new BehaviorSubject({});
|
|
229
|
+
this.style = this.#dims.pipe(map(dims => {
|
|
230
|
+
const res = {};
|
|
231
|
+
for (const [k, v] of Object.entries(dims)) {
|
|
232
|
+
if (v == null) {
|
|
233
|
+
continue;
|
|
234
|
+
}
|
|
235
|
+
const [vertical, horizontal] = k.split(":");
|
|
236
|
+
res[`--${this.prefix}-${vertical}-${horizontal}-w`] = v.width.toString();
|
|
237
|
+
res[`--${this.prefix}-${vertical}-${horizontal}-h`] = v.height.toString();
|
|
238
|
+
}
|
|
239
|
+
return res;
|
|
240
|
+
}), shareReplay(1));
|
|
241
|
+
}
|
|
242
|
+
update(range, dim) {
|
|
243
|
+
range = L9Range.coerce(range);
|
|
244
|
+
const dims = { ...this.#dims.value };
|
|
245
|
+
// for (const cell of range.horizontals) {
|
|
246
|
+
// dims[cell] = dim.width
|
|
247
|
+
// }
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
class DockingContentComponent {
|
|
252
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: DockingContentComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
253
|
+
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;overflow:auto}\n"] }); }
|
|
254
|
+
}
|
|
255
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: DockingContentComponent, decorators: [{
|
|
256
|
+
type: Component,
|
|
257
|
+
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;overflow:auto}\n"] }]
|
|
258
|
+
}] });
|
|
259
|
+
|
|
260
|
+
const DEFAULT_POSITION = L9Range.coerce("left");
|
|
261
|
+
const INVISIBLE_SIZE = new NumberWithUnit(0, "px");
|
|
262
|
+
const AUTO_SIZE = NumberWithUnit.coerce("auto");
|
|
263
|
+
class DockingPanelComponent extends Destructible {
|
|
264
|
+
set positionInput(val) {
|
|
265
|
+
const coerced = L9Range.coerce(val);
|
|
266
|
+
if (coerced.orient === "rect") {
|
|
267
|
+
throw new Error(`Invalid position value: ${val}`);
|
|
268
|
+
}
|
|
269
|
+
if (!this.position.value.isEq(coerced)) {
|
|
270
|
+
this.position.next(coerced);
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
set stateInput(val) {
|
|
274
|
+
if (this.state.value !== val) {
|
|
275
|
+
this.state.next(val);
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
set modeInput(val) {
|
|
279
|
+
if (this.mode.value !== val) {
|
|
280
|
+
this.mode.next(val);
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
set fullSizeInput(val) {
|
|
284
|
+
const coerced = NumberWithUnit.coerce(val, "px");
|
|
285
|
+
if (this.#fullSize.value !== coerced) {
|
|
286
|
+
this.#fullSize.next(coerced);
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
#fullSize;
|
|
290
|
+
set miniSizeInput(val) {
|
|
291
|
+
const coerced = NumberWithUnit.coerce(val, "px");
|
|
292
|
+
if (this.#miniSize.value !== coerced) {
|
|
293
|
+
this.#miniSize.next(coerced);
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
#miniSize;
|
|
297
|
+
set minimizable(val) {
|
|
298
|
+
this.#minimizable = coerceBoolAttr(val);
|
|
299
|
+
this.#minimizableAuto = false;
|
|
300
|
+
}
|
|
301
|
+
get minimizable() {
|
|
302
|
+
return this.#minimizable;
|
|
303
|
+
}
|
|
304
|
+
#minimizable;
|
|
305
|
+
#minimizableAuto;
|
|
306
|
+
#contentSize;
|
|
307
|
+
#autoSize;
|
|
308
|
+
constructor() {
|
|
309
|
+
super();
|
|
310
|
+
this.el = inject((ElementRef));
|
|
311
|
+
this.position = new BehaviorSubject(DEFAULT_POSITION);
|
|
312
|
+
this.state = new BehaviorSubject("invisible");
|
|
313
|
+
this.mode = new BehaviorSubject("rigid");
|
|
314
|
+
this.#fullSize = new BehaviorSubject(AUTO_SIZE);
|
|
315
|
+
this.#miniSize = new BehaviorSubject(INVISIBLE_SIZE);
|
|
316
|
+
this.#minimizable = false;
|
|
317
|
+
this.#minimizableAuto = true;
|
|
318
|
+
this.#contentSize = watchDimension(this.el.nativeElement, "scroll-box").pipe(shareReplay(1));
|
|
319
|
+
this.#autoSize = combineLatest({
|
|
320
|
+
dim: this.#contentSize,
|
|
321
|
+
pos: this.position
|
|
322
|
+
}).pipe(map(({ dim, pos }) => {
|
|
323
|
+
if (pos.orient === "horizontal") {
|
|
324
|
+
return dim.height;
|
|
325
|
+
}
|
|
326
|
+
else {
|
|
327
|
+
return dim.width;
|
|
328
|
+
}
|
|
329
|
+
}), shareReplay(1));
|
|
330
|
+
this.fullSize = this.#fullSize.pipe(switchMap(size => {
|
|
331
|
+
if (size.unit === "auto") {
|
|
332
|
+
return this.#autoSize;
|
|
333
|
+
}
|
|
334
|
+
else {
|
|
335
|
+
return of(size);
|
|
336
|
+
}
|
|
337
|
+
}), shareReplay(1));
|
|
338
|
+
this.miniSize = this.#miniSize.pipe(switchMap(size => {
|
|
339
|
+
if (size.unit === "auto") {
|
|
340
|
+
return this.#autoSize;
|
|
341
|
+
}
|
|
342
|
+
else {
|
|
343
|
+
return of(size);
|
|
344
|
+
}
|
|
345
|
+
}), shareReplay(1));
|
|
346
|
+
this.changes = combineLatest({
|
|
347
|
+
position: this.position,
|
|
348
|
+
state: this.state,
|
|
349
|
+
mode: this.mode,
|
|
350
|
+
fullSize: this.fullSize,
|
|
351
|
+
miniSize: this.miniSize,
|
|
352
|
+
contentSize: this.#contentSize
|
|
353
|
+
});
|
|
354
|
+
this.d.sub(this.changes).subscribe(changes => {
|
|
355
|
+
if (this.#minimizableAuto) {
|
|
356
|
+
this.#minimizable = this.#miniSize.value.value !== 0;
|
|
357
|
+
}
|
|
358
|
+
FastDOM.setAttributes(this.el.nativeElement, {
|
|
359
|
+
state: changes.state,
|
|
360
|
+
orient: changes.position.orient,
|
|
361
|
+
mode: changes.mode,
|
|
362
|
+
side: changes.position.orient === "horizontal" ? changes.position.cells[0].v : changes.position.cells[0].h
|
|
363
|
+
});
|
|
364
|
+
const isHorizontal = changes.position.orient === "horizontal";
|
|
365
|
+
let w = null;
|
|
366
|
+
let h = null;
|
|
367
|
+
// TODO: when change state from mini -> invisible, currently wrong behavior
|
|
368
|
+
// the good behavior is to not gain fullSize ang go to invisible
|
|
369
|
+
if (changes.state === "mini") {
|
|
370
|
+
if (isHorizontal) {
|
|
371
|
+
h = changes.miniSize.unit === "auto" ? changes.contentSize.height : changes.miniSize;
|
|
372
|
+
}
|
|
373
|
+
else {
|
|
374
|
+
w = changes.miniSize.unit === "auto" ? changes.contentSize.width : changes.miniSize;
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
else {
|
|
378
|
+
if (isHorizontal) {
|
|
379
|
+
h = changes.fullSize.unit === "auto" ? changes.contentSize.height : changes.fullSize;
|
|
380
|
+
}
|
|
381
|
+
else {
|
|
382
|
+
w = changes.fullSize.unit === "auto" ? changes.contentSize.width : changes.fullSize;
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
FastDOM.setStyle(this.el.nativeElement, {
|
|
386
|
+
"--docking-panel-w": w != null ? `${w}` : null,
|
|
387
|
+
"--docking-panel-h": h != null ? `${h}` : null,
|
|
388
|
+
"--docking-panel-content-w": changes.contentSize.width,
|
|
389
|
+
"--docking-panel-content-h": changes.contentSize.height
|
|
390
|
+
}, () => FastDOM.setAttributes(this.el.nativeElement, { animate: "" }));
|
|
391
|
+
});
|
|
392
|
+
}
|
|
393
|
+
open() {
|
|
394
|
+
this.state.next("full");
|
|
395
|
+
}
|
|
396
|
+
close() {
|
|
397
|
+
this.state.next("invisible");
|
|
398
|
+
}
|
|
399
|
+
minimize() {
|
|
400
|
+
if (this.minimizable) {
|
|
401
|
+
this.state.next("mini");
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: DockingPanelComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
405
|
+
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" }, exportAs: ["nuDockingPanel"], usesInheritance: true, ngImport: i0, template: `<ng-content></ng-content>`, 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-h: var(--docking-panel-content-h, var(---docking-panel-h));display:flex;flex-flow:column nowrap;align-items:stretch;position:absolute;box-sizing:border-box;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=invisible][orient=horizontal]{transform:translateY(var(---docking-panel-t-hide))}:host[state=invisible][orient=vertical]{transform:translate(var(---docking-panel-t-hide))}:host:not([state=invisible])[orient=horizontal]{transform:translateY(var(---docking-panel-t-visible))}:host:not([state=invisible])[orient=vertical]{transform:translate(var(---docking-panel-t-visible))}\n"] }); }
|
|
406
|
+
}
|
|
407
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: DockingPanelComponent, decorators: [{
|
|
408
|
+
type: Component,
|
|
409
|
+
args: [{ standalone: true, selector: "nu-docking-panel", exportAs: "nuDockingPanel", template: `<ng-content></ng-content>`, 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-h: var(--docking-panel-content-h, var(---docking-panel-h));display:flex;flex-flow:column nowrap;align-items:stretch;position:absolute;box-sizing:border-box;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=invisible][orient=horizontal]{transform:translateY(var(---docking-panel-t-hide))}:host[state=invisible][orient=vertical]{transform:translate(var(---docking-panel-t-hide))}:host:not([state=invisible])[orient=horizontal]{transform:translateY(var(---docking-panel-t-visible))}:host:not([state=invisible])[orient=vertical]{transform:translate(var(---docking-panel-t-visible))}\n"] }]
|
|
410
|
+
}], ctorParameters: () => [], propDecorators: { positionInput: [{
|
|
411
|
+
type: Input,
|
|
412
|
+
args: ["position"]
|
|
413
|
+
}], stateInput: [{
|
|
414
|
+
type: Input,
|
|
415
|
+
args: ["state"]
|
|
416
|
+
}], state: [{
|
|
417
|
+
type: Output,
|
|
418
|
+
args: ["stateChanges"]
|
|
419
|
+
}], modeInput: [{
|
|
420
|
+
type: Input,
|
|
421
|
+
args: ["mode"]
|
|
422
|
+
}], fullSizeInput: [{
|
|
423
|
+
type: Input,
|
|
424
|
+
args: ["fullSize"]
|
|
425
|
+
}], miniSizeInput: [{
|
|
426
|
+
type: Input,
|
|
427
|
+
args: ["miniSize"]
|
|
428
|
+
}], minimizable: [{
|
|
429
|
+
type: Input,
|
|
430
|
+
args: ["minimizable"]
|
|
431
|
+
}] } });
|
|
432
|
+
|
|
433
|
+
const RIGID_ZINDEX = 20;
|
|
434
|
+
const OVER_ZINDEX = RIGID_ZINDEX * 2;
|
|
435
|
+
class DockingLayoutComponent extends Destructible {
|
|
436
|
+
constructor() {
|
|
437
|
+
super(...arguments);
|
|
438
|
+
this.#el = inject((ElementRef));
|
|
439
|
+
this.contentOnly = false;
|
|
440
|
+
this.#reflow = new Subject();
|
|
441
|
+
}
|
|
442
|
+
#el;
|
|
443
|
+
#reflow;
|
|
444
|
+
ngAfterViewInit() {
|
|
445
|
+
// eslint-disable-next-line prettier/prettier
|
|
446
|
+
this.panels = this.dockingPanels.changes.pipe(startWith(null), map(() => this.dockingPanels.toArray()), shareReplay(1));
|
|
447
|
+
this.d
|
|
448
|
+
.sub(combineLatest({ panels: this.panels, reflow: this.#reflow.pipe(startWith(null)) }))
|
|
449
|
+
.pipe(switchMap(({ panels }) => combineLatest(panels.map(panel => panel.changes.pipe(map(changes => {
|
|
450
|
+
return { panel, changes };
|
|
451
|
+
}))))))
|
|
452
|
+
.subscribe(this.#layout.bind(this));
|
|
453
|
+
}
|
|
454
|
+
ngOnChanges(changes) {
|
|
455
|
+
if ("contentOnly" in changes || "positionMode" in changes) {
|
|
456
|
+
this.#reflow.next();
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
#layout(entries) {
|
|
460
|
+
let paddingTop = 0;
|
|
461
|
+
let paddingRight = 0;
|
|
462
|
+
let paddingBottom = 0;
|
|
463
|
+
let paddingLeft = 0;
|
|
464
|
+
let rigidZIndex = RIGID_ZINDEX;
|
|
465
|
+
let overZIndex = OVER_ZINDEX;
|
|
466
|
+
if (this.contentOnly) {
|
|
467
|
+
// TODO:...
|
|
468
|
+
}
|
|
469
|
+
else {
|
|
470
|
+
for (const entry of entries) {
|
|
471
|
+
const panelState = entry.changes;
|
|
472
|
+
const panelSize = panelState.state === "full"
|
|
473
|
+
? panelState.fullSize.value
|
|
474
|
+
: panelState.state === "mini"
|
|
475
|
+
? panelState.miniSize.value
|
|
476
|
+
: 0;
|
|
477
|
+
const isHorizontal = panelState.position.orient === "horizontal";
|
|
478
|
+
const isRigid = panelState.mode === "rigid";
|
|
479
|
+
let panelTop = null;
|
|
480
|
+
let panelRight = null;
|
|
481
|
+
let panelBottom = null;
|
|
482
|
+
let panelLeft = null;
|
|
483
|
+
if (isHorizontal) {
|
|
484
|
+
panelLeft = 0;
|
|
485
|
+
panelRight = 0;
|
|
486
|
+
if (panelState.position.cells[0].v === "top") {
|
|
487
|
+
if (isRigid) {
|
|
488
|
+
paddingTop = Math.max(paddingTop, panelSize);
|
|
489
|
+
}
|
|
490
|
+
panelTop = 0;
|
|
491
|
+
}
|
|
492
|
+
else if (panelState.position.cells[0].v === "bottom") {
|
|
493
|
+
if (isRigid) {
|
|
494
|
+
paddingBottom = Math.max(paddingBottom, panelSize);
|
|
495
|
+
}
|
|
496
|
+
panelBottom = 0;
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
else {
|
|
500
|
+
panelTop = 0;
|
|
501
|
+
panelBottom = 0;
|
|
502
|
+
if (panelState.position.cells[0].h === "left") {
|
|
503
|
+
if (isRigid) {
|
|
504
|
+
paddingLeft = Math.max(paddingLeft, panelSize);
|
|
505
|
+
}
|
|
506
|
+
panelLeft = 0;
|
|
507
|
+
}
|
|
508
|
+
else if (panelState.position.cells[0].h === "right") {
|
|
509
|
+
if (isRigid) {
|
|
510
|
+
paddingRight = Math.max(paddingRight, panelSize);
|
|
511
|
+
}
|
|
512
|
+
panelRight = 0;
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
FastDOM.setStyle(entry.panel.el.nativeElement, {
|
|
516
|
+
"z-index": `${isRigid ? rigidZIndex++ : overZIndex++}`,
|
|
517
|
+
"--docking-panel-t": panelTop != null ? `${panelTop}px` : null,
|
|
518
|
+
"--docking-panel-r": panelRight != null ? `${panelRight}px` : null,
|
|
519
|
+
"--docking-panel-b": panelBottom != null ? `${panelBottom}px` : null,
|
|
520
|
+
"--docking-panel-l": panelLeft != null ? `${panelLeft}px` : null
|
|
521
|
+
});
|
|
522
|
+
}
|
|
523
|
+
FastDOM.setStyle(this.#el.nativeElement, {
|
|
524
|
+
"--docking-layout-top": `${paddingTop}px`,
|
|
525
|
+
"--docking-layout-right": `${paddingRight}px`,
|
|
526
|
+
"--docking-layout-bottom": `${paddingBottom}px`,
|
|
527
|
+
"--docking-layout-left": `${paddingLeft}px`
|
|
528
|
+
});
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: DockingLayoutComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
|
|
532
|
+
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: `
|
|
533
|
+
<ng-content select="nu-docking-panel"></ng-content>
|
|
534
|
+
|
|
535
|
+
@if (!contentComponent) {
|
|
536
|
+
<nu-docking-content>
|
|
537
|
+
<ng-content></ng-content>
|
|
538
|
+
</nu-docking-content>
|
|
539
|
+
} @else {
|
|
540
|
+
<ng-content select="nu-docking-content"></ng-content>
|
|
541
|
+
}
|
|
542
|
+
`, 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, .2s);---docking-layout-anim-ease: var(--docking-layout-anim-ease, ease-out);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 }); }
|
|
543
|
+
}
|
|
544
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: DockingLayoutComponent, decorators: [{
|
|
545
|
+
type: Component,
|
|
546
|
+
args: [{ selector: "nu-docking", standalone: true, imports: [DockingContentComponent], template: `
|
|
547
|
+
<ng-content select="nu-docking-panel"></ng-content>
|
|
548
|
+
|
|
549
|
+
@if (!contentComponent) {
|
|
550
|
+
<nu-docking-content>
|
|
551
|
+
<ng-content></ng-content>
|
|
552
|
+
</nu-docking-content>
|
|
553
|
+
} @else {
|
|
554
|
+
<ng-content select="nu-docking-content"></ng-content>
|
|
555
|
+
}
|
|
556
|
+
`, 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, .2s);---docking-layout-anim-ease: var(--docking-layout-anim-ease, ease-out);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"] }]
|
|
557
|
+
}], propDecorators: { contentOnly: [{
|
|
558
|
+
type: Input
|
|
559
|
+
}], contentComponent: [{
|
|
560
|
+
type: ContentChild,
|
|
561
|
+
args: [DockingContentComponent]
|
|
562
|
+
}], dockingPanels: [{
|
|
563
|
+
type: ContentChildren,
|
|
564
|
+
args: [DockingPanelComponent]
|
|
565
|
+
}] } });
|
|
566
|
+
|
|
567
|
+
const members = [DockingLayoutComponent, DockingPanelComponent, DockingContentComponent];
|
|
568
|
+
class NuDockingLayout {
|
|
569
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: NuDockingLayout, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
|
|
570
|
+
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "17.1.3", ngImport: i0, type: NuDockingLayout, imports: [DockingLayoutComponent, DockingPanelComponent, DockingContentComponent], exports: [DockingLayoutComponent, DockingPanelComponent, DockingContentComponent] }); }
|
|
571
|
+
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: NuDockingLayout }); }
|
|
572
|
+
}
|
|
573
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: NuDockingLayout, decorators: [{
|
|
574
|
+
type: NgModule,
|
|
575
|
+
args: [{
|
|
576
|
+
imports: members,
|
|
577
|
+
exports: members
|
|
578
|
+
}]
|
|
579
|
+
}] });
|
|
580
|
+
|
|
581
|
+
const SLOT_REGEX = /^([^:\s]+)(?::(\d+))?(?:\s+as\s+(.*?))?$/i;
|
|
582
|
+
class SlotDef {
|
|
583
|
+
constructor(slot, tpl) {
|
|
584
|
+
this.tpl = tpl;
|
|
585
|
+
const match = slot.match(SLOT_REGEX);
|
|
586
|
+
if (!match) {
|
|
587
|
+
console.warn(`Invalid slot definition: ${slot}`);
|
|
588
|
+
}
|
|
589
|
+
else {
|
|
590
|
+
this.slot = match[1];
|
|
591
|
+
this.order = match[2] != null ? Number(match[2]) : Infinity;
|
|
592
|
+
this.id = match[3];
|
|
593
|
+
}
|
|
594
|
+
}
|
|
595
|
+
dispose() {
|
|
596
|
+
this.viewRef?.destroy();
|
|
597
|
+
this.viewRef = undefined;
|
|
598
|
+
}
|
|
599
|
+
}
|
|
600
|
+
/**
|
|
601
|
+
* @Directive({selector: "ng-template[xyzSlot]", inputs: [{name: "slot", alias: "xyzSlot"}]})
|
|
602
|
+
* class XYZSlotDirective extends SlotDirective<XYZComponentSlots> { }
|
|
603
|
+
*
|
|
604
|
+
* @Directive({selector: "ng-template[xyzSlotOutlet]", inputs: [{name: "slot", alias: "xyzSlotOutlet"}]})
|
|
605
|
+
* class XYZSlotOutletDirective extends SlotOutletDirective<XYZComponentSlots> { }
|
|
606
|
+
*
|
|
607
|
+
*
|
|
608
|
+
* @Component({provides: [SlotsService]})
|
|
609
|
+
* class XYZComponent {
|
|
610
|
+
* slots: inject(SlotsService<XYZComponentSlots>)
|
|
611
|
+
* }
|
|
612
|
+
*
|
|
613
|
+
*
|
|
614
|
+
*/
|
|
615
|
+
class SlotsService extends Destructible {
|
|
616
|
+
#events = new Subject();
|
|
617
|
+
#entries = this.#events.pipe(scan((entries, event) => {
|
|
618
|
+
if (event.type === "add") {
|
|
619
|
+
const index = entries.findIndex(value => value === event.def);
|
|
620
|
+
if (index > -1) {
|
|
621
|
+
entries[index] = event.def;
|
|
622
|
+
}
|
|
623
|
+
else {
|
|
624
|
+
entries.push(event.def);
|
|
625
|
+
}
|
|
626
|
+
}
|
|
627
|
+
else if (event.type === "del") {
|
|
628
|
+
const index = entries.findIndex(value => value === event.def);
|
|
629
|
+
if (index > -1) {
|
|
630
|
+
entries.splice(index, 1);
|
|
631
|
+
}
|
|
632
|
+
}
|
|
633
|
+
return entries;
|
|
634
|
+
}, []), tap(entries => {
|
|
635
|
+
entries.sort((a, b) => {
|
|
636
|
+
if (a.slot === b.slot) {
|
|
637
|
+
return a.order - b.order;
|
|
638
|
+
}
|
|
639
|
+
else {
|
|
640
|
+
return a.slot.localeCompare(b.slot);
|
|
641
|
+
}
|
|
642
|
+
});
|
|
643
|
+
}), shareReplay(1));
|
|
644
|
+
constructor() {
|
|
645
|
+
super();
|
|
646
|
+
// XXX: need to collect entries from the beginning
|
|
647
|
+
this.d.sub(this.#entries).subscribe();
|
|
648
|
+
}
|
|
649
|
+
addTpl(def) {
|
|
650
|
+
this.#events.next({ type: "add", def });
|
|
651
|
+
}
|
|
652
|
+
delTpl(def) {
|
|
653
|
+
this.#events.next({ type: "del", def });
|
|
654
|
+
}
|
|
655
|
+
#watchers = {};
|
|
656
|
+
watch(slot) {
|
|
657
|
+
const existing = this.#watchers[slot];
|
|
658
|
+
if (existing == null) {
|
|
659
|
+
return (this.#watchers[slot] = this.#watch(slot));
|
|
660
|
+
}
|
|
661
|
+
else {
|
|
662
|
+
return existing;
|
|
663
|
+
}
|
|
664
|
+
}
|
|
665
|
+
#watch(slot) {
|
|
666
|
+
return this.#entries.pipe(map(entries => entries.filter(entry => entry.slot === slot)), distinctUntilChanged((prev, curr) => {
|
|
667
|
+
if (prev.length === curr.length) {
|
|
668
|
+
for (let i = 0; i < prev.length; i++) {
|
|
669
|
+
if (prev[i] !== curr[i]) {
|
|
670
|
+
return false;
|
|
671
|
+
}
|
|
672
|
+
}
|
|
673
|
+
return true;
|
|
674
|
+
}
|
|
675
|
+
else {
|
|
676
|
+
return false;
|
|
677
|
+
}
|
|
678
|
+
}), finalize(() => {
|
|
679
|
+
delete this.#watchers[slot];
|
|
680
|
+
}), shareReplay(1));
|
|
681
|
+
}
|
|
682
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: SlotsService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
683
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: SlotsService }); }
|
|
684
|
+
}
|
|
685
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: SlotsService, decorators: [{
|
|
686
|
+
type: Injectable
|
|
687
|
+
}], ctorParameters: () => [] });
|
|
688
|
+
class SlotDirective {
|
|
689
|
+
constructor() {
|
|
690
|
+
this.tpl = inject((TemplateRef));
|
|
691
|
+
}
|
|
692
|
+
set slot(slot) {
|
|
693
|
+
if (this.#slot !== slot) {
|
|
694
|
+
this.#slot = slot;
|
|
695
|
+
if (this.#slotDef) {
|
|
696
|
+
this.slotSvc.delTpl(this.#slotDef);
|
|
697
|
+
}
|
|
698
|
+
this.#slotDef = new SlotDef(slot, this.tpl);
|
|
699
|
+
this.slotSvc.addTpl(this.#slotDef);
|
|
700
|
+
}
|
|
701
|
+
}
|
|
702
|
+
get slot() {
|
|
703
|
+
return this.#slot;
|
|
704
|
+
}
|
|
705
|
+
#slot;
|
|
706
|
+
#slotDef;
|
|
707
|
+
ngOnDestroy() {
|
|
708
|
+
if (this.#slotDef) {
|
|
709
|
+
this.slotSvc.delTpl(this.#slotDef);
|
|
710
|
+
}
|
|
711
|
+
}
|
|
712
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: SlotDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
713
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.1.3", type: SlotDirective, ngImport: i0 }); }
|
|
714
|
+
}
|
|
715
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: SlotDirective, decorators: [{
|
|
716
|
+
type: Directive
|
|
717
|
+
}] });
|
|
718
|
+
class SlotOutletDirective extends Destructible {
|
|
719
|
+
set slot(slot) {
|
|
720
|
+
if (this.#slot.value !== slot) {
|
|
721
|
+
this.#slot.next(slot);
|
|
722
|
+
}
|
|
723
|
+
}
|
|
724
|
+
get slot() {
|
|
725
|
+
return this.#slot.value;
|
|
726
|
+
}
|
|
727
|
+
#slot;
|
|
728
|
+
#watch;
|
|
729
|
+
#views;
|
|
730
|
+
constructor() {
|
|
731
|
+
super();
|
|
732
|
+
this.vcr = inject(ViewContainerRef);
|
|
733
|
+
this.injector = inject(Injector);
|
|
734
|
+
this.#slot = new BehaviorSubject(null);
|
|
735
|
+
this.#watch = this.#slot.pipe(switchMap(slot => {
|
|
736
|
+
if (slot) {
|
|
737
|
+
return this.slotSvc.watch(slot);
|
|
738
|
+
}
|
|
739
|
+
else {
|
|
740
|
+
return of([]);
|
|
741
|
+
}
|
|
742
|
+
}));
|
|
743
|
+
this.#views = [];
|
|
744
|
+
this.#onEntriesChanged = (entries) => {
|
|
745
|
+
const { remove, undecided } = this.#determineActions(entries);
|
|
746
|
+
for (const r of remove) {
|
|
747
|
+
r.dispose();
|
|
748
|
+
const idx = this.#views.indexOf(r);
|
|
749
|
+
if (idx >= 0) {
|
|
750
|
+
this.#views.splice(idx, 1);
|
|
751
|
+
}
|
|
752
|
+
}
|
|
753
|
+
this.#views.length = 0;
|
|
754
|
+
for (const [pos, entry] of undecided.entries()) {
|
|
755
|
+
if (entry.viewRef && !entry.viewRef.destroyed) {
|
|
756
|
+
const currentPos = this.vcr.indexOf(entry.viewRef);
|
|
757
|
+
if (currentPos !== pos) {
|
|
758
|
+
this.vcr.insert(entry.viewRef, pos);
|
|
759
|
+
}
|
|
760
|
+
}
|
|
761
|
+
else {
|
|
762
|
+
;
|
|
763
|
+
entry.viewRef = this.vcr.createEmbeddedView(entry.tpl, null, {
|
|
764
|
+
index: pos,
|
|
765
|
+
injector: this.injector
|
|
766
|
+
});
|
|
767
|
+
entry.viewRef.markForCheck();
|
|
768
|
+
}
|
|
769
|
+
this.#views.push(entry);
|
|
770
|
+
}
|
|
771
|
+
};
|
|
772
|
+
this.d.any(this.#clearViews.bind(this));
|
|
773
|
+
}
|
|
774
|
+
ngOnInit() {
|
|
775
|
+
this.d.sub(this.#watch).subscribe(this.#onEntriesChanged);
|
|
776
|
+
}
|
|
777
|
+
#onEntriesChanged;
|
|
778
|
+
#determineActions(entries) {
|
|
779
|
+
const byId = {};
|
|
780
|
+
let remove = [];
|
|
781
|
+
const undecided = [];
|
|
782
|
+
for (const entry of entries) {
|
|
783
|
+
if (entry.id != null) {
|
|
784
|
+
if (!byId[entry.id]) {
|
|
785
|
+
byId[entry.id] = [entry];
|
|
786
|
+
}
|
|
787
|
+
else {
|
|
788
|
+
byId[entry.id].push(entry);
|
|
789
|
+
}
|
|
790
|
+
}
|
|
791
|
+
else {
|
|
792
|
+
undecided.push(entry);
|
|
793
|
+
}
|
|
794
|
+
}
|
|
795
|
+
for (const values of Object.values(byId)) {
|
|
796
|
+
remove = remove.concat(values.slice(0, -1));
|
|
797
|
+
undecided.push(values[values.length - 1]);
|
|
798
|
+
}
|
|
799
|
+
for (const current of this.#views) {
|
|
800
|
+
if (!undecided.includes(current)) {
|
|
801
|
+
remove.push(current);
|
|
802
|
+
}
|
|
803
|
+
}
|
|
804
|
+
return { remove, undecided };
|
|
805
|
+
}
|
|
806
|
+
#clearViews() {
|
|
807
|
+
this.vcr.clear();
|
|
808
|
+
this.#views = [];
|
|
809
|
+
}
|
|
810
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: SlotOutletDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
811
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.1.3", type: SlotOutletDirective, usesInheritance: true, ngImport: i0 }); }
|
|
812
|
+
}
|
|
813
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: SlotOutletDirective, decorators: [{
|
|
814
|
+
type: Directive
|
|
815
|
+
}], ctorParameters: () => [] });
|
|
816
|
+
|
|
817
|
+
/**
|
|
818
|
+
* Generated bundle index. Do not edit.
|
|
819
|
+
*/
|
|
820
|
+
|
|
821
|
+
export { DockingContentComponent, DockingLayoutComponent, DockingPanelComponent, L9Cell, L9Range, L9State, NuDockingLayout, SlotDef, SlotDirective, SlotOutletDirective, SlotsService, watchDimension, watchMedia };
|
|
822
|
+
//# sourceMappingURL=ngutil-layout.mjs.map
|