@ngutil/layout 0.0.3-dev.6 → 0.0.3-dev.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,19 +1,747 @@
1
- import { CommonModule } from '@angular/common';
2
1
  import * as i0 from '@angular/core';
3
- import { Component } from '@angular/core';
2
+ import { inject, NgZone, Component, ElementRef, Input, Output, ChangeDetectionStrategy, ContentChild, ContentChildren, NgModule } from '@angular/core';
3
+ import { Observable, distinctUntilChanged, shareReplay, BehaviorSubject, map, combineLatest, switchMap, of, Subject, startWith } from 'rxjs';
4
+ import { NumberWithUnit, rawRequestAnimationFrame, Destructible, coerceBoolAttr } from '@ngutil/common';
4
5
 
5
- class LayoutComponent {
6
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: LayoutComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
7
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.1.3", type: LayoutComponent, isStandalone: true, selector: "nu-layout", ngImport: i0, template: `<p>layout works!</p>`, isInline: true, styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }] }); }
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_CONTENT_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_CONTENT_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
+ };
107
+ }).pipe(shareReplay(1)));
108
+ }
109
+ function _number(val) {
110
+ return new NumberWithUnit(val, "pk");
111
+ }
112
+
113
+ class _FastDOM {
114
+ #rafId;
115
+ #mutate = [];
116
+ #measure = [];
117
+ mutate(handler) {
118
+ this.#mutate.push(handler);
119
+ this._schedule();
120
+ }
121
+ mutateNext(handler) {
122
+ this.#mutate.push(() => {
123
+ this.#mutate.push(handler);
124
+ });
125
+ this._schedule();
126
+ }
127
+ measure(handler) {
128
+ this.#measure.push(handler);
129
+ this._schedule();
130
+ }
131
+ setStyle(el, style, chain) {
132
+ this.mutate(() => {
133
+ for (const [k, v] of Object.entries(style)) {
134
+ if (v == null) {
135
+ el.style.removeProperty(k);
136
+ }
137
+ else {
138
+ el.style.setProperty(k, v);
139
+ }
140
+ }
141
+ chain && chain();
142
+ });
143
+ }
144
+ setAttributes(el, attrs, chain) {
145
+ this.mutate(() => {
146
+ for (const [k, v] of Object.entries(attrs)) {
147
+ if (v == null) {
148
+ el.removeAttribute(k);
149
+ }
150
+ else {
151
+ el.setAttribute(k, v);
152
+ }
153
+ }
154
+ chain && chain();
155
+ });
156
+ }
157
+ _schedule() {
158
+ if (!this.#rafId) {
159
+ this.#rafId = rawRequestAnimationFrame(this._apply.bind(this));
160
+ }
161
+ }
162
+ _apply() {
163
+ this.#rafId = null;
164
+ const measure = this.#measure.slice();
165
+ const mutate = this.#mutate.slice();
166
+ this.#measure.length = 0;
167
+ this.#mutate.length = 0;
168
+ runQ(measure);
169
+ runQ(mutate);
170
+ if (this.#measure.length || this.#mutate.length) {
171
+ this._schedule();
172
+ }
173
+ }
174
+ }
175
+ function runQ(items) {
176
+ let item;
177
+ while ((item = items.shift())) {
178
+ item();
179
+ }
180
+ }
181
+ const FastDOM = new _FastDOM();
182
+
183
+ /**
184
+ * -----------------------------------------------
185
+ * | TOP:LEFT | TOP:CENTER | TOP:RIGHT |
186
+ * -----------------------------------------------
187
+ * | MIDDLE:LEFT | MIDDLE:CENTER | MIDDLE:RIGH |
188
+ * -----------------------------------------------
189
+ * | BOTTOMN:LEFT | BOTTOM:CENTER | BOTTOM:RIGHT |
190
+ * -----------------------------------------------
191
+ */
192
+ const vertical = ["top", "middle", "bottom"];
193
+ const horizontal = ["left", "center", "right"];
194
+ class L9Cell {
195
+ static coerce(value) {
196
+ const [v, h] = value.split(":");
197
+ if (vertical.includes(v) && horizontal.includes(h)) {
198
+ return new L9Cell(v, h);
199
+ }
200
+ throw new Error(`Invalid cell value: ${value}`);
201
+ }
202
+ constructor(v, h) {
203
+ this.v = v;
204
+ this.h = h;
205
+ }
8
206
  }
9
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: LayoutComponent, decorators: [{
207
+ class L9Range {
208
+ static coerce(value) {
209
+ if (value instanceof L9Range) {
210
+ return value;
211
+ }
212
+ else {
213
+ return new L9Range(value);
214
+ }
215
+ }
216
+ constructor(range) {
217
+ this.cells = parse(range);
218
+ this.orient = this.#determineOrient();
219
+ }
220
+ isEq(other) {
221
+ if (other instanceof L9Range) {
222
+ const selfFirst = this.cells[0];
223
+ const otherFirst = other.cells[0];
224
+ if (selfFirst.h !== otherFirst.h || selfFirst.v !== otherFirst.v) {
225
+ return false;
226
+ }
227
+ const selfLast = this.cells[this.cells.length - 1];
228
+ const otherLast = other.cells[other.cells.length - 1];
229
+ if (selfLast.h === otherLast.h && selfLast.v === otherLast.v) {
230
+ return true;
231
+ }
232
+ }
233
+ return false;
234
+ }
235
+ #determineOrient() {
236
+ const { v: sv, h: sh } = this.cells[0];
237
+ const { v: ev, h: eh } = this.cells[this.cells.length - 1];
238
+ if (sv === ev) {
239
+ return "horizontal";
240
+ }
241
+ else if (sh === eh) {
242
+ return "vertical";
243
+ }
244
+ else {
245
+ return "rect";
246
+ }
247
+ }
248
+ }
249
+ function parse(value) {
250
+ const cells = [];
251
+ if (vertical.includes(value)) {
252
+ for (const h of horizontal) {
253
+ cells.push(new L9Cell(value, h));
254
+ }
255
+ }
256
+ else if (horizontal.includes(value)) {
257
+ for (const v of vertical) {
258
+ cells.push(new L9Cell(v, value));
259
+ }
260
+ }
261
+ else if (value.includes("-")) {
262
+ const [begin, end] = value.split("-");
263
+ const beginCells = parse(begin);
264
+ const endCells = parse(end);
265
+ if (beginCells.length > 1) {
266
+ throw new Error(`Currently not supported begin range value: ${begin}`);
267
+ }
268
+ if (endCells.length > 1) {
269
+ throw new Error(`Currently not supported end range value: ${end}`);
270
+ }
271
+ const { v: bv, h: bh } = beginCells[0];
272
+ const { v: ev, h: eh } = endCells[0];
273
+ const vstart = Math.min(vertical.indexOf(bv), vertical.indexOf(ev));
274
+ const vend = Math.max(vertical.indexOf(bv), vertical.indexOf(ev));
275
+ const hstart = Math.min(horizontal.indexOf(bh), horizontal.indexOf(eh));
276
+ const hend = Math.max(horizontal.indexOf(bh), horizontal.indexOf(eh));
277
+ for (let vi = vstart; vi <= vend; vi++) {
278
+ for (let hi = hstart; hi <= hend; hi++) {
279
+ cells.push(new L9Cell(vertical[vi], horizontal[hi]));
280
+ }
281
+ }
282
+ }
283
+ else if (value.includes(":")) {
284
+ cells.push(L9Cell.coerce(value));
285
+ }
286
+ if (cells.length === 0) {
287
+ throw Error(`Undefined l9cell: "${value}"`);
288
+ }
289
+ return cells;
290
+ }
291
+
292
+ class L9State {
293
+ #dims;
294
+ constructor(prefix) {
295
+ this.prefix = prefix;
296
+ this.#dims = new BehaviorSubject({});
297
+ this.style = this.#dims.pipe(map(dims => {
298
+ const res = {};
299
+ for (const [k, v] of Object.entries(dims)) {
300
+ if (v == null) {
301
+ continue;
302
+ }
303
+ const [vertical, horizontal] = k.split(":");
304
+ res[`--${this.prefix}-${vertical}-${horizontal}-w`] = v.width.toString();
305
+ res[`--${this.prefix}-${vertical}-${horizontal}-h`] = v.height.toString();
306
+ }
307
+ return res;
308
+ }), shareReplay(1));
309
+ }
310
+ update(range, dim) {
311
+ range = L9Range.coerce(range);
312
+ const dims = { ...this.#dims.value };
313
+ // for (const cell of range.horizontals) {
314
+ // dims[cell] = dim.width
315
+ // }
316
+ }
317
+ }
318
+
319
+ class DockingContentComponent {
320
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: DockingContentComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
321
+ 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;overflow:auto}\n"] }); }
322
+ }
323
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: DockingContentComponent, decorators: [{
10
324
  type: Component,
11
- args: [{ selector: "nu-layout", standalone: true, imports: [CommonModule], template: `<p>layout works!</p>` }]
325
+ 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;overflow:auto}\n"] }]
326
+ }] });
327
+
328
+ const DEFAULT_POSITION = L9Range.coerce("left");
329
+ class DockingPanelComponent extends Destructible {
330
+ set positionInput(val) {
331
+ const coerced = L9Range.coerce(val);
332
+ console.log("SET POSITION", coerced, this.position.value.isEq(coerced));
333
+ if (coerced.orient === "rect") {
334
+ throw new Error(`Invalid position value: ${val}`);
335
+ }
336
+ if (!this.position.value.isEq(coerced)) {
337
+ this.position.next(coerced);
338
+ }
339
+ }
340
+ set stateInput(val) {
341
+ if (this.state.value !== val) {
342
+ this.state.next(val);
343
+ }
344
+ }
345
+ set modeInput(val) {
346
+ if (this.mode.value !== val) {
347
+ this.mode.next(val);
348
+ }
349
+ }
350
+ set fullSizeInput(val) {
351
+ const coerced = NumberWithUnit.coerce(val, "px");
352
+ if (this.#fullSize.value !== coerced) {
353
+ this.#fullSize.next(coerced);
354
+ }
355
+ }
356
+ #fullSize;
357
+ set miniSizeInput(val) {
358
+ const coerced = NumberWithUnit.coerce(val, "px");
359
+ if (this.#miniSize.value !== coerced) {
360
+ this.#miniSize.next(coerced);
361
+ }
362
+ }
363
+ #miniSize;
364
+ set minimizable(val) {
365
+ this.#minimizable = coerceBoolAttr(val);
366
+ this.#minimizableAuto = false;
367
+ }
368
+ get minimizable() {
369
+ return this.#minimizable;
370
+ }
371
+ #minimizable;
372
+ #minimizableAuto;
373
+ #autoSize;
374
+ constructor() {
375
+ super();
376
+ this.el = inject((ElementRef));
377
+ this.position = new BehaviorSubject(DEFAULT_POSITION);
378
+ this.state = new BehaviorSubject("invisible");
379
+ this.mode = new BehaviorSubject("overlay");
380
+ this.#fullSize = new BehaviorSubject(NumberWithUnit.coerce(0));
381
+ this.#miniSize = new BehaviorSubject(NumberWithUnit.coerce(0));
382
+ this.#minimizable = false;
383
+ this.#minimizableAuto = true;
384
+ this.#autoSize = combineLatest({
385
+ dim: watchDimension(this.el.nativeElement, "scroll-box"),
386
+ pos: this.position
387
+ }).pipe(map(({ dim, pos }) => {
388
+ if (pos.orient === "horizontal") {
389
+ return dim.height;
390
+ }
391
+ else {
392
+ return dim.width;
393
+ }
394
+ }), shareReplay(1));
395
+ this.fullSize = this.#fullSize.pipe(switchMap(size => {
396
+ if (size.unit === "auto") {
397
+ return this.#autoSize;
398
+ }
399
+ else {
400
+ return of(size);
401
+ }
402
+ }), shareReplay(1));
403
+ this.miniSize = this.#miniSize.pipe(switchMap(size => {
404
+ if (size.unit === "auto") {
405
+ return this.#autoSize;
406
+ }
407
+ else {
408
+ return of(size);
409
+ }
410
+ }), shareReplay(1));
411
+ this.changes = combineLatest({
412
+ position: this.position,
413
+ state: this.state,
414
+ mode: this.mode,
415
+ fullSize: this.fullSize,
416
+ miniSize: this.miniSize
417
+ });
418
+ this.d.sub(this.changes).subscribe(changes => {
419
+ if (this.#minimizableAuto) {
420
+ this.#minimizable = this.#miniSize.value.value !== 0;
421
+ }
422
+ FastDOM.setAttributes(this.el.nativeElement, {
423
+ state: changes.state,
424
+ orient: changes.position.orient,
425
+ mode: changes.mode,
426
+ side: changes.position.orient === "horizontal" ? changes.position.cells[0].v : changes.position.cells[0].h
427
+ });
428
+ });
429
+ }
430
+ open() {
431
+ this.state.next("full");
432
+ }
433
+ close() {
434
+ this.state.next("invisible");
435
+ }
436
+ minimize() {
437
+ if (this.minimizable) {
438
+ this.state.next("mini");
439
+ }
440
+ }
441
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: DockingPanelComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
442
+ 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-real-w: var(--docking-panel-real-w, var(---docking-panel-w));---docking-panel-real-h: var(--docking-panel-real-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);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"] }); }
443
+ }
444
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: DockingPanelComponent, decorators: [{
445
+ type: Component,
446
+ 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-real-w: var(--docking-panel-real-w, var(---docking-panel-w));---docking-panel-real-h: var(--docking-panel-real-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);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"] }]
447
+ }], ctorParameters: () => [], propDecorators: { positionInput: [{
448
+ type: Input,
449
+ args: ["position"]
450
+ }], stateInput: [{
451
+ type: Input,
452
+ args: ["state"]
453
+ }], state: [{
454
+ type: Output,
455
+ args: ["stateChanges"]
456
+ }], modeInput: [{
457
+ type: Input,
458
+ args: ["mode"]
459
+ }], fullSizeInput: [{
460
+ type: Input,
461
+ args: ["fullSize"]
462
+ }], miniSizeInput: [{
463
+ type: Input,
464
+ args: ["miniSize"]
465
+ }], minimizable: [{
466
+ type: Input,
467
+ args: ["minimizable"]
468
+ }] } });
469
+
470
+ const EMBEDDED_ZINDEX = 20;
471
+ const OVERLAY_ZINDEX = EMBEDDED_ZINDEX * 2;
472
+ // interface PanelRefChanges {
473
+ // ref: PanelRef
474
+ // changes: DockingPanelChanges
475
+ // }
476
+ // class PanelRef {
477
+ // style: Partial<CSSStyleDeclaration> = {}
478
+ // readonly changes: Observable<PanelRefChanges>
479
+ // constructor(public readonly panel: DockingPanelDirective) {
480
+ // this.changes = panel.changes.pipe(
481
+ // map(changes => {
482
+ // return { ref: this, changes }
483
+ // })
484
+ // )
485
+ // }
486
+ // }
487
+ class DockingLayoutComponent extends Destructible {
488
+ constructor() {
489
+ super(...arguments);
490
+ this.#el = inject((ElementRef));
491
+ this.contentOnly = false;
492
+ this.positionMode = "absolute";
493
+ this.#reflow = new Subject();
494
+ }
495
+ #el;
496
+ #reflow;
497
+ ngAfterViewInit() {
498
+ // eslint-disable-next-line prettier/prettier
499
+ this.panels = this.dockingPanels.changes.pipe(startWith(null), map(() => this.dockingPanels.toArray()), shareReplay(1));
500
+ // this.panels.subscribe(panels => console.log({ panels }))
501
+ this.d
502
+ .sub(combineLatest({ panels: this.panels, reflow: this.#reflow.pipe(startWith(null)) }))
503
+ .pipe(switchMap(({ panels }) => combineLatest(panels.map(panel => panel.changes.pipe(map(changes => {
504
+ return { panel, changes };
505
+ }))))))
506
+ .subscribe(this.#layout.bind(this));
507
+ // this.d
508
+ // .sub(merge(this.dockingPanels.changes, this.#reflow))
509
+ // .pipe(
510
+ // startWith(null),
511
+ // map(() => this.dockingPanels.map(panel => new PanelRef(panel))),
512
+ // switchMap(refs => combineLatest(refs.map(ref => ref.changes))),
513
+ // map(changes => {
514
+ // this.#layout(changes)
515
+ // return changes.map(c => c.ref)
516
+ // })
517
+ // )
518
+ // .subscribe(this.panels)
519
+ }
520
+ ngOnChanges(changes) {
521
+ if ("contentOnly" in changes || "positionMode" in changes) {
522
+ this.#reflow.next();
523
+ }
524
+ }
525
+ #layout(entries) {
526
+ console.log("layout", entries);
527
+ let paddingTop = 0;
528
+ let paddingRight = 0;
529
+ let paddingBottom = 0;
530
+ let paddingLeft = 0;
531
+ let embeddedZIndex = EMBEDDED_ZINDEX;
532
+ let overlayZIndex = OVERLAY_ZINDEX;
533
+ if (this.contentOnly) {
534
+ // TODO:...
535
+ }
536
+ else {
537
+ for (const entry of entries) {
538
+ const panelState = entry.changes;
539
+ const panelSize = panelState.state === "full"
540
+ ? panelState.fullSize.value
541
+ : panelState.state === "mini"
542
+ ? panelState.miniSize.value
543
+ : 0;
544
+ const isHorizontal = panelState.position.orient === "horizontal";
545
+ const isEmbedded = panelState.mode === "embedded";
546
+ let panelTop = null;
547
+ let panelRight = null;
548
+ let panelBottom = null;
549
+ let panelLeft = null;
550
+ if (isHorizontal) {
551
+ panelLeft = 0;
552
+ panelRight = 0;
553
+ if (panelState.position.cells[0].v === "top") {
554
+ if (isEmbedded) {
555
+ paddingTop = Math.max(paddingTop, panelSize);
556
+ }
557
+ panelTop = 0;
558
+ }
559
+ else if (panelState.position.cells[0].v === "bottom") {
560
+ if (isEmbedded) {
561
+ paddingBottom = Math.max(paddingBottom, panelSize);
562
+ }
563
+ panelBottom = 0;
564
+ }
565
+ }
566
+ else {
567
+ panelTop = 0;
568
+ panelBottom = 0;
569
+ if (panelState.position.cells[0].h === "left") {
570
+ if (isEmbedded) {
571
+ paddingLeft = Math.max(paddingLeft, panelSize);
572
+ }
573
+ panelLeft = 0;
574
+ }
575
+ else if (panelState.position.cells[0].h === "right") {
576
+ if (isEmbedded) {
577
+ paddingRight = Math.max(paddingRight, panelSize);
578
+ }
579
+ panelRight = 0;
580
+ }
581
+ }
582
+ const panelGivenSize = panelState.state === "full"
583
+ ? panelState.fullSize
584
+ : panelState.state === "mini"
585
+ ? panelState.miniSize
586
+ : new NumberWithUnit(0, "px");
587
+ FastDOM.setStyle(entry.panel.el.nativeElement, {
588
+ "z-index": `${isEmbedded ? embeddedZIndex++ : overlayZIndex++}`,
589
+ "--docking-panel-t": panelTop != null ? `${panelTop}px` : null,
590
+ "--docking-panel-r": panelRight != null ? `${panelRight}px` : null,
591
+ "--docking-panel-b": panelBottom != null ? `${panelBottom}px` : null,
592
+ "--docking-panel-l": panelLeft != null ? `${panelLeft}px` : null,
593
+ "--docking-panel-w": !isHorizontal
594
+ ? `${panelGivenSize.unit === "auto" ? "auto" : panelGivenSize}`
595
+ : null,
596
+ "--docking-panel-h": isHorizontal
597
+ ? `${panelGivenSize.unit === "auto" ? "auto" : panelGivenSize}`
598
+ : null,
599
+ "--docking-panel-real-w": !isHorizontal ? `${panelSize}px` : null,
600
+ "--docking-panel-real-h": isHorizontal ? `${panelSize}px` : null
601
+ });
602
+ }
603
+ console.log({ paddingTop, paddingRight, paddingBottom, paddingLeft });
604
+ FastDOM.setStyle(this.#el.nativeElement, {
605
+ "--docking-layout-top": `${paddingTop}px`,
606
+ "--docking-layout-right": `${paddingRight}px`,
607
+ "--docking-layout-bottom": `${paddingBottom}px`,
608
+ "--docking-layout-left": `${paddingLeft}px`
609
+ });
610
+ }
611
+ }
612
+ #layoutOld(entries) {
613
+ // let paddingTop = 0
614
+ // let paddingRight = 0
615
+ // let paddingBottom = 0
616
+ // let paddingLeft = 0
617
+ // if (!this.contentOnly) {
618
+ // let embeddedZIndex = EMBEDDED_ZINDEX
619
+ // let overlayZIndex = OVERLAY_ZINDEX
620
+ // const leftRight: PanelRefChanges[] = entries.filter(v =>
621
+ // ["left", "right"].includes(v.changes.position.side)
622
+ // )
623
+ // const topBottom: PanelRefChanges[] = entries.filter(v =>
624
+ // ["top", "bottom"].includes(v.changes.position.side)
625
+ // )
626
+ // for (const entry of entries) {
627
+ // const changes = entry.changes
628
+ // const ref = entry.ref
629
+ // if (changes.mode === "embedded") {
630
+ // ref.style.zIndex = `${embeddedZIndex++}`
631
+ // } else if (changes.mode === "overlay") {
632
+ // ref.style.zIndex = `${overlayZIndex++}`
633
+ // }
634
+ // }
635
+ // for (const entry of leftRight) {
636
+ // const changes = entry.changes
637
+ // const ref = entry.ref
638
+ // const padding =
639
+ // changes.mode === "embedded"
640
+ // ? changes.state === "full"
641
+ // ? changes.fullSize
642
+ // : changes.state === "mini"
643
+ // ? changes.miniSize
644
+ // : 0
645
+ // : 0
646
+ // ref.style.top = "0"
647
+ // ref.style.bottom = "0"
648
+ // if (changes.position.side === "left") {
649
+ // paddingLeft = Math.max(paddingLeft, padding)
650
+ // ref.style.left = "0"
651
+ // ref.style.right = ""
652
+ // } else {
653
+ // paddingRight = Math.max(paddingRight, padding)
654
+ // ref.style.right = "0"
655
+ // ref.style.left = ""
656
+ // }
657
+ // }
658
+ // for (const entry of topBottom) {
659
+ // const changes = entry.changes
660
+ // const ref = entry.ref
661
+ // const padding =
662
+ // changes.mode === "embedded"
663
+ // ? changes.state === "full"
664
+ // ? changes.fullSize
665
+ // : changes.state === "mini"
666
+ // ? changes.miniSize
667
+ // : 0
668
+ // : 0
669
+ // if (changes.mode === "embedded") {
670
+ // ref.style.left = `${paddingLeft}px`
671
+ // ref.style.right = `${paddingRight}px`
672
+ // } else {
673
+ // ref.style.left = "0"
674
+ // ref.style.right = "0"
675
+ // }
676
+ // if (changes.position?.cells[0].v === "top") {
677
+ // paddingTop = Math.max(paddingTop, padding)
678
+ // ref.style.top = "0"
679
+ // ref.style.bottom = ""
680
+ // } else {
681
+ // paddingBottom = Math.max(paddingBottom, padding)
682
+ // ref.style.bottom = `0`
683
+ // ref.style.top = ""
684
+ // }
685
+ // }
686
+ // }
687
+ // const cel = this.contentEl.nativeElement
688
+ // cel.style.padding = `${paddingTop}px ${paddingRight}px ${paddingBottom}px ${paddingLeft}px`
689
+ }
690
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: DockingLayoutComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
691
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.1.3", type: DockingLayoutComponent, isStandalone: true, selector: "nu-docking", inputs: { contentOnly: "contentOnly", positionMode: "positionMode" }, queries: [{ propertyName: "contentComponent", first: true, predicate: DockingContentComponent, descendants: true }, { propertyName: "dockingPanels", predicate: DockingPanelComponent }], usesInheritance: true, usesOnChanges: true, ngImport: i0, template: `
692
+ <ng-content select="nu-docking-panel"></ng-content>
693
+
694
+ @if (!contentComponent) {
695
+ <nu-docking-content>
696
+ <ng-content></ng-content>
697
+ </nu-docking-content>
698
+ } @else {
699
+ <ng-content select="nu-docking-content"></ng-content>
700
+ }
701
+ `, 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" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
702
+ }
703
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: DockingLayoutComponent, decorators: [{
704
+ type: Component,
705
+ args: [{ selector: "nu-docking", standalone: true, imports: [DockingContentComponent], template: `
706
+ <ng-content select="nu-docking-panel"></ng-content>
707
+
708
+ @if (!contentComponent) {
709
+ <nu-docking-content>
710
+ <ng-content></ng-content>
711
+ </nu-docking-content>
712
+ } @else {
713
+ <ng-content select="nu-docking-content"></ng-content>
714
+ }
715
+ `, 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"] }]
716
+ }], propDecorators: { contentOnly: [{
717
+ type: Input
718
+ }], positionMode: [{
719
+ type: Input
720
+ }], contentComponent: [{
721
+ type: ContentChild,
722
+ args: [DockingContentComponent]
723
+ }], dockingPanels: [{
724
+ type: ContentChildren,
725
+ args: [DockingPanelComponent]
726
+ }] } });
727
+
728
+ const members = [DockingLayoutComponent, DockingPanelComponent, DockingContentComponent];
729
+ class NuDockingLayout {
730
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: NuDockingLayout, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
731
+ 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] }); }
732
+ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: NuDockingLayout }); }
733
+ }
734
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: NuDockingLayout, decorators: [{
735
+ type: NgModule,
736
+ args: [{
737
+ imports: members,
738
+ exports: members
739
+ }]
12
740
  }] });
13
741
 
14
742
  /**
15
743
  * Generated bundle index. Do not edit.
16
744
  */
17
745
 
18
- export { LayoutComponent };
746
+ export { DockingContentComponent, DockingLayoutComponent, DockingPanelComponent, FastDOM, L9Cell, L9Range, L9State, NuDockingLayout, watchDimension, watchMedia };
19
747
  //# sourceMappingURL=ngutil-layout.mjs.map